]> Git Repo - qemu.git/blob - target/mips/translate.c
target/mips: Rename 'rn' to 'register_name'
[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 /* MXU registers */
2460 static TCGv mxu_gpr[NUMBER_OF_MXU_REGISTERS - 1];
2461 static TCGv mxu_CR;
2462 #endif
2463
2464 #include "exec/gen-icount.h"
2465
2466 #define gen_helper_0e0i(name, arg) do {                           \
2467     TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
2468     gen_helper_##name(cpu_env, helper_tmp);                       \
2469     tcg_temp_free_i32(helper_tmp);                                \
2470     } while(0)
2471
2472 #define gen_helper_0e1i(name, arg1, arg2) do {                    \
2473     TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
2474     gen_helper_##name(cpu_env, arg1, helper_tmp);                 \
2475     tcg_temp_free_i32(helper_tmp);                                \
2476     } while(0)
2477
2478 #define gen_helper_1e0i(name, ret, arg1) do {                     \
2479     TCGv_i32 helper_tmp = tcg_const_i32(arg1);                    \
2480     gen_helper_##name(ret, cpu_env, helper_tmp);                  \
2481     tcg_temp_free_i32(helper_tmp);                                \
2482     } while(0)
2483
2484 #define gen_helper_1e1i(name, ret, arg1, arg2) do {               \
2485     TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
2486     gen_helper_##name(ret, cpu_env, arg1, helper_tmp);            \
2487     tcg_temp_free_i32(helper_tmp);                                \
2488     } while(0)
2489
2490 #define gen_helper_0e2i(name, arg1, arg2, arg3) do {              \
2491     TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
2492     gen_helper_##name(cpu_env, arg1, arg2, helper_tmp);           \
2493     tcg_temp_free_i32(helper_tmp);                                \
2494     } while(0)
2495
2496 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do {         \
2497     TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
2498     gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp);      \
2499     tcg_temp_free_i32(helper_tmp);                                \
2500     } while(0)
2501
2502 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do {        \
2503     TCGv_i32 helper_tmp = tcg_const_i32(arg4);                    \
2504     gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp);     \
2505     tcg_temp_free_i32(helper_tmp);                                \
2506     } while(0)
2507
2508 typedef struct DisasContext {
2509     DisasContextBase base;
2510     target_ulong saved_pc;
2511     target_ulong page_start;
2512     uint32_t opcode;
2513     uint64_t insn_flags;
2514     int32_t CP0_Config1;
2515     int32_t CP0_Config2;
2516     int32_t CP0_Config3;
2517     int32_t CP0_Config5;
2518     /* Routine used to access memory */
2519     int mem_idx;
2520     TCGMemOp default_tcg_memop_mask;
2521     uint32_t hflags, saved_hflags;
2522     target_ulong btarget;
2523     bool ulri;
2524     int kscrexist;
2525     bool rxi;
2526     int ie;
2527     bool bi;
2528     bool bp;
2529     uint64_t PAMask;
2530     bool mvh;
2531     bool eva;
2532     bool sc;
2533     int CP0_LLAddr_shift;
2534     bool ps;
2535     bool vp;
2536     bool cmgcr;
2537     bool mrp;
2538     bool nan2008;
2539     bool abs2008;
2540     bool saar;
2541 } DisasContext;
2542
2543 #define DISAS_STOP       DISAS_TARGET_0
2544 #define DISAS_EXIT       DISAS_TARGET_1
2545
2546 static const char * const regnames[] = {
2547     "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2548     "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2549     "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2550     "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2551 };
2552
2553 static const char * const regnames_HI[] = {
2554     "HI0", "HI1", "HI2", "HI3",
2555 };
2556
2557 static const char * const regnames_LO[] = {
2558     "LO0", "LO1", "LO2", "LO3",
2559 };
2560
2561 static const char * const fregnames[] = {
2562     "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
2563     "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
2564     "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2565     "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2566 };
2567
2568 static const char * const msaregnames[] = {
2569     "w0.d0",  "w0.d1",  "w1.d0",  "w1.d1",
2570     "w2.d0",  "w2.d1",  "w3.d0",  "w3.d1",
2571     "w4.d0",  "w4.d1",  "w5.d0",  "w5.d1",
2572     "w6.d0",  "w6.d1",  "w7.d0",  "w7.d1",
2573     "w8.d0",  "w8.d1",  "w9.d0",  "w9.d1",
2574     "w10.d0", "w10.d1", "w11.d0", "w11.d1",
2575     "w12.d0", "w12.d1", "w13.d0", "w13.d1",
2576     "w14.d0", "w14.d1", "w15.d0", "w15.d1",
2577     "w16.d0", "w16.d1", "w17.d0", "w17.d1",
2578     "w18.d0", "w18.d1", "w19.d0", "w19.d1",
2579     "w20.d0", "w20.d1", "w21.d0", "w21.d1",
2580     "w22.d0", "w22.d1", "w23.d0", "w23.d1",
2581     "w24.d0", "w24.d1", "w25.d0", "w25.d1",
2582     "w26.d0", "w26.d1", "w27.d0", "w27.d1",
2583     "w28.d0", "w28.d1", "w29.d0", "w29.d1",
2584     "w30.d0", "w30.d1", "w31.d0", "w31.d1",
2585 };
2586
2587 #if !defined(TARGET_MIPS64)
2588 static const char * const mxuregnames[] = {
2589     "XR1",  "XR2",  "XR3",  "XR4",  "XR5",  "XR6",  "XR7",  "XR8",
2590     "XR9",  "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
2591 };
2592 #endif
2593
2594 #define LOG_DISAS(...)                                                        \
2595     do {                                                                      \
2596         if (MIPS_DEBUG_DISAS) {                                               \
2597             qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__);                 \
2598         }                                                                     \
2599     } while (0)
2600
2601 #define MIPS_INVAL(op)                                                        \
2602     do {                                                                      \
2603         if (MIPS_DEBUG_DISAS) {                                               \
2604             qemu_log_mask(CPU_LOG_TB_IN_ASM,                                  \
2605                           TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
2606                           ctx->base.pc_next, ctx->opcode, op,                 \
2607                           ctx->opcode >> 26, ctx->opcode & 0x3F,              \
2608                           ((ctx->opcode >> 16) & 0x1F));                      \
2609         }                                                                     \
2610     } while (0)
2611
2612 /* General purpose registers moves. */
2613 static inline void gen_load_gpr (TCGv t, int reg)
2614 {
2615     if (reg == 0)
2616         tcg_gen_movi_tl(t, 0);
2617     else
2618         tcg_gen_mov_tl(t, cpu_gpr[reg]);
2619 }
2620
2621 static inline void gen_store_gpr (TCGv t, int reg)
2622 {
2623     if (reg != 0)
2624         tcg_gen_mov_tl(cpu_gpr[reg], t);
2625 }
2626
2627 /* Moves to/from shadow registers. */
2628 static inline void gen_load_srsgpr (int from, int to)
2629 {
2630     TCGv t0 = tcg_temp_new();
2631
2632     if (from == 0)
2633         tcg_gen_movi_tl(t0, 0);
2634     else {
2635         TCGv_i32 t2 = tcg_temp_new_i32();
2636         TCGv_ptr addr = tcg_temp_new_ptr();
2637
2638         tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2639         tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2640         tcg_gen_andi_i32(t2, t2, 0xf);
2641         tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2642         tcg_gen_ext_i32_ptr(addr, t2);
2643         tcg_gen_add_ptr(addr, cpu_env, addr);
2644
2645         tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
2646         tcg_temp_free_ptr(addr);
2647         tcg_temp_free_i32(t2);
2648     }
2649     gen_store_gpr(t0, to);
2650     tcg_temp_free(t0);
2651 }
2652
2653 static inline void gen_store_srsgpr (int from, int to)
2654 {
2655     if (to != 0) {
2656         TCGv t0 = tcg_temp_new();
2657         TCGv_i32 t2 = tcg_temp_new_i32();
2658         TCGv_ptr addr = tcg_temp_new_ptr();
2659
2660         gen_load_gpr(t0, from);
2661         tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2662         tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2663         tcg_gen_andi_i32(t2, t2, 0xf);
2664         tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2665         tcg_gen_ext_i32_ptr(addr, t2);
2666         tcg_gen_add_ptr(addr, cpu_env, addr);
2667
2668         tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
2669         tcg_temp_free_ptr(addr);
2670         tcg_temp_free_i32(t2);
2671         tcg_temp_free(t0);
2672     }
2673 }
2674
2675 #if !defined(TARGET_MIPS64)
2676 /* MXU General purpose registers moves. */
2677 static inline void gen_load_mxu_gpr(TCGv t, unsigned int reg)
2678 {
2679     if (reg == 0) {
2680         tcg_gen_movi_tl(t, 0);
2681     } else if (reg <= 15) {
2682         tcg_gen_mov_tl(t, mxu_gpr[reg - 1]);
2683     }
2684 }
2685
2686 static inline void gen_store_mxu_gpr(TCGv t, unsigned int reg)
2687 {
2688     if (reg > 0 && reg <= 15) {
2689         tcg_gen_mov_tl(mxu_gpr[reg - 1], t);
2690     }
2691 }
2692
2693 /* MXU control register moves. */
2694 static inline void gen_load_mxu_cr(TCGv t)
2695 {
2696     tcg_gen_mov_tl(t, mxu_CR);
2697 }
2698
2699 static inline void gen_store_mxu_cr(TCGv t)
2700 {
2701     /* TODO: Add handling of RW rules for MXU_CR. */
2702     tcg_gen_mov_tl(mxu_CR, t);
2703 }
2704 #endif
2705
2706
2707 /* Tests */
2708 static inline void gen_save_pc(target_ulong pc)
2709 {
2710     tcg_gen_movi_tl(cpu_PC, pc);
2711 }
2712
2713 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
2714 {
2715     LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
2716     if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
2717         gen_save_pc(ctx->base.pc_next);
2718         ctx->saved_pc = ctx->base.pc_next;
2719     }
2720     if (ctx->hflags != ctx->saved_hflags) {
2721         tcg_gen_movi_i32(hflags, ctx->hflags);
2722         ctx->saved_hflags = ctx->hflags;
2723         switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2724         case MIPS_HFLAG_BR:
2725             break;
2726         case MIPS_HFLAG_BC:
2727         case MIPS_HFLAG_BL:
2728         case MIPS_HFLAG_B:
2729             tcg_gen_movi_tl(btarget, ctx->btarget);
2730             break;
2731         }
2732     }
2733 }
2734
2735 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
2736 {
2737     ctx->saved_hflags = ctx->hflags;
2738     switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2739     case MIPS_HFLAG_BR:
2740         break;
2741     case MIPS_HFLAG_BC:
2742     case MIPS_HFLAG_BL:
2743     case MIPS_HFLAG_B:
2744         ctx->btarget = env->btarget;
2745         break;
2746     }
2747 }
2748
2749 static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
2750 {
2751     TCGv_i32 texcp = tcg_const_i32(excp);
2752     TCGv_i32 terr = tcg_const_i32(err);
2753     save_cpu_state(ctx, 1);
2754     gen_helper_raise_exception_err(cpu_env, texcp, terr);
2755     tcg_temp_free_i32(terr);
2756     tcg_temp_free_i32(texcp);
2757     ctx->base.is_jmp = DISAS_NORETURN;
2758 }
2759
2760 static inline void generate_exception(DisasContext *ctx, int excp)
2761 {
2762     gen_helper_0e0i(raise_exception, excp);
2763 }
2764
2765 static inline void generate_exception_end(DisasContext *ctx, int excp)
2766 {
2767     generate_exception_err(ctx, excp, 0);
2768 }
2769
2770 /* Floating point register moves. */
2771 static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2772 {
2773     if (ctx->hflags & MIPS_HFLAG_FRE) {
2774         generate_exception(ctx, EXCP_RI);
2775     }
2776     tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
2777 }
2778
2779 static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2780 {
2781     TCGv_i64 t64;
2782     if (ctx->hflags & MIPS_HFLAG_FRE) {
2783         generate_exception(ctx, EXCP_RI);
2784     }
2785     t64 = tcg_temp_new_i64();
2786     tcg_gen_extu_i32_i64(t64, t);
2787     tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
2788     tcg_temp_free_i64(t64);
2789 }
2790
2791 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2792 {
2793     if (ctx->hflags & MIPS_HFLAG_F64) {
2794         tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
2795     } else {
2796         gen_load_fpr32(ctx, t, reg | 1);
2797     }
2798 }
2799
2800 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2801 {
2802     if (ctx->hflags & MIPS_HFLAG_F64) {
2803         TCGv_i64 t64 = tcg_temp_new_i64();
2804         tcg_gen_extu_i32_i64(t64, t);
2805         tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
2806         tcg_temp_free_i64(t64);
2807     } else {
2808         gen_store_fpr32(ctx, t, reg | 1);
2809     }
2810 }
2811
2812 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2813 {
2814     if (ctx->hflags & MIPS_HFLAG_F64) {
2815         tcg_gen_mov_i64(t, fpu_f64[reg]);
2816     } else {
2817         tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
2818     }
2819 }
2820
2821 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2822 {
2823     if (ctx->hflags & MIPS_HFLAG_F64) {
2824         tcg_gen_mov_i64(fpu_f64[reg], t);
2825     } else {
2826         TCGv_i64 t0;
2827         tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
2828         t0 = tcg_temp_new_i64();
2829         tcg_gen_shri_i64(t0, t, 32);
2830         tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
2831         tcg_temp_free_i64(t0);
2832     }
2833 }
2834
2835 static inline int get_fp_bit (int cc)
2836 {
2837     if (cc)
2838         return 24 + cc;
2839     else
2840         return 23;
2841 }
2842
2843 /* Addresses computation */
2844 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
2845 {
2846     tcg_gen_add_tl(ret, arg0, arg1);
2847
2848 #if defined(TARGET_MIPS64)
2849     if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2850         tcg_gen_ext32s_i64(ret, ret);
2851     }
2852 #endif
2853 }
2854
2855 static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
2856                                     target_long ofs)
2857 {
2858     tcg_gen_addi_tl(ret, base, ofs);
2859
2860 #if defined(TARGET_MIPS64)
2861     if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2862         tcg_gen_ext32s_i64(ret, ret);
2863     }
2864 #endif
2865 }
2866
2867 /* Addresses computation (translation time) */
2868 static target_long addr_add(DisasContext *ctx, target_long base,
2869                             target_long offset)
2870 {
2871     target_long sum = base + offset;
2872
2873 #if defined(TARGET_MIPS64)
2874     if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2875         sum = (int32_t)sum;
2876     }
2877 #endif
2878     return sum;
2879 }
2880
2881 /* Sign-extract the low 32-bits to a target_long.  */
2882 static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
2883 {
2884 #if defined(TARGET_MIPS64)
2885     tcg_gen_ext32s_i64(ret, arg);
2886 #else
2887     tcg_gen_extrl_i64_i32(ret, arg);
2888 #endif
2889 }
2890
2891 /* Sign-extract the high 32-bits to a target_long.  */
2892 static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
2893 {
2894 #if defined(TARGET_MIPS64)
2895     tcg_gen_sari_i64(ret, arg, 32);
2896 #else
2897     tcg_gen_extrh_i64_i32(ret, arg);
2898 #endif
2899 }
2900
2901 static inline void check_cp0_enabled(DisasContext *ctx)
2902 {
2903     if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
2904         generate_exception_err(ctx, EXCP_CpU, 0);
2905 }
2906
2907 static inline void check_cp1_enabled(DisasContext *ctx)
2908 {
2909     if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
2910         generate_exception_err(ctx, EXCP_CpU, 1);
2911 }
2912
2913 /* Verify that the processor is running with COP1X instructions enabled.
2914    This is associated with the nabla symbol in the MIPS32 and MIPS64
2915    opcode tables.  */
2916
2917 static inline void check_cop1x(DisasContext *ctx)
2918 {
2919     if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
2920         generate_exception_end(ctx, EXCP_RI);
2921 }
2922
2923 /* Verify that the processor is running with 64-bit floating-point
2924    operations enabled.  */
2925
2926 static inline void check_cp1_64bitmode(DisasContext *ctx)
2927 {
2928     if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
2929         generate_exception_end(ctx, EXCP_RI);
2930 }
2931
2932 /*
2933  * Verify if floating point register is valid; an operation is not defined
2934  * if bit 0 of any register specification is set and the FR bit in the
2935  * Status register equals zero, since the register numbers specify an
2936  * even-odd pair of adjacent coprocessor general registers. When the FR bit
2937  * in the Status register equals one, both even and odd register numbers
2938  * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
2939  *
2940  * Multiple 64 bit wide registers can be checked by calling
2941  * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
2942  */
2943 static inline void check_cp1_registers(DisasContext *ctx, int regs)
2944 {
2945     if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
2946         generate_exception_end(ctx, EXCP_RI);
2947 }
2948
2949 /* Verify that the processor is running with DSP instructions enabled.
2950    This is enabled by CP0 Status register MX(24) bit.
2951  */
2952
2953 static inline void check_dsp(DisasContext *ctx)
2954 {
2955     if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
2956         if (ctx->insn_flags & ASE_DSP) {
2957             generate_exception_end(ctx, EXCP_DSPDIS);
2958         } else {
2959             generate_exception_end(ctx, EXCP_RI);
2960         }
2961     }
2962 }
2963
2964 static inline void check_dsp_r2(DisasContext *ctx)
2965 {
2966     if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
2967         if (ctx->insn_flags & ASE_DSP) {
2968             generate_exception_end(ctx, EXCP_DSPDIS);
2969         } else {
2970             generate_exception_end(ctx, EXCP_RI);
2971         }
2972     }
2973 }
2974
2975 static inline void check_dsp_r3(DisasContext *ctx)
2976 {
2977     if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
2978         if (ctx->insn_flags & ASE_DSP) {
2979             generate_exception_end(ctx, EXCP_DSPDIS);
2980         } else {
2981             generate_exception_end(ctx, EXCP_RI);
2982         }
2983     }
2984 }
2985
2986 /* This code generates a "reserved instruction" exception if the
2987    CPU does not support the instruction set corresponding to flags. */
2988 static inline void check_insn(DisasContext *ctx, uint64_t flags)
2989 {
2990     if (unlikely(!(ctx->insn_flags & flags))) {
2991         generate_exception_end(ctx, EXCP_RI);
2992     }
2993 }
2994
2995 /* This code generates a "reserved instruction" exception if the
2996    CPU has corresponding flag set which indicates that the instruction
2997    has been removed. */
2998 static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
2999 {
3000     if (unlikely(ctx->insn_flags & flags)) {
3001         generate_exception_end(ctx, EXCP_RI);
3002     }
3003 }
3004
3005 /*
3006  * The Linux kernel traps certain reserved instruction exceptions to
3007  * emulate the corresponding instructions. QEMU is the kernel in user
3008  * mode, so those traps are emulated by accepting the instructions.
3009  *
3010  * A reserved instruction exception is generated for flagged CPUs if
3011  * QEMU runs in system mode.
3012  */
3013 static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
3014 {
3015 #ifndef CONFIG_USER_ONLY
3016     check_insn_opc_removed(ctx, flags);
3017 #endif
3018 }
3019
3020 /* This code generates a "reserved instruction" exception if the
3021    CPU does not support 64-bit paired-single (PS) floating point data type */
3022 static inline void check_ps(DisasContext *ctx)
3023 {
3024     if (unlikely(!ctx->ps)) {
3025         generate_exception(ctx, EXCP_RI);
3026     }
3027     check_cp1_64bitmode(ctx);
3028 }
3029
3030 #ifdef TARGET_MIPS64
3031 /* This code generates a "reserved instruction" exception if 64-bit
3032    instructions are not enabled. */
3033 static inline void check_mips_64(DisasContext *ctx)
3034 {
3035     if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
3036         generate_exception_end(ctx, EXCP_RI);
3037 }
3038 #endif
3039
3040 #ifndef CONFIG_USER_ONLY
3041 static inline void check_mvh(DisasContext *ctx)
3042 {
3043     if (unlikely(!ctx->mvh)) {
3044         generate_exception(ctx, EXCP_RI);
3045     }
3046 }
3047 #endif
3048
3049 /*
3050  * This code generates a "reserved instruction" exception if the
3051  * Config5 XNP bit is set.
3052  */
3053 static inline void check_xnp(DisasContext *ctx)
3054 {
3055     if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
3056         generate_exception_end(ctx, EXCP_RI);
3057     }
3058 }
3059
3060 #ifndef CONFIG_USER_ONLY
3061 /*
3062  * This code generates a "reserved instruction" exception if the
3063  * Config3 PW bit is NOT set.
3064  */
3065 static inline void check_pw(DisasContext *ctx)
3066 {
3067     if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
3068         generate_exception_end(ctx, EXCP_RI);
3069     }
3070 }
3071 #endif
3072
3073 /*
3074  * This code generates a "reserved instruction" exception if the
3075  * Config3 MT bit is NOT set.
3076  */
3077 static inline void check_mt(DisasContext *ctx)
3078 {
3079     if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3080         generate_exception_end(ctx, EXCP_RI);
3081     }
3082 }
3083
3084 #ifndef CONFIG_USER_ONLY
3085 /*
3086  * This code generates a "coprocessor unusable" exception if CP0 is not
3087  * available, and, if that is not the case, generates a "reserved instruction"
3088  * exception if the Config5 MT bit is NOT set. This is needed for availability
3089  * control of some of MT ASE instructions.
3090  */
3091 static inline void check_cp0_mt(DisasContext *ctx)
3092 {
3093     if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
3094         generate_exception_err(ctx, EXCP_CpU, 0);
3095     } else {
3096         if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3097             generate_exception_err(ctx, EXCP_RI, 0);
3098         }
3099     }
3100 }
3101 #endif
3102
3103 /*
3104  * This code generates a "reserved instruction" exception if the
3105  * Config5 NMS bit is set.
3106  */
3107 static inline void check_nms(DisasContext *ctx)
3108 {
3109     if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
3110         generate_exception_end(ctx, EXCP_RI);
3111     }
3112 }
3113
3114 /*
3115  * This code generates a "reserved instruction" exception if the
3116  * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
3117  * Config2 TL, and Config5 L2C are unset.
3118  */
3119 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
3120 {
3121     if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
3122         !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
3123         !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
3124         !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
3125         !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
3126         !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))
3127     {
3128         generate_exception_end(ctx, EXCP_RI);
3129     }
3130 }
3131
3132 /*
3133  * This code generates a "reserved instruction" exception if the
3134  * Config5 EVA bit is NOT set.
3135  */
3136 static inline void check_eva(DisasContext *ctx)
3137 {
3138     if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
3139         generate_exception_end(ctx, EXCP_RI);
3140     }
3141 }
3142
3143
3144 /* Define small wrappers for gen_load_fpr* so that we have a uniform
3145    calling interface for 32 and 64-bit FPRs.  No sense in changing
3146    all callers for gen_load_fpr32 when we need the CTX parameter for
3147    this one use.  */
3148 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
3149 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
3150 #define FOP_CONDS(type, abs, fmt, ifmt, bits)                                 \
3151 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
3152                                                int ft, int fs, int cc)        \
3153 {                                                                             \
3154     TCGv_i##bits fp0 = tcg_temp_new_i##bits ();                               \
3155     TCGv_i##bits fp1 = tcg_temp_new_i##bits ();                               \
3156     switch (ifmt) {                                                           \
3157     case FMT_PS:                                                              \
3158         check_ps(ctx);                                                        \
3159         break;                                                                \
3160     case FMT_D:                                                               \
3161         if (abs) {                                                            \
3162             check_cop1x(ctx);                                                 \
3163         }                                                                     \
3164         check_cp1_registers(ctx, fs | ft);                                    \
3165         break;                                                                \
3166     case FMT_S:                                                               \
3167         if (abs) {                                                            \
3168             check_cop1x(ctx);                                                 \
3169         }                                                                     \
3170         break;                                                                \
3171     }                                                                         \
3172     gen_ldcmp_fpr##bits (ctx, fp0, fs);                                       \
3173     gen_ldcmp_fpr##bits (ctx, fp1, ft);                                       \
3174     switch (n) {                                                              \
3175     case  0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc);    break;\
3176     case  1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc);   break;\
3177     case  2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc);   break;\
3178     case  3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc);  break;\
3179     case  4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc);  break;\
3180     case  5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc);  break;\
3181     case  6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc);  break;\
3182     case  7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc);  break;\
3183     case  8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc);   break;\
3184     case  9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
3185     case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc);  break;\
3186     case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc);  break;\
3187     case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc);   break;\
3188     case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc);  break;\
3189     case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc);   break;\
3190     case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc);  break;\
3191     default: abort();                                                         \
3192     }                                                                         \
3193     tcg_temp_free_i##bits (fp0);                                              \
3194     tcg_temp_free_i##bits (fp1);                                              \
3195 }
3196
3197 FOP_CONDS(, 0, d, FMT_D, 64)
3198 FOP_CONDS(abs, 1, d, FMT_D, 64)
3199 FOP_CONDS(, 0, s, FMT_S, 32)
3200 FOP_CONDS(abs, 1, s, FMT_S, 32)
3201 FOP_CONDS(, 0, ps, FMT_PS, 64)
3202 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
3203 #undef FOP_CONDS
3204
3205 #define FOP_CONDNS(fmt, ifmt, bits, STORE)                              \
3206 static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n,        \
3207                                       int ft, int fs, int fd)           \
3208 {                                                                       \
3209     TCGv_i ## bits fp0 = tcg_temp_new_i ## bits();                      \
3210     TCGv_i ## bits fp1 = tcg_temp_new_i ## bits();                      \
3211     if (ifmt == FMT_D) {                                                \
3212         check_cp1_registers(ctx, fs | ft | fd);                         \
3213     }                                                                   \
3214     gen_ldcmp_fpr ## bits(ctx, fp0, fs);                                \
3215     gen_ldcmp_fpr ## bits(ctx, fp1, ft);                                \
3216     switch (n) {                                                        \
3217     case  0:                                                            \
3218         gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1);       \
3219         break;                                                          \
3220     case  1:                                                            \
3221         gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1);       \
3222         break;                                                          \
3223     case  2:                                                            \
3224         gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1);       \
3225         break;                                                          \
3226     case  3:                                                            \
3227         gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1);      \
3228         break;                                                          \
3229     case  4:                                                            \
3230         gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1);       \
3231         break;                                                          \
3232     case  5:                                                            \
3233         gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1);      \
3234         break;                                                          \
3235     case  6:                                                            \
3236         gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1);       \
3237         break;                                                          \
3238     case  7:                                                            \
3239         gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1);      \
3240         break;                                                          \
3241     case  8:                                                            \
3242         gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1);      \
3243         break;                                                          \
3244     case  9:                                                            \
3245         gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1);      \
3246         break;                                                          \
3247     case 10:                                                            \
3248         gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1);      \
3249         break;                                                          \
3250     case 11:                                                            \
3251         gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1);     \
3252         break;                                                          \
3253     case 12:                                                            \
3254         gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1);      \
3255         break;                                                          \
3256     case 13:                                                            \
3257         gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1);     \
3258         break;                                                          \
3259     case 14:                                                            \
3260         gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1);      \
3261         break;                                                          \
3262     case 15:                                                            \
3263         gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1);     \
3264         break;                                                          \
3265     case 17:                                                            \
3266         gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1);       \
3267         break;                                                          \
3268     case 18:                                                            \
3269         gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1);      \
3270         break;                                                          \
3271     case 19:                                                            \
3272         gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1);       \
3273         break;                                                          \
3274     case 25:                                                            \
3275         gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1);      \
3276         break;                                                          \
3277     case 26:                                                            \
3278         gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1);     \
3279         break;                                                          \
3280     case 27:                                                            \
3281         gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1);      \
3282         break;                                                          \
3283     default:                                                            \
3284         abort();                                                        \
3285     }                                                                   \
3286     STORE;                                                              \
3287     tcg_temp_free_i ## bits (fp0);                                      \
3288     tcg_temp_free_i ## bits (fp1);                                      \
3289 }
3290
3291 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
3292 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3293 #undef FOP_CONDNS
3294 #undef gen_ldcmp_fpr32
3295 #undef gen_ldcmp_fpr64
3296
3297 /* load/store instructions. */
3298 #ifdef CONFIG_USER_ONLY
3299 #define OP_LD_ATOMIC(insn,fname)                                           \
3300 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
3301                                 DisasContext *ctx)                         \
3302 {                                                                          \
3303     TCGv t0 = tcg_temp_new();                                              \
3304     tcg_gen_mov_tl(t0, arg1);                                              \
3305     tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
3306     tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));                \
3307     tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval));                \
3308     tcg_temp_free(t0);                                                     \
3309 }
3310 #else
3311 #define OP_LD_ATOMIC(insn,fname)                                           \
3312 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
3313                                 DisasContext *ctx)                         \
3314 {                                                                          \
3315     gen_helper_1e1i(insn, ret, arg1, mem_idx);                             \
3316 }
3317 #endif
3318 OP_LD_ATOMIC(ll,ld32s);
3319 #if defined(TARGET_MIPS64)
3320 OP_LD_ATOMIC(lld,ld64);
3321 #endif
3322 #undef OP_LD_ATOMIC
3323
3324 #ifdef CONFIG_USER_ONLY
3325 #define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
3326 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx,   \
3327                                 DisasContext *ctx)                           \
3328 {                                                                            \
3329     TCGv t0 = tcg_temp_new();                                                \
3330     TCGLabel *l1 = gen_new_label();                                          \
3331     TCGLabel *l2 = gen_new_label();                                          \
3332                                                                              \
3333     tcg_gen_andi_tl(t0, arg2, almask);                                       \
3334     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);                              \
3335     tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));          \
3336     generate_exception(ctx, EXCP_AdES);                                      \
3337     gen_set_label(l1);                                                       \
3338     tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));                  \
3339     tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2);                            \
3340     tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20));                        \
3341     tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg));                   \
3342     tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval));              \
3343     generate_exception_end(ctx, EXCP_SC);                                    \
3344     gen_set_label(l2);                                                       \
3345     tcg_gen_movi_tl(t0, 0);                                                  \
3346     gen_store_gpr(t0, rt);                                                   \
3347     tcg_temp_free(t0);                                                       \
3348 }
3349 #else
3350 #define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
3351 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx,   \
3352                                 DisasContext *ctx)                           \
3353 {                                                                            \
3354     TCGv t0 = tcg_temp_new();                                                \
3355     gen_helper_1e2i(insn, t0, arg1, arg2, mem_idx);                          \
3356     gen_store_gpr(t0, rt);                                                   \
3357     tcg_temp_free(t0);                                                       \
3358 }
3359 #endif
3360 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
3361 #if defined(TARGET_MIPS64)
3362 OP_ST_ATOMIC(scd,st64,ld64,0x7);
3363 #endif
3364 #undef OP_ST_ATOMIC
3365
3366 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
3367                                   int base, int offset)
3368 {
3369     if (base == 0) {
3370         tcg_gen_movi_tl(addr, offset);
3371     } else if (offset == 0) {
3372         gen_load_gpr(addr, base);
3373     } else {
3374         tcg_gen_movi_tl(addr, offset);
3375         gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
3376     }
3377 }
3378
3379 static target_ulong pc_relative_pc (DisasContext *ctx)
3380 {
3381     target_ulong pc = ctx->base.pc_next;
3382
3383     if (ctx->hflags & MIPS_HFLAG_BMASK) {
3384         int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
3385
3386         pc -= branch_bytes;
3387     }
3388
3389     pc &= ~(target_ulong)3;
3390     return pc;
3391 }
3392
3393 /* Load */
3394 static void gen_ld(DisasContext *ctx, uint32_t opc,
3395                    int rt, int base, int offset)
3396 {
3397     TCGv t0, t1, t2;
3398     int mem_idx = ctx->mem_idx;
3399
3400     if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
3401         /* Loongson CPU uses a load to zero register for prefetch.
3402            We emulate it as a NOP. On other CPU we must perform the
3403            actual memory access. */
3404         return;
3405     }
3406
3407     t0 = tcg_temp_new();
3408     gen_base_offset_addr(ctx, t0, base, offset);
3409
3410     switch (opc) {
3411 #if defined(TARGET_MIPS64)
3412     case OPC_LWU:
3413         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
3414                            ctx->default_tcg_memop_mask);
3415         gen_store_gpr(t0, rt);
3416         break;
3417     case OPC_LD:
3418         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
3419                            ctx->default_tcg_memop_mask);
3420         gen_store_gpr(t0, rt);
3421         break;
3422     case OPC_LLD:
3423     case R6_OPC_LLD:
3424         op_ld_lld(t0, t0, mem_idx, ctx);
3425         gen_store_gpr(t0, rt);
3426         break;
3427     case OPC_LDL:
3428         t1 = tcg_temp_new();
3429         /* Do a byte access to possibly trigger a page
3430            fault with the unaligned address.  */
3431         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3432         tcg_gen_andi_tl(t1, t0, 7);
3433 #ifndef TARGET_WORDS_BIGENDIAN
3434         tcg_gen_xori_tl(t1, t1, 7);
3435 #endif
3436         tcg_gen_shli_tl(t1, t1, 3);
3437         tcg_gen_andi_tl(t0, t0, ~7);
3438         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3439         tcg_gen_shl_tl(t0, t0, t1);
3440         t2 = tcg_const_tl(-1);
3441         tcg_gen_shl_tl(t2, t2, t1);
3442         gen_load_gpr(t1, rt);
3443         tcg_gen_andc_tl(t1, t1, t2);
3444         tcg_temp_free(t2);
3445         tcg_gen_or_tl(t0, t0, t1);
3446         tcg_temp_free(t1);
3447         gen_store_gpr(t0, rt);
3448         break;
3449     case OPC_LDR:
3450         t1 = tcg_temp_new();
3451         /* Do a byte access to possibly trigger a page
3452            fault with the unaligned address.  */
3453         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3454         tcg_gen_andi_tl(t1, t0, 7);
3455 #ifdef TARGET_WORDS_BIGENDIAN
3456         tcg_gen_xori_tl(t1, t1, 7);
3457 #endif
3458         tcg_gen_shli_tl(t1, t1, 3);
3459         tcg_gen_andi_tl(t0, t0, ~7);
3460         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3461         tcg_gen_shr_tl(t0, t0, t1);
3462         tcg_gen_xori_tl(t1, t1, 63);
3463         t2 = tcg_const_tl(0xfffffffffffffffeull);
3464         tcg_gen_shl_tl(t2, t2, t1);
3465         gen_load_gpr(t1, rt);
3466         tcg_gen_and_tl(t1, t1, t2);
3467         tcg_temp_free(t2);
3468         tcg_gen_or_tl(t0, t0, t1);
3469         tcg_temp_free(t1);
3470         gen_store_gpr(t0, rt);
3471         break;
3472     case OPC_LDPC:
3473         t1 = tcg_const_tl(pc_relative_pc(ctx));
3474         gen_op_addr_add(ctx, t0, t0, t1);
3475         tcg_temp_free(t1);
3476         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3477         gen_store_gpr(t0, rt);
3478         break;
3479 #endif
3480     case OPC_LWPC:
3481         t1 = tcg_const_tl(pc_relative_pc(ctx));
3482         gen_op_addr_add(ctx, t0, t0, t1);
3483         tcg_temp_free(t1);
3484         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
3485         gen_store_gpr(t0, rt);
3486         break;
3487     case OPC_LWE:
3488         mem_idx = MIPS_HFLAG_UM;
3489         /* fall through */
3490     case OPC_LW:
3491         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
3492                            ctx->default_tcg_memop_mask);
3493         gen_store_gpr(t0, rt);
3494         break;
3495     case OPC_LHE:
3496         mem_idx = MIPS_HFLAG_UM;
3497         /* fall through */
3498     case OPC_LH:
3499         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
3500                            ctx->default_tcg_memop_mask);
3501         gen_store_gpr(t0, rt);
3502         break;
3503     case OPC_LHUE:
3504         mem_idx = MIPS_HFLAG_UM;
3505         /* fall through */
3506     case OPC_LHU:
3507         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
3508                            ctx->default_tcg_memop_mask);
3509         gen_store_gpr(t0, rt);
3510         break;
3511     case OPC_LBE:
3512         mem_idx = MIPS_HFLAG_UM;
3513         /* fall through */
3514     case OPC_LB:
3515         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
3516         gen_store_gpr(t0, rt);
3517         break;
3518     case OPC_LBUE:
3519         mem_idx = MIPS_HFLAG_UM;
3520         /* fall through */
3521     case OPC_LBU:
3522         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
3523         gen_store_gpr(t0, rt);
3524         break;
3525     case OPC_LWLE:
3526         mem_idx = MIPS_HFLAG_UM;
3527         /* fall through */
3528     case OPC_LWL:
3529         t1 = tcg_temp_new();
3530         /* Do a byte access to possibly trigger a page
3531            fault with the unaligned address.  */
3532         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3533         tcg_gen_andi_tl(t1, t0, 3);
3534 #ifndef TARGET_WORDS_BIGENDIAN
3535         tcg_gen_xori_tl(t1, t1, 3);
3536 #endif
3537         tcg_gen_shli_tl(t1, t1, 3);
3538         tcg_gen_andi_tl(t0, t0, ~3);
3539         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3540         tcg_gen_shl_tl(t0, t0, t1);
3541         t2 = tcg_const_tl(-1);
3542         tcg_gen_shl_tl(t2, t2, t1);
3543         gen_load_gpr(t1, rt);
3544         tcg_gen_andc_tl(t1, t1, t2);
3545         tcg_temp_free(t2);
3546         tcg_gen_or_tl(t0, t0, t1);
3547         tcg_temp_free(t1);
3548         tcg_gen_ext32s_tl(t0, t0);
3549         gen_store_gpr(t0, rt);
3550         break;
3551     case OPC_LWRE:
3552         mem_idx = MIPS_HFLAG_UM;
3553         /* fall through */
3554     case OPC_LWR:
3555         t1 = tcg_temp_new();
3556         /* Do a byte access to possibly trigger a page
3557            fault with the unaligned address.  */
3558         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3559         tcg_gen_andi_tl(t1, t0, 3);
3560 #ifdef TARGET_WORDS_BIGENDIAN
3561         tcg_gen_xori_tl(t1, t1, 3);
3562 #endif
3563         tcg_gen_shli_tl(t1, t1, 3);
3564         tcg_gen_andi_tl(t0, t0, ~3);
3565         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3566         tcg_gen_shr_tl(t0, t0, t1);
3567         tcg_gen_xori_tl(t1, t1, 31);
3568         t2 = tcg_const_tl(0xfffffffeull);
3569         tcg_gen_shl_tl(t2, t2, t1);
3570         gen_load_gpr(t1, rt);
3571         tcg_gen_and_tl(t1, t1, t2);
3572         tcg_temp_free(t2);
3573         tcg_gen_or_tl(t0, t0, t1);
3574         tcg_temp_free(t1);
3575         tcg_gen_ext32s_tl(t0, t0);
3576         gen_store_gpr(t0, rt);
3577         break;
3578     case OPC_LLE:
3579         mem_idx = MIPS_HFLAG_UM;
3580         /* fall through */
3581     case OPC_LL:
3582     case R6_OPC_LL:
3583         op_ld_ll(t0, t0, mem_idx, ctx);
3584         gen_store_gpr(t0, rt);
3585         break;
3586     }
3587     tcg_temp_free(t0);
3588 }
3589
3590 static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
3591                     uint32_t reg1, uint32_t reg2)
3592 {
3593     TCGv taddr = tcg_temp_new();
3594     TCGv_i64 tval = tcg_temp_new_i64();
3595     TCGv tmp1 = tcg_temp_new();
3596     TCGv tmp2 = tcg_temp_new();
3597
3598     gen_base_offset_addr(ctx, taddr, base, offset);
3599     tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx);
3600 #ifdef TARGET_WORDS_BIGENDIAN
3601     tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
3602 #else
3603     tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
3604 #endif
3605     gen_store_gpr(tmp1, reg1);
3606     tcg_temp_free(tmp1);
3607     gen_store_gpr(tmp2, reg2);
3608     tcg_temp_free(tmp2);
3609     tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3610     tcg_temp_free_i64(tval);
3611     tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr));
3612     tcg_temp_free(taddr);
3613 }
3614
3615 /* Store */
3616 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
3617                     int base, int offset)
3618 {
3619     TCGv t0 = tcg_temp_new();
3620     TCGv t1 = tcg_temp_new();
3621     int mem_idx = ctx->mem_idx;
3622
3623     gen_base_offset_addr(ctx, t0, base, offset);
3624     gen_load_gpr(t1, rt);
3625     switch (opc) {
3626 #if defined(TARGET_MIPS64)
3627     case OPC_SD:
3628         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
3629                            ctx->default_tcg_memop_mask);
3630         break;
3631     case OPC_SDL:
3632         gen_helper_0e2i(sdl, t1, t0, mem_idx);
3633         break;
3634     case OPC_SDR:
3635         gen_helper_0e2i(sdr, t1, t0, mem_idx);
3636         break;
3637 #endif
3638     case OPC_SWE:
3639         mem_idx = MIPS_HFLAG_UM;
3640         /* fall through */
3641     case OPC_SW:
3642         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
3643                            ctx->default_tcg_memop_mask);
3644         break;
3645     case OPC_SHE:
3646         mem_idx = MIPS_HFLAG_UM;
3647         /* fall through */
3648     case OPC_SH:
3649         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
3650                            ctx->default_tcg_memop_mask);
3651         break;
3652     case OPC_SBE:
3653         mem_idx = MIPS_HFLAG_UM;
3654         /* fall through */
3655     case OPC_SB:
3656         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
3657         break;
3658     case OPC_SWLE:
3659         mem_idx = MIPS_HFLAG_UM;
3660         /* fall through */
3661     case OPC_SWL:
3662         gen_helper_0e2i(swl, t1, t0, mem_idx);
3663         break;
3664     case OPC_SWRE:
3665         mem_idx = MIPS_HFLAG_UM;
3666         /* fall through */
3667     case OPC_SWR:
3668         gen_helper_0e2i(swr, t1, t0, mem_idx);
3669         break;
3670     }
3671     tcg_temp_free(t0);
3672     tcg_temp_free(t1);
3673 }
3674
3675
3676 /* Store conditional */
3677 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
3678                          int base, int16_t offset)
3679 {
3680     TCGv t0, t1;
3681     int mem_idx = ctx->mem_idx;
3682
3683 #ifdef CONFIG_USER_ONLY
3684     t0 = tcg_temp_local_new();
3685     t1 = tcg_temp_local_new();
3686 #else
3687     t0 = tcg_temp_new();
3688     t1 = tcg_temp_new();
3689 #endif
3690     gen_base_offset_addr(ctx, t0, base, offset);
3691     gen_load_gpr(t1, rt);
3692     switch (opc) {
3693 #if defined(TARGET_MIPS64)
3694     case OPC_SCD:
3695     case R6_OPC_SCD:
3696         op_st_scd(t1, t0, rt, mem_idx, ctx);
3697         break;
3698 #endif
3699     case OPC_SCE:
3700         mem_idx = MIPS_HFLAG_UM;
3701         /* fall through */
3702     case OPC_SC:
3703     case R6_OPC_SC:
3704         op_st_sc(t1, t0, rt, mem_idx, ctx);
3705         break;
3706     }
3707     tcg_temp_free(t1);
3708     tcg_temp_free(t0);
3709 }
3710
3711 static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
3712                     uint32_t reg1, uint32_t reg2)
3713 {
3714     TCGv taddr = tcg_temp_local_new();
3715     TCGv lladdr = tcg_temp_local_new();
3716     TCGv_i64 tval = tcg_temp_new_i64();
3717     TCGv_i64 llval = tcg_temp_new_i64();
3718     TCGv_i64 val = tcg_temp_new_i64();
3719     TCGv tmp1 = tcg_temp_new();
3720     TCGv tmp2 = tcg_temp_new();
3721     TCGLabel *lab_fail = gen_new_label();
3722     TCGLabel *lab_done = gen_new_label();
3723
3724     gen_base_offset_addr(ctx, taddr, base, offset);
3725
3726     tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3727     tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail);
3728
3729     gen_load_gpr(tmp1, reg1);
3730     gen_load_gpr(tmp2, reg2);
3731
3732 #ifdef TARGET_WORDS_BIGENDIAN
3733     tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
3734 #else
3735     tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
3736 #endif
3737
3738     tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3739     tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
3740                                ctx->mem_idx, MO_64);
3741     if (reg1 != 0) {
3742         tcg_gen_movi_tl(cpu_gpr[reg1], 1);
3743     }
3744     tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done);
3745
3746     gen_set_label(lab_fail);
3747
3748     if (reg1 != 0) {
3749         tcg_gen_movi_tl(cpu_gpr[reg1], 0);
3750     }
3751     gen_set_label(lab_done);
3752     tcg_gen_movi_tl(lladdr, -1);
3753     tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3754 }
3755
3756 /* Load and store */
3757 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
3758                           TCGv t0)
3759 {
3760     /* Don't do NOP if destination is zero: we must perform the actual
3761        memory access. */
3762     switch (opc) {
3763     case OPC_LWC1:
3764         {
3765             TCGv_i32 fp0 = tcg_temp_new_i32();
3766             tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
3767                                 ctx->default_tcg_memop_mask);
3768             gen_store_fpr32(ctx, fp0, ft);
3769             tcg_temp_free_i32(fp0);
3770         }
3771         break;
3772     case OPC_SWC1:
3773         {
3774             TCGv_i32 fp0 = tcg_temp_new_i32();
3775             gen_load_fpr32(ctx, fp0, ft);
3776             tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
3777                                 ctx->default_tcg_memop_mask);
3778             tcg_temp_free_i32(fp0);
3779         }
3780         break;
3781     case OPC_LDC1:
3782         {
3783             TCGv_i64 fp0 = tcg_temp_new_i64();
3784             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3785                                 ctx->default_tcg_memop_mask);
3786             gen_store_fpr64(ctx, fp0, ft);
3787             tcg_temp_free_i64(fp0);
3788         }
3789         break;
3790     case OPC_SDC1:
3791         {
3792             TCGv_i64 fp0 = tcg_temp_new_i64();
3793             gen_load_fpr64(ctx, fp0, ft);
3794             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3795                                 ctx->default_tcg_memop_mask);
3796             tcg_temp_free_i64(fp0);
3797         }
3798         break;
3799     default:
3800         MIPS_INVAL("flt_ldst");
3801         generate_exception_end(ctx, EXCP_RI);
3802         break;
3803     }
3804 }
3805
3806 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
3807                           int rs, int16_t imm)
3808 {
3809     TCGv t0 = tcg_temp_new();
3810
3811     if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3812         check_cp1_enabled(ctx);
3813         switch (op) {
3814         case OPC_LDC1:
3815         case OPC_SDC1:
3816             check_insn(ctx, ISA_MIPS2);
3817             /* Fallthrough */
3818         default:
3819             gen_base_offset_addr(ctx, t0, rs, imm);
3820             gen_flt_ldst(ctx, op, rt, t0);
3821         }
3822     } else {
3823         generate_exception_err(ctx, EXCP_CpU, 1);
3824     }
3825     tcg_temp_free(t0);
3826 }
3827
3828 /* Arithmetic with immediate operand */
3829 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
3830                           int rt, int rs, int imm)
3831 {
3832     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3833
3834     if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
3835         /* If no destination, treat it as a NOP.
3836            For addi, we must generate the overflow exception when needed. */
3837         return;
3838     }
3839     switch (opc) {
3840     case OPC_ADDI:
3841         {
3842             TCGv t0 = tcg_temp_local_new();
3843             TCGv t1 = tcg_temp_new();
3844             TCGv t2 = tcg_temp_new();
3845             TCGLabel *l1 = gen_new_label();
3846
3847             gen_load_gpr(t1, rs);
3848             tcg_gen_addi_tl(t0, t1, uimm);
3849             tcg_gen_ext32s_tl(t0, t0);
3850
3851             tcg_gen_xori_tl(t1, t1, ~uimm);
3852             tcg_gen_xori_tl(t2, t0, uimm);
3853             tcg_gen_and_tl(t1, t1, t2);
3854             tcg_temp_free(t2);
3855             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3856             tcg_temp_free(t1);
3857             /* operands of same sign, result different sign */
3858             generate_exception(ctx, EXCP_OVERFLOW);
3859             gen_set_label(l1);
3860             tcg_gen_ext32s_tl(t0, t0);
3861             gen_store_gpr(t0, rt);
3862             tcg_temp_free(t0);
3863         }
3864         break;
3865     case OPC_ADDIU:
3866         if (rs != 0) {
3867             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3868             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3869         } else {
3870             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3871         }
3872         break;
3873 #if defined(TARGET_MIPS64)
3874     case OPC_DADDI:
3875         {
3876             TCGv t0 = tcg_temp_local_new();
3877             TCGv t1 = tcg_temp_new();
3878             TCGv t2 = tcg_temp_new();
3879             TCGLabel *l1 = gen_new_label();
3880
3881             gen_load_gpr(t1, rs);
3882             tcg_gen_addi_tl(t0, t1, uimm);
3883
3884             tcg_gen_xori_tl(t1, t1, ~uimm);
3885             tcg_gen_xori_tl(t2, t0, uimm);
3886             tcg_gen_and_tl(t1, t1, t2);
3887             tcg_temp_free(t2);
3888             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3889             tcg_temp_free(t1);
3890             /* operands of same sign, result different sign */
3891             generate_exception(ctx, EXCP_OVERFLOW);
3892             gen_set_label(l1);
3893             gen_store_gpr(t0, rt);
3894             tcg_temp_free(t0);
3895         }
3896         break;
3897     case OPC_DADDIU:
3898         if (rs != 0) {
3899             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3900         } else {
3901             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3902         }
3903         break;
3904 #endif
3905     }
3906 }
3907
3908 /* Logic with immediate operand */
3909 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
3910                           int rt, int rs, int16_t imm)
3911 {
3912     target_ulong uimm;
3913
3914     if (rt == 0) {
3915         /* If no destination, treat it as a NOP. */
3916         return;
3917     }
3918     uimm = (uint16_t)imm;
3919     switch (opc) {
3920     case OPC_ANDI:
3921         if (likely(rs != 0))
3922             tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3923         else
3924             tcg_gen_movi_tl(cpu_gpr[rt], 0);
3925         break;
3926     case OPC_ORI:
3927         if (rs != 0)
3928             tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3929         else
3930             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3931         break;
3932     case OPC_XORI:
3933         if (likely(rs != 0))
3934             tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3935         else
3936             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3937         break;
3938     case OPC_LUI:
3939         if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
3940             /* OPC_AUI */
3941             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
3942             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3943         } else {
3944             tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
3945         }
3946         break;
3947
3948     default:
3949         break;
3950     }
3951 }
3952
3953 /* Set on less than with immediate operand */
3954 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
3955                         int rt, int rs, int16_t imm)
3956 {
3957     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3958     TCGv t0;
3959
3960     if (rt == 0) {
3961         /* If no destination, treat it as a NOP. */
3962         return;
3963     }
3964     t0 = tcg_temp_new();
3965     gen_load_gpr(t0, rs);
3966     switch (opc) {
3967     case OPC_SLTI:
3968         tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
3969         break;
3970     case OPC_SLTIU:
3971         tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
3972         break;
3973     }
3974     tcg_temp_free(t0);
3975 }
3976
3977 /* Shifts with immediate operand */
3978 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
3979                           int rt, int rs, int16_t imm)
3980 {
3981     target_ulong uimm = ((uint16_t)imm) & 0x1f;
3982     TCGv t0;
3983
3984     if (rt == 0) {
3985         /* If no destination, treat it as a NOP. */
3986         return;
3987     }
3988
3989     t0 = tcg_temp_new();
3990     gen_load_gpr(t0, rs);
3991     switch (opc) {
3992     case OPC_SLL:
3993         tcg_gen_shli_tl(t0, t0, uimm);
3994         tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3995         break;
3996     case OPC_SRA:
3997         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
3998         break;
3999     case OPC_SRL:
4000         if (uimm != 0) {
4001             tcg_gen_ext32u_tl(t0, t0);
4002             tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
4003         } else {
4004             tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
4005         }
4006         break;
4007     case OPC_ROTR:
4008         if (uimm != 0) {
4009             TCGv_i32 t1 = tcg_temp_new_i32();
4010
4011             tcg_gen_trunc_tl_i32(t1, t0);
4012             tcg_gen_rotri_i32(t1, t1, uimm);
4013             tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
4014             tcg_temp_free_i32(t1);
4015         } else {
4016             tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
4017         }
4018         break;
4019 #if defined(TARGET_MIPS64)
4020     case OPC_DSLL:
4021         tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
4022         break;
4023     case OPC_DSRA:
4024         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
4025         break;
4026     case OPC_DSRL:
4027         tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
4028         break;
4029     case OPC_DROTR:
4030         if (uimm != 0) {
4031             tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
4032         } else {
4033             tcg_gen_mov_tl(cpu_gpr[rt], t0);
4034         }
4035         break;
4036     case OPC_DSLL32:
4037         tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
4038         break;
4039     case OPC_DSRA32:
4040         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
4041         break;
4042     case OPC_DSRL32:
4043         tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
4044         break;
4045     case OPC_DROTR32:
4046         tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
4047         break;
4048 #endif
4049     }
4050     tcg_temp_free(t0);
4051 }
4052
4053 /* Arithmetic */
4054 static void gen_arith(DisasContext *ctx, uint32_t opc,
4055                       int rd, int rs, int rt)
4056 {
4057     if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
4058        && opc != OPC_DADD && opc != OPC_DSUB) {
4059         /* If no destination, treat it as a NOP.
4060            For add & sub, we must generate the overflow exception when needed. */
4061         return;
4062     }
4063
4064     switch (opc) {
4065     case OPC_ADD:
4066         {
4067             TCGv t0 = tcg_temp_local_new();
4068             TCGv t1 = tcg_temp_new();
4069             TCGv t2 = tcg_temp_new();
4070             TCGLabel *l1 = gen_new_label();
4071
4072             gen_load_gpr(t1, rs);
4073             gen_load_gpr(t2, rt);
4074             tcg_gen_add_tl(t0, t1, t2);
4075             tcg_gen_ext32s_tl(t0, t0);
4076             tcg_gen_xor_tl(t1, t1, t2);
4077             tcg_gen_xor_tl(t2, t0, t2);
4078             tcg_gen_andc_tl(t1, t2, t1);
4079             tcg_temp_free(t2);
4080             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4081             tcg_temp_free(t1);
4082             /* operands of same sign, result different sign */
4083             generate_exception(ctx, EXCP_OVERFLOW);
4084             gen_set_label(l1);
4085             gen_store_gpr(t0, rd);
4086             tcg_temp_free(t0);
4087         }
4088         break;
4089     case OPC_ADDU:
4090         if (rs != 0 && rt != 0) {
4091             tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4092             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4093         } else if (rs == 0 && rt != 0) {
4094             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4095         } else if (rs != 0 && rt == 0) {
4096             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4097         } else {
4098             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4099         }
4100         break;
4101     case OPC_SUB:
4102         {
4103             TCGv t0 = tcg_temp_local_new();
4104             TCGv t1 = tcg_temp_new();
4105             TCGv t2 = tcg_temp_new();
4106             TCGLabel *l1 = gen_new_label();
4107
4108             gen_load_gpr(t1, rs);
4109             gen_load_gpr(t2, rt);
4110             tcg_gen_sub_tl(t0, t1, t2);
4111             tcg_gen_ext32s_tl(t0, t0);
4112             tcg_gen_xor_tl(t2, t1, t2);
4113             tcg_gen_xor_tl(t1, t0, t1);
4114             tcg_gen_and_tl(t1, t1, t2);
4115             tcg_temp_free(t2);
4116             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4117             tcg_temp_free(t1);
4118             /* operands of different sign, first operand and result different sign */
4119             generate_exception(ctx, EXCP_OVERFLOW);
4120             gen_set_label(l1);
4121             gen_store_gpr(t0, rd);
4122             tcg_temp_free(t0);
4123         }
4124         break;
4125     case OPC_SUBU:
4126         if (rs != 0 && rt != 0) {
4127             tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4128             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4129         } else if (rs == 0 && rt != 0) {
4130             tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4131             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4132         } else if (rs != 0 && rt == 0) {
4133             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4134         } else {
4135             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4136         }
4137         break;
4138 #if defined(TARGET_MIPS64)
4139     case OPC_DADD:
4140         {
4141             TCGv t0 = tcg_temp_local_new();
4142             TCGv t1 = tcg_temp_new();
4143             TCGv t2 = tcg_temp_new();
4144             TCGLabel *l1 = gen_new_label();
4145
4146             gen_load_gpr(t1, rs);
4147             gen_load_gpr(t2, rt);
4148             tcg_gen_add_tl(t0, t1, t2);
4149             tcg_gen_xor_tl(t1, t1, t2);
4150             tcg_gen_xor_tl(t2, t0, t2);
4151             tcg_gen_andc_tl(t1, t2, t1);
4152             tcg_temp_free(t2);
4153             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4154             tcg_temp_free(t1);
4155             /* operands of same sign, result different sign */
4156             generate_exception(ctx, EXCP_OVERFLOW);
4157             gen_set_label(l1);
4158             gen_store_gpr(t0, rd);
4159             tcg_temp_free(t0);
4160         }
4161         break;
4162     case OPC_DADDU:
4163         if (rs != 0 && rt != 0) {
4164             tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4165         } else if (rs == 0 && rt != 0) {
4166             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4167         } else if (rs != 0 && rt == 0) {
4168             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4169         } else {
4170             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4171         }
4172         break;
4173     case OPC_DSUB:
4174         {
4175             TCGv t0 = tcg_temp_local_new();
4176             TCGv t1 = tcg_temp_new();
4177             TCGv t2 = tcg_temp_new();
4178             TCGLabel *l1 = gen_new_label();
4179
4180             gen_load_gpr(t1, rs);
4181             gen_load_gpr(t2, rt);
4182             tcg_gen_sub_tl(t0, t1, t2);
4183             tcg_gen_xor_tl(t2, t1, t2);
4184             tcg_gen_xor_tl(t1, t0, t1);
4185             tcg_gen_and_tl(t1, t1, t2);
4186             tcg_temp_free(t2);
4187             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4188             tcg_temp_free(t1);
4189             /* operands of different sign, first operand and result different sign */
4190             generate_exception(ctx, EXCP_OVERFLOW);
4191             gen_set_label(l1);
4192             gen_store_gpr(t0, rd);
4193             tcg_temp_free(t0);
4194         }
4195         break;
4196     case OPC_DSUBU:
4197         if (rs != 0 && rt != 0) {
4198             tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4199         } else if (rs == 0 && rt != 0) {
4200             tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4201         } else if (rs != 0 && rt == 0) {
4202             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4203         } else {
4204             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4205         }
4206         break;
4207 #endif
4208     case OPC_MUL:
4209         if (likely(rs != 0 && rt != 0)) {
4210             tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4211             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4212         } else {
4213             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4214         }
4215         break;
4216     }
4217 }
4218
4219 /* Conditional move */
4220 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
4221                           int rd, int rs, int rt)
4222 {
4223     TCGv t0, t1, t2;
4224
4225     if (rd == 0) {
4226         /* If no destination, treat it as a NOP. */
4227         return;
4228     }
4229
4230     t0 = tcg_temp_new();
4231     gen_load_gpr(t0, rt);
4232     t1 = tcg_const_tl(0);
4233     t2 = tcg_temp_new();
4234     gen_load_gpr(t2, rs);
4235     switch (opc) {
4236     case OPC_MOVN:
4237         tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4238         break;
4239     case OPC_MOVZ:
4240         tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4241         break;
4242     case OPC_SELNEZ:
4243         tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
4244         break;
4245     case OPC_SELEQZ:
4246         tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
4247         break;
4248     }
4249     tcg_temp_free(t2);
4250     tcg_temp_free(t1);
4251     tcg_temp_free(t0);
4252 }
4253
4254 /* Logic */
4255 static void gen_logic(DisasContext *ctx, uint32_t opc,
4256                       int rd, int rs, int rt)
4257 {
4258     if (rd == 0) {
4259         /* If no destination, treat it as a NOP. */
4260         return;
4261     }
4262
4263     switch (opc) {
4264     case OPC_AND:
4265         if (likely(rs != 0 && rt != 0)) {
4266             tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4267         } else {
4268             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4269         }
4270         break;
4271     case OPC_NOR:
4272         if (rs != 0 && rt != 0) {
4273             tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4274         } else if (rs == 0 && rt != 0) {
4275             tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
4276         } else if (rs != 0 && rt == 0) {
4277             tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
4278         } else {
4279             tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
4280         }
4281         break;
4282     case OPC_OR:
4283         if (likely(rs != 0 && rt != 0)) {
4284             tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4285         } else if (rs == 0 && rt != 0) {
4286             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4287         } else if (rs != 0 && rt == 0) {
4288             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4289         } else {
4290             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4291         }
4292         break;
4293     case OPC_XOR:
4294         if (likely(rs != 0 && rt != 0)) {
4295             tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4296         } else if (rs == 0 && rt != 0) {
4297             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4298         } else if (rs != 0 && rt == 0) {
4299             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4300         } else {
4301             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4302         }
4303         break;
4304     }
4305 }
4306
4307 /* Set on lower than */
4308 static void gen_slt(DisasContext *ctx, uint32_t opc,
4309                     int rd, int rs, int rt)
4310 {
4311     TCGv t0, t1;
4312
4313     if (rd == 0) {
4314         /* If no destination, treat it as a NOP. */
4315         return;
4316     }
4317
4318     t0 = tcg_temp_new();
4319     t1 = tcg_temp_new();
4320     gen_load_gpr(t0, rs);
4321     gen_load_gpr(t1, rt);
4322     switch (opc) {
4323     case OPC_SLT:
4324         tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
4325         break;
4326     case OPC_SLTU:
4327         tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
4328         break;
4329     }
4330     tcg_temp_free(t0);
4331     tcg_temp_free(t1);
4332 }
4333
4334 /* Shifts */
4335 static void gen_shift(DisasContext *ctx, uint32_t opc,
4336                       int rd, int rs, int rt)
4337 {
4338     TCGv t0, t1;
4339
4340     if (rd == 0) {
4341         /* If no destination, treat it as a NOP.
4342            For add & sub, we must generate the overflow exception when needed. */
4343         return;
4344     }
4345
4346     t0 = tcg_temp_new();
4347     t1 = tcg_temp_new();
4348     gen_load_gpr(t0, rs);
4349     gen_load_gpr(t1, rt);
4350     switch (opc) {
4351     case OPC_SLLV:
4352         tcg_gen_andi_tl(t0, t0, 0x1f);
4353         tcg_gen_shl_tl(t0, t1, t0);
4354         tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4355         break;
4356     case OPC_SRAV:
4357         tcg_gen_andi_tl(t0, t0, 0x1f);
4358         tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4359         break;
4360     case OPC_SRLV:
4361         tcg_gen_ext32u_tl(t1, t1);
4362         tcg_gen_andi_tl(t0, t0, 0x1f);
4363         tcg_gen_shr_tl(t0, t1, t0);
4364         tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4365         break;
4366     case OPC_ROTRV:
4367         {
4368             TCGv_i32 t2 = tcg_temp_new_i32();
4369             TCGv_i32 t3 = tcg_temp_new_i32();
4370
4371             tcg_gen_trunc_tl_i32(t2, t0);
4372             tcg_gen_trunc_tl_i32(t3, t1);
4373             tcg_gen_andi_i32(t2, t2, 0x1f);
4374             tcg_gen_rotr_i32(t2, t3, t2);
4375             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4376             tcg_temp_free_i32(t2);
4377             tcg_temp_free_i32(t3);
4378         }
4379         break;
4380 #if defined(TARGET_MIPS64)
4381     case OPC_DSLLV:
4382         tcg_gen_andi_tl(t0, t0, 0x3f);
4383         tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
4384         break;
4385     case OPC_DSRAV:
4386         tcg_gen_andi_tl(t0, t0, 0x3f);
4387         tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4388         break;
4389     case OPC_DSRLV:
4390         tcg_gen_andi_tl(t0, t0, 0x3f);
4391         tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
4392         break;
4393     case OPC_DROTRV:
4394         tcg_gen_andi_tl(t0, t0, 0x3f);
4395         tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
4396         break;
4397 #endif
4398     }
4399     tcg_temp_free(t0);
4400     tcg_temp_free(t1);
4401 }
4402
4403 /* Copy GPR to and from TX79 HI1/LO1 register. */
4404 static void gen_HILO1_tx79(DisasContext *ctx, uint32_t opc, int reg)
4405 {
4406     if (reg == 0 && (opc == MMI_OPC_MFHI1 || opc == MMI_OPC_MFLO1)) {
4407         /* Treat as NOP. */
4408         return;
4409     }
4410
4411     switch (opc) {
4412     case MMI_OPC_MFHI1:
4413         tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]);
4414         break;
4415     case MMI_OPC_MFLO1:
4416         tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[1]);
4417         break;
4418     case MMI_OPC_MTHI1:
4419         if (reg != 0) {
4420             tcg_gen_mov_tl(cpu_HI[1], cpu_gpr[reg]);
4421         } else {
4422             tcg_gen_movi_tl(cpu_HI[1], 0);
4423         }
4424         break;
4425     case MMI_OPC_MTLO1:
4426         if (reg != 0) {
4427             tcg_gen_mov_tl(cpu_LO[1], cpu_gpr[reg]);
4428         } else {
4429             tcg_gen_movi_tl(cpu_LO[1], 0);
4430         }
4431         break;
4432     default:
4433         MIPS_INVAL("mfthilo1 TX79");
4434         generate_exception_end(ctx, EXCP_RI);
4435         break;
4436     }
4437 }
4438
4439 /* Arithmetic on HI/LO registers */
4440 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
4441 {
4442     if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
4443         /* Treat as NOP. */
4444         return;
4445     }
4446
4447     if (acc != 0) {
4448         check_dsp(ctx);
4449     }
4450
4451     switch (opc) {
4452     case OPC_MFHI:
4453 #if defined(TARGET_MIPS64)
4454         if (acc != 0) {
4455             tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
4456         } else
4457 #endif
4458         {
4459             tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
4460         }
4461         break;
4462     case OPC_MFLO:
4463 #if defined(TARGET_MIPS64)
4464         if (acc != 0) {
4465             tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
4466         } else
4467 #endif
4468         {
4469             tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
4470         }
4471         break;
4472     case OPC_MTHI:
4473         if (reg != 0) {
4474 #if defined(TARGET_MIPS64)
4475             if (acc != 0) {
4476                 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
4477             } else
4478 #endif
4479             {
4480                 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
4481             }
4482         } else {
4483             tcg_gen_movi_tl(cpu_HI[acc], 0);
4484         }
4485         break;
4486     case OPC_MTLO:
4487         if (reg != 0) {
4488 #if defined(TARGET_MIPS64)
4489             if (acc != 0) {
4490                 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
4491             } else
4492 #endif
4493             {
4494                 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
4495             }
4496         } else {
4497             tcg_gen_movi_tl(cpu_LO[acc], 0);
4498         }
4499         break;
4500     }
4501 }
4502
4503 static inline void gen_r6_ld(target_long addr, int reg, int memidx,
4504                              TCGMemOp memop)
4505 {
4506     TCGv t0 = tcg_const_tl(addr);
4507     tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
4508     gen_store_gpr(t0, reg);
4509     tcg_temp_free(t0);
4510 }
4511
4512 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
4513                              int rs)
4514 {
4515     target_long offset;
4516     target_long addr;
4517
4518     switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
4519     case OPC_ADDIUPC:
4520         if (rs != 0) {
4521             offset = sextract32(ctx->opcode << 2, 0, 21);
4522             addr = addr_add(ctx, pc, offset);
4523             tcg_gen_movi_tl(cpu_gpr[rs], addr);
4524         }
4525         break;
4526     case R6_OPC_LWPC:
4527         offset = sextract32(ctx->opcode << 2, 0, 21);
4528         addr = addr_add(ctx, pc, offset);
4529         gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
4530         break;
4531 #if defined(TARGET_MIPS64)
4532     case OPC_LWUPC:
4533         check_mips_64(ctx);
4534         offset = sextract32(ctx->opcode << 2, 0, 21);
4535         addr = addr_add(ctx, pc, offset);
4536         gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
4537         break;
4538 #endif
4539     default:
4540         switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
4541         case OPC_AUIPC:
4542             if (rs != 0) {
4543                 offset = sextract32(ctx->opcode, 0, 16) << 16;
4544                 addr = addr_add(ctx, pc, offset);
4545                 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4546             }
4547             break;
4548         case OPC_ALUIPC:
4549             if (rs != 0) {
4550                 offset = sextract32(ctx->opcode, 0, 16) << 16;
4551                 addr = ~0xFFFF & addr_add(ctx, pc, offset);
4552                 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4553             }
4554             break;
4555 #if defined(TARGET_MIPS64)
4556         case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
4557         case R6_OPC_LDPC + (1 << 16):
4558         case R6_OPC_LDPC + (2 << 16):
4559         case R6_OPC_LDPC + (3 << 16):
4560             check_mips_64(ctx);
4561             offset = sextract32(ctx->opcode << 3, 0, 21);
4562             addr = addr_add(ctx, (pc & ~0x7), offset);
4563             gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
4564             break;
4565 #endif
4566         default:
4567             MIPS_INVAL("OPC_PCREL");
4568             generate_exception_end(ctx, EXCP_RI);
4569             break;
4570         }
4571         break;
4572     }
4573 }
4574
4575 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
4576 {
4577     TCGv t0, t1;
4578
4579     if (rd == 0) {
4580         /* Treat as NOP. */
4581         return;
4582     }
4583
4584     t0 = tcg_temp_new();
4585     t1 = tcg_temp_new();
4586
4587     gen_load_gpr(t0, rs);
4588     gen_load_gpr(t1, rt);
4589
4590     switch (opc) {
4591     case R6_OPC_DIV:
4592         {
4593             TCGv t2 = tcg_temp_new();
4594             TCGv t3 = tcg_temp_new();
4595             tcg_gen_ext32s_tl(t0, t0);
4596             tcg_gen_ext32s_tl(t1, t1);
4597             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4598             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4599             tcg_gen_and_tl(t2, t2, t3);
4600             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4601             tcg_gen_or_tl(t2, t2, t3);
4602             tcg_gen_movi_tl(t3, 0);
4603             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4604             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4605             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4606             tcg_temp_free(t3);
4607             tcg_temp_free(t2);
4608         }
4609         break;
4610     case R6_OPC_MOD:
4611         {
4612             TCGv t2 = tcg_temp_new();
4613             TCGv t3 = tcg_temp_new();
4614             tcg_gen_ext32s_tl(t0, t0);
4615             tcg_gen_ext32s_tl(t1, t1);
4616             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4617             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4618             tcg_gen_and_tl(t2, t2, t3);
4619             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4620             tcg_gen_or_tl(t2, t2, t3);
4621             tcg_gen_movi_tl(t3, 0);
4622             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4623             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4624             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4625             tcg_temp_free(t3);
4626             tcg_temp_free(t2);
4627         }
4628         break;
4629     case R6_OPC_DIVU:
4630         {
4631             TCGv t2 = tcg_const_tl(0);
4632             TCGv t3 = tcg_const_tl(1);
4633             tcg_gen_ext32u_tl(t0, t0);
4634             tcg_gen_ext32u_tl(t1, t1);
4635             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4636             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4637             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4638             tcg_temp_free(t3);
4639             tcg_temp_free(t2);
4640         }
4641         break;
4642     case R6_OPC_MODU:
4643         {
4644             TCGv t2 = tcg_const_tl(0);
4645             TCGv t3 = tcg_const_tl(1);
4646             tcg_gen_ext32u_tl(t0, t0);
4647             tcg_gen_ext32u_tl(t1, t1);
4648             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4649             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4650             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4651             tcg_temp_free(t3);
4652             tcg_temp_free(t2);
4653         }
4654         break;
4655     case R6_OPC_MUL:
4656         {
4657             TCGv_i32 t2 = tcg_temp_new_i32();
4658             TCGv_i32 t3 = tcg_temp_new_i32();
4659             tcg_gen_trunc_tl_i32(t2, t0);
4660             tcg_gen_trunc_tl_i32(t3, t1);
4661             tcg_gen_mul_i32(t2, t2, t3);
4662             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4663             tcg_temp_free_i32(t2);
4664             tcg_temp_free_i32(t3);
4665         }
4666         break;
4667     case R6_OPC_MUH:
4668         {
4669             TCGv_i32 t2 = tcg_temp_new_i32();
4670             TCGv_i32 t3 = tcg_temp_new_i32();
4671             tcg_gen_trunc_tl_i32(t2, t0);
4672             tcg_gen_trunc_tl_i32(t3, t1);
4673             tcg_gen_muls2_i32(t2, t3, t2, t3);
4674             tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4675             tcg_temp_free_i32(t2);
4676             tcg_temp_free_i32(t3);
4677         }
4678         break;
4679     case R6_OPC_MULU:
4680         {
4681             TCGv_i32 t2 = tcg_temp_new_i32();
4682             TCGv_i32 t3 = tcg_temp_new_i32();
4683             tcg_gen_trunc_tl_i32(t2, t0);
4684             tcg_gen_trunc_tl_i32(t3, t1);
4685             tcg_gen_mul_i32(t2, t2, t3);
4686             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4687             tcg_temp_free_i32(t2);
4688             tcg_temp_free_i32(t3);
4689         }
4690         break;
4691     case R6_OPC_MUHU:
4692         {
4693             TCGv_i32 t2 = tcg_temp_new_i32();
4694             TCGv_i32 t3 = tcg_temp_new_i32();
4695             tcg_gen_trunc_tl_i32(t2, t0);
4696             tcg_gen_trunc_tl_i32(t3, t1);
4697             tcg_gen_mulu2_i32(t2, t3, t2, t3);
4698             tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4699             tcg_temp_free_i32(t2);
4700             tcg_temp_free_i32(t3);
4701         }
4702         break;
4703 #if defined(TARGET_MIPS64)
4704     case R6_OPC_DDIV:
4705         {
4706             TCGv t2 = tcg_temp_new();
4707             TCGv t3 = tcg_temp_new();
4708             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4709             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4710             tcg_gen_and_tl(t2, t2, t3);
4711             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4712             tcg_gen_or_tl(t2, t2, t3);
4713             tcg_gen_movi_tl(t3, 0);
4714             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4715             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4716             tcg_temp_free(t3);
4717             tcg_temp_free(t2);
4718         }
4719         break;
4720     case R6_OPC_DMOD:
4721         {
4722             TCGv t2 = tcg_temp_new();
4723             TCGv t3 = tcg_temp_new();
4724             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4725             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4726             tcg_gen_and_tl(t2, t2, t3);
4727             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4728             tcg_gen_or_tl(t2, t2, t3);
4729             tcg_gen_movi_tl(t3, 0);
4730             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4731             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4732             tcg_temp_free(t3);
4733             tcg_temp_free(t2);
4734         }
4735         break;
4736     case R6_OPC_DDIVU:
4737         {
4738             TCGv t2 = tcg_const_tl(0);
4739             TCGv t3 = tcg_const_tl(1);
4740             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4741             tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
4742             tcg_temp_free(t3);
4743             tcg_temp_free(t2);
4744         }
4745         break;
4746     case R6_OPC_DMODU:
4747         {
4748             TCGv t2 = tcg_const_tl(0);
4749             TCGv t3 = tcg_const_tl(1);
4750             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4751             tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
4752             tcg_temp_free(t3);
4753             tcg_temp_free(t2);
4754         }
4755         break;
4756     case R6_OPC_DMUL:
4757         tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4758         break;
4759     case R6_OPC_DMUH:
4760         {
4761             TCGv t2 = tcg_temp_new();
4762             tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
4763             tcg_temp_free(t2);
4764         }
4765         break;
4766     case R6_OPC_DMULU:
4767         tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4768         break;
4769     case R6_OPC_DMUHU:
4770         {
4771             TCGv t2 = tcg_temp_new();
4772             tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
4773             tcg_temp_free(t2);
4774         }
4775         break;
4776 #endif
4777     default:
4778         MIPS_INVAL("r6 mul/div");
4779         generate_exception_end(ctx, EXCP_RI);
4780         goto out;
4781     }
4782  out:
4783     tcg_temp_free(t0);
4784     tcg_temp_free(t1);
4785 }
4786
4787 static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
4788 {
4789     TCGv t0, t1;
4790
4791     t0 = tcg_temp_new();
4792     t1 = tcg_temp_new();
4793
4794     gen_load_gpr(t0, rs);
4795     gen_load_gpr(t1, rt);
4796
4797     switch (opc) {
4798     case MMI_OPC_DIV1:
4799         {
4800             TCGv t2 = tcg_temp_new();
4801             TCGv t3 = tcg_temp_new();
4802             tcg_gen_ext32s_tl(t0, t0);
4803             tcg_gen_ext32s_tl(t1, t1);
4804             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4805             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4806             tcg_gen_and_tl(t2, t2, t3);
4807             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4808             tcg_gen_or_tl(t2, t2, t3);
4809             tcg_gen_movi_tl(t3, 0);
4810             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4811             tcg_gen_div_tl(cpu_LO[1], t0, t1);
4812             tcg_gen_rem_tl(cpu_HI[1], t0, t1);
4813             tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
4814             tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
4815             tcg_temp_free(t3);
4816             tcg_temp_free(t2);
4817         }
4818         break;
4819     case MMI_OPC_DIVU1:
4820         {
4821             TCGv t2 = tcg_const_tl(0);
4822             TCGv t3 = tcg_const_tl(1);
4823             tcg_gen_ext32u_tl(t0, t0);
4824             tcg_gen_ext32u_tl(t1, t1);
4825             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4826             tcg_gen_divu_tl(cpu_LO[1], t0, t1);
4827             tcg_gen_remu_tl(cpu_HI[1], t0, t1);
4828             tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
4829             tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
4830             tcg_temp_free(t3);
4831             tcg_temp_free(t2);
4832         }
4833         break;
4834     default:
4835         MIPS_INVAL("div1 TX79");
4836         generate_exception_end(ctx, EXCP_RI);
4837         goto out;
4838     }
4839  out:
4840     tcg_temp_free(t0);
4841     tcg_temp_free(t1);
4842 }
4843
4844 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
4845                        int acc, int rs, int rt)
4846 {
4847     TCGv t0, t1;
4848
4849     t0 = tcg_temp_new();
4850     t1 = tcg_temp_new();
4851
4852     gen_load_gpr(t0, rs);
4853     gen_load_gpr(t1, rt);
4854
4855     if (acc != 0) {
4856         check_dsp(ctx);
4857     }
4858
4859     switch (opc) {
4860     case OPC_DIV:
4861         {
4862             TCGv t2 = tcg_temp_new();
4863             TCGv t3 = tcg_temp_new();
4864             tcg_gen_ext32s_tl(t0, t0);
4865             tcg_gen_ext32s_tl(t1, t1);
4866             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4867             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4868             tcg_gen_and_tl(t2, t2, t3);
4869             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4870             tcg_gen_or_tl(t2, t2, t3);
4871             tcg_gen_movi_tl(t3, 0);
4872             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4873             tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4874             tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4875             tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4876             tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4877             tcg_temp_free(t3);
4878             tcg_temp_free(t2);
4879         }
4880         break;
4881     case OPC_DIVU:
4882         {
4883             TCGv t2 = tcg_const_tl(0);
4884             TCGv t3 = tcg_const_tl(1);
4885             tcg_gen_ext32u_tl(t0, t0);
4886             tcg_gen_ext32u_tl(t1, t1);
4887             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4888             tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
4889             tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
4890             tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4891             tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4892             tcg_temp_free(t3);
4893             tcg_temp_free(t2);
4894         }
4895         break;
4896     case OPC_MULT:
4897         {
4898             TCGv_i32 t2 = tcg_temp_new_i32();
4899             TCGv_i32 t3 = tcg_temp_new_i32();
4900             tcg_gen_trunc_tl_i32(t2, t0);
4901             tcg_gen_trunc_tl_i32(t3, t1);
4902             tcg_gen_muls2_i32(t2, t3, t2, t3);
4903             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4904             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4905             tcg_temp_free_i32(t2);
4906             tcg_temp_free_i32(t3);
4907         }
4908         break;
4909     case OPC_MULTU:
4910         {
4911             TCGv_i32 t2 = tcg_temp_new_i32();
4912             TCGv_i32 t3 = tcg_temp_new_i32();
4913             tcg_gen_trunc_tl_i32(t2, t0);
4914             tcg_gen_trunc_tl_i32(t3, t1);
4915             tcg_gen_mulu2_i32(t2, t3, t2, t3);
4916             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4917             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4918             tcg_temp_free_i32(t2);
4919             tcg_temp_free_i32(t3);
4920         }
4921         break;
4922 #if defined(TARGET_MIPS64)
4923     case OPC_DDIV:
4924         {
4925             TCGv t2 = tcg_temp_new();
4926             TCGv t3 = tcg_temp_new();
4927             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4928             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4929             tcg_gen_and_tl(t2, t2, t3);
4930             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4931             tcg_gen_or_tl(t2, t2, t3);
4932             tcg_gen_movi_tl(t3, 0);
4933             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4934             tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4935             tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4936             tcg_temp_free(t3);
4937             tcg_temp_free(t2);
4938         }
4939         break;
4940     case OPC_DDIVU:
4941         {
4942             TCGv t2 = tcg_const_tl(0);
4943             TCGv t3 = tcg_const_tl(1);
4944             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4945             tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
4946             tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
4947             tcg_temp_free(t3);
4948             tcg_temp_free(t2);
4949         }
4950         break;
4951     case OPC_DMULT:
4952         tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
4953         break;
4954     case OPC_DMULTU:
4955         tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
4956         break;
4957 #endif
4958     case OPC_MADD:
4959         {
4960             TCGv_i64 t2 = tcg_temp_new_i64();
4961             TCGv_i64 t3 = tcg_temp_new_i64();
4962
4963             tcg_gen_ext_tl_i64(t2, t0);
4964             tcg_gen_ext_tl_i64(t3, t1);
4965             tcg_gen_mul_i64(t2, t2, t3);
4966             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4967             tcg_gen_add_i64(t2, t2, t3);
4968             tcg_temp_free_i64(t3);
4969             gen_move_low32(cpu_LO[acc], t2);
4970             gen_move_high32(cpu_HI[acc], t2);
4971             tcg_temp_free_i64(t2);
4972         }
4973         break;
4974     case OPC_MADDU:
4975         {
4976             TCGv_i64 t2 = tcg_temp_new_i64();
4977             TCGv_i64 t3 = tcg_temp_new_i64();
4978
4979             tcg_gen_ext32u_tl(t0, t0);
4980             tcg_gen_ext32u_tl(t1, t1);
4981             tcg_gen_extu_tl_i64(t2, t0);
4982             tcg_gen_extu_tl_i64(t3, t1);
4983             tcg_gen_mul_i64(t2, t2, t3);
4984             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4985             tcg_gen_add_i64(t2, t2, t3);
4986             tcg_temp_free_i64(t3);
4987             gen_move_low32(cpu_LO[acc], t2);
4988             gen_move_high32(cpu_HI[acc], t2);
4989             tcg_temp_free_i64(t2);
4990         }
4991         break;
4992     case OPC_MSUB:
4993         {
4994             TCGv_i64 t2 = tcg_temp_new_i64();
4995             TCGv_i64 t3 = tcg_temp_new_i64();
4996
4997             tcg_gen_ext_tl_i64(t2, t0);
4998             tcg_gen_ext_tl_i64(t3, t1);
4999             tcg_gen_mul_i64(t2, t2, t3);
5000             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5001             tcg_gen_sub_i64(t2, t3, t2);
5002             tcg_temp_free_i64(t3);
5003             gen_move_low32(cpu_LO[acc], t2);
5004             gen_move_high32(cpu_HI[acc], t2);
5005             tcg_temp_free_i64(t2);
5006         }
5007         break;
5008     case OPC_MSUBU:
5009         {
5010             TCGv_i64 t2 = tcg_temp_new_i64();
5011             TCGv_i64 t3 = tcg_temp_new_i64();
5012
5013             tcg_gen_ext32u_tl(t0, t0);
5014             tcg_gen_ext32u_tl(t1, t1);
5015             tcg_gen_extu_tl_i64(t2, t0);
5016             tcg_gen_extu_tl_i64(t3, t1);
5017             tcg_gen_mul_i64(t2, t2, t3);
5018             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5019             tcg_gen_sub_i64(t2, t3, t2);
5020             tcg_temp_free_i64(t3);
5021             gen_move_low32(cpu_LO[acc], t2);
5022             gen_move_high32(cpu_HI[acc], t2);
5023             tcg_temp_free_i64(t2);
5024         }
5025         break;
5026     default:
5027         MIPS_INVAL("mul/div");
5028         generate_exception_end(ctx, EXCP_RI);
5029         goto out;
5030     }
5031  out:
5032     tcg_temp_free(t0);
5033     tcg_temp_free(t1);
5034 }
5035
5036 /*
5037  * These MULT[U] and MADD[U] instructions implemented in for example
5038  * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
5039  * architectures are special three-operand variants with the syntax
5040  *
5041  *     MULT[U][1] rd, rs, rt
5042  *
5043  * such that
5044  *
5045  *     (rd, LO, HI) <- rs * rt
5046  *
5047  * and
5048  *
5049  *     MADD[U][1] rd, rs, rt
5050  *
5051  * such that
5052  *
5053  *     (rd, LO, HI) <- (LO, HI) + rs * rt
5054  *
5055  * where the low-order 32-bits of the result is placed into both the
5056  * GPR rd and the special register LO. The high-order 32-bits of the
5057  * result is placed into the special register HI.
5058  *
5059  * If the GPR rd is omitted in assembly language, it is taken to be 0,
5060  * which is the zero register that always reads as 0.
5061  */
5062 static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
5063                          int rd, int rs, int rt)
5064 {
5065     TCGv t0 = tcg_temp_new();
5066     TCGv t1 = tcg_temp_new();
5067     int acc = 0;
5068
5069     gen_load_gpr(t0, rs);
5070     gen_load_gpr(t1, rt);
5071
5072     switch (opc) {
5073     case MMI_OPC_MULT1:
5074         acc = 1;
5075         /* Fall through */
5076     case OPC_MULT:
5077         {
5078             TCGv_i32 t2 = tcg_temp_new_i32();
5079             TCGv_i32 t3 = tcg_temp_new_i32();
5080             tcg_gen_trunc_tl_i32(t2, t0);
5081             tcg_gen_trunc_tl_i32(t3, t1);
5082             tcg_gen_muls2_i32(t2, t3, t2, t3);
5083             if (rd) {
5084                 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
5085             }
5086             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
5087             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
5088             tcg_temp_free_i32(t2);
5089             tcg_temp_free_i32(t3);
5090         }
5091         break;
5092     case MMI_OPC_MULTU1:
5093         acc = 1;
5094         /* Fall through */
5095     case OPC_MULTU:
5096         {
5097             TCGv_i32 t2 = tcg_temp_new_i32();
5098             TCGv_i32 t3 = tcg_temp_new_i32();
5099             tcg_gen_trunc_tl_i32(t2, t0);
5100             tcg_gen_trunc_tl_i32(t3, t1);
5101             tcg_gen_mulu2_i32(t2, t3, t2, t3);
5102             if (rd) {
5103                 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
5104             }
5105             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
5106             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
5107             tcg_temp_free_i32(t2);
5108             tcg_temp_free_i32(t3);
5109         }
5110         break;
5111     case MMI_OPC_MADD1:
5112         acc = 1;
5113         /* Fall through */
5114     case MMI_OPC_MADD:
5115         {
5116             TCGv_i64 t2 = tcg_temp_new_i64();
5117             TCGv_i64 t3 = tcg_temp_new_i64();
5118
5119             tcg_gen_ext_tl_i64(t2, t0);
5120             tcg_gen_ext_tl_i64(t3, t1);
5121             tcg_gen_mul_i64(t2, t2, t3);
5122             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5123             tcg_gen_add_i64(t2, t2, t3);
5124             tcg_temp_free_i64(t3);
5125             gen_move_low32(cpu_LO[acc], t2);
5126             gen_move_high32(cpu_HI[acc], t2);
5127             if (rd) {
5128                 gen_move_low32(cpu_gpr[rd], t2);
5129             }
5130             tcg_temp_free_i64(t2);
5131         }
5132         break;
5133     case MMI_OPC_MADDU1:
5134         acc = 1;
5135         /* Fall through */
5136     case MMI_OPC_MADDU:
5137         {
5138             TCGv_i64 t2 = tcg_temp_new_i64();
5139             TCGv_i64 t3 = tcg_temp_new_i64();
5140
5141             tcg_gen_ext32u_tl(t0, t0);
5142             tcg_gen_ext32u_tl(t1, t1);
5143             tcg_gen_extu_tl_i64(t2, t0);
5144             tcg_gen_extu_tl_i64(t3, t1);
5145             tcg_gen_mul_i64(t2, t2, t3);
5146             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5147             tcg_gen_add_i64(t2, t2, t3);
5148             tcg_temp_free_i64(t3);
5149             gen_move_low32(cpu_LO[acc], t2);
5150             gen_move_high32(cpu_HI[acc], t2);
5151             if (rd) {
5152                 gen_move_low32(cpu_gpr[rd], t2);
5153             }
5154             tcg_temp_free_i64(t2);
5155         }
5156         break;
5157     default:
5158         MIPS_INVAL("mul/madd TXx9");
5159         generate_exception_end(ctx, EXCP_RI);
5160         goto out;
5161     }
5162
5163  out:
5164     tcg_temp_free(t0);
5165     tcg_temp_free(t1);
5166 }
5167
5168 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
5169                             int rd, int rs, int rt)
5170 {
5171     TCGv t0 = tcg_temp_new();
5172     TCGv t1 = tcg_temp_new();
5173
5174     gen_load_gpr(t0, rs);
5175     gen_load_gpr(t1, rt);
5176
5177     switch (opc) {
5178     case OPC_VR54XX_MULS:
5179         gen_helper_muls(t0, cpu_env, t0, t1);
5180         break;
5181     case OPC_VR54XX_MULSU:
5182         gen_helper_mulsu(t0, cpu_env, t0, t1);
5183         break;
5184     case OPC_VR54XX_MACC:
5185         gen_helper_macc(t0, cpu_env, t0, t1);
5186         break;
5187     case OPC_VR54XX_MACCU:
5188         gen_helper_maccu(t0, cpu_env, t0, t1);
5189         break;
5190     case OPC_VR54XX_MSAC:
5191         gen_helper_msac(t0, cpu_env, t0, t1);
5192         break;
5193     case OPC_VR54XX_MSACU:
5194         gen_helper_msacu(t0, cpu_env, t0, t1);
5195         break;
5196     case OPC_VR54XX_MULHI:
5197         gen_helper_mulhi(t0, cpu_env, t0, t1);
5198         break;
5199     case OPC_VR54XX_MULHIU:
5200         gen_helper_mulhiu(t0, cpu_env, t0, t1);
5201         break;
5202     case OPC_VR54XX_MULSHI:
5203         gen_helper_mulshi(t0, cpu_env, t0, t1);
5204         break;
5205     case OPC_VR54XX_MULSHIU:
5206         gen_helper_mulshiu(t0, cpu_env, t0, t1);
5207         break;
5208     case OPC_VR54XX_MACCHI:
5209         gen_helper_macchi(t0, cpu_env, t0, t1);
5210         break;
5211     case OPC_VR54XX_MACCHIU:
5212         gen_helper_macchiu(t0, cpu_env, t0, t1);
5213         break;
5214     case OPC_VR54XX_MSACHI:
5215         gen_helper_msachi(t0, cpu_env, t0, t1);
5216         break;
5217     case OPC_VR54XX_MSACHIU:
5218         gen_helper_msachiu(t0, cpu_env, t0, t1);
5219         break;
5220     default:
5221         MIPS_INVAL("mul vr54xx");
5222         generate_exception_end(ctx, EXCP_RI);
5223         goto out;
5224     }
5225     gen_store_gpr(t0, rd);
5226
5227  out:
5228     tcg_temp_free(t0);
5229     tcg_temp_free(t1);
5230 }
5231
5232 static void gen_cl (DisasContext *ctx, uint32_t opc,
5233                     int rd, int rs)
5234 {
5235     TCGv t0;
5236
5237     if (rd == 0) {
5238         /* Treat as NOP. */
5239         return;
5240     }
5241     t0 = cpu_gpr[rd];
5242     gen_load_gpr(t0, rs);
5243
5244     switch (opc) {
5245     case OPC_CLO:
5246     case R6_OPC_CLO:
5247 #if defined(TARGET_MIPS64)
5248     case OPC_DCLO:
5249     case R6_OPC_DCLO:
5250 #endif
5251         tcg_gen_not_tl(t0, t0);
5252         break;
5253     }
5254
5255     switch (opc) {
5256     case OPC_CLO:
5257     case R6_OPC_CLO:
5258     case OPC_CLZ:
5259     case R6_OPC_CLZ:
5260         tcg_gen_ext32u_tl(t0, t0);
5261         tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
5262         tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
5263         break;
5264 #if defined(TARGET_MIPS64)
5265     case OPC_DCLO:
5266     case R6_OPC_DCLO:
5267     case OPC_DCLZ:
5268     case R6_OPC_DCLZ:
5269         tcg_gen_clzi_i64(t0, t0, 64);
5270         break;
5271 #endif
5272     }
5273 }
5274
5275 /* Godson integer instructions */
5276 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
5277                                  int rd, int rs, int rt)
5278 {
5279     TCGv t0, t1;
5280
5281     if (rd == 0) {
5282         /* Treat as NOP. */
5283         return;
5284     }
5285
5286     switch (opc) {
5287     case OPC_MULT_G_2E:
5288     case OPC_MULT_G_2F:
5289     case OPC_MULTU_G_2E:
5290     case OPC_MULTU_G_2F:
5291 #if defined(TARGET_MIPS64)
5292     case OPC_DMULT_G_2E:
5293     case OPC_DMULT_G_2F:
5294     case OPC_DMULTU_G_2E:
5295     case OPC_DMULTU_G_2F:
5296 #endif
5297         t0 = tcg_temp_new();
5298         t1 = tcg_temp_new();
5299         break;
5300     default:
5301         t0 = tcg_temp_local_new();
5302         t1 = tcg_temp_local_new();
5303         break;
5304     }
5305
5306     gen_load_gpr(t0, rs);
5307     gen_load_gpr(t1, rt);
5308
5309     switch (opc) {
5310     case OPC_MULT_G_2E:
5311     case OPC_MULT_G_2F:
5312         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5313         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5314         break;
5315     case OPC_MULTU_G_2E:
5316     case OPC_MULTU_G_2F:
5317         tcg_gen_ext32u_tl(t0, t0);
5318         tcg_gen_ext32u_tl(t1, t1);
5319         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5320         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5321         break;
5322     case OPC_DIV_G_2E:
5323     case OPC_DIV_G_2F:
5324         {
5325             TCGLabel *l1 = gen_new_label();
5326             TCGLabel *l2 = gen_new_label();
5327             TCGLabel *l3 = gen_new_label();
5328             tcg_gen_ext32s_tl(t0, t0);
5329             tcg_gen_ext32s_tl(t1, t1);
5330             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5331             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5332             tcg_gen_br(l3);
5333             gen_set_label(l1);
5334             tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5335             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5336             tcg_gen_mov_tl(cpu_gpr[rd], t0);
5337             tcg_gen_br(l3);
5338             gen_set_label(l2);
5339             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5340             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5341             gen_set_label(l3);
5342         }
5343         break;
5344     case OPC_DIVU_G_2E:
5345     case OPC_DIVU_G_2F:
5346         {
5347             TCGLabel *l1 = gen_new_label();
5348             TCGLabel *l2 = gen_new_label();
5349             tcg_gen_ext32u_tl(t0, t0);
5350             tcg_gen_ext32u_tl(t1, t1);
5351             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5352             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5353             tcg_gen_br(l2);
5354             gen_set_label(l1);
5355             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5356             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5357             gen_set_label(l2);
5358         }
5359         break;
5360     case OPC_MOD_G_2E:
5361     case OPC_MOD_G_2F:
5362         {
5363             TCGLabel *l1 = gen_new_label();
5364             TCGLabel *l2 = gen_new_label();
5365             TCGLabel *l3 = gen_new_label();
5366             tcg_gen_ext32u_tl(t0, t0);
5367             tcg_gen_ext32u_tl(t1, t1);
5368             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5369             tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5370             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5371             gen_set_label(l1);
5372             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5373             tcg_gen_br(l3);
5374             gen_set_label(l2);
5375             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5376             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5377             gen_set_label(l3);
5378         }
5379         break;
5380     case OPC_MODU_G_2E:
5381     case OPC_MODU_G_2F:
5382         {
5383             TCGLabel *l1 = gen_new_label();
5384             TCGLabel *l2 = gen_new_label();
5385             tcg_gen_ext32u_tl(t0, t0);
5386             tcg_gen_ext32u_tl(t1, t1);
5387             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5388             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5389             tcg_gen_br(l2);
5390             gen_set_label(l1);
5391             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5392             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5393             gen_set_label(l2);
5394         }
5395         break;
5396 #if defined(TARGET_MIPS64)
5397     case OPC_DMULT_G_2E:
5398     case OPC_DMULT_G_2F:
5399         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5400         break;
5401     case OPC_DMULTU_G_2E:
5402     case OPC_DMULTU_G_2F:
5403         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5404         break;
5405     case OPC_DDIV_G_2E:
5406     case OPC_DDIV_G_2F:
5407         {
5408             TCGLabel *l1 = gen_new_label();
5409             TCGLabel *l2 = gen_new_label();
5410             TCGLabel *l3 = gen_new_label();
5411             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5412             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5413             tcg_gen_br(l3);
5414             gen_set_label(l1);
5415             tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5416             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5417             tcg_gen_mov_tl(cpu_gpr[rd], t0);
5418             tcg_gen_br(l3);
5419             gen_set_label(l2);
5420             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5421             gen_set_label(l3);
5422         }
5423         break;
5424     case OPC_DDIVU_G_2E:
5425     case OPC_DDIVU_G_2F:
5426         {
5427             TCGLabel *l1 = gen_new_label();
5428             TCGLabel *l2 = gen_new_label();
5429             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5430             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5431             tcg_gen_br(l2);
5432             gen_set_label(l1);
5433             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5434             gen_set_label(l2);
5435         }
5436         break;
5437     case OPC_DMOD_G_2E:
5438     case OPC_DMOD_G_2F:
5439         {
5440             TCGLabel *l1 = gen_new_label();
5441             TCGLabel *l2 = gen_new_label();
5442             TCGLabel *l3 = gen_new_label();
5443             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5444             tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5445             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5446             gen_set_label(l1);
5447             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5448             tcg_gen_br(l3);
5449             gen_set_label(l2);
5450             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5451             gen_set_label(l3);
5452         }
5453         break;
5454     case OPC_DMODU_G_2E:
5455     case OPC_DMODU_G_2F:
5456         {
5457             TCGLabel *l1 = gen_new_label();
5458             TCGLabel *l2 = gen_new_label();
5459             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5460             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5461             tcg_gen_br(l2);
5462             gen_set_label(l1);
5463             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5464             gen_set_label(l2);
5465         }
5466         break;
5467 #endif
5468     }
5469
5470     tcg_temp_free(t0);
5471     tcg_temp_free(t1);
5472 }
5473
5474 /* Loongson multimedia instructions */
5475 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
5476 {
5477     uint32_t opc, shift_max;
5478     TCGv_i64 t0, t1;
5479
5480     opc = MASK_LMI(ctx->opcode);
5481     switch (opc) {
5482     case OPC_ADD_CP2:
5483     case OPC_SUB_CP2:
5484     case OPC_DADD_CP2:
5485     case OPC_DSUB_CP2:
5486         t0 = tcg_temp_local_new_i64();
5487         t1 = tcg_temp_local_new_i64();
5488         break;
5489     default:
5490         t0 = tcg_temp_new_i64();
5491         t1 = tcg_temp_new_i64();
5492         break;
5493     }
5494
5495     check_cp1_enabled(ctx);
5496     gen_load_fpr64(ctx, t0, rs);
5497     gen_load_fpr64(ctx, t1, rt);
5498
5499 #define LMI_HELPER(UP, LO) \
5500     case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
5501 #define LMI_HELPER_1(UP, LO) \
5502     case OPC_##UP: gen_helper_##LO(t0, t0); break
5503 #define LMI_DIRECT(UP, LO, OP) \
5504     case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
5505
5506     switch (opc) {
5507     LMI_HELPER(PADDSH, paddsh);
5508     LMI_HELPER(PADDUSH, paddush);
5509     LMI_HELPER(PADDH, paddh);
5510     LMI_HELPER(PADDW, paddw);
5511     LMI_HELPER(PADDSB, paddsb);
5512     LMI_HELPER(PADDUSB, paddusb);
5513     LMI_HELPER(PADDB, paddb);
5514
5515     LMI_HELPER(PSUBSH, psubsh);
5516     LMI_HELPER(PSUBUSH, psubush);
5517     LMI_HELPER(PSUBH, psubh);
5518     LMI_HELPER(PSUBW, psubw);
5519     LMI_HELPER(PSUBSB, psubsb);
5520     LMI_HELPER(PSUBUSB, psubusb);
5521     LMI_HELPER(PSUBB, psubb);
5522
5523     LMI_HELPER(PSHUFH, pshufh);
5524     LMI_HELPER(PACKSSWH, packsswh);
5525     LMI_HELPER(PACKSSHB, packsshb);
5526     LMI_HELPER(PACKUSHB, packushb);
5527
5528     LMI_HELPER(PUNPCKLHW, punpcklhw);
5529     LMI_HELPER(PUNPCKHHW, punpckhhw);
5530     LMI_HELPER(PUNPCKLBH, punpcklbh);
5531     LMI_HELPER(PUNPCKHBH, punpckhbh);
5532     LMI_HELPER(PUNPCKLWD, punpcklwd);
5533     LMI_HELPER(PUNPCKHWD, punpckhwd);
5534
5535     LMI_HELPER(PAVGH, pavgh);
5536     LMI_HELPER(PAVGB, pavgb);
5537     LMI_HELPER(PMAXSH, pmaxsh);
5538     LMI_HELPER(PMINSH, pminsh);
5539     LMI_HELPER(PMAXUB, pmaxub);
5540     LMI_HELPER(PMINUB, pminub);
5541
5542     LMI_HELPER(PCMPEQW, pcmpeqw);
5543     LMI_HELPER(PCMPGTW, pcmpgtw);
5544     LMI_HELPER(PCMPEQH, pcmpeqh);
5545     LMI_HELPER(PCMPGTH, pcmpgth);
5546     LMI_HELPER(PCMPEQB, pcmpeqb);
5547     LMI_HELPER(PCMPGTB, pcmpgtb);
5548
5549     LMI_HELPER(PSLLW, psllw);
5550     LMI_HELPER(PSLLH, psllh);
5551     LMI_HELPER(PSRLW, psrlw);
5552     LMI_HELPER(PSRLH, psrlh);
5553     LMI_HELPER(PSRAW, psraw);
5554     LMI_HELPER(PSRAH, psrah);
5555
5556     LMI_HELPER(PMULLH, pmullh);
5557     LMI_HELPER(PMULHH, pmulhh);
5558     LMI_HELPER(PMULHUH, pmulhuh);
5559     LMI_HELPER(PMADDHW, pmaddhw);
5560
5561     LMI_HELPER(PASUBUB, pasubub);
5562     LMI_HELPER_1(BIADD, biadd);
5563     LMI_HELPER_1(PMOVMSKB, pmovmskb);
5564
5565     LMI_DIRECT(PADDD, paddd, add);
5566     LMI_DIRECT(PSUBD, psubd, sub);
5567     LMI_DIRECT(XOR_CP2, xor, xor);
5568     LMI_DIRECT(NOR_CP2, nor, nor);
5569     LMI_DIRECT(AND_CP2, and, and);
5570     LMI_DIRECT(OR_CP2, or, or);
5571
5572     case OPC_PANDN:
5573         tcg_gen_andc_i64(t0, t1, t0);
5574         break;
5575
5576     case OPC_PINSRH_0:
5577         tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
5578         break;
5579     case OPC_PINSRH_1:
5580         tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
5581         break;
5582     case OPC_PINSRH_2:
5583         tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
5584         break;
5585     case OPC_PINSRH_3:
5586         tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
5587         break;
5588
5589     case OPC_PEXTRH:
5590         tcg_gen_andi_i64(t1, t1, 3);
5591         tcg_gen_shli_i64(t1, t1, 4);
5592         tcg_gen_shr_i64(t0, t0, t1);
5593         tcg_gen_ext16u_i64(t0, t0);
5594         break;
5595
5596     case OPC_ADDU_CP2:
5597         tcg_gen_add_i64(t0, t0, t1);
5598         tcg_gen_ext32s_i64(t0, t0);
5599         break;
5600     case OPC_SUBU_CP2:
5601         tcg_gen_sub_i64(t0, t0, t1);
5602         tcg_gen_ext32s_i64(t0, t0);
5603         break;
5604
5605     case OPC_SLL_CP2:
5606         shift_max = 32;
5607         goto do_shift;
5608     case OPC_SRL_CP2:
5609         shift_max = 32;
5610         goto do_shift;
5611     case OPC_SRA_CP2:
5612         shift_max = 32;
5613         goto do_shift;
5614     case OPC_DSLL_CP2:
5615         shift_max = 64;
5616         goto do_shift;
5617     case OPC_DSRL_CP2:
5618         shift_max = 64;
5619         goto do_shift;
5620     case OPC_DSRA_CP2:
5621         shift_max = 64;
5622         goto do_shift;
5623     do_shift:
5624         /* Make sure shift count isn't TCG undefined behaviour.  */
5625         tcg_gen_andi_i64(t1, t1, shift_max - 1);
5626
5627         switch (opc) {
5628         case OPC_SLL_CP2:
5629         case OPC_DSLL_CP2:
5630             tcg_gen_shl_i64(t0, t0, t1);
5631             break;
5632         case OPC_SRA_CP2:
5633         case OPC_DSRA_CP2:
5634             /* Since SRA is UndefinedResult without sign-extended inputs,
5635                we can treat SRA and DSRA the same.  */
5636             tcg_gen_sar_i64(t0, t0, t1);
5637             break;
5638         case OPC_SRL_CP2:
5639             /* We want to shift in zeros for SRL; zero-extend first.  */
5640             tcg_gen_ext32u_i64(t0, t0);
5641             /* FALLTHRU */
5642         case OPC_DSRL_CP2:
5643             tcg_gen_shr_i64(t0, t0, t1);
5644             break;
5645         }
5646
5647         if (shift_max == 32) {
5648             tcg_gen_ext32s_i64(t0, t0);
5649         }
5650
5651         /* Shifts larger than MAX produce zero.  */
5652         tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
5653         tcg_gen_neg_i64(t1, t1);
5654         tcg_gen_and_i64(t0, t0, t1);
5655         break;
5656
5657     case OPC_ADD_CP2:
5658     case OPC_DADD_CP2:
5659         {
5660             TCGv_i64 t2 = tcg_temp_new_i64();
5661             TCGLabel *lab = gen_new_label();
5662
5663             tcg_gen_mov_i64(t2, t0);
5664             tcg_gen_add_i64(t0, t1, t2);
5665             if (opc == OPC_ADD_CP2) {
5666                 tcg_gen_ext32s_i64(t0, t0);
5667             }
5668             tcg_gen_xor_i64(t1, t1, t2);
5669             tcg_gen_xor_i64(t2, t2, t0);
5670             tcg_gen_andc_i64(t1, t2, t1);
5671             tcg_temp_free_i64(t2);
5672             tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5673             generate_exception(ctx, EXCP_OVERFLOW);
5674             gen_set_label(lab);
5675             break;
5676         }
5677
5678     case OPC_SUB_CP2:
5679     case OPC_DSUB_CP2:
5680         {
5681             TCGv_i64 t2 = tcg_temp_new_i64();
5682             TCGLabel *lab = gen_new_label();
5683
5684             tcg_gen_mov_i64(t2, t0);
5685             tcg_gen_sub_i64(t0, t1, t2);
5686             if (opc == OPC_SUB_CP2) {
5687                 tcg_gen_ext32s_i64(t0, t0);
5688             }
5689             tcg_gen_xor_i64(t1, t1, t2);
5690             tcg_gen_xor_i64(t2, t2, t0);
5691             tcg_gen_and_i64(t1, t1, t2);
5692             tcg_temp_free_i64(t2);
5693             tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5694             generate_exception(ctx, EXCP_OVERFLOW);
5695             gen_set_label(lab);
5696             break;
5697         }
5698
5699     case OPC_PMULUW:
5700         tcg_gen_ext32u_i64(t0, t0);
5701         tcg_gen_ext32u_i64(t1, t1);
5702         tcg_gen_mul_i64(t0, t0, t1);
5703         break;
5704
5705     case OPC_SEQU_CP2:
5706     case OPC_SEQ_CP2:
5707     case OPC_SLTU_CP2:
5708     case OPC_SLT_CP2:
5709     case OPC_SLEU_CP2:
5710     case OPC_SLE_CP2:
5711         /* ??? Document is unclear: Set FCC[CC].  Does that mean the
5712            FD field is the CC field?  */
5713     default:
5714         MIPS_INVAL("loongson_cp2");
5715         generate_exception_end(ctx, EXCP_RI);
5716         return;
5717     }
5718
5719 #undef LMI_HELPER
5720 #undef LMI_DIRECT
5721
5722     gen_store_fpr64(ctx, t0, rd);
5723
5724     tcg_temp_free_i64(t0);
5725     tcg_temp_free_i64(t1);
5726 }
5727
5728 /* Traps */
5729 static void gen_trap (DisasContext *ctx, uint32_t opc,
5730                       int rs, int rt, int16_t imm)
5731 {
5732     int cond;
5733     TCGv t0 = tcg_temp_new();
5734     TCGv t1 = tcg_temp_new();
5735
5736     cond = 0;
5737     /* Load needed operands */
5738     switch (opc) {
5739     case OPC_TEQ:
5740     case OPC_TGE:
5741     case OPC_TGEU:
5742     case OPC_TLT:
5743     case OPC_TLTU:
5744     case OPC_TNE:
5745         /* Compare two registers */
5746         if (rs != rt) {
5747             gen_load_gpr(t0, rs);
5748             gen_load_gpr(t1, rt);
5749             cond = 1;
5750         }
5751         break;
5752     case OPC_TEQI:
5753     case OPC_TGEI:
5754     case OPC_TGEIU:
5755     case OPC_TLTI:
5756     case OPC_TLTIU:
5757     case OPC_TNEI:
5758         /* Compare register to immediate */
5759         if (rs != 0 || imm != 0) {
5760             gen_load_gpr(t0, rs);
5761             tcg_gen_movi_tl(t1, (int32_t)imm);
5762             cond = 1;
5763         }
5764         break;
5765     }
5766     if (cond == 0) {
5767         switch (opc) {
5768         case OPC_TEQ:   /* rs == rs */
5769         case OPC_TEQI:  /* r0 == 0  */
5770         case OPC_TGE:   /* rs >= rs */
5771         case OPC_TGEI:  /* r0 >= 0  */
5772         case OPC_TGEU:  /* rs >= rs unsigned */
5773         case OPC_TGEIU: /* r0 >= 0  unsigned */
5774             /* Always trap */
5775             generate_exception_end(ctx, EXCP_TRAP);
5776             break;
5777         case OPC_TLT:   /* rs < rs           */
5778         case OPC_TLTI:  /* r0 < 0            */
5779         case OPC_TLTU:  /* rs < rs unsigned  */
5780         case OPC_TLTIU: /* r0 < 0  unsigned  */
5781         case OPC_TNE:   /* rs != rs          */
5782         case OPC_TNEI:  /* r0 != 0           */
5783             /* Never trap: treat as NOP. */
5784             break;
5785         }
5786     } else {
5787         TCGLabel *l1 = gen_new_label();
5788
5789         switch (opc) {
5790         case OPC_TEQ:
5791         case OPC_TEQI:
5792             tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
5793             break;
5794         case OPC_TGE:
5795         case OPC_TGEI:
5796             tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
5797             break;
5798         case OPC_TGEU:
5799         case OPC_TGEIU:
5800             tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
5801             break;
5802         case OPC_TLT:
5803         case OPC_TLTI:
5804             tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
5805             break;
5806         case OPC_TLTU:
5807         case OPC_TLTIU:
5808             tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
5809             break;
5810         case OPC_TNE:
5811         case OPC_TNEI:
5812             tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
5813             break;
5814         }
5815         generate_exception(ctx, EXCP_TRAP);
5816         gen_set_label(l1);
5817     }
5818     tcg_temp_free(t0);
5819     tcg_temp_free(t1);
5820 }
5821
5822 static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
5823 {
5824     if (unlikely(ctx->base.singlestep_enabled)) {
5825         return false;
5826     }
5827
5828 #ifndef CONFIG_USER_ONLY
5829     return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
5830 #else
5831     return true;
5832 #endif
5833 }
5834
5835 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
5836 {
5837     if (use_goto_tb(ctx, dest)) {
5838         tcg_gen_goto_tb(n);
5839         gen_save_pc(dest);
5840         tcg_gen_exit_tb(ctx->base.tb, n);
5841     } else {
5842         gen_save_pc(dest);
5843         if (ctx->base.singlestep_enabled) {
5844             save_cpu_state(ctx, 0);
5845             gen_helper_raise_exception_debug(cpu_env);
5846         }
5847         tcg_gen_lookup_and_goto_ptr();
5848     }
5849 }
5850
5851 /* Branches (before delay slot) */
5852 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
5853                                 int insn_bytes,
5854                                 int rs, int rt, int32_t offset,
5855                                 int delayslot_size)
5856 {
5857     target_ulong btgt = -1;
5858     int blink = 0;
5859     int bcond_compute = 0;
5860     TCGv t0 = tcg_temp_new();
5861     TCGv t1 = tcg_temp_new();
5862
5863     if (ctx->hflags & MIPS_HFLAG_BMASK) {
5864 #ifdef MIPS_DEBUG_DISAS
5865         LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
5866                   TARGET_FMT_lx "\n", ctx->base.pc_next);
5867 #endif
5868         generate_exception_end(ctx, EXCP_RI);
5869         goto out;
5870     }
5871
5872     /* Load needed operands */
5873     switch (opc) {
5874     case OPC_BEQ:
5875     case OPC_BEQL:
5876     case OPC_BNE:
5877     case OPC_BNEL:
5878         /* Compare two registers */
5879         if (rs != rt) {
5880             gen_load_gpr(t0, rs);
5881             gen_load_gpr(t1, rt);
5882             bcond_compute = 1;
5883         }
5884         btgt = ctx->base.pc_next + insn_bytes + offset;
5885         break;
5886     case OPC_BGEZ:
5887     case OPC_BGEZAL:
5888     case OPC_BGEZALL:
5889     case OPC_BGEZL:
5890     case OPC_BGTZ:
5891     case OPC_BGTZL:
5892     case OPC_BLEZ:
5893     case OPC_BLEZL:
5894     case OPC_BLTZ:
5895     case OPC_BLTZAL:
5896     case OPC_BLTZALL:
5897     case OPC_BLTZL:
5898         /* Compare to zero */
5899         if (rs != 0) {
5900             gen_load_gpr(t0, rs);
5901             bcond_compute = 1;
5902         }
5903         btgt = ctx->base.pc_next + insn_bytes + offset;
5904         break;
5905     case OPC_BPOSGE32:
5906 #if defined(TARGET_MIPS64)
5907     case OPC_BPOSGE64:
5908         tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
5909 #else
5910         tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5911 #endif
5912         bcond_compute = 1;
5913         btgt = ctx->base.pc_next + insn_bytes + offset;
5914         break;
5915     case OPC_J:
5916     case OPC_JAL:
5917     case OPC_JALX:
5918         /* Jump to immediate */
5919         btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
5920             (uint32_t)offset;
5921         break;
5922     case OPC_JR:
5923     case OPC_JALR:
5924         /* Jump to register */
5925         if (offset != 0 && offset != 16) {
5926             /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5927                others are reserved. */
5928             MIPS_INVAL("jump hint");
5929             generate_exception_end(ctx, EXCP_RI);
5930             goto out;
5931         }
5932         gen_load_gpr(btarget, rs);
5933         break;
5934     default:
5935         MIPS_INVAL("branch/jump");
5936         generate_exception_end(ctx, EXCP_RI);
5937         goto out;
5938     }
5939     if (bcond_compute == 0) {
5940         /* No condition to be computed */
5941         switch (opc) {
5942         case OPC_BEQ:     /* rx == rx        */
5943         case OPC_BEQL:    /* rx == rx likely */
5944         case OPC_BGEZ:    /* 0 >= 0          */
5945         case OPC_BGEZL:   /* 0 >= 0 likely   */
5946         case OPC_BLEZ:    /* 0 <= 0          */
5947         case OPC_BLEZL:   /* 0 <= 0 likely   */
5948             /* Always take */
5949             ctx->hflags |= MIPS_HFLAG_B;
5950             break;
5951         case OPC_BGEZAL:  /* 0 >= 0          */
5952         case OPC_BGEZALL: /* 0 >= 0 likely   */
5953             /* Always take and link */
5954             blink = 31;
5955             ctx->hflags |= MIPS_HFLAG_B;
5956             break;
5957         case OPC_BNE:     /* rx != rx        */
5958         case OPC_BGTZ:    /* 0 > 0           */
5959         case OPC_BLTZ:    /* 0 < 0           */
5960             /* Treat as NOP. */
5961             goto out;
5962         case OPC_BLTZAL:  /* 0 < 0           */
5963             /* Handle as an unconditional branch to get correct delay
5964                slot checking.  */
5965             blink = 31;
5966             btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
5967             ctx->hflags |= MIPS_HFLAG_B;
5968             break;
5969         case OPC_BLTZALL: /* 0 < 0 likely */
5970             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
5971             /* Skip the instruction in the delay slot */
5972             ctx->base.pc_next += 4;
5973             goto out;
5974         case OPC_BNEL:    /* rx != rx likely */
5975         case OPC_BGTZL:   /* 0 > 0 likely */
5976         case OPC_BLTZL:   /* 0 < 0 likely */
5977             /* Skip the instruction in the delay slot */
5978             ctx->base.pc_next += 4;
5979             goto out;
5980         case OPC_J:
5981             ctx->hflags |= MIPS_HFLAG_B;
5982             break;
5983         case OPC_JALX:
5984             ctx->hflags |= MIPS_HFLAG_BX;
5985             /* Fallthrough */
5986         case OPC_JAL:
5987             blink = 31;
5988             ctx->hflags |= MIPS_HFLAG_B;
5989             break;
5990         case OPC_JR:
5991             ctx->hflags |= MIPS_HFLAG_BR;
5992             break;
5993         case OPC_JALR:
5994             blink = rt;
5995             ctx->hflags |= MIPS_HFLAG_BR;
5996             break;
5997         default:
5998             MIPS_INVAL("branch/jump");
5999             generate_exception_end(ctx, EXCP_RI);
6000             goto out;
6001         }
6002     } else {
6003         switch (opc) {
6004         case OPC_BEQ:
6005             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6006             goto not_likely;
6007         case OPC_BEQL:
6008             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6009             goto likely;
6010         case OPC_BNE:
6011             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6012             goto not_likely;
6013         case OPC_BNEL:
6014             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6015             goto likely;
6016         case OPC_BGEZ:
6017             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6018             goto not_likely;
6019         case OPC_BGEZL:
6020             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6021             goto likely;
6022         case OPC_BGEZAL:
6023             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6024             blink = 31;
6025             goto not_likely;
6026         case OPC_BGEZALL:
6027             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6028             blink = 31;
6029             goto likely;
6030         case OPC_BGTZ:
6031             tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6032             goto not_likely;
6033         case OPC_BGTZL:
6034             tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6035             goto likely;
6036         case OPC_BLEZ:
6037             tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6038             goto not_likely;
6039         case OPC_BLEZL:
6040             tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6041             goto likely;
6042         case OPC_BLTZ:
6043             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6044             goto not_likely;
6045         case OPC_BLTZL:
6046             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6047             goto likely;
6048         case OPC_BPOSGE32:
6049             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
6050             goto not_likely;
6051 #if defined(TARGET_MIPS64)
6052         case OPC_BPOSGE64:
6053             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
6054             goto not_likely;
6055 #endif
6056         case OPC_BLTZAL:
6057             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6058             blink = 31;
6059         not_likely:
6060             ctx->hflags |= MIPS_HFLAG_BC;
6061             break;
6062         case OPC_BLTZALL:
6063             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6064             blink = 31;
6065         likely:
6066             ctx->hflags |= MIPS_HFLAG_BL;
6067             break;
6068         default:
6069             MIPS_INVAL("conditional branch/jump");
6070             generate_exception_end(ctx, EXCP_RI);
6071             goto out;
6072         }
6073     }
6074
6075     ctx->btarget = btgt;
6076
6077     switch (delayslot_size) {
6078     case 2:
6079         ctx->hflags |= MIPS_HFLAG_BDS16;
6080         break;
6081     case 4:
6082         ctx->hflags |= MIPS_HFLAG_BDS32;
6083         break;
6084     }
6085
6086     if (blink > 0) {
6087         int post_delay = insn_bytes + delayslot_size;
6088         int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
6089
6090         tcg_gen_movi_tl(cpu_gpr[blink],
6091                         ctx->base.pc_next + post_delay + lowbit);
6092     }
6093
6094  out:
6095     if (insn_bytes == 2)
6096         ctx->hflags |= MIPS_HFLAG_B16;
6097     tcg_temp_free(t0);
6098     tcg_temp_free(t1);
6099 }
6100
6101
6102 /* nanoMIPS Branches */
6103 static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc,
6104                                 int insn_bytes,
6105                                 int rs, int rt, int32_t offset)
6106 {
6107     target_ulong btgt = -1;
6108     int bcond_compute = 0;
6109     TCGv t0 = tcg_temp_new();
6110     TCGv t1 = tcg_temp_new();
6111
6112     /* Load needed operands */
6113     switch (opc) {
6114     case OPC_BEQ:
6115     case OPC_BNE:
6116         /* Compare two registers */
6117         if (rs != rt) {
6118             gen_load_gpr(t0, rs);
6119             gen_load_gpr(t1, rt);
6120             bcond_compute = 1;
6121         }
6122         btgt = ctx->base.pc_next + insn_bytes + offset;
6123         break;
6124     case OPC_BGEZAL:
6125         /* Compare to zero */
6126         if (rs != 0) {
6127             gen_load_gpr(t0, rs);
6128             bcond_compute = 1;
6129         }
6130         btgt = ctx->base.pc_next + insn_bytes + offset;
6131         break;
6132     case OPC_BPOSGE32:
6133         tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
6134         bcond_compute = 1;
6135         btgt = ctx->base.pc_next + insn_bytes + offset;
6136         break;
6137     case OPC_JR:
6138     case OPC_JALR:
6139         /* Jump to register */
6140         if (offset != 0 && offset != 16) {
6141             /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6142                others are reserved. */
6143             MIPS_INVAL("jump hint");
6144             generate_exception_end(ctx, EXCP_RI);
6145             goto out;
6146         }
6147         gen_load_gpr(btarget, rs);
6148         break;
6149     default:
6150         MIPS_INVAL("branch/jump");
6151         generate_exception_end(ctx, EXCP_RI);
6152         goto out;
6153     }
6154     if (bcond_compute == 0) {
6155         /* No condition to be computed */
6156         switch (opc) {
6157         case OPC_BEQ:     /* rx == rx        */
6158             /* Always take */
6159             ctx->hflags |= MIPS_HFLAG_B;
6160             break;
6161         case OPC_BGEZAL:  /* 0 >= 0          */
6162             /* Always take and link */
6163             tcg_gen_movi_tl(cpu_gpr[31],
6164                             ctx->base.pc_next + insn_bytes);
6165             ctx->hflags |= MIPS_HFLAG_B;
6166             break;
6167         case OPC_BNE:     /* rx != rx        */
6168             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
6169             /* Skip the instruction in the delay slot */
6170             ctx->base.pc_next += 4;
6171             goto out;
6172         case OPC_JR:
6173             ctx->hflags |= MIPS_HFLAG_BR;
6174             break;
6175         case OPC_JALR:
6176             if (rt > 0) {
6177                 tcg_gen_movi_tl(cpu_gpr[rt],
6178                                 ctx->base.pc_next + insn_bytes);
6179             }
6180             ctx->hflags |= MIPS_HFLAG_BR;
6181             break;
6182         default:
6183             MIPS_INVAL("branch/jump");
6184             generate_exception_end(ctx, EXCP_RI);
6185             goto out;
6186         }
6187     } else {
6188         switch (opc) {
6189         case OPC_BEQ:
6190             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6191             goto not_likely;
6192         case OPC_BNE:
6193             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6194             goto not_likely;
6195         case OPC_BGEZAL:
6196             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6197             tcg_gen_movi_tl(cpu_gpr[31],
6198                             ctx->base.pc_next + insn_bytes);
6199             goto not_likely;
6200         case OPC_BPOSGE32:
6201             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
6202         not_likely:
6203             ctx->hflags |= MIPS_HFLAG_BC;
6204             break;
6205         default:
6206             MIPS_INVAL("conditional branch/jump");
6207             generate_exception_end(ctx, EXCP_RI);
6208             goto out;
6209         }
6210     }
6211
6212     ctx->btarget = btgt;
6213
6214  out:
6215     if (insn_bytes == 2) {
6216         ctx->hflags |= MIPS_HFLAG_B16;
6217     }
6218     tcg_temp_free(t0);
6219     tcg_temp_free(t1);
6220 }
6221
6222
6223 /* special3 bitfield operations */
6224 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
6225                         int rs, int lsb, int msb)
6226 {
6227     TCGv t0 = tcg_temp_new();
6228     TCGv t1 = tcg_temp_new();
6229
6230     gen_load_gpr(t1, rs);
6231     switch (opc) {
6232     case OPC_EXT:
6233         if (lsb + msb > 31) {
6234             goto fail;
6235         }
6236         if (msb != 31) {
6237             tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
6238         } else {
6239             /* The two checks together imply that lsb == 0,
6240                so this is a simple sign-extension.  */
6241             tcg_gen_ext32s_tl(t0, t1);
6242         }
6243         break;
6244 #if defined(TARGET_MIPS64)
6245     case OPC_DEXTU:
6246         lsb += 32;
6247         goto do_dext;
6248     case OPC_DEXTM:
6249         msb += 32;
6250         goto do_dext;
6251     case OPC_DEXT:
6252     do_dext:
6253         if (lsb + msb > 63) {
6254             goto fail;
6255         }
6256         tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
6257         break;
6258 #endif
6259     case OPC_INS:
6260         if (lsb > msb) {
6261             goto fail;
6262         }
6263         gen_load_gpr(t0, rt);
6264         tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
6265         tcg_gen_ext32s_tl(t0, t0);
6266         break;
6267 #if defined(TARGET_MIPS64)
6268     case OPC_DINSU:
6269         lsb += 32;
6270         /* FALLTHRU */
6271     case OPC_DINSM:
6272         msb += 32;
6273         /* FALLTHRU */
6274     case OPC_DINS:
6275         if (lsb > msb) {
6276             goto fail;
6277         }
6278         gen_load_gpr(t0, rt);
6279         tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
6280         break;
6281 #endif
6282     default:
6283 fail:
6284         MIPS_INVAL("bitops");
6285         generate_exception_end(ctx, EXCP_RI);
6286         tcg_temp_free(t0);
6287         tcg_temp_free(t1);
6288         return;
6289     }
6290     gen_store_gpr(t0, rt);
6291     tcg_temp_free(t0);
6292     tcg_temp_free(t1);
6293 }
6294
6295 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
6296 {
6297     TCGv t0;
6298
6299     if (rd == 0) {
6300         /* If no destination, treat it as a NOP. */
6301         return;
6302     }
6303
6304     t0 = tcg_temp_new();
6305     gen_load_gpr(t0, rt);
6306     switch (op2) {
6307     case OPC_WSBH:
6308         {
6309             TCGv t1 = tcg_temp_new();
6310             TCGv t2 = tcg_const_tl(0x00FF00FF);
6311
6312             tcg_gen_shri_tl(t1, t0, 8);
6313             tcg_gen_and_tl(t1, t1, t2);
6314             tcg_gen_and_tl(t0, t0, t2);
6315             tcg_gen_shli_tl(t0, t0, 8);
6316             tcg_gen_or_tl(t0, t0, t1);
6317             tcg_temp_free(t2);
6318             tcg_temp_free(t1);
6319             tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6320         }
6321         break;
6322     case OPC_SEB:
6323         tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
6324         break;
6325     case OPC_SEH:
6326         tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
6327         break;
6328 #if defined(TARGET_MIPS64)
6329     case OPC_DSBH:
6330         {
6331             TCGv t1 = tcg_temp_new();
6332             TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
6333
6334             tcg_gen_shri_tl(t1, t0, 8);
6335             tcg_gen_and_tl(t1, t1, t2);
6336             tcg_gen_and_tl(t0, t0, t2);
6337             tcg_gen_shli_tl(t0, t0, 8);
6338             tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
6339             tcg_temp_free(t2);
6340             tcg_temp_free(t1);
6341         }
6342         break;
6343     case OPC_DSHD:
6344         {
6345             TCGv t1 = tcg_temp_new();
6346             TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
6347
6348             tcg_gen_shri_tl(t1, t0, 16);
6349             tcg_gen_and_tl(t1, t1, t2);
6350             tcg_gen_and_tl(t0, t0, t2);
6351             tcg_gen_shli_tl(t0, t0, 16);
6352             tcg_gen_or_tl(t0, t0, t1);
6353             tcg_gen_shri_tl(t1, t0, 32);
6354             tcg_gen_shli_tl(t0, t0, 32);
6355             tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
6356             tcg_temp_free(t2);
6357             tcg_temp_free(t1);
6358         }
6359         break;
6360 #endif
6361     default:
6362         MIPS_INVAL("bsfhl");
6363         generate_exception_end(ctx, EXCP_RI);
6364         tcg_temp_free(t0);
6365         return;
6366     }
6367     tcg_temp_free(t0);
6368 }
6369
6370 static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
6371                     int imm2)
6372 {
6373     TCGv t0;
6374     TCGv t1;
6375     if (rd == 0) {
6376         /* Treat as NOP. */
6377         return;
6378     }
6379     t0 = tcg_temp_new();
6380     t1 = tcg_temp_new();
6381     gen_load_gpr(t0, rs);
6382     gen_load_gpr(t1, rt);
6383     tcg_gen_shli_tl(t0, t0, imm2 + 1);
6384     tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
6385     if (opc == OPC_LSA) {
6386         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
6387     }
6388
6389     tcg_temp_free(t1);
6390     tcg_temp_free(t0);
6391
6392     return;
6393 }
6394
6395 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
6396                            int rt, int bits)
6397 {
6398     TCGv t0;
6399     if (rd == 0) {
6400         /* Treat as NOP. */
6401         return;
6402     }
6403     t0 = tcg_temp_new();
6404     if (bits == 0 || bits == wordsz) {
6405         if (bits == 0) {
6406             gen_load_gpr(t0, rt);
6407         } else {
6408             gen_load_gpr(t0, rs);
6409         }
6410         switch (wordsz) {
6411         case 32:
6412             tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6413             break;
6414 #if defined(TARGET_MIPS64)
6415         case 64:
6416             tcg_gen_mov_tl(cpu_gpr[rd], t0);
6417             break;
6418 #endif
6419         }
6420     } else {
6421         TCGv t1 = tcg_temp_new();
6422         gen_load_gpr(t0, rt);
6423         gen_load_gpr(t1, rs);
6424         switch (wordsz) {
6425         case 32:
6426             {
6427                 TCGv_i64 t2 = tcg_temp_new_i64();
6428                 tcg_gen_concat_tl_i64(t2, t1, t0);
6429                 tcg_gen_shri_i64(t2, t2, 32 - bits);
6430                 gen_move_low32(cpu_gpr[rd], t2);
6431                 tcg_temp_free_i64(t2);
6432             }
6433             break;
6434 #if defined(TARGET_MIPS64)
6435         case 64:
6436             tcg_gen_shli_tl(t0, t0, bits);
6437             tcg_gen_shri_tl(t1, t1, 64 - bits);
6438             tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
6439             break;
6440 #endif
6441         }
6442         tcg_temp_free(t1);
6443     }
6444
6445     tcg_temp_free(t0);
6446 }
6447
6448 static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6449                       int bp)
6450 {
6451     gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
6452 }
6453
6454 static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6455                     int shift)
6456 {
6457     gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift);
6458 }
6459
6460 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
6461 {
6462     TCGv t0;
6463     if (rd == 0) {
6464         /* Treat as NOP. */
6465         return;
6466     }
6467     t0 = tcg_temp_new();
6468     gen_load_gpr(t0, rt);
6469     switch (opc) {
6470     case OPC_BITSWAP:
6471         gen_helper_bitswap(cpu_gpr[rd], t0);
6472         break;
6473 #if defined(TARGET_MIPS64)
6474     case OPC_DBITSWAP:
6475         gen_helper_dbitswap(cpu_gpr[rd], t0);
6476         break;
6477 #endif
6478     }
6479     tcg_temp_free(t0);
6480 }
6481
6482 #ifndef CONFIG_USER_ONLY
6483 /* CP0 (MMU and control) */
6484 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
6485 {
6486     TCGv_i64 t0 = tcg_temp_new_i64();
6487     TCGv_i64 t1 = tcg_temp_new_i64();
6488
6489     tcg_gen_ext_tl_i64(t0, arg);
6490     tcg_gen_ld_i64(t1, cpu_env, off);
6491 #if defined(TARGET_MIPS64)
6492     tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
6493 #else
6494     tcg_gen_concat32_i64(t1, t1, t0);
6495 #endif
6496     tcg_gen_st_i64(t1, cpu_env, off);
6497     tcg_temp_free_i64(t1);
6498     tcg_temp_free_i64(t0);
6499 }
6500
6501 static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
6502 {
6503     TCGv_i64 t0 = tcg_temp_new_i64();
6504     TCGv_i64 t1 = tcg_temp_new_i64();
6505
6506     tcg_gen_ext_tl_i64(t0, arg);
6507     tcg_gen_ld_i64(t1, cpu_env, off);
6508     tcg_gen_concat32_i64(t1, t1, t0);
6509     tcg_gen_st_i64(t1, cpu_env, off);
6510     tcg_temp_free_i64(t1);
6511     tcg_temp_free_i64(t0);
6512 }
6513
6514 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
6515 {
6516     TCGv_i64 t0 = tcg_temp_new_i64();
6517
6518     tcg_gen_ld_i64(t0, cpu_env, off);
6519 #if defined(TARGET_MIPS64)
6520     tcg_gen_shri_i64(t0, t0, 30);
6521 #else
6522     tcg_gen_shri_i64(t0, t0, 32);
6523 #endif
6524     gen_move_low32(arg, t0);
6525     tcg_temp_free_i64(t0);
6526 }
6527
6528 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
6529 {
6530     TCGv_i64 t0 = tcg_temp_new_i64();
6531
6532     tcg_gen_ld_i64(t0, cpu_env, off);
6533     tcg_gen_shri_i64(t0, t0, 32 + shift);
6534     gen_move_low32(arg, t0);
6535     tcg_temp_free_i64(t0);
6536 }
6537
6538 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
6539 {
6540     TCGv_i32 t0 = tcg_temp_new_i32();
6541
6542     tcg_gen_ld_i32(t0, cpu_env, off);
6543     tcg_gen_ext_i32_tl(arg, t0);
6544     tcg_temp_free_i32(t0);
6545 }
6546
6547 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
6548 {
6549     tcg_gen_ld_tl(arg, cpu_env, off);
6550     tcg_gen_ext32s_tl(arg, arg);
6551 }
6552
6553 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
6554 {
6555     TCGv_i32 t0 = tcg_temp_new_i32();
6556
6557     tcg_gen_trunc_tl_i32(t0, arg);
6558     tcg_gen_st_i32(t0, cpu_env, off);
6559     tcg_temp_free_i32(t0);
6560 }
6561
6562 #define CP0_CHECK(c)                            \
6563     do {                                        \
6564         if (!(c)) {                             \
6565             goto cp0_unimplemented;             \
6566         }                                       \
6567     } while (0)
6568
6569 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6570 {
6571     const char *register_name = "invalid";
6572
6573     switch (reg) {
6574     case CP0_REGISTER_02:
6575         switch (sel) {
6576         case 0:
6577             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6578             gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6579             register_name = "EntryLo0";
6580             break;
6581         default:
6582             goto cp0_unimplemented;
6583         }
6584         break;
6585     case CP0_REGISTER_03:
6586         switch (sel) {
6587         case 0:
6588             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6589             gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6590             register_name = "EntryLo1";
6591             break;
6592         default:
6593             goto cp0_unimplemented;
6594         }
6595         break;
6596     case CP0_REGISTER_09:
6597         switch (sel) {
6598         case 7:
6599             CP0_CHECK(ctx->saar);
6600             gen_helper_mfhc0_saar(arg, cpu_env);
6601             register_name = "SAAR";
6602             break;
6603         default:
6604             goto cp0_unimplemented;
6605         }
6606         break;
6607     case CP0_REGISTER_17:
6608         switch (sel) {
6609         case 0:
6610             gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
6611                              ctx->CP0_LLAddr_shift);
6612             register_name = "LLAddr";
6613             break;
6614         case 1:
6615             CP0_CHECK(ctx->mrp);
6616             gen_helper_mfhc0_maar(arg, cpu_env);
6617             register_name = "MAAR";
6618             break;
6619         default:
6620             goto cp0_unimplemented;
6621         }
6622         break;
6623     case CP0_REGISTER_28:
6624         switch (sel) {
6625         case 0:
6626         case 2:
6627         case 4:
6628         case 6:
6629             gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
6630             register_name = "TagLo";
6631             break;
6632         default:
6633             goto cp0_unimplemented;
6634         }
6635         break;
6636     default:
6637         goto cp0_unimplemented;
6638     }
6639     trace_mips_translate_c0("mfhc0", register_name, reg, sel);
6640     return;
6641
6642 cp0_unimplemented:
6643     qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n",
6644                   register_name, reg, sel);
6645     tcg_gen_movi_tl(arg, 0);
6646 }
6647
6648 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6649 {
6650     const char *register_name = "invalid";
6651     uint64_t mask = ctx->PAMask >> 36;
6652
6653     switch (reg) {
6654     case CP0_REGISTER_02:
6655         switch (sel) {
6656         case 0:
6657             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6658             tcg_gen_andi_tl(arg, arg, mask);
6659             gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6660             register_name = "EntryLo0";
6661             break;
6662         default:
6663             goto cp0_unimplemented;
6664         }
6665         break;
6666     case CP0_REGISTER_03:
6667         switch (sel) {
6668         case 0:
6669             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6670             tcg_gen_andi_tl(arg, arg, mask);
6671             gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6672             register_name = "EntryLo1";
6673             break;
6674         default:
6675             goto cp0_unimplemented;
6676         }
6677         break;
6678     case CP0_REGISTER_09:
6679         switch (sel) {
6680         case 7:
6681             CP0_CHECK(ctx->saar);
6682             gen_helper_mthc0_saar(cpu_env, arg);
6683             register_name = "SAAR";
6684             break;
6685         default:
6686             goto cp0_unimplemented;
6687         }
6688     case CP0_REGISTER_17:
6689         switch (sel) {
6690         case 0:
6691             /* LLAddr is read-only (the only exception is bit 0 if LLB is
6692                supported); the CP0_LLAddr_rw_bitmask does not seem to be
6693                relevant for modern MIPS cores supporting MTHC0, therefore
6694                treating MTHC0 to LLAddr as NOP. */
6695             register_name = "LLAddr";
6696             break;
6697         case 1:
6698             CP0_CHECK(ctx->mrp);
6699             gen_helper_mthc0_maar(cpu_env, arg);
6700             register_name = "MAAR";
6701             break;
6702         default:
6703             goto cp0_unimplemented;
6704         }
6705         break;
6706     case CP0_REGISTER_28:
6707         switch (sel) {
6708         case 0:
6709         case 2:
6710         case 4:
6711         case 6:
6712             tcg_gen_andi_tl(arg, arg, mask);
6713             gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
6714             register_name = "TagLo";
6715             break;
6716         default:
6717             goto cp0_unimplemented;
6718         }
6719         break;
6720     default:
6721         goto cp0_unimplemented;
6722     }
6723     trace_mips_translate_c0("mthc0", register_name, reg, sel);
6724
6725 cp0_unimplemented:
6726     qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n",
6727                   register_name, reg, sel);
6728 }
6729
6730 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
6731 {
6732     if (ctx->insn_flags & ISA_MIPS32R6) {
6733         tcg_gen_movi_tl(arg, 0);
6734     } else {
6735         tcg_gen_movi_tl(arg, ~0);
6736     }
6737 }
6738
6739 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6740 {
6741     const char *register_name = "invalid";
6742
6743     if (sel != 0)
6744         check_insn(ctx, ISA_MIPS32);
6745
6746     switch (reg) {
6747     case CP0_REGISTER_00:
6748         switch (sel) {
6749         case 0:
6750             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
6751             register_name = "Index";
6752             break;
6753         case 1:
6754             CP0_CHECK(ctx->insn_flags & ASE_MT);
6755             gen_helper_mfc0_mvpcontrol(arg, cpu_env);
6756             register_name = "MVPControl";
6757             break;
6758         case 2:
6759             CP0_CHECK(ctx->insn_flags & ASE_MT);
6760             gen_helper_mfc0_mvpconf0(arg, cpu_env);
6761             register_name = "MVPConf0";
6762             break;
6763         case 3:
6764             CP0_CHECK(ctx->insn_flags & ASE_MT);
6765             gen_helper_mfc0_mvpconf1(arg, cpu_env);
6766             register_name = "MVPConf1";
6767             break;
6768         case 4:
6769             CP0_CHECK(ctx->vp);
6770             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6771             register_name = "VPControl";
6772             break;
6773         default:
6774             goto cp0_unimplemented;
6775         }
6776         break;
6777     case CP0_REGISTER_01:
6778         switch (sel) {
6779         case 0:
6780             CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6781             gen_helper_mfc0_random(arg, cpu_env);
6782             register_name = "Random";
6783             break;
6784         case 1:
6785             CP0_CHECK(ctx->insn_flags & ASE_MT);
6786             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
6787             register_name = "VPEControl";
6788             break;
6789         case 2:
6790             CP0_CHECK(ctx->insn_flags & ASE_MT);
6791             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
6792             register_name = "VPEConf0";
6793             break;
6794         case 3:
6795             CP0_CHECK(ctx->insn_flags & ASE_MT);
6796             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
6797             register_name = "VPEConf1";
6798             break;
6799         case 4:
6800             CP0_CHECK(ctx->insn_flags & ASE_MT);
6801             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
6802             register_name = "YQMask";
6803             break;
6804         case 5:
6805             CP0_CHECK(ctx->insn_flags & ASE_MT);
6806             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
6807             register_name = "VPESchedule";
6808             break;
6809         case 6:
6810             CP0_CHECK(ctx->insn_flags & ASE_MT);
6811             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6812             register_name = "VPEScheFBack";
6813             break;
6814         case 7:
6815             CP0_CHECK(ctx->insn_flags & ASE_MT);
6816             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
6817             register_name = "VPEOpt";
6818             break;
6819         default:
6820             goto cp0_unimplemented;
6821         }
6822         break;
6823     case CP0_REGISTER_02:
6824         switch (sel) {
6825         case 0:
6826             {
6827                 TCGv_i64 tmp = tcg_temp_new_i64();
6828                 tcg_gen_ld_i64(tmp, cpu_env,
6829                                offsetof(CPUMIPSState, CP0_EntryLo0));
6830 #if defined(TARGET_MIPS64)
6831                 if (ctx->rxi) {
6832                     /* Move RI/XI fields to bits 31:30 */
6833                     tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6834                     tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6835                 }
6836 #endif
6837                 gen_move_low32(arg, tmp);
6838                 tcg_temp_free_i64(tmp);
6839             }
6840             register_name = "EntryLo0";
6841             break;
6842         case 1:
6843             CP0_CHECK(ctx->insn_flags & ASE_MT);
6844             gen_helper_mfc0_tcstatus(arg, cpu_env);
6845             register_name = "TCStatus";
6846             break;
6847         case 2:
6848             CP0_CHECK(ctx->insn_flags & ASE_MT);
6849             gen_helper_mfc0_tcbind(arg, cpu_env);
6850             register_name = "TCBind";
6851             break;
6852         case 3:
6853             CP0_CHECK(ctx->insn_flags & ASE_MT);
6854             gen_helper_mfc0_tcrestart(arg, cpu_env);
6855             register_name = "TCRestart";
6856             break;
6857         case 4:
6858             CP0_CHECK(ctx->insn_flags & ASE_MT);
6859             gen_helper_mfc0_tchalt(arg, cpu_env);
6860             register_name = "TCHalt";
6861             break;
6862         case 5:
6863             CP0_CHECK(ctx->insn_flags & ASE_MT);
6864             gen_helper_mfc0_tccontext(arg, cpu_env);
6865             register_name = "TCContext";
6866             break;
6867         case 6:
6868             CP0_CHECK(ctx->insn_flags & ASE_MT);
6869             gen_helper_mfc0_tcschedule(arg, cpu_env);
6870             register_name = "TCSchedule";
6871             break;
6872         case 7:
6873             CP0_CHECK(ctx->insn_flags & ASE_MT);
6874             gen_helper_mfc0_tcschefback(arg, cpu_env);
6875             register_name = "TCScheFBack";
6876             break;
6877         default:
6878             goto cp0_unimplemented;
6879         }
6880         break;
6881     case CP0_REGISTER_03:
6882         switch (sel) {
6883         case 0:
6884             {
6885                 TCGv_i64 tmp = tcg_temp_new_i64();
6886                 tcg_gen_ld_i64(tmp, cpu_env,
6887                                offsetof(CPUMIPSState, CP0_EntryLo1));
6888 #if defined(TARGET_MIPS64)
6889                 if (ctx->rxi) {
6890                     /* Move RI/XI fields to bits 31:30 */
6891                     tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6892                     tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6893                 }
6894 #endif
6895                 gen_move_low32(arg, tmp);
6896                 tcg_temp_free_i64(tmp);
6897             }
6898             register_name = "EntryLo1";
6899             break;
6900         case 1:
6901             CP0_CHECK(ctx->vp);
6902             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6903             register_name = "GlobalNumber";
6904             break;
6905         default:
6906             goto cp0_unimplemented;
6907         }
6908         break;
6909     case CP0_REGISTER_04:
6910         switch (sel) {
6911         case 0:
6912             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
6913             tcg_gen_ext32s_tl(arg, arg);
6914             register_name = "Context";
6915             break;
6916         case 1:
6917 //            gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
6918             register_name = "ContextConfig";
6919             goto cp0_unimplemented;
6920         case 2:
6921             CP0_CHECK(ctx->ulri);
6922             tcg_gen_ld_tl(arg, cpu_env,
6923                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6924             tcg_gen_ext32s_tl(arg, arg);
6925             register_name = "UserLocal";
6926             break;
6927         default:
6928             goto cp0_unimplemented;
6929         }
6930         break;
6931     case CP0_REGISTER_05:
6932         switch (sel) {
6933         case 0:
6934             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
6935             register_name = "PageMask";
6936             break;
6937         case 1:
6938             check_insn(ctx, ISA_MIPS32R2);
6939             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
6940             register_name = "PageGrain";
6941             break;
6942         case 2:
6943             CP0_CHECK(ctx->sc);
6944             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
6945             tcg_gen_ext32s_tl(arg, arg);
6946             register_name = "SegCtl0";
6947             break;
6948         case 3:
6949             CP0_CHECK(ctx->sc);
6950             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
6951             tcg_gen_ext32s_tl(arg, arg);
6952             register_name = "SegCtl1";
6953             break;
6954         case 4:
6955             CP0_CHECK(ctx->sc);
6956             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
6957             tcg_gen_ext32s_tl(arg, arg);
6958             register_name = "SegCtl2";
6959             break;
6960         case 5:
6961             check_pw(ctx);
6962             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6963             register_name = "PWBase";
6964             break;
6965         case 6:
6966             check_pw(ctx);
6967             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
6968             register_name = "PWField";
6969             break;
6970         case 7:
6971             check_pw(ctx);
6972             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
6973             register_name = "PWSize";
6974             break;
6975         default:
6976             goto cp0_unimplemented;
6977         }
6978         break;
6979     case CP0_REGISTER_06:
6980         switch (sel) {
6981         case 0:
6982             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
6983             register_name = "Wired";
6984             break;
6985         case 1:
6986             check_insn(ctx, ISA_MIPS32R2);
6987             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
6988             register_name = "SRSConf0";
6989             break;
6990         case 2:
6991             check_insn(ctx, ISA_MIPS32R2);
6992             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
6993             register_name = "SRSConf1";
6994             break;
6995         case 3:
6996             check_insn(ctx, ISA_MIPS32R2);
6997             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
6998             register_name = "SRSConf2";
6999             break;
7000         case 4:
7001             check_insn(ctx, ISA_MIPS32R2);
7002             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
7003             register_name = "SRSConf3";
7004             break;
7005         case 5:
7006             check_insn(ctx, ISA_MIPS32R2);
7007             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
7008             register_name = "SRSConf4";
7009             break;
7010         case 6:
7011             check_pw(ctx);
7012             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
7013             register_name = "PWCtl";
7014             break;
7015         default:
7016             goto cp0_unimplemented;
7017         }
7018         break;
7019     case CP0_REGISTER_07:
7020         switch (sel) {
7021         case 0:
7022             check_insn(ctx, ISA_MIPS32R2);
7023             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
7024             register_name = "HWREna";
7025             break;
7026         default:
7027             goto cp0_unimplemented;
7028         }
7029         break;
7030     case CP0_REGISTER_08:
7031         switch (sel) {
7032         case 0:
7033             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
7034             tcg_gen_ext32s_tl(arg, arg);
7035             register_name = "BadVAddr";
7036             break;
7037         case 1:
7038             CP0_CHECK(ctx->bi);
7039             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
7040             register_name = "BadInstr";
7041             break;
7042         case 2:
7043             CP0_CHECK(ctx->bp);
7044             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
7045             register_name = "BadInstrP";
7046             break;
7047         case 3:
7048             CP0_CHECK(ctx->bi);
7049             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
7050             tcg_gen_andi_tl(arg, arg, ~0xffff);
7051             register_name = "BadInstrX";
7052             break;
7053        default:
7054             goto cp0_unimplemented;
7055         }
7056         break;
7057     case CP0_REGISTER_09:
7058         switch (sel) {
7059         case 0:
7060             /* Mark as an IO operation because we read the time.  */
7061             if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7062                 gen_io_start();
7063             }
7064             gen_helper_mfc0_count(arg, cpu_env);
7065             if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7066                 gen_io_end();
7067             }
7068             /* Break the TB to be able to take timer interrupts immediately
7069                after reading count. DISAS_STOP isn't sufficient, we need to
7070                ensure we break completely out of translated code.  */
7071             gen_save_pc(ctx->base.pc_next + 4);
7072             ctx->base.is_jmp = DISAS_EXIT;
7073             register_name = "Count";
7074             break;
7075         case 6:
7076             CP0_CHECK(ctx->saar);
7077             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
7078             register_name = "SAARI";
7079             break;
7080         case 7:
7081             CP0_CHECK(ctx->saar);
7082             gen_helper_mfc0_saar(arg, cpu_env);
7083             register_name = "SAAR";
7084             break;
7085         default:
7086             goto cp0_unimplemented;
7087         }
7088         break;
7089     case CP0_REGISTER_10:
7090         switch (sel) {
7091         case 0:
7092             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
7093             tcg_gen_ext32s_tl(arg, arg);
7094             register_name = "EntryHi";
7095             break;
7096         default:
7097             goto cp0_unimplemented;
7098         }
7099         break;
7100     case CP0_REGISTER_11:
7101         switch (sel) {
7102         case 0:
7103             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
7104             register_name = "Compare";
7105             break;
7106         /* 6,7 are implementation dependent */
7107         default:
7108             goto cp0_unimplemented;
7109         }
7110         break;
7111     case CP0_REGISTER_12:
7112         switch (sel) {
7113         case 0:
7114             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
7115             register_name = "Status";
7116             break;
7117         case 1:
7118             check_insn(ctx, ISA_MIPS32R2);
7119             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
7120             register_name = "IntCtl";
7121             break;
7122         case 2:
7123             check_insn(ctx, ISA_MIPS32R2);
7124             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
7125             register_name = "SRSCtl";
7126             break;
7127         case 3:
7128             check_insn(ctx, ISA_MIPS32R2);
7129             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7130             register_name = "SRSMap";
7131             break;
7132         default:
7133             goto cp0_unimplemented;
7134        }
7135         break;
7136     case CP0_REGISTER_13:
7137         switch (sel) {
7138         case 0:
7139             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
7140             register_name = "Cause";
7141             break;
7142         default:
7143             goto cp0_unimplemented;
7144        }
7145         break;
7146     case CP0_REGISTER_14:
7147         switch (sel) {
7148         case 0:
7149             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7150             tcg_gen_ext32s_tl(arg, arg);
7151             register_name = "EPC";
7152             break;
7153         default:
7154             goto cp0_unimplemented;
7155         }
7156         break;
7157     case CP0_REGISTER_15:
7158         switch (sel) {
7159         case 0:
7160             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
7161             register_name = "PRid";
7162             break;
7163         case 1:
7164             check_insn(ctx, ISA_MIPS32R2);
7165             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
7166             tcg_gen_ext32s_tl(arg, arg);
7167             register_name = "EBase";
7168             break;
7169         case 3:
7170             check_insn(ctx, ISA_MIPS32R2);
7171             CP0_CHECK(ctx->cmgcr);
7172             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7173             tcg_gen_ext32s_tl(arg, arg);
7174             register_name = "CMGCRBase";
7175             break;
7176         default:
7177             goto cp0_unimplemented;
7178        }
7179         break;
7180     case CP0_REGISTER_16:
7181         switch (sel) {
7182         case 0:
7183             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
7184             register_name = "Config";
7185             break;
7186         case 1:
7187             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
7188             register_name = "Config1";
7189             break;
7190         case 2:
7191             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7192             register_name = "Config2";
7193             break;
7194         case 3:
7195             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7196             register_name = "Config3";
7197             break;
7198         case 4:
7199             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7200             register_name = "Config4";
7201             break;
7202         case 5:
7203             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7204             register_name = "Config5";
7205             break;
7206         /* 6,7 are implementation dependent */
7207         case 6:
7208             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
7209             register_name = "Config6";
7210             break;
7211         case 7:
7212             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
7213             register_name = "Config7";
7214             break;
7215         default:
7216             goto cp0_unimplemented;
7217         }
7218         break;
7219     case CP0_REGISTER_17:
7220         switch (sel) {
7221         case 0:
7222             gen_helper_mfc0_lladdr(arg, cpu_env);
7223             register_name = "LLAddr";
7224             break;
7225         case 1:
7226             CP0_CHECK(ctx->mrp);
7227             gen_helper_mfc0_maar(arg, cpu_env);
7228             register_name = "MAAR";
7229             break;
7230         case 2:
7231             CP0_CHECK(ctx->mrp);
7232             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7233             register_name = "MAARI";
7234             break;
7235         default:
7236             goto cp0_unimplemented;
7237         }
7238         break;
7239     case CP0_REGISTER_18:
7240         switch (sel) {
7241         case 0:
7242         case 1:
7243         case 2:
7244         case 3:
7245         case 4:
7246         case 5:
7247         case 6:
7248         case 7:
7249             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7250             gen_helper_1e0i(mfc0_watchlo, arg, sel);
7251             register_name = "WatchLo";
7252             break;
7253         default:
7254             goto cp0_unimplemented;
7255         }
7256         break;
7257     case CP0_REGISTER_19:
7258         switch (sel) {
7259         case 0:
7260         case 1:
7261         case 2:
7262         case 3:
7263         case 4:
7264         case 5:
7265         case 6:
7266         case 7:
7267             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7268             gen_helper_1e0i(mfc0_watchhi, arg, sel);
7269             register_name = "WatchHi";
7270             break;
7271         default:
7272             goto cp0_unimplemented;
7273         }
7274         break;
7275     case CP0_REGISTER_20:
7276         switch (sel) {
7277         case 0:
7278 #if defined(TARGET_MIPS64)
7279             check_insn(ctx, ISA_MIPS3);
7280             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
7281             tcg_gen_ext32s_tl(arg, arg);
7282             register_name = "XContext";
7283             break;
7284 #endif
7285         default:
7286             goto cp0_unimplemented;
7287         }
7288         break;
7289     case CP0_REGISTER_21:
7290        /* Officially reserved, but sel 0 is used for R1x000 framemask */
7291         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7292         switch (sel) {
7293         case 0:
7294             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
7295             register_name = "Framemask";
7296             break;
7297         default:
7298             goto cp0_unimplemented;
7299         }
7300         break;
7301     case CP0_REGISTER_22:
7302         tcg_gen_movi_tl(arg, 0); /* unimplemented */
7303         register_name = "'Diagnostic"; /* implementation dependent */
7304         break;
7305     case CP0_REGISTER_23:
7306         switch (sel) {
7307         case 0:
7308             gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
7309             register_name = "Debug";
7310             break;
7311         case 1:
7312 //            gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
7313             register_name = "TraceControl";
7314             goto cp0_unimplemented;
7315         case 2:
7316 //            gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
7317             register_name = "TraceControl2";
7318             goto cp0_unimplemented;
7319         case 3:
7320 //            gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
7321             register_name = "UserTraceData";
7322             goto cp0_unimplemented;
7323         case 4:
7324 //            gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
7325             register_name = "TraceBPC";
7326             goto cp0_unimplemented;
7327         default:
7328             goto cp0_unimplemented;
7329         }
7330         break;
7331     case CP0_REGISTER_24:
7332         switch (sel) {
7333         case 0:
7334             /* EJTAG support */
7335             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7336             tcg_gen_ext32s_tl(arg, arg);
7337             register_name = "DEPC";
7338             break;
7339         default:
7340             goto cp0_unimplemented;
7341         }
7342         break;
7343     case CP0_REGISTER_25:
7344         switch (sel) {
7345         case 0:
7346             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
7347             register_name = "Performance0";
7348             break;
7349         case 1:
7350 //            gen_helper_mfc0_performance1(arg);
7351             register_name = "Performance1";
7352             goto cp0_unimplemented;
7353         case 2:
7354 //            gen_helper_mfc0_performance2(arg);
7355             register_name = "Performance2";
7356             goto cp0_unimplemented;
7357         case 3:
7358 //            gen_helper_mfc0_performance3(arg);
7359             register_name = "Performance3";
7360             goto cp0_unimplemented;
7361         case 4:
7362 //            gen_helper_mfc0_performance4(arg);
7363             register_name = "Performance4";
7364             goto cp0_unimplemented;
7365         case 5:
7366 //            gen_helper_mfc0_performance5(arg);
7367             register_name = "Performance5";
7368             goto cp0_unimplemented;
7369         case 6:
7370 //            gen_helper_mfc0_performance6(arg);
7371             register_name = "Performance6";
7372             goto cp0_unimplemented;
7373         case 7:
7374 //            gen_helper_mfc0_performance7(arg);
7375             register_name = "Performance7";
7376             goto cp0_unimplemented;
7377         default:
7378             goto cp0_unimplemented;
7379         }
7380         break;
7381     case CP0_REGISTER_26:
7382         switch (sel) {
7383         case 0:
7384             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7385             register_name = "ErrCtl";
7386             break;
7387         default:
7388             goto cp0_unimplemented;
7389         }
7390         break;
7391     case CP0_REGISTER_27:
7392         switch (sel) {
7393         case 0:
7394         case 1:
7395         case 2:
7396         case 3:
7397             tcg_gen_movi_tl(arg, 0); /* unimplemented */
7398             register_name = "CacheErr";
7399             break;
7400         default:
7401             goto cp0_unimplemented;
7402         }
7403         break;
7404     case CP0_REGISTER_28:
7405         switch (sel) {
7406         case 0:
7407         case 2:
7408         case 4:
7409         case 6:
7410             {
7411                 TCGv_i64 tmp = tcg_temp_new_i64();
7412                 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
7413                 gen_move_low32(arg, tmp);
7414                 tcg_temp_free_i64(tmp);
7415             }
7416             register_name = "TagLo";
7417             break;
7418         case 1:
7419         case 3:
7420         case 5:
7421         case 7:
7422             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
7423             register_name = "DataLo";
7424             break;
7425         default:
7426             goto cp0_unimplemented;
7427         }
7428         break;
7429     case CP0_REGISTER_29:
7430         switch (sel) {
7431         case 0:
7432         case 2:
7433         case 4:
7434         case 6:
7435             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7436             register_name = "TagHi";
7437             break;
7438         case 1:
7439         case 3:
7440         case 5:
7441         case 7:
7442             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7443             register_name = "DataHi";
7444             break;
7445         default:
7446             goto cp0_unimplemented;
7447         }
7448         break;
7449     case CP0_REGISTER_30:
7450         switch (sel) {
7451         case 0:
7452             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7453             tcg_gen_ext32s_tl(arg, arg);
7454             register_name = "ErrorEPC";
7455             break;
7456         default:
7457             goto cp0_unimplemented;
7458         }
7459         break;
7460     case CP0_REGISTER_31:
7461         switch (sel) {
7462         case 0:
7463             /* EJTAG support */
7464             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7465             register_name = "DESAVE";
7466             break;
7467         case 2:
7468         case 3:
7469         case 4:
7470         case 5:
7471         case 6:
7472         case 7:
7473             CP0_CHECK(ctx->kscrexist & (1 << sel));
7474             tcg_gen_ld_tl(arg, cpu_env,
7475                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7476             tcg_gen_ext32s_tl(arg, arg);
7477             register_name = "KScratch";
7478             break;
7479         default:
7480             goto cp0_unimplemented;
7481         }
7482         break;
7483     default:
7484        goto cp0_unimplemented;
7485     }
7486     trace_mips_translate_c0("mfc0", register_name, reg, sel);
7487     return;
7488
7489 cp0_unimplemented:
7490     qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n",
7491                   register_name, reg, sel);
7492     gen_mfc0_unimplemented(ctx, arg);
7493 }
7494
7495 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7496 {
7497     const char *register_name = "invalid";
7498
7499     if (sel != 0)
7500         check_insn(ctx, ISA_MIPS32);
7501
7502     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7503         gen_io_start();
7504     }
7505
7506     switch (reg) {
7507     case CP0_REGISTER_00:
7508         switch (sel) {
7509         case 0:
7510             gen_helper_mtc0_index(cpu_env, arg);
7511             register_name = "Index";
7512             break;
7513         case 1:
7514             CP0_CHECK(ctx->insn_flags & ASE_MT);
7515             gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7516             register_name = "MVPControl";
7517             break;
7518         case 2:
7519             CP0_CHECK(ctx->insn_flags & ASE_MT);
7520             /* ignored */
7521             register_name = "MVPConf0";
7522             break;
7523         case 3:
7524             CP0_CHECK(ctx->insn_flags & ASE_MT);
7525             /* ignored */
7526             register_name = "MVPConf1";
7527             break;
7528         case 4:
7529             CP0_CHECK(ctx->vp);
7530             /* ignored */
7531             register_name = "VPControl";
7532             break;
7533         default:
7534             goto cp0_unimplemented;
7535         }
7536         break;
7537     case CP0_REGISTER_01:
7538         switch (sel) {
7539         case 0:
7540             /* ignored */
7541             register_name = "Random";
7542             break;
7543         case 1:
7544             CP0_CHECK(ctx->insn_flags & ASE_MT);
7545             gen_helper_mtc0_vpecontrol(cpu_env, arg);
7546             register_name = "VPEControl";
7547             break;
7548         case 2:
7549             CP0_CHECK(ctx->insn_flags & ASE_MT);
7550             gen_helper_mtc0_vpeconf0(cpu_env, arg);
7551             register_name = "VPEConf0";
7552             break;
7553         case 3:
7554             CP0_CHECK(ctx->insn_flags & ASE_MT);
7555             gen_helper_mtc0_vpeconf1(cpu_env, arg);
7556             register_name = "VPEConf1";
7557             break;
7558         case 4:
7559             CP0_CHECK(ctx->insn_flags & ASE_MT);
7560             gen_helper_mtc0_yqmask(cpu_env, arg);
7561             register_name = "YQMask";
7562             break;
7563         case 5:
7564             CP0_CHECK(ctx->insn_flags & ASE_MT);
7565             tcg_gen_st_tl(arg, cpu_env,
7566                           offsetof(CPUMIPSState, CP0_VPESchedule));
7567             register_name = "VPESchedule";
7568             break;
7569         case 6:
7570             CP0_CHECK(ctx->insn_flags & ASE_MT);
7571             tcg_gen_st_tl(arg, cpu_env,
7572                           offsetof(CPUMIPSState, CP0_VPEScheFBack));
7573             register_name = "VPEScheFBack";
7574             break;
7575         case 7:
7576             CP0_CHECK(ctx->insn_flags & ASE_MT);
7577             gen_helper_mtc0_vpeopt(cpu_env, arg);
7578             register_name = "VPEOpt";
7579             break;
7580         default:
7581             goto cp0_unimplemented;
7582         }
7583         break;
7584     case CP0_REGISTER_02:
7585         switch (sel) {
7586         case 0:
7587             gen_helper_mtc0_entrylo0(cpu_env, arg);
7588             register_name = "EntryLo0";
7589             break;
7590         case 1:
7591             CP0_CHECK(ctx->insn_flags & ASE_MT);
7592             gen_helper_mtc0_tcstatus(cpu_env, arg);
7593             register_name = "TCStatus";
7594             break;
7595         case 2:
7596             CP0_CHECK(ctx->insn_flags & ASE_MT);
7597             gen_helper_mtc0_tcbind(cpu_env, arg);
7598             register_name = "TCBind";
7599             break;
7600         case 3:
7601             CP0_CHECK(ctx->insn_flags & ASE_MT);
7602             gen_helper_mtc0_tcrestart(cpu_env, arg);
7603             register_name = "TCRestart";
7604             break;
7605         case 4:
7606             CP0_CHECK(ctx->insn_flags & ASE_MT);
7607             gen_helper_mtc0_tchalt(cpu_env, arg);
7608             register_name = "TCHalt";
7609             break;
7610         case 5:
7611             CP0_CHECK(ctx->insn_flags & ASE_MT);
7612             gen_helper_mtc0_tccontext(cpu_env, arg);
7613             register_name = "TCContext";
7614             break;
7615         case 6:
7616             CP0_CHECK(ctx->insn_flags & ASE_MT);
7617             gen_helper_mtc0_tcschedule(cpu_env, arg);
7618             register_name = "TCSchedule";
7619             break;
7620         case 7:
7621             CP0_CHECK(ctx->insn_flags & ASE_MT);
7622             gen_helper_mtc0_tcschefback(cpu_env, arg);
7623             register_name = "TCScheFBack";
7624             break;
7625         default:
7626             goto cp0_unimplemented;
7627         }
7628         break;
7629     case CP0_REGISTER_03:
7630         switch (sel) {
7631         case 0:
7632             gen_helper_mtc0_entrylo1(cpu_env, arg);
7633             register_name = "EntryLo1";
7634             break;
7635         case 1:
7636             CP0_CHECK(ctx->vp);
7637             /* ignored */
7638             register_name = "GlobalNumber";
7639             break;
7640         default:
7641             goto cp0_unimplemented;
7642         }
7643         break;
7644     case CP0_REGISTER_04:
7645         switch (sel) {
7646         case 0:
7647             gen_helper_mtc0_context(cpu_env, arg);
7648             register_name = "Context";
7649             break;
7650         case 1:
7651 //            gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
7652             register_name = "ContextConfig";
7653             goto cp0_unimplemented;
7654         case 2:
7655             CP0_CHECK(ctx->ulri);
7656             tcg_gen_st_tl(arg, cpu_env,
7657                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7658             register_name = "UserLocal";
7659             break;
7660         default:
7661             goto cp0_unimplemented;
7662         }
7663         break;
7664     case CP0_REGISTER_05:
7665         switch (sel) {
7666         case 0:
7667             gen_helper_mtc0_pagemask(cpu_env, arg);
7668             register_name = "PageMask";
7669             break;
7670         case 1:
7671             check_insn(ctx, ISA_MIPS32R2);
7672             gen_helper_mtc0_pagegrain(cpu_env, arg);
7673             register_name = "PageGrain";
7674             ctx->base.is_jmp = DISAS_STOP;
7675             break;
7676         case 2:
7677             CP0_CHECK(ctx->sc);
7678             gen_helper_mtc0_segctl0(cpu_env, arg);
7679             register_name = "SegCtl0";
7680             break;
7681         case 3:
7682             CP0_CHECK(ctx->sc);
7683             gen_helper_mtc0_segctl1(cpu_env, arg);
7684             register_name = "SegCtl1";
7685             break;
7686         case 4:
7687             CP0_CHECK(ctx->sc);
7688             gen_helper_mtc0_segctl2(cpu_env, arg);
7689             register_name = "SegCtl2";
7690             break;
7691         case 5:
7692             check_pw(ctx);
7693             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
7694             register_name = "PWBase";
7695             break;
7696         case 6:
7697             check_pw(ctx);
7698             gen_helper_mtc0_pwfield(cpu_env, arg);
7699             register_name = "PWField";
7700             break;
7701         case 7:
7702             check_pw(ctx);
7703             gen_helper_mtc0_pwsize(cpu_env, arg);
7704             register_name = "PWSize";
7705             break;
7706         default:
7707             goto cp0_unimplemented;
7708         }
7709         break;
7710     case CP0_REGISTER_06:
7711         switch (sel) {
7712         case 0:
7713             gen_helper_mtc0_wired(cpu_env, arg);
7714             register_name = "Wired";
7715             break;
7716         case 1:
7717             check_insn(ctx, ISA_MIPS32R2);
7718             gen_helper_mtc0_srsconf0(cpu_env, arg);
7719             register_name = "SRSConf0";
7720             break;
7721         case 2:
7722             check_insn(ctx, ISA_MIPS32R2);
7723             gen_helper_mtc0_srsconf1(cpu_env, arg);
7724             register_name = "SRSConf1";
7725             break;
7726         case 3:
7727             check_insn(ctx, ISA_MIPS32R2);
7728             gen_helper_mtc0_srsconf2(cpu_env, arg);
7729             register_name = "SRSConf2";
7730             break;
7731         case 4:
7732             check_insn(ctx, ISA_MIPS32R2);
7733             gen_helper_mtc0_srsconf3(cpu_env, arg);
7734             register_name = "SRSConf3";
7735             break;
7736         case 5:
7737             check_insn(ctx, ISA_MIPS32R2);
7738             gen_helper_mtc0_srsconf4(cpu_env, arg);
7739             register_name = "SRSConf4";
7740             break;
7741         case 6:
7742             check_pw(ctx);
7743             gen_helper_mtc0_pwctl(cpu_env, arg);
7744             register_name = "PWCtl";
7745             break;
7746         default:
7747             goto cp0_unimplemented;
7748         }
7749         break;
7750     case CP0_REGISTER_07:
7751         switch (sel) {
7752         case 0:
7753             check_insn(ctx, ISA_MIPS32R2);
7754             gen_helper_mtc0_hwrena(cpu_env, arg);
7755             ctx->base.is_jmp = DISAS_STOP;
7756             register_name = "HWREna";
7757             break;
7758         default:
7759             goto cp0_unimplemented;
7760         }
7761         break;
7762     case CP0_REGISTER_08:
7763         switch (sel) {
7764         case 0:
7765             /* ignored */
7766             register_name = "BadVAddr";
7767             break;
7768         case 1:
7769             /* ignored */
7770             register_name = "BadInstr";
7771             break;
7772         case 2:
7773             /* ignored */
7774             register_name = "BadInstrP";
7775             break;
7776         case 3:
7777             /* ignored */
7778             register_name = "BadInstrX";
7779             break;
7780         default:
7781             goto cp0_unimplemented;
7782         }
7783         break;
7784     case CP0_REGISTER_09:
7785         switch (sel) {
7786         case 0:
7787             gen_helper_mtc0_count(cpu_env, arg);
7788             register_name = "Count";
7789             break;
7790         case 6:
7791             CP0_CHECK(ctx->saar);
7792             gen_helper_mtc0_saari(cpu_env, arg);
7793             register_name = "SAARI";
7794             break;
7795         case 7:
7796             CP0_CHECK(ctx->saar);
7797             gen_helper_mtc0_saar(cpu_env, arg);
7798             register_name = "SAAR";
7799             break;
7800         default:
7801             goto cp0_unimplemented;
7802         }
7803         break;
7804     case CP0_REGISTER_10:
7805         switch (sel) {
7806         case 0:
7807             gen_helper_mtc0_entryhi(cpu_env, arg);
7808             register_name = "EntryHi";
7809             break;
7810         default:
7811             goto cp0_unimplemented;
7812         }
7813         break;
7814     case CP0_REGISTER_11:
7815         switch (sel) {
7816         case 0:
7817             gen_helper_mtc0_compare(cpu_env, arg);
7818             register_name = "Compare";
7819             break;
7820         /* 6,7 are implementation dependent */
7821         default:
7822             goto cp0_unimplemented;
7823         }
7824         break;
7825     case CP0_REGISTER_12:
7826         switch (sel) {
7827         case 0:
7828             save_cpu_state(ctx, 1);
7829             gen_helper_mtc0_status(cpu_env, arg);
7830             /* DISAS_STOP isn't good enough here, hflags may have changed. */
7831             gen_save_pc(ctx->base.pc_next + 4);
7832             ctx->base.is_jmp = DISAS_EXIT;
7833             register_name = "Status";
7834             break;
7835         case 1:
7836             check_insn(ctx, ISA_MIPS32R2);
7837             gen_helper_mtc0_intctl(cpu_env, arg);
7838             /* Stop translation as we may have switched the execution mode */
7839             ctx->base.is_jmp = DISAS_STOP;
7840             register_name = "IntCtl";
7841             break;
7842         case 2:
7843             check_insn(ctx, ISA_MIPS32R2);
7844             gen_helper_mtc0_srsctl(cpu_env, arg);
7845             /* Stop translation as we may have switched the execution mode */
7846             ctx->base.is_jmp = DISAS_STOP;
7847             register_name = "SRSCtl";
7848             break;
7849         case 3:
7850             check_insn(ctx, ISA_MIPS32R2);
7851             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7852             /* Stop translation as we may have switched the execution mode */
7853             ctx->base.is_jmp = DISAS_STOP;
7854             register_name = "SRSMap";
7855             break;
7856         default:
7857             goto cp0_unimplemented;
7858         }
7859         break;
7860     case CP0_REGISTER_13:
7861         switch (sel) {
7862         case 0:
7863             save_cpu_state(ctx, 1);
7864             gen_helper_mtc0_cause(cpu_env, arg);
7865             /* Stop translation as we may have triggered an interrupt.
7866              * DISAS_STOP isn't sufficient, we need to ensure we break out of
7867              * translated code to check for pending interrupts.  */
7868             gen_save_pc(ctx->base.pc_next + 4);
7869             ctx->base.is_jmp = DISAS_EXIT;
7870             register_name = "Cause";
7871             break;
7872         default:
7873             goto cp0_unimplemented;
7874         }
7875         break;
7876     case CP0_REGISTER_14:
7877         switch (sel) {
7878         case 0:
7879             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7880             register_name = "EPC";
7881             break;
7882         default:
7883             goto cp0_unimplemented;
7884         }
7885         break;
7886     case CP0_REGISTER_15:
7887         switch (sel) {
7888         case 0:
7889             /* ignored */
7890             register_name = "PRid";
7891             break;
7892         case 1:
7893             check_insn(ctx, ISA_MIPS32R2);
7894             gen_helper_mtc0_ebase(cpu_env, arg);
7895             register_name = "EBase";
7896             break;
7897         default:
7898             goto cp0_unimplemented;
7899         }
7900         break;
7901     case CP0_REGISTER_16:
7902         switch (sel) {
7903         case 0:
7904             gen_helper_mtc0_config0(cpu_env, arg);
7905             register_name = "Config";
7906             /* Stop translation as we may have switched the execution mode */
7907             ctx->base.is_jmp = DISAS_STOP;
7908             break;
7909         case 1:
7910             /* ignored, read only */
7911             register_name = "Config1";
7912             break;
7913         case 2:
7914             gen_helper_mtc0_config2(cpu_env, arg);
7915             register_name = "Config2";
7916             /* Stop translation as we may have switched the execution mode */
7917             ctx->base.is_jmp = DISAS_STOP;
7918             break;
7919         case 3:
7920             gen_helper_mtc0_config3(cpu_env, arg);
7921             register_name = "Config3";
7922             /* Stop translation as we may have switched the execution mode */
7923             ctx->base.is_jmp = DISAS_STOP;
7924             break;
7925         case 4:
7926             gen_helper_mtc0_config4(cpu_env, arg);
7927             register_name = "Config4";
7928             ctx->base.is_jmp = DISAS_STOP;
7929             break;
7930         case 5:
7931             gen_helper_mtc0_config5(cpu_env, arg);
7932             register_name = "Config5";
7933             /* Stop translation as we may have switched the execution mode */
7934             ctx->base.is_jmp = DISAS_STOP;
7935             break;
7936         /* 6,7 are implementation dependent */
7937         case 6:
7938             /* ignored */
7939             register_name = "Config6";
7940             break;
7941         case 7:
7942             /* ignored */
7943             register_name = "Config7";
7944             break;
7945         default:
7946             register_name = "Invalid config selector";
7947             goto cp0_unimplemented;
7948         }
7949         break;
7950     case CP0_REGISTER_17:
7951         switch (sel) {
7952         case 0:
7953             gen_helper_mtc0_lladdr(cpu_env, arg);
7954             register_name = "LLAddr";
7955             break;
7956         case 1:
7957             CP0_CHECK(ctx->mrp);
7958             gen_helper_mtc0_maar(cpu_env, arg);
7959             register_name = "MAAR";
7960             break;
7961         case 2:
7962             CP0_CHECK(ctx->mrp);
7963             gen_helper_mtc0_maari(cpu_env, arg);
7964             register_name = "MAARI";
7965             break;
7966         default:
7967             goto cp0_unimplemented;
7968         }
7969         break;
7970     case CP0_REGISTER_18:
7971         switch (sel) {
7972         case 0:
7973         case 1:
7974         case 2:
7975         case 3:
7976         case 4:
7977         case 5:
7978         case 6:
7979         case 7:
7980             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7981             gen_helper_0e1i(mtc0_watchlo, arg, sel);
7982             register_name = "WatchLo";
7983             break;
7984         default:
7985             goto cp0_unimplemented;
7986         }
7987         break;
7988     case CP0_REGISTER_19:
7989         switch (sel) {
7990         case 0:
7991         case 1:
7992         case 2:
7993         case 3:
7994         case 4:
7995         case 5:
7996         case 6:
7997         case 7:
7998             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7999             gen_helper_0e1i(mtc0_watchhi, arg, sel);
8000             register_name = "WatchHi";
8001             break;
8002         default:
8003             goto cp0_unimplemented;
8004         }
8005         break;
8006     case CP0_REGISTER_20:
8007         switch (sel) {
8008         case 0:
8009 #if defined(TARGET_MIPS64)
8010             check_insn(ctx, ISA_MIPS3);
8011             gen_helper_mtc0_xcontext(cpu_env, arg);
8012             register_name = "XContext";
8013             break;
8014 #endif
8015         default:
8016             goto cp0_unimplemented;
8017         }
8018         break;
8019     case CP0_REGISTER_21:
8020        /* Officially reserved, but sel 0 is used for R1x000 framemask */
8021         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8022         switch (sel) {
8023         case 0:
8024             gen_helper_mtc0_framemask(cpu_env, arg);
8025             register_name = "Framemask";
8026             break;
8027         default:
8028             goto cp0_unimplemented;
8029         }
8030         break;
8031     case CP0_REGISTER_22:
8032         /* ignored */
8033         register_name = "Diagnostic"; /* implementation dependent */
8034         break;
8035     case CP0_REGISTER_23:
8036         switch (sel) {
8037         case 0:
8038             gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8039             /* DISAS_STOP isn't good enough here, hflags may have changed. */
8040             gen_save_pc(ctx->base.pc_next + 4);
8041             ctx->base.is_jmp = DISAS_EXIT;
8042             register_name = "Debug";
8043             break;
8044         case 1:
8045 //            gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8046             register_name = "TraceControl";
8047             /* Stop translation as we may have switched the execution mode */
8048             ctx->base.is_jmp = DISAS_STOP;
8049             goto cp0_unimplemented;
8050         case 2:
8051 //            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8052             register_name = "TraceControl2";
8053             /* Stop translation as we may have switched the execution mode */
8054             ctx->base.is_jmp = DISAS_STOP;
8055             goto cp0_unimplemented;
8056         case 3:
8057             /* Stop translation as we may have switched the execution mode */
8058             ctx->base.is_jmp = DISAS_STOP;
8059 //            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8060             register_name = "UserTraceData";
8061             /* Stop translation as we may have switched the execution mode */
8062             ctx->base.is_jmp = DISAS_STOP;
8063             goto cp0_unimplemented;
8064         case 4:
8065 //            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8066             /* Stop translation as we may have switched the execution mode */
8067             ctx->base.is_jmp = DISAS_STOP;
8068             register_name = "TraceBPC";
8069             goto cp0_unimplemented;
8070         default:
8071             goto cp0_unimplemented;
8072         }
8073         break;
8074     case CP0_REGISTER_24:
8075         switch (sel) {
8076         case 0:
8077             /* EJTAG support */
8078             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8079             register_name = "DEPC";
8080             break;
8081         default:
8082             goto cp0_unimplemented;
8083         }
8084         break;
8085     case CP0_REGISTER_25:
8086         switch (sel) {
8087         case 0:
8088             gen_helper_mtc0_performance0(cpu_env, arg);
8089             register_name = "Performance0";
8090             break;
8091         case 1:
8092 //            gen_helper_mtc0_performance1(arg);
8093             register_name = "Performance1";
8094             goto cp0_unimplemented;
8095         case 2:
8096 //            gen_helper_mtc0_performance2(arg);
8097             register_name = "Performance2";
8098             goto cp0_unimplemented;
8099         case 3:
8100 //            gen_helper_mtc0_performance3(arg);
8101             register_name = "Performance3";
8102             goto cp0_unimplemented;
8103         case 4:
8104 //            gen_helper_mtc0_performance4(arg);
8105             register_name = "Performance4";
8106             goto cp0_unimplemented;
8107         case 5:
8108 //            gen_helper_mtc0_performance5(arg);
8109             register_name = "Performance5";
8110             goto cp0_unimplemented;
8111         case 6:
8112 //            gen_helper_mtc0_performance6(arg);
8113             register_name = "Performance6";
8114             goto cp0_unimplemented;
8115         case 7:
8116 //            gen_helper_mtc0_performance7(arg);
8117             register_name = "Performance7";
8118             goto cp0_unimplemented;
8119         default:
8120             goto cp0_unimplemented;
8121         }
8122        break;
8123     case CP0_REGISTER_26:
8124         switch (sel) {
8125         case 0:
8126             gen_helper_mtc0_errctl(cpu_env, arg);
8127             ctx->base.is_jmp = DISAS_STOP;
8128             register_name = "ErrCtl";
8129             break;
8130         default:
8131             goto cp0_unimplemented;
8132         }
8133         break;
8134     case CP0_REGISTER_27:
8135         switch (sel) {
8136         case 0:
8137         case 1:
8138         case 2:
8139         case 3:
8140             /* ignored */
8141             register_name = "CacheErr";
8142             break;
8143         default:
8144             goto cp0_unimplemented;
8145         }
8146        break;
8147     case CP0_REGISTER_28:
8148         switch (sel) {
8149         case 0:
8150         case 2:
8151         case 4:
8152         case 6:
8153             gen_helper_mtc0_taglo(cpu_env, arg);
8154             register_name = "TagLo";
8155             break;
8156         case 1:
8157         case 3:
8158         case 5:
8159         case 7:
8160             gen_helper_mtc0_datalo(cpu_env, arg);
8161             register_name = "DataLo";
8162             break;
8163         default:
8164             goto cp0_unimplemented;
8165         }
8166         break;
8167     case CP0_REGISTER_29:
8168         switch (sel) {
8169         case 0:
8170         case 2:
8171         case 4:
8172         case 6:
8173             gen_helper_mtc0_taghi(cpu_env, arg);
8174             register_name = "TagHi";
8175             break;
8176         case 1:
8177         case 3:
8178         case 5:
8179         case 7:
8180             gen_helper_mtc0_datahi(cpu_env, arg);
8181             register_name = "DataHi";
8182             break;
8183         default:
8184             register_name = "invalid sel";
8185             goto cp0_unimplemented;
8186         }
8187        break;
8188     case CP0_REGISTER_30:
8189         switch (sel) {
8190         case 0:
8191             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8192             register_name = "ErrorEPC";
8193             break;
8194         default:
8195             goto cp0_unimplemented;
8196         }
8197         break;
8198     case CP0_REGISTER_31:
8199         switch (sel) {
8200         case 0:
8201             /* EJTAG support */
8202             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8203             register_name = "DESAVE";
8204             break;
8205         case 2:
8206         case 3:
8207         case 4:
8208         case 5:
8209         case 6:
8210         case 7:
8211             CP0_CHECK(ctx->kscrexist & (1 << sel));
8212             tcg_gen_st_tl(arg, cpu_env,
8213                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8214             register_name = "KScratch";
8215             break;
8216         default:
8217             goto cp0_unimplemented;
8218         }
8219         break;
8220     default:
8221        goto cp0_unimplemented;
8222     }
8223     trace_mips_translate_c0("mtc0", register_name, reg, sel);
8224
8225     /* For simplicity assume that all writes can cause interrupts.  */
8226     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8227         gen_io_end();
8228         /* DISAS_STOP isn't sufficient, we need to ensure we break out of
8229          * translated code to check for pending interrupts.  */
8230         gen_save_pc(ctx->base.pc_next + 4);
8231         ctx->base.is_jmp = DISAS_EXIT;
8232     }
8233     return;
8234
8235 cp0_unimplemented:
8236     qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n",
8237                   register_name, reg, sel);
8238 }
8239
8240 #if defined(TARGET_MIPS64)
8241 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8242 {
8243     const char *register_name = "invalid";
8244
8245     if (sel != 0)
8246         check_insn(ctx, ISA_MIPS64);
8247
8248     switch (reg) {
8249     case CP0_REGISTER_00:
8250         switch (sel) {
8251         case 0:
8252             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
8253             register_name = "Index";
8254             break;
8255         case 1:
8256             CP0_CHECK(ctx->insn_flags & ASE_MT);
8257             gen_helper_mfc0_mvpcontrol(arg, cpu_env);
8258             register_name = "MVPControl";
8259             break;
8260         case 2:
8261             CP0_CHECK(ctx->insn_flags & ASE_MT);
8262             gen_helper_mfc0_mvpconf0(arg, cpu_env);
8263             register_name = "MVPConf0";
8264             break;
8265         case 3:
8266             CP0_CHECK(ctx->insn_flags & ASE_MT);
8267             gen_helper_mfc0_mvpconf1(arg, cpu_env);
8268             register_name = "MVPConf1";
8269             break;
8270         case 4:
8271             CP0_CHECK(ctx->vp);
8272             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
8273             register_name = "VPControl";
8274             break;
8275         default:
8276             goto cp0_unimplemented;
8277         }
8278         break;
8279     case CP0_REGISTER_01:
8280         switch (sel) {
8281         case 0:
8282             CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8283             gen_helper_mfc0_random(arg, cpu_env);
8284             register_name = "Random";
8285             break;
8286         case 1:
8287             CP0_CHECK(ctx->insn_flags & ASE_MT);
8288             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
8289             register_name = "VPEControl";
8290             break;
8291         case 2:
8292             CP0_CHECK(ctx->insn_flags & ASE_MT);
8293             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
8294             register_name = "VPEConf0";
8295             break;
8296         case 3:
8297             CP0_CHECK(ctx->insn_flags & ASE_MT);
8298             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
8299             register_name = "VPEConf1";
8300             break;
8301         case 4:
8302             CP0_CHECK(ctx->insn_flags & ASE_MT);
8303             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
8304             register_name = "YQMask";
8305             break;
8306         case 5:
8307             CP0_CHECK(ctx->insn_flags & ASE_MT);
8308             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
8309             register_name = "VPESchedule";
8310             break;
8311         case 6:
8312             CP0_CHECK(ctx->insn_flags & ASE_MT);
8313             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
8314             register_name = "VPEScheFBack";
8315             break;
8316         case 7:
8317             CP0_CHECK(ctx->insn_flags & ASE_MT);
8318             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
8319             register_name = "VPEOpt";
8320             break;
8321         default:
8322             goto cp0_unimplemented;
8323         }
8324         break;
8325     case CP0_REGISTER_02:
8326         switch (sel) {
8327         case 0:
8328             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
8329             register_name = "EntryLo0";
8330             break;
8331         case 1:
8332             CP0_CHECK(ctx->insn_flags & ASE_MT);
8333             gen_helper_mfc0_tcstatus(arg, cpu_env);
8334             register_name = "TCStatus";
8335             break;
8336         case 2:
8337             CP0_CHECK(ctx->insn_flags & ASE_MT);
8338             gen_helper_mfc0_tcbind(arg, cpu_env);
8339             register_name = "TCBind";
8340             break;
8341         case 3:
8342             CP0_CHECK(ctx->insn_flags & ASE_MT);
8343             gen_helper_dmfc0_tcrestart(arg, cpu_env);
8344             register_name = "TCRestart";
8345             break;
8346         case 4:
8347             CP0_CHECK(ctx->insn_flags & ASE_MT);
8348             gen_helper_dmfc0_tchalt(arg, cpu_env);
8349             register_name = "TCHalt";
8350             break;
8351         case 5:
8352             CP0_CHECK(ctx->insn_flags & ASE_MT);
8353             gen_helper_dmfc0_tccontext(arg, cpu_env);
8354             register_name = "TCContext";
8355             break;
8356         case 6:
8357             CP0_CHECK(ctx->insn_flags & ASE_MT);
8358             gen_helper_dmfc0_tcschedule(arg, cpu_env);
8359             register_name = "TCSchedule";
8360             break;
8361         case 7:
8362             CP0_CHECK(ctx->insn_flags & ASE_MT);
8363             gen_helper_dmfc0_tcschefback(arg, cpu_env);
8364             register_name = "TCScheFBack";
8365             break;
8366         default:
8367             goto cp0_unimplemented;
8368         }
8369         break;
8370     case CP0_REGISTER_03:
8371         switch (sel) {
8372         case 0:
8373             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
8374             register_name = "EntryLo1";
8375             break;
8376         case 1:
8377             CP0_CHECK(ctx->vp);
8378             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
8379             register_name = "GlobalNumber";
8380             break;
8381         default:
8382             goto cp0_unimplemented;
8383         }
8384         break;
8385     case CP0_REGISTER_04:
8386         switch (sel) {
8387         case 0:
8388             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
8389             register_name = "Context";
8390             break;
8391         case 1:
8392 //            gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
8393             register_name = "ContextConfig";
8394             goto cp0_unimplemented;
8395         case 2:
8396             CP0_CHECK(ctx->ulri);
8397             tcg_gen_ld_tl(arg, cpu_env,
8398                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8399             register_name = "UserLocal";
8400             break;
8401         default:
8402             goto cp0_unimplemented;
8403         }
8404         break;
8405     case CP0_REGISTER_05:
8406         switch (sel) {
8407         case 0:
8408             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
8409             register_name = "PageMask";
8410             break;
8411         case 1:
8412             check_insn(ctx, ISA_MIPS32R2);
8413             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
8414             register_name = "PageGrain";
8415             break;
8416         case 2:
8417             CP0_CHECK(ctx->sc);
8418             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
8419             register_name = "SegCtl0";
8420             break;
8421         case 3:
8422             CP0_CHECK(ctx->sc);
8423             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
8424             register_name = "SegCtl1";
8425             break;
8426         case 4:
8427             CP0_CHECK(ctx->sc);
8428             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
8429             register_name = "SegCtl2";
8430             break;
8431         case 5:
8432             check_pw(ctx);
8433             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8434             register_name = "PWBase";
8435             break;
8436         case 6:
8437             check_pw(ctx);
8438             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
8439             register_name = "PWField";
8440             break;
8441         case 7:
8442             check_pw(ctx);
8443             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
8444             register_name = "PWSize";
8445             break;
8446         default:
8447             goto cp0_unimplemented;
8448         }
8449         break;
8450     case CP0_REGISTER_06:
8451         switch (sel) {
8452         case 0:
8453             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
8454             register_name = "Wired";
8455             break;
8456         case 1:
8457             check_insn(ctx, ISA_MIPS32R2);
8458             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
8459             register_name = "SRSConf0";
8460             break;
8461         case 2:
8462             check_insn(ctx, ISA_MIPS32R2);
8463             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
8464             register_name = "SRSConf1";
8465             break;
8466         case 3:
8467             check_insn(ctx, ISA_MIPS32R2);
8468             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
8469             register_name = "SRSConf2";
8470             break;
8471         case 4:
8472             check_insn(ctx, ISA_MIPS32R2);
8473             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
8474             register_name = "SRSConf3";
8475             break;
8476         case 5:
8477             check_insn(ctx, ISA_MIPS32R2);
8478             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
8479             register_name = "SRSConf4";
8480             break;
8481         case 6:
8482             check_pw(ctx);
8483             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
8484             register_name = "PWCtl";
8485             break;
8486         default:
8487             goto cp0_unimplemented;
8488         }
8489         break;
8490     case CP0_REGISTER_07:
8491         switch (sel) {
8492         case 0:
8493             check_insn(ctx, ISA_MIPS32R2);
8494             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
8495             register_name = "HWREna";
8496             break;
8497         default:
8498             goto cp0_unimplemented;
8499         }
8500         break;
8501     case CP0_REGISTER_08:
8502         switch (sel) {
8503         case 0:
8504             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
8505             register_name = "BadVAddr";
8506             break;
8507         case 1:
8508             CP0_CHECK(ctx->bi);
8509             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
8510             register_name = "BadInstr";
8511             break;
8512         case 2:
8513             CP0_CHECK(ctx->bp);
8514             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
8515             register_name = "BadInstrP";
8516             break;
8517         case 3:
8518             CP0_CHECK(ctx->bi);
8519             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
8520             tcg_gen_andi_tl(arg, arg, ~0xffff);
8521             register_name = "BadInstrX";
8522             break;
8523         default:
8524             goto cp0_unimplemented;
8525         }
8526         break;
8527     case CP0_REGISTER_09:
8528         switch (sel) {
8529         case 0:
8530             /* Mark as an IO operation because we read the time.  */
8531             if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8532                 gen_io_start();
8533             }
8534             gen_helper_mfc0_count(arg, cpu_env);
8535             if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8536                 gen_io_end();
8537             }
8538             /* Break the TB to be able to take timer interrupts immediately
8539                after reading count. DISAS_STOP isn't sufficient, we need to
8540                ensure we break completely out of translated code.  */
8541             gen_save_pc(ctx->base.pc_next + 4);
8542             ctx->base.is_jmp = DISAS_EXIT;
8543             register_name = "Count";
8544             break;
8545         case 6:
8546             CP0_CHECK(ctx->saar);
8547             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
8548             register_name = "SAARI";
8549             break;
8550         case 7:
8551             CP0_CHECK(ctx->saar);
8552             gen_helper_dmfc0_saar(arg, cpu_env);
8553             register_name = "SAAR";
8554             break;
8555         default:
8556             goto cp0_unimplemented;
8557         }
8558         break;
8559     case CP0_REGISTER_10:
8560         switch (sel) {
8561         case 0:
8562             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
8563             register_name = "EntryHi";
8564             break;
8565         default:
8566             goto cp0_unimplemented;
8567         }
8568         break;
8569     case CP0_REGISTER_11:
8570         switch (sel) {
8571         case 0:
8572             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
8573             register_name = "Compare";
8574             break;
8575         /* 6,7 are implementation dependent */
8576         default:
8577             goto cp0_unimplemented;
8578         }
8579         break;
8580     case CP0_REGISTER_12:
8581         switch (sel) {
8582         case 0:
8583             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
8584             register_name = "Status";
8585             break;
8586         case 1:
8587             check_insn(ctx, ISA_MIPS32R2);
8588             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
8589             register_name = "IntCtl";
8590             break;
8591         case 2:
8592             check_insn(ctx, ISA_MIPS32R2);
8593             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
8594             register_name = "SRSCtl";
8595             break;
8596         case 3:
8597             check_insn(ctx, ISA_MIPS32R2);
8598             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8599             register_name = "SRSMap";
8600             break;
8601         default:
8602             goto cp0_unimplemented;
8603         }
8604         break;
8605     case CP0_REGISTER_13:
8606         switch (sel) {
8607         case 0:
8608             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
8609             register_name = "Cause";
8610             break;
8611         default:
8612             goto cp0_unimplemented;
8613         }
8614         break;
8615     case CP0_REGISTER_14:
8616         switch (sel) {
8617         case 0:
8618             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
8619             register_name = "EPC";
8620             break;
8621         default:
8622             goto cp0_unimplemented;
8623         }
8624         break;
8625     case CP0_REGISTER_15:
8626         switch (sel) {
8627         case 0:
8628             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
8629             register_name = "PRid";
8630             break;
8631         case 1:
8632             check_insn(ctx, ISA_MIPS32R2);
8633             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
8634             register_name = "EBase";
8635             break;
8636         case 3:
8637             check_insn(ctx, ISA_MIPS32R2);
8638             CP0_CHECK(ctx->cmgcr);
8639             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
8640             register_name = "CMGCRBase";
8641             break;
8642         default:
8643             goto cp0_unimplemented;
8644         }
8645         break;
8646     case CP0_REGISTER_16:
8647         switch (sel) {
8648         case 0:
8649             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
8650             register_name = "Config";
8651             break;
8652         case 1:
8653             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
8654             register_name = "Config1";
8655             break;
8656         case 2:
8657             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
8658             register_name = "Config2";
8659             break;
8660         case 3:
8661             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
8662             register_name = "Config3";
8663             break;
8664         case 4:
8665             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
8666             register_name = "Config4";
8667             break;
8668         case 5:
8669             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
8670             register_name = "Config5";
8671             break;
8672        /* 6,7 are implementation dependent */
8673         case 6:
8674             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
8675             register_name = "Config6";
8676             break;
8677         case 7:
8678             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
8679             register_name = "Config7";
8680             break;
8681         default:
8682             goto cp0_unimplemented;
8683         }
8684         break;
8685     case CP0_REGISTER_17:
8686         switch (sel) {
8687         case 0:
8688             gen_helper_dmfc0_lladdr(arg, cpu_env);
8689             register_name = "LLAddr";
8690             break;
8691         case 1:
8692             CP0_CHECK(ctx->mrp);
8693             gen_helper_dmfc0_maar(arg, cpu_env);
8694             register_name = "MAAR";
8695             break;
8696         case 2:
8697             CP0_CHECK(ctx->mrp);
8698             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
8699             register_name = "MAARI";
8700             break;
8701         default:
8702             goto cp0_unimplemented;
8703         }
8704         break;
8705     case CP0_REGISTER_18:
8706         switch (sel) {
8707         case 0:
8708         case 1:
8709         case 2:
8710         case 3:
8711         case 4:
8712         case 5:
8713         case 6:
8714         case 7:
8715             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8716             gen_helper_1e0i(dmfc0_watchlo, arg, sel);
8717             register_name = "WatchLo";
8718             break;
8719         default:
8720             goto cp0_unimplemented;
8721         }
8722         break;
8723     case CP0_REGISTER_19:
8724         switch (sel) {
8725         case 0:
8726         case 1:
8727         case 2:
8728         case 3:
8729         case 4:
8730         case 5:
8731         case 6:
8732         case 7:
8733             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8734             gen_helper_1e0i(mfc0_watchhi, arg, sel);
8735             register_name = "WatchHi";
8736             break;
8737         default:
8738             goto cp0_unimplemented;
8739         }
8740         break;
8741     case CP0_REGISTER_20:
8742         switch (sel) {
8743         case 0:
8744             check_insn(ctx, ISA_MIPS3);
8745             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
8746             register_name = "XContext";
8747             break;
8748         default:
8749             goto cp0_unimplemented;
8750         }
8751         break;
8752     case CP0_REGISTER_21:
8753        /* Officially reserved, but sel 0 is used for R1x000 framemask */
8754         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8755         switch (sel) {
8756         case 0:
8757             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
8758             register_name = "Framemask";
8759             break;
8760         default:
8761             goto cp0_unimplemented;
8762         }
8763         break;
8764     case CP0_REGISTER_22:
8765         tcg_gen_movi_tl(arg, 0); /* unimplemented */
8766         register_name = "'Diagnostic"; /* implementation dependent */
8767         break;
8768     case CP0_REGISTER_23:
8769         switch (sel) {
8770         case 0:
8771             gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
8772             register_name = "Debug";
8773             break;
8774         case 1:
8775 //            gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
8776             register_name = "TraceControl";
8777             goto cp0_unimplemented;
8778         case 2:
8779 //            gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
8780             register_name = "TraceControl2";
8781             goto cp0_unimplemented;
8782         case 3:
8783 //            gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
8784             register_name = "UserTraceData";
8785             goto cp0_unimplemented;
8786         case 4:
8787 //            gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
8788             register_name = "TraceBPC";
8789             goto cp0_unimplemented;
8790         default:
8791             goto cp0_unimplemented;
8792         }
8793         break;
8794     case CP0_REGISTER_24:
8795         switch (sel) {
8796         case 0:
8797             /* EJTAG support */
8798             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8799             register_name = "DEPC";
8800             break;
8801         default:
8802             goto cp0_unimplemented;
8803         }
8804         break;
8805     case CP0_REGISTER_25:
8806         switch (sel) {
8807         case 0:
8808             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
8809             register_name = "Performance0";
8810             break;
8811         case 1:
8812 //            gen_helper_dmfc0_performance1(arg);
8813             register_name = "Performance1";
8814             goto cp0_unimplemented;
8815         case 2:
8816 //            gen_helper_dmfc0_performance2(arg);
8817             register_name = "Performance2";
8818             goto cp0_unimplemented;
8819         case 3:
8820 //            gen_helper_dmfc0_performance3(arg);
8821             register_name = "Performance3";
8822             goto cp0_unimplemented;
8823         case 4:
8824 //            gen_helper_dmfc0_performance4(arg);
8825             register_name = "Performance4";
8826             goto cp0_unimplemented;
8827         case 5:
8828 //            gen_helper_dmfc0_performance5(arg);
8829             register_name = "Performance5";
8830             goto cp0_unimplemented;
8831         case 6:
8832 //            gen_helper_dmfc0_performance6(arg);
8833             register_name = "Performance6";
8834             goto cp0_unimplemented;
8835         case 7:
8836 //            gen_helper_dmfc0_performance7(arg);
8837             register_name = "Performance7";
8838             goto cp0_unimplemented;
8839         default:
8840             goto cp0_unimplemented;
8841         }
8842         break;
8843     case CP0_REGISTER_26:
8844         switch (sel) {
8845         case 0:
8846             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
8847             register_name = "ErrCtl";
8848             break;
8849         default:
8850             goto cp0_unimplemented;
8851         }
8852         break;
8853     case CP0_REGISTER_27:
8854         switch (sel) {
8855         /* ignored */
8856         case 0:
8857         case 1:
8858         case 2:
8859         case 3:
8860             tcg_gen_movi_tl(arg, 0); /* unimplemented */
8861             register_name = "CacheErr";
8862             break;
8863         default:
8864             goto cp0_unimplemented;
8865         }
8866         break;
8867     case CP0_REGISTER_28:
8868         switch (sel) {
8869         case 0:
8870         case 2:
8871         case 4:
8872         case 6:
8873             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
8874             register_name = "TagLo";
8875             break;
8876         case 1:
8877         case 3:
8878         case 5:
8879         case 7:
8880             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
8881             register_name = "DataLo";
8882             break;
8883         default:
8884             goto cp0_unimplemented;
8885         }
8886         break;
8887     case CP0_REGISTER_29:
8888         switch (sel) {
8889         case 0:
8890         case 2:
8891         case 4:
8892         case 6:
8893             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
8894             register_name = "TagHi";
8895             break;
8896         case 1:
8897         case 3:
8898         case 5:
8899         case 7:
8900             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
8901             register_name = "DataHi";
8902             break;
8903         default:
8904             goto cp0_unimplemented;
8905         }
8906         break;
8907     case CP0_REGISTER_30:
8908         switch (sel) {
8909         case 0:
8910             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8911             register_name = "ErrorEPC";
8912             break;
8913         default:
8914             goto cp0_unimplemented;
8915         }
8916         break;
8917     case CP0_REGISTER_31:
8918         switch (sel) {
8919         case 0:
8920             /* EJTAG support */
8921             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8922             register_name = "DESAVE";
8923             break;
8924         case 2:
8925         case 3:
8926         case 4:
8927         case 5:
8928         case 6:
8929         case 7:
8930             CP0_CHECK(ctx->kscrexist & (1 << sel));
8931             tcg_gen_ld_tl(arg, cpu_env,
8932                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8933             register_name = "KScratch";
8934             break;
8935         default:
8936             goto cp0_unimplemented;
8937         }
8938         break;
8939     default:
8940         goto cp0_unimplemented;
8941     }
8942     trace_mips_translate_c0("dmfc0", register_name, reg, sel);
8943     return;
8944
8945 cp0_unimplemented:
8946     qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n",
8947                   register_name, reg, sel);
8948     gen_mfc0_unimplemented(ctx, arg);
8949 }
8950
8951 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8952 {
8953     const char *register_name = "invalid";
8954
8955     if (sel != 0)
8956         check_insn(ctx, ISA_MIPS64);
8957
8958     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8959         gen_io_start();
8960     }
8961
8962     switch (reg) {
8963     case CP0_REGISTER_00:
8964         switch (sel) {
8965         case 0:
8966             gen_helper_mtc0_index(cpu_env, arg);
8967             register_name = "Index";
8968             break;
8969         case 1:
8970             CP0_CHECK(ctx->insn_flags & ASE_MT);
8971             gen_helper_mtc0_mvpcontrol(cpu_env, arg);
8972             register_name = "MVPControl";
8973             break;
8974         case 2:
8975             CP0_CHECK(ctx->insn_flags & ASE_MT);
8976             /* ignored */
8977             register_name = "MVPConf0";
8978             break;
8979         case 3:
8980             CP0_CHECK(ctx->insn_flags & ASE_MT);
8981             /* ignored */
8982             register_name = "MVPConf1";
8983             break;
8984         case 4:
8985             CP0_CHECK(ctx->vp);
8986             /* ignored */
8987             register_name = "VPControl";
8988             break;
8989         default:
8990             goto cp0_unimplemented;
8991         }
8992         break;
8993     case CP0_REGISTER_01:
8994         switch (sel) {
8995         case 0:
8996             /* ignored */
8997             register_name = "Random";
8998             break;
8999         case 1:
9000             CP0_CHECK(ctx->insn_flags & ASE_MT);
9001             gen_helper_mtc0_vpecontrol(cpu_env, arg);
9002             register_name = "VPEControl";
9003             break;
9004         case 2:
9005             CP0_CHECK(ctx->insn_flags & ASE_MT);
9006             gen_helper_mtc0_vpeconf0(cpu_env, arg);
9007             register_name = "VPEConf0";
9008             break;
9009         case 3:
9010             CP0_CHECK(ctx->insn_flags & ASE_MT);
9011             gen_helper_mtc0_vpeconf1(cpu_env, arg);
9012             register_name = "VPEConf1";
9013             break;
9014         case 4:
9015             CP0_CHECK(ctx->insn_flags & ASE_MT);
9016             gen_helper_mtc0_yqmask(cpu_env, arg);
9017             register_name = "YQMask";
9018             break;
9019         case 5:
9020             CP0_CHECK(ctx->insn_flags & ASE_MT);
9021             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9022             register_name = "VPESchedule";
9023             break;
9024         case 6:
9025             CP0_CHECK(ctx->insn_flags & ASE_MT);
9026             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9027             register_name = "VPEScheFBack";
9028             break;
9029         case 7:
9030             CP0_CHECK(ctx->insn_flags & ASE_MT);
9031             gen_helper_mtc0_vpeopt(cpu_env, arg);
9032             register_name = "VPEOpt";
9033             break;
9034         default:
9035             goto cp0_unimplemented;
9036         }
9037         break;
9038     case CP0_REGISTER_02:
9039         switch (sel) {
9040         case 0:
9041             gen_helper_dmtc0_entrylo0(cpu_env, arg);
9042             register_name = "EntryLo0";
9043             break;
9044         case 1:
9045             CP0_CHECK(ctx->insn_flags & ASE_MT);
9046             gen_helper_mtc0_tcstatus(cpu_env, arg);
9047             register_name = "TCStatus";
9048             break;
9049         case 2:
9050             CP0_CHECK(ctx->insn_flags & ASE_MT);
9051             gen_helper_mtc0_tcbind(cpu_env, arg);
9052             register_name = "TCBind";
9053             break;
9054         case 3:
9055             CP0_CHECK(ctx->insn_flags & ASE_MT);
9056             gen_helper_mtc0_tcrestart(cpu_env, arg);
9057             register_name = "TCRestart";
9058             break;
9059         case 4:
9060             CP0_CHECK(ctx->insn_flags & ASE_MT);
9061             gen_helper_mtc0_tchalt(cpu_env, arg);
9062             register_name = "TCHalt";
9063             break;
9064         case 5:
9065             CP0_CHECK(ctx->insn_flags & ASE_MT);
9066             gen_helper_mtc0_tccontext(cpu_env, arg);
9067             register_name = "TCContext";
9068             break;
9069         case 6:
9070             CP0_CHECK(ctx->insn_flags & ASE_MT);
9071             gen_helper_mtc0_tcschedule(cpu_env, arg);
9072             register_name = "TCSchedule";
9073             break;
9074         case 7:
9075             CP0_CHECK(ctx->insn_flags & ASE_MT);
9076             gen_helper_mtc0_tcschefback(cpu_env, arg);
9077             register_name = "TCScheFBack";
9078             break;
9079         default:
9080             goto cp0_unimplemented;
9081         }
9082         break;
9083     case CP0_REGISTER_03:
9084         switch (sel) {
9085         case 0:
9086             gen_helper_dmtc0_entrylo1(cpu_env, arg);
9087             register_name = "EntryLo1";
9088             break;
9089         case 1:
9090             CP0_CHECK(ctx->vp);
9091             /* ignored */
9092             register_name = "GlobalNumber";
9093             break;
9094         default:
9095             goto cp0_unimplemented;
9096         }
9097         break;
9098     case CP0_REGISTER_04:
9099         switch (sel) {
9100         case 0:
9101             gen_helper_mtc0_context(cpu_env, arg);
9102             register_name = "Context";
9103             break;
9104         case 1:
9105 //           gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
9106             register_name = "ContextConfig";
9107             goto cp0_unimplemented;
9108         case 2:
9109             CP0_CHECK(ctx->ulri);
9110             tcg_gen_st_tl(arg, cpu_env,
9111                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
9112             register_name = "UserLocal";
9113             break;
9114         default:
9115             goto cp0_unimplemented;
9116         }
9117         break;
9118     case CP0_REGISTER_05:
9119         switch (sel) {
9120         case 0:
9121             gen_helper_mtc0_pagemask(cpu_env, arg);
9122             register_name = "PageMask";
9123             break;
9124         case 1:
9125             check_insn(ctx, ISA_MIPS32R2);
9126             gen_helper_mtc0_pagegrain(cpu_env, arg);
9127             register_name = "PageGrain";
9128             break;
9129         case 2:
9130             CP0_CHECK(ctx->sc);
9131             gen_helper_mtc0_segctl0(cpu_env, arg);
9132             register_name = "SegCtl0";
9133             break;
9134         case 3:
9135             CP0_CHECK(ctx->sc);
9136             gen_helper_mtc0_segctl1(cpu_env, arg);
9137             register_name = "SegCtl1";
9138             break;
9139         case 4:
9140             CP0_CHECK(ctx->sc);
9141             gen_helper_mtc0_segctl2(cpu_env, arg);
9142             register_name = "SegCtl2";
9143             break;
9144         case 5:
9145             check_pw(ctx);
9146             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
9147             register_name = "PWBase";
9148             break;
9149         case 6:
9150             check_pw(ctx);
9151             gen_helper_mtc0_pwfield(cpu_env, arg);
9152             register_name = "PWField";
9153             break;
9154         case 7:
9155             check_pw(ctx);
9156             gen_helper_mtc0_pwsize(cpu_env, arg);
9157             register_name = "PWSize";
9158             break;
9159         default:
9160             goto cp0_unimplemented;
9161         }
9162         break;
9163     case CP0_REGISTER_06:
9164         switch (sel) {
9165         case 0:
9166             gen_helper_mtc0_wired(cpu_env, arg);
9167             register_name = "Wired";
9168             break;
9169         case 1:
9170             check_insn(ctx, ISA_MIPS32R2);
9171             gen_helper_mtc0_srsconf0(cpu_env, arg);
9172             register_name = "SRSConf0";
9173             break;
9174         case 2:
9175             check_insn(ctx, ISA_MIPS32R2);
9176             gen_helper_mtc0_srsconf1(cpu_env, arg);
9177             register_name = "SRSConf1";
9178             break;
9179         case 3:
9180             check_insn(ctx, ISA_MIPS32R2);
9181             gen_helper_mtc0_srsconf2(cpu_env, arg);
9182             register_name = "SRSConf2";
9183             break;
9184         case 4:
9185             check_insn(ctx, ISA_MIPS32R2);
9186             gen_helper_mtc0_srsconf3(cpu_env, arg);
9187             register_name = "SRSConf3";
9188             break;
9189         case 5:
9190             check_insn(ctx, ISA_MIPS32R2);
9191             gen_helper_mtc0_srsconf4(cpu_env, arg);
9192             register_name = "SRSConf4";
9193             break;
9194         case 6:
9195             check_pw(ctx);
9196             gen_helper_mtc0_pwctl(cpu_env, arg);
9197             register_name = "PWCtl";
9198             break;
9199         default:
9200             goto cp0_unimplemented;
9201         }
9202         break;
9203     case CP0_REGISTER_07:
9204         switch (sel) {
9205         case 0:
9206             check_insn(ctx, ISA_MIPS32R2);
9207             gen_helper_mtc0_hwrena(cpu_env, arg);
9208             ctx->base.is_jmp = DISAS_STOP;
9209             register_name = "HWREna";
9210             break;
9211         default:
9212             goto cp0_unimplemented;
9213         }
9214         break;
9215     case CP0_REGISTER_08:
9216         switch (sel) {
9217         case 0:
9218             /* ignored */
9219             register_name = "BadVAddr";
9220             break;
9221         case 1:
9222             /* ignored */
9223             register_name = "BadInstr";
9224             break;
9225         case 2:
9226             /* ignored */
9227             register_name = "BadInstrP";
9228             break;
9229         case 3:
9230             /* ignored */
9231             register_name = "BadInstrX";
9232             break;
9233         default:
9234             goto cp0_unimplemented;
9235         }
9236         break;
9237     case CP0_REGISTER_09:
9238         switch (sel) {
9239         case 0:
9240             gen_helper_mtc0_count(cpu_env, arg);
9241             register_name = "Count";
9242             break;
9243         case 6:
9244             CP0_CHECK(ctx->saar);
9245             gen_helper_mtc0_saari(cpu_env, arg);
9246             register_name = "SAARI";
9247             break;
9248         case 7:
9249             CP0_CHECK(ctx->saar);
9250             gen_helper_mtc0_saar(cpu_env, arg);
9251             register_name = "SAAR";
9252             break;
9253         default:
9254             goto cp0_unimplemented;
9255         }
9256         /* Stop translation as we may have switched the execution mode */
9257         ctx->base.is_jmp = DISAS_STOP;
9258         break;
9259     case CP0_REGISTER_10:
9260         switch (sel) {
9261         case 0:
9262             gen_helper_mtc0_entryhi(cpu_env, arg);
9263             register_name = "EntryHi";
9264             break;
9265         default:
9266             goto cp0_unimplemented;
9267         }
9268         break;
9269     case CP0_REGISTER_11:
9270         switch (sel) {
9271         case 0:
9272             gen_helper_mtc0_compare(cpu_env, arg);
9273             register_name = "Compare";
9274             break;
9275         /* 6,7 are implementation dependent */
9276         default:
9277             goto cp0_unimplemented;
9278         }
9279         /* Stop translation as we may have switched the execution mode */
9280         ctx->base.is_jmp = DISAS_STOP;
9281         break;
9282     case CP0_REGISTER_12:
9283         switch (sel) {
9284         case 0:
9285             save_cpu_state(ctx, 1);
9286             gen_helper_mtc0_status(cpu_env, arg);
9287             /* DISAS_STOP isn't good enough here, hflags may have changed. */
9288             gen_save_pc(ctx->base.pc_next + 4);
9289             ctx->base.is_jmp = DISAS_EXIT;
9290             register_name = "Status";
9291             break;
9292         case 1:
9293             check_insn(ctx, ISA_MIPS32R2);
9294             gen_helper_mtc0_intctl(cpu_env, arg);
9295             /* Stop translation as we may have switched the execution mode */
9296             ctx->base.is_jmp = DISAS_STOP;
9297             register_name = "IntCtl";
9298             break;
9299         case 2:
9300             check_insn(ctx, ISA_MIPS32R2);
9301             gen_helper_mtc0_srsctl(cpu_env, arg);
9302             /* Stop translation as we may have switched the execution mode */
9303             ctx->base.is_jmp = DISAS_STOP;
9304             register_name = "SRSCtl";
9305             break;
9306         case 3:
9307             check_insn(ctx, ISA_MIPS32R2);
9308             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
9309             /* Stop translation as we may have switched the execution mode */
9310             ctx->base.is_jmp = DISAS_STOP;
9311             register_name = "SRSMap";
9312             break;
9313         default:
9314             goto cp0_unimplemented;
9315         }
9316         break;
9317     case CP0_REGISTER_13:
9318         switch (sel) {
9319         case 0:
9320             save_cpu_state(ctx, 1);
9321             gen_helper_mtc0_cause(cpu_env, arg);
9322             /* Stop translation as we may have triggered an interrupt.
9323              * DISAS_STOP isn't sufficient, we need to ensure we break out of
9324              * translated code to check for pending interrupts.  */
9325             gen_save_pc(ctx->base.pc_next + 4);
9326             ctx->base.is_jmp = DISAS_EXIT;
9327             register_name = "Cause";
9328             break;
9329         default:
9330             goto cp0_unimplemented;
9331         }
9332         break;
9333     case CP0_REGISTER_14:
9334         switch (sel) {
9335         case 0:
9336             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
9337             register_name = "EPC";
9338             break;
9339         default:
9340             goto cp0_unimplemented;
9341         }
9342         break;
9343     case CP0_REGISTER_15:
9344         switch (sel) {
9345         case 0:
9346             /* ignored */
9347             register_name = "PRid";
9348             break;
9349         case 1:
9350             check_insn(ctx, ISA_MIPS32R2);
9351             gen_helper_mtc0_ebase(cpu_env, arg);
9352             register_name = "EBase";
9353             break;
9354         default:
9355             goto cp0_unimplemented;
9356         }
9357         break;
9358     case CP0_REGISTER_16:
9359         switch (sel) {
9360         case 0:
9361             gen_helper_mtc0_config0(cpu_env, arg);
9362             register_name = "Config";
9363             /* Stop translation as we may have switched the execution mode */
9364             ctx->base.is_jmp = DISAS_STOP;
9365             break;
9366         case 1:
9367             /* ignored, read only */
9368             register_name = "Config1";
9369             break;
9370         case 2:
9371             gen_helper_mtc0_config2(cpu_env, arg);
9372             register_name = "Config2";
9373             /* Stop translation as we may have switched the execution mode */
9374             ctx->base.is_jmp = DISAS_STOP;
9375             break;
9376         case 3:
9377             gen_helper_mtc0_config3(cpu_env, arg);
9378             register_name = "Config3";
9379             /* Stop translation as we may have switched the execution mode */
9380             ctx->base.is_jmp = DISAS_STOP;
9381             break;
9382         case 4:
9383             /* currently ignored */
9384             register_name = "Config4";
9385             break;
9386         case 5:
9387             gen_helper_mtc0_config5(cpu_env, arg);
9388             register_name = "Config5";
9389             /* Stop translation as we may have switched the execution mode */
9390             ctx->base.is_jmp = DISAS_STOP;
9391             break;
9392         /* 6,7 are implementation dependent */
9393         default:
9394             register_name = "Invalid config selector";
9395             goto cp0_unimplemented;
9396         }
9397         break;
9398     case CP0_REGISTER_17:
9399         switch (sel) {
9400         case 0:
9401             gen_helper_mtc0_lladdr(cpu_env, arg);
9402             register_name = "LLAddr";
9403             break;
9404         case 1:
9405             CP0_CHECK(ctx->mrp);
9406             gen_helper_mtc0_maar(cpu_env, arg);
9407             register_name = "MAAR";
9408             break;
9409         case 2:
9410             CP0_CHECK(ctx->mrp);
9411             gen_helper_mtc0_maari(cpu_env, arg);
9412             register_name = "MAARI";
9413             break;
9414         default:
9415             goto cp0_unimplemented;
9416         }
9417         break;
9418     case CP0_REGISTER_18:
9419         switch (sel) {
9420         case 0:
9421         case 1:
9422         case 2:
9423         case 3:
9424         case 4:
9425         case 5:
9426         case 6:
9427         case 7:
9428             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9429             gen_helper_0e1i(mtc0_watchlo, arg, sel);
9430             register_name = "WatchLo";
9431             break;
9432         default:
9433             goto cp0_unimplemented;
9434         }
9435         break;
9436     case CP0_REGISTER_19:
9437         switch (sel) {
9438         case 0:
9439         case 1:
9440         case 2:
9441         case 3:
9442         case 4:
9443         case 5:
9444         case 6:
9445         case 7:
9446             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9447             gen_helper_0e1i(mtc0_watchhi, arg, sel);
9448             register_name = "WatchHi";
9449             break;
9450         default:
9451             goto cp0_unimplemented;
9452         }
9453         break;
9454     case CP0_REGISTER_20:
9455         switch (sel) {
9456         case 0:
9457             check_insn(ctx, ISA_MIPS3);
9458             gen_helper_mtc0_xcontext(cpu_env, arg);
9459             register_name = "XContext";
9460             break;
9461         default:
9462             goto cp0_unimplemented;
9463         }
9464         break;
9465     case CP0_REGISTER_21:
9466        /* Officially reserved, but sel 0 is used for R1x000 framemask */
9467         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9468         switch (sel) {
9469         case 0:
9470             gen_helper_mtc0_framemask(cpu_env, arg);
9471             register_name = "Framemask";
9472             break;
9473         default:
9474             goto cp0_unimplemented;
9475         }
9476         break;
9477     case CP0_REGISTER_22:
9478         /* ignored */
9479         register_name = "Diagnostic"; /* implementation dependent */
9480         break;
9481     case CP0_REGISTER_23:
9482         switch (sel) {
9483         case 0:
9484             gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
9485             /* DISAS_STOP isn't good enough here, hflags may have changed. */
9486             gen_save_pc(ctx->base.pc_next + 4);
9487             ctx->base.is_jmp = DISAS_EXIT;
9488             register_name = "Debug";
9489             break;
9490         case 1:
9491 //            gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
9492             /* Stop translation as we may have switched the execution mode */
9493             ctx->base.is_jmp = DISAS_STOP;
9494             register_name = "TraceControl";
9495             goto cp0_unimplemented;
9496         case 2:
9497 //            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
9498             /* Stop translation as we may have switched the execution mode */
9499             ctx->base.is_jmp = DISAS_STOP;
9500             register_name = "TraceControl2";
9501             goto cp0_unimplemented;
9502         case 3:
9503 //            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
9504             /* Stop translation as we may have switched the execution mode */
9505             ctx->base.is_jmp = DISAS_STOP;
9506             register_name = "UserTraceData";
9507             goto cp0_unimplemented;
9508         case 4:
9509 //            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
9510             /* Stop translation as we may have switched the execution mode */
9511             ctx->base.is_jmp = DISAS_STOP;
9512             register_name = "TraceBPC";
9513             goto cp0_unimplemented;
9514         default:
9515             goto cp0_unimplemented;
9516         }
9517         break;
9518     case CP0_REGISTER_24:
9519         switch (sel) {
9520         case 0:
9521             /* EJTAG support */
9522             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
9523             register_name = "DEPC";
9524             break;
9525         default:
9526             goto cp0_unimplemented;
9527         }
9528         break;
9529     case CP0_REGISTER_25:
9530         switch (sel) {
9531         case 0:
9532             gen_helper_mtc0_performance0(cpu_env, arg);
9533             register_name = "Performance0";
9534             break;
9535         case 1:
9536 //            gen_helper_mtc0_performance1(cpu_env, arg);
9537             register_name = "Performance1";
9538             goto cp0_unimplemented;
9539         case 2:
9540 //            gen_helper_mtc0_performance2(cpu_env, arg);
9541             register_name = "Performance2";
9542             goto cp0_unimplemented;
9543         case 3:
9544 //            gen_helper_mtc0_performance3(cpu_env, arg);
9545             register_name = "Performance3";
9546             goto cp0_unimplemented;
9547         case 4:
9548 //            gen_helper_mtc0_performance4(cpu_env, arg);
9549             register_name = "Performance4";
9550             goto cp0_unimplemented;
9551         case 5:
9552 //            gen_helper_mtc0_performance5(cpu_env, arg);
9553             register_name = "Performance5";
9554             goto cp0_unimplemented;
9555         case 6:
9556 //            gen_helper_mtc0_performance6(cpu_env, arg);
9557             register_name = "Performance6";
9558             goto cp0_unimplemented;
9559         case 7:
9560 //            gen_helper_mtc0_performance7(cpu_env, arg);
9561             register_name = "Performance7";
9562             goto cp0_unimplemented;
9563         default:
9564             goto cp0_unimplemented;
9565         }
9566         break;
9567     case CP0_REGISTER_26:
9568         switch (sel) {
9569         case 0:
9570             gen_helper_mtc0_errctl(cpu_env, arg);
9571             ctx->base.is_jmp = DISAS_STOP;
9572             register_name = "ErrCtl";
9573             break;
9574         default:
9575             goto cp0_unimplemented;
9576         }
9577         break;
9578     case CP0_REGISTER_27:
9579         switch (sel) {
9580         case 0:
9581         case 1:
9582         case 2:
9583         case 3:
9584             /* ignored */
9585             register_name = "CacheErr";
9586             break;
9587         default:
9588             goto cp0_unimplemented;
9589         }
9590         break;
9591     case CP0_REGISTER_28:
9592         switch (sel) {
9593         case 0:
9594         case 2:
9595         case 4:
9596         case 6:
9597             gen_helper_mtc0_taglo(cpu_env, arg);
9598             register_name = "TagLo";
9599             break;
9600         case 1:
9601         case 3:
9602         case 5:
9603         case 7:
9604             gen_helper_mtc0_datalo(cpu_env, arg);
9605             register_name = "DataLo";
9606             break;
9607         default:
9608             goto cp0_unimplemented;
9609         }
9610         break;
9611     case CP0_REGISTER_29:
9612         switch (sel) {
9613         case 0:
9614         case 2:
9615         case 4:
9616         case 6:
9617             gen_helper_mtc0_taghi(cpu_env, arg);
9618             register_name = "TagHi";
9619             break;
9620         case 1:
9621         case 3:
9622         case 5:
9623         case 7:
9624             gen_helper_mtc0_datahi(cpu_env, arg);
9625             register_name = "DataHi";
9626             break;
9627         default:
9628             register_name = "invalid sel";
9629             goto cp0_unimplemented;
9630         }
9631         break;
9632     case CP0_REGISTER_30:
9633         switch (sel) {
9634         case 0:
9635             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
9636             register_name = "ErrorEPC";
9637             break;
9638         default:
9639             goto cp0_unimplemented;
9640         }
9641         break;
9642     case CP0_REGISTER_31:
9643         switch (sel) {
9644         case 0:
9645             /* EJTAG support */
9646             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
9647             register_name = "DESAVE";
9648             break;
9649         case 2:
9650         case 3:
9651         case 4:
9652         case 5:
9653         case 6:
9654         case 7:
9655             CP0_CHECK(ctx->kscrexist & (1 << sel));
9656             tcg_gen_st_tl(arg, cpu_env,
9657                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
9658             register_name = "KScratch";
9659             break;
9660         default:
9661             goto cp0_unimplemented;
9662         }
9663         break;
9664     default:
9665         goto cp0_unimplemented;
9666     }
9667     trace_mips_translate_c0("dmtc0", register_name, reg, sel);
9668
9669     /* For simplicity assume that all writes can cause interrupts.  */
9670     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
9671         gen_io_end();
9672         /* DISAS_STOP isn't sufficient, we need to ensure we break out of
9673          * translated code to check for pending interrupts.  */
9674         gen_save_pc(ctx->base.pc_next + 4);
9675         ctx->base.is_jmp = DISAS_EXIT;
9676     }
9677     return;
9678
9679 cp0_unimplemented:
9680     qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n",
9681                   register_name, reg, sel);
9682 }
9683 #endif /* TARGET_MIPS64 */
9684
9685 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
9686                      int u, int sel, int h)
9687 {
9688     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9689     TCGv t0 = tcg_temp_local_new();
9690
9691     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9692         ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9693          (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
9694         tcg_gen_movi_tl(t0, -1);
9695     else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9696              (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
9697         tcg_gen_movi_tl(t0, -1);
9698     else if (u == 0) {
9699         switch (rt) {
9700         case 1:
9701             switch (sel) {
9702             case 1:
9703                 gen_helper_mftc0_vpecontrol(t0, cpu_env);
9704                 break;
9705             case 2:
9706                 gen_helper_mftc0_vpeconf0(t0, cpu_env);
9707                 break;
9708             default:
9709                 goto die;
9710                 break;
9711             }
9712             break;
9713         case 2:
9714             switch (sel) {
9715             case 1:
9716                 gen_helper_mftc0_tcstatus(t0, cpu_env);
9717                 break;
9718             case 2:
9719                 gen_helper_mftc0_tcbind(t0, cpu_env);
9720                 break;
9721             case 3:
9722                 gen_helper_mftc0_tcrestart(t0, cpu_env);
9723                 break;
9724             case 4:
9725                 gen_helper_mftc0_tchalt(t0, cpu_env);
9726                 break;
9727             case 5:
9728                 gen_helper_mftc0_tccontext(t0, cpu_env);
9729                 break;
9730             case 6:
9731                 gen_helper_mftc0_tcschedule(t0, cpu_env);
9732                 break;
9733             case 7:
9734                 gen_helper_mftc0_tcschefback(t0, cpu_env);
9735                 break;
9736             default:
9737                 gen_mfc0(ctx, t0, rt, sel);
9738                 break;
9739             }
9740             break;
9741         case 10:
9742             switch (sel) {
9743             case 0:
9744                 gen_helper_mftc0_entryhi(t0, cpu_env);
9745                 break;
9746             default:
9747                 gen_mfc0(ctx, t0, rt, sel);
9748                 break;
9749             }
9750         case 12:
9751             switch (sel) {
9752             case 0:
9753                 gen_helper_mftc0_status(t0, cpu_env);
9754                 break;
9755             default:
9756                 gen_mfc0(ctx, t0, rt, sel);
9757                 break;
9758             }
9759         case 13:
9760             switch (sel) {
9761             case 0:
9762                 gen_helper_mftc0_cause(t0, cpu_env);
9763                 break;
9764             default:
9765                 goto die;
9766                 break;
9767             }
9768             break;
9769         case 14:
9770             switch (sel) {
9771             case 0:
9772                 gen_helper_mftc0_epc(t0, cpu_env);
9773                 break;
9774             default:
9775                 goto die;
9776                 break;
9777             }
9778             break;
9779         case 15:
9780             switch (sel) {
9781             case 1:
9782                 gen_helper_mftc0_ebase(t0, cpu_env);
9783                 break;
9784             default:
9785                 goto die;
9786                 break;
9787             }
9788             break;
9789         case 16:
9790             switch (sel) {
9791             case 0:
9792             case 1:
9793             case 2:
9794             case 3:
9795             case 4:
9796             case 5:
9797             case 6:
9798             case 7:
9799                 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
9800                 break;
9801             default:
9802                 goto die;
9803                 break;
9804             }
9805             break;
9806         case 23:
9807             switch (sel) {
9808             case 0:
9809                 gen_helper_mftc0_debug(t0, cpu_env);
9810                 break;
9811             default:
9812                 gen_mfc0(ctx, t0, rt, sel);
9813                 break;
9814             }
9815             break;
9816         default:
9817             gen_mfc0(ctx, t0, rt, sel);
9818         }
9819     } else switch (sel) {
9820     /* GPR registers. */
9821     case 0:
9822         gen_helper_1e0i(mftgpr, t0, rt);
9823         break;
9824     /* Auxiliary CPU registers */
9825     case 1:
9826         switch (rt) {
9827         case 0:
9828             gen_helper_1e0i(mftlo, t0, 0);
9829             break;
9830         case 1:
9831             gen_helper_1e0i(mfthi, t0, 0);
9832             break;
9833         case 2:
9834             gen_helper_1e0i(mftacx, t0, 0);
9835             break;
9836         case 4:
9837             gen_helper_1e0i(mftlo, t0, 1);
9838             break;
9839         case 5:
9840             gen_helper_1e0i(mfthi, t0, 1);
9841             break;
9842         case 6:
9843             gen_helper_1e0i(mftacx, t0, 1);
9844             break;
9845         case 8:
9846             gen_helper_1e0i(mftlo, t0, 2);
9847             break;
9848         case 9:
9849             gen_helper_1e0i(mfthi, t0, 2);
9850             break;
9851         case 10:
9852             gen_helper_1e0i(mftacx, t0, 2);
9853             break;
9854         case 12:
9855             gen_helper_1e0i(mftlo, t0, 3);
9856             break;
9857         case 13:
9858             gen_helper_1e0i(mfthi, t0, 3);
9859             break;
9860         case 14:
9861             gen_helper_1e0i(mftacx, t0, 3);
9862             break;
9863         case 16:
9864             gen_helper_mftdsp(t0, cpu_env);
9865             break;
9866         default:
9867             goto die;
9868         }
9869         break;
9870     /* Floating point (COP1). */
9871     case 2:
9872         /* XXX: For now we support only a single FPU context. */
9873         if (h == 0) {
9874             TCGv_i32 fp0 = tcg_temp_new_i32();
9875
9876             gen_load_fpr32(ctx, fp0, rt);
9877             tcg_gen_ext_i32_tl(t0, fp0);
9878             tcg_temp_free_i32(fp0);
9879         } else {
9880             TCGv_i32 fp0 = tcg_temp_new_i32();
9881
9882             gen_load_fpr32h(ctx, fp0, rt);
9883             tcg_gen_ext_i32_tl(t0, fp0);
9884             tcg_temp_free_i32(fp0);
9885         }
9886         break;
9887     case 3:
9888         /* XXX: For now we support only a single FPU context. */
9889         gen_helper_1e0i(cfc1, t0, rt);
9890         break;
9891     /* COP2: Not implemented. */
9892     case 4:
9893     case 5:
9894         /* fall through */
9895     default:
9896         goto die;
9897     }
9898     trace_mips_translate_tr("mftr", rt, u, sel, h);
9899     gen_store_gpr(t0, rd);
9900     tcg_temp_free(t0);
9901     return;
9902
9903 die:
9904     tcg_temp_free(t0);
9905     LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
9906     generate_exception_end(ctx, EXCP_RI);
9907 }
9908
9909 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
9910                      int u, int sel, int h)
9911 {
9912     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9913     TCGv t0 = tcg_temp_local_new();
9914
9915     gen_load_gpr(t0, rt);
9916     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9917         ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9918          (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
9919         /* NOP */ ;
9920     else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9921              (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
9922         /* NOP */ ;
9923     else if (u == 0) {
9924         switch (rd) {
9925         case 1:
9926             switch (sel) {
9927             case 1:
9928                 gen_helper_mttc0_vpecontrol(cpu_env, t0);
9929                 break;
9930             case 2:
9931                 gen_helper_mttc0_vpeconf0(cpu_env, t0);
9932                 break;
9933             default:
9934                 goto die;
9935                 break;
9936             }
9937             break;
9938         case 2:
9939             switch (sel) {
9940             case 1:
9941                 gen_helper_mttc0_tcstatus(cpu_env, t0);
9942                 break;
9943             case 2:
9944                 gen_helper_mttc0_tcbind(cpu_env, t0);
9945                 break;
9946             case 3:
9947                 gen_helper_mttc0_tcrestart(cpu_env, t0);
9948                 break;
9949             case 4:
9950                 gen_helper_mttc0_tchalt(cpu_env, t0);
9951                 break;
9952             case 5:
9953                 gen_helper_mttc0_tccontext(cpu_env, t0);
9954                 break;
9955             case 6:
9956                 gen_helper_mttc0_tcschedule(cpu_env, t0);
9957                 break;
9958             case 7:
9959                 gen_helper_mttc0_tcschefback(cpu_env, t0);
9960                 break;
9961             default:
9962                 gen_mtc0(ctx, t0, rd, sel);
9963                 break;
9964             }
9965             break;
9966         case 10:
9967             switch (sel) {
9968             case 0:
9969                 gen_helper_mttc0_entryhi(cpu_env, t0);
9970                 break;
9971             default:
9972                 gen_mtc0(ctx, t0, rd, sel);
9973                 break;
9974             }
9975         case 12:
9976             switch (sel) {
9977             case 0:
9978                 gen_helper_mttc0_status(cpu_env, t0);
9979                 break;
9980             default:
9981                 gen_mtc0(ctx, t0, rd, sel);
9982                 break;
9983             }
9984         case 13:
9985             switch (sel) {
9986             case 0:
9987                 gen_helper_mttc0_cause(cpu_env, t0);
9988                 break;
9989             default:
9990                 goto die;
9991                 break;
9992             }
9993             break;
9994         case 15:
9995             switch (sel) {
9996             case 1:
9997                 gen_helper_mttc0_ebase(cpu_env, t0);
9998                 break;
9999             default:
10000                 goto die;
10001                 break;
10002             }
10003             break;
10004         case 23:
10005             switch (sel) {
10006             case 0:
10007                 gen_helper_mttc0_debug(cpu_env, t0);
10008                 break;
10009             default:
10010                 gen_mtc0(ctx, t0, rd, sel);
10011                 break;
10012             }
10013             break;
10014         default:
10015             gen_mtc0(ctx, t0, rd, sel);
10016         }
10017     } else switch (sel) {
10018     /* GPR registers. */
10019     case 0:
10020         gen_helper_0e1i(mttgpr, t0, rd);
10021         break;
10022     /* Auxiliary CPU registers */
10023     case 1:
10024         switch (rd) {
10025         case 0:
10026             gen_helper_0e1i(mttlo, t0, 0);
10027             break;
10028         case 1:
10029             gen_helper_0e1i(mtthi, t0, 0);
10030             break;
10031         case 2:
10032             gen_helper_0e1i(mttacx, t0, 0);
10033             break;
10034         case 4:
10035             gen_helper_0e1i(mttlo, t0, 1);
10036             break;
10037         case 5:
10038             gen_helper_0e1i(mtthi, t0, 1);
10039             break;
10040         case 6:
10041             gen_helper_0e1i(mttacx, t0, 1);
10042             break;
10043         case 8:
10044             gen_helper_0e1i(mttlo, t0, 2);
10045             break;
10046         case 9:
10047             gen_helper_0e1i(mtthi, t0, 2);
10048             break;
10049         case 10:
10050             gen_helper_0e1i(mttacx, t0, 2);
10051             break;
10052         case 12:
10053             gen_helper_0e1i(mttlo, t0, 3);
10054             break;
10055         case 13:
10056             gen_helper_0e1i(mtthi, t0, 3);
10057             break;
10058         case 14:
10059             gen_helper_0e1i(mttacx, t0, 3);
10060             break;
10061         case 16:
10062             gen_helper_mttdsp(cpu_env, t0);
10063             break;
10064         default:
10065             goto die;
10066         }
10067         break;
10068     /* Floating point (COP1). */
10069     case 2:
10070         /* XXX: For now we support only a single FPU context. */
10071         if (h == 0) {
10072             TCGv_i32 fp0 = tcg_temp_new_i32();
10073
10074             tcg_gen_trunc_tl_i32(fp0, t0);
10075             gen_store_fpr32(ctx, fp0, rd);
10076             tcg_temp_free_i32(fp0);
10077         } else {
10078             TCGv_i32 fp0 = tcg_temp_new_i32();
10079
10080             tcg_gen_trunc_tl_i32(fp0, t0);
10081             gen_store_fpr32h(ctx, fp0, rd);
10082             tcg_temp_free_i32(fp0);
10083         }
10084         break;
10085     case 3:
10086         /* XXX: For now we support only a single FPU context. */
10087         {
10088             TCGv_i32 fs_tmp = tcg_const_i32(rd);
10089
10090             gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10091             tcg_temp_free_i32(fs_tmp);
10092         }
10093         /* Stop translation as we may have changed hflags */
10094         ctx->base.is_jmp = DISAS_STOP;
10095         break;
10096     /* COP2: Not implemented. */
10097     case 4:
10098     case 5:
10099         /* fall through */
10100     default:
10101         goto die;
10102     }
10103     trace_mips_translate_tr("mttr", rd, u, sel, h);
10104     tcg_temp_free(t0);
10105     return;
10106
10107 die:
10108     tcg_temp_free(t0);
10109     LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
10110     generate_exception_end(ctx, EXCP_RI);
10111 }
10112
10113 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
10114 {
10115     const char *opn = "ldst";
10116
10117     check_cp0_enabled(ctx);
10118     switch (opc) {
10119     case OPC_MFC0:
10120         if (rt == 0) {
10121             /* Treat as NOP. */
10122             return;
10123         }
10124         gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10125         opn = "mfc0";
10126         break;
10127     case OPC_MTC0:
10128         {
10129             TCGv t0 = tcg_temp_new();
10130
10131             gen_load_gpr(t0, rt);
10132             gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
10133             tcg_temp_free(t0);
10134         }
10135         opn = "mtc0";
10136         break;
10137 #if defined(TARGET_MIPS64)
10138     case OPC_DMFC0:
10139         check_insn(ctx, ISA_MIPS3);
10140         if (rt == 0) {
10141             /* Treat as NOP. */
10142             return;
10143         }
10144         gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10145         opn = "dmfc0";
10146         break;
10147     case OPC_DMTC0:
10148         check_insn(ctx, ISA_MIPS3);
10149         {
10150             TCGv t0 = tcg_temp_new();
10151
10152             gen_load_gpr(t0, rt);
10153             gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
10154             tcg_temp_free(t0);
10155         }
10156         opn = "dmtc0";
10157         break;
10158 #endif
10159     case OPC_MFHC0:
10160         check_mvh(ctx);
10161         if (rt == 0) {
10162             /* Treat as NOP. */
10163             return;
10164         }
10165         gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10166         opn = "mfhc0";
10167         break;
10168     case OPC_MTHC0:
10169         check_mvh(ctx);
10170         {
10171             TCGv t0 = tcg_temp_new();
10172             gen_load_gpr(t0, rt);
10173             gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
10174             tcg_temp_free(t0);
10175         }
10176         opn = "mthc0";
10177         break;
10178     case OPC_MFTR:
10179         check_cp0_enabled(ctx);
10180         if (rd == 0) {
10181             /* Treat as NOP. */
10182             return;
10183         }
10184         gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
10185                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
10186         opn = "mftr";
10187         break;
10188     case OPC_MTTR:
10189         check_cp0_enabled(ctx);
10190         gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
10191                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
10192         opn = "mttr";
10193         break;
10194     case OPC_TLBWI:
10195         opn = "tlbwi";
10196         if (!env->tlb->helper_tlbwi)
10197             goto die;
10198         gen_helper_tlbwi(cpu_env);
10199         break;
10200     case OPC_TLBINV:
10201         opn = "tlbinv";
10202         if (ctx->ie >= 2) {
10203             if (!env->tlb->helper_tlbinv) {
10204                 goto die;
10205             }
10206             gen_helper_tlbinv(cpu_env);
10207         } /* treat as nop if TLBINV not supported */
10208         break;
10209     case OPC_TLBINVF:
10210         opn = "tlbinvf";
10211         if (ctx->ie >= 2) {
10212             if (!env->tlb->helper_tlbinvf) {
10213                 goto die;
10214             }
10215             gen_helper_tlbinvf(cpu_env);
10216         } /* treat as nop if TLBINV not supported */
10217         break;
10218     case OPC_TLBWR:
10219         opn = "tlbwr";
10220         if (!env->tlb->helper_tlbwr)
10221             goto die;
10222         gen_helper_tlbwr(cpu_env);
10223         break;
10224     case OPC_TLBP:
10225         opn = "tlbp";
10226         if (!env->tlb->helper_tlbp)
10227             goto die;
10228         gen_helper_tlbp(cpu_env);
10229         break;
10230     case OPC_TLBR:
10231         opn = "tlbr";
10232         if (!env->tlb->helper_tlbr)
10233             goto die;
10234         gen_helper_tlbr(cpu_env);
10235         break;
10236     case OPC_ERET: /* OPC_ERETNC */
10237         if ((ctx->insn_flags & ISA_MIPS32R6) &&
10238             (ctx->hflags & MIPS_HFLAG_BMASK)) {
10239             goto die;
10240         } else {
10241             int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
10242             if (ctx->opcode & (1 << bit_shift)) {
10243                 /* OPC_ERETNC */
10244                 opn = "eretnc";
10245                 check_insn(ctx, ISA_MIPS32R5);
10246                 gen_helper_eretnc(cpu_env);
10247             } else {
10248                 /* OPC_ERET */
10249                 opn = "eret";
10250                 check_insn(ctx, ISA_MIPS2);
10251                 gen_helper_eret(cpu_env);
10252             }
10253             ctx->base.is_jmp = DISAS_EXIT;
10254         }
10255         break;
10256     case OPC_DERET:
10257         opn = "deret";
10258         check_insn(ctx, ISA_MIPS32);
10259         if ((ctx->insn_flags & ISA_MIPS32R6) &&
10260             (ctx->hflags & MIPS_HFLAG_BMASK)) {
10261             goto die;
10262         }
10263         if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10264             MIPS_INVAL(opn);
10265             generate_exception_end(ctx, EXCP_RI);
10266         } else {
10267             gen_helper_deret(cpu_env);
10268             ctx->base.is_jmp = DISAS_EXIT;
10269         }
10270         break;
10271     case OPC_WAIT:
10272         opn = "wait";
10273         check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
10274         if ((ctx->insn_flags & ISA_MIPS32R6) &&
10275             (ctx->hflags & MIPS_HFLAG_BMASK)) {
10276             goto die;
10277         }
10278         /* If we get an exception, we want to restart at next instruction */
10279         ctx->base.pc_next += 4;
10280         save_cpu_state(ctx, 1);
10281         ctx->base.pc_next -= 4;
10282         gen_helper_wait(cpu_env);
10283         ctx->base.is_jmp = DISAS_NORETURN;
10284         break;
10285     default:
10286  die:
10287         MIPS_INVAL(opn);
10288         generate_exception_end(ctx, EXCP_RI);
10289         return;
10290     }
10291     (void)opn; /* avoid a compiler warning */
10292 }
10293 #endif /* !CONFIG_USER_ONLY */
10294
10295 /* CP1 Branches (before delay slot) */
10296 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
10297                                 int32_t cc, int32_t offset)
10298 {
10299     target_ulong btarget;
10300     TCGv_i32 t0 = tcg_temp_new_i32();
10301
10302     if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
10303         generate_exception_end(ctx, EXCP_RI);
10304         goto out;
10305     }
10306
10307     if (cc != 0)
10308         check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
10309
10310     btarget = ctx->base.pc_next + 4 + offset;
10311
10312     switch (op) {
10313     case OPC_BC1F:
10314         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10315         tcg_gen_not_i32(t0, t0);
10316         tcg_gen_andi_i32(t0, t0, 1);
10317         tcg_gen_extu_i32_tl(bcond, t0);
10318         goto not_likely;
10319     case OPC_BC1FL:
10320         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10321         tcg_gen_not_i32(t0, t0);
10322         tcg_gen_andi_i32(t0, t0, 1);
10323         tcg_gen_extu_i32_tl(bcond, t0);
10324         goto likely;
10325     case OPC_BC1T:
10326         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10327         tcg_gen_andi_i32(t0, t0, 1);
10328         tcg_gen_extu_i32_tl(bcond, t0);
10329         goto not_likely;
10330     case OPC_BC1TL:
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     likely:
10335         ctx->hflags |= MIPS_HFLAG_BL;
10336         break;
10337     case OPC_BC1FANY2:
10338         {
10339             TCGv_i32 t1 = tcg_temp_new_i32();
10340             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10341             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10342             tcg_gen_nand_i32(t0, t0, t1);
10343             tcg_temp_free_i32(t1);
10344             tcg_gen_andi_i32(t0, t0, 1);
10345             tcg_gen_extu_i32_tl(bcond, t0);
10346         }
10347         goto not_likely;
10348     case OPC_BC1TANY2:
10349         {
10350             TCGv_i32 t1 = tcg_temp_new_i32();
10351             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10352             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10353             tcg_gen_or_i32(t0, t0, t1);
10354             tcg_temp_free_i32(t1);
10355             tcg_gen_andi_i32(t0, t0, 1);
10356             tcg_gen_extu_i32_tl(bcond, t0);
10357         }
10358         goto not_likely;
10359     case OPC_BC1FANY4:
10360         {
10361             TCGv_i32 t1 = tcg_temp_new_i32();
10362             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10363             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10364             tcg_gen_and_i32(t0, t0, t1);
10365             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
10366             tcg_gen_and_i32(t0, t0, t1);
10367             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
10368             tcg_gen_nand_i32(t0, t0, t1);
10369             tcg_temp_free_i32(t1);
10370             tcg_gen_andi_i32(t0, t0, 1);
10371             tcg_gen_extu_i32_tl(bcond, t0);
10372         }
10373         goto not_likely;
10374     case OPC_BC1TANY4:
10375         {
10376             TCGv_i32 t1 = tcg_temp_new_i32();
10377             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10378             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10379             tcg_gen_or_i32(t0, t0, t1);
10380             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
10381             tcg_gen_or_i32(t0, t0, t1);
10382             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
10383             tcg_gen_or_i32(t0, t0, t1);
10384             tcg_temp_free_i32(t1);
10385             tcg_gen_andi_i32(t0, t0, 1);
10386             tcg_gen_extu_i32_tl(bcond, t0);
10387         }
10388     not_likely:
10389         ctx->hflags |= MIPS_HFLAG_BC;
10390         break;
10391     default:
10392         MIPS_INVAL("cp1 cond branch");
10393         generate_exception_end(ctx, EXCP_RI);
10394         goto out;
10395     }
10396     ctx->btarget = btarget;
10397     ctx->hflags |= MIPS_HFLAG_BDS32;
10398  out:
10399     tcg_temp_free_i32(t0);
10400 }
10401
10402 /* R6 CP1 Branches */
10403 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
10404                                    int32_t ft, int32_t offset,
10405                                    int delayslot_size)
10406 {
10407     target_ulong btarget;
10408     TCGv_i64 t0 = tcg_temp_new_i64();
10409
10410     if (ctx->hflags & MIPS_HFLAG_BMASK) {
10411 #ifdef MIPS_DEBUG_DISAS
10412         LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10413                   "\n", ctx->base.pc_next);
10414 #endif
10415         generate_exception_end(ctx, EXCP_RI);
10416         goto out;
10417     }
10418
10419     gen_load_fpr64(ctx, t0, ft);
10420     tcg_gen_andi_i64(t0, t0, 1);
10421
10422     btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
10423
10424     switch (op) {
10425     case OPC_BC1EQZ:
10426         tcg_gen_xori_i64(t0, t0, 1);
10427         ctx->hflags |= MIPS_HFLAG_BC;
10428         break;
10429     case OPC_BC1NEZ:
10430         /* t0 already set */
10431         ctx->hflags |= MIPS_HFLAG_BC;
10432         break;
10433     default:
10434         MIPS_INVAL("cp1 cond branch");
10435         generate_exception_end(ctx, EXCP_RI);
10436         goto out;
10437     }
10438
10439     tcg_gen_trunc_i64_tl(bcond, t0);
10440
10441     ctx->btarget = btarget;
10442
10443     switch (delayslot_size) {
10444     case 2:
10445         ctx->hflags |= MIPS_HFLAG_BDS16;
10446         break;
10447     case 4:
10448         ctx->hflags |= MIPS_HFLAG_BDS32;
10449         break;
10450     }
10451
10452 out:
10453     tcg_temp_free_i64(t0);
10454 }
10455
10456 /* Coprocessor 1 (FPU) */
10457
10458 #define FOP(func, fmt) (((fmt) << 21) | (func))
10459
10460 enum fopcode {
10461     OPC_ADD_S = FOP(0, FMT_S),
10462     OPC_SUB_S = FOP(1, FMT_S),
10463     OPC_MUL_S = FOP(2, FMT_S),
10464     OPC_DIV_S = FOP(3, FMT_S),
10465     OPC_SQRT_S = FOP(4, FMT_S),
10466     OPC_ABS_S = FOP(5, FMT_S),
10467     OPC_MOV_S = FOP(6, FMT_S),
10468     OPC_NEG_S = FOP(7, FMT_S),
10469     OPC_ROUND_L_S = FOP(8, FMT_S),
10470     OPC_TRUNC_L_S = FOP(9, FMT_S),
10471     OPC_CEIL_L_S = FOP(10, FMT_S),
10472     OPC_FLOOR_L_S = FOP(11, FMT_S),
10473     OPC_ROUND_W_S = FOP(12, FMT_S),
10474     OPC_TRUNC_W_S = FOP(13, FMT_S),
10475     OPC_CEIL_W_S = FOP(14, FMT_S),
10476     OPC_FLOOR_W_S = FOP(15, FMT_S),
10477     OPC_SEL_S = FOP(16, FMT_S),
10478     OPC_MOVCF_S = FOP(17, FMT_S),
10479     OPC_MOVZ_S = FOP(18, FMT_S),
10480     OPC_MOVN_S = FOP(19, FMT_S),
10481     OPC_SELEQZ_S = FOP(20, FMT_S),
10482     OPC_RECIP_S = FOP(21, FMT_S),
10483     OPC_RSQRT_S = FOP(22, FMT_S),
10484     OPC_SELNEZ_S = FOP(23, FMT_S),
10485     OPC_MADDF_S = FOP(24, FMT_S),
10486     OPC_MSUBF_S = FOP(25, FMT_S),
10487     OPC_RINT_S = FOP(26, FMT_S),
10488     OPC_CLASS_S = FOP(27, FMT_S),
10489     OPC_MIN_S = FOP(28, FMT_S),
10490     OPC_RECIP2_S = FOP(28, FMT_S),
10491     OPC_MINA_S = FOP(29, FMT_S),
10492     OPC_RECIP1_S = FOP(29, FMT_S),
10493     OPC_MAX_S = FOP(30, FMT_S),
10494     OPC_RSQRT1_S = FOP(30, FMT_S),
10495     OPC_MAXA_S = FOP(31, FMT_S),
10496     OPC_RSQRT2_S = FOP(31, FMT_S),
10497     OPC_CVT_D_S = FOP(33, FMT_S),
10498     OPC_CVT_W_S = FOP(36, FMT_S),
10499     OPC_CVT_L_S = FOP(37, FMT_S),
10500     OPC_CVT_PS_S = FOP(38, FMT_S),
10501     OPC_CMP_F_S = FOP (48, FMT_S),
10502     OPC_CMP_UN_S = FOP (49, FMT_S),
10503     OPC_CMP_EQ_S = FOP (50, FMT_S),
10504     OPC_CMP_UEQ_S = FOP (51, FMT_S),
10505     OPC_CMP_OLT_S = FOP (52, FMT_S),
10506     OPC_CMP_ULT_S = FOP (53, FMT_S),
10507     OPC_CMP_OLE_S = FOP (54, FMT_S),
10508     OPC_CMP_ULE_S = FOP (55, FMT_S),
10509     OPC_CMP_SF_S = FOP (56, FMT_S),
10510     OPC_CMP_NGLE_S = FOP (57, FMT_S),
10511     OPC_CMP_SEQ_S = FOP (58, FMT_S),
10512     OPC_CMP_NGL_S = FOP (59, FMT_S),
10513     OPC_CMP_LT_S = FOP (60, FMT_S),
10514     OPC_CMP_NGE_S = FOP (61, FMT_S),
10515     OPC_CMP_LE_S = FOP (62, FMT_S),
10516     OPC_CMP_NGT_S = FOP (63, FMT_S),
10517
10518     OPC_ADD_D = FOP(0, FMT_D),
10519     OPC_SUB_D = FOP(1, FMT_D),
10520     OPC_MUL_D = FOP(2, FMT_D),
10521     OPC_DIV_D = FOP(3, FMT_D),
10522     OPC_SQRT_D = FOP(4, FMT_D),
10523     OPC_ABS_D = FOP(5, FMT_D),
10524     OPC_MOV_D = FOP(6, FMT_D),
10525     OPC_NEG_D = FOP(7, FMT_D),
10526     OPC_ROUND_L_D = FOP(8, FMT_D),
10527     OPC_TRUNC_L_D = FOP(9, FMT_D),
10528     OPC_CEIL_L_D = FOP(10, FMT_D),
10529     OPC_FLOOR_L_D = FOP(11, FMT_D),
10530     OPC_ROUND_W_D = FOP(12, FMT_D),
10531     OPC_TRUNC_W_D = FOP(13, FMT_D),
10532     OPC_CEIL_W_D = FOP(14, FMT_D),
10533     OPC_FLOOR_W_D = FOP(15, FMT_D),
10534     OPC_SEL_D = FOP(16, FMT_D),
10535     OPC_MOVCF_D = FOP(17, FMT_D),
10536     OPC_MOVZ_D = FOP(18, FMT_D),
10537     OPC_MOVN_D = FOP(19, FMT_D),
10538     OPC_SELEQZ_D = FOP(20, FMT_D),
10539     OPC_RECIP_D = FOP(21, FMT_D),
10540     OPC_RSQRT_D = FOP(22, FMT_D),
10541     OPC_SELNEZ_D = FOP(23, FMT_D),
10542     OPC_MADDF_D = FOP(24, FMT_D),
10543     OPC_MSUBF_D = FOP(25, FMT_D),
10544     OPC_RINT_D = FOP(26, FMT_D),
10545     OPC_CLASS_D = FOP(27, FMT_D),
10546     OPC_MIN_D = FOP(28, FMT_D),
10547     OPC_RECIP2_D = FOP(28, FMT_D),
10548     OPC_MINA_D = FOP(29, FMT_D),
10549     OPC_RECIP1_D = FOP(29, FMT_D),
10550     OPC_MAX_D = FOP(30, FMT_D),
10551     OPC_RSQRT1_D = FOP(30, FMT_D),
10552     OPC_MAXA_D = FOP(31, FMT_D),
10553     OPC_RSQRT2_D = FOP(31, FMT_D),
10554     OPC_CVT_S_D = FOP(32, FMT_D),
10555     OPC_CVT_W_D = FOP(36, FMT_D),
10556     OPC_CVT_L_D = FOP(37, FMT_D),
10557     OPC_CMP_F_D = FOP (48, FMT_D),
10558     OPC_CMP_UN_D = FOP (49, FMT_D),
10559     OPC_CMP_EQ_D = FOP (50, FMT_D),
10560     OPC_CMP_UEQ_D = FOP (51, FMT_D),
10561     OPC_CMP_OLT_D = FOP (52, FMT_D),
10562     OPC_CMP_ULT_D = FOP (53, FMT_D),
10563     OPC_CMP_OLE_D = FOP (54, FMT_D),
10564     OPC_CMP_ULE_D = FOP (55, FMT_D),
10565     OPC_CMP_SF_D = FOP (56, FMT_D),
10566     OPC_CMP_NGLE_D = FOP (57, FMT_D),
10567     OPC_CMP_SEQ_D = FOP (58, FMT_D),
10568     OPC_CMP_NGL_D = FOP (59, FMT_D),
10569     OPC_CMP_LT_D = FOP (60, FMT_D),
10570     OPC_CMP_NGE_D = FOP (61, FMT_D),
10571     OPC_CMP_LE_D = FOP (62, FMT_D),
10572     OPC_CMP_NGT_D = FOP (63, FMT_D),
10573
10574     OPC_CVT_S_W = FOP(32, FMT_W),
10575     OPC_CVT_D_W = FOP(33, FMT_W),
10576     OPC_CVT_S_L = FOP(32, FMT_L),
10577     OPC_CVT_D_L = FOP(33, FMT_L),
10578     OPC_CVT_PS_PW = FOP(38, FMT_W),
10579
10580     OPC_ADD_PS = FOP(0, FMT_PS),
10581     OPC_SUB_PS = FOP(1, FMT_PS),
10582     OPC_MUL_PS = FOP(2, FMT_PS),
10583     OPC_DIV_PS = FOP(3, FMT_PS),
10584     OPC_ABS_PS = FOP(5, FMT_PS),
10585     OPC_MOV_PS = FOP(6, FMT_PS),
10586     OPC_NEG_PS = FOP(7, FMT_PS),
10587     OPC_MOVCF_PS = FOP(17, FMT_PS),
10588     OPC_MOVZ_PS = FOP(18, FMT_PS),
10589     OPC_MOVN_PS = FOP(19, FMT_PS),
10590     OPC_ADDR_PS = FOP(24, FMT_PS),
10591     OPC_MULR_PS = FOP(26, FMT_PS),
10592     OPC_RECIP2_PS = FOP(28, FMT_PS),
10593     OPC_RECIP1_PS = FOP(29, FMT_PS),
10594     OPC_RSQRT1_PS = FOP(30, FMT_PS),
10595     OPC_RSQRT2_PS = FOP(31, FMT_PS),
10596
10597     OPC_CVT_S_PU = FOP(32, FMT_PS),
10598     OPC_CVT_PW_PS = FOP(36, FMT_PS),
10599     OPC_CVT_S_PL = FOP(40, FMT_PS),
10600     OPC_PLL_PS = FOP(44, FMT_PS),
10601     OPC_PLU_PS = FOP(45, FMT_PS),
10602     OPC_PUL_PS = FOP(46, FMT_PS),
10603     OPC_PUU_PS = FOP(47, FMT_PS),
10604     OPC_CMP_F_PS = FOP (48, FMT_PS),
10605     OPC_CMP_UN_PS = FOP (49, FMT_PS),
10606     OPC_CMP_EQ_PS = FOP (50, FMT_PS),
10607     OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
10608     OPC_CMP_OLT_PS = FOP (52, FMT_PS),
10609     OPC_CMP_ULT_PS = FOP (53, FMT_PS),
10610     OPC_CMP_OLE_PS = FOP (54, FMT_PS),
10611     OPC_CMP_ULE_PS = FOP (55, FMT_PS),
10612     OPC_CMP_SF_PS = FOP (56, FMT_PS),
10613     OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
10614     OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
10615     OPC_CMP_NGL_PS = FOP (59, FMT_PS),
10616     OPC_CMP_LT_PS = FOP (60, FMT_PS),
10617     OPC_CMP_NGE_PS = FOP (61, FMT_PS),
10618     OPC_CMP_LE_PS = FOP (62, FMT_PS),
10619     OPC_CMP_NGT_PS = FOP (63, FMT_PS),
10620 };
10621
10622 enum r6_f_cmp_op {
10623     R6_OPC_CMP_AF_S   = FOP(0, FMT_W),
10624     R6_OPC_CMP_UN_S   = FOP(1, FMT_W),
10625     R6_OPC_CMP_EQ_S   = FOP(2, FMT_W),
10626     R6_OPC_CMP_UEQ_S  = FOP(3, FMT_W),
10627     R6_OPC_CMP_LT_S   = FOP(4, FMT_W),
10628     R6_OPC_CMP_ULT_S  = FOP(5, FMT_W),
10629     R6_OPC_CMP_LE_S   = FOP(6, FMT_W),
10630     R6_OPC_CMP_ULE_S  = FOP(7, FMT_W),
10631     R6_OPC_CMP_SAF_S  = FOP(8, FMT_W),
10632     R6_OPC_CMP_SUN_S  = FOP(9, FMT_W),
10633     R6_OPC_CMP_SEQ_S  = FOP(10, FMT_W),
10634     R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
10635     R6_OPC_CMP_SLT_S  = FOP(12, FMT_W),
10636     R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
10637     R6_OPC_CMP_SLE_S  = FOP(14, FMT_W),
10638     R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
10639     R6_OPC_CMP_OR_S   = FOP(17, FMT_W),
10640     R6_OPC_CMP_UNE_S  = FOP(18, FMT_W),
10641     R6_OPC_CMP_NE_S   = FOP(19, FMT_W),
10642     R6_OPC_CMP_SOR_S  = FOP(25, FMT_W),
10643     R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
10644     R6_OPC_CMP_SNE_S  = FOP(27, FMT_W),
10645
10646     R6_OPC_CMP_AF_D   = FOP(0, FMT_L),
10647     R6_OPC_CMP_UN_D   = FOP(1, FMT_L),
10648     R6_OPC_CMP_EQ_D   = FOP(2, FMT_L),
10649     R6_OPC_CMP_UEQ_D  = FOP(3, FMT_L),
10650     R6_OPC_CMP_LT_D   = FOP(4, FMT_L),
10651     R6_OPC_CMP_ULT_D  = FOP(5, FMT_L),
10652     R6_OPC_CMP_LE_D   = FOP(6, FMT_L),
10653     R6_OPC_CMP_ULE_D  = FOP(7, FMT_L),
10654     R6_OPC_CMP_SAF_D  = FOP(8, FMT_L),
10655     R6_OPC_CMP_SUN_D  = FOP(9, FMT_L),
10656     R6_OPC_CMP_SEQ_D  = FOP(10, FMT_L),
10657     R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
10658     R6_OPC_CMP_SLT_D  = FOP(12, FMT_L),
10659     R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
10660     R6_OPC_CMP_SLE_D  = FOP(14, FMT_L),
10661     R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
10662     R6_OPC_CMP_OR_D   = FOP(17, FMT_L),
10663     R6_OPC_CMP_UNE_D  = FOP(18, FMT_L),
10664     R6_OPC_CMP_NE_D   = FOP(19, FMT_L),
10665     R6_OPC_CMP_SOR_D  = FOP(25, FMT_L),
10666     R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
10667     R6_OPC_CMP_SNE_D  = FOP(27, FMT_L),
10668 };
10669 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
10670 {
10671     TCGv t0 = tcg_temp_new();
10672
10673     switch (opc) {
10674     case OPC_MFC1:
10675         {
10676             TCGv_i32 fp0 = tcg_temp_new_i32();
10677
10678             gen_load_fpr32(ctx, fp0, fs);
10679             tcg_gen_ext_i32_tl(t0, fp0);
10680             tcg_temp_free_i32(fp0);
10681         }
10682         gen_store_gpr(t0, rt);
10683         break;
10684     case OPC_MTC1:
10685         gen_load_gpr(t0, rt);
10686         {
10687             TCGv_i32 fp0 = tcg_temp_new_i32();
10688
10689             tcg_gen_trunc_tl_i32(fp0, t0);
10690             gen_store_fpr32(ctx, fp0, fs);
10691             tcg_temp_free_i32(fp0);
10692         }
10693         break;
10694     case OPC_CFC1:
10695         gen_helper_1e0i(cfc1, t0, fs);
10696         gen_store_gpr(t0, rt);
10697         break;
10698     case OPC_CTC1:
10699         gen_load_gpr(t0, rt);
10700         save_cpu_state(ctx, 0);
10701         {
10702             TCGv_i32 fs_tmp = tcg_const_i32(fs);
10703
10704             gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10705             tcg_temp_free_i32(fs_tmp);
10706         }
10707         /* Stop translation as we may have changed hflags */
10708         ctx->base.is_jmp = DISAS_STOP;
10709         break;
10710 #if defined(TARGET_MIPS64)
10711     case OPC_DMFC1:
10712         gen_load_fpr64(ctx, t0, fs);
10713         gen_store_gpr(t0, rt);
10714         break;
10715     case OPC_DMTC1:
10716         gen_load_gpr(t0, rt);
10717         gen_store_fpr64(ctx, t0, fs);
10718         break;
10719 #endif
10720     case OPC_MFHC1:
10721         {
10722             TCGv_i32 fp0 = tcg_temp_new_i32();
10723
10724             gen_load_fpr32h(ctx, fp0, fs);
10725             tcg_gen_ext_i32_tl(t0, fp0);
10726             tcg_temp_free_i32(fp0);
10727         }
10728         gen_store_gpr(t0, rt);
10729         break;
10730     case OPC_MTHC1:
10731         gen_load_gpr(t0, rt);
10732         {
10733             TCGv_i32 fp0 = tcg_temp_new_i32();
10734
10735             tcg_gen_trunc_tl_i32(fp0, t0);
10736             gen_store_fpr32h(ctx, fp0, fs);
10737             tcg_temp_free_i32(fp0);
10738         }
10739         break;
10740     default:
10741         MIPS_INVAL("cp1 move");
10742         generate_exception_end(ctx, EXCP_RI);
10743         goto out;
10744     }
10745
10746  out:
10747     tcg_temp_free(t0);
10748 }
10749
10750 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
10751 {
10752     TCGLabel *l1;
10753     TCGCond cond;
10754     TCGv_i32 t0;
10755
10756     if (rd == 0) {
10757         /* Treat as NOP. */
10758         return;
10759     }
10760
10761     if (tf)
10762         cond = TCG_COND_EQ;
10763     else
10764         cond = TCG_COND_NE;
10765
10766     l1 = gen_new_label();
10767     t0 = tcg_temp_new_i32();
10768     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10769     tcg_gen_brcondi_i32(cond, t0, 0, l1);
10770     tcg_temp_free_i32(t0);
10771     if (rs == 0) {
10772         tcg_gen_movi_tl(cpu_gpr[rd], 0);
10773     } else {
10774         tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
10775     }
10776     gen_set_label(l1);
10777 }
10778
10779 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
10780                                int tf)
10781 {
10782     int cond;
10783     TCGv_i32 t0 = tcg_temp_new_i32();
10784     TCGLabel *l1 = gen_new_label();
10785
10786     if (tf)
10787         cond = TCG_COND_EQ;
10788     else
10789         cond = TCG_COND_NE;
10790
10791     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10792     tcg_gen_brcondi_i32(cond, t0, 0, l1);
10793     gen_load_fpr32(ctx, t0, fs);
10794     gen_store_fpr32(ctx, t0, fd);
10795     gen_set_label(l1);
10796     tcg_temp_free_i32(t0);
10797 }
10798
10799 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
10800 {
10801     int cond;
10802     TCGv_i32 t0 = tcg_temp_new_i32();
10803     TCGv_i64 fp0;
10804     TCGLabel *l1 = gen_new_label();
10805
10806     if (tf)
10807         cond = TCG_COND_EQ;
10808     else
10809         cond = TCG_COND_NE;
10810
10811     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10812     tcg_gen_brcondi_i32(cond, t0, 0, l1);
10813     tcg_temp_free_i32(t0);
10814     fp0 = tcg_temp_new_i64();
10815     gen_load_fpr64(ctx, fp0, fs);
10816     gen_store_fpr64(ctx, fp0, fd);
10817     tcg_temp_free_i64(fp0);
10818     gen_set_label(l1);
10819 }
10820
10821 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
10822                                 int cc, int tf)
10823 {
10824     int cond;
10825     TCGv_i32 t0 = tcg_temp_new_i32();
10826     TCGLabel *l1 = gen_new_label();
10827     TCGLabel *l2 = gen_new_label();
10828
10829     if (tf)
10830         cond = TCG_COND_EQ;
10831     else
10832         cond = TCG_COND_NE;
10833
10834     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10835     tcg_gen_brcondi_i32(cond, t0, 0, l1);
10836     gen_load_fpr32(ctx, t0, fs);
10837     gen_store_fpr32(ctx, t0, fd);
10838     gen_set_label(l1);
10839
10840     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
10841     tcg_gen_brcondi_i32(cond, t0, 0, l2);
10842     gen_load_fpr32h(ctx, t0, fs);
10843     gen_store_fpr32h(ctx, t0, fd);
10844     tcg_temp_free_i32(t0);
10845     gen_set_label(l2);
10846 }
10847
10848 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10849                       int fs)
10850 {
10851     TCGv_i32 t1 = tcg_const_i32(0);
10852     TCGv_i32 fp0 = tcg_temp_new_i32();
10853     TCGv_i32 fp1 = tcg_temp_new_i32();
10854     TCGv_i32 fp2 = tcg_temp_new_i32();
10855     gen_load_fpr32(ctx, fp0, fd);
10856     gen_load_fpr32(ctx, fp1, ft);
10857     gen_load_fpr32(ctx, fp2, fs);
10858
10859     switch (op1) {
10860     case OPC_SEL_S:
10861         tcg_gen_andi_i32(fp0, fp0, 1);
10862         tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10863         break;
10864     case OPC_SELEQZ_S:
10865         tcg_gen_andi_i32(fp1, fp1, 1);
10866         tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10867         break;
10868     case OPC_SELNEZ_S:
10869         tcg_gen_andi_i32(fp1, fp1, 1);
10870         tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10871         break;
10872     default:
10873         MIPS_INVAL("gen_sel_s");
10874         generate_exception_end(ctx, EXCP_RI);
10875         break;
10876     }
10877
10878     gen_store_fpr32(ctx, fp0, fd);
10879     tcg_temp_free_i32(fp2);
10880     tcg_temp_free_i32(fp1);
10881     tcg_temp_free_i32(fp0);
10882     tcg_temp_free_i32(t1);
10883 }
10884
10885 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10886                       int fs)
10887 {
10888     TCGv_i64 t1 = tcg_const_i64(0);
10889     TCGv_i64 fp0 = tcg_temp_new_i64();
10890     TCGv_i64 fp1 = tcg_temp_new_i64();
10891     TCGv_i64 fp2 = tcg_temp_new_i64();
10892     gen_load_fpr64(ctx, fp0, fd);
10893     gen_load_fpr64(ctx, fp1, ft);
10894     gen_load_fpr64(ctx, fp2, fs);
10895
10896     switch (op1) {
10897     case OPC_SEL_D:
10898         tcg_gen_andi_i64(fp0, fp0, 1);
10899         tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10900         break;
10901     case OPC_SELEQZ_D:
10902         tcg_gen_andi_i64(fp1, fp1, 1);
10903         tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10904         break;
10905     case OPC_SELNEZ_D:
10906         tcg_gen_andi_i64(fp1, fp1, 1);
10907         tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10908         break;
10909     default:
10910         MIPS_INVAL("gen_sel_d");
10911         generate_exception_end(ctx, EXCP_RI);
10912         break;
10913     }
10914
10915     gen_store_fpr64(ctx, fp0, fd);
10916     tcg_temp_free_i64(fp2);
10917     tcg_temp_free_i64(fp1);
10918     tcg_temp_free_i64(fp0);
10919     tcg_temp_free_i64(t1);
10920 }
10921
10922 static void gen_farith (DisasContext *ctx, enum fopcode op1,
10923                         int ft, int fs, int fd, int cc)
10924 {
10925     uint32_t func = ctx->opcode & 0x3f;
10926     switch (op1) {
10927     case OPC_ADD_S:
10928         {
10929             TCGv_i32 fp0 = tcg_temp_new_i32();
10930             TCGv_i32 fp1 = tcg_temp_new_i32();
10931
10932             gen_load_fpr32(ctx, fp0, fs);
10933             gen_load_fpr32(ctx, fp1, ft);
10934             gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
10935             tcg_temp_free_i32(fp1);
10936             gen_store_fpr32(ctx, fp0, fd);
10937             tcg_temp_free_i32(fp0);
10938         }
10939         break;
10940     case OPC_SUB_S:
10941         {
10942             TCGv_i32 fp0 = tcg_temp_new_i32();
10943             TCGv_i32 fp1 = tcg_temp_new_i32();
10944
10945             gen_load_fpr32(ctx, fp0, fs);
10946             gen_load_fpr32(ctx, fp1, ft);
10947             gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
10948             tcg_temp_free_i32(fp1);
10949             gen_store_fpr32(ctx, fp0, fd);
10950             tcg_temp_free_i32(fp0);
10951         }
10952         break;
10953     case OPC_MUL_S:
10954         {
10955             TCGv_i32 fp0 = tcg_temp_new_i32();
10956             TCGv_i32 fp1 = tcg_temp_new_i32();
10957
10958             gen_load_fpr32(ctx, fp0, fs);
10959             gen_load_fpr32(ctx, fp1, ft);
10960             gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
10961             tcg_temp_free_i32(fp1);
10962             gen_store_fpr32(ctx, fp0, fd);
10963             tcg_temp_free_i32(fp0);
10964         }
10965         break;
10966     case OPC_DIV_S:
10967         {
10968             TCGv_i32 fp0 = tcg_temp_new_i32();
10969             TCGv_i32 fp1 = tcg_temp_new_i32();
10970
10971             gen_load_fpr32(ctx, fp0, fs);
10972             gen_load_fpr32(ctx, fp1, ft);
10973             gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
10974             tcg_temp_free_i32(fp1);
10975             gen_store_fpr32(ctx, fp0, fd);
10976             tcg_temp_free_i32(fp0);
10977         }
10978         break;
10979     case OPC_SQRT_S:
10980         {
10981             TCGv_i32 fp0 = tcg_temp_new_i32();
10982
10983             gen_load_fpr32(ctx, fp0, fs);
10984             gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
10985             gen_store_fpr32(ctx, fp0, fd);
10986             tcg_temp_free_i32(fp0);
10987         }
10988         break;
10989     case OPC_ABS_S:
10990         {
10991             TCGv_i32 fp0 = tcg_temp_new_i32();
10992
10993             gen_load_fpr32(ctx, fp0, fs);
10994             if (ctx->abs2008) {
10995                 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
10996             } else {
10997                 gen_helper_float_abs_s(fp0, fp0);
10998             }
10999             gen_store_fpr32(ctx, fp0, fd);
11000             tcg_temp_free_i32(fp0);
11001         }
11002         break;
11003     case OPC_MOV_S:
11004         {
11005             TCGv_i32 fp0 = tcg_temp_new_i32();
11006
11007             gen_load_fpr32(ctx, fp0, fs);
11008             gen_store_fpr32(ctx, fp0, fd);
11009             tcg_temp_free_i32(fp0);
11010         }
11011         break;
11012     case OPC_NEG_S:
11013         {
11014             TCGv_i32 fp0 = tcg_temp_new_i32();
11015
11016             gen_load_fpr32(ctx, fp0, fs);
11017             if (ctx->abs2008) {
11018                 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
11019             } else {
11020                 gen_helper_float_chs_s(fp0, fp0);
11021             }
11022             gen_store_fpr32(ctx, fp0, fd);
11023             tcg_temp_free_i32(fp0);
11024         }
11025         break;
11026     case OPC_ROUND_L_S:
11027         check_cp1_64bitmode(ctx);
11028         {
11029             TCGv_i32 fp32 = tcg_temp_new_i32();
11030             TCGv_i64 fp64 = tcg_temp_new_i64();
11031
11032             gen_load_fpr32(ctx, fp32, fs);
11033             if (ctx->nan2008) {
11034                 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
11035             } else {
11036                 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
11037             }
11038             tcg_temp_free_i32(fp32);
11039             gen_store_fpr64(ctx, fp64, fd);
11040             tcg_temp_free_i64(fp64);
11041         }
11042         break;
11043     case OPC_TRUNC_L_S:
11044         check_cp1_64bitmode(ctx);
11045         {
11046             TCGv_i32 fp32 = tcg_temp_new_i32();
11047             TCGv_i64 fp64 = tcg_temp_new_i64();
11048
11049             gen_load_fpr32(ctx, fp32, fs);
11050             if (ctx->nan2008) {
11051                 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
11052             } else {
11053                 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
11054             }
11055             tcg_temp_free_i32(fp32);
11056             gen_store_fpr64(ctx, fp64, fd);
11057             tcg_temp_free_i64(fp64);
11058         }
11059         break;
11060     case OPC_CEIL_L_S:
11061         check_cp1_64bitmode(ctx);
11062         {
11063             TCGv_i32 fp32 = tcg_temp_new_i32();
11064             TCGv_i64 fp64 = tcg_temp_new_i64();
11065
11066             gen_load_fpr32(ctx, fp32, fs);
11067             if (ctx->nan2008) {
11068                 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
11069             } else {
11070                 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
11071             }
11072             tcg_temp_free_i32(fp32);
11073             gen_store_fpr64(ctx, fp64, fd);
11074             tcg_temp_free_i64(fp64);
11075         }
11076         break;
11077     case OPC_FLOOR_L_S:
11078         check_cp1_64bitmode(ctx);
11079         {
11080             TCGv_i32 fp32 = tcg_temp_new_i32();
11081             TCGv_i64 fp64 = tcg_temp_new_i64();
11082
11083             gen_load_fpr32(ctx, fp32, fs);
11084             if (ctx->nan2008) {
11085                 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
11086             } else {
11087                 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
11088             }
11089             tcg_temp_free_i32(fp32);
11090             gen_store_fpr64(ctx, fp64, fd);
11091             tcg_temp_free_i64(fp64);
11092         }
11093         break;
11094     case OPC_ROUND_W_S:
11095         {
11096             TCGv_i32 fp0 = tcg_temp_new_i32();
11097
11098             gen_load_fpr32(ctx, fp0, fs);
11099             if (ctx->nan2008) {
11100                 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
11101             } else {
11102                 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
11103             }
11104             gen_store_fpr32(ctx, fp0, fd);
11105             tcg_temp_free_i32(fp0);
11106         }
11107         break;
11108     case OPC_TRUNC_W_S:
11109         {
11110             TCGv_i32 fp0 = tcg_temp_new_i32();
11111
11112             gen_load_fpr32(ctx, fp0, fs);
11113             if (ctx->nan2008) {
11114                 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
11115             } else {
11116                 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
11117             }
11118             gen_store_fpr32(ctx, fp0, fd);
11119             tcg_temp_free_i32(fp0);
11120         }
11121         break;
11122     case OPC_CEIL_W_S:
11123         {
11124             TCGv_i32 fp0 = tcg_temp_new_i32();
11125
11126             gen_load_fpr32(ctx, fp0, fs);
11127             if (ctx->nan2008) {
11128                 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
11129             } else {
11130                 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
11131             }
11132             gen_store_fpr32(ctx, fp0, fd);
11133             tcg_temp_free_i32(fp0);
11134         }
11135         break;
11136     case OPC_FLOOR_W_S:
11137         {
11138             TCGv_i32 fp0 = tcg_temp_new_i32();
11139
11140             gen_load_fpr32(ctx, fp0, fs);
11141             if (ctx->nan2008) {
11142                 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
11143             } else {
11144                 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
11145             }
11146             gen_store_fpr32(ctx, fp0, fd);
11147             tcg_temp_free_i32(fp0);
11148         }
11149         break;
11150     case OPC_SEL_S:
11151         check_insn(ctx, ISA_MIPS32R6);
11152         gen_sel_s(ctx, op1, fd, ft, fs);
11153         break;
11154     case OPC_SELEQZ_S:
11155         check_insn(ctx, ISA_MIPS32R6);
11156         gen_sel_s(ctx, op1, fd, ft, fs);
11157         break;
11158     case OPC_SELNEZ_S:
11159         check_insn(ctx, ISA_MIPS32R6);
11160         gen_sel_s(ctx, op1, fd, ft, fs);
11161         break;
11162     case OPC_MOVCF_S:
11163         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11164         gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11165         break;
11166     case OPC_MOVZ_S:
11167         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11168         {
11169             TCGLabel *l1 = gen_new_label();
11170             TCGv_i32 fp0;
11171
11172             if (ft != 0) {
11173                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11174             }
11175             fp0 = tcg_temp_new_i32();
11176             gen_load_fpr32(ctx, fp0, fs);
11177             gen_store_fpr32(ctx, fp0, fd);
11178             tcg_temp_free_i32(fp0);
11179             gen_set_label(l1);
11180         }
11181         break;
11182     case OPC_MOVN_S:
11183         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11184         {
11185             TCGLabel *l1 = gen_new_label();
11186             TCGv_i32 fp0;
11187
11188             if (ft != 0) {
11189                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11190                 fp0 = tcg_temp_new_i32();
11191                 gen_load_fpr32(ctx, fp0, fs);
11192                 gen_store_fpr32(ctx, fp0, fd);
11193                 tcg_temp_free_i32(fp0);
11194                 gen_set_label(l1);
11195             }
11196         }
11197         break;
11198     case OPC_RECIP_S:
11199         {
11200             TCGv_i32 fp0 = tcg_temp_new_i32();
11201
11202             gen_load_fpr32(ctx, fp0, fs);
11203             gen_helper_float_recip_s(fp0, cpu_env, fp0);
11204             gen_store_fpr32(ctx, fp0, fd);
11205             tcg_temp_free_i32(fp0);
11206         }
11207         break;
11208     case OPC_RSQRT_S:
11209         {
11210             TCGv_i32 fp0 = tcg_temp_new_i32();
11211
11212             gen_load_fpr32(ctx, fp0, fs);
11213             gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
11214             gen_store_fpr32(ctx, fp0, fd);
11215             tcg_temp_free_i32(fp0);
11216         }
11217         break;
11218     case OPC_MADDF_S:
11219         check_insn(ctx, ISA_MIPS32R6);
11220         {
11221             TCGv_i32 fp0 = tcg_temp_new_i32();
11222             TCGv_i32 fp1 = tcg_temp_new_i32();
11223             TCGv_i32 fp2 = tcg_temp_new_i32();
11224             gen_load_fpr32(ctx, fp0, fs);
11225             gen_load_fpr32(ctx, fp1, ft);
11226             gen_load_fpr32(ctx, fp2, fd);
11227             gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
11228             gen_store_fpr32(ctx, fp2, fd);
11229             tcg_temp_free_i32(fp2);
11230             tcg_temp_free_i32(fp1);
11231             tcg_temp_free_i32(fp0);
11232         }
11233         break;
11234     case OPC_MSUBF_S:
11235         check_insn(ctx, ISA_MIPS32R6);
11236         {
11237             TCGv_i32 fp0 = tcg_temp_new_i32();
11238             TCGv_i32 fp1 = tcg_temp_new_i32();
11239             TCGv_i32 fp2 = tcg_temp_new_i32();
11240             gen_load_fpr32(ctx, fp0, fs);
11241             gen_load_fpr32(ctx, fp1, ft);
11242             gen_load_fpr32(ctx, fp2, fd);
11243             gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
11244             gen_store_fpr32(ctx, fp2, fd);
11245             tcg_temp_free_i32(fp2);
11246             tcg_temp_free_i32(fp1);
11247             tcg_temp_free_i32(fp0);
11248         }
11249         break;
11250     case OPC_RINT_S:
11251         check_insn(ctx, ISA_MIPS32R6);
11252         {
11253             TCGv_i32 fp0 = tcg_temp_new_i32();
11254             gen_load_fpr32(ctx, fp0, fs);
11255             gen_helper_float_rint_s(fp0, cpu_env, fp0);
11256             gen_store_fpr32(ctx, fp0, fd);
11257             tcg_temp_free_i32(fp0);
11258         }
11259         break;
11260     case OPC_CLASS_S:
11261         check_insn(ctx, ISA_MIPS32R6);
11262         {
11263             TCGv_i32 fp0 = tcg_temp_new_i32();
11264             gen_load_fpr32(ctx, fp0, fs);
11265             gen_helper_float_class_s(fp0, cpu_env, fp0);
11266             gen_store_fpr32(ctx, fp0, fd);
11267             tcg_temp_free_i32(fp0);
11268         }
11269         break;
11270     case OPC_MIN_S: /* OPC_RECIP2_S */
11271         if (ctx->insn_flags & ISA_MIPS32R6) {
11272             /* OPC_MIN_S */
11273             TCGv_i32 fp0 = tcg_temp_new_i32();
11274             TCGv_i32 fp1 = tcg_temp_new_i32();
11275             TCGv_i32 fp2 = tcg_temp_new_i32();
11276             gen_load_fpr32(ctx, fp0, fs);
11277             gen_load_fpr32(ctx, fp1, ft);
11278             gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
11279             gen_store_fpr32(ctx, fp2, fd);
11280             tcg_temp_free_i32(fp2);
11281             tcg_temp_free_i32(fp1);
11282             tcg_temp_free_i32(fp0);
11283         } else {
11284             /* OPC_RECIP2_S */
11285             check_cp1_64bitmode(ctx);
11286             {
11287                 TCGv_i32 fp0 = tcg_temp_new_i32();
11288                 TCGv_i32 fp1 = tcg_temp_new_i32();
11289
11290                 gen_load_fpr32(ctx, fp0, fs);
11291                 gen_load_fpr32(ctx, fp1, ft);
11292                 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
11293                 tcg_temp_free_i32(fp1);
11294                 gen_store_fpr32(ctx, fp0, fd);
11295                 tcg_temp_free_i32(fp0);
11296             }
11297         }
11298         break;
11299     case OPC_MINA_S: /* OPC_RECIP1_S */
11300         if (ctx->insn_flags & ISA_MIPS32R6) {
11301             /* OPC_MINA_S */
11302             TCGv_i32 fp0 = tcg_temp_new_i32();
11303             TCGv_i32 fp1 = tcg_temp_new_i32();
11304             TCGv_i32 fp2 = tcg_temp_new_i32();
11305             gen_load_fpr32(ctx, fp0, fs);
11306             gen_load_fpr32(ctx, fp1, ft);
11307             gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
11308             gen_store_fpr32(ctx, fp2, fd);
11309             tcg_temp_free_i32(fp2);
11310             tcg_temp_free_i32(fp1);
11311             tcg_temp_free_i32(fp0);
11312         } else {
11313             /* OPC_RECIP1_S */
11314             check_cp1_64bitmode(ctx);
11315             {
11316                 TCGv_i32 fp0 = tcg_temp_new_i32();
11317
11318                 gen_load_fpr32(ctx, fp0, fs);
11319                 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
11320                 gen_store_fpr32(ctx, fp0, fd);
11321                 tcg_temp_free_i32(fp0);
11322             }
11323         }
11324         break;
11325     case OPC_MAX_S: /* OPC_RSQRT1_S */
11326         if (ctx->insn_flags & ISA_MIPS32R6) {
11327             /* OPC_MAX_S */
11328             TCGv_i32 fp0 = tcg_temp_new_i32();
11329             TCGv_i32 fp1 = tcg_temp_new_i32();
11330             gen_load_fpr32(ctx, fp0, fs);
11331             gen_load_fpr32(ctx, fp1, ft);
11332             gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
11333             gen_store_fpr32(ctx, fp1, fd);
11334             tcg_temp_free_i32(fp1);
11335             tcg_temp_free_i32(fp0);
11336         } else {
11337             /* OPC_RSQRT1_S */
11338             check_cp1_64bitmode(ctx);
11339             {
11340                 TCGv_i32 fp0 = tcg_temp_new_i32();
11341
11342                 gen_load_fpr32(ctx, fp0, fs);
11343                 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
11344                 gen_store_fpr32(ctx, fp0, fd);
11345                 tcg_temp_free_i32(fp0);
11346             }
11347         }
11348         break;
11349     case OPC_MAXA_S: /* OPC_RSQRT2_S */
11350         if (ctx->insn_flags & ISA_MIPS32R6) {
11351             /* OPC_MAXA_S */
11352             TCGv_i32 fp0 = tcg_temp_new_i32();
11353             TCGv_i32 fp1 = tcg_temp_new_i32();
11354             gen_load_fpr32(ctx, fp0, fs);
11355             gen_load_fpr32(ctx, fp1, ft);
11356             gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
11357             gen_store_fpr32(ctx, fp1, fd);
11358             tcg_temp_free_i32(fp1);
11359             tcg_temp_free_i32(fp0);
11360         } else {
11361             /* OPC_RSQRT2_S */
11362             check_cp1_64bitmode(ctx);
11363             {
11364                 TCGv_i32 fp0 = tcg_temp_new_i32();
11365                 TCGv_i32 fp1 = tcg_temp_new_i32();
11366
11367                 gen_load_fpr32(ctx, fp0, fs);
11368                 gen_load_fpr32(ctx, fp1, ft);
11369                 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
11370                 tcg_temp_free_i32(fp1);
11371                 gen_store_fpr32(ctx, fp0, fd);
11372                 tcg_temp_free_i32(fp0);
11373             }
11374         }
11375         break;
11376     case OPC_CVT_D_S:
11377         check_cp1_registers(ctx, fd);
11378         {
11379             TCGv_i32 fp32 = tcg_temp_new_i32();
11380             TCGv_i64 fp64 = tcg_temp_new_i64();
11381
11382             gen_load_fpr32(ctx, fp32, fs);
11383             gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
11384             tcg_temp_free_i32(fp32);
11385             gen_store_fpr64(ctx, fp64, fd);
11386             tcg_temp_free_i64(fp64);
11387         }
11388         break;
11389     case OPC_CVT_W_S:
11390         {
11391             TCGv_i32 fp0 = tcg_temp_new_i32();
11392
11393             gen_load_fpr32(ctx, fp0, fs);
11394             if (ctx->nan2008) {
11395                 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
11396             } else {
11397                 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
11398             }
11399             gen_store_fpr32(ctx, fp0, fd);
11400             tcg_temp_free_i32(fp0);
11401         }
11402         break;
11403     case OPC_CVT_L_S:
11404         check_cp1_64bitmode(ctx);
11405         {
11406             TCGv_i32 fp32 = tcg_temp_new_i32();
11407             TCGv_i64 fp64 = tcg_temp_new_i64();
11408
11409             gen_load_fpr32(ctx, fp32, fs);
11410             if (ctx->nan2008) {
11411                 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
11412             } else {
11413                 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
11414             }
11415             tcg_temp_free_i32(fp32);
11416             gen_store_fpr64(ctx, fp64, fd);
11417             tcg_temp_free_i64(fp64);
11418         }
11419         break;
11420     case OPC_CVT_PS_S:
11421         check_ps(ctx);
11422         {
11423             TCGv_i64 fp64 = tcg_temp_new_i64();
11424             TCGv_i32 fp32_0 = tcg_temp_new_i32();
11425             TCGv_i32 fp32_1 = tcg_temp_new_i32();
11426
11427             gen_load_fpr32(ctx, fp32_0, fs);
11428             gen_load_fpr32(ctx, fp32_1, ft);
11429             tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
11430             tcg_temp_free_i32(fp32_1);
11431             tcg_temp_free_i32(fp32_0);
11432             gen_store_fpr64(ctx, fp64, fd);
11433             tcg_temp_free_i64(fp64);
11434         }
11435         break;
11436     case OPC_CMP_F_S:
11437     case OPC_CMP_UN_S:
11438     case OPC_CMP_EQ_S:
11439     case OPC_CMP_UEQ_S:
11440     case OPC_CMP_OLT_S:
11441     case OPC_CMP_ULT_S:
11442     case OPC_CMP_OLE_S:
11443     case OPC_CMP_ULE_S:
11444     case OPC_CMP_SF_S:
11445     case OPC_CMP_NGLE_S:
11446     case OPC_CMP_SEQ_S:
11447     case OPC_CMP_NGL_S:
11448     case OPC_CMP_LT_S:
11449     case OPC_CMP_NGE_S:
11450     case OPC_CMP_LE_S:
11451     case OPC_CMP_NGT_S:
11452         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11453         if (ctx->opcode & (1 << 6)) {
11454             gen_cmpabs_s(ctx, func-48, ft, fs, cc);
11455         } else {
11456             gen_cmp_s(ctx, func-48, ft, fs, cc);
11457         }
11458         break;
11459     case OPC_ADD_D:
11460         check_cp1_registers(ctx, fs | ft | fd);
11461         {
11462             TCGv_i64 fp0 = tcg_temp_new_i64();
11463             TCGv_i64 fp1 = tcg_temp_new_i64();
11464
11465             gen_load_fpr64(ctx, fp0, fs);
11466             gen_load_fpr64(ctx, fp1, ft);
11467             gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
11468             tcg_temp_free_i64(fp1);
11469             gen_store_fpr64(ctx, fp0, fd);
11470             tcg_temp_free_i64(fp0);
11471         }
11472         break;
11473     case OPC_SUB_D:
11474         check_cp1_registers(ctx, fs | ft | fd);
11475         {
11476             TCGv_i64 fp0 = tcg_temp_new_i64();
11477             TCGv_i64 fp1 = tcg_temp_new_i64();
11478
11479             gen_load_fpr64(ctx, fp0, fs);
11480             gen_load_fpr64(ctx, fp1, ft);
11481             gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
11482             tcg_temp_free_i64(fp1);
11483             gen_store_fpr64(ctx, fp0, fd);
11484             tcg_temp_free_i64(fp0);
11485         }
11486         break;
11487     case OPC_MUL_D:
11488         check_cp1_registers(ctx, fs | ft | fd);
11489         {
11490             TCGv_i64 fp0 = tcg_temp_new_i64();
11491             TCGv_i64 fp1 = tcg_temp_new_i64();
11492
11493             gen_load_fpr64(ctx, fp0, fs);
11494             gen_load_fpr64(ctx, fp1, ft);
11495             gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
11496             tcg_temp_free_i64(fp1);
11497             gen_store_fpr64(ctx, fp0, fd);
11498             tcg_temp_free_i64(fp0);
11499         }
11500         break;
11501     case OPC_DIV_D:
11502         check_cp1_registers(ctx, fs | ft | fd);
11503         {
11504             TCGv_i64 fp0 = tcg_temp_new_i64();
11505             TCGv_i64 fp1 = tcg_temp_new_i64();
11506
11507             gen_load_fpr64(ctx, fp0, fs);
11508             gen_load_fpr64(ctx, fp1, ft);
11509             gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
11510             tcg_temp_free_i64(fp1);
11511             gen_store_fpr64(ctx, fp0, fd);
11512             tcg_temp_free_i64(fp0);
11513         }
11514         break;
11515     case OPC_SQRT_D:
11516         check_cp1_registers(ctx, fs | fd);
11517         {
11518             TCGv_i64 fp0 = tcg_temp_new_i64();
11519
11520             gen_load_fpr64(ctx, fp0, fs);
11521             gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
11522             gen_store_fpr64(ctx, fp0, fd);
11523             tcg_temp_free_i64(fp0);
11524         }
11525         break;
11526     case OPC_ABS_D:
11527         check_cp1_registers(ctx, fs | fd);
11528         {
11529             TCGv_i64 fp0 = tcg_temp_new_i64();
11530
11531             gen_load_fpr64(ctx, fp0, fs);
11532             if (ctx->abs2008) {
11533                 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
11534             } else {
11535                 gen_helper_float_abs_d(fp0, fp0);
11536             }
11537             gen_store_fpr64(ctx, fp0, fd);
11538             tcg_temp_free_i64(fp0);
11539         }
11540         break;
11541     case OPC_MOV_D:
11542         check_cp1_registers(ctx, fs | fd);
11543         {
11544             TCGv_i64 fp0 = tcg_temp_new_i64();
11545
11546             gen_load_fpr64(ctx, fp0, fs);
11547             gen_store_fpr64(ctx, fp0, fd);
11548             tcg_temp_free_i64(fp0);
11549         }
11550         break;
11551     case OPC_NEG_D:
11552         check_cp1_registers(ctx, fs | fd);
11553         {
11554             TCGv_i64 fp0 = tcg_temp_new_i64();
11555
11556             gen_load_fpr64(ctx, fp0, fs);
11557             if (ctx->abs2008) {
11558                 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
11559             } else {
11560                 gen_helper_float_chs_d(fp0, fp0);
11561             }
11562             gen_store_fpr64(ctx, fp0, fd);
11563             tcg_temp_free_i64(fp0);
11564         }
11565         break;
11566     case OPC_ROUND_L_D:
11567         check_cp1_64bitmode(ctx);
11568         {
11569             TCGv_i64 fp0 = tcg_temp_new_i64();
11570
11571             gen_load_fpr64(ctx, fp0, fs);
11572             if (ctx->nan2008) {
11573                 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
11574             } else {
11575                 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
11576             }
11577             gen_store_fpr64(ctx, fp0, fd);
11578             tcg_temp_free_i64(fp0);
11579         }
11580         break;
11581     case OPC_TRUNC_L_D:
11582         check_cp1_64bitmode(ctx);
11583         {
11584             TCGv_i64 fp0 = tcg_temp_new_i64();
11585
11586             gen_load_fpr64(ctx, fp0, fs);
11587             if (ctx->nan2008) {
11588                 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
11589             } else {
11590                 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
11591             }
11592             gen_store_fpr64(ctx, fp0, fd);
11593             tcg_temp_free_i64(fp0);
11594         }
11595         break;
11596     case OPC_CEIL_L_D:
11597         check_cp1_64bitmode(ctx);
11598         {
11599             TCGv_i64 fp0 = tcg_temp_new_i64();
11600
11601             gen_load_fpr64(ctx, fp0, fs);
11602             if (ctx->nan2008) {
11603                 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
11604             } else {
11605                 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
11606             }
11607             gen_store_fpr64(ctx, fp0, fd);
11608             tcg_temp_free_i64(fp0);
11609         }
11610         break;
11611     case OPC_FLOOR_L_D:
11612         check_cp1_64bitmode(ctx);
11613         {
11614             TCGv_i64 fp0 = tcg_temp_new_i64();
11615
11616             gen_load_fpr64(ctx, fp0, fs);
11617             if (ctx->nan2008) {
11618                 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
11619             } else {
11620                 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
11621             }
11622             gen_store_fpr64(ctx, fp0, fd);
11623             tcg_temp_free_i64(fp0);
11624         }
11625         break;
11626     case OPC_ROUND_W_D:
11627         check_cp1_registers(ctx, fs);
11628         {
11629             TCGv_i32 fp32 = tcg_temp_new_i32();
11630             TCGv_i64 fp64 = tcg_temp_new_i64();
11631
11632             gen_load_fpr64(ctx, fp64, fs);
11633             if (ctx->nan2008) {
11634                 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
11635             } else {
11636                 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
11637             }
11638             tcg_temp_free_i64(fp64);
11639             gen_store_fpr32(ctx, fp32, fd);
11640             tcg_temp_free_i32(fp32);
11641         }
11642         break;
11643     case OPC_TRUNC_W_D:
11644         check_cp1_registers(ctx, fs);
11645         {
11646             TCGv_i32 fp32 = tcg_temp_new_i32();
11647             TCGv_i64 fp64 = tcg_temp_new_i64();
11648
11649             gen_load_fpr64(ctx, fp64, fs);
11650             if (ctx->nan2008) {
11651                 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
11652             } else {
11653                 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
11654             }
11655             tcg_temp_free_i64(fp64);
11656             gen_store_fpr32(ctx, fp32, fd);
11657             tcg_temp_free_i32(fp32);
11658         }
11659         break;
11660     case OPC_CEIL_W_D:
11661         check_cp1_registers(ctx, fs);
11662         {
11663             TCGv_i32 fp32 = tcg_temp_new_i32();
11664             TCGv_i64 fp64 = tcg_temp_new_i64();
11665
11666             gen_load_fpr64(ctx, fp64, fs);
11667             if (ctx->nan2008) {
11668                 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
11669             } else {
11670                 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
11671             }
11672             tcg_temp_free_i64(fp64);
11673             gen_store_fpr32(ctx, fp32, fd);
11674             tcg_temp_free_i32(fp32);
11675         }
11676         break;
11677     case OPC_FLOOR_W_D:
11678         check_cp1_registers(ctx, fs);
11679         {
11680             TCGv_i32 fp32 = tcg_temp_new_i32();
11681             TCGv_i64 fp64 = tcg_temp_new_i64();
11682
11683             gen_load_fpr64(ctx, fp64, fs);
11684             if (ctx->nan2008) {
11685                 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
11686             } else {
11687                 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
11688             }
11689             tcg_temp_free_i64(fp64);
11690             gen_store_fpr32(ctx, fp32, fd);
11691             tcg_temp_free_i32(fp32);
11692         }
11693         break;
11694     case OPC_SEL_D:
11695         check_insn(ctx, ISA_MIPS32R6);
11696         gen_sel_d(ctx, op1, fd, ft, fs);
11697         break;
11698     case OPC_SELEQZ_D:
11699         check_insn(ctx, ISA_MIPS32R6);
11700         gen_sel_d(ctx, op1, fd, ft, fs);
11701         break;
11702     case OPC_SELNEZ_D:
11703         check_insn(ctx, ISA_MIPS32R6);
11704         gen_sel_d(ctx, op1, fd, ft, fs);
11705         break;
11706     case OPC_MOVCF_D:
11707         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11708         gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11709         break;
11710     case OPC_MOVZ_D:
11711         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11712         {
11713             TCGLabel *l1 = gen_new_label();
11714             TCGv_i64 fp0;
11715
11716             if (ft != 0) {
11717                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11718             }
11719             fp0 = tcg_temp_new_i64();
11720             gen_load_fpr64(ctx, fp0, fs);
11721             gen_store_fpr64(ctx, fp0, fd);
11722             tcg_temp_free_i64(fp0);
11723             gen_set_label(l1);
11724         }
11725         break;
11726     case OPC_MOVN_D:
11727         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11728         {
11729             TCGLabel *l1 = gen_new_label();
11730             TCGv_i64 fp0;
11731
11732             if (ft != 0) {
11733                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11734                 fp0 = tcg_temp_new_i64();
11735                 gen_load_fpr64(ctx, fp0, fs);
11736                 gen_store_fpr64(ctx, fp0, fd);
11737                 tcg_temp_free_i64(fp0);
11738                 gen_set_label(l1);
11739             }
11740         }
11741         break;
11742     case OPC_RECIP_D:
11743         check_cp1_registers(ctx, fs | fd);
11744         {
11745             TCGv_i64 fp0 = tcg_temp_new_i64();
11746
11747             gen_load_fpr64(ctx, fp0, fs);
11748             gen_helper_float_recip_d(fp0, cpu_env, fp0);
11749             gen_store_fpr64(ctx, fp0, fd);
11750             tcg_temp_free_i64(fp0);
11751         }
11752         break;
11753     case OPC_RSQRT_D:
11754         check_cp1_registers(ctx, fs | fd);
11755         {
11756             TCGv_i64 fp0 = tcg_temp_new_i64();
11757
11758             gen_load_fpr64(ctx, fp0, fs);
11759             gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
11760             gen_store_fpr64(ctx, fp0, fd);
11761             tcg_temp_free_i64(fp0);
11762         }
11763         break;
11764     case OPC_MADDF_D:
11765         check_insn(ctx, ISA_MIPS32R6);
11766         {
11767             TCGv_i64 fp0 = tcg_temp_new_i64();
11768             TCGv_i64 fp1 = tcg_temp_new_i64();
11769             TCGv_i64 fp2 = tcg_temp_new_i64();
11770             gen_load_fpr64(ctx, fp0, fs);
11771             gen_load_fpr64(ctx, fp1, ft);
11772             gen_load_fpr64(ctx, fp2, fd);
11773             gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
11774             gen_store_fpr64(ctx, fp2, fd);
11775             tcg_temp_free_i64(fp2);
11776             tcg_temp_free_i64(fp1);
11777             tcg_temp_free_i64(fp0);
11778         }
11779         break;
11780     case OPC_MSUBF_D:
11781         check_insn(ctx, ISA_MIPS32R6);
11782         {
11783             TCGv_i64 fp0 = tcg_temp_new_i64();
11784             TCGv_i64 fp1 = tcg_temp_new_i64();
11785             TCGv_i64 fp2 = tcg_temp_new_i64();
11786             gen_load_fpr64(ctx, fp0, fs);
11787             gen_load_fpr64(ctx, fp1, ft);
11788             gen_load_fpr64(ctx, fp2, fd);
11789             gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
11790             gen_store_fpr64(ctx, fp2, fd);
11791             tcg_temp_free_i64(fp2);
11792             tcg_temp_free_i64(fp1);
11793             tcg_temp_free_i64(fp0);
11794         }
11795         break;
11796     case OPC_RINT_D:
11797         check_insn(ctx, ISA_MIPS32R6);
11798         {
11799             TCGv_i64 fp0 = tcg_temp_new_i64();
11800             gen_load_fpr64(ctx, fp0, fs);
11801             gen_helper_float_rint_d(fp0, cpu_env, fp0);
11802             gen_store_fpr64(ctx, fp0, fd);
11803             tcg_temp_free_i64(fp0);
11804         }
11805         break;
11806     case OPC_CLASS_D:
11807         check_insn(ctx, ISA_MIPS32R6);
11808         {
11809             TCGv_i64 fp0 = tcg_temp_new_i64();
11810             gen_load_fpr64(ctx, fp0, fs);
11811             gen_helper_float_class_d(fp0, cpu_env, fp0);
11812             gen_store_fpr64(ctx, fp0, fd);
11813             tcg_temp_free_i64(fp0);
11814         }
11815         break;
11816     case OPC_MIN_D: /* OPC_RECIP2_D */
11817         if (ctx->insn_flags & ISA_MIPS32R6) {
11818             /* OPC_MIN_D */
11819             TCGv_i64 fp0 = tcg_temp_new_i64();
11820             TCGv_i64 fp1 = tcg_temp_new_i64();
11821             gen_load_fpr64(ctx, fp0, fs);
11822             gen_load_fpr64(ctx, fp1, ft);
11823             gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
11824             gen_store_fpr64(ctx, fp1, fd);
11825             tcg_temp_free_i64(fp1);
11826             tcg_temp_free_i64(fp0);
11827         } else {
11828             /* OPC_RECIP2_D */
11829             check_cp1_64bitmode(ctx);
11830             {
11831                 TCGv_i64 fp0 = tcg_temp_new_i64();
11832                 TCGv_i64 fp1 = tcg_temp_new_i64();
11833
11834                 gen_load_fpr64(ctx, fp0, fs);
11835                 gen_load_fpr64(ctx, fp1, ft);
11836                 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
11837                 tcg_temp_free_i64(fp1);
11838                 gen_store_fpr64(ctx, fp0, fd);
11839                 tcg_temp_free_i64(fp0);
11840             }
11841         }
11842         break;
11843     case OPC_MINA_D: /* OPC_RECIP1_D */
11844         if (ctx->insn_flags & ISA_MIPS32R6) {
11845             /* OPC_MINA_D */
11846             TCGv_i64 fp0 = tcg_temp_new_i64();
11847             TCGv_i64 fp1 = tcg_temp_new_i64();
11848             gen_load_fpr64(ctx, fp0, fs);
11849             gen_load_fpr64(ctx, fp1, ft);
11850             gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
11851             gen_store_fpr64(ctx, fp1, fd);
11852             tcg_temp_free_i64(fp1);
11853             tcg_temp_free_i64(fp0);
11854         } else {
11855             /* OPC_RECIP1_D */
11856             check_cp1_64bitmode(ctx);
11857             {
11858                 TCGv_i64 fp0 = tcg_temp_new_i64();
11859
11860                 gen_load_fpr64(ctx, fp0, fs);
11861                 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
11862                 gen_store_fpr64(ctx, fp0, fd);
11863                 tcg_temp_free_i64(fp0);
11864             }
11865         }
11866         break;
11867     case OPC_MAX_D: /*  OPC_RSQRT1_D */
11868         if (ctx->insn_flags & ISA_MIPS32R6) {
11869             /* OPC_MAX_D */
11870             TCGv_i64 fp0 = tcg_temp_new_i64();
11871             TCGv_i64 fp1 = tcg_temp_new_i64();
11872             gen_load_fpr64(ctx, fp0, fs);
11873             gen_load_fpr64(ctx, fp1, ft);
11874             gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
11875             gen_store_fpr64(ctx, fp1, fd);
11876             tcg_temp_free_i64(fp1);
11877             tcg_temp_free_i64(fp0);
11878         } else {
11879             /* OPC_RSQRT1_D */
11880             check_cp1_64bitmode(ctx);
11881             {
11882                 TCGv_i64 fp0 = tcg_temp_new_i64();
11883
11884                 gen_load_fpr64(ctx, fp0, fs);
11885                 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
11886                 gen_store_fpr64(ctx, fp0, fd);
11887                 tcg_temp_free_i64(fp0);
11888             }
11889         }
11890         break;
11891     case OPC_MAXA_D: /* OPC_RSQRT2_D */
11892         if (ctx->insn_flags & ISA_MIPS32R6) {
11893             /* OPC_MAXA_D */
11894             TCGv_i64 fp0 = tcg_temp_new_i64();
11895             TCGv_i64 fp1 = tcg_temp_new_i64();
11896             gen_load_fpr64(ctx, fp0, fs);
11897             gen_load_fpr64(ctx, fp1, ft);
11898             gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
11899             gen_store_fpr64(ctx, fp1, fd);
11900             tcg_temp_free_i64(fp1);
11901             tcg_temp_free_i64(fp0);
11902         } else {
11903             /* OPC_RSQRT2_D */
11904             check_cp1_64bitmode(ctx);
11905             {
11906                 TCGv_i64 fp0 = tcg_temp_new_i64();
11907                 TCGv_i64 fp1 = tcg_temp_new_i64();
11908
11909                 gen_load_fpr64(ctx, fp0, fs);
11910                 gen_load_fpr64(ctx, fp1, ft);
11911                 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
11912                 tcg_temp_free_i64(fp1);
11913                 gen_store_fpr64(ctx, fp0, fd);
11914                 tcg_temp_free_i64(fp0);
11915             }
11916         }
11917         break;
11918     case OPC_CMP_F_D:
11919     case OPC_CMP_UN_D:
11920     case OPC_CMP_EQ_D:
11921     case OPC_CMP_UEQ_D:
11922     case OPC_CMP_OLT_D:
11923     case OPC_CMP_ULT_D:
11924     case OPC_CMP_OLE_D:
11925     case OPC_CMP_ULE_D:
11926     case OPC_CMP_SF_D:
11927     case OPC_CMP_NGLE_D:
11928     case OPC_CMP_SEQ_D:
11929     case OPC_CMP_NGL_D:
11930     case OPC_CMP_LT_D:
11931     case OPC_CMP_NGE_D:
11932     case OPC_CMP_LE_D:
11933     case OPC_CMP_NGT_D:
11934         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11935         if (ctx->opcode & (1 << 6)) {
11936             gen_cmpabs_d(ctx, func-48, ft, fs, cc);
11937         } else {
11938             gen_cmp_d(ctx, func-48, ft, fs, cc);
11939         }
11940         break;
11941     case OPC_CVT_S_D:
11942         check_cp1_registers(ctx, fs);
11943         {
11944             TCGv_i32 fp32 = tcg_temp_new_i32();
11945             TCGv_i64 fp64 = tcg_temp_new_i64();
11946
11947             gen_load_fpr64(ctx, fp64, fs);
11948             gen_helper_float_cvts_d(fp32, cpu_env, fp64);
11949             tcg_temp_free_i64(fp64);
11950             gen_store_fpr32(ctx, fp32, fd);
11951             tcg_temp_free_i32(fp32);
11952         }
11953         break;
11954     case OPC_CVT_W_D:
11955         check_cp1_registers(ctx, fs);
11956         {
11957             TCGv_i32 fp32 = tcg_temp_new_i32();
11958             TCGv_i64 fp64 = tcg_temp_new_i64();
11959
11960             gen_load_fpr64(ctx, fp64, fs);
11961             if (ctx->nan2008) {
11962                 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
11963             } else {
11964                 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
11965             }
11966             tcg_temp_free_i64(fp64);
11967             gen_store_fpr32(ctx, fp32, fd);
11968             tcg_temp_free_i32(fp32);
11969         }
11970         break;
11971     case OPC_CVT_L_D:
11972         check_cp1_64bitmode(ctx);
11973         {
11974             TCGv_i64 fp0 = tcg_temp_new_i64();
11975
11976             gen_load_fpr64(ctx, fp0, fs);
11977             if (ctx->nan2008) {
11978                 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
11979             } else {
11980                 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
11981             }
11982             gen_store_fpr64(ctx, fp0, fd);
11983             tcg_temp_free_i64(fp0);
11984         }
11985         break;
11986     case OPC_CVT_S_W:
11987         {
11988             TCGv_i32 fp0 = tcg_temp_new_i32();
11989
11990             gen_load_fpr32(ctx, fp0, fs);
11991             gen_helper_float_cvts_w(fp0, cpu_env, fp0);
11992             gen_store_fpr32(ctx, fp0, fd);
11993             tcg_temp_free_i32(fp0);
11994         }
11995         break;
11996     case OPC_CVT_D_W:
11997         check_cp1_registers(ctx, fd);
11998         {
11999             TCGv_i32 fp32 = tcg_temp_new_i32();
12000             TCGv_i64 fp64 = tcg_temp_new_i64();
12001
12002             gen_load_fpr32(ctx, fp32, fs);
12003             gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
12004             tcg_temp_free_i32(fp32);
12005             gen_store_fpr64(ctx, fp64, fd);
12006             tcg_temp_free_i64(fp64);
12007         }
12008         break;
12009     case OPC_CVT_S_L:
12010         check_cp1_64bitmode(ctx);
12011         {
12012             TCGv_i32 fp32 = tcg_temp_new_i32();
12013             TCGv_i64 fp64 = tcg_temp_new_i64();
12014
12015             gen_load_fpr64(ctx, fp64, fs);
12016             gen_helper_float_cvts_l(fp32, cpu_env, fp64);
12017             tcg_temp_free_i64(fp64);
12018             gen_store_fpr32(ctx, fp32, fd);
12019             tcg_temp_free_i32(fp32);
12020         }
12021         break;
12022     case OPC_CVT_D_L:
12023         check_cp1_64bitmode(ctx);
12024         {
12025             TCGv_i64 fp0 = tcg_temp_new_i64();
12026
12027             gen_load_fpr64(ctx, fp0, fs);
12028             gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
12029             gen_store_fpr64(ctx, fp0, fd);
12030             tcg_temp_free_i64(fp0);
12031         }
12032         break;
12033     case OPC_CVT_PS_PW:
12034         check_ps(ctx);
12035         {
12036             TCGv_i64 fp0 = tcg_temp_new_i64();
12037
12038             gen_load_fpr64(ctx, fp0, fs);
12039             gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
12040             gen_store_fpr64(ctx, fp0, fd);
12041             tcg_temp_free_i64(fp0);
12042         }
12043         break;
12044     case OPC_ADD_PS:
12045         check_ps(ctx);
12046         {
12047             TCGv_i64 fp0 = tcg_temp_new_i64();
12048             TCGv_i64 fp1 = tcg_temp_new_i64();
12049
12050             gen_load_fpr64(ctx, fp0, fs);
12051             gen_load_fpr64(ctx, fp1, ft);
12052             gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
12053             tcg_temp_free_i64(fp1);
12054             gen_store_fpr64(ctx, fp0, fd);
12055             tcg_temp_free_i64(fp0);
12056         }
12057         break;
12058     case OPC_SUB_PS:
12059         check_ps(ctx);
12060         {
12061             TCGv_i64 fp0 = tcg_temp_new_i64();
12062             TCGv_i64 fp1 = tcg_temp_new_i64();
12063
12064             gen_load_fpr64(ctx, fp0, fs);
12065             gen_load_fpr64(ctx, fp1, ft);
12066             gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
12067             tcg_temp_free_i64(fp1);
12068             gen_store_fpr64(ctx, fp0, fd);
12069             tcg_temp_free_i64(fp0);
12070         }
12071         break;
12072     case OPC_MUL_PS:
12073         check_ps(ctx);
12074         {
12075             TCGv_i64 fp0 = tcg_temp_new_i64();
12076             TCGv_i64 fp1 = tcg_temp_new_i64();
12077
12078             gen_load_fpr64(ctx, fp0, fs);
12079             gen_load_fpr64(ctx, fp1, ft);
12080             gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
12081             tcg_temp_free_i64(fp1);
12082             gen_store_fpr64(ctx, fp0, fd);
12083             tcg_temp_free_i64(fp0);
12084         }
12085         break;
12086     case OPC_ABS_PS:
12087         check_ps(ctx);
12088         {
12089             TCGv_i64 fp0 = tcg_temp_new_i64();
12090
12091             gen_load_fpr64(ctx, fp0, fs);
12092             gen_helper_float_abs_ps(fp0, fp0);
12093             gen_store_fpr64(ctx, fp0, fd);
12094             tcg_temp_free_i64(fp0);
12095         }
12096         break;
12097     case OPC_MOV_PS:
12098         check_ps(ctx);
12099         {
12100             TCGv_i64 fp0 = tcg_temp_new_i64();
12101
12102             gen_load_fpr64(ctx, fp0, fs);
12103             gen_store_fpr64(ctx, fp0, fd);
12104             tcg_temp_free_i64(fp0);
12105         }
12106         break;
12107     case OPC_NEG_PS:
12108         check_ps(ctx);
12109         {
12110             TCGv_i64 fp0 = tcg_temp_new_i64();
12111
12112             gen_load_fpr64(ctx, fp0, fs);
12113             gen_helper_float_chs_ps(fp0, fp0);
12114             gen_store_fpr64(ctx, fp0, fd);
12115             tcg_temp_free_i64(fp0);
12116         }
12117         break;
12118     case OPC_MOVCF_PS:
12119         check_ps(ctx);
12120         gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
12121         break;
12122     case OPC_MOVZ_PS:
12123         check_ps(ctx);
12124         {
12125             TCGLabel *l1 = gen_new_label();
12126             TCGv_i64 fp0;
12127
12128             if (ft != 0)
12129                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
12130             fp0 = tcg_temp_new_i64();
12131             gen_load_fpr64(ctx, fp0, fs);
12132             gen_store_fpr64(ctx, fp0, fd);
12133             tcg_temp_free_i64(fp0);
12134             gen_set_label(l1);
12135         }
12136         break;
12137     case OPC_MOVN_PS:
12138         check_ps(ctx);
12139         {
12140             TCGLabel *l1 = gen_new_label();
12141             TCGv_i64 fp0;
12142
12143             if (ft != 0) {
12144                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
12145                 fp0 = tcg_temp_new_i64();
12146                 gen_load_fpr64(ctx, fp0, fs);
12147                 gen_store_fpr64(ctx, fp0, fd);
12148                 tcg_temp_free_i64(fp0);
12149                 gen_set_label(l1);
12150             }
12151         }
12152         break;
12153     case OPC_ADDR_PS:
12154         check_ps(ctx);
12155         {
12156             TCGv_i64 fp0 = tcg_temp_new_i64();
12157             TCGv_i64 fp1 = tcg_temp_new_i64();
12158
12159             gen_load_fpr64(ctx, fp0, ft);
12160             gen_load_fpr64(ctx, fp1, fs);
12161             gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
12162             tcg_temp_free_i64(fp1);
12163             gen_store_fpr64(ctx, fp0, fd);
12164             tcg_temp_free_i64(fp0);
12165         }
12166         break;
12167     case OPC_MULR_PS:
12168         check_ps(ctx);
12169         {
12170             TCGv_i64 fp0 = tcg_temp_new_i64();
12171             TCGv_i64 fp1 = tcg_temp_new_i64();
12172
12173             gen_load_fpr64(ctx, fp0, ft);
12174             gen_load_fpr64(ctx, fp1, fs);
12175             gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
12176             tcg_temp_free_i64(fp1);
12177             gen_store_fpr64(ctx, fp0, fd);
12178             tcg_temp_free_i64(fp0);
12179         }
12180         break;
12181     case OPC_RECIP2_PS:
12182         check_ps(ctx);
12183         {
12184             TCGv_i64 fp0 = tcg_temp_new_i64();
12185             TCGv_i64 fp1 = tcg_temp_new_i64();
12186
12187             gen_load_fpr64(ctx, fp0, fs);
12188             gen_load_fpr64(ctx, fp1, ft);
12189             gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
12190             tcg_temp_free_i64(fp1);
12191             gen_store_fpr64(ctx, fp0, fd);
12192             tcg_temp_free_i64(fp0);
12193         }
12194         break;
12195     case OPC_RECIP1_PS:
12196         check_ps(ctx);
12197         {
12198             TCGv_i64 fp0 = tcg_temp_new_i64();
12199
12200             gen_load_fpr64(ctx, fp0, fs);
12201             gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
12202             gen_store_fpr64(ctx, fp0, fd);
12203             tcg_temp_free_i64(fp0);
12204         }
12205         break;
12206     case OPC_RSQRT1_PS:
12207         check_ps(ctx);
12208         {
12209             TCGv_i64 fp0 = tcg_temp_new_i64();
12210
12211             gen_load_fpr64(ctx, fp0, fs);
12212             gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
12213             gen_store_fpr64(ctx, fp0, fd);
12214             tcg_temp_free_i64(fp0);
12215         }
12216         break;
12217     case OPC_RSQRT2_PS:
12218         check_ps(ctx);
12219         {
12220             TCGv_i64 fp0 = tcg_temp_new_i64();
12221             TCGv_i64 fp1 = tcg_temp_new_i64();
12222
12223             gen_load_fpr64(ctx, fp0, fs);
12224             gen_load_fpr64(ctx, fp1, ft);
12225             gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
12226             tcg_temp_free_i64(fp1);
12227             gen_store_fpr64(ctx, fp0, fd);
12228             tcg_temp_free_i64(fp0);
12229         }
12230         break;
12231     case OPC_CVT_S_PU:
12232         check_cp1_64bitmode(ctx);
12233         {
12234             TCGv_i32 fp0 = tcg_temp_new_i32();
12235
12236             gen_load_fpr32h(ctx, fp0, fs);
12237             gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
12238             gen_store_fpr32(ctx, fp0, fd);
12239             tcg_temp_free_i32(fp0);
12240         }
12241         break;
12242     case OPC_CVT_PW_PS:
12243         check_ps(ctx);
12244         {
12245             TCGv_i64 fp0 = tcg_temp_new_i64();
12246
12247             gen_load_fpr64(ctx, fp0, fs);
12248             gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
12249             gen_store_fpr64(ctx, fp0, fd);
12250             tcg_temp_free_i64(fp0);
12251         }
12252         break;
12253     case OPC_CVT_S_PL:
12254         check_cp1_64bitmode(ctx);
12255         {
12256             TCGv_i32 fp0 = tcg_temp_new_i32();
12257
12258             gen_load_fpr32(ctx, fp0, fs);
12259             gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
12260             gen_store_fpr32(ctx, fp0, fd);
12261             tcg_temp_free_i32(fp0);
12262         }
12263         break;
12264     case OPC_PLL_PS:
12265         check_ps(ctx);
12266         {
12267             TCGv_i32 fp0 = tcg_temp_new_i32();
12268             TCGv_i32 fp1 = tcg_temp_new_i32();
12269
12270             gen_load_fpr32(ctx, fp0, fs);
12271             gen_load_fpr32(ctx, fp1, ft);
12272             gen_store_fpr32h(ctx, fp0, fd);
12273             gen_store_fpr32(ctx, fp1, fd);
12274             tcg_temp_free_i32(fp0);
12275             tcg_temp_free_i32(fp1);
12276         }
12277         break;
12278     case OPC_PLU_PS:
12279         check_ps(ctx);
12280         {
12281             TCGv_i32 fp0 = tcg_temp_new_i32();
12282             TCGv_i32 fp1 = tcg_temp_new_i32();
12283
12284             gen_load_fpr32(ctx, fp0, fs);
12285             gen_load_fpr32h(ctx, fp1, ft);
12286             gen_store_fpr32(ctx, fp1, fd);
12287             gen_store_fpr32h(ctx, fp0, fd);
12288             tcg_temp_free_i32(fp0);
12289             tcg_temp_free_i32(fp1);
12290         }
12291         break;
12292     case OPC_PUL_PS:
12293         check_ps(ctx);
12294         {
12295             TCGv_i32 fp0 = tcg_temp_new_i32();
12296             TCGv_i32 fp1 = tcg_temp_new_i32();
12297
12298             gen_load_fpr32h(ctx, fp0, fs);
12299             gen_load_fpr32(ctx, fp1, ft);
12300             gen_store_fpr32(ctx, fp1, fd);
12301             gen_store_fpr32h(ctx, fp0, fd);
12302             tcg_temp_free_i32(fp0);
12303             tcg_temp_free_i32(fp1);
12304         }
12305         break;
12306     case OPC_PUU_PS:
12307         check_ps(ctx);
12308         {
12309             TCGv_i32 fp0 = tcg_temp_new_i32();
12310             TCGv_i32 fp1 = tcg_temp_new_i32();
12311
12312             gen_load_fpr32h(ctx, fp0, fs);
12313             gen_load_fpr32h(ctx, fp1, ft);
12314             gen_store_fpr32(ctx, fp1, fd);
12315             gen_store_fpr32h(ctx, fp0, fd);
12316             tcg_temp_free_i32(fp0);
12317             tcg_temp_free_i32(fp1);
12318         }
12319         break;
12320     case OPC_CMP_F_PS:
12321     case OPC_CMP_UN_PS:
12322     case OPC_CMP_EQ_PS:
12323     case OPC_CMP_UEQ_PS:
12324     case OPC_CMP_OLT_PS:
12325     case OPC_CMP_ULT_PS:
12326     case OPC_CMP_OLE_PS:
12327     case OPC_CMP_ULE_PS:
12328     case OPC_CMP_SF_PS:
12329     case OPC_CMP_NGLE_PS:
12330     case OPC_CMP_SEQ_PS:
12331     case OPC_CMP_NGL_PS:
12332     case OPC_CMP_LT_PS:
12333     case OPC_CMP_NGE_PS:
12334     case OPC_CMP_LE_PS:
12335     case OPC_CMP_NGT_PS:
12336         if (ctx->opcode & (1 << 6)) {
12337             gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
12338         } else {
12339             gen_cmp_ps(ctx, func-48, ft, fs, cc);
12340         }
12341         break;
12342     default:
12343         MIPS_INVAL("farith");
12344         generate_exception_end(ctx, EXCP_RI);
12345         return;
12346     }
12347 }
12348
12349 /* Coprocessor 3 (FPU) */
12350 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
12351                            int fd, int fs, int base, int index)
12352 {
12353     TCGv t0 = tcg_temp_new();
12354
12355     if (base == 0) {
12356         gen_load_gpr(t0, index);
12357     } else if (index == 0) {
12358         gen_load_gpr(t0, base);
12359     } else {
12360         gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
12361     }
12362     /* Don't do NOP if destination is zero: we must perform the actual
12363        memory access. */
12364     switch (opc) {
12365     case OPC_LWXC1:
12366         check_cop1x(ctx);
12367         {
12368             TCGv_i32 fp0 = tcg_temp_new_i32();
12369
12370             tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
12371             tcg_gen_trunc_tl_i32(fp0, t0);
12372             gen_store_fpr32(ctx, fp0, fd);
12373             tcg_temp_free_i32(fp0);
12374         }
12375         break;
12376     case OPC_LDXC1:
12377         check_cop1x(ctx);
12378         check_cp1_registers(ctx, fd);
12379         {
12380             TCGv_i64 fp0 = tcg_temp_new_i64();
12381             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12382             gen_store_fpr64(ctx, fp0, fd);
12383             tcg_temp_free_i64(fp0);
12384         }
12385         break;
12386     case OPC_LUXC1:
12387         check_cp1_64bitmode(ctx);
12388         tcg_gen_andi_tl(t0, t0, ~0x7);
12389         {
12390             TCGv_i64 fp0 = tcg_temp_new_i64();
12391
12392             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12393             gen_store_fpr64(ctx, fp0, fd);
12394             tcg_temp_free_i64(fp0);
12395         }
12396         break;
12397     case OPC_SWXC1:
12398         check_cop1x(ctx);
12399         {
12400             TCGv_i32 fp0 = tcg_temp_new_i32();
12401             gen_load_fpr32(ctx, fp0, fs);
12402             tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
12403             tcg_temp_free_i32(fp0);
12404         }
12405         break;
12406     case OPC_SDXC1:
12407         check_cop1x(ctx);
12408         check_cp1_registers(ctx, fs);
12409         {
12410             TCGv_i64 fp0 = tcg_temp_new_i64();
12411             gen_load_fpr64(ctx, fp0, fs);
12412             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12413             tcg_temp_free_i64(fp0);
12414         }
12415         break;
12416     case OPC_SUXC1:
12417         check_cp1_64bitmode(ctx);
12418         tcg_gen_andi_tl(t0, t0, ~0x7);
12419         {
12420             TCGv_i64 fp0 = tcg_temp_new_i64();
12421             gen_load_fpr64(ctx, fp0, fs);
12422             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12423             tcg_temp_free_i64(fp0);
12424         }
12425         break;
12426     }
12427     tcg_temp_free(t0);
12428 }
12429
12430 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
12431                             int fd, int fr, int fs, int ft)
12432 {
12433     switch (opc) {
12434     case OPC_ALNV_PS:
12435         check_ps(ctx);
12436         {
12437             TCGv t0 = tcg_temp_local_new();
12438             TCGv_i32 fp = tcg_temp_new_i32();
12439             TCGv_i32 fph = tcg_temp_new_i32();
12440             TCGLabel *l1 = gen_new_label();
12441             TCGLabel *l2 = gen_new_label();
12442
12443             gen_load_gpr(t0, fr);
12444             tcg_gen_andi_tl(t0, t0, 0x7);
12445
12446             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
12447             gen_load_fpr32(ctx, fp, fs);
12448             gen_load_fpr32h(ctx, fph, fs);
12449             gen_store_fpr32(ctx, fp, fd);
12450             gen_store_fpr32h(ctx, fph, fd);
12451             tcg_gen_br(l2);
12452             gen_set_label(l1);
12453             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
12454             tcg_temp_free(t0);
12455 #ifdef TARGET_WORDS_BIGENDIAN
12456             gen_load_fpr32(ctx, fp, fs);
12457             gen_load_fpr32h(ctx, fph, ft);
12458             gen_store_fpr32h(ctx, fp, fd);
12459             gen_store_fpr32(ctx, fph, fd);
12460 #else
12461             gen_load_fpr32h(ctx, fph, fs);
12462             gen_load_fpr32(ctx, fp, ft);
12463             gen_store_fpr32(ctx, fph, fd);
12464             gen_store_fpr32h(ctx, fp, fd);
12465 #endif
12466             gen_set_label(l2);
12467             tcg_temp_free_i32(fp);
12468             tcg_temp_free_i32(fph);
12469         }
12470         break;
12471     case OPC_MADD_S:
12472         check_cop1x(ctx);
12473         {
12474             TCGv_i32 fp0 = tcg_temp_new_i32();
12475             TCGv_i32 fp1 = tcg_temp_new_i32();
12476             TCGv_i32 fp2 = tcg_temp_new_i32();
12477
12478             gen_load_fpr32(ctx, fp0, fs);
12479             gen_load_fpr32(ctx, fp1, ft);
12480             gen_load_fpr32(ctx, fp2, fr);
12481             gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
12482             tcg_temp_free_i32(fp0);
12483             tcg_temp_free_i32(fp1);
12484             gen_store_fpr32(ctx, fp2, fd);
12485             tcg_temp_free_i32(fp2);
12486         }
12487         break;
12488     case OPC_MADD_D:
12489         check_cop1x(ctx);
12490         check_cp1_registers(ctx, fd | fs | ft | fr);
12491         {
12492             TCGv_i64 fp0 = tcg_temp_new_i64();
12493             TCGv_i64 fp1 = tcg_temp_new_i64();
12494             TCGv_i64 fp2 = tcg_temp_new_i64();
12495
12496             gen_load_fpr64(ctx, fp0, fs);
12497             gen_load_fpr64(ctx, fp1, ft);
12498             gen_load_fpr64(ctx, fp2, fr);
12499             gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
12500             tcg_temp_free_i64(fp0);
12501             tcg_temp_free_i64(fp1);
12502             gen_store_fpr64(ctx, fp2, fd);
12503             tcg_temp_free_i64(fp2);
12504         }
12505         break;
12506     case OPC_MADD_PS:
12507         check_ps(ctx);
12508         {
12509             TCGv_i64 fp0 = tcg_temp_new_i64();
12510             TCGv_i64 fp1 = tcg_temp_new_i64();
12511             TCGv_i64 fp2 = tcg_temp_new_i64();
12512
12513             gen_load_fpr64(ctx, fp0, fs);
12514             gen_load_fpr64(ctx, fp1, ft);
12515             gen_load_fpr64(ctx, fp2, fr);
12516             gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
12517             tcg_temp_free_i64(fp0);
12518             tcg_temp_free_i64(fp1);
12519             gen_store_fpr64(ctx, fp2, fd);
12520             tcg_temp_free_i64(fp2);
12521         }
12522         break;
12523     case OPC_MSUB_S:
12524         check_cop1x(ctx);
12525         {
12526             TCGv_i32 fp0 = tcg_temp_new_i32();
12527             TCGv_i32 fp1 = tcg_temp_new_i32();
12528             TCGv_i32 fp2 = tcg_temp_new_i32();
12529
12530             gen_load_fpr32(ctx, fp0, fs);
12531             gen_load_fpr32(ctx, fp1, ft);
12532             gen_load_fpr32(ctx, fp2, fr);
12533             gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
12534             tcg_temp_free_i32(fp0);
12535             tcg_temp_free_i32(fp1);
12536             gen_store_fpr32(ctx, fp2, fd);
12537             tcg_temp_free_i32(fp2);
12538         }
12539         break;
12540     case OPC_MSUB_D:
12541         check_cop1x(ctx);
12542         check_cp1_registers(ctx, fd | fs | ft | fr);
12543         {
12544             TCGv_i64 fp0 = tcg_temp_new_i64();
12545             TCGv_i64 fp1 = tcg_temp_new_i64();
12546             TCGv_i64 fp2 = tcg_temp_new_i64();
12547
12548             gen_load_fpr64(ctx, fp0, fs);
12549             gen_load_fpr64(ctx, fp1, ft);
12550             gen_load_fpr64(ctx, fp2, fr);
12551             gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
12552             tcg_temp_free_i64(fp0);
12553             tcg_temp_free_i64(fp1);
12554             gen_store_fpr64(ctx, fp2, fd);
12555             tcg_temp_free_i64(fp2);
12556         }
12557         break;
12558     case OPC_MSUB_PS:
12559         check_ps(ctx);
12560         {
12561             TCGv_i64 fp0 = tcg_temp_new_i64();
12562             TCGv_i64 fp1 = tcg_temp_new_i64();
12563             TCGv_i64 fp2 = tcg_temp_new_i64();
12564
12565             gen_load_fpr64(ctx, fp0, fs);
12566             gen_load_fpr64(ctx, fp1, ft);
12567             gen_load_fpr64(ctx, fp2, fr);
12568             gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
12569             tcg_temp_free_i64(fp0);
12570             tcg_temp_free_i64(fp1);
12571             gen_store_fpr64(ctx, fp2, fd);
12572             tcg_temp_free_i64(fp2);
12573         }
12574         break;
12575     case OPC_NMADD_S:
12576         check_cop1x(ctx);
12577         {
12578             TCGv_i32 fp0 = tcg_temp_new_i32();
12579             TCGv_i32 fp1 = tcg_temp_new_i32();
12580             TCGv_i32 fp2 = tcg_temp_new_i32();
12581
12582             gen_load_fpr32(ctx, fp0, fs);
12583             gen_load_fpr32(ctx, fp1, ft);
12584             gen_load_fpr32(ctx, fp2, fr);
12585             gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
12586             tcg_temp_free_i32(fp0);
12587             tcg_temp_free_i32(fp1);
12588             gen_store_fpr32(ctx, fp2, fd);
12589             tcg_temp_free_i32(fp2);
12590         }
12591         break;
12592     case OPC_NMADD_D:
12593         check_cop1x(ctx);
12594         check_cp1_registers(ctx, fd | fs | ft | fr);
12595         {
12596             TCGv_i64 fp0 = tcg_temp_new_i64();
12597             TCGv_i64 fp1 = tcg_temp_new_i64();
12598             TCGv_i64 fp2 = tcg_temp_new_i64();
12599
12600             gen_load_fpr64(ctx, fp0, fs);
12601             gen_load_fpr64(ctx, fp1, ft);
12602             gen_load_fpr64(ctx, fp2, fr);
12603             gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
12604             tcg_temp_free_i64(fp0);
12605             tcg_temp_free_i64(fp1);
12606             gen_store_fpr64(ctx, fp2, fd);
12607             tcg_temp_free_i64(fp2);
12608         }
12609         break;
12610     case OPC_NMADD_PS:
12611         check_ps(ctx);
12612         {
12613             TCGv_i64 fp0 = tcg_temp_new_i64();
12614             TCGv_i64 fp1 = tcg_temp_new_i64();
12615             TCGv_i64 fp2 = tcg_temp_new_i64();
12616
12617             gen_load_fpr64(ctx, fp0, fs);
12618             gen_load_fpr64(ctx, fp1, ft);
12619             gen_load_fpr64(ctx, fp2, fr);
12620             gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
12621             tcg_temp_free_i64(fp0);
12622             tcg_temp_free_i64(fp1);
12623             gen_store_fpr64(ctx, fp2, fd);
12624             tcg_temp_free_i64(fp2);
12625         }
12626         break;
12627     case OPC_NMSUB_S:
12628         check_cop1x(ctx);
12629         {
12630             TCGv_i32 fp0 = tcg_temp_new_i32();
12631             TCGv_i32 fp1 = tcg_temp_new_i32();
12632             TCGv_i32 fp2 = tcg_temp_new_i32();
12633
12634             gen_load_fpr32(ctx, fp0, fs);
12635             gen_load_fpr32(ctx, fp1, ft);
12636             gen_load_fpr32(ctx, fp2, fr);
12637             gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
12638             tcg_temp_free_i32(fp0);
12639             tcg_temp_free_i32(fp1);
12640             gen_store_fpr32(ctx, fp2, fd);
12641             tcg_temp_free_i32(fp2);
12642         }
12643         break;
12644     case OPC_NMSUB_D:
12645         check_cop1x(ctx);
12646         check_cp1_registers(ctx, fd | fs | ft | fr);
12647         {
12648             TCGv_i64 fp0 = tcg_temp_new_i64();
12649             TCGv_i64 fp1 = tcg_temp_new_i64();
12650             TCGv_i64 fp2 = tcg_temp_new_i64();
12651
12652             gen_load_fpr64(ctx, fp0, fs);
12653             gen_load_fpr64(ctx, fp1, ft);
12654             gen_load_fpr64(ctx, fp2, fr);
12655             gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
12656             tcg_temp_free_i64(fp0);
12657             tcg_temp_free_i64(fp1);
12658             gen_store_fpr64(ctx, fp2, fd);
12659             tcg_temp_free_i64(fp2);
12660         }
12661         break;
12662     case OPC_NMSUB_PS:
12663         check_ps(ctx);
12664         {
12665             TCGv_i64 fp0 = tcg_temp_new_i64();
12666             TCGv_i64 fp1 = tcg_temp_new_i64();
12667             TCGv_i64 fp2 = tcg_temp_new_i64();
12668
12669             gen_load_fpr64(ctx, fp0, fs);
12670             gen_load_fpr64(ctx, fp1, ft);
12671             gen_load_fpr64(ctx, fp2, fr);
12672             gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
12673             tcg_temp_free_i64(fp0);
12674             tcg_temp_free_i64(fp1);
12675             gen_store_fpr64(ctx, fp2, fd);
12676             tcg_temp_free_i64(fp2);
12677         }
12678         break;
12679     default:
12680         MIPS_INVAL("flt3_arith");
12681         generate_exception_end(ctx, EXCP_RI);
12682         return;
12683     }
12684 }
12685
12686 static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
12687 {
12688     TCGv t0;
12689
12690 #if !defined(CONFIG_USER_ONLY)
12691     /* The Linux kernel will emulate rdhwr if it's not supported natively.
12692        Therefore only check the ISA in system mode.  */
12693     check_insn(ctx, ISA_MIPS32R2);
12694 #endif
12695     t0 = tcg_temp_new();
12696
12697     switch (rd) {
12698     case 0:
12699         gen_helper_rdhwr_cpunum(t0, cpu_env);
12700         gen_store_gpr(t0, rt);
12701         break;
12702     case 1:
12703         gen_helper_rdhwr_synci_step(t0, cpu_env);
12704         gen_store_gpr(t0, rt);
12705         break;
12706     case 2:
12707         if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
12708             gen_io_start();
12709         }
12710         gen_helper_rdhwr_cc(t0, cpu_env);
12711         if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
12712             gen_io_end();
12713         }
12714         gen_store_gpr(t0, rt);
12715         /* Break the TB to be able to take timer interrupts immediately
12716            after reading count. DISAS_STOP isn't sufficient, we need to ensure
12717            we break completely out of translated code.  */
12718         gen_save_pc(ctx->base.pc_next + 4);
12719         ctx->base.is_jmp = DISAS_EXIT;
12720         break;
12721     case 3:
12722         gen_helper_rdhwr_ccres(t0, cpu_env);
12723         gen_store_gpr(t0, rt);
12724         break;
12725     case 4:
12726         check_insn(ctx, ISA_MIPS32R6);
12727         if (sel != 0) {
12728             /* Performance counter registers are not implemented other than
12729              * control register 0.
12730              */
12731             generate_exception(ctx, EXCP_RI);
12732         }
12733         gen_helper_rdhwr_performance(t0, cpu_env);
12734         gen_store_gpr(t0, rt);
12735         break;
12736     case 5:
12737         check_insn(ctx, ISA_MIPS32R6);
12738         gen_helper_rdhwr_xnp(t0, cpu_env);
12739         gen_store_gpr(t0, rt);
12740         break;
12741     case 29:
12742 #if defined(CONFIG_USER_ONLY)
12743         tcg_gen_ld_tl(t0, cpu_env,
12744                       offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12745         gen_store_gpr(t0, rt);
12746         break;
12747 #else
12748         if ((ctx->hflags & MIPS_HFLAG_CP0) ||
12749             (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
12750             tcg_gen_ld_tl(t0, cpu_env,
12751                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12752             gen_store_gpr(t0, rt);
12753         } else {
12754             generate_exception_end(ctx, EXCP_RI);
12755         }
12756         break;
12757 #endif
12758     default:            /* Invalid */
12759         MIPS_INVAL("rdhwr");
12760         generate_exception_end(ctx, EXCP_RI);
12761         break;
12762     }
12763     tcg_temp_free(t0);
12764 }
12765
12766 static inline void clear_branch_hflags(DisasContext *ctx)
12767 {
12768     ctx->hflags &= ~MIPS_HFLAG_BMASK;
12769     if (ctx->base.is_jmp == DISAS_NEXT) {
12770         save_cpu_state(ctx, 0);
12771     } else {
12772         /* it is not safe to save ctx->hflags as hflags may be changed
12773            in execution time by the instruction in delay / forbidden slot. */
12774         tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
12775     }
12776 }
12777
12778 static void gen_branch(DisasContext *ctx, int insn_bytes)
12779 {
12780     if (ctx->hflags & MIPS_HFLAG_BMASK) {
12781         int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
12782         /* Branches completion */
12783         clear_branch_hflags(ctx);
12784         ctx->base.is_jmp = DISAS_NORETURN;
12785         /* FIXME: Need to clear can_do_io.  */
12786         switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
12787         case MIPS_HFLAG_FBNSLOT:
12788             gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
12789             break;
12790         case MIPS_HFLAG_B:
12791             /* unconditional branch */
12792             if (proc_hflags & MIPS_HFLAG_BX) {
12793                 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
12794             }
12795             gen_goto_tb(ctx, 0, ctx->btarget);
12796             break;
12797         case MIPS_HFLAG_BL:
12798             /* blikely taken case */
12799             gen_goto_tb(ctx, 0, ctx->btarget);
12800             break;
12801         case MIPS_HFLAG_BC:
12802             /* Conditional branch */
12803             {
12804                 TCGLabel *l1 = gen_new_label();
12805
12806                 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
12807                 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
12808                 gen_set_label(l1);
12809                 gen_goto_tb(ctx, 0, ctx->btarget);
12810             }
12811             break;
12812         case MIPS_HFLAG_BR:
12813             /* unconditional branch to register */
12814             if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
12815                 TCGv t0 = tcg_temp_new();
12816                 TCGv_i32 t1 = tcg_temp_new_i32();
12817
12818                 tcg_gen_andi_tl(t0, btarget, 0x1);
12819                 tcg_gen_trunc_tl_i32(t1, t0);
12820                 tcg_temp_free(t0);
12821                 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
12822                 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
12823                 tcg_gen_or_i32(hflags, hflags, t1);
12824                 tcg_temp_free_i32(t1);
12825
12826                 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
12827             } else {
12828                 tcg_gen_mov_tl(cpu_PC, btarget);
12829             }
12830             if (ctx->base.singlestep_enabled) {
12831                 save_cpu_state(ctx, 0);
12832                 gen_helper_raise_exception_debug(cpu_env);
12833             }
12834             tcg_gen_lookup_and_goto_ptr();
12835             break;
12836         default:
12837             fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
12838             abort();
12839         }
12840     }
12841 }
12842
12843 /* Compact Branches */
12844 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
12845                                        int rs, int rt, int32_t offset)
12846 {
12847     int bcond_compute = 0;
12848     TCGv t0 = tcg_temp_new();
12849     TCGv t1 = tcg_temp_new();
12850     int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
12851
12852     if (ctx->hflags & MIPS_HFLAG_BMASK) {
12853 #ifdef MIPS_DEBUG_DISAS
12854         LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
12855                   "\n", ctx->base.pc_next);
12856 #endif
12857         generate_exception_end(ctx, EXCP_RI);
12858         goto out;
12859     }
12860
12861     /* Load needed operands and calculate btarget */
12862     switch (opc) {
12863     /* compact branch */
12864     case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12865     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12866         gen_load_gpr(t0, rs);
12867         gen_load_gpr(t1, rt);
12868         bcond_compute = 1;
12869         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12870         if (rs <= rt && rs == 0) {
12871             /* OPC_BEQZALC, OPC_BNEZALC */
12872             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12873         }
12874         break;
12875     case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12876     case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12877         gen_load_gpr(t0, rs);
12878         gen_load_gpr(t1, rt);
12879         bcond_compute = 1;
12880         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12881         break;
12882     case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12883     case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12884         if (rs == 0 || rs == rt) {
12885             /* OPC_BLEZALC, OPC_BGEZALC */
12886             /* OPC_BGTZALC, OPC_BLTZALC */
12887             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12888         }
12889         gen_load_gpr(t0, rs);
12890         gen_load_gpr(t1, rt);
12891         bcond_compute = 1;
12892         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12893         break;
12894     case OPC_BC:
12895     case OPC_BALC:
12896         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12897         break;
12898     case OPC_BEQZC:
12899     case OPC_BNEZC:
12900         if (rs != 0) {
12901             /* OPC_BEQZC, OPC_BNEZC */
12902             gen_load_gpr(t0, rs);
12903             bcond_compute = 1;
12904             ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12905         } else {
12906             /* OPC_JIC, OPC_JIALC */
12907             TCGv tbase = tcg_temp_new();
12908             TCGv toffset = tcg_temp_new();
12909
12910             gen_load_gpr(tbase, rt);
12911             tcg_gen_movi_tl(toffset, offset);
12912             gen_op_addr_add(ctx, btarget, tbase, toffset);
12913             tcg_temp_free(tbase);
12914             tcg_temp_free(toffset);
12915         }
12916         break;
12917     default:
12918         MIPS_INVAL("Compact branch/jump");
12919         generate_exception_end(ctx, EXCP_RI);
12920         goto out;
12921     }
12922
12923     if (bcond_compute == 0) {
12924         /* Uncoditional compact branch */
12925         switch (opc) {
12926         case OPC_JIALC:
12927             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12928             /* Fallthrough */
12929         case OPC_JIC:
12930             ctx->hflags |= MIPS_HFLAG_BR;
12931             break;
12932         case OPC_BALC:
12933             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12934             /* Fallthrough */
12935         case OPC_BC:
12936             ctx->hflags |= MIPS_HFLAG_B;
12937             break;
12938         default:
12939             MIPS_INVAL("Compact branch/jump");
12940             generate_exception_end(ctx, EXCP_RI);
12941             goto out;
12942         }
12943
12944         /* Generating branch here as compact branches don't have delay slot */
12945         gen_branch(ctx, 4);
12946     } else {
12947         /* Conditional compact branch */
12948         TCGLabel *fs = gen_new_label();
12949         save_cpu_state(ctx, 0);
12950
12951         switch (opc) {
12952         case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12953             if (rs == 0 && rt != 0) {
12954                 /* OPC_BLEZALC */
12955                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12956             } else if (rs != 0 && rt != 0 && rs == rt) {
12957                 /* OPC_BGEZALC */
12958                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12959             } else {
12960                 /* OPC_BGEUC */
12961                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
12962             }
12963             break;
12964         case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12965             if (rs == 0 && rt != 0) {
12966                 /* OPC_BGTZALC */
12967                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12968             } else if (rs != 0 && rt != 0 && rs == rt) {
12969                 /* OPC_BLTZALC */
12970                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12971             } else {
12972                 /* OPC_BLTUC */
12973                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
12974             }
12975             break;
12976         case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12977             if (rs == 0 && rt != 0) {
12978                 /* OPC_BLEZC */
12979                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12980             } else if (rs != 0 && rt != 0 && rs == rt) {
12981                 /* OPC_BGEZC */
12982                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12983             } else {
12984                 /* OPC_BGEC */
12985                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
12986             }
12987             break;
12988         case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12989             if (rs == 0 && rt != 0) {
12990                 /* OPC_BGTZC */
12991                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12992             } else if (rs != 0 && rt != 0 && rs == rt) {
12993                 /* OPC_BLTZC */
12994                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12995             } else {
12996                 /* OPC_BLTC */
12997                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
12998             }
12999             break;
13000         case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
13001         case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
13002             if (rs >= rt) {
13003                 /* OPC_BOVC, OPC_BNVC */
13004                 TCGv t2 = tcg_temp_new();
13005                 TCGv t3 = tcg_temp_new();
13006                 TCGv t4 = tcg_temp_new();
13007                 TCGv input_overflow = tcg_temp_new();
13008
13009                 gen_load_gpr(t0, rs);
13010                 gen_load_gpr(t1, rt);
13011                 tcg_gen_ext32s_tl(t2, t0);
13012                 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
13013                 tcg_gen_ext32s_tl(t3, t1);
13014                 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
13015                 tcg_gen_or_tl(input_overflow, input_overflow, t4);
13016
13017                 tcg_gen_add_tl(t4, t2, t3);
13018                 tcg_gen_ext32s_tl(t4, t4);
13019                 tcg_gen_xor_tl(t2, t2, t3);
13020                 tcg_gen_xor_tl(t3, t4, t3);
13021                 tcg_gen_andc_tl(t2, t3, t2);
13022                 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
13023                 tcg_gen_or_tl(t4, t4, input_overflow);
13024                 if (opc == OPC_BOVC) {
13025                     /* OPC_BOVC */
13026                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
13027                 } else {
13028                     /* OPC_BNVC */
13029                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
13030                 }
13031                 tcg_temp_free(input_overflow);
13032                 tcg_temp_free(t4);
13033                 tcg_temp_free(t3);
13034                 tcg_temp_free(t2);
13035             } else if (rs < rt && rs == 0) {
13036                 /* OPC_BEQZALC, OPC_BNEZALC */
13037                 if (opc == OPC_BEQZALC) {
13038                     /* OPC_BEQZALC */
13039                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
13040                 } else {
13041                     /* OPC_BNEZALC */
13042                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
13043                 }
13044             } else {
13045                 /* OPC_BEQC, OPC_BNEC */
13046                 if (opc == OPC_BEQC) {
13047                     /* OPC_BEQC */
13048                     tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
13049                 } else {
13050                     /* OPC_BNEC */
13051                     tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
13052                 }
13053             }
13054             break;
13055         case OPC_BEQZC:
13056             tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
13057             break;
13058         case OPC_BNEZC:
13059             tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
13060             break;
13061         default:
13062             MIPS_INVAL("Compact conditional branch/jump");
13063             generate_exception_end(ctx, EXCP_RI);
13064             goto out;
13065         }
13066
13067         /* Generating branch here as compact branches don't have delay slot */
13068         gen_goto_tb(ctx, 1, ctx->btarget);
13069         gen_set_label(fs);
13070
13071         ctx->hflags |= MIPS_HFLAG_FBNSLOT;
13072     }
13073
13074 out:
13075     tcg_temp_free(t0);
13076     tcg_temp_free(t1);
13077 }
13078
13079 /* ISA extensions (ASEs) */
13080 /* MIPS16 extension to MIPS32 */
13081
13082 /* MIPS16 major opcodes */
13083 enum {
13084   M16_OPC_ADDIUSP = 0x00,
13085   M16_OPC_ADDIUPC = 0x01,
13086   M16_OPC_B = 0x02,
13087   M16_OPC_JAL = 0x03,
13088   M16_OPC_BEQZ = 0x04,
13089   M16_OPC_BNEQZ = 0x05,
13090   M16_OPC_SHIFT = 0x06,
13091   M16_OPC_LD = 0x07,
13092   M16_OPC_RRIA = 0x08,
13093   M16_OPC_ADDIU8 = 0x09,
13094   M16_OPC_SLTI = 0x0a,
13095   M16_OPC_SLTIU = 0x0b,
13096   M16_OPC_I8 = 0x0c,
13097   M16_OPC_LI = 0x0d,
13098   M16_OPC_CMPI = 0x0e,
13099   M16_OPC_SD = 0x0f,
13100   M16_OPC_LB = 0x10,
13101   M16_OPC_LH = 0x11,
13102   M16_OPC_LWSP = 0x12,
13103   M16_OPC_LW = 0x13,
13104   M16_OPC_LBU = 0x14,
13105   M16_OPC_LHU = 0x15,
13106   M16_OPC_LWPC = 0x16,
13107   M16_OPC_LWU = 0x17,
13108   M16_OPC_SB = 0x18,
13109   M16_OPC_SH = 0x19,
13110   M16_OPC_SWSP = 0x1a,
13111   M16_OPC_SW = 0x1b,
13112   M16_OPC_RRR = 0x1c,
13113   M16_OPC_RR = 0x1d,
13114   M16_OPC_EXTEND = 0x1e,
13115   M16_OPC_I64 = 0x1f
13116 };
13117
13118 /* I8 funct field */
13119 enum {
13120   I8_BTEQZ = 0x0,
13121   I8_BTNEZ = 0x1,
13122   I8_SWRASP = 0x2,
13123   I8_ADJSP = 0x3,
13124   I8_SVRS = 0x4,
13125   I8_MOV32R = 0x5,
13126   I8_MOVR32 = 0x7
13127 };
13128
13129 /* RRR f field */
13130 enum {
13131   RRR_DADDU = 0x0,
13132   RRR_ADDU = 0x1,
13133   RRR_DSUBU = 0x2,
13134   RRR_SUBU = 0x3
13135 };
13136
13137 /* RR funct field */
13138 enum {
13139   RR_JR = 0x00,
13140   RR_SDBBP = 0x01,
13141   RR_SLT = 0x02,
13142   RR_SLTU = 0x03,
13143   RR_SLLV = 0x04,
13144   RR_BREAK = 0x05,
13145   RR_SRLV = 0x06,
13146   RR_SRAV = 0x07,
13147   RR_DSRL = 0x08,
13148   RR_CMP = 0x0a,
13149   RR_NEG = 0x0b,
13150   RR_AND = 0x0c,
13151   RR_OR = 0x0d,
13152   RR_XOR = 0x0e,
13153   RR_NOT = 0x0f,
13154   RR_MFHI = 0x10,
13155   RR_CNVT = 0x11,
13156   RR_MFLO = 0x12,
13157   RR_DSRA = 0x13,
13158   RR_DSLLV = 0x14,
13159   RR_DSRLV = 0x16,
13160   RR_DSRAV = 0x17,
13161   RR_MULT = 0x18,
13162   RR_MULTU = 0x19,
13163   RR_DIV = 0x1a,
13164   RR_DIVU = 0x1b,
13165   RR_DMULT = 0x1c,
13166   RR_DMULTU = 0x1d,
13167   RR_DDIV = 0x1e,
13168   RR_DDIVU = 0x1f
13169 };
13170
13171 /* I64 funct field */
13172 enum {
13173   I64_LDSP = 0x0,
13174   I64_SDSP = 0x1,
13175   I64_SDRASP = 0x2,
13176   I64_DADJSP = 0x3,
13177   I64_LDPC = 0x4,
13178   I64_DADDIU5 = 0x5,
13179   I64_DADDIUPC = 0x6,
13180   I64_DADDIUSP = 0x7
13181 };
13182
13183 /* RR ry field for CNVT */
13184 enum {
13185   RR_RY_CNVT_ZEB = 0x0,
13186   RR_RY_CNVT_ZEH = 0x1,
13187   RR_RY_CNVT_ZEW = 0x2,
13188   RR_RY_CNVT_SEB = 0x4,
13189   RR_RY_CNVT_SEH = 0x5,
13190   RR_RY_CNVT_SEW = 0x6,
13191 };
13192
13193 static int xlat (int r)
13194 {
13195   static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13196
13197   return map[r];
13198 }
13199
13200 static void gen_mips16_save (DisasContext *ctx,
13201                              int xsregs, int aregs,
13202                              int do_ra, int do_s0, int do_s1,
13203                              int framesize)
13204 {
13205     TCGv t0 = tcg_temp_new();
13206     TCGv t1 = tcg_temp_new();
13207     TCGv t2 = tcg_temp_new();
13208     int args, astatic;
13209
13210     switch (aregs) {
13211     case 0:
13212     case 1:
13213     case 2:
13214     case 3:
13215     case 11:
13216         args = 0;
13217         break;
13218     case 4:
13219     case 5:
13220     case 6:
13221     case 7:
13222         args = 1;
13223         break;
13224     case 8:
13225     case 9:
13226     case 10:
13227         args = 2;
13228         break;
13229     case 12:
13230     case 13:
13231         args = 3;
13232         break;
13233     case 14:
13234         args = 4;
13235         break;
13236     default:
13237         generate_exception_end(ctx, EXCP_RI);
13238         return;
13239     }
13240
13241     switch (args) {
13242     case 4:
13243         gen_base_offset_addr(ctx, t0, 29, 12);
13244         gen_load_gpr(t1, 7);
13245         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13246         /* Fall through */
13247     case 3:
13248         gen_base_offset_addr(ctx, t0, 29, 8);
13249         gen_load_gpr(t1, 6);
13250         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13251         /* Fall through */
13252     case 2:
13253         gen_base_offset_addr(ctx, t0, 29, 4);
13254         gen_load_gpr(t1, 5);
13255         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13256         /* Fall through */
13257     case 1:
13258         gen_base_offset_addr(ctx, t0, 29, 0);
13259         gen_load_gpr(t1, 4);
13260         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13261     }
13262
13263     gen_load_gpr(t0, 29);
13264
13265 #define DECR_AND_STORE(reg) do {                                 \
13266         tcg_gen_movi_tl(t2, -4);                                 \
13267         gen_op_addr_add(ctx, t0, t0, t2);                        \
13268         gen_load_gpr(t1, reg);                                   \
13269         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
13270     } while (0)
13271
13272     if (do_ra) {
13273         DECR_AND_STORE(31);
13274     }
13275
13276     switch (xsregs) {
13277     case 7:
13278         DECR_AND_STORE(30);
13279         /* Fall through */
13280     case 6:
13281         DECR_AND_STORE(23);
13282         /* Fall through */
13283     case 5:
13284         DECR_AND_STORE(22);
13285         /* Fall through */
13286     case 4:
13287         DECR_AND_STORE(21);
13288         /* Fall through */
13289     case 3:
13290         DECR_AND_STORE(20);
13291         /* Fall through */
13292     case 2:
13293         DECR_AND_STORE(19);
13294         /* Fall through */
13295     case 1:
13296         DECR_AND_STORE(18);
13297     }
13298
13299     if (do_s1) {
13300         DECR_AND_STORE(17);
13301     }
13302     if (do_s0) {
13303         DECR_AND_STORE(16);
13304     }
13305
13306     switch (aregs) {
13307     case 0:
13308     case 4:
13309     case 8:
13310     case 12:
13311     case 14:
13312         astatic = 0;
13313         break;
13314     case 1:
13315     case 5:
13316     case 9:
13317     case 13:
13318         astatic = 1;
13319         break;
13320     case 2:
13321     case 6:
13322     case 10:
13323         astatic = 2;
13324         break;
13325     case 3:
13326     case 7:
13327         astatic = 3;
13328         break;
13329     case 11:
13330         astatic = 4;
13331         break;
13332     default:
13333         generate_exception_end(ctx, EXCP_RI);
13334         return;
13335     }
13336
13337     if (astatic > 0) {
13338         DECR_AND_STORE(7);
13339         if (astatic > 1) {
13340             DECR_AND_STORE(6);
13341             if (astatic > 2) {
13342                 DECR_AND_STORE(5);
13343                 if (astatic > 3) {
13344                     DECR_AND_STORE(4);
13345                 }
13346             }
13347         }
13348     }
13349 #undef DECR_AND_STORE
13350
13351     tcg_gen_movi_tl(t2, -framesize);
13352     gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
13353     tcg_temp_free(t0);
13354     tcg_temp_free(t1);
13355     tcg_temp_free(t2);
13356 }
13357
13358 static void gen_mips16_restore (DisasContext *ctx,
13359                                 int xsregs, int aregs,
13360                                 int do_ra, int do_s0, int do_s1,
13361                                 int framesize)
13362 {
13363     int astatic;
13364     TCGv t0 = tcg_temp_new();
13365     TCGv t1 = tcg_temp_new();
13366     TCGv t2 = tcg_temp_new();
13367
13368     tcg_gen_movi_tl(t2, framesize);
13369     gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
13370
13371 #define DECR_AND_LOAD(reg) do {                            \
13372         tcg_gen_movi_tl(t2, -4);                           \
13373         gen_op_addr_add(ctx, t0, t0, t2);                  \
13374         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
13375         gen_store_gpr(t1, reg);                            \
13376     } while (0)
13377
13378     if (do_ra) {
13379         DECR_AND_LOAD(31);
13380     }
13381
13382     switch (xsregs) {
13383     case 7:
13384         DECR_AND_LOAD(30);
13385         /* Fall through */
13386     case 6:
13387         DECR_AND_LOAD(23);
13388         /* Fall through */
13389     case 5:
13390         DECR_AND_LOAD(22);
13391         /* Fall through */
13392     case 4:
13393         DECR_AND_LOAD(21);
13394         /* Fall through */
13395     case 3:
13396         DECR_AND_LOAD(20);
13397         /* Fall through */
13398     case 2:
13399         DECR_AND_LOAD(19);
13400         /* Fall through */
13401     case 1:
13402         DECR_AND_LOAD(18);
13403     }
13404
13405     if (do_s1) {
13406         DECR_AND_LOAD(17);
13407     }
13408     if (do_s0) {
13409         DECR_AND_LOAD(16);
13410     }
13411
13412     switch (aregs) {
13413     case 0:
13414     case 4:
13415     case 8:
13416     case 12:
13417     case 14:
13418         astatic = 0;
13419         break;
13420     case 1:
13421     case 5:
13422     case 9:
13423     case 13:
13424         astatic = 1;
13425         break;
13426     case 2:
13427     case 6:
13428     case 10:
13429         astatic = 2;
13430         break;
13431     case 3:
13432     case 7:
13433         astatic = 3;
13434         break;
13435     case 11:
13436         astatic = 4;
13437         break;
13438     default:
13439         generate_exception_end(ctx, EXCP_RI);
13440         return;
13441     }
13442
13443     if (astatic > 0) {
13444         DECR_AND_LOAD(7);
13445         if (astatic > 1) {
13446             DECR_AND_LOAD(6);
13447             if (astatic > 2) {
13448                 DECR_AND_LOAD(5);
13449                 if (astatic > 3) {
13450                     DECR_AND_LOAD(4);
13451                 }
13452             }
13453         }
13454     }
13455 #undef DECR_AND_LOAD
13456
13457     tcg_gen_movi_tl(t2, framesize);
13458     gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
13459     tcg_temp_free(t0);
13460     tcg_temp_free(t1);
13461     tcg_temp_free(t2);
13462 }
13463
13464 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
13465                          int is_64_bit, int extended)
13466 {
13467     TCGv t0;
13468
13469     if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
13470         generate_exception_end(ctx, EXCP_RI);
13471         return;
13472     }
13473
13474     t0 = tcg_temp_new();
13475
13476     tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
13477     tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
13478     if (!is_64_bit) {
13479         tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13480     }
13481
13482     tcg_temp_free(t0);
13483 }
13484
13485 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
13486                                 int16_t offset)
13487 {
13488     TCGv_i32 t0 = tcg_const_i32(op);
13489     TCGv t1 = tcg_temp_new();
13490     gen_base_offset_addr(ctx, t1, base, offset);
13491     gen_helper_cache(cpu_env, t1, t0);
13492 }
13493
13494 #if defined(TARGET_MIPS64)
13495 static void decode_i64_mips16 (DisasContext *ctx,
13496                                int ry, int funct, int16_t offset,
13497                                int extended)
13498 {
13499     switch (funct) {
13500     case I64_LDSP:
13501         check_insn(ctx, ISA_MIPS3);
13502         check_mips_64(ctx);
13503         offset = extended ? offset : offset << 3;
13504         gen_ld(ctx, OPC_LD, ry, 29, offset);
13505         break;
13506     case I64_SDSP:
13507         check_insn(ctx, ISA_MIPS3);
13508         check_mips_64(ctx);
13509         offset = extended ? offset : offset << 3;
13510         gen_st(ctx, OPC_SD, ry, 29, offset);
13511         break;
13512     case I64_SDRASP:
13513         check_insn(ctx, ISA_MIPS3);
13514         check_mips_64(ctx);
13515         offset = extended ? offset : (ctx->opcode & 0xff) << 3;
13516         gen_st(ctx, OPC_SD, 31, 29, offset);
13517         break;
13518     case I64_DADJSP:
13519         check_insn(ctx, ISA_MIPS3);
13520         check_mips_64(ctx);
13521         offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
13522         gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
13523         break;
13524     case I64_LDPC:
13525         check_insn(ctx, ISA_MIPS3);
13526         check_mips_64(ctx);
13527         if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
13528             generate_exception_end(ctx, EXCP_RI);
13529         } else {
13530             offset = extended ? offset : offset << 3;
13531             gen_ld(ctx, OPC_LDPC, ry, 0, offset);
13532         }
13533         break;
13534     case I64_DADDIU5:
13535         check_insn(ctx, ISA_MIPS3);
13536         check_mips_64(ctx);
13537         offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
13538         gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
13539         break;
13540     case I64_DADDIUPC:
13541         check_insn(ctx, ISA_MIPS3);
13542         check_mips_64(ctx);
13543         offset = extended ? offset : offset << 2;
13544         gen_addiupc(ctx, ry, offset, 1, extended);
13545         break;
13546     case I64_DADDIUSP:
13547         check_insn(ctx, ISA_MIPS3);
13548         check_mips_64(ctx);
13549         offset = extended ? offset : offset << 2;
13550         gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
13551         break;
13552     }
13553 }
13554 #endif
13555
13556 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
13557 {
13558     int extend = cpu_lduw_code(env, ctx->base.pc_next + 2);
13559     int op, rx, ry, funct, sa;
13560     int16_t imm, offset;
13561
13562     ctx->opcode = (ctx->opcode << 16) | extend;
13563     op = (ctx->opcode >> 11) & 0x1f;
13564     sa = (ctx->opcode >> 22) & 0x1f;
13565     funct = (ctx->opcode >> 8) & 0x7;
13566     rx = xlat((ctx->opcode >> 8) & 0x7);
13567     ry = xlat((ctx->opcode >> 5) & 0x7);
13568     offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
13569                               | ((ctx->opcode >> 21) & 0x3f) << 5
13570                               | (ctx->opcode & 0x1f));
13571
13572     /* The extended opcodes cleverly reuse the opcodes from their 16-bit
13573        counterparts.  */
13574     switch (op) {
13575     case M16_OPC_ADDIUSP:
13576         gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
13577         break;
13578     case M16_OPC_ADDIUPC:
13579         gen_addiupc(ctx, rx, imm, 0, 1);
13580         break;
13581     case M16_OPC_B:
13582         gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
13583         /* No delay slot, so just process as a normal instruction */
13584         break;
13585     case M16_OPC_BEQZ:
13586         gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
13587         /* No delay slot, so just process as a normal instruction */
13588         break;
13589     case M16_OPC_BNEQZ:
13590         gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
13591         /* No delay slot, so just process as a normal instruction */
13592         break;
13593     case M16_OPC_SHIFT:
13594         switch (ctx->opcode & 0x3) {
13595         case 0x0:
13596             gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
13597             break;
13598         case 0x1:
13599 #if defined(TARGET_MIPS64)
13600             check_mips_64(ctx);
13601             gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
13602 #else
13603             generate_exception_end(ctx, EXCP_RI);
13604 #endif
13605             break;
13606         case 0x2:
13607             gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
13608             break;
13609         case 0x3:
13610             gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
13611             break;
13612         }
13613         break;
13614 #if defined(TARGET_MIPS64)
13615     case M16_OPC_LD:
13616         check_insn(ctx, ISA_MIPS3);
13617         check_mips_64(ctx);
13618         gen_ld(ctx, OPC_LD, ry, rx, offset);
13619         break;
13620 #endif
13621     case M16_OPC_RRIA:
13622         imm = ctx->opcode & 0xf;
13623         imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
13624         imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
13625         imm = (int16_t) (imm << 1) >> 1;
13626         if ((ctx->opcode >> 4) & 0x1) {
13627 #if defined(TARGET_MIPS64)
13628             check_mips_64(ctx);
13629             gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
13630 #else
13631             generate_exception_end(ctx, EXCP_RI);
13632 #endif
13633         } else {
13634             gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
13635         }
13636         break;
13637     case M16_OPC_ADDIU8:
13638         gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
13639         break;
13640     case M16_OPC_SLTI:
13641         gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
13642         break;
13643     case M16_OPC_SLTIU:
13644         gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
13645         break;
13646     case M16_OPC_I8:
13647         switch (funct) {
13648         case I8_BTEQZ:
13649             gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
13650             break;
13651         case I8_BTNEZ:
13652             gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
13653             break;
13654         case I8_SWRASP:
13655             gen_st(ctx, OPC_SW, 31, 29, imm);
13656             break;
13657         case I8_ADJSP:
13658             gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
13659             break;
13660         case I8_SVRS:
13661             check_insn(ctx, ISA_MIPS32);
13662             {
13663                 int xsregs = (ctx->opcode >> 24) & 0x7;
13664                 int aregs = (ctx->opcode >> 16) & 0xf;
13665                 int do_ra = (ctx->opcode >> 6) & 0x1;
13666                 int do_s0 = (ctx->opcode >> 5) & 0x1;
13667                 int do_s1 = (ctx->opcode >> 4) & 0x1;
13668                 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
13669                                  | (ctx->opcode & 0xf)) << 3;
13670
13671                 if (ctx->opcode & (1 << 7)) {
13672                     gen_mips16_save(ctx, xsregs, aregs,
13673                                     do_ra, do_s0, do_s1,
13674                                     framesize);
13675                 } else {
13676                     gen_mips16_restore(ctx, xsregs, aregs,
13677                                        do_ra, do_s0, do_s1,
13678                                        framesize);
13679                 }
13680             }
13681             break;
13682         default:
13683             generate_exception_end(ctx, EXCP_RI);
13684             break;
13685         }
13686         break;
13687     case M16_OPC_LI:
13688         tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
13689         break;
13690     case M16_OPC_CMPI:
13691         tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
13692         break;
13693 #if defined(TARGET_MIPS64)
13694     case M16_OPC_SD:
13695         check_insn(ctx, ISA_MIPS3);
13696         check_mips_64(ctx);
13697         gen_st(ctx, OPC_SD, ry, rx, offset);
13698         break;
13699 #endif
13700     case M16_OPC_LB:
13701         gen_ld(ctx, OPC_LB, ry, rx, offset);
13702         break;
13703     case M16_OPC_LH:
13704         gen_ld(ctx, OPC_LH, ry, rx, offset);
13705         break;
13706     case M16_OPC_LWSP:
13707         gen_ld(ctx, OPC_LW, rx, 29, offset);
13708         break;
13709     case M16_OPC_LW:
13710         gen_ld(ctx, OPC_LW, ry, rx, offset);
13711         break;
13712     case M16_OPC_LBU:
13713         gen_ld(ctx, OPC_LBU, ry, rx, offset);
13714         break;
13715     case M16_OPC_LHU:
13716         gen_ld(ctx, OPC_LHU, ry, rx, offset);
13717         break;
13718     case M16_OPC_LWPC:
13719         gen_ld(ctx, OPC_LWPC, rx, 0, offset);
13720         break;
13721 #if defined(TARGET_MIPS64)
13722     case M16_OPC_LWU:
13723         check_insn(ctx, ISA_MIPS3);
13724         check_mips_64(ctx);
13725         gen_ld(ctx, OPC_LWU, ry, rx, offset);
13726         break;
13727 #endif
13728     case M16_OPC_SB:
13729         gen_st(ctx, OPC_SB, ry, rx, offset);
13730         break;
13731     case M16_OPC_SH:
13732         gen_st(ctx, OPC_SH, ry, rx, offset);
13733         break;
13734     case M16_OPC_SWSP:
13735         gen_st(ctx, OPC_SW, rx, 29, offset);
13736         break;
13737     case M16_OPC_SW:
13738         gen_st(ctx, OPC_SW, ry, rx, offset);
13739         break;
13740 #if defined(TARGET_MIPS64)
13741     case M16_OPC_I64:
13742         decode_i64_mips16(ctx, ry, funct, offset, 1);
13743         break;
13744 #endif
13745     default:
13746         generate_exception_end(ctx, EXCP_RI);
13747         break;
13748     }
13749
13750     return 4;
13751 }
13752
13753 static inline bool is_uhi(int sdbbp_code)
13754 {
13755 #ifdef CONFIG_USER_ONLY
13756     return false;
13757 #else
13758     return semihosting_enabled() && sdbbp_code == 1;
13759 #endif
13760 }
13761
13762 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
13763 {
13764     int rx, ry;
13765     int sa;
13766     int op, cnvt_op, op1, offset;
13767     int funct;
13768     int n_bytes;
13769
13770     op = (ctx->opcode >> 11) & 0x1f;
13771     sa = (ctx->opcode >> 2) & 0x7;
13772     sa = sa == 0 ? 8 : sa;
13773     rx = xlat((ctx->opcode >> 8) & 0x7);
13774     cnvt_op = (ctx->opcode >> 5) & 0x7;
13775     ry = xlat((ctx->opcode >> 5) & 0x7);
13776     op1 = offset = ctx->opcode & 0x1f;
13777
13778     n_bytes = 2;
13779
13780     switch (op) {
13781     case M16_OPC_ADDIUSP:
13782         {
13783             int16_t imm = ((uint8_t) ctx->opcode) << 2;
13784
13785             gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
13786         }
13787         break;
13788     case M16_OPC_ADDIUPC:
13789         gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
13790         break;
13791     case M16_OPC_B:
13792         offset = (ctx->opcode & 0x7ff) << 1;
13793         offset = (int16_t)(offset << 4) >> 4;
13794         gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
13795         /* No delay slot, so just process as a normal instruction */
13796         break;
13797     case M16_OPC_JAL:
13798         offset = cpu_lduw_code(env, ctx->base.pc_next + 2);
13799         offset = (((ctx->opcode & 0x1f) << 21)
13800                   | ((ctx->opcode >> 5) & 0x1f) << 16
13801                   | offset) << 2;
13802         op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
13803         gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
13804         n_bytes = 4;
13805         break;
13806     case M16_OPC_BEQZ:
13807         gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
13808                            ((int8_t)ctx->opcode) << 1, 0);
13809         /* No delay slot, so just process as a normal instruction */
13810         break;
13811     case M16_OPC_BNEQZ:
13812         gen_compute_branch(ctx, OPC_BNE, 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_SHIFT:
13817         switch (ctx->opcode & 0x3) {
13818         case 0x0:
13819             gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
13820             break;
13821         case 0x1:
13822 #if defined(TARGET_MIPS64)
13823             check_insn(ctx, ISA_MIPS3);
13824             check_mips_64(ctx);
13825             gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
13826 #else
13827             generate_exception_end(ctx, EXCP_RI);
13828 #endif
13829             break;
13830         case 0x2:
13831             gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
13832             break;
13833         case 0x3:
13834             gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
13835             break;
13836         }
13837         break;
13838 #if defined(TARGET_MIPS64)
13839     case M16_OPC_LD:
13840         check_insn(ctx, ISA_MIPS3);
13841         check_mips_64(ctx);
13842         gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
13843         break;
13844 #endif
13845     case M16_OPC_RRIA:
13846         {
13847             int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
13848
13849             if ((ctx->opcode >> 4) & 1) {
13850 #if defined(TARGET_MIPS64)
13851                 check_insn(ctx, ISA_MIPS3);
13852                 check_mips_64(ctx);
13853                 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
13854 #else
13855                 generate_exception_end(ctx, EXCP_RI);
13856 #endif
13857             } else {
13858                 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
13859             }
13860         }
13861         break;
13862     case M16_OPC_ADDIU8:
13863         {
13864             int16_t imm = (int8_t) ctx->opcode;
13865
13866             gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
13867         }
13868         break;
13869     case M16_OPC_SLTI:
13870         {
13871             int16_t imm = (uint8_t) ctx->opcode;
13872             gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
13873         }
13874         break;
13875     case M16_OPC_SLTIU:
13876         {
13877             int16_t imm = (uint8_t) ctx->opcode;
13878             gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
13879         }
13880         break;
13881     case M16_OPC_I8:
13882         {
13883             int reg32;
13884
13885             funct = (ctx->opcode >> 8) & 0x7;
13886             switch (funct) {
13887             case I8_BTEQZ:
13888                 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
13889                                    ((int8_t)ctx->opcode) << 1, 0);
13890                 break;
13891             case I8_BTNEZ:
13892                 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
13893                                    ((int8_t)ctx->opcode) << 1, 0);
13894                 break;
13895             case I8_SWRASP:
13896                 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
13897                 break;
13898             case I8_ADJSP:
13899                 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
13900                               ((int8_t)ctx->opcode) << 3);
13901                 break;
13902             case I8_SVRS:
13903                 check_insn(ctx, ISA_MIPS32);
13904                 {
13905                     int do_ra = ctx->opcode & (1 << 6);
13906                     int do_s0 = ctx->opcode & (1 << 5);
13907                     int do_s1 = ctx->opcode & (1 << 4);
13908                     int framesize = ctx->opcode & 0xf;
13909
13910                     if (framesize == 0) {
13911                         framesize = 128;
13912                     } else {
13913                         framesize = framesize << 3;
13914                     }
13915
13916                     if (ctx->opcode & (1 << 7)) {
13917                         gen_mips16_save(ctx, 0, 0,
13918                                         do_ra, do_s0, do_s1, framesize);
13919                     } else {
13920                         gen_mips16_restore(ctx, 0, 0,
13921                                            do_ra, do_s0, do_s1, framesize);
13922                     }
13923                 }
13924                 break;
13925             case I8_MOV32R:
13926                 {
13927                     int rz = xlat(ctx->opcode & 0x7);
13928
13929                     reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
13930                         ((ctx->opcode >> 5) & 0x7);
13931                     gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
13932                 }
13933                 break;
13934             case I8_MOVR32:
13935                 reg32 = ctx->opcode & 0x1f;
13936                 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
13937                 break;
13938             default:
13939                 generate_exception_end(ctx, EXCP_RI);
13940                 break;
13941             }
13942         }
13943         break;
13944     case M16_OPC_LI:
13945         {
13946             int16_t imm = (uint8_t) ctx->opcode;
13947
13948             gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
13949         }
13950         break;
13951     case M16_OPC_CMPI:
13952         {
13953             int16_t imm = (uint8_t) ctx->opcode;
13954             gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
13955         }
13956         break;
13957 #if defined(TARGET_MIPS64)
13958     case M16_OPC_SD:
13959         check_insn(ctx, ISA_MIPS3);
13960         check_mips_64(ctx);
13961         gen_st(ctx, OPC_SD, ry, rx, offset << 3);
13962         break;
13963 #endif
13964     case M16_OPC_LB:
13965         gen_ld(ctx, OPC_LB, ry, rx, offset);
13966         break;
13967     case M16_OPC_LH:
13968         gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
13969         break;
13970     case M16_OPC_LWSP:
13971         gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
13972         break;
13973     case M16_OPC_LW:
13974         gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
13975         break;
13976     case M16_OPC_LBU:
13977         gen_ld(ctx, OPC_LBU, ry, rx, offset);
13978         break;
13979     case M16_OPC_LHU:
13980         gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
13981         break;
13982     case M16_OPC_LWPC:
13983         gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
13984         break;
13985 #if defined (TARGET_MIPS64)
13986     case M16_OPC_LWU:
13987         check_insn(ctx, ISA_MIPS3);
13988         check_mips_64(ctx);
13989         gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
13990         break;
13991 #endif
13992     case M16_OPC_SB:
13993         gen_st(ctx, OPC_SB, ry, rx, offset);
13994         break;
13995     case M16_OPC_SH:
13996         gen_st(ctx, OPC_SH, ry, rx, offset << 1);
13997         break;
13998     case M16_OPC_SWSP:
13999         gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
14000         break;
14001     case M16_OPC_SW:
14002         gen_st(ctx, OPC_SW, ry, rx, offset << 2);
14003         break;
14004     case M16_OPC_RRR:
14005         {
14006             int rz = xlat((ctx->opcode >> 2) & 0x7);
14007             int mips32_op;
14008
14009             switch (ctx->opcode & 0x3) {
14010             case RRR_ADDU:
14011                 mips32_op = OPC_ADDU;
14012                 break;
14013             case RRR_SUBU:
14014                 mips32_op = OPC_SUBU;
14015                 break;
14016 #if defined(TARGET_MIPS64)
14017             case RRR_DADDU:
14018                 mips32_op = OPC_DADDU;
14019                 check_insn(ctx, ISA_MIPS3);
14020                 check_mips_64(ctx);
14021                 break;
14022             case RRR_DSUBU:
14023                 mips32_op = OPC_DSUBU;
14024                 check_insn(ctx, ISA_MIPS3);
14025                 check_mips_64(ctx);
14026                 break;
14027 #endif
14028             default:
14029                 generate_exception_end(ctx, EXCP_RI);
14030                 goto done;
14031             }
14032
14033             gen_arith(ctx, mips32_op, rz, rx, ry);
14034         done:
14035             ;
14036         }
14037         break;
14038     case M16_OPC_RR:
14039         switch (op1) {
14040         case RR_JR:
14041             {
14042                 int nd = (ctx->opcode >> 7) & 0x1;
14043                 int link = (ctx->opcode >> 6) & 0x1;
14044                 int ra = (ctx->opcode >> 5) & 0x1;
14045
14046                 if (nd) {
14047                     check_insn(ctx, ISA_MIPS32);
14048                 }
14049
14050                 if (link) {
14051                     op = OPC_JALR;
14052                 } else {
14053                     op = OPC_JR;
14054                 }
14055
14056                 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
14057                                    (nd ? 0 : 2));
14058             }
14059             break;
14060         case RR_SDBBP:
14061             if (is_uhi(extract32(ctx->opcode, 5, 6))) {
14062                 gen_helper_do_semihosting(cpu_env);
14063             } else {
14064                 /* XXX: not clear which exception should be raised
14065                  *      when in debug mode...
14066                  */
14067                 check_insn(ctx, ISA_MIPS32);
14068                 generate_exception_end(ctx, EXCP_DBp);
14069             }
14070             break;
14071         case RR_SLT:
14072             gen_slt(ctx, OPC_SLT, 24, rx, ry);
14073             break;
14074         case RR_SLTU:
14075             gen_slt(ctx, OPC_SLTU, 24, rx, ry);
14076             break;
14077         case RR_BREAK:
14078             generate_exception_end(ctx, EXCP_BREAK);
14079             break;
14080         case RR_SLLV:
14081             gen_shift(ctx, OPC_SLLV, ry, rx, ry);
14082             break;
14083         case RR_SRLV:
14084             gen_shift(ctx, OPC_SRLV, ry, rx, ry);
14085             break;
14086         case RR_SRAV:
14087             gen_shift(ctx, OPC_SRAV, ry, rx, ry);
14088             break;
14089 #if defined (TARGET_MIPS64)
14090         case RR_DSRL:
14091             check_insn(ctx, ISA_MIPS3);
14092             check_mips_64(ctx);
14093             gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
14094             break;
14095 #endif
14096         case RR_CMP:
14097             gen_logic(ctx, OPC_XOR, 24, rx, ry);
14098             break;
14099         case RR_NEG:
14100             gen_arith(ctx, OPC_SUBU, rx, 0, ry);
14101             break;
14102         case RR_AND:
14103             gen_logic(ctx, OPC_AND, rx, rx, ry);
14104             break;
14105         case RR_OR:
14106             gen_logic(ctx, OPC_OR, rx, rx, ry);
14107             break;
14108         case RR_XOR:
14109             gen_logic(ctx, OPC_XOR, rx, rx, ry);
14110             break;
14111         case RR_NOT:
14112             gen_logic(ctx, OPC_NOR, rx, ry, 0);
14113             break;
14114         case RR_MFHI:
14115             gen_HILO(ctx, OPC_MFHI, 0, rx);
14116             break;
14117         case RR_CNVT:
14118             check_insn(ctx, ISA_MIPS32);
14119             switch (cnvt_op) {
14120             case RR_RY_CNVT_ZEB:
14121                 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14122                 break;
14123             case RR_RY_CNVT_ZEH:
14124                 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14125                 break;
14126             case RR_RY_CNVT_SEB:
14127                 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14128                 break;
14129             case RR_RY_CNVT_SEH:
14130                 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14131                 break;
14132 #if defined (TARGET_MIPS64)
14133             case RR_RY_CNVT_ZEW:
14134                 check_insn(ctx, ISA_MIPS64);
14135                 check_mips_64(ctx);
14136                 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14137                 break;
14138             case RR_RY_CNVT_SEW:
14139                 check_insn(ctx, ISA_MIPS64);
14140                 check_mips_64(ctx);
14141                 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14142                 break;
14143 #endif
14144             default:
14145                 generate_exception_end(ctx, EXCP_RI);
14146                 break;
14147             }
14148             break;
14149         case RR_MFLO:
14150             gen_HILO(ctx, OPC_MFLO, 0, rx);
14151             break;
14152 #if defined (TARGET_MIPS64)
14153         case RR_DSRA:
14154             check_insn(ctx, ISA_MIPS3);
14155             check_mips_64(ctx);
14156             gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
14157             break;
14158         case RR_DSLLV:
14159             check_insn(ctx, ISA_MIPS3);
14160             check_mips_64(ctx);
14161             gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
14162             break;
14163         case RR_DSRLV:
14164             check_insn(ctx, ISA_MIPS3);
14165             check_mips_64(ctx);
14166             gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
14167             break;
14168         case RR_DSRAV:
14169             check_insn(ctx, ISA_MIPS3);
14170             check_mips_64(ctx);
14171             gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
14172             break;
14173 #endif
14174         case RR_MULT:
14175             gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
14176             break;
14177         case RR_MULTU:
14178             gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
14179             break;
14180         case RR_DIV:
14181             gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
14182             break;
14183         case RR_DIVU:
14184             gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
14185             break;
14186 #if defined (TARGET_MIPS64)
14187         case RR_DMULT:
14188             check_insn(ctx, ISA_MIPS3);
14189             check_mips_64(ctx);
14190             gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
14191             break;
14192         case RR_DMULTU:
14193             check_insn(ctx, ISA_MIPS3);
14194             check_mips_64(ctx);
14195             gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
14196             break;
14197         case RR_DDIV:
14198             check_insn(ctx, ISA_MIPS3);
14199             check_mips_64(ctx);
14200             gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
14201             break;
14202         case RR_DDIVU:
14203             check_insn(ctx, ISA_MIPS3);
14204             check_mips_64(ctx);
14205             gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
14206             break;
14207 #endif
14208         default:
14209             generate_exception_end(ctx, EXCP_RI);
14210             break;
14211         }
14212         break;
14213     case M16_OPC_EXTEND:
14214         decode_extended_mips16_opc(env, ctx);
14215         n_bytes = 4;
14216         break;
14217 #if defined(TARGET_MIPS64)
14218     case M16_OPC_I64:
14219         funct = (ctx->opcode >> 8) & 0x7;
14220         decode_i64_mips16(ctx, ry, funct, offset, 0);
14221         break;
14222 #endif
14223     default:
14224         generate_exception_end(ctx, EXCP_RI);
14225         break;
14226     }
14227
14228     return n_bytes;
14229 }
14230
14231 /* microMIPS extension to MIPS32/MIPS64 */
14232
14233 /*
14234  * microMIPS32/microMIPS64 major opcodes
14235  *
14236  * 1. MIPS Architecture for Programmers Volume II-B:
14237  *      The microMIPS32 Instruction Set (Revision 3.05)
14238  *
14239  *    Table 6.2 microMIPS32 Encoding of Major Opcode Field
14240  *
14241  * 2. MIPS Architecture For Programmers Volume II-A:
14242  *      The MIPS64 Instruction Set (Revision 3.51)
14243  */
14244
14245 enum {
14246     POOL32A = 0x00,
14247     POOL16A = 0x01,
14248     LBU16 = 0x02,
14249     MOVE16 = 0x03,
14250     ADDI32 = 0x04,
14251     R6_LUI = 0x04,
14252     AUI = 0x04,
14253     LBU32 = 0x05,
14254     SB32 = 0x06,
14255     LB32 = 0x07,
14256
14257     POOL32B = 0x08,
14258     POOL16B = 0x09,
14259     LHU16 = 0x0a,
14260     ANDI16 = 0x0b,
14261     ADDIU32 = 0x0c,
14262     LHU32 = 0x0d,
14263     SH32 = 0x0e,
14264     LH32 = 0x0f,
14265
14266     POOL32I = 0x10,
14267     POOL16C = 0x11,
14268     LWSP16 = 0x12,
14269     POOL16D = 0x13,
14270     ORI32 = 0x14,
14271     POOL32F = 0x15,
14272     POOL32S = 0x16,  /* MIPS64 */
14273     DADDIU32 = 0x17, /* MIPS64 */
14274
14275     POOL32C = 0x18,
14276     LWGP16 = 0x19,
14277     LW16 = 0x1a,
14278     POOL16E = 0x1b,
14279     XORI32 = 0x1c,
14280     JALS32 = 0x1d,
14281     BOVC = 0x1d,
14282     BEQC = 0x1d,
14283     BEQZALC = 0x1d,
14284     ADDIUPC = 0x1e,
14285     PCREL = 0x1e,
14286     BNVC = 0x1f,
14287     BNEC = 0x1f,
14288     BNEZALC = 0x1f,
14289
14290     R6_BEQZC = 0x20,
14291     JIC = 0x20,
14292     POOL16F = 0x21,
14293     SB16 = 0x22,
14294     BEQZ16 = 0x23,
14295     BEQZC16 = 0x23,
14296     SLTI32 = 0x24,
14297     BEQ32 = 0x25,
14298     BC = 0x25,
14299     SWC132 = 0x26,
14300     LWC132 = 0x27,
14301
14302     /* 0x29 is reserved */
14303     RES_29 = 0x29,
14304     R6_BNEZC = 0x28,
14305     JIALC = 0x28,
14306     SH16 = 0x2a,
14307     BNEZ16 = 0x2b,
14308     BNEZC16 = 0x2b,
14309     SLTIU32 = 0x2c,
14310     BNE32 = 0x2d,
14311     BALC = 0x2d,
14312     SDC132 = 0x2e,
14313     LDC132 = 0x2f,
14314
14315     /* 0x31 is reserved */
14316     RES_31 = 0x31,
14317     BLEZALC = 0x30,
14318     BGEZALC = 0x30,
14319     BGEUC = 0x30,
14320     SWSP16 = 0x32,
14321     B16 = 0x33,
14322     BC16 = 0x33,
14323     ANDI32 = 0x34,
14324     J32 = 0x35,
14325     BGTZC = 0x35,
14326     BLTZC = 0x35,
14327     BLTC = 0x35,
14328     SD32 = 0x36, /* MIPS64 */
14329     LD32 = 0x37, /* MIPS64 */
14330
14331     /* 0x39 is reserved */
14332     RES_39 = 0x39,
14333     BGTZALC = 0x38,
14334     BLTZALC = 0x38,
14335     BLTUC = 0x38,
14336     SW16 = 0x3a,
14337     LI16 = 0x3b,
14338     JALX32 = 0x3c,
14339     JAL32 = 0x3d,
14340     BLEZC = 0x3d,
14341     BGEZC = 0x3d,
14342     BGEC = 0x3d,
14343     SW32 = 0x3e,
14344     LW32 = 0x3f
14345 };
14346
14347 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
14348 enum {
14349     ADDIUPC_00 = 0x00,
14350     ADDIUPC_01 = 0x01,
14351     ADDIUPC_02 = 0x02,
14352     ADDIUPC_03 = 0x03,
14353     ADDIUPC_04 = 0x04,
14354     ADDIUPC_05 = 0x05,
14355     ADDIUPC_06 = 0x06,
14356     ADDIUPC_07 = 0x07,
14357     AUIPC = 0x1e,
14358     ALUIPC = 0x1f,
14359     LWPC_08 = 0x08,
14360     LWPC_09 = 0x09,
14361     LWPC_0A = 0x0A,
14362     LWPC_0B = 0x0B,
14363     LWPC_0C = 0x0C,
14364     LWPC_0D = 0x0D,
14365     LWPC_0E = 0x0E,
14366     LWPC_0F = 0x0F,
14367 };
14368
14369 /* POOL32A encoding of minor opcode field */
14370
14371 enum {
14372     /* These opcodes are distinguished only by bits 9..6; those bits are
14373      * what are recorded below. */
14374     SLL32 = 0x0,
14375     SRL32 = 0x1,
14376     SRA = 0x2,
14377     ROTR = 0x3,
14378     SELEQZ = 0x5,
14379     SELNEZ = 0x6,
14380     R6_RDHWR = 0x7,
14381
14382     SLLV = 0x0,
14383     SRLV = 0x1,
14384     SRAV = 0x2,
14385     ROTRV = 0x3,
14386     ADD = 0x4,
14387     ADDU32 = 0x5,
14388     SUB = 0x6,
14389     SUBU32 = 0x7,
14390     MUL = 0x8,
14391     AND = 0x9,
14392     OR32 = 0xa,
14393     NOR = 0xb,
14394     XOR32 = 0xc,
14395     SLT = 0xd,
14396     SLTU = 0xe,
14397
14398     MOVN = 0x0,
14399     R6_MUL  = 0x0,
14400     MOVZ = 0x1,
14401     MUH  = 0x1,
14402     MULU = 0x2,
14403     MUHU = 0x3,
14404     LWXS = 0x4,
14405     R6_DIV  = 0x4,
14406     MOD  = 0x5,
14407     R6_DIVU = 0x6,
14408     MODU = 0x7,
14409
14410     /* The following can be distinguished by their lower 6 bits. */
14411     BREAK32 = 0x07,
14412     INS = 0x0c,
14413     LSA = 0x0f,
14414     ALIGN = 0x1f,
14415     EXT = 0x2c,
14416     POOL32AXF = 0x3c,
14417     SIGRIE = 0x3f
14418 };
14419
14420 /* POOL32AXF encoding of minor opcode field extension */
14421
14422 /*
14423  * 1. MIPS Architecture for Programmers Volume II-B:
14424  *      The microMIPS32 Instruction Set (Revision 3.05)
14425  *
14426  *    Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
14427  *
14428  * 2. MIPS Architecture for Programmers VolumeIV-e:
14429  *      The MIPS DSP Application-Specific Extension
14430  *        to the microMIPS32 Architecture (Revision 2.34)
14431  *
14432  *    Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
14433  */
14434
14435 enum {
14436     /* bits 11..6 */
14437     TEQ = 0x00,
14438     TGE = 0x08,
14439     TGEU = 0x10,
14440     TLT = 0x20,
14441     TLTU = 0x28,
14442     TNE = 0x30,
14443
14444     MFC0 = 0x03,
14445     MTC0 = 0x0b,
14446
14447     /* begin of microMIPS32 DSP */
14448
14449     /* bits 13..12 for 0x01 */
14450     MFHI_ACC = 0x0,
14451     MFLO_ACC = 0x1,
14452     MTHI_ACC = 0x2,
14453     MTLO_ACC = 0x3,
14454
14455     /* bits 13..12 for 0x2a */
14456     MADD_ACC = 0x0,
14457     MADDU_ACC = 0x1,
14458     MSUB_ACC = 0x2,
14459     MSUBU_ACC = 0x3,
14460
14461     /* bits 13..12 for 0x32 */
14462     MULT_ACC = 0x0,
14463     MULTU_ACC = 0x1,
14464
14465     /* end of microMIPS32 DSP */
14466
14467     /* bits 15..12 for 0x2c */
14468     BITSWAP = 0x0,
14469     SEB = 0x2,
14470     SEH = 0x3,
14471     CLO = 0x4,
14472     CLZ = 0x5,
14473     RDHWR = 0x6,
14474     WSBH = 0x7,
14475     MULT = 0x8,
14476     MULTU = 0x9,
14477     DIV = 0xa,
14478     DIVU = 0xb,
14479     MADD = 0xc,
14480     MADDU = 0xd,
14481     MSUB = 0xe,
14482     MSUBU = 0xf,
14483
14484     /* bits 15..12 for 0x34 */
14485     MFC2 = 0x4,
14486     MTC2 = 0x5,
14487     MFHC2 = 0x8,
14488     MTHC2 = 0x9,
14489     CFC2 = 0xc,
14490     CTC2 = 0xd,
14491
14492     /* bits 15..12 for 0x3c */
14493     JALR = 0x0,
14494     JR = 0x0,                   /* alias */
14495     JALRC = 0x0,
14496     JRC = 0x0,
14497     JALR_HB = 0x1,
14498     JALRC_HB = 0x1,
14499     JALRS = 0x4,
14500     JALRS_HB = 0x5,
14501
14502     /* bits 15..12 for 0x05 */
14503     RDPGPR = 0xe,
14504     WRPGPR = 0xf,
14505
14506     /* bits 15..12 for 0x0d */
14507     TLBP = 0x0,
14508     TLBR = 0x1,
14509     TLBWI = 0x2,
14510     TLBWR = 0x3,
14511     TLBINV = 0x4,
14512     TLBINVF = 0x5,
14513     WAIT = 0x9,
14514     IRET = 0xd,
14515     DERET = 0xe,
14516     ERET = 0xf,
14517
14518     /* bits 15..12 for 0x15 */
14519     DMT = 0x0,
14520     DVPE = 0x1,
14521     EMT = 0x2,
14522     EVPE = 0x3,
14523
14524     /* bits 15..12 for 0x1d */
14525     DI = 0x4,
14526     EI = 0x5,
14527
14528     /* bits 15..12 for 0x2d */
14529     SYNC = 0x6,
14530     SYSCALL = 0x8,
14531     SDBBP = 0xd,
14532
14533     /* bits 15..12 for 0x35 */
14534     MFHI32 = 0x0,
14535     MFLO32 = 0x1,
14536     MTHI32 = 0x2,
14537     MTLO32 = 0x3,
14538 };
14539
14540 /* POOL32B encoding of minor opcode field (bits 15..12) */
14541
14542 enum {
14543     LWC2 = 0x0,
14544     LWP = 0x1,
14545     LDP = 0x4,
14546     LWM32 = 0x5,
14547     CACHE = 0x6,
14548     LDM = 0x7,
14549     SWC2 = 0x8,
14550     SWP = 0x9,
14551     SDP = 0xc,
14552     SWM32 = 0xd,
14553     SDM = 0xf
14554 };
14555
14556 /* POOL32C encoding of minor opcode field (bits 15..12) */
14557
14558 enum {
14559     LWL = 0x0,
14560     SWL = 0x8,
14561     LWR = 0x1,
14562     SWR = 0x9,
14563     PREF = 0x2,
14564     ST_EVA = 0xa,
14565     LL = 0x3,
14566     SC = 0xb,
14567     LDL = 0x4,
14568     SDL = 0xc,
14569     LDR = 0x5,
14570     SDR = 0xd,
14571     LD_EVA = 0x6,
14572     LWU = 0xe,
14573     LLD = 0x7,
14574     SCD = 0xf
14575 };
14576
14577 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
14578
14579 enum {
14580     LBUE = 0x0,
14581     LHUE = 0x1,
14582     LWLE = 0x2,
14583     LWRE = 0x3,
14584     LBE = 0x4,
14585     LHE = 0x5,
14586     LLE = 0x6,
14587     LWE = 0x7,
14588 };
14589
14590 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
14591
14592 enum {
14593     SWLE = 0x0,
14594     SWRE = 0x1,
14595     PREFE = 0x2,
14596     CACHEE = 0x3,
14597     SBE = 0x4,
14598     SHE = 0x5,
14599     SCE = 0x6,
14600     SWE = 0x7,
14601 };
14602
14603 /* POOL32F encoding of minor opcode field (bits 5..0) */
14604
14605 enum {
14606     /* These are the bit 7..6 values */
14607     ADD_FMT = 0x0,
14608
14609     SUB_FMT = 0x1,
14610
14611     MUL_FMT = 0x2,
14612
14613     DIV_FMT = 0x3,
14614
14615     /* These are the bit 8..6 values */
14616     MOVN_FMT = 0x0,
14617     RSQRT2_FMT = 0x0,
14618     MOVF_FMT = 0x0,
14619     RINT_FMT = 0x0,
14620     SELNEZ_FMT = 0x0,
14621
14622     MOVZ_FMT = 0x1,
14623     LWXC1 = 0x1,
14624     MOVT_FMT = 0x1,
14625     CLASS_FMT = 0x1,
14626     SELEQZ_FMT = 0x1,
14627
14628     PLL_PS = 0x2,
14629     SWXC1 = 0x2,
14630     SEL_FMT = 0x2,
14631
14632     PLU_PS = 0x3,
14633     LDXC1 = 0x3,
14634
14635     MOVN_FMT_04 = 0x4,
14636     PUL_PS = 0x4,
14637     SDXC1 = 0x4,
14638     RECIP2_FMT = 0x4,
14639
14640     MOVZ_FMT_05 = 0x05,
14641     PUU_PS = 0x5,
14642     LUXC1 = 0x5,
14643
14644     CVT_PS_S = 0x6,
14645     SUXC1 = 0x6,
14646     ADDR_PS = 0x6,
14647     PREFX = 0x6,
14648     MADDF_FMT = 0x6,
14649
14650     MULR_PS = 0x7,
14651     MSUBF_FMT = 0x7,
14652
14653     MADD_S = 0x01,
14654     MADD_D = 0x09,
14655     MADD_PS = 0x11,
14656     ALNV_PS = 0x19,
14657     MSUB_S = 0x21,
14658     MSUB_D = 0x29,
14659     MSUB_PS = 0x31,
14660
14661     NMADD_S = 0x02,
14662     NMADD_D = 0x0a,
14663     NMADD_PS = 0x12,
14664     NMSUB_S = 0x22,
14665     NMSUB_D = 0x2a,
14666     NMSUB_PS = 0x32,
14667
14668     MIN_FMT = 0x3,
14669     MAX_FMT = 0xb,
14670     MINA_FMT = 0x23,
14671     MAXA_FMT = 0x2b,
14672     POOL32FXF = 0x3b,
14673
14674     CABS_COND_FMT = 0x1c,              /* MIPS3D */
14675     C_COND_FMT = 0x3c,
14676
14677     CMP_CONDN_S = 0x5,
14678     CMP_CONDN_D = 0x15
14679 };
14680
14681 /* POOL32Fxf encoding of minor opcode extension field */
14682
14683 enum {
14684     CVT_L = 0x04,
14685     RSQRT_FMT = 0x08,
14686     FLOOR_L = 0x0c,
14687     CVT_PW_PS = 0x1c,
14688     CVT_W = 0x24,
14689     SQRT_FMT = 0x28,
14690     FLOOR_W = 0x2c,
14691     CVT_PS_PW = 0x3c,
14692     CFC1 = 0x40,
14693     RECIP_FMT = 0x48,
14694     CEIL_L = 0x4c,
14695     CTC1 = 0x60,
14696     CEIL_W = 0x6c,
14697     MFC1 = 0x80,
14698     CVT_S_PL = 0x84,
14699     TRUNC_L = 0x8c,
14700     MTC1 = 0xa0,
14701     CVT_S_PU = 0xa4,
14702     TRUNC_W = 0xac,
14703     MFHC1 = 0xc0,
14704     ROUND_L = 0xcc,
14705     MTHC1 = 0xe0,
14706     ROUND_W = 0xec,
14707
14708     MOV_FMT = 0x01,
14709     MOVF = 0x05,
14710     ABS_FMT = 0x0d,
14711     RSQRT1_FMT = 0x1d,
14712     MOVT = 0x25,
14713     NEG_FMT = 0x2d,
14714     CVT_D = 0x4d,
14715     RECIP1_FMT = 0x5d,
14716     CVT_S = 0x6d
14717 };
14718
14719 /* POOL32I encoding of minor opcode field (bits 25..21) */
14720
14721 enum {
14722     BLTZ = 0x00,
14723     BLTZAL = 0x01,
14724     BGEZ = 0x02,
14725     BGEZAL = 0x03,
14726     BLEZ = 0x04,
14727     BNEZC = 0x05,
14728     BGTZ = 0x06,
14729     BEQZC = 0x07,
14730     TLTI = 0x08,
14731     BC1EQZC = 0x08,
14732     TGEI = 0x09,
14733     BC1NEZC = 0x09,
14734     TLTIU = 0x0a,
14735     BC2EQZC = 0x0a,
14736     TGEIU = 0x0b,
14737     BC2NEZC = 0x0a,
14738     TNEI = 0x0c,
14739     R6_SYNCI = 0x0c,
14740     LUI = 0x0d,
14741     TEQI = 0x0e,
14742     SYNCI = 0x10,
14743     BLTZALS = 0x11,
14744     BGEZALS = 0x13,
14745     BC2F = 0x14,
14746     BC2T = 0x15,
14747     BPOSGE64 = 0x1a,
14748     BPOSGE32 = 0x1b,
14749     /* These overlap and are distinguished by bit16 of the instruction */
14750     BC1F = 0x1c,
14751     BC1T = 0x1d,
14752     BC1ANY2F = 0x1c,
14753     BC1ANY2T = 0x1d,
14754     BC1ANY4F = 0x1e,
14755     BC1ANY4T = 0x1f
14756 };
14757
14758 /* POOL16A encoding of minor opcode field */
14759
14760 enum {
14761     ADDU16 = 0x0,
14762     SUBU16 = 0x1
14763 };
14764
14765 /* POOL16B encoding of minor opcode field */
14766
14767 enum {
14768     SLL16 = 0x0,
14769     SRL16 = 0x1
14770 };
14771
14772 /* POOL16C encoding of minor opcode field */
14773
14774 enum {
14775     NOT16 = 0x00,
14776     XOR16 = 0x04,
14777     AND16 = 0x08,
14778     OR16 = 0x0c,
14779     LWM16 = 0x10,
14780     SWM16 = 0x14,
14781     JR16 = 0x18,
14782     JRC16 = 0x1a,
14783     JALR16 = 0x1c,
14784     JALR16S = 0x1e,
14785     MFHI16 = 0x20,
14786     MFLO16 = 0x24,
14787     BREAK16 = 0x28,
14788     SDBBP16 = 0x2c,
14789     JRADDIUSP = 0x30
14790 };
14791
14792 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
14793
14794 enum {
14795     R6_NOT16    = 0x00,
14796     R6_AND16    = 0x01,
14797     R6_LWM16    = 0x02,
14798     R6_JRC16    = 0x03,
14799     MOVEP       = 0x04,
14800     MOVEP_05    = 0x05,
14801     MOVEP_06    = 0x06,
14802     MOVEP_07    = 0x07,
14803     R6_XOR16    = 0x08,
14804     R6_OR16     = 0x09,
14805     R6_SWM16    = 0x0a,
14806     JALRC16     = 0x0b,
14807     MOVEP_0C    = 0x0c,
14808     MOVEP_0D    = 0x0d,
14809     MOVEP_0E    = 0x0e,
14810     MOVEP_0F    = 0x0f,
14811     JRCADDIUSP  = 0x13,
14812     R6_BREAK16  = 0x1b,
14813     R6_SDBBP16  = 0x3b
14814 };
14815
14816 /* POOL16D encoding of minor opcode field */
14817
14818 enum {
14819     ADDIUS5 = 0x0,
14820     ADDIUSP = 0x1
14821 };
14822
14823 /* POOL16E encoding of minor opcode field */
14824
14825 enum {
14826     ADDIUR2 = 0x0,
14827     ADDIUR1SP = 0x1
14828 };
14829
14830 static int mmreg (int r)
14831 {
14832     static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
14833
14834     return map[r];
14835 }
14836
14837 /* Used for 16-bit store instructions.  */
14838 static int mmreg2 (int r)
14839 {
14840     static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
14841
14842     return map[r];
14843 }
14844
14845 #define uMIPS_RD(op) ((op >> 7) & 0x7)
14846 #define uMIPS_RS(op) ((op >> 4) & 0x7)
14847 #define uMIPS_RS2(op) uMIPS_RS(op)
14848 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
14849 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
14850 #define uMIPS_RS5(op) (op & 0x1f)
14851
14852 /* Signed immediate */
14853 #define SIMM(op, start, width)                                          \
14854     ((int32_t)(((op >> start) & ((~0U) >> (32-width)))                 \
14855                << (32-width))                                           \
14856      >> (32-width))
14857 /* Zero-extended immediate */
14858 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
14859
14860 static void gen_addiur1sp(DisasContext *ctx)
14861 {
14862     int rd = mmreg(uMIPS_RD(ctx->opcode));
14863
14864     gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
14865 }
14866
14867 static void gen_addiur2(DisasContext *ctx)
14868 {
14869     static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
14870     int rd = mmreg(uMIPS_RD(ctx->opcode));
14871     int rs = mmreg(uMIPS_RS(ctx->opcode));
14872
14873     gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
14874 }
14875
14876 static void gen_addiusp(DisasContext *ctx)
14877 {
14878     int encoded = ZIMM(ctx->opcode, 1, 9);
14879     int decoded;
14880
14881     if (encoded <= 1) {
14882         decoded = 256 + encoded;
14883     } else if (encoded <= 255) {
14884         decoded = encoded;
14885     } else if (encoded <= 509) {
14886         decoded = encoded - 512;
14887     } else {
14888         decoded = encoded - 768;
14889     }
14890
14891     gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
14892 }
14893
14894 static void gen_addius5(DisasContext *ctx)
14895 {
14896     int imm = SIMM(ctx->opcode, 1, 4);
14897     int rd = (ctx->opcode >> 5) & 0x1f;
14898
14899     gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
14900 }
14901
14902 static void gen_andi16(DisasContext *ctx)
14903 {
14904     static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
14905                                  31, 32, 63, 64, 255, 32768, 65535 };
14906     int rd = mmreg(uMIPS_RD(ctx->opcode));
14907     int rs = mmreg(uMIPS_RS(ctx->opcode));
14908     int encoded = ZIMM(ctx->opcode, 0, 4);
14909
14910     gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
14911 }
14912
14913 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
14914                                int base, int16_t offset)
14915 {
14916     TCGv t0, t1;
14917     TCGv_i32 t2;
14918
14919     if (ctx->hflags & MIPS_HFLAG_BMASK) {
14920         generate_exception_end(ctx, EXCP_RI);
14921         return;
14922     }
14923
14924     t0 = tcg_temp_new();
14925
14926     gen_base_offset_addr(ctx, t0, base, offset);
14927
14928     t1 = tcg_const_tl(reglist);
14929     t2 = tcg_const_i32(ctx->mem_idx);
14930
14931     save_cpu_state(ctx, 1);
14932     switch (opc) {
14933     case LWM32:
14934         gen_helper_lwm(cpu_env, t0, t1, t2);
14935         break;
14936     case SWM32:
14937         gen_helper_swm(cpu_env, t0, t1, t2);
14938         break;
14939 #ifdef TARGET_MIPS64
14940     case LDM:
14941         gen_helper_ldm(cpu_env, t0, t1, t2);
14942         break;
14943     case SDM:
14944         gen_helper_sdm(cpu_env, t0, t1, t2);
14945         break;
14946 #endif
14947     }
14948     tcg_temp_free(t0);
14949     tcg_temp_free(t1);
14950     tcg_temp_free_i32(t2);
14951 }
14952
14953
14954 static void gen_pool16c_insn(DisasContext *ctx)
14955 {
14956     int rd = mmreg((ctx->opcode >> 3) & 0x7);
14957     int rs = mmreg(ctx->opcode & 0x7);
14958
14959     switch (((ctx->opcode) >> 4) & 0x3f) {
14960     case NOT16 + 0:
14961     case NOT16 + 1:
14962     case NOT16 + 2:
14963     case NOT16 + 3:
14964         gen_logic(ctx, OPC_NOR, rd, rs, 0);
14965         break;
14966     case XOR16 + 0:
14967     case XOR16 + 1:
14968     case XOR16 + 2:
14969     case XOR16 + 3:
14970         gen_logic(ctx, OPC_XOR, rd, rd, rs);
14971         break;
14972     case AND16 + 0:
14973     case AND16 + 1:
14974     case AND16 + 2:
14975     case AND16 + 3:
14976         gen_logic(ctx, OPC_AND, rd, rd, rs);
14977         break;
14978     case OR16 + 0:
14979     case OR16 + 1:
14980     case OR16 + 2:
14981     case OR16 + 3:
14982         gen_logic(ctx, OPC_OR, rd, rd, rs);
14983         break;
14984     case LWM16 + 0:
14985     case LWM16 + 1:
14986     case LWM16 + 2:
14987     case LWM16 + 3:
14988         {
14989             static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14990             int offset = ZIMM(ctx->opcode, 0, 4);
14991
14992             gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
14993                               29, offset << 2);
14994         }
14995         break;
14996     case SWM16 + 0:
14997     case SWM16 + 1:
14998     case SWM16 + 2:
14999     case SWM16 + 3:
15000         {
15001             static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
15002             int offset = ZIMM(ctx->opcode, 0, 4);
15003
15004             gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
15005                               29, offset << 2);
15006         }
15007         break;
15008     case JR16 + 0:
15009     case JR16 + 1:
15010         {
15011             int reg = ctx->opcode & 0x1f;
15012
15013             gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
15014         }
15015         break;
15016     case JRC16 + 0:
15017     case JRC16 + 1:
15018         {
15019             int reg = ctx->opcode & 0x1f;
15020             gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
15021             /* Let normal delay slot handling in our caller take us
15022                to the branch target.  */
15023         }
15024         break;
15025     case JALR16 + 0:
15026     case JALR16 + 1:
15027         gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
15028         ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15029         break;
15030     case JALR16S + 0:
15031     case JALR16S + 1:
15032         gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
15033         ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15034         break;
15035     case MFHI16 + 0:
15036     case MFHI16 + 1:
15037         gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
15038         break;
15039     case MFLO16 + 0:
15040     case MFLO16 + 1:
15041         gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
15042         break;
15043     case BREAK16:
15044         generate_exception_end(ctx, EXCP_BREAK);
15045         break;
15046     case SDBBP16:
15047         if (is_uhi(extract32(ctx->opcode, 0, 4))) {
15048             gen_helper_do_semihosting(cpu_env);
15049         } else {
15050             /* XXX: not clear which exception should be raised
15051              *      when in debug mode...
15052              */
15053             check_insn(ctx, ISA_MIPS32);
15054             generate_exception_end(ctx, EXCP_DBp);
15055         }
15056         break;
15057     case JRADDIUSP + 0:
15058     case JRADDIUSP + 1:
15059         {
15060             int imm = ZIMM(ctx->opcode, 0, 5);
15061             gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
15062             gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
15063             /* Let normal delay slot handling in our caller take us
15064                to the branch target.  */
15065         }
15066         break;
15067     default:
15068         generate_exception_end(ctx, EXCP_RI);
15069         break;
15070     }
15071 }
15072
15073 static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
15074                              int enc_rs)
15075 {
15076     int rd, rs, re, rt;
15077     static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
15078     static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
15079     static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
15080     rd = rd_enc[enc_dest];
15081     re = re_enc[enc_dest];
15082     rs = rs_rt_enc[enc_rs];
15083     rt = rs_rt_enc[enc_rt];
15084     if (rs) {
15085         tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
15086     } else {
15087         tcg_gen_movi_tl(cpu_gpr[rd], 0);
15088     }
15089     if (rt) {
15090         tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
15091     } else {
15092         tcg_gen_movi_tl(cpu_gpr[re], 0);
15093     }
15094 }
15095
15096 static void gen_pool16c_r6_insn(DisasContext *ctx)
15097 {
15098     int rt = mmreg((ctx->opcode >> 7) & 0x7);
15099     int rs = mmreg((ctx->opcode >> 4) & 0x7);
15100
15101     switch (ctx->opcode & 0xf) {
15102     case R6_NOT16:
15103         gen_logic(ctx, OPC_NOR, rt, rs, 0);
15104         break;
15105     case R6_AND16:
15106         gen_logic(ctx, OPC_AND, rt, rt, rs);
15107         break;
15108     case R6_LWM16:
15109         {
15110             int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
15111             int offset = extract32(ctx->opcode, 4, 4);
15112             gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
15113         }
15114         break;
15115     case R6_JRC16: /* JRCADDIUSP */
15116         if ((ctx->opcode >> 4) & 1) {
15117             /* JRCADDIUSP */
15118             int imm = extract32(ctx->opcode, 5, 5);
15119             gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
15120             gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
15121         } else {
15122             /* JRC16 */
15123             rs = extract32(ctx->opcode, 5, 5);
15124             gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
15125         }
15126         break;
15127     case MOVEP:
15128     case MOVEP_05:
15129     case MOVEP_06:
15130     case MOVEP_07:
15131     case MOVEP_0C:
15132     case MOVEP_0D:
15133     case MOVEP_0E:
15134     case MOVEP_0F:
15135         {
15136             int enc_dest = uMIPS_RD(ctx->opcode);
15137             int enc_rt = uMIPS_RS2(ctx->opcode);
15138             int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
15139             gen_movep(ctx, enc_dest, enc_rt, enc_rs);
15140         }
15141         break;
15142     case R6_XOR16:
15143         gen_logic(ctx, OPC_XOR, rt, rt, rs);
15144         break;
15145     case R6_OR16:
15146         gen_logic(ctx, OPC_OR, rt, rt, rs);
15147         break;
15148     case R6_SWM16:
15149         {
15150             int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
15151             int offset = extract32(ctx->opcode, 4, 4);
15152             gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
15153         }
15154         break;
15155     case JALRC16: /* BREAK16, SDBBP16 */
15156         switch (ctx->opcode & 0x3f) {
15157         case JALRC16:
15158         case JALRC16 + 0x20:
15159             /* JALRC16 */
15160             gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
15161                                31, 0, 0);
15162             break;
15163         case R6_BREAK16:
15164             /* BREAK16 */
15165             generate_exception(ctx, EXCP_BREAK);
15166             break;
15167         case R6_SDBBP16:
15168             /* SDBBP16 */
15169             if (is_uhi(extract32(ctx->opcode, 6, 4))) {
15170                 gen_helper_do_semihosting(cpu_env);
15171             } else {
15172                 if (ctx->hflags & MIPS_HFLAG_SBRI) {
15173                     generate_exception(ctx, EXCP_RI);
15174                 } else {
15175                     generate_exception(ctx, EXCP_DBp);
15176                 }
15177             }
15178             break;
15179         }
15180         break;
15181     default:
15182         generate_exception(ctx, EXCP_RI);
15183         break;
15184     }
15185 }
15186
15187 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
15188 {
15189     TCGv t0 = tcg_temp_new();
15190     TCGv t1 = tcg_temp_new();
15191
15192     gen_load_gpr(t0, base);
15193
15194     if (index != 0) {
15195         gen_load_gpr(t1, index);
15196         tcg_gen_shli_tl(t1, t1, 2);
15197         gen_op_addr_add(ctx, t0, t1, t0);
15198     }
15199
15200     tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15201     gen_store_gpr(t1, rd);
15202
15203     tcg_temp_free(t0);
15204     tcg_temp_free(t1);
15205 }
15206
15207 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
15208                            int base, int16_t offset)
15209 {
15210     TCGv t0, t1;
15211
15212     if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
15213         generate_exception_end(ctx, EXCP_RI);
15214         return;
15215     }
15216
15217     t0 = tcg_temp_new();
15218     t1 = tcg_temp_new();
15219
15220     gen_base_offset_addr(ctx, t0, base, offset);
15221
15222     switch (opc) {
15223     case LWP:
15224         if (rd == base) {
15225             generate_exception_end(ctx, EXCP_RI);
15226             return;
15227         }
15228         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15229         gen_store_gpr(t1, rd);
15230         tcg_gen_movi_tl(t1, 4);
15231         gen_op_addr_add(ctx, t0, t0, t1);
15232         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15233         gen_store_gpr(t1, rd+1);
15234         break;
15235     case SWP:
15236         gen_load_gpr(t1, rd);
15237         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
15238         tcg_gen_movi_tl(t1, 4);
15239         gen_op_addr_add(ctx, t0, t0, t1);
15240         gen_load_gpr(t1, rd+1);
15241         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
15242         break;
15243 #ifdef TARGET_MIPS64
15244     case LDP:
15245         if (rd == base) {
15246             generate_exception_end(ctx, EXCP_RI);
15247             return;
15248         }
15249         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15250         gen_store_gpr(t1, rd);
15251         tcg_gen_movi_tl(t1, 8);
15252         gen_op_addr_add(ctx, t0, t0, t1);
15253         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15254         gen_store_gpr(t1, rd+1);
15255         break;
15256     case SDP:
15257         gen_load_gpr(t1, rd);
15258         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15259         tcg_gen_movi_tl(t1, 8);
15260         gen_op_addr_add(ctx, t0, t0, t1);
15261         gen_load_gpr(t1, rd+1);
15262         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15263         break;
15264 #endif
15265     }
15266     tcg_temp_free(t0);
15267     tcg_temp_free(t1);
15268 }
15269
15270 static void gen_sync(int stype)
15271 {
15272     TCGBar tcg_mo = TCG_BAR_SC;
15273
15274     switch (stype) {
15275     case 0x4: /* SYNC_WMB */
15276         tcg_mo |= TCG_MO_ST_ST;
15277         break;
15278     case 0x10: /* SYNC_MB */
15279         tcg_mo |= TCG_MO_ALL;
15280         break;
15281     case 0x11: /* SYNC_ACQUIRE */
15282         tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
15283         break;
15284     case 0x12: /* SYNC_RELEASE */
15285         tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
15286         break;
15287     case 0x13: /* SYNC_RMB */
15288         tcg_mo |= TCG_MO_LD_LD;
15289         break;
15290     default:
15291         tcg_mo |= TCG_MO_ALL;
15292         break;
15293     }
15294
15295     tcg_gen_mb(tcg_mo);
15296 }
15297
15298 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
15299 {
15300     int extension = (ctx->opcode >> 6) & 0x3f;
15301     int minor = (ctx->opcode >> 12) & 0xf;
15302     uint32_t mips32_op;
15303
15304     switch (extension) {
15305     case TEQ:
15306         mips32_op = OPC_TEQ;
15307         goto do_trap;
15308     case TGE:
15309         mips32_op = OPC_TGE;
15310         goto do_trap;
15311     case TGEU:
15312         mips32_op = OPC_TGEU;
15313         goto do_trap;
15314     case TLT:
15315         mips32_op = OPC_TLT;
15316         goto do_trap;
15317     case TLTU:
15318         mips32_op = OPC_TLTU;
15319         goto do_trap;
15320     case TNE:
15321         mips32_op = OPC_TNE;
15322     do_trap:
15323         gen_trap(ctx, mips32_op, rs, rt, -1);
15324         break;
15325 #ifndef CONFIG_USER_ONLY
15326     case MFC0:
15327     case MFC0 + 32:
15328         check_cp0_enabled(ctx);
15329         if (rt == 0) {
15330             /* Treat as NOP. */
15331             break;
15332         }
15333         gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
15334         break;
15335     case MTC0:
15336     case MTC0 + 32:
15337         check_cp0_enabled(ctx);
15338         {
15339             TCGv t0 = tcg_temp_new();
15340
15341             gen_load_gpr(t0, rt);
15342             gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
15343             tcg_temp_free(t0);
15344         }
15345         break;
15346 #endif
15347     case 0x2a:
15348         switch (minor & 3) {
15349         case MADD_ACC:
15350             gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
15351             break;
15352         case MADDU_ACC:
15353             gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
15354             break;
15355         case MSUB_ACC:
15356             gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
15357             break;
15358         case MSUBU_ACC:
15359             gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
15360             break;
15361         default:
15362             goto pool32axf_invalid;
15363         }
15364         break;
15365     case 0x32:
15366         switch (minor & 3) {
15367         case MULT_ACC:
15368             gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
15369             break;
15370         case MULTU_ACC:
15371             gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
15372             break;
15373         default:
15374             goto pool32axf_invalid;
15375         }
15376         break;
15377     case 0x2c:
15378         switch (minor) {
15379         case BITSWAP:
15380             check_insn(ctx, ISA_MIPS32R6);
15381             gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
15382             break;
15383         case SEB:
15384             gen_bshfl(ctx, OPC_SEB, rs, rt);
15385             break;
15386         case SEH:
15387             gen_bshfl(ctx, OPC_SEH, rs, rt);
15388             break;
15389         case CLO:
15390             mips32_op = OPC_CLO;
15391             goto do_cl;
15392         case CLZ:
15393             mips32_op = OPC_CLZ;
15394         do_cl:
15395             check_insn(ctx, ISA_MIPS32);
15396             gen_cl(ctx, mips32_op, rt, rs);
15397             break;
15398         case RDHWR:
15399             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15400             gen_rdhwr(ctx, rt, rs, 0);
15401             break;
15402         case WSBH:
15403             gen_bshfl(ctx, OPC_WSBH, rs, rt);
15404             break;
15405         case MULT:
15406             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15407             mips32_op = OPC_MULT;
15408             goto do_mul;
15409         case MULTU:
15410             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15411             mips32_op = OPC_MULTU;
15412             goto do_mul;
15413         case DIV:
15414             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15415             mips32_op = OPC_DIV;
15416             goto do_div;
15417         case DIVU:
15418             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15419             mips32_op = OPC_DIVU;
15420             goto do_div;
15421         do_div:
15422             check_insn(ctx, ISA_MIPS32);
15423             gen_muldiv(ctx, mips32_op, 0, rs, rt);
15424             break;
15425         case MADD:
15426             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15427             mips32_op = OPC_MADD;
15428             goto do_mul;
15429         case MADDU:
15430             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15431             mips32_op = OPC_MADDU;
15432             goto do_mul;
15433         case MSUB:
15434             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15435             mips32_op = OPC_MSUB;
15436             goto do_mul;
15437         case MSUBU:
15438             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15439             mips32_op = OPC_MSUBU;
15440         do_mul:
15441             check_insn(ctx, ISA_MIPS32);
15442             gen_muldiv(ctx, mips32_op, 0, rs, rt);
15443             break;
15444         default:
15445             goto pool32axf_invalid;
15446         }
15447         break;
15448     case 0x34:
15449         switch (minor) {
15450         case MFC2:
15451         case MTC2:
15452         case MFHC2:
15453         case MTHC2:
15454         case CFC2:
15455         case CTC2:
15456             generate_exception_err(ctx, EXCP_CpU, 2);
15457             break;
15458         default:
15459             goto pool32axf_invalid;
15460         }
15461         break;
15462     case 0x3c:
15463         switch (minor) {
15464         case JALR:    /* JALRC */
15465         case JALR_HB: /* JALRC_HB */
15466             if (ctx->insn_flags & ISA_MIPS32R6) {
15467                 /* JALRC, JALRC_HB */
15468                 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
15469             } else {
15470                 /* JALR, JALR_HB */
15471                 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
15472                 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15473             }
15474             break;
15475         case JALRS:
15476         case JALRS_HB:
15477             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15478             gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
15479             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15480             break;
15481         default:
15482             goto pool32axf_invalid;
15483         }
15484         break;
15485     case 0x05:
15486         switch (minor) {
15487         case RDPGPR:
15488             check_cp0_enabled(ctx);
15489             check_insn(ctx, ISA_MIPS32R2);
15490             gen_load_srsgpr(rs, rt);
15491             break;
15492         case WRPGPR:
15493             check_cp0_enabled(ctx);
15494             check_insn(ctx, ISA_MIPS32R2);
15495             gen_store_srsgpr(rs, rt);
15496             break;
15497         default:
15498             goto pool32axf_invalid;
15499         }
15500         break;
15501 #ifndef CONFIG_USER_ONLY
15502     case 0x0d:
15503         switch (minor) {
15504         case TLBP:
15505             mips32_op = OPC_TLBP;
15506             goto do_cp0;
15507         case TLBR:
15508             mips32_op = OPC_TLBR;
15509             goto do_cp0;
15510         case TLBWI:
15511             mips32_op = OPC_TLBWI;
15512             goto do_cp0;
15513         case TLBWR:
15514             mips32_op = OPC_TLBWR;
15515             goto do_cp0;
15516         case TLBINV:
15517             mips32_op = OPC_TLBINV;
15518             goto do_cp0;
15519         case TLBINVF:
15520             mips32_op = OPC_TLBINVF;
15521             goto do_cp0;
15522         case WAIT:
15523             mips32_op = OPC_WAIT;
15524             goto do_cp0;
15525         case DERET:
15526             mips32_op = OPC_DERET;
15527             goto do_cp0;
15528         case ERET:
15529             mips32_op = OPC_ERET;
15530         do_cp0:
15531             gen_cp0(env, ctx, mips32_op, rt, rs);
15532             break;
15533         default:
15534             goto pool32axf_invalid;
15535         }
15536         break;
15537     case 0x1d:
15538         switch (minor) {
15539         case DI:
15540             check_cp0_enabled(ctx);
15541             {
15542                 TCGv t0 = tcg_temp_new();
15543
15544                 save_cpu_state(ctx, 1);
15545                 gen_helper_di(t0, cpu_env);
15546                 gen_store_gpr(t0, rs);
15547                 /* Stop translation as we may have switched the execution mode */
15548                 ctx->base.is_jmp = DISAS_STOP;
15549                 tcg_temp_free(t0);
15550             }
15551             break;
15552         case EI:
15553             check_cp0_enabled(ctx);
15554             {
15555                 TCGv t0 = tcg_temp_new();
15556
15557                 save_cpu_state(ctx, 1);
15558                 gen_helper_ei(t0, cpu_env);
15559                 gen_store_gpr(t0, rs);
15560                 /* DISAS_STOP isn't sufficient, we need to ensure we break out
15561                    of translated code to check for pending interrupts.  */
15562                 gen_save_pc(ctx->base.pc_next + 4);
15563                 ctx->base.is_jmp = DISAS_EXIT;
15564                 tcg_temp_free(t0);
15565             }
15566             break;
15567         default:
15568             goto pool32axf_invalid;
15569         }
15570         break;
15571 #endif
15572     case 0x2d:
15573         switch (minor) {
15574         case SYNC:
15575             gen_sync(extract32(ctx->opcode, 16, 5));
15576             break;
15577         case SYSCALL:
15578             generate_exception_end(ctx, EXCP_SYSCALL);
15579             break;
15580         case SDBBP:
15581             if (is_uhi(extract32(ctx->opcode, 16, 10))) {
15582                 gen_helper_do_semihosting(cpu_env);
15583             } else {
15584                 check_insn(ctx, ISA_MIPS32);
15585                 if (ctx->hflags & MIPS_HFLAG_SBRI) {
15586                     generate_exception_end(ctx, EXCP_RI);
15587                 } else {
15588                     generate_exception_end(ctx, EXCP_DBp);
15589                 }
15590             }
15591             break;
15592         default:
15593             goto pool32axf_invalid;
15594         }
15595         break;
15596     case 0x01:
15597         switch (minor & 3) {
15598         case MFHI_ACC:
15599             gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
15600             break;
15601         case MFLO_ACC:
15602             gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
15603             break;
15604         case MTHI_ACC:
15605             gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
15606             break;
15607         case MTLO_ACC:
15608             gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
15609             break;
15610         default:
15611             goto pool32axf_invalid;
15612         }
15613         break;
15614     case 0x35:
15615         check_insn_opc_removed(ctx, ISA_MIPS32R6);
15616         switch (minor) {
15617         case MFHI32:
15618             gen_HILO(ctx, OPC_MFHI, 0, rs);
15619             break;
15620         case MFLO32:
15621             gen_HILO(ctx, OPC_MFLO, 0, rs);
15622             break;
15623         case MTHI32:
15624             gen_HILO(ctx, OPC_MTHI, 0, rs);
15625             break;
15626         case MTLO32:
15627             gen_HILO(ctx, OPC_MTLO, 0, rs);
15628             break;
15629         default:
15630             goto pool32axf_invalid;
15631         }
15632         break;
15633     default:
15634     pool32axf_invalid:
15635         MIPS_INVAL("pool32axf");
15636         generate_exception_end(ctx, EXCP_RI);
15637         break;
15638     }
15639 }
15640
15641 /* Values for microMIPS fmt field.  Variable-width, depending on which
15642    formats the instruction supports.  */
15643
15644 enum {
15645     FMT_SD_S = 0,
15646     FMT_SD_D = 1,
15647
15648     FMT_SDPS_S = 0,
15649     FMT_SDPS_D = 1,
15650     FMT_SDPS_PS = 2,
15651
15652     FMT_SWL_S = 0,
15653     FMT_SWL_W = 1,
15654     FMT_SWL_L = 2,
15655
15656     FMT_DWL_D = 0,
15657     FMT_DWL_W = 1,
15658     FMT_DWL_L = 2
15659 };
15660
15661 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
15662 {
15663     int extension = (ctx->opcode >> 6) & 0x3ff;
15664     uint32_t mips32_op;
15665
15666 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
15667 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
15668 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
15669
15670     switch (extension) {
15671     case FLOAT_1BIT_FMT(CFC1, 0):
15672         mips32_op = OPC_CFC1;
15673         goto do_cp1;
15674     case FLOAT_1BIT_FMT(CTC1, 0):
15675         mips32_op = OPC_CTC1;
15676         goto do_cp1;
15677     case FLOAT_1BIT_FMT(MFC1, 0):
15678         mips32_op = OPC_MFC1;
15679         goto do_cp1;
15680     case FLOAT_1BIT_FMT(MTC1, 0):
15681         mips32_op = OPC_MTC1;
15682         goto do_cp1;
15683     case FLOAT_1BIT_FMT(MFHC1, 0):
15684         mips32_op = OPC_MFHC1;
15685         goto do_cp1;
15686     case FLOAT_1BIT_FMT(MTHC1, 0):
15687         mips32_op = OPC_MTHC1;
15688     do_cp1:
15689         gen_cp1(ctx, mips32_op, rt, rs);
15690         break;
15691
15692         /* Reciprocal square root */
15693     case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
15694         mips32_op = OPC_RSQRT_S;
15695         goto do_unaryfp;
15696     case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
15697         mips32_op = OPC_RSQRT_D;
15698         goto do_unaryfp;
15699
15700         /* Square root */
15701     case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
15702         mips32_op = OPC_SQRT_S;
15703         goto do_unaryfp;
15704     case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
15705         mips32_op = OPC_SQRT_D;
15706         goto do_unaryfp;
15707
15708         /* Reciprocal */
15709     case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
15710         mips32_op = OPC_RECIP_S;
15711         goto do_unaryfp;
15712     case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
15713         mips32_op = OPC_RECIP_D;
15714         goto do_unaryfp;
15715
15716         /* Floor */
15717     case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
15718         mips32_op = OPC_FLOOR_L_S;
15719         goto do_unaryfp;
15720     case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
15721         mips32_op = OPC_FLOOR_L_D;
15722         goto do_unaryfp;
15723     case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
15724         mips32_op = OPC_FLOOR_W_S;
15725         goto do_unaryfp;
15726     case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
15727         mips32_op = OPC_FLOOR_W_D;
15728         goto do_unaryfp;
15729
15730         /* Ceiling */
15731     case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
15732         mips32_op = OPC_CEIL_L_S;
15733         goto do_unaryfp;
15734     case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
15735         mips32_op = OPC_CEIL_L_D;
15736         goto do_unaryfp;
15737     case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
15738         mips32_op = OPC_CEIL_W_S;
15739         goto do_unaryfp;
15740     case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
15741         mips32_op = OPC_CEIL_W_D;
15742         goto do_unaryfp;
15743
15744         /* Truncation */
15745     case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
15746         mips32_op = OPC_TRUNC_L_S;
15747         goto do_unaryfp;
15748     case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
15749         mips32_op = OPC_TRUNC_L_D;
15750         goto do_unaryfp;
15751     case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
15752         mips32_op = OPC_TRUNC_W_S;
15753         goto do_unaryfp;
15754     case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
15755         mips32_op = OPC_TRUNC_W_D;
15756         goto do_unaryfp;
15757
15758         /* Round */
15759     case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
15760         mips32_op = OPC_ROUND_L_S;
15761         goto do_unaryfp;
15762     case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
15763         mips32_op = OPC_ROUND_L_D;
15764         goto do_unaryfp;
15765     case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
15766         mips32_op = OPC_ROUND_W_S;
15767         goto do_unaryfp;
15768     case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
15769         mips32_op = OPC_ROUND_W_D;
15770         goto do_unaryfp;
15771
15772         /* Integer to floating-point conversion */
15773     case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
15774         mips32_op = OPC_CVT_L_S;
15775         goto do_unaryfp;
15776     case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
15777         mips32_op = OPC_CVT_L_D;
15778         goto do_unaryfp;
15779     case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
15780         mips32_op = OPC_CVT_W_S;
15781         goto do_unaryfp;
15782     case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
15783         mips32_op = OPC_CVT_W_D;
15784         goto do_unaryfp;
15785
15786         /* Paired-foo conversions */
15787     case FLOAT_1BIT_FMT(CVT_S_PL, 0):
15788         mips32_op = OPC_CVT_S_PL;
15789         goto do_unaryfp;
15790     case FLOAT_1BIT_FMT(CVT_S_PU, 0):
15791         mips32_op = OPC_CVT_S_PU;
15792         goto do_unaryfp;
15793     case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
15794         mips32_op = OPC_CVT_PW_PS;
15795         goto do_unaryfp;
15796     case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
15797         mips32_op = OPC_CVT_PS_PW;
15798         goto do_unaryfp;
15799
15800         /* Floating-point moves */
15801     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
15802         mips32_op = OPC_MOV_S;
15803         goto do_unaryfp;
15804     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
15805         mips32_op = OPC_MOV_D;
15806         goto do_unaryfp;
15807     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
15808         mips32_op = OPC_MOV_PS;
15809         goto do_unaryfp;
15810
15811         /* Absolute value */
15812     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
15813         mips32_op = OPC_ABS_S;
15814         goto do_unaryfp;
15815     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
15816         mips32_op = OPC_ABS_D;
15817         goto do_unaryfp;
15818     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
15819         mips32_op = OPC_ABS_PS;
15820         goto do_unaryfp;
15821
15822         /* Negation */
15823     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
15824         mips32_op = OPC_NEG_S;
15825         goto do_unaryfp;
15826     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
15827         mips32_op = OPC_NEG_D;
15828         goto do_unaryfp;
15829     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
15830         mips32_op = OPC_NEG_PS;
15831         goto do_unaryfp;
15832
15833         /* Reciprocal square root step */
15834     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
15835         mips32_op = OPC_RSQRT1_S;
15836         goto do_unaryfp;
15837     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
15838         mips32_op = OPC_RSQRT1_D;
15839         goto do_unaryfp;
15840     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
15841         mips32_op = OPC_RSQRT1_PS;
15842         goto do_unaryfp;
15843
15844         /* Reciprocal step */
15845     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
15846         mips32_op = OPC_RECIP1_S;
15847         goto do_unaryfp;
15848     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
15849         mips32_op = OPC_RECIP1_S;
15850         goto do_unaryfp;
15851     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
15852         mips32_op = OPC_RECIP1_PS;
15853         goto do_unaryfp;
15854
15855         /* Conversions from double */
15856     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
15857         mips32_op = OPC_CVT_D_S;
15858         goto do_unaryfp;
15859     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
15860         mips32_op = OPC_CVT_D_W;
15861         goto do_unaryfp;
15862     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
15863         mips32_op = OPC_CVT_D_L;
15864         goto do_unaryfp;
15865
15866         /* Conversions from single */
15867     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
15868         mips32_op = OPC_CVT_S_D;
15869         goto do_unaryfp;
15870     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
15871         mips32_op = OPC_CVT_S_W;
15872         goto do_unaryfp;
15873     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
15874         mips32_op = OPC_CVT_S_L;
15875     do_unaryfp:
15876         gen_farith(ctx, mips32_op, -1, rs, rt, 0);
15877         break;
15878
15879         /* Conditional moves on floating-point codes */
15880     case COND_FLOAT_MOV(MOVT, 0):
15881     case COND_FLOAT_MOV(MOVT, 1):
15882     case COND_FLOAT_MOV(MOVT, 2):
15883     case COND_FLOAT_MOV(MOVT, 3):
15884     case COND_FLOAT_MOV(MOVT, 4):
15885     case COND_FLOAT_MOV(MOVT, 5):
15886     case COND_FLOAT_MOV(MOVT, 6):
15887     case COND_FLOAT_MOV(MOVT, 7):
15888         check_insn_opc_removed(ctx, ISA_MIPS32R6);
15889         gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
15890         break;
15891     case COND_FLOAT_MOV(MOVF, 0):
15892     case COND_FLOAT_MOV(MOVF, 1):
15893     case COND_FLOAT_MOV(MOVF, 2):
15894     case COND_FLOAT_MOV(MOVF, 3):
15895     case COND_FLOAT_MOV(MOVF, 4):
15896     case COND_FLOAT_MOV(MOVF, 5):
15897     case COND_FLOAT_MOV(MOVF, 6):
15898     case COND_FLOAT_MOV(MOVF, 7):
15899         check_insn_opc_removed(ctx, ISA_MIPS32R6);
15900         gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
15901         break;
15902     default:
15903         MIPS_INVAL("pool32fxf");
15904         generate_exception_end(ctx, EXCP_RI);
15905         break;
15906     }
15907 }
15908
15909 static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
15910 {
15911     int32_t offset;
15912     uint16_t insn;
15913     int rt, rs, rd, rr;
15914     int16_t imm;
15915     uint32_t op, minor, minor2, mips32_op;
15916     uint32_t cond, fmt, cc;
15917
15918     insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
15919     ctx->opcode = (ctx->opcode << 16) | insn;
15920
15921     rt = (ctx->opcode >> 21) & 0x1f;
15922     rs = (ctx->opcode >> 16) & 0x1f;
15923     rd = (ctx->opcode >> 11) & 0x1f;
15924     rr = (ctx->opcode >> 6) & 0x1f;
15925     imm = (int16_t) ctx->opcode;
15926
15927     op = (ctx->opcode >> 26) & 0x3f;
15928     switch (op) {
15929     case POOL32A:
15930         minor = ctx->opcode & 0x3f;
15931         switch (minor) {
15932         case 0x00:
15933             minor = (ctx->opcode >> 6) & 0xf;
15934             switch (minor) {
15935             case SLL32:
15936                 mips32_op = OPC_SLL;
15937                 goto do_shifti;
15938             case SRA:
15939                 mips32_op = OPC_SRA;
15940                 goto do_shifti;
15941             case SRL32:
15942                 mips32_op = OPC_SRL;
15943                 goto do_shifti;
15944             case ROTR:
15945                 mips32_op = OPC_ROTR;
15946             do_shifti:
15947                 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
15948                 break;
15949             case SELEQZ:
15950                 check_insn(ctx, ISA_MIPS32R6);
15951                 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
15952                 break;
15953             case SELNEZ:
15954                 check_insn(ctx, ISA_MIPS32R6);
15955                 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
15956                 break;
15957             case R6_RDHWR:
15958                 check_insn(ctx, ISA_MIPS32R6);
15959                 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
15960                 break;
15961             default:
15962                 goto pool32a_invalid;
15963             }
15964             break;
15965         case 0x10:
15966             minor = (ctx->opcode >> 6) & 0xf;
15967             switch (minor) {
15968                 /* Arithmetic */
15969             case ADD:
15970                 mips32_op = OPC_ADD;
15971                 goto do_arith;
15972             case ADDU32:
15973                 mips32_op = OPC_ADDU;
15974                 goto do_arith;
15975             case SUB:
15976                 mips32_op = OPC_SUB;
15977                 goto do_arith;
15978             case SUBU32:
15979                 mips32_op = OPC_SUBU;
15980                 goto do_arith;
15981             case MUL:
15982                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15983                 mips32_op = OPC_MUL;
15984             do_arith:
15985                 gen_arith(ctx, mips32_op, rd, rs, rt);
15986                 break;
15987                 /* Shifts */
15988             case SLLV:
15989                 mips32_op = OPC_SLLV;
15990                 goto do_shift;
15991             case SRLV:
15992                 mips32_op = OPC_SRLV;
15993                 goto do_shift;
15994             case SRAV:
15995                 mips32_op = OPC_SRAV;
15996                 goto do_shift;
15997             case ROTRV:
15998                 mips32_op = OPC_ROTRV;
15999             do_shift:
16000                 gen_shift(ctx, mips32_op, rd, rs, rt);
16001                 break;
16002                 /* Logical operations */
16003             case AND:
16004                 mips32_op = OPC_AND;
16005                 goto do_logic;
16006             case OR32:
16007                 mips32_op = OPC_OR;
16008                 goto do_logic;
16009             case NOR:
16010                 mips32_op = OPC_NOR;
16011                 goto do_logic;
16012             case XOR32:
16013                 mips32_op = OPC_XOR;
16014             do_logic:
16015                 gen_logic(ctx, mips32_op, rd, rs, rt);
16016                 break;
16017                 /* Set less than */
16018             case SLT:
16019                 mips32_op = OPC_SLT;
16020                 goto do_slt;
16021             case SLTU:
16022                 mips32_op = OPC_SLTU;
16023             do_slt:
16024                 gen_slt(ctx, mips32_op, rd, rs, rt);
16025                 break;
16026             default:
16027                 goto pool32a_invalid;
16028             }
16029             break;
16030         case 0x18:
16031             minor = (ctx->opcode >> 6) & 0xf;
16032             switch (minor) {
16033                 /* Conditional moves */
16034             case MOVN: /* MUL */
16035                 if (ctx->insn_flags & ISA_MIPS32R6) {
16036                     /* MUL */
16037                     gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
16038                 } else {
16039                     /* MOVN */
16040                     gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
16041                 }
16042                 break;
16043             case MOVZ: /* MUH */
16044                 if (ctx->insn_flags & ISA_MIPS32R6) {
16045                     /* MUH */
16046                     gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
16047                 } else {
16048                     /* MOVZ */
16049                     gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
16050                 }
16051                 break;
16052             case MULU:
16053                 check_insn(ctx, ISA_MIPS32R6);
16054                 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
16055                 break;
16056             case MUHU:
16057                 check_insn(ctx, ISA_MIPS32R6);
16058                 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
16059                 break;
16060             case LWXS: /* DIV */
16061                 if (ctx->insn_flags & ISA_MIPS32R6) {
16062                     /* DIV */
16063                     gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
16064                 } else {
16065                     /* LWXS */
16066                     gen_ldxs(ctx, rs, rt, rd);
16067                 }
16068                 break;
16069             case MOD:
16070                 check_insn(ctx, ISA_MIPS32R6);
16071                 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
16072                 break;
16073             case R6_DIVU:
16074                 check_insn(ctx, ISA_MIPS32R6);
16075                 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
16076                 break;
16077             case MODU:
16078                 check_insn(ctx, ISA_MIPS32R6);
16079                 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
16080                 break;
16081             default:
16082                 goto pool32a_invalid;
16083             }
16084             break;
16085         case INS:
16086             gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
16087             return;
16088         case LSA:
16089             check_insn(ctx, ISA_MIPS32R6);
16090             gen_lsa(ctx, OPC_LSA, rd, rs, rt,
16091                     extract32(ctx->opcode, 9, 2));
16092             break;
16093         case ALIGN:
16094             check_insn(ctx, ISA_MIPS32R6);
16095             gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2));
16096             break;
16097         case EXT:
16098             gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
16099             return;
16100         case POOL32AXF:
16101             gen_pool32axf(env, ctx, rt, rs);
16102             break;
16103         case BREAK32:
16104             generate_exception_end(ctx, EXCP_BREAK);
16105             break;
16106         case SIGRIE:
16107             check_insn(ctx, ISA_MIPS32R6);
16108             generate_exception_end(ctx, EXCP_RI);
16109             break;
16110         default:
16111         pool32a_invalid:
16112                 MIPS_INVAL("pool32a");
16113                 generate_exception_end(ctx, EXCP_RI);
16114                 break;
16115         }
16116         break;
16117     case POOL32B:
16118         minor = (ctx->opcode >> 12) & 0xf;
16119         switch (minor) {
16120         case CACHE:
16121             check_cp0_enabled(ctx);
16122             if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
16123                 gen_cache_operation(ctx, rt, rs, imm);
16124             }
16125             break;
16126         case LWC2:
16127         case SWC2:
16128             /* COP2: Not implemented. */
16129             generate_exception_err(ctx, EXCP_CpU, 2);
16130             break;
16131 #ifdef TARGET_MIPS64
16132         case LDP:
16133         case SDP:
16134             check_insn(ctx, ISA_MIPS3);
16135             check_mips_64(ctx);
16136 #endif
16137             /* fall through */
16138         case LWP:
16139         case SWP:
16140             gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
16141             break;
16142 #ifdef TARGET_MIPS64
16143         case LDM:
16144         case SDM:
16145             check_insn(ctx, ISA_MIPS3);
16146             check_mips_64(ctx);
16147 #endif
16148             /* fall through */
16149         case LWM32:
16150         case SWM32:
16151             gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
16152             break;
16153         default:
16154             MIPS_INVAL("pool32b");
16155             generate_exception_end(ctx, EXCP_RI);
16156             break;
16157         }
16158         break;
16159     case POOL32F:
16160         if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
16161             minor = ctx->opcode & 0x3f;
16162             check_cp1_enabled(ctx);
16163             switch (minor) {
16164             case ALNV_PS:
16165                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16166                 mips32_op = OPC_ALNV_PS;
16167                 goto do_madd;
16168             case MADD_S:
16169                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16170                 mips32_op = OPC_MADD_S;
16171                 goto do_madd;
16172             case MADD_D:
16173                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16174                 mips32_op = OPC_MADD_D;
16175                 goto do_madd;
16176             case MADD_PS:
16177                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16178                 mips32_op = OPC_MADD_PS;
16179                 goto do_madd;
16180             case MSUB_S:
16181                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16182                 mips32_op = OPC_MSUB_S;
16183                 goto do_madd;
16184             case MSUB_D:
16185                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16186                 mips32_op = OPC_MSUB_D;
16187                 goto do_madd;
16188             case MSUB_PS:
16189                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16190                 mips32_op = OPC_MSUB_PS;
16191                 goto do_madd;
16192             case NMADD_S:
16193                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16194                 mips32_op = OPC_NMADD_S;
16195                 goto do_madd;
16196             case NMADD_D:
16197                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16198                 mips32_op = OPC_NMADD_D;
16199                 goto do_madd;
16200             case NMADD_PS:
16201                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16202                 mips32_op = OPC_NMADD_PS;
16203                 goto do_madd;
16204             case NMSUB_S:
16205                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16206                 mips32_op = OPC_NMSUB_S;
16207                 goto do_madd;
16208             case NMSUB_D:
16209                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16210                 mips32_op = OPC_NMSUB_D;
16211                 goto do_madd;
16212             case NMSUB_PS:
16213                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16214                 mips32_op = OPC_NMSUB_PS;
16215             do_madd:
16216                 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
16217                 break;
16218             case CABS_COND_FMT:
16219                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16220                 cond = (ctx->opcode >> 6) & 0xf;
16221                 cc = (ctx->opcode >> 13) & 0x7;
16222                 fmt = (ctx->opcode >> 10) & 0x3;
16223                 switch (fmt) {
16224                 case 0x0:
16225                     gen_cmpabs_s(ctx, cond, rt, rs, cc);
16226                     break;
16227                 case 0x1:
16228                     gen_cmpabs_d(ctx, cond, rt, rs, cc);
16229                     break;
16230                 case 0x2:
16231                     gen_cmpabs_ps(ctx, cond, rt, rs, cc);
16232                     break;
16233                 default:
16234                     goto pool32f_invalid;
16235                 }
16236                 break;
16237             case C_COND_FMT:
16238                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16239                 cond = (ctx->opcode >> 6) & 0xf;
16240                 cc = (ctx->opcode >> 13) & 0x7;
16241                 fmt = (ctx->opcode >> 10) & 0x3;
16242                 switch (fmt) {
16243                 case 0x0:
16244                     gen_cmp_s(ctx, cond, rt, rs, cc);
16245                     break;
16246                 case 0x1:
16247                     gen_cmp_d(ctx, cond, rt, rs, cc);
16248                     break;
16249                 case 0x2:
16250                     gen_cmp_ps(ctx, cond, rt, rs, cc);
16251                     break;
16252                 default:
16253                     goto pool32f_invalid;
16254                 }
16255                 break;
16256             case CMP_CONDN_S:
16257                 check_insn(ctx, ISA_MIPS32R6);
16258                 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
16259                 break;
16260             case CMP_CONDN_D:
16261                 check_insn(ctx, ISA_MIPS32R6);
16262                 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
16263                 break;
16264             case POOL32FXF:
16265                 gen_pool32fxf(ctx, rt, rs);
16266                 break;
16267             case 0x00:
16268                 /* PLL foo */
16269                 switch ((ctx->opcode >> 6) & 0x7) {
16270                 case PLL_PS:
16271                     mips32_op = OPC_PLL_PS;
16272                     goto do_ps;
16273                 case PLU_PS:
16274                     mips32_op = OPC_PLU_PS;
16275                     goto do_ps;
16276                 case PUL_PS:
16277                     mips32_op = OPC_PUL_PS;
16278                     goto do_ps;
16279                 case PUU_PS:
16280                     mips32_op = OPC_PUU_PS;
16281                     goto do_ps;
16282                 case CVT_PS_S:
16283                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16284                     mips32_op = OPC_CVT_PS_S;
16285                 do_ps:
16286                     gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16287                     break;
16288                 default:
16289                     goto pool32f_invalid;
16290                 }
16291                 break;
16292             case MIN_FMT:
16293                 check_insn(ctx, ISA_MIPS32R6);
16294                 switch ((ctx->opcode >> 9) & 0x3) {
16295                 case FMT_SDPS_S:
16296                     gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
16297                     break;
16298                 case FMT_SDPS_D:
16299                     gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
16300                     break;
16301                 default:
16302                     goto pool32f_invalid;
16303                 }
16304                 break;
16305             case 0x08:
16306                 /* [LS][WDU]XC1 */
16307                 switch ((ctx->opcode >> 6) & 0x7) {
16308                 case LWXC1:
16309                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16310                     mips32_op = OPC_LWXC1;
16311                     goto do_ldst_cp1;
16312                 case SWXC1:
16313                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16314                     mips32_op = OPC_SWXC1;
16315                     goto do_ldst_cp1;
16316                 case LDXC1:
16317                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16318                     mips32_op = OPC_LDXC1;
16319                     goto do_ldst_cp1;
16320                 case SDXC1:
16321                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16322                     mips32_op = OPC_SDXC1;
16323                     goto do_ldst_cp1;
16324                 case LUXC1:
16325                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16326                     mips32_op = OPC_LUXC1;
16327                     goto do_ldst_cp1;
16328                 case SUXC1:
16329                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16330                     mips32_op = OPC_SUXC1;
16331                 do_ldst_cp1:
16332                     gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
16333                     break;
16334                 default:
16335                     goto pool32f_invalid;
16336                 }
16337                 break;
16338             case MAX_FMT:
16339                 check_insn(ctx, ISA_MIPS32R6);
16340                 switch ((ctx->opcode >> 9) & 0x3) {
16341                 case FMT_SDPS_S:
16342                     gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
16343                     break;
16344                 case FMT_SDPS_D:
16345                     gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
16346                     break;
16347                 default:
16348                     goto pool32f_invalid;
16349                 }
16350                 break;
16351             case 0x18:
16352                 /* 3D insns */
16353                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16354                 fmt = (ctx->opcode >> 9) & 0x3;
16355                 switch ((ctx->opcode >> 6) & 0x7) {
16356                 case RSQRT2_FMT:
16357                     switch (fmt) {
16358                     case FMT_SDPS_S:
16359                         mips32_op = OPC_RSQRT2_S;
16360                         goto do_3d;
16361                     case FMT_SDPS_D:
16362                         mips32_op = OPC_RSQRT2_D;
16363                         goto do_3d;
16364                     case FMT_SDPS_PS:
16365                         mips32_op = OPC_RSQRT2_PS;
16366                         goto do_3d;
16367                     default:
16368                         goto pool32f_invalid;
16369                     }
16370                     break;
16371                 case RECIP2_FMT:
16372                     switch (fmt) {
16373                     case FMT_SDPS_S:
16374                         mips32_op = OPC_RECIP2_S;
16375                         goto do_3d;
16376                     case FMT_SDPS_D:
16377                         mips32_op = OPC_RECIP2_D;
16378                         goto do_3d;
16379                     case FMT_SDPS_PS:
16380                         mips32_op = OPC_RECIP2_PS;
16381                         goto do_3d;
16382                     default:
16383                         goto pool32f_invalid;
16384                     }
16385                     break;
16386                 case ADDR_PS:
16387                     mips32_op = OPC_ADDR_PS;
16388                     goto do_3d;
16389                 case MULR_PS:
16390                     mips32_op = OPC_MULR_PS;
16391                 do_3d:
16392                     gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16393                     break;
16394                 default:
16395                     goto pool32f_invalid;
16396                 }
16397                 break;
16398             case 0x20:
16399                 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
16400                 cc = (ctx->opcode >> 13) & 0x7;
16401                 fmt = (ctx->opcode >> 9) & 0x3;
16402                 switch ((ctx->opcode >> 6) & 0x7) {
16403                 case MOVF_FMT: /* RINT_FMT */
16404                     if (ctx->insn_flags & ISA_MIPS32R6) {
16405                         /* RINT_FMT */
16406                         switch (fmt) {
16407                         case FMT_SDPS_S:
16408                             gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
16409                             break;
16410                         case FMT_SDPS_D:
16411                             gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
16412                             break;
16413                         default:
16414                             goto pool32f_invalid;
16415                         }
16416                     } else {
16417                         /* MOVF_FMT */
16418                         switch (fmt) {
16419                         case FMT_SDPS_S:
16420                             gen_movcf_s(ctx, rs, rt, cc, 0);
16421                             break;
16422                         case FMT_SDPS_D:
16423                             gen_movcf_d(ctx, rs, rt, cc, 0);
16424                             break;
16425                         case FMT_SDPS_PS:
16426                             check_ps(ctx);
16427                             gen_movcf_ps(ctx, rs, rt, cc, 0);
16428                             break;
16429                         default:
16430                             goto pool32f_invalid;
16431                         }
16432                     }
16433                     break;
16434                 case MOVT_FMT: /* CLASS_FMT */
16435                     if (ctx->insn_flags & ISA_MIPS32R6) {
16436                         /* CLASS_FMT */
16437                         switch (fmt) {
16438                         case FMT_SDPS_S:
16439                             gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
16440                             break;
16441                         case FMT_SDPS_D:
16442                             gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
16443                             break;
16444                         default:
16445                             goto pool32f_invalid;
16446                         }
16447                     } else {
16448                         /* MOVT_FMT */
16449                         switch (fmt) {
16450                         case FMT_SDPS_S:
16451                             gen_movcf_s(ctx, rs, rt, cc, 1);
16452                             break;
16453                         case FMT_SDPS_D:
16454                             gen_movcf_d(ctx, rs, rt, cc, 1);
16455                             break;
16456                         case FMT_SDPS_PS:
16457                             check_ps(ctx);
16458                             gen_movcf_ps(ctx, rs, rt, cc, 1);
16459                             break;
16460                         default:
16461                             goto pool32f_invalid;
16462                         }
16463                     }
16464                     break;
16465                 case PREFX:
16466                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16467                     break;
16468                 default:
16469                     goto pool32f_invalid;
16470                 }
16471                 break;
16472 #define FINSN_3ARG_SDPS(prfx)                           \
16473                 switch ((ctx->opcode >> 8) & 0x3) {     \
16474                 case FMT_SDPS_S:                        \
16475                     mips32_op = OPC_##prfx##_S;         \
16476                     goto do_fpop;                       \
16477                 case FMT_SDPS_D:                        \
16478                     mips32_op = OPC_##prfx##_D;         \
16479                     goto do_fpop;                       \
16480                 case FMT_SDPS_PS:                       \
16481                     check_ps(ctx);                      \
16482                     mips32_op = OPC_##prfx##_PS;        \
16483                     goto do_fpop;                       \
16484                 default:                                \
16485                     goto pool32f_invalid;               \
16486                 }
16487             case MINA_FMT:
16488                 check_insn(ctx, ISA_MIPS32R6);
16489                 switch ((ctx->opcode >> 9) & 0x3) {
16490                 case FMT_SDPS_S:
16491                     gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
16492                     break;
16493                 case FMT_SDPS_D:
16494                     gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
16495                     break;
16496                 default:
16497                     goto pool32f_invalid;
16498                 }
16499                 break;
16500             case MAXA_FMT:
16501                 check_insn(ctx, ISA_MIPS32R6);
16502                 switch ((ctx->opcode >> 9) & 0x3) {
16503                 case FMT_SDPS_S:
16504                     gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
16505                     break;
16506                 case FMT_SDPS_D:
16507                     gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
16508                     break;
16509                 default:
16510                     goto pool32f_invalid;
16511                 }
16512                 break;
16513             case 0x30:
16514                 /* regular FP ops */
16515                 switch ((ctx->opcode >> 6) & 0x3) {
16516                 case ADD_FMT:
16517                     FINSN_3ARG_SDPS(ADD);
16518                     break;
16519                 case SUB_FMT:
16520                     FINSN_3ARG_SDPS(SUB);
16521                     break;
16522                 case MUL_FMT:
16523                     FINSN_3ARG_SDPS(MUL);
16524                     break;
16525                 case DIV_FMT:
16526                     fmt = (ctx->opcode >> 8) & 0x3;
16527                     if (fmt == 1) {
16528                         mips32_op = OPC_DIV_D;
16529                     } else if (fmt == 0) {
16530                         mips32_op = OPC_DIV_S;
16531                     } else {
16532                         goto pool32f_invalid;
16533                     }
16534                     goto do_fpop;
16535                 default:
16536                     goto pool32f_invalid;
16537                 }
16538                 break;
16539             case 0x38:
16540                 /* cmovs */
16541                 switch ((ctx->opcode >> 6) & 0x7) {
16542                 case MOVN_FMT: /* SELEQZ_FMT */
16543                     if (ctx->insn_flags & ISA_MIPS32R6) {
16544                         /* SELEQZ_FMT */
16545                         switch ((ctx->opcode >> 9) & 0x3) {
16546                         case FMT_SDPS_S:
16547                             gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
16548                             break;
16549                         case FMT_SDPS_D:
16550                             gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
16551                             break;
16552                         default:
16553                             goto pool32f_invalid;
16554                         }
16555                     } else {
16556                         /* MOVN_FMT */
16557                         FINSN_3ARG_SDPS(MOVN);
16558                     }
16559                     break;
16560                 case MOVN_FMT_04:
16561                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16562                     FINSN_3ARG_SDPS(MOVN);
16563                     break;
16564                 case MOVZ_FMT: /* SELNEZ_FMT */
16565                     if (ctx->insn_flags & ISA_MIPS32R6) {
16566                         /* SELNEZ_FMT */
16567                         switch ((ctx->opcode >> 9) & 0x3) {
16568                         case FMT_SDPS_S:
16569                             gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
16570                             break;
16571                         case FMT_SDPS_D:
16572                             gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
16573                             break;
16574                         default:
16575                             goto pool32f_invalid;
16576                         }
16577                     } else {
16578                         /* MOVZ_FMT */
16579                         FINSN_3ARG_SDPS(MOVZ);
16580                     }
16581                     break;
16582                 case MOVZ_FMT_05:
16583                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16584                     FINSN_3ARG_SDPS(MOVZ);
16585                     break;
16586                 case SEL_FMT:
16587                     check_insn(ctx, ISA_MIPS32R6);
16588                     switch ((ctx->opcode >> 9) & 0x3) {
16589                     case FMT_SDPS_S:
16590                         gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
16591                         break;
16592                     case FMT_SDPS_D:
16593                         gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
16594                         break;
16595                     default:
16596                         goto pool32f_invalid;
16597                     }
16598                     break;
16599                 case MADDF_FMT:
16600                     check_insn(ctx, ISA_MIPS32R6);
16601                     switch ((ctx->opcode >> 9) & 0x3) {
16602                     case FMT_SDPS_S:
16603                         mips32_op = OPC_MADDF_S;
16604                         goto do_fpop;
16605                     case FMT_SDPS_D:
16606                         mips32_op = OPC_MADDF_D;
16607                         goto do_fpop;
16608                     default:
16609                         goto pool32f_invalid;
16610                     }
16611                     break;
16612                 case MSUBF_FMT:
16613                     check_insn(ctx, ISA_MIPS32R6);
16614                     switch ((ctx->opcode >> 9) & 0x3) {
16615                     case FMT_SDPS_S:
16616                         mips32_op = OPC_MSUBF_S;
16617                         goto do_fpop;
16618                     case FMT_SDPS_D:
16619                         mips32_op = OPC_MSUBF_D;
16620                         goto do_fpop;
16621                     default:
16622                         goto pool32f_invalid;
16623                     }
16624                     break;
16625                 default:
16626                     goto pool32f_invalid;
16627                 }
16628                 break;
16629             do_fpop:
16630                 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16631                 break;
16632             default:
16633             pool32f_invalid:
16634                 MIPS_INVAL("pool32f");
16635                 generate_exception_end(ctx, EXCP_RI);
16636                 break;
16637             }
16638         } else {
16639             generate_exception_err(ctx, EXCP_CpU, 1);
16640         }
16641         break;
16642     case POOL32I:
16643         minor = (ctx->opcode >> 21) & 0x1f;
16644         switch (minor) {
16645         case BLTZ:
16646             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16647             gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
16648             break;
16649         case BLTZAL:
16650             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16651             gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
16652             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16653             break;
16654         case BLTZALS:
16655             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16656             gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
16657             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16658             break;
16659         case BGEZ:
16660             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16661             gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
16662             break;
16663         case BGEZAL:
16664             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16665             gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
16666             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16667             break;
16668         case BGEZALS:
16669             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16670             gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
16671             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16672             break;
16673         case BLEZ:
16674             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16675             gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
16676             break;
16677         case BGTZ:
16678             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16679             gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
16680             break;
16681
16682             /* Traps */
16683         case TLTI: /* BC1EQZC */
16684             if (ctx->insn_flags & ISA_MIPS32R6) {
16685                 /* BC1EQZC */
16686                 check_cp1_enabled(ctx);
16687                 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
16688             } else {
16689                 /* TLTI */
16690                 mips32_op = OPC_TLTI;
16691                 goto do_trapi;
16692             }
16693             break;
16694         case TGEI: /* BC1NEZC */
16695             if (ctx->insn_flags & ISA_MIPS32R6) {
16696                 /* BC1NEZC */
16697                 check_cp1_enabled(ctx);
16698                 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
16699             } else {
16700                 /* TGEI */
16701                 mips32_op = OPC_TGEI;
16702                 goto do_trapi;
16703             }
16704             break;
16705         case TLTIU:
16706             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16707             mips32_op = OPC_TLTIU;
16708             goto do_trapi;
16709         case TGEIU:
16710             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16711             mips32_op = OPC_TGEIU;
16712             goto do_trapi;
16713         case TNEI: /* SYNCI */
16714             if (ctx->insn_flags & ISA_MIPS32R6) {
16715                 /* SYNCI */
16716                 /* Break the TB to be able to sync copied instructions
16717                    immediately */
16718                 ctx->base.is_jmp = DISAS_STOP;
16719             } else {
16720                 /* TNEI */
16721                 mips32_op = OPC_TNEI;
16722                 goto do_trapi;
16723             }
16724             break;
16725         case TEQI:
16726             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16727             mips32_op = OPC_TEQI;
16728         do_trapi:
16729             gen_trap(ctx, mips32_op, rs, -1, imm);
16730             break;
16731
16732         case BNEZC:
16733         case BEQZC:
16734             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16735             gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
16736                                4, rs, 0, imm << 1, 0);
16737             /* Compact branches don't have a delay slot, so just let
16738                the normal delay slot handling take us to the branch
16739                target. */
16740             break;
16741         case LUI:
16742             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16743             gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
16744             break;
16745         case SYNCI:
16746             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16747             /* Break the TB to be able to sync copied instructions
16748                immediately */
16749             ctx->base.is_jmp = DISAS_STOP;
16750             break;
16751         case BC2F:
16752         case BC2T:
16753             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16754             /* COP2: Not implemented. */
16755             generate_exception_err(ctx, EXCP_CpU, 2);
16756             break;
16757         case BC1F:
16758             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16759             mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
16760             goto do_cp1branch;
16761         case BC1T:
16762             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16763             mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
16764             goto do_cp1branch;
16765         case BC1ANY4F:
16766             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16767             mips32_op = OPC_BC1FANY4;
16768             goto do_cp1mips3d;
16769         case BC1ANY4T:
16770             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16771             mips32_op = OPC_BC1TANY4;
16772         do_cp1mips3d:
16773             check_cop1x(ctx);
16774             check_insn(ctx, ASE_MIPS3D);
16775             /* Fall through */
16776         do_cp1branch:
16777             if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16778                 check_cp1_enabled(ctx);
16779                 gen_compute_branch1(ctx, mips32_op,
16780                                     (ctx->opcode >> 18) & 0x7, imm << 1);
16781             } else {
16782                 generate_exception_err(ctx, EXCP_CpU, 1);
16783             }
16784             break;
16785         case BPOSGE64:
16786         case BPOSGE32:
16787             /* MIPS DSP: not implemented */
16788             /* Fall through */
16789         default:
16790             MIPS_INVAL("pool32i");
16791             generate_exception_end(ctx, EXCP_RI);
16792             break;
16793         }
16794         break;
16795     case POOL32C:
16796         minor = (ctx->opcode >> 12) & 0xf;
16797         offset = sextract32(ctx->opcode, 0,
16798                             (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
16799         switch (minor) {
16800         case LWL:
16801             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16802             mips32_op = OPC_LWL;
16803             goto do_ld_lr;
16804         case SWL:
16805             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16806             mips32_op = OPC_SWL;
16807             goto do_st_lr;
16808         case LWR:
16809             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16810             mips32_op = OPC_LWR;
16811             goto do_ld_lr;
16812         case SWR:
16813             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16814             mips32_op = OPC_SWR;
16815             goto do_st_lr;
16816 #if defined(TARGET_MIPS64)
16817         case LDL:
16818             check_insn(ctx, ISA_MIPS3);
16819             check_mips_64(ctx);
16820             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16821             mips32_op = OPC_LDL;
16822             goto do_ld_lr;
16823         case SDL:
16824             check_insn(ctx, ISA_MIPS3);
16825             check_mips_64(ctx);
16826             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16827             mips32_op = OPC_SDL;
16828             goto do_st_lr;
16829         case LDR:
16830             check_insn(ctx, ISA_MIPS3);
16831             check_mips_64(ctx);
16832             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16833             mips32_op = OPC_LDR;
16834             goto do_ld_lr;
16835         case SDR:
16836             check_insn(ctx, ISA_MIPS3);
16837             check_mips_64(ctx);
16838             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16839             mips32_op = OPC_SDR;
16840             goto do_st_lr;
16841         case LWU:
16842             check_insn(ctx, ISA_MIPS3);
16843             check_mips_64(ctx);
16844             mips32_op = OPC_LWU;
16845             goto do_ld_lr;
16846         case LLD:
16847             check_insn(ctx, ISA_MIPS3);
16848             check_mips_64(ctx);
16849             mips32_op = OPC_LLD;
16850             goto do_ld_lr;
16851 #endif
16852         case LL:
16853             mips32_op = OPC_LL;
16854             goto do_ld_lr;
16855         do_ld_lr:
16856             gen_ld(ctx, mips32_op, rt, rs, offset);
16857             break;
16858         do_st_lr:
16859             gen_st(ctx, mips32_op, rt, rs, offset);
16860             break;
16861         case SC:
16862             gen_st_cond(ctx, OPC_SC, rt, rs, offset);
16863             break;
16864 #if defined(TARGET_MIPS64)
16865         case SCD:
16866             check_insn(ctx, ISA_MIPS3);
16867             check_mips_64(ctx);
16868             gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
16869             break;
16870 #endif
16871         case LD_EVA:
16872             if (!ctx->eva) {
16873                 MIPS_INVAL("pool32c ld-eva");
16874                 generate_exception_end(ctx, EXCP_RI);
16875                 break;
16876             }
16877             check_cp0_enabled(ctx);
16878
16879             minor2 = (ctx->opcode >> 9) & 0x7;
16880             offset = sextract32(ctx->opcode, 0, 9);
16881             switch (minor2) {
16882             case LBUE:
16883                 mips32_op = OPC_LBUE;
16884                 goto do_ld_lr;
16885             case LHUE:
16886                 mips32_op = OPC_LHUE;
16887                 goto do_ld_lr;
16888             case LWLE:
16889                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16890                 mips32_op = OPC_LWLE;
16891                 goto do_ld_lr;
16892             case LWRE:
16893                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16894                 mips32_op = OPC_LWRE;
16895                 goto do_ld_lr;
16896             case LBE:
16897                 mips32_op = OPC_LBE;
16898                 goto do_ld_lr;
16899             case LHE:
16900                 mips32_op = OPC_LHE;
16901                 goto do_ld_lr;
16902             case LLE:
16903                 mips32_op = OPC_LLE;
16904                 goto do_ld_lr;
16905             case LWE:
16906                 mips32_op = OPC_LWE;
16907                 goto do_ld_lr;
16908             };
16909             break;
16910         case ST_EVA:
16911             if (!ctx->eva) {
16912                 MIPS_INVAL("pool32c st-eva");
16913                 generate_exception_end(ctx, EXCP_RI);
16914                 break;
16915             }
16916             check_cp0_enabled(ctx);
16917
16918             minor2 = (ctx->opcode >> 9) & 0x7;
16919             offset = sextract32(ctx->opcode, 0, 9);
16920             switch (minor2) {
16921             case SWLE:
16922                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16923                 mips32_op = OPC_SWLE;
16924                 goto do_st_lr;
16925             case SWRE:
16926                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16927                 mips32_op = OPC_SWRE;
16928                 goto do_st_lr;
16929             case PREFE:
16930                 /* Treat as no-op */
16931                 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16932                     /* hint codes 24-31 are reserved and signal RI */
16933                     generate_exception(ctx, EXCP_RI);
16934                 }
16935                 break;
16936             case CACHEE:
16937                 /* Treat as no-op */
16938                 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
16939                     gen_cache_operation(ctx, rt, rs, offset);
16940                 }
16941                 break;
16942             case SBE:
16943                 mips32_op = OPC_SBE;
16944                 goto do_st_lr;
16945             case SHE:
16946                 mips32_op = OPC_SHE;
16947                 goto do_st_lr;
16948             case SCE:
16949                 gen_st_cond(ctx, OPC_SCE, rt, rs, offset);
16950                 break;
16951             case SWE:
16952                 mips32_op = OPC_SWE;
16953                 goto do_st_lr;
16954             };
16955             break;
16956         case PREF:
16957             /* Treat as no-op */
16958             if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16959                 /* hint codes 24-31 are reserved and signal RI */
16960                 generate_exception(ctx, EXCP_RI);
16961             }
16962             break;
16963         default:
16964             MIPS_INVAL("pool32c");
16965             generate_exception_end(ctx, EXCP_RI);
16966             break;
16967         }
16968         break;
16969     case ADDI32: /* AUI, LUI */
16970         if (ctx->insn_flags & ISA_MIPS32R6) {
16971             /* AUI, LUI */
16972             gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
16973         } else {
16974             /* ADDI32 */
16975             mips32_op = OPC_ADDI;
16976             goto do_addi;
16977         }
16978         break;
16979     case ADDIU32:
16980         mips32_op = OPC_ADDIU;
16981     do_addi:
16982         gen_arith_imm(ctx, mips32_op, rt, rs, imm);
16983         break;
16984
16985         /* Logical operations */
16986     case ORI32:
16987         mips32_op = OPC_ORI;
16988         goto do_logici;
16989     case XORI32:
16990         mips32_op = OPC_XORI;
16991         goto do_logici;
16992     case ANDI32:
16993         mips32_op = OPC_ANDI;
16994     do_logici:
16995         gen_logic_imm(ctx, mips32_op, rt, rs, imm);
16996         break;
16997
16998         /* Set less than immediate */
16999     case SLTI32:
17000         mips32_op = OPC_SLTI;
17001         goto do_slti;
17002     case SLTIU32:
17003         mips32_op = OPC_SLTIU;
17004     do_slti:
17005         gen_slt_imm(ctx, mips32_op, rt, rs, imm);
17006         break;
17007     case JALX32:
17008         check_insn_opc_removed(ctx, ISA_MIPS32R6);
17009         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
17010         gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
17011         ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17012         break;
17013     case JALS32: /* BOVC, BEQC, BEQZALC */
17014         if (ctx->insn_flags & ISA_MIPS32R6) {
17015             if (rs >= rt) {
17016                 /* BOVC */
17017                 mips32_op = OPC_BOVC;
17018             } else if (rs < rt && rs == 0) {
17019                 /* BEQZALC */
17020                 mips32_op = OPC_BEQZALC;
17021             } else {
17022                 /* BEQC */
17023                 mips32_op = OPC_BEQC;
17024             }
17025             gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17026         } else {
17027             /* JALS32 */
17028             offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
17029             gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
17030             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17031         }
17032         break;
17033     case BEQ32: /* BC */
17034         if (ctx->insn_flags & ISA_MIPS32R6) {
17035             /* BC */
17036             gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
17037                                        sextract32(ctx->opcode << 1, 0, 27));
17038         } else {
17039             /* BEQ32 */
17040             gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
17041         }
17042         break;
17043     case BNE32: /* BALC */
17044         if (ctx->insn_flags & ISA_MIPS32R6) {
17045             /* BALC */
17046             gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
17047                                        sextract32(ctx->opcode << 1, 0, 27));
17048         } else {
17049             /* BNE32 */
17050             gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
17051         }
17052         break;
17053     case J32: /* BGTZC, BLTZC, BLTC */
17054         if (ctx->insn_flags & ISA_MIPS32R6) {
17055             if (rs == 0 && rt != 0) {
17056                 /* BGTZC */
17057                 mips32_op = OPC_BGTZC;
17058             } else if (rs != 0 && rt != 0 && rs == rt) {
17059                 /* BLTZC */
17060                 mips32_op = OPC_BLTZC;
17061             } else {
17062                 /* BLTC */
17063                 mips32_op = OPC_BLTC;
17064             }
17065             gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17066         } else {
17067             /* J32 */
17068             gen_compute_branch(ctx, OPC_J, 4, rt, rs,
17069                                (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
17070         }
17071         break;
17072     case JAL32: /* BLEZC, BGEZC, BGEC */
17073         if (ctx->insn_flags & ISA_MIPS32R6) {
17074             if (rs == 0 && rt != 0) {
17075                 /* BLEZC */
17076                 mips32_op = OPC_BLEZC;
17077             } else if (rs != 0 && rt != 0 && rs == rt) {
17078                 /* BGEZC */
17079                 mips32_op = OPC_BGEZC;
17080             } else {
17081                 /* BGEC */
17082                 mips32_op = OPC_BGEC;
17083             }
17084             gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17085         } else {
17086             /* JAL32 */
17087             gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
17088                                (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
17089             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17090         }
17091         break;
17092         /* Floating point (COP1) */
17093     case LWC132:
17094         mips32_op = OPC_LWC1;
17095         goto do_cop1;
17096     case LDC132:
17097         mips32_op = OPC_LDC1;
17098         goto do_cop1;
17099     case SWC132:
17100         mips32_op = OPC_SWC1;
17101         goto do_cop1;
17102     case SDC132:
17103         mips32_op = OPC_SDC1;
17104     do_cop1:
17105         gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
17106         break;
17107     case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17108         if (ctx->insn_flags & ISA_MIPS32R6) {
17109             /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17110             switch ((ctx->opcode >> 16) & 0x1f) {
17111             case ADDIUPC_00:
17112             case ADDIUPC_01:
17113             case ADDIUPC_02:
17114             case ADDIUPC_03:
17115             case ADDIUPC_04:
17116             case ADDIUPC_05:
17117             case ADDIUPC_06:
17118             case ADDIUPC_07:
17119                 gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
17120                 break;
17121             case AUIPC:
17122                 gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
17123                 break;
17124             case ALUIPC:
17125                 gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
17126                 break;
17127             case LWPC_08:
17128             case LWPC_09:
17129             case LWPC_0A:
17130             case LWPC_0B:
17131             case LWPC_0C:
17132             case LWPC_0D:
17133             case LWPC_0E:
17134             case LWPC_0F:
17135                 gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
17136                 break;
17137             default:
17138                 generate_exception(ctx, EXCP_RI);
17139                 break;
17140             }
17141         } else {
17142             /* ADDIUPC */
17143             int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
17144             offset = SIMM(ctx->opcode, 0, 23) << 2;
17145
17146             gen_addiupc(ctx, reg, offset, 0, 0);
17147         }
17148         break;
17149     case BNVC: /* BNEC, BNEZALC */
17150         check_insn(ctx, ISA_MIPS32R6);
17151         if (rs >= rt) {
17152             /* BNVC */
17153             mips32_op = OPC_BNVC;
17154         } else if (rs < rt && rs == 0) {
17155             /* BNEZALC */
17156             mips32_op = OPC_BNEZALC;
17157         } else {
17158             /* BNEC */
17159             mips32_op = OPC_BNEC;
17160         }
17161         gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17162         break;
17163     case R6_BNEZC: /* JIALC */
17164         check_insn(ctx, ISA_MIPS32R6);
17165         if (rt != 0) {
17166             /* BNEZC */
17167             gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
17168                                        sextract32(ctx->opcode << 1, 0, 22));
17169         } else {
17170             /* JIALC */
17171             gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
17172         }
17173         break;
17174     case R6_BEQZC: /* JIC */
17175         check_insn(ctx, ISA_MIPS32R6);
17176         if (rt != 0) {
17177             /* BEQZC */
17178             gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
17179                                        sextract32(ctx->opcode << 1, 0, 22));
17180         } else {
17181             /* JIC */
17182             gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
17183         }
17184         break;
17185     case BLEZALC: /* BGEZALC, BGEUC */
17186         check_insn(ctx, ISA_MIPS32R6);
17187         if (rs == 0 && rt != 0) {
17188             /* BLEZALC */
17189             mips32_op = OPC_BLEZALC;
17190         } else if (rs != 0 && rt != 0 && rs == rt) {
17191             /* BGEZALC */
17192             mips32_op = OPC_BGEZALC;
17193         } else {
17194             /* BGEUC */
17195             mips32_op = OPC_BGEUC;
17196         }
17197         gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17198         break;
17199     case BGTZALC: /* BLTZALC, BLTUC */
17200         check_insn(ctx, ISA_MIPS32R6);
17201         if (rs == 0 && rt != 0) {
17202             /* BGTZALC */
17203             mips32_op = OPC_BGTZALC;
17204         } else if (rs != 0 && rt != 0 && rs == rt) {
17205             /* BLTZALC */
17206             mips32_op = OPC_BLTZALC;
17207         } else {
17208             /* BLTUC */
17209             mips32_op = OPC_BLTUC;
17210         }
17211         gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17212         break;
17213         /* Loads and stores */
17214     case LB32:
17215         mips32_op = OPC_LB;
17216         goto do_ld;
17217     case LBU32:
17218         mips32_op = OPC_LBU;
17219         goto do_ld;
17220     case LH32:
17221         mips32_op = OPC_LH;
17222         goto do_ld;
17223     case LHU32:
17224         mips32_op = OPC_LHU;
17225         goto do_ld;
17226     case LW32:
17227         mips32_op = OPC_LW;
17228         goto do_ld;
17229 #ifdef TARGET_MIPS64
17230     case LD32:
17231         check_insn(ctx, ISA_MIPS3);
17232         check_mips_64(ctx);
17233         mips32_op = OPC_LD;
17234         goto do_ld;
17235     case SD32:
17236         check_insn(ctx, ISA_MIPS3);
17237         check_mips_64(ctx);
17238         mips32_op = OPC_SD;
17239         goto do_st;
17240 #endif
17241     case SB32:
17242         mips32_op = OPC_SB;
17243         goto do_st;
17244     case SH32:
17245         mips32_op = OPC_SH;
17246         goto do_st;
17247     case SW32:
17248         mips32_op = OPC_SW;
17249         goto do_st;
17250     do_ld:
17251         gen_ld(ctx, mips32_op, rt, rs, imm);
17252         break;
17253     do_st:
17254         gen_st(ctx, mips32_op, rt, rs, imm);
17255         break;
17256     default:
17257         generate_exception_end(ctx, EXCP_RI);
17258         break;
17259     }
17260 }
17261
17262 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
17263 {
17264     uint32_t op;
17265
17266     /* make sure instructions are on a halfword boundary */
17267     if (ctx->base.pc_next & 0x1) {
17268         env->CP0_BadVAddr = ctx->base.pc_next;
17269         generate_exception_end(ctx, EXCP_AdEL);
17270         return 2;
17271     }
17272
17273     op = (ctx->opcode >> 10) & 0x3f;
17274     /* Enforce properly-sized instructions in a delay slot */
17275     if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
17276         switch (op & 0x7) { /* MSB-3..MSB-5 */
17277         case 0:
17278         /* POOL32A, POOL32B, POOL32I, POOL32C */
17279         case 4:
17280         /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
17281         case 5:
17282         /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
17283         case 6:
17284         /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
17285         case 7:
17286         /* LB32, LH32, LWC132, LDC132, LW32 */
17287             if (ctx->hflags & MIPS_HFLAG_BDS16) {
17288                 generate_exception_end(ctx, EXCP_RI);
17289                 return 2;
17290             }
17291             break;
17292         case 1:
17293         /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
17294         case 2:
17295         /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
17296         case 3:
17297         /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
17298             if (ctx->hflags & MIPS_HFLAG_BDS32) {
17299                 generate_exception_end(ctx, EXCP_RI);
17300                 return 2;
17301             }
17302             break;
17303         }
17304     }
17305
17306     switch (op) {
17307     case POOL16A:
17308         {
17309             int rd = mmreg(uMIPS_RD(ctx->opcode));
17310             int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
17311             int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
17312             uint32_t opc = 0;
17313
17314             switch (ctx->opcode & 0x1) {
17315             case ADDU16:
17316                 opc = OPC_ADDU;
17317                 break;
17318             case SUBU16:
17319                 opc = OPC_SUBU;
17320                 break;
17321             }
17322             if (ctx->insn_flags & ISA_MIPS32R6) {
17323                 /* In the Release 6 the register number location in
17324                  * the instruction encoding has changed.
17325                  */
17326                 gen_arith(ctx, opc, rs1, rd, rs2);
17327             } else {
17328                 gen_arith(ctx, opc, rd, rs1, rs2);
17329             }
17330         }
17331         break;
17332     case POOL16B:
17333         {
17334             int rd = mmreg(uMIPS_RD(ctx->opcode));
17335             int rs = mmreg(uMIPS_RS(ctx->opcode));
17336             int amount = (ctx->opcode >> 1) & 0x7;
17337             uint32_t opc = 0;
17338             amount = amount == 0 ? 8 : amount;
17339
17340             switch (ctx->opcode & 0x1) {
17341             case SLL16:
17342                 opc = OPC_SLL;
17343                 break;
17344             case SRL16:
17345                 opc = OPC_SRL;
17346                 break;
17347             }
17348
17349             gen_shift_imm(ctx, opc, rd, rs, amount);
17350         }
17351         break;
17352     case POOL16C:
17353         if (ctx->insn_flags & ISA_MIPS32R6) {
17354             gen_pool16c_r6_insn(ctx);
17355         } else {
17356             gen_pool16c_insn(ctx);
17357         }
17358         break;
17359     case LWGP16:
17360         {
17361             int rd = mmreg(uMIPS_RD(ctx->opcode));
17362             int rb = 28;            /* GP */
17363             int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
17364
17365             gen_ld(ctx, OPC_LW, rd, rb, offset);
17366         }
17367         break;
17368     case POOL16F:
17369         check_insn_opc_removed(ctx, ISA_MIPS32R6);
17370         if (ctx->opcode & 1) {
17371             generate_exception_end(ctx, EXCP_RI);
17372         } else {
17373             /* MOVEP */
17374             int enc_dest = uMIPS_RD(ctx->opcode);
17375             int enc_rt = uMIPS_RS2(ctx->opcode);
17376             int enc_rs = uMIPS_RS1(ctx->opcode);
17377             gen_movep(ctx, enc_dest, enc_rt, enc_rs);
17378         }
17379         break;
17380     case LBU16:
17381         {
17382             int rd = mmreg(uMIPS_RD(ctx->opcode));
17383             int rb = mmreg(uMIPS_RS(ctx->opcode));
17384             int16_t offset = ZIMM(ctx->opcode, 0, 4);
17385             offset = (offset == 0xf ? -1 : offset);
17386
17387             gen_ld(ctx, OPC_LBU, rd, rb, offset);
17388         }
17389         break;
17390     case LHU16:
17391         {
17392             int rd = mmreg(uMIPS_RD(ctx->opcode));
17393             int rb = mmreg(uMIPS_RS(ctx->opcode));
17394             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17395
17396             gen_ld(ctx, OPC_LHU, rd, rb, offset);
17397         }
17398         break;
17399     case LWSP16:
17400         {
17401             int rd = (ctx->opcode >> 5) & 0x1f;
17402             int rb = 29;            /* SP */
17403             int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17404
17405             gen_ld(ctx, OPC_LW, rd, rb, offset);
17406         }
17407         break;
17408     case LW16:
17409         {
17410             int rd = mmreg(uMIPS_RD(ctx->opcode));
17411             int rb = mmreg(uMIPS_RS(ctx->opcode));
17412             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17413
17414             gen_ld(ctx, OPC_LW, rd, rb, offset);
17415         }
17416         break;
17417     case SB16:
17418         {
17419             int rd = mmreg2(uMIPS_RD(ctx->opcode));
17420             int rb = mmreg(uMIPS_RS(ctx->opcode));
17421             int16_t offset = ZIMM(ctx->opcode, 0, 4);
17422
17423             gen_st(ctx, OPC_SB, rd, rb, offset);
17424         }
17425         break;
17426     case SH16:
17427         {
17428             int rd = mmreg2(uMIPS_RD(ctx->opcode));
17429             int rb = mmreg(uMIPS_RS(ctx->opcode));
17430             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17431
17432             gen_st(ctx, OPC_SH, rd, rb, offset);
17433         }
17434         break;
17435     case SWSP16:
17436         {
17437             int rd = (ctx->opcode >> 5) & 0x1f;
17438             int rb = 29;            /* SP */
17439             int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17440
17441             gen_st(ctx, OPC_SW, rd, rb, offset);
17442         }
17443         break;
17444     case SW16:
17445         {
17446             int rd = mmreg2(uMIPS_RD(ctx->opcode));
17447             int rb = mmreg(uMIPS_RS(ctx->opcode));
17448             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17449
17450             gen_st(ctx, OPC_SW, rd, rb, offset);
17451         }
17452         break;
17453     case MOVE16:
17454         {
17455             int rd = uMIPS_RD5(ctx->opcode);
17456             int rs = uMIPS_RS5(ctx->opcode);
17457
17458             gen_arith(ctx, OPC_ADDU, rd, rs, 0);
17459         }
17460         break;
17461     case ANDI16:
17462         gen_andi16(ctx);
17463         break;
17464     case POOL16D:
17465         switch (ctx->opcode & 0x1) {
17466         case ADDIUS5:
17467             gen_addius5(ctx);
17468             break;
17469         case ADDIUSP:
17470             gen_addiusp(ctx);
17471             break;
17472         }
17473         break;
17474     case POOL16E:
17475         switch (ctx->opcode & 0x1) {
17476         case ADDIUR2:
17477             gen_addiur2(ctx);
17478             break;
17479         case ADDIUR1SP:
17480             gen_addiur1sp(ctx);
17481             break;
17482         }
17483         break;
17484     case B16: /* BC16 */
17485         gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
17486                            sextract32(ctx->opcode, 0, 10) << 1,
17487                            (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17488         break;
17489     case BNEZ16: /* BNEZC16 */
17490     case BEQZ16: /* BEQZC16 */
17491         gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
17492                            mmreg(uMIPS_RD(ctx->opcode)),
17493                            0, sextract32(ctx->opcode, 0, 7) << 1,
17494                            (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17495
17496         break;
17497     case LI16:
17498         {
17499             int reg = mmreg(uMIPS_RD(ctx->opcode));
17500             int imm = ZIMM(ctx->opcode, 0, 7);
17501
17502             imm = (imm == 0x7f ? -1 : imm);
17503             tcg_gen_movi_tl(cpu_gpr[reg], imm);
17504         }
17505         break;
17506     case RES_29:
17507     case RES_31:
17508     case RES_39:
17509         generate_exception_end(ctx, EXCP_RI);
17510         break;
17511     default:
17512         decode_micromips32_opc(env, ctx);
17513         return 4;
17514     }
17515
17516     return 2;
17517 }
17518
17519 /*
17520  *
17521  * nanoMIPS opcodes
17522  *
17523  */
17524
17525 /* MAJOR, P16, and P32 pools opcodes */
17526 enum {
17527     NM_P_ADDIU      = 0x00,
17528     NM_ADDIUPC      = 0x01,
17529     NM_MOVE_BALC    = 0x02,
17530     NM_P16_MV       = 0x04,
17531     NM_LW16         = 0x05,
17532     NM_BC16         = 0x06,
17533     NM_P16_SR       = 0x07,
17534
17535     NM_POOL32A      = 0x08,
17536     NM_P_BAL        = 0x0a,
17537     NM_P16_SHIFT    = 0x0c,
17538     NM_LWSP16       = 0x0d,
17539     NM_BALC16       = 0x0e,
17540     NM_P16_4X4      = 0x0f,
17541
17542     NM_P_GP_W       = 0x10,
17543     NM_P_GP_BH      = 0x11,
17544     NM_P_J          = 0x12,
17545     NM_P16C         = 0x14,
17546     NM_LWGP16       = 0x15,
17547     NM_P16_LB       = 0x17,
17548
17549     NM_P48I         = 0x18,
17550     NM_P16_A1       = 0x1c,
17551     NM_LW4X4        = 0x1d,
17552     NM_P16_LH       = 0x1f,
17553
17554     NM_P_U12        = 0x20,
17555     NM_P_LS_U12     = 0x21,
17556     NM_P_BR1        = 0x22,
17557     NM_P16_A2       = 0x24,
17558     NM_SW16         = 0x25,
17559     NM_BEQZC16      = 0x26,
17560
17561     NM_POOL32F      = 0x28,
17562     NM_P_LS_S9      = 0x29,
17563     NM_P_BR2        = 0x2a,
17564
17565     NM_P16_ADDU     = 0x2c,
17566     NM_SWSP16       = 0x2d,
17567     NM_BNEZC16      = 0x2e,
17568     NM_MOVEP        = 0x2f,
17569
17570     NM_POOL32S      = 0x30,
17571     NM_P_BRI        = 0x32,
17572     NM_LI16         = 0x34,
17573     NM_SWGP16       = 0x35,
17574     NM_P16_BR       = 0x36,
17575
17576     NM_P_LUI        = 0x38,
17577     NM_ANDI16       = 0x3c,
17578     NM_SW4X4        = 0x3d,
17579     NM_MOVEPREV     = 0x3f,
17580 };
17581
17582 /* POOL32A instruction pool */
17583 enum {
17584     NM_POOL32A0    = 0x00,
17585     NM_SPECIAL2    = 0x01,
17586     NM_COP2_1      = 0x02,
17587     NM_UDI         = 0x03,
17588     NM_POOL32A5    = 0x05,
17589     NM_POOL32A7    = 0x07,
17590 };
17591
17592 /* P.GP.W instruction pool */
17593 enum {
17594     NM_ADDIUGP_W = 0x00,
17595     NM_LWGP      = 0x02,
17596     NM_SWGP      = 0x03,
17597 };
17598
17599 /* P48I instruction pool */
17600 enum {
17601     NM_LI48        = 0x00,
17602     NM_ADDIU48     = 0x01,
17603     NM_ADDIUGP48   = 0x02,
17604     NM_ADDIUPC48   = 0x03,
17605     NM_LWPC48      = 0x0b,
17606     NM_SWPC48      = 0x0f,
17607 };
17608
17609 /* P.U12 instruction pool */
17610 enum {
17611     NM_ORI      = 0x00,
17612     NM_XORI     = 0x01,
17613     NM_ANDI     = 0x02,
17614     NM_P_SR     = 0x03,
17615     NM_SLTI     = 0x04,
17616     NM_SLTIU    = 0x05,
17617     NM_SEQI     = 0x06,
17618     NM_ADDIUNEG = 0x08,
17619     NM_P_SHIFT  = 0x0c,
17620     NM_P_ROTX   = 0x0d,
17621     NM_P_INS    = 0x0e,
17622     NM_P_EXT    = 0x0f,
17623 };
17624
17625 /* POOL32F instruction pool */
17626 enum {
17627     NM_POOL32F_0   = 0x00,
17628     NM_POOL32F_3   = 0x03,
17629     NM_POOL32F_5   = 0x05,
17630 };
17631
17632 /* POOL32S instruction pool */
17633 enum {
17634     NM_POOL32S_0   = 0x00,
17635     NM_POOL32S_4   = 0x04,
17636 };
17637
17638 /* P.LUI instruction pool */
17639 enum {
17640     NM_LUI      = 0x00,
17641     NM_ALUIPC   = 0x01,
17642 };
17643
17644 /* P.GP.BH instruction pool */
17645 enum {
17646     NM_LBGP      = 0x00,
17647     NM_SBGP      = 0x01,
17648     NM_LBUGP     = 0x02,
17649     NM_ADDIUGP_B = 0x03,
17650     NM_P_GP_LH   = 0x04,
17651     NM_P_GP_SH   = 0x05,
17652     NM_P_GP_CP1  = 0x06,
17653 };
17654
17655 /* P.LS.U12 instruction pool */
17656 enum {
17657     NM_LB        = 0x00,
17658     NM_SB        = 0x01,
17659     NM_LBU       = 0x02,
17660     NM_P_PREFU12 = 0x03,
17661     NM_LH        = 0x04,
17662     NM_SH        = 0x05,
17663     NM_LHU       = 0x06,
17664     NM_LWU       = 0x07,
17665     NM_LW        = 0x08,
17666     NM_SW        = 0x09,
17667     NM_LWC1      = 0x0a,
17668     NM_SWC1      = 0x0b,
17669     NM_LDC1      = 0x0e,
17670     NM_SDC1      = 0x0f,
17671 };
17672
17673 /* P.LS.S9 instruction pool */
17674 enum {
17675     NM_P_LS_S0         = 0x00,
17676     NM_P_LS_S1         = 0x01,
17677     NM_P_LS_E0         = 0x02,
17678     NM_P_LS_WM         = 0x04,
17679     NM_P_LS_UAWM       = 0x05,
17680 };
17681
17682 /* P.BAL instruction pool */
17683 enum {
17684     NM_BC       = 0x00,
17685     NM_BALC     = 0x01,
17686 };
17687
17688 /* P.J instruction pool */
17689 enum {
17690     NM_JALRC    = 0x00,
17691     NM_JALRC_HB = 0x01,
17692     NM_P_BALRSC = 0x08,
17693 };
17694
17695 /* P.BR1 instruction pool */
17696 enum {
17697     NM_BEQC     = 0x00,
17698     NM_P_BR3A   = 0x01,
17699     NM_BGEC     = 0x02,
17700     NM_BGEUC    = 0x03,
17701 };
17702
17703 /* P.BR2 instruction pool */
17704 enum {
17705     NM_BNEC     = 0x00,
17706     NM_BLTC     = 0x02,
17707     NM_BLTUC    = 0x03,
17708 };
17709
17710 /* P.BRI instruction pool */
17711 enum {
17712     NM_BEQIC    = 0x00,
17713     NM_BBEQZC   = 0x01,
17714     NM_BGEIC    = 0x02,
17715     NM_BGEIUC   = 0x03,
17716     NM_BNEIC    = 0x04,
17717     NM_BBNEZC   = 0x05,
17718     NM_BLTIC    = 0x06,
17719     NM_BLTIUC   = 0x07,
17720 };
17721
17722 /* P16.SHIFT instruction pool */
17723 enum {
17724     NM_SLL16    = 0x00,
17725     NM_SRL16    = 0x01,
17726 };
17727
17728 /* POOL16C instruction pool */
17729 enum {
17730     NM_POOL16C_0  = 0x00,
17731     NM_LWXS16     = 0x01,
17732 };
17733
17734 /* P16.A1 instruction pool */
17735 enum {
17736     NM_ADDIUR1SP = 0x01,
17737 };
17738
17739 /* P16.A2 instruction pool */
17740 enum {
17741     NM_ADDIUR2  = 0x00,
17742     NM_P_ADDIURS5  = 0x01,
17743 };
17744
17745 /* P16.ADDU instruction pool */
17746 enum {
17747     NM_ADDU16     = 0x00,
17748     NM_SUBU16     = 0x01,
17749 };
17750
17751 /* P16.SR instruction pool */
17752 enum {
17753     NM_SAVE16        = 0x00,
17754     NM_RESTORE_JRC16 = 0x01,
17755 };
17756
17757 /* P16.4X4 instruction pool */
17758 enum {
17759     NM_ADDU4X4      = 0x00,
17760     NM_MUL4X4       = 0x01,
17761 };
17762
17763 /* P16.LB instruction pool */
17764 enum {
17765     NM_LB16       = 0x00,
17766     NM_SB16       = 0x01,
17767     NM_LBU16      = 0x02,
17768 };
17769
17770 /* P16.LH  instruction pool */
17771 enum {
17772     NM_LH16     = 0x00,
17773     NM_SH16     = 0x01,
17774     NM_LHU16    = 0x02,
17775 };
17776
17777 /* P.RI instruction pool */
17778 enum {
17779     NM_SIGRIE       = 0x00,
17780     NM_P_SYSCALL    = 0x01,
17781     NM_BREAK        = 0x02,
17782     NM_SDBBP        = 0x03,
17783 };
17784
17785 /* POOL32A0 instruction pool */
17786 enum {
17787     NM_P_TRAP   = 0x00,
17788     NM_SEB      = 0x01,
17789     NM_SLLV     = 0x02,
17790     NM_MUL      = 0x03,
17791     NM_MFC0     = 0x06,
17792     NM_MFHC0    = 0x07,
17793     NM_SEH      = 0x09,
17794     NM_SRLV     = 0x0a,
17795     NM_MUH      = 0x0b,
17796     NM_MTC0     = 0x0e,
17797     NM_MTHC0    = 0x0f,
17798     NM_SRAV     = 0x12,
17799     NM_MULU     = 0x13,
17800     NM_ROTRV    = 0x1a,
17801     NM_MUHU     = 0x1b,
17802     NM_ADD      = 0x22,
17803     NM_DIV      = 0x23,
17804     NM_ADDU     = 0x2a,
17805     NM_MOD      = 0x2b,
17806     NM_SUB      = 0x32,
17807     NM_DIVU     = 0x33,
17808     NM_RDHWR    = 0x38,
17809     NM_SUBU     = 0x3a,
17810     NM_MODU     = 0x3b,
17811     NM_P_CMOVE  = 0x42,
17812     NM_FORK     = 0x45,
17813     NM_MFTR     = 0x46,
17814     NM_MFHTR    = 0x47,
17815     NM_AND      = 0x4a,
17816     NM_YIELD    = 0x4d,
17817     NM_MTTR     = 0x4e,
17818     NM_MTHTR    = 0x4f,
17819     NM_OR       = 0x52,
17820     NM_D_E_MT_VPE = 0x56,
17821     NM_NOR      = 0x5a,
17822     NM_XOR      = 0x62,
17823     NM_SLT      = 0x6a,
17824     NM_P_SLTU   = 0x72,
17825     NM_SOV      = 0x7a,
17826 };
17827
17828 /* CRC32 instruction pool */
17829 enum {
17830     NM_CRC32B   = 0x00,
17831     NM_CRC32H   = 0x01,
17832     NM_CRC32W   = 0x02,
17833     NM_CRC32CB  = 0x04,
17834     NM_CRC32CH  = 0x05,
17835     NM_CRC32CW  = 0x06,
17836 };
17837
17838 /* POOL32A5 instruction pool */
17839 enum {
17840     NM_CMP_EQ_PH        = 0x00,
17841     NM_CMP_LT_PH        = 0x08,
17842     NM_CMP_LE_PH        = 0x10,
17843     NM_CMPGU_EQ_QB      = 0x18,
17844     NM_CMPGU_LT_QB      = 0x20,
17845     NM_CMPGU_LE_QB      = 0x28,
17846     NM_CMPGDU_EQ_QB     = 0x30,
17847     NM_CMPGDU_LT_QB     = 0x38,
17848     NM_CMPGDU_LE_QB     = 0x40,
17849     NM_CMPU_EQ_QB       = 0x48,
17850     NM_CMPU_LT_QB       = 0x50,
17851     NM_CMPU_LE_QB       = 0x58,
17852     NM_ADDQ_S_W         = 0x60,
17853     NM_SUBQ_S_W         = 0x68,
17854     NM_ADDSC            = 0x70,
17855     NM_ADDWC            = 0x78,
17856
17857     NM_ADDQ_S_PH   = 0x01,
17858     NM_ADDQH_R_PH  = 0x09,
17859     NM_ADDQH_R_W   = 0x11,
17860     NM_ADDU_S_QB   = 0x19,
17861     NM_ADDU_S_PH   = 0x21,
17862     NM_ADDUH_R_QB  = 0x29,
17863     NM_SHRAV_R_PH  = 0x31,
17864     NM_SHRAV_R_QB  = 0x39,
17865     NM_SUBQ_S_PH   = 0x41,
17866     NM_SUBQH_R_PH  = 0x49,
17867     NM_SUBQH_R_W   = 0x51,
17868     NM_SUBU_S_QB   = 0x59,
17869     NM_SUBU_S_PH   = 0x61,
17870     NM_SUBUH_R_QB  = 0x69,
17871     NM_SHLLV_S_PH  = 0x71,
17872     NM_PRECR_SRA_R_PH_W = 0x79,
17873
17874     NM_MULEU_S_PH_QBL   = 0x12,
17875     NM_MULEU_S_PH_QBR   = 0x1a,
17876     NM_MULQ_RS_PH       = 0x22,
17877     NM_MULQ_S_PH        = 0x2a,
17878     NM_MULQ_RS_W        = 0x32,
17879     NM_MULQ_S_W         = 0x3a,
17880     NM_APPEND           = 0x42,
17881     NM_MODSUB           = 0x52,
17882     NM_SHRAV_R_W        = 0x5a,
17883     NM_SHRLV_PH         = 0x62,
17884     NM_SHRLV_QB         = 0x6a,
17885     NM_SHLLV_QB         = 0x72,
17886     NM_SHLLV_S_W        = 0x7a,
17887
17888     NM_SHILO            = 0x03,
17889
17890     NM_MULEQ_S_W_PHL    = 0x04,
17891     NM_MULEQ_S_W_PHR    = 0x0c,
17892
17893     NM_MUL_S_PH         = 0x05,
17894     NM_PRECR_QB_PH      = 0x0d,
17895     NM_PRECRQ_QB_PH     = 0x15,
17896     NM_PRECRQ_PH_W      = 0x1d,
17897     NM_PRECRQ_RS_PH_W   = 0x25,
17898     NM_PRECRQU_S_QB_PH  = 0x2d,
17899     NM_PACKRL_PH        = 0x35,
17900     NM_PICK_QB          = 0x3d,
17901     NM_PICK_PH          = 0x45,
17902
17903     NM_SHRA_R_W         = 0x5e,
17904     NM_SHRA_R_PH        = 0x66,
17905     NM_SHLL_S_PH        = 0x76,
17906     NM_SHLL_S_W         = 0x7e,
17907
17908     NM_REPL_PH          = 0x07
17909 };
17910
17911 /* POOL32A7 instruction pool */
17912 enum {
17913     NM_P_LSX        = 0x00,
17914     NM_LSA          = 0x01,
17915     NM_EXTW         = 0x03,
17916     NM_POOL32AXF    = 0x07,
17917 };
17918
17919 /* P.SR instruction pool */
17920 enum {
17921     NM_PP_SR           = 0x00,
17922     NM_P_SR_F          = 0x01,
17923 };
17924
17925 /* P.SHIFT instruction pool */
17926 enum {
17927     NM_P_SLL        = 0x00,
17928     NM_SRL          = 0x02,
17929     NM_SRA          = 0x04,
17930     NM_ROTR         = 0x06,
17931 };
17932
17933 /* P.ROTX instruction pool */
17934 enum {
17935     NM_ROTX         = 0x00,
17936 };
17937
17938 /* P.INS instruction pool */
17939 enum {
17940     NM_INS          = 0x00,
17941 };
17942
17943 /* P.EXT instruction pool */
17944 enum {
17945     NM_EXT          = 0x00,
17946 };
17947
17948 /* POOL32F_0 (fmt) instruction pool */
17949 enum {
17950     NM_RINT_S              = 0x04,
17951     NM_RINT_D              = 0x44,
17952     NM_ADD_S               = 0x06,
17953     NM_SELEQZ_S            = 0x07,
17954     NM_SELEQZ_D            = 0x47,
17955     NM_CLASS_S             = 0x0c,
17956     NM_CLASS_D             = 0x4c,
17957     NM_SUB_S               = 0x0e,
17958     NM_SELNEZ_S            = 0x0f,
17959     NM_SELNEZ_D            = 0x4f,
17960     NM_MUL_S               = 0x16,
17961     NM_SEL_S               = 0x17,
17962     NM_SEL_D               = 0x57,
17963     NM_DIV_S               = 0x1e,
17964     NM_ADD_D               = 0x26,
17965     NM_SUB_D               = 0x2e,
17966     NM_MUL_D               = 0x36,
17967     NM_MADDF_S             = 0x37,
17968     NM_MADDF_D             = 0x77,
17969     NM_DIV_D               = 0x3e,
17970     NM_MSUBF_S             = 0x3f,
17971     NM_MSUBF_D             = 0x7f,
17972 };
17973
17974 /* POOL32F_3  instruction pool */
17975 enum {
17976     NM_MIN_FMT         = 0x00,
17977     NM_MAX_FMT         = 0x01,
17978     NM_MINA_FMT        = 0x04,
17979     NM_MAXA_FMT        = 0x05,
17980     NM_POOL32FXF       = 0x07,
17981 };
17982
17983 /* POOL32F_5  instruction pool */
17984 enum {
17985     NM_CMP_CONDN_S     = 0x00,
17986     NM_CMP_CONDN_D     = 0x02,
17987 };
17988
17989 /* P.GP.LH instruction pool */
17990 enum {
17991     NM_LHGP    = 0x00,
17992     NM_LHUGP   = 0x01,
17993 };
17994
17995 /* P.GP.SH instruction pool */
17996 enum {
17997     NM_SHGP    = 0x00,
17998 };
17999
18000 /* P.GP.CP1 instruction pool */
18001 enum {
18002     NM_LWC1GP       = 0x00,
18003     NM_SWC1GP       = 0x01,
18004     NM_LDC1GP       = 0x02,
18005     NM_SDC1GP       = 0x03,
18006 };
18007
18008 /* P.LS.S0 instruction pool */
18009 enum {
18010     NM_LBS9     = 0x00,
18011     NM_LHS9     = 0x04,
18012     NM_LWS9     = 0x08,
18013     NM_LDS9     = 0x0c,
18014
18015     NM_SBS9     = 0x01,
18016     NM_SHS9     = 0x05,
18017     NM_SWS9     = 0x09,
18018     NM_SDS9     = 0x0d,
18019
18020     NM_LBUS9    = 0x02,
18021     NM_LHUS9    = 0x06,
18022     NM_LWC1S9   = 0x0a,
18023     NM_LDC1S9   = 0x0e,
18024
18025     NM_P_PREFS9 = 0x03,
18026     NM_LWUS9    = 0x07,
18027     NM_SWC1S9   = 0x0b,
18028     NM_SDC1S9   = 0x0f,
18029 };
18030
18031 /* P.LS.S1 instruction pool */
18032 enum {
18033     NM_ASET_ACLR = 0x02,
18034     NM_UALH      = 0x04,
18035     NM_UASH      = 0x05,
18036     NM_CACHE     = 0x07,
18037     NM_P_LL      = 0x0a,
18038     NM_P_SC      = 0x0b,
18039 };
18040
18041 /* P.LS.E0 instruction pool */
18042 enum {
18043     NM_LBE      = 0x00,
18044     NM_SBE      = 0x01,
18045     NM_LBUE     = 0x02,
18046     NM_P_PREFE  = 0x03,
18047     NM_LHE      = 0x04,
18048     NM_SHE      = 0x05,
18049     NM_LHUE     = 0x06,
18050     NM_CACHEE   = 0x07,
18051     NM_LWE      = 0x08,
18052     NM_SWE      = 0x09,
18053     NM_P_LLE    = 0x0a,
18054     NM_P_SCE    = 0x0b,
18055 };
18056
18057 /* P.PREFE instruction pool */
18058 enum {
18059     NM_SYNCIE   = 0x00,
18060     NM_PREFE    = 0x01,
18061 };
18062
18063 /* P.LLE instruction pool */
18064 enum {
18065     NM_LLE      = 0x00,
18066     NM_LLWPE    = 0x01,
18067 };
18068
18069 /* P.SCE instruction pool */
18070 enum {
18071     NM_SCE      = 0x00,
18072     NM_SCWPE    = 0x01,
18073 };
18074
18075 /* P.LS.WM instruction pool */
18076 enum {
18077     NM_LWM       = 0x00,
18078     NM_SWM       = 0x01,
18079 };
18080
18081 /* P.LS.UAWM instruction pool */
18082 enum {
18083     NM_UALWM       = 0x00,
18084     NM_UASWM       = 0x01,
18085 };
18086
18087 /* P.BR3A instruction pool */
18088 enum {
18089     NM_BC1EQZC          = 0x00,
18090     NM_BC1NEZC          = 0x01,
18091     NM_BC2EQZC          = 0x02,
18092     NM_BC2NEZC          = 0x03,
18093     NM_BPOSGE32C        = 0x04,
18094 };
18095
18096 /* P16.RI instruction pool */
18097 enum {
18098     NM_P16_SYSCALL  = 0x01,
18099     NM_BREAK16      = 0x02,
18100     NM_SDBBP16      = 0x03,
18101 };
18102
18103 /* POOL16C_0 instruction pool */
18104 enum {
18105     NM_POOL16C_00      = 0x00,
18106 };
18107
18108 /* P16.JRC instruction pool */
18109 enum {
18110     NM_JRC          = 0x00,
18111     NM_JALRC16      = 0x01,
18112 };
18113
18114 /* P.SYSCALL instruction pool */
18115 enum {
18116     NM_SYSCALL      = 0x00,
18117     NM_HYPCALL      = 0x01,
18118 };
18119
18120 /* P.TRAP instruction pool */
18121 enum {
18122     NM_TEQ          = 0x00,
18123     NM_TNE          = 0x01,
18124 };
18125
18126 /* P.CMOVE instruction pool */
18127 enum {
18128     NM_MOVZ            = 0x00,
18129     NM_MOVN            = 0x01,
18130 };
18131
18132 /* POOL32Axf instruction pool */
18133 enum {
18134     NM_POOL32AXF_1 = 0x01,
18135     NM_POOL32AXF_2 = 0x02,
18136     NM_POOL32AXF_4 = 0x04,
18137     NM_POOL32AXF_5 = 0x05,
18138     NM_POOL32AXF_7 = 0x07,
18139 };
18140
18141 /* POOL32Axf_1 instruction pool */
18142 enum {
18143     NM_POOL32AXF_1_0 = 0x00,
18144     NM_POOL32AXF_1_1 = 0x01,
18145     NM_POOL32AXF_1_3 = 0x03,
18146     NM_POOL32AXF_1_4 = 0x04,
18147     NM_POOL32AXF_1_5 = 0x05,
18148     NM_POOL32AXF_1_7 = 0x07,
18149 };
18150
18151 /* POOL32Axf_2 instruction pool */
18152 enum {
18153     NM_POOL32AXF_2_0_7     = 0x00,
18154     NM_POOL32AXF_2_8_15    = 0x01,
18155     NM_POOL32AXF_2_16_23   = 0x02,
18156     NM_POOL32AXF_2_24_31   = 0x03,
18157 };
18158
18159 /* POOL32Axf_7 instruction pool */
18160 enum {
18161     NM_SHRA_R_QB    = 0x0,
18162     NM_SHRL_PH      = 0x1,
18163     NM_REPL_QB      = 0x2,
18164 };
18165
18166 /* POOL32Axf_1_0 instruction pool */
18167 enum {
18168     NM_MFHI = 0x0,
18169     NM_MFLO = 0x1,
18170     NM_MTHI = 0x2,
18171     NM_MTLO = 0x3,
18172 };
18173
18174 /* POOL32Axf_1_1 instruction pool */
18175 enum {
18176     NM_MTHLIP = 0x0,
18177     NM_SHILOV = 0x1,
18178 };
18179
18180 /* POOL32Axf_1_3 instruction pool */
18181 enum {
18182     NM_RDDSP    = 0x0,
18183     NM_WRDSP    = 0x1,
18184     NM_EXTP     = 0x2,
18185     NM_EXTPDP   = 0x3,
18186 };
18187
18188 /* POOL32Axf_1_4 instruction pool */
18189 enum {
18190     NM_SHLL_QB  = 0x0,
18191     NM_SHRL_QB  = 0x1,
18192 };
18193
18194 /* POOL32Axf_1_5 instruction pool */
18195 enum {
18196     NM_MAQ_S_W_PHR   = 0x0,
18197     NM_MAQ_S_W_PHL   = 0x1,
18198     NM_MAQ_SA_W_PHR  = 0x2,
18199     NM_MAQ_SA_W_PHL  = 0x3,
18200 };
18201
18202 /* POOL32Axf_1_7 instruction pool */
18203 enum {
18204     NM_EXTR_W       = 0x0,
18205     NM_EXTR_R_W     = 0x1,
18206     NM_EXTR_RS_W    = 0x2,
18207     NM_EXTR_S_H     = 0x3,
18208 };
18209
18210 /* POOL32Axf_2_0_7 instruction pool */
18211 enum {
18212     NM_DPA_W_PH     = 0x0,
18213     NM_DPAQ_S_W_PH  = 0x1,
18214     NM_DPS_W_PH     = 0x2,
18215     NM_DPSQ_S_W_PH  = 0x3,
18216     NM_BALIGN       = 0x4,
18217     NM_MADD         = 0x5,
18218     NM_MULT         = 0x6,
18219     NM_EXTRV_W      = 0x7,
18220 };
18221
18222 /* POOL32Axf_2_8_15 instruction pool */
18223 enum {
18224     NM_DPAX_W_PH    = 0x0,
18225     NM_DPAQ_SA_L_W  = 0x1,
18226     NM_DPSX_W_PH    = 0x2,
18227     NM_DPSQ_SA_L_W  = 0x3,
18228     NM_MADDU        = 0x5,
18229     NM_MULTU        = 0x6,
18230     NM_EXTRV_R_W    = 0x7,
18231 };
18232
18233 /* POOL32Axf_2_16_23 instruction pool */
18234 enum {
18235     NM_DPAU_H_QBL       = 0x0,
18236     NM_DPAQX_S_W_PH     = 0x1,
18237     NM_DPSU_H_QBL       = 0x2,
18238     NM_DPSQX_S_W_PH     = 0x3,
18239     NM_EXTPV            = 0x4,
18240     NM_MSUB             = 0x5,
18241     NM_MULSA_W_PH       = 0x6,
18242     NM_EXTRV_RS_W       = 0x7,
18243 };
18244
18245 /* POOL32Axf_2_24_31 instruction pool */
18246 enum {
18247     NM_DPAU_H_QBR       = 0x0,
18248     NM_DPAQX_SA_W_PH    = 0x1,
18249     NM_DPSU_H_QBR       = 0x2,
18250     NM_DPSQX_SA_W_PH    = 0x3,
18251     NM_EXTPDPV          = 0x4,
18252     NM_MSUBU            = 0x5,
18253     NM_MULSAQ_S_W_PH    = 0x6,
18254     NM_EXTRV_S_H        = 0x7,
18255 };
18256
18257 /* POOL32Axf_{4, 5} instruction pool */
18258 enum {
18259     NM_CLO      = 0x25,
18260     NM_CLZ      = 0x2d,
18261
18262     NM_TLBP     = 0x01,
18263     NM_TLBR     = 0x09,
18264     NM_TLBWI    = 0x11,
18265     NM_TLBWR    = 0x19,
18266     NM_TLBINV   = 0x03,
18267     NM_TLBINVF  = 0x0b,
18268     NM_DI       = 0x23,
18269     NM_EI       = 0x2b,
18270     NM_RDPGPR   = 0x70,
18271     NM_WRPGPR   = 0x78,
18272     NM_WAIT     = 0x61,
18273     NM_DERET    = 0x71,
18274     NM_ERETX    = 0x79,
18275
18276     /* nanoMIPS DSP instructions */
18277     NM_ABSQ_S_QB        = 0x00,
18278     NM_ABSQ_S_PH        = 0x08,
18279     NM_ABSQ_S_W         = 0x10,
18280     NM_PRECEQ_W_PHL     = 0x28,
18281     NM_PRECEQ_W_PHR     = 0x30,
18282     NM_PRECEQU_PH_QBL   = 0x38,
18283     NM_PRECEQU_PH_QBR   = 0x48,
18284     NM_PRECEU_PH_QBL    = 0x58,
18285     NM_PRECEU_PH_QBR    = 0x68,
18286     NM_PRECEQU_PH_QBLA  = 0x39,
18287     NM_PRECEQU_PH_QBRA  = 0x49,
18288     NM_PRECEU_PH_QBLA   = 0x59,
18289     NM_PRECEU_PH_QBRA   = 0x69,
18290     NM_REPLV_PH         = 0x01,
18291     NM_REPLV_QB         = 0x09,
18292     NM_BITREV           = 0x18,
18293     NM_INSV             = 0x20,
18294     NM_RADDU_W_QB       = 0x78,
18295
18296     NM_BITSWAP          = 0x05,
18297     NM_WSBH             = 0x3d,
18298 };
18299
18300 /* PP.SR instruction pool */
18301 enum {
18302     NM_SAVE         = 0x00,
18303     NM_RESTORE      = 0x02,
18304     NM_RESTORE_JRC  = 0x03,
18305 };
18306
18307 /* P.SR.F instruction pool */
18308 enum {
18309     NM_SAVEF        = 0x00,
18310     NM_RESTOREF     = 0x01,
18311 };
18312
18313 /* P16.SYSCALL  instruction pool */
18314 enum {
18315     NM_SYSCALL16     = 0x00,
18316     NM_HYPCALL16     = 0x01,
18317 };
18318
18319 /* POOL16C_00 instruction pool */
18320 enum {
18321     NM_NOT16           = 0x00,
18322     NM_XOR16           = 0x01,
18323     NM_AND16           = 0x02,
18324     NM_OR16            = 0x03,
18325 };
18326
18327 /* PP.LSX and PP.LSXS instruction pool */
18328 enum {
18329     NM_LBX      = 0x00,
18330     NM_LHX      = 0x04,
18331     NM_LWX      = 0x08,
18332     NM_LDX      = 0x0c,
18333
18334     NM_SBX      = 0x01,
18335     NM_SHX      = 0x05,
18336     NM_SWX      = 0x09,
18337     NM_SDX      = 0x0d,
18338
18339     NM_LBUX     = 0x02,
18340     NM_LHUX     = 0x06,
18341     NM_LWC1X    = 0x0a,
18342     NM_LDC1X    = 0x0e,
18343
18344     NM_LWUX     = 0x07,
18345     NM_SWC1X    = 0x0b,
18346     NM_SDC1X    = 0x0f,
18347
18348     NM_LHXS     = 0x04,
18349     NM_LWXS     = 0x08,
18350     NM_LDXS     = 0x0c,
18351
18352     NM_SHXS     = 0x05,
18353     NM_SWXS     = 0x09,
18354     NM_SDXS     = 0x0d,
18355
18356     NM_LHUXS    = 0x06,
18357     NM_LWC1XS   = 0x0a,
18358     NM_LDC1XS   = 0x0e,
18359
18360     NM_LWUXS    = 0x07,
18361     NM_SWC1XS   = 0x0b,
18362     NM_SDC1XS   = 0x0f,
18363 };
18364
18365 /* ERETx instruction pool */
18366 enum {
18367     NM_ERET     = 0x00,
18368     NM_ERETNC   = 0x01,
18369 };
18370
18371 /* POOL32FxF_{0, 1} insturction pool */
18372 enum {
18373     NM_CFC1     = 0x40,
18374     NM_CTC1     = 0x60,
18375     NM_MFC1     = 0x80,
18376     NM_MTC1     = 0xa0,
18377     NM_MFHC1    = 0xc0,
18378     NM_MTHC1    = 0xe0,
18379
18380     NM_CVT_S_PL = 0x84,
18381     NM_CVT_S_PU = 0xa4,
18382
18383     NM_CVT_L_S     = 0x004,
18384     NM_CVT_L_D     = 0x104,
18385     NM_CVT_W_S     = 0x024,
18386     NM_CVT_W_D     = 0x124,
18387
18388     NM_RSQRT_S     = 0x008,
18389     NM_RSQRT_D     = 0x108,
18390
18391     NM_SQRT_S      = 0x028,
18392     NM_SQRT_D      = 0x128,
18393
18394     NM_RECIP_S     = 0x048,
18395     NM_RECIP_D     = 0x148,
18396
18397     NM_FLOOR_L_S   = 0x00c,
18398     NM_FLOOR_L_D   = 0x10c,
18399
18400     NM_FLOOR_W_S   = 0x02c,
18401     NM_FLOOR_W_D   = 0x12c,
18402
18403     NM_CEIL_L_S    = 0x04c,
18404     NM_CEIL_L_D    = 0x14c,
18405     NM_CEIL_W_S    = 0x06c,
18406     NM_CEIL_W_D    = 0x16c,
18407     NM_TRUNC_L_S   = 0x08c,
18408     NM_TRUNC_L_D   = 0x18c,
18409     NM_TRUNC_W_S   = 0x0ac,
18410     NM_TRUNC_W_D   = 0x1ac,
18411     NM_ROUND_L_S   = 0x0cc,
18412     NM_ROUND_L_D   = 0x1cc,
18413     NM_ROUND_W_S   = 0x0ec,
18414     NM_ROUND_W_D   = 0x1ec,
18415
18416     NM_MOV_S       = 0x01,
18417     NM_MOV_D       = 0x81,
18418     NM_ABS_S       = 0x0d,
18419     NM_ABS_D       = 0x8d,
18420     NM_NEG_S       = 0x2d,
18421     NM_NEG_D       = 0xad,
18422     NM_CVT_D_S     = 0x04d,
18423     NM_CVT_D_W     = 0x0cd,
18424     NM_CVT_D_L     = 0x14d,
18425     NM_CVT_S_D     = 0x06d,
18426     NM_CVT_S_W     = 0x0ed,
18427     NM_CVT_S_L     = 0x16d,
18428 };
18429
18430 /* P.LL instruction pool */
18431 enum {
18432     NM_LL       = 0x00,
18433     NM_LLWP     = 0x01,
18434 };
18435
18436 /* P.SC instruction pool */
18437 enum {
18438     NM_SC       = 0x00,
18439     NM_SCWP     = 0x01,
18440 };
18441
18442 /* P.DVP instruction pool */
18443 enum {
18444     NM_DVP      = 0x00,
18445     NM_EVP      = 0x01,
18446 };
18447
18448
18449 /*
18450  *
18451  * nanoMIPS decoding engine
18452  *
18453  */
18454
18455
18456 /* extraction utilities */
18457
18458 #define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
18459 #define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
18460 #define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
18461 #define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
18462 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18463 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18464
18465 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
18466 static inline int decode_gpr_gpr3(int r)
18467 {
18468     static const int map[] = { 16, 17, 18, 19,  4,  5,  6,  7 };
18469
18470     return map[r & 0x7];
18471 }
18472
18473 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
18474 static inline int decode_gpr_gpr3_src_store(int r)
18475 {
18476     static const int map[] = {  0, 17, 18, 19,  4,  5,  6,  7 };
18477
18478     return map[r & 0x7];
18479 }
18480
18481 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
18482 static inline int decode_gpr_gpr4(int r)
18483 {
18484     static const int map[] = {  8,  9, 10, 11,  4,  5,  6,  7,
18485                                16, 17, 18, 19, 20, 21, 22, 23 };
18486
18487     return map[r & 0xf];
18488 }
18489
18490 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
18491 static inline int decode_gpr_gpr4_zero(int r)
18492 {
18493     static const int map[] = {  8,  9, 10,  0,  4,  5,  6,  7,
18494                                16, 17, 18, 19, 20, 21, 22, 23 };
18495
18496     return map[r & 0xf];
18497 }
18498
18499
18500 /* extraction utilities */
18501
18502 #define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
18503 #define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
18504 #define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
18505 #define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
18506 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18507 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18508
18509
18510 static void gen_adjust_sp(DisasContext *ctx, int u)
18511 {
18512     gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u);
18513 }
18514
18515 static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count,
18516                      uint8_t gp, uint16_t u)
18517 {
18518     int counter = 0;
18519     TCGv va = tcg_temp_new();
18520     TCGv t0 = tcg_temp_new();
18521
18522     while (counter != count) {
18523         bool use_gp = gp && (counter == count - 1);
18524         int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18525         int this_offset = -((counter + 1) << 2);
18526         gen_base_offset_addr(ctx, va, 29, this_offset);
18527         gen_load_gpr(t0, this_rt);
18528         tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx,
18529                            (MO_TEUL | ctx->default_tcg_memop_mask));
18530         counter++;
18531     }
18532
18533     /* adjust stack pointer */
18534     gen_adjust_sp(ctx, -u);
18535
18536     tcg_temp_free(t0);
18537     tcg_temp_free(va);
18538 }
18539
18540 static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count,
18541                         uint8_t gp, uint16_t u)
18542 {
18543     int counter = 0;
18544     TCGv va = tcg_temp_new();
18545     TCGv t0 = tcg_temp_new();
18546
18547     while (counter != count) {
18548         bool use_gp = gp && (counter == count - 1);
18549         int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18550         int this_offset = u - ((counter + 1) << 2);
18551         gen_base_offset_addr(ctx, va, 29, this_offset);
18552         tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL |
18553                         ctx->default_tcg_memop_mask);
18554         tcg_gen_ext32s_tl(t0, t0);
18555         gen_store_gpr(t0, this_rt);
18556         counter++;
18557     }
18558
18559     /* adjust stack pointer */
18560     gen_adjust_sp(ctx, u);
18561
18562     tcg_temp_free(t0);
18563     tcg_temp_free(va);
18564 }
18565
18566 static void gen_pool16c_nanomips_insn(DisasContext *ctx)
18567 {
18568     int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
18569     int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
18570
18571     switch (extract32(ctx->opcode, 2, 2)) {
18572     case NM_NOT16:
18573         gen_logic(ctx, OPC_NOR, rt, rs, 0);
18574         break;
18575     case NM_AND16:
18576         gen_logic(ctx, OPC_AND, rt, rt, rs);
18577         break;
18578     case NM_XOR16:
18579         gen_logic(ctx, OPC_XOR, rt, rt, rs);
18580         break;
18581     case NM_OR16:
18582         gen_logic(ctx, OPC_OR, rt, rt, rs);
18583         break;
18584     }
18585 }
18586
18587 static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
18588 {
18589     int rt = extract32(ctx->opcode, 21, 5);
18590     int rs = extract32(ctx->opcode, 16, 5);
18591     int rd = extract32(ctx->opcode, 11, 5);
18592
18593     switch (extract32(ctx->opcode, 3, 7)) {
18594     case NM_P_TRAP:
18595         switch (extract32(ctx->opcode, 10, 1)) {
18596         case NM_TEQ:
18597             check_nms(ctx);
18598             gen_trap(ctx, OPC_TEQ, rs, rt, -1);
18599             break;
18600         case NM_TNE:
18601             check_nms(ctx);
18602             gen_trap(ctx, OPC_TNE, rs, rt, -1);
18603             break;
18604         }
18605         break;
18606     case NM_RDHWR:
18607         check_nms(ctx);
18608         gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
18609         break;
18610     case NM_SEB:
18611         check_nms(ctx);
18612         gen_bshfl(ctx, OPC_SEB, rs, rt);
18613         break;
18614     case NM_SEH:
18615         gen_bshfl(ctx, OPC_SEH, rs, rt);
18616         break;
18617     case NM_SLLV:
18618         gen_shift(ctx, OPC_SLLV, rd, rt, rs);
18619         break;
18620     case NM_SRLV:
18621         gen_shift(ctx, OPC_SRLV, rd, rt, rs);
18622         break;
18623     case NM_SRAV:
18624         gen_shift(ctx, OPC_SRAV, rd, rt, rs);
18625         break;
18626     case NM_ROTRV:
18627         gen_shift(ctx, OPC_ROTRV, rd, rt, rs);
18628         break;
18629     case NM_ADD:
18630         gen_arith(ctx, OPC_ADD, rd, rs, rt);
18631         break;
18632     case NM_ADDU:
18633         gen_arith(ctx, OPC_ADDU, rd, rs, rt);
18634         break;
18635     case NM_SUB:
18636         check_nms(ctx);
18637         gen_arith(ctx, OPC_SUB, rd, rs, rt);
18638         break;
18639     case NM_SUBU:
18640         gen_arith(ctx, OPC_SUBU, rd, rs, rt);
18641         break;
18642     case NM_P_CMOVE:
18643         switch (extract32(ctx->opcode, 10, 1)) {
18644         case NM_MOVZ:
18645             gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
18646             break;
18647         case NM_MOVN:
18648             gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
18649             break;
18650         }
18651         break;
18652     case NM_AND:
18653         gen_logic(ctx, OPC_AND, rd, rs, rt);
18654         break;
18655     case NM_OR:
18656         gen_logic(ctx, OPC_OR, rd, rs, rt);
18657         break;
18658     case NM_NOR:
18659         gen_logic(ctx, OPC_NOR, rd, rs, rt);
18660         break;
18661     case NM_XOR:
18662         gen_logic(ctx, OPC_XOR, rd, rs, rt);
18663         break;
18664     case NM_SLT:
18665         gen_slt(ctx, OPC_SLT, rd, rs, rt);
18666         break;
18667     case NM_P_SLTU:
18668         if (rd == 0) {
18669             /* P_DVP */
18670 #ifndef CONFIG_USER_ONLY
18671             TCGv t0 = tcg_temp_new();
18672             switch (extract32(ctx->opcode, 10, 1)) {
18673             case NM_DVP:
18674                 if (ctx->vp) {
18675                     check_cp0_enabled(ctx);
18676                     gen_helper_dvp(t0, cpu_env);
18677                     gen_store_gpr(t0, rt);
18678                 }
18679                 break;
18680             case NM_EVP:
18681                 if (ctx->vp) {
18682                     check_cp0_enabled(ctx);
18683                     gen_helper_evp(t0, cpu_env);
18684                     gen_store_gpr(t0, rt);
18685                 }
18686                 break;
18687             }
18688             tcg_temp_free(t0);
18689 #endif
18690         } else {
18691             gen_slt(ctx, OPC_SLTU, rd, rs, rt);
18692         }
18693         break;
18694     case NM_SOV:
18695         {
18696             TCGv t0 = tcg_temp_new();
18697             TCGv t1 = tcg_temp_new();
18698             TCGv t2 = tcg_temp_new();
18699
18700             gen_load_gpr(t1, rs);
18701             gen_load_gpr(t2, rt);
18702             tcg_gen_add_tl(t0, t1, t2);
18703             tcg_gen_ext32s_tl(t0, t0);
18704             tcg_gen_xor_tl(t1, t1, t2);
18705             tcg_gen_xor_tl(t2, t0, t2);
18706             tcg_gen_andc_tl(t1, t2, t1);
18707
18708             /* operands of same sign, result different sign */
18709             tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0);
18710             gen_store_gpr(t0, rd);
18711
18712             tcg_temp_free(t0);
18713             tcg_temp_free(t1);
18714             tcg_temp_free(t2);
18715         }
18716         break;
18717     case NM_MUL:
18718         gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
18719         break;
18720     case NM_MUH:
18721         gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
18722         break;
18723     case NM_MULU:
18724         gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
18725         break;
18726     case NM_MUHU:
18727         gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
18728         break;
18729     case NM_DIV:
18730         gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
18731         break;
18732     case NM_MOD:
18733         gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
18734         break;
18735     case NM_DIVU:
18736         gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
18737         break;
18738     case NM_MODU:
18739         gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
18740         break;
18741 #ifndef CONFIG_USER_ONLY
18742     case NM_MFC0:
18743         check_cp0_enabled(ctx);
18744         if (rt == 0) {
18745             /* Treat as NOP. */
18746             break;
18747         }
18748         gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3));
18749         break;
18750     case NM_MTC0:
18751         check_cp0_enabled(ctx);
18752         {
18753             TCGv t0 = tcg_temp_new();
18754
18755             gen_load_gpr(t0, rt);
18756             gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3));
18757             tcg_temp_free(t0);
18758         }
18759         break;
18760     case NM_D_E_MT_VPE:
18761         {
18762             uint8_t sc = extract32(ctx->opcode, 10, 1);
18763             TCGv t0 = tcg_temp_new();
18764
18765             switch (sc) {
18766             case 0:
18767                 if (rs == 1) {
18768                     /* DMT */
18769                     check_cp0_mt(ctx);
18770                     gen_helper_dmt(t0);
18771                     gen_store_gpr(t0, rt);
18772                 } else if (rs == 0) {
18773                     /* DVPE */
18774                     check_cp0_mt(ctx);
18775                     gen_helper_dvpe(t0, cpu_env);
18776                     gen_store_gpr(t0, rt);
18777                 } else {
18778                     generate_exception_end(ctx, EXCP_RI);
18779                 }
18780                 break;
18781             case 1:
18782                 if (rs == 1) {
18783                     /* EMT */
18784                     check_cp0_mt(ctx);
18785                     gen_helper_emt(t0);
18786                     gen_store_gpr(t0, rt);
18787                 } else if (rs == 0) {
18788                     /* EVPE */
18789                     check_cp0_mt(ctx);
18790                     gen_helper_evpe(t0, cpu_env);
18791                     gen_store_gpr(t0, rt);
18792                 } else {
18793                     generate_exception_end(ctx, EXCP_RI);
18794                 }
18795                 break;
18796             }
18797
18798             tcg_temp_free(t0);
18799         }
18800         break;
18801     case NM_FORK:
18802         check_mt(ctx);
18803         {
18804             TCGv t0 = tcg_temp_new();
18805             TCGv t1 = tcg_temp_new();
18806
18807             gen_load_gpr(t0, rt);
18808             gen_load_gpr(t1, rs);
18809             gen_helper_fork(t0, t1);
18810             tcg_temp_free(t0);
18811             tcg_temp_free(t1);
18812         }
18813         break;
18814     case NM_MFTR:
18815     case NM_MFHTR:
18816         check_cp0_enabled(ctx);
18817         if (rd == 0) {
18818             /* Treat as NOP. */
18819             return;
18820         }
18821         gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18822                  extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18823         break;
18824     case NM_MTTR:
18825     case NM_MTHTR:
18826         check_cp0_enabled(ctx);
18827         gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18828                  extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18829         break;
18830     case NM_YIELD:
18831         check_mt(ctx);
18832         {
18833             TCGv t0 = tcg_temp_new();
18834
18835             gen_load_gpr(t0, rs);
18836             gen_helper_yield(t0, cpu_env, t0);
18837             gen_store_gpr(t0, rt);
18838             tcg_temp_free(t0);
18839         }
18840         break;
18841 #endif
18842     default:
18843         generate_exception_end(ctx, EXCP_RI);
18844         break;
18845     }
18846 }
18847
18848 /* dsp */
18849 static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc,
18850                                             int ret, int v1, int v2)
18851 {
18852     TCGv_i32 t0;
18853     TCGv v0_t;
18854     TCGv v1_t;
18855
18856     t0 = tcg_temp_new_i32();
18857
18858     v0_t = tcg_temp_new();
18859     v1_t = tcg_temp_new();
18860
18861     tcg_gen_movi_i32(t0, v2 >> 3);
18862
18863     gen_load_gpr(v0_t, ret);
18864     gen_load_gpr(v1_t, v1);
18865
18866     switch (opc) {
18867     case NM_MAQ_S_W_PHR:
18868         check_dsp(ctx);
18869         gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env);
18870         break;
18871     case NM_MAQ_S_W_PHL:
18872         check_dsp(ctx);
18873         gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env);
18874         break;
18875     case NM_MAQ_SA_W_PHR:
18876         check_dsp(ctx);
18877         gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env);
18878         break;
18879     case NM_MAQ_SA_W_PHL:
18880         check_dsp(ctx);
18881         gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env);
18882         break;
18883     default:
18884         generate_exception_end(ctx, EXCP_RI);
18885         break;
18886     }
18887
18888     tcg_temp_free_i32(t0);
18889
18890     tcg_temp_free(v0_t);
18891     tcg_temp_free(v1_t);
18892 }
18893
18894
18895 static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc,
18896                                     int ret, int v1, int v2)
18897 {
18898     int16_t imm;
18899     TCGv t0 = tcg_temp_new();
18900     TCGv t1 = tcg_temp_new();
18901     TCGv v0_t = tcg_temp_new();
18902
18903     gen_load_gpr(v0_t, v1);
18904
18905     switch (opc) {
18906     case NM_POOL32AXF_1_0:
18907         check_dsp(ctx);
18908         switch (extract32(ctx->opcode, 12, 2)) {
18909         case NM_MFHI:
18910             gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret);
18911             break;
18912         case NM_MFLO:
18913             gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret);
18914             break;
18915         case NM_MTHI:
18916             gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1);
18917             break;
18918         case NM_MTLO:
18919             gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1);
18920             break;
18921         }
18922         break;
18923     case NM_POOL32AXF_1_1:
18924         check_dsp(ctx);
18925         switch (extract32(ctx->opcode, 12, 2)) {
18926         case NM_MTHLIP:
18927             tcg_gen_movi_tl(t0, v2);
18928             gen_helper_mthlip(t0, v0_t, cpu_env);
18929             break;
18930         case NM_SHILOV:
18931             tcg_gen_movi_tl(t0, v2 >> 3);
18932             gen_helper_shilo(t0, v0_t, cpu_env);
18933             break;
18934         default:
18935             generate_exception_end(ctx, EXCP_RI);
18936             break;
18937         }
18938         break;
18939     case NM_POOL32AXF_1_3:
18940         check_dsp(ctx);
18941         imm = extract32(ctx->opcode, 14, 7);
18942         switch (extract32(ctx->opcode, 12, 2)) {
18943         case NM_RDDSP:
18944             tcg_gen_movi_tl(t0, imm);
18945             gen_helper_rddsp(t0, t0, cpu_env);
18946             gen_store_gpr(t0, ret);
18947             break;
18948         case NM_WRDSP:
18949             gen_load_gpr(t0, ret);
18950             tcg_gen_movi_tl(t1, imm);
18951             gen_helper_wrdsp(t0, t1, cpu_env);
18952             break;
18953         case NM_EXTP:
18954             tcg_gen_movi_tl(t0, v2 >> 3);
18955             tcg_gen_movi_tl(t1, v1);
18956             gen_helper_extp(t0, t0, t1, cpu_env);
18957             gen_store_gpr(t0, ret);
18958             break;
18959         case NM_EXTPDP:
18960             tcg_gen_movi_tl(t0, v2 >> 3);
18961             tcg_gen_movi_tl(t1, v1);
18962             gen_helper_extpdp(t0, t0, t1, cpu_env);
18963             gen_store_gpr(t0, ret);
18964             break;
18965         }
18966         break;
18967     case NM_POOL32AXF_1_4:
18968         check_dsp(ctx);
18969         tcg_gen_movi_tl(t0, v2 >> 2);
18970         switch (extract32(ctx->opcode, 12, 1)) {
18971         case NM_SHLL_QB:
18972             gen_helper_shll_qb(t0, t0, v0_t, cpu_env);
18973             gen_store_gpr(t0, ret);
18974             break;
18975         case NM_SHRL_QB:
18976             gen_helper_shrl_qb(t0, t0, v0_t);
18977             gen_store_gpr(t0, ret);
18978             break;
18979         }
18980         break;
18981     case NM_POOL32AXF_1_5:
18982         opc = extract32(ctx->opcode, 12, 2);
18983         gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2);
18984         break;
18985     case NM_POOL32AXF_1_7:
18986         check_dsp(ctx);
18987         tcg_gen_movi_tl(t0, v2 >> 3);
18988         tcg_gen_movi_tl(t1, v1);
18989         switch (extract32(ctx->opcode, 12, 2)) {
18990         case NM_EXTR_W:
18991             gen_helper_extr_w(t0, t0, t1, cpu_env);
18992             gen_store_gpr(t0, ret);
18993             break;
18994         case NM_EXTR_R_W:
18995             gen_helper_extr_r_w(t0, t0, t1, cpu_env);
18996             gen_store_gpr(t0, ret);
18997             break;
18998         case NM_EXTR_RS_W:
18999             gen_helper_extr_rs_w(t0, t0, t1, cpu_env);
19000             gen_store_gpr(t0, ret);
19001             break;
19002         case NM_EXTR_S_H:
19003             gen_helper_extr_s_h(t0, t0, t1, cpu_env);
19004             gen_store_gpr(t0, ret);
19005             break;
19006         }
19007         break;
19008     default:
19009         generate_exception_end(ctx, EXCP_RI);
19010         break;
19011     }
19012
19013     tcg_temp_free(t0);
19014     tcg_temp_free(t1);
19015     tcg_temp_free(v0_t);
19016 }
19017
19018 static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc,
19019                                     TCGv v0, TCGv v1, int rd)
19020 {
19021     TCGv_i32 t0;
19022
19023     t0 = tcg_temp_new_i32();
19024
19025     tcg_gen_movi_i32(t0, rd >> 3);
19026
19027     switch (opc) {
19028     case NM_POOL32AXF_2_0_7:
19029         switch (extract32(ctx->opcode, 9, 3)) {
19030         case NM_DPA_W_PH:
19031             check_dsp_r2(ctx);
19032             gen_helper_dpa_w_ph(t0, v1, v0, cpu_env);
19033             break;
19034         case NM_DPAQ_S_W_PH:
19035             check_dsp(ctx);
19036             gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env);
19037             break;
19038         case NM_DPS_W_PH:
19039             check_dsp_r2(ctx);
19040             gen_helper_dps_w_ph(t0, v1, v0, cpu_env);
19041             break;
19042         case NM_DPSQ_S_W_PH:
19043             check_dsp(ctx);
19044             gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env);
19045             break;
19046         default:
19047             generate_exception_end(ctx, EXCP_RI);
19048             break;
19049         }
19050         break;
19051     case NM_POOL32AXF_2_8_15:
19052         switch (extract32(ctx->opcode, 9, 3)) {
19053         case NM_DPAX_W_PH:
19054             check_dsp_r2(ctx);
19055             gen_helper_dpax_w_ph(t0, v0, v1, cpu_env);
19056             break;
19057         case NM_DPAQ_SA_L_W:
19058             check_dsp(ctx);
19059             gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env);
19060             break;
19061         case NM_DPSX_W_PH:
19062             check_dsp_r2(ctx);
19063             gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env);
19064             break;
19065         case NM_DPSQ_SA_L_W:
19066             check_dsp(ctx);
19067             gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env);
19068             break;
19069         default:
19070             generate_exception_end(ctx, EXCP_RI);
19071             break;
19072         }
19073         break;
19074     case NM_POOL32AXF_2_16_23:
19075         switch (extract32(ctx->opcode, 9, 3)) {
19076         case NM_DPAU_H_QBL:
19077             check_dsp(ctx);
19078             gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env);
19079             break;
19080         case NM_DPAQX_S_W_PH:
19081             check_dsp_r2(ctx);
19082             gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env);
19083             break;
19084         case NM_DPSU_H_QBL:
19085             check_dsp(ctx);
19086             gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env);
19087             break;
19088         case NM_DPSQX_S_W_PH:
19089             check_dsp_r2(ctx);
19090             gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env);
19091             break;
19092         case NM_MULSA_W_PH:
19093             check_dsp_r2(ctx);
19094             gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env);
19095             break;
19096         default:
19097             generate_exception_end(ctx, EXCP_RI);
19098             break;
19099         }
19100         break;
19101     case NM_POOL32AXF_2_24_31:
19102         switch (extract32(ctx->opcode, 9, 3)) {
19103         case NM_DPAU_H_QBR:
19104             check_dsp(ctx);
19105             gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env);
19106             break;
19107         case NM_DPAQX_SA_W_PH:
19108             check_dsp_r2(ctx);
19109             gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env);
19110             break;
19111         case NM_DPSU_H_QBR:
19112             check_dsp(ctx);
19113             gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env);
19114             break;
19115         case NM_DPSQX_SA_W_PH:
19116             check_dsp_r2(ctx);
19117             gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env);
19118             break;
19119         case NM_MULSAQ_S_W_PH:
19120             check_dsp(ctx);
19121             gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env);
19122             break;
19123         default:
19124             generate_exception_end(ctx, EXCP_RI);
19125             break;
19126         }
19127         break;
19128     default:
19129         generate_exception_end(ctx, EXCP_RI);
19130         break;
19131     }
19132
19133     tcg_temp_free_i32(t0);
19134 }
19135
19136 static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc,
19137                                           int rt, int rs, int rd)
19138 {
19139     int ret = rt;
19140     TCGv t0 = tcg_temp_new();
19141     TCGv t1 = tcg_temp_new();
19142     TCGv v0_t = tcg_temp_new();
19143     TCGv v1_t = tcg_temp_new();
19144
19145     gen_load_gpr(v0_t, rt);
19146     gen_load_gpr(v1_t, rs);
19147
19148     switch (opc) {
19149     case NM_POOL32AXF_2_0_7:
19150         switch (extract32(ctx->opcode, 9, 3)) {
19151         case NM_DPA_W_PH:
19152         case NM_DPAQ_S_W_PH:
19153         case NM_DPS_W_PH:
19154         case NM_DPSQ_S_W_PH:
19155             gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19156             break;
19157         case NM_BALIGN:
19158             check_dsp_r2(ctx);
19159             if (rt != 0) {
19160                 gen_load_gpr(t0, rs);
19161                 rd &= 3;
19162                 if (rd != 0 && rd != 2) {
19163                     tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd);
19164                     tcg_gen_ext32u_tl(t0, t0);
19165                     tcg_gen_shri_tl(t0, t0, 8 * (4 - rd));
19166                     tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
19167                 }
19168                 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
19169             }
19170             break;
19171         case NM_MADD:
19172             check_dsp(ctx);
19173             {
19174                 int acc = extract32(ctx->opcode, 14, 2);
19175                 TCGv_i64 t2 = tcg_temp_new_i64();
19176                 TCGv_i64 t3 = tcg_temp_new_i64();
19177
19178                 gen_load_gpr(t0, rt);
19179                 gen_load_gpr(t1, rs);
19180                 tcg_gen_ext_tl_i64(t2, t0);
19181                 tcg_gen_ext_tl_i64(t3, t1);
19182                 tcg_gen_mul_i64(t2, t2, t3);
19183                 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19184                 tcg_gen_add_i64(t2, t2, t3);
19185                 tcg_temp_free_i64(t3);
19186                 gen_move_low32(cpu_LO[acc], t2);
19187                 gen_move_high32(cpu_HI[acc], t2);
19188                 tcg_temp_free_i64(t2);
19189             }
19190             break;
19191         case NM_MULT:
19192             check_dsp(ctx);
19193             {
19194                 int acc = extract32(ctx->opcode, 14, 2);
19195                 TCGv_i32 t2 = tcg_temp_new_i32();
19196                 TCGv_i32 t3 = tcg_temp_new_i32();
19197
19198                 gen_load_gpr(t0, rs);
19199                 gen_load_gpr(t1, rt);
19200                 tcg_gen_trunc_tl_i32(t2, t0);
19201                 tcg_gen_trunc_tl_i32(t3, t1);
19202                 tcg_gen_muls2_i32(t2, t3, t2, t3);
19203                 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
19204                 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
19205                 tcg_temp_free_i32(t2);
19206                 tcg_temp_free_i32(t3);
19207             }
19208             break;
19209         case NM_EXTRV_W:
19210             check_dsp(ctx);
19211             gen_load_gpr(v1_t, rs);
19212             tcg_gen_movi_tl(t0, rd >> 3);
19213             gen_helper_extr_w(t0, t0, v1_t, cpu_env);
19214             gen_store_gpr(t0, ret);
19215             break;
19216         }
19217         break;
19218     case NM_POOL32AXF_2_8_15:
19219         switch (extract32(ctx->opcode, 9, 3)) {
19220         case NM_DPAX_W_PH:
19221         case NM_DPAQ_SA_L_W:
19222         case NM_DPSX_W_PH:
19223         case NM_DPSQ_SA_L_W:
19224             gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19225             break;
19226         case NM_MADDU:
19227             check_dsp(ctx);
19228             {
19229                 int acc = extract32(ctx->opcode, 14, 2);
19230                 TCGv_i64 t2 = tcg_temp_new_i64();
19231                 TCGv_i64 t3 = tcg_temp_new_i64();
19232
19233                 gen_load_gpr(t0, rs);
19234                 gen_load_gpr(t1, rt);
19235                 tcg_gen_ext32u_tl(t0, t0);
19236                 tcg_gen_ext32u_tl(t1, t1);
19237                 tcg_gen_extu_tl_i64(t2, t0);
19238                 tcg_gen_extu_tl_i64(t3, t1);
19239                 tcg_gen_mul_i64(t2, t2, t3);
19240                 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19241                 tcg_gen_add_i64(t2, t2, t3);
19242                 tcg_temp_free_i64(t3);
19243                 gen_move_low32(cpu_LO[acc], t2);
19244                 gen_move_high32(cpu_HI[acc], t2);
19245                 tcg_temp_free_i64(t2);
19246             }
19247             break;
19248         case NM_MULTU:
19249             check_dsp(ctx);
19250             {
19251                 int acc = extract32(ctx->opcode, 14, 2);
19252                 TCGv_i32 t2 = tcg_temp_new_i32();
19253                 TCGv_i32 t3 = tcg_temp_new_i32();
19254
19255                 gen_load_gpr(t0, rs);
19256                 gen_load_gpr(t1, rt);
19257                 tcg_gen_trunc_tl_i32(t2, t0);
19258                 tcg_gen_trunc_tl_i32(t3, t1);
19259                 tcg_gen_mulu2_i32(t2, t3, t2, t3);
19260                 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
19261                 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
19262                 tcg_temp_free_i32(t2);
19263                 tcg_temp_free_i32(t3);
19264             }
19265             break;
19266         case NM_EXTRV_R_W:
19267             check_dsp(ctx);
19268             tcg_gen_movi_tl(t0, rd >> 3);
19269             gen_helper_extr_r_w(t0, t0, v1_t, cpu_env);
19270             gen_store_gpr(t0, ret);
19271             break;
19272         default:
19273             generate_exception_end(ctx, EXCP_RI);
19274             break;
19275         }
19276         break;
19277     case NM_POOL32AXF_2_16_23:
19278         switch (extract32(ctx->opcode, 9, 3)) {
19279         case NM_DPAU_H_QBL:
19280         case NM_DPAQX_S_W_PH:
19281         case NM_DPSU_H_QBL:
19282         case NM_DPSQX_S_W_PH:
19283         case NM_MULSA_W_PH:
19284             gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19285             break;
19286         case NM_EXTPV:
19287             check_dsp(ctx);
19288             tcg_gen_movi_tl(t0, rd >> 3);
19289             gen_helper_extp(t0, t0, v1_t, cpu_env);
19290             gen_store_gpr(t0, ret);
19291             break;
19292         case NM_MSUB:
19293             check_dsp(ctx);
19294             {
19295                 int acc = extract32(ctx->opcode, 14, 2);
19296                 TCGv_i64 t2 = tcg_temp_new_i64();
19297                 TCGv_i64 t3 = tcg_temp_new_i64();
19298
19299                 gen_load_gpr(t0, rs);
19300                 gen_load_gpr(t1, rt);
19301                 tcg_gen_ext_tl_i64(t2, t0);
19302                 tcg_gen_ext_tl_i64(t3, t1);
19303                 tcg_gen_mul_i64(t2, t2, t3);
19304                 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19305                 tcg_gen_sub_i64(t2, t3, t2);
19306                 tcg_temp_free_i64(t3);
19307                 gen_move_low32(cpu_LO[acc], t2);
19308                 gen_move_high32(cpu_HI[acc], t2);
19309                 tcg_temp_free_i64(t2);
19310             }
19311             break;
19312         case NM_EXTRV_RS_W:
19313             check_dsp(ctx);
19314             tcg_gen_movi_tl(t0, rd >> 3);
19315             gen_helper_extr_rs_w(t0, t0, v1_t, cpu_env);
19316             gen_store_gpr(t0, ret);
19317             break;
19318         }
19319         break;
19320     case NM_POOL32AXF_2_24_31:
19321         switch (extract32(ctx->opcode, 9, 3)) {
19322         case NM_DPAU_H_QBR:
19323         case NM_DPAQX_SA_W_PH:
19324         case NM_DPSU_H_QBR:
19325         case NM_DPSQX_SA_W_PH:
19326         case NM_MULSAQ_S_W_PH:
19327             gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19328             break;
19329         case NM_EXTPDPV:
19330             check_dsp(ctx);
19331             tcg_gen_movi_tl(t0, rd >> 3);
19332             gen_helper_extpdp(t0, t0, v1_t, cpu_env);
19333             gen_store_gpr(t0, ret);
19334             break;
19335         case NM_MSUBU:
19336             check_dsp(ctx);
19337             {
19338                 int acc = extract32(ctx->opcode, 14, 2);
19339                 TCGv_i64 t2 = tcg_temp_new_i64();
19340                 TCGv_i64 t3 = tcg_temp_new_i64();
19341
19342                 gen_load_gpr(t0, rs);
19343                 gen_load_gpr(t1, rt);
19344                 tcg_gen_ext32u_tl(t0, t0);
19345                 tcg_gen_ext32u_tl(t1, t1);
19346                 tcg_gen_extu_tl_i64(t2, t0);
19347                 tcg_gen_extu_tl_i64(t3, t1);
19348                 tcg_gen_mul_i64(t2, t2, t3);
19349                 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19350                 tcg_gen_sub_i64(t2, t3, t2);
19351                 tcg_temp_free_i64(t3);
19352                 gen_move_low32(cpu_LO[acc], t2);
19353                 gen_move_high32(cpu_HI[acc], t2);
19354                 tcg_temp_free_i64(t2);
19355             }
19356             break;
19357         case NM_EXTRV_S_H:
19358             check_dsp(ctx);
19359             tcg_gen_movi_tl(t0, rd >> 3);
19360             gen_helper_extr_s_h(t0, t0, v0_t, cpu_env);
19361             gen_store_gpr(t0, ret);
19362             break;
19363         }
19364         break;
19365     default:
19366         generate_exception_end(ctx, EXCP_RI);
19367         break;
19368     }
19369
19370     tcg_temp_free(t0);
19371     tcg_temp_free(t1);
19372
19373     tcg_temp_free(v0_t);
19374     tcg_temp_free(v1_t);
19375 }
19376
19377 static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc,
19378                                           int rt, int rs)
19379 {
19380     int ret = rt;
19381     TCGv t0 = tcg_temp_new();
19382     TCGv v0_t = tcg_temp_new();
19383
19384     gen_load_gpr(v0_t, rs);
19385
19386     switch (opc) {
19387     case NM_ABSQ_S_QB:
19388         check_dsp_r2(ctx);
19389         gen_helper_absq_s_qb(v0_t, v0_t, cpu_env);
19390         gen_store_gpr(v0_t, ret);
19391         break;
19392     case NM_ABSQ_S_PH:
19393         check_dsp(ctx);
19394         gen_helper_absq_s_ph(v0_t, v0_t, cpu_env);
19395         gen_store_gpr(v0_t, ret);
19396         break;
19397     case NM_ABSQ_S_W:
19398         check_dsp(ctx);
19399         gen_helper_absq_s_w(v0_t, v0_t, cpu_env);
19400         gen_store_gpr(v0_t, ret);
19401         break;
19402     case NM_PRECEQ_W_PHL:
19403         check_dsp(ctx);
19404         tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000);
19405         tcg_gen_ext32s_tl(v0_t, v0_t);
19406         gen_store_gpr(v0_t, ret);
19407         break;
19408     case NM_PRECEQ_W_PHR:
19409         check_dsp(ctx);
19410         tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF);
19411         tcg_gen_shli_tl(v0_t, v0_t, 16);
19412         tcg_gen_ext32s_tl(v0_t, v0_t);
19413         gen_store_gpr(v0_t, ret);
19414         break;
19415     case NM_PRECEQU_PH_QBL:
19416         check_dsp(ctx);
19417         gen_helper_precequ_ph_qbl(v0_t, v0_t);
19418         gen_store_gpr(v0_t, ret);
19419         break;
19420     case NM_PRECEQU_PH_QBR:
19421         check_dsp(ctx);
19422         gen_helper_precequ_ph_qbr(v0_t, v0_t);
19423         gen_store_gpr(v0_t, ret);
19424         break;
19425     case NM_PRECEQU_PH_QBLA:
19426         check_dsp(ctx);
19427         gen_helper_precequ_ph_qbla(v0_t, v0_t);
19428         gen_store_gpr(v0_t, ret);
19429         break;
19430     case NM_PRECEQU_PH_QBRA:
19431         check_dsp(ctx);
19432         gen_helper_precequ_ph_qbra(v0_t, v0_t);
19433         gen_store_gpr(v0_t, ret);
19434         break;
19435     case NM_PRECEU_PH_QBL:
19436         check_dsp(ctx);
19437         gen_helper_preceu_ph_qbl(v0_t, v0_t);
19438         gen_store_gpr(v0_t, ret);
19439         break;
19440     case NM_PRECEU_PH_QBR:
19441         check_dsp(ctx);
19442         gen_helper_preceu_ph_qbr(v0_t, v0_t);
19443         gen_store_gpr(v0_t, ret);
19444         break;
19445     case NM_PRECEU_PH_QBLA:
19446         check_dsp(ctx);
19447         gen_helper_preceu_ph_qbla(v0_t, v0_t);
19448         gen_store_gpr(v0_t, ret);
19449         break;
19450     case NM_PRECEU_PH_QBRA:
19451         check_dsp(ctx);
19452         gen_helper_preceu_ph_qbra(v0_t, v0_t);
19453         gen_store_gpr(v0_t, ret);
19454         break;
19455     case NM_REPLV_PH:
19456         check_dsp(ctx);
19457         tcg_gen_ext16u_tl(v0_t, v0_t);
19458         tcg_gen_shli_tl(t0, v0_t, 16);
19459         tcg_gen_or_tl(v0_t, v0_t, t0);
19460         tcg_gen_ext32s_tl(v0_t, v0_t);
19461         gen_store_gpr(v0_t, ret);
19462         break;
19463     case NM_REPLV_QB:
19464         check_dsp(ctx);
19465         tcg_gen_ext8u_tl(v0_t, v0_t);
19466         tcg_gen_shli_tl(t0, v0_t, 8);
19467         tcg_gen_or_tl(v0_t, v0_t, t0);
19468         tcg_gen_shli_tl(t0, v0_t, 16);
19469         tcg_gen_or_tl(v0_t, v0_t, t0);
19470         tcg_gen_ext32s_tl(v0_t, v0_t);
19471         gen_store_gpr(v0_t, ret);
19472         break;
19473     case NM_BITREV:
19474         check_dsp(ctx);
19475         gen_helper_bitrev(v0_t, v0_t);
19476         gen_store_gpr(v0_t, ret);
19477         break;
19478     case NM_INSV:
19479         check_dsp(ctx);
19480         {
19481             TCGv tv0 = tcg_temp_new();
19482
19483             gen_load_gpr(tv0, rt);
19484             gen_helper_insv(v0_t, cpu_env, v0_t, tv0);
19485             gen_store_gpr(v0_t, ret);
19486             tcg_temp_free(tv0);
19487         }
19488         break;
19489     case NM_RADDU_W_QB:
19490         check_dsp(ctx);
19491         gen_helper_raddu_w_qb(v0_t, v0_t);
19492         gen_store_gpr(v0_t, ret);
19493         break;
19494     case NM_BITSWAP:
19495         gen_bitswap(ctx, OPC_BITSWAP, ret, rs);
19496         break;
19497     case NM_CLO:
19498         check_nms(ctx);
19499         gen_cl(ctx, OPC_CLO, ret, rs);
19500         break;
19501     case NM_CLZ:
19502         check_nms(ctx);
19503         gen_cl(ctx, OPC_CLZ, ret, rs);
19504         break;
19505     case NM_WSBH:
19506         gen_bshfl(ctx, OPC_WSBH, ret, rs);
19507         break;
19508     default:
19509         generate_exception_end(ctx, EXCP_RI);
19510         break;
19511     }
19512
19513     tcg_temp_free(v0_t);
19514     tcg_temp_free(t0);
19515 }
19516
19517 static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc,
19518                                           int rt, int rs, int rd)
19519 {
19520     TCGv t0 = tcg_temp_new();
19521     TCGv rs_t = tcg_temp_new();
19522
19523     gen_load_gpr(rs_t, rs);
19524
19525     switch (opc) {
19526     case NM_SHRA_R_QB:
19527         check_dsp_r2(ctx);
19528         tcg_gen_movi_tl(t0, rd >> 2);
19529         switch (extract32(ctx->opcode, 12, 1)) {
19530         case 0:
19531             /* NM_SHRA_QB */
19532             gen_helper_shra_qb(t0, t0, rs_t);
19533             gen_store_gpr(t0, rt);
19534             break;
19535         case 1:
19536             /* NM_SHRA_R_QB */
19537             gen_helper_shra_r_qb(t0, t0, rs_t);
19538             gen_store_gpr(t0, rt);
19539             break;
19540         }
19541         break;
19542     case NM_SHRL_PH:
19543         check_dsp_r2(ctx);
19544         tcg_gen_movi_tl(t0, rd >> 1);
19545         gen_helper_shrl_ph(t0, t0, rs_t);
19546         gen_store_gpr(t0, rt);
19547         break;
19548     case NM_REPL_QB:
19549         check_dsp(ctx);
19550         {
19551             int16_t imm;
19552             target_long result;
19553             imm = extract32(ctx->opcode, 13, 8);
19554             result = (uint32_t)imm << 24 |
19555                      (uint32_t)imm << 16 |
19556                      (uint32_t)imm << 8  |
19557                      (uint32_t)imm;
19558             result = (int32_t)result;
19559             tcg_gen_movi_tl(t0, result);
19560             gen_store_gpr(t0, rt);
19561         }
19562         break;
19563     default:
19564         generate_exception_end(ctx, EXCP_RI);
19565         break;
19566     }
19567     tcg_temp_free(t0);
19568     tcg_temp_free(rs_t);
19569 }
19570
19571
19572 static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
19573 {
19574     int rt = extract32(ctx->opcode, 21, 5);
19575     int rs = extract32(ctx->opcode, 16, 5);
19576     int rd = extract32(ctx->opcode, 11, 5);
19577
19578     switch (extract32(ctx->opcode, 6, 3)) {
19579     case NM_POOL32AXF_1:
19580         {
19581             int32_t op1 = extract32(ctx->opcode, 9, 3);
19582             gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd);
19583         }
19584         break;
19585     case NM_POOL32AXF_2:
19586         {
19587             int32_t op1 = extract32(ctx->opcode, 12, 2);
19588             gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd);
19589         }
19590         break;
19591     case NM_POOL32AXF_4:
19592         {
19593             int32_t op1 = extract32(ctx->opcode, 9, 7);
19594             gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs);
19595         }
19596         break;
19597     case NM_POOL32AXF_5:
19598         switch (extract32(ctx->opcode, 9, 7)) {
19599 #ifndef CONFIG_USER_ONLY
19600         case NM_TLBP:
19601             gen_cp0(env, ctx, OPC_TLBP, 0, 0);
19602             break;
19603         case NM_TLBR:
19604             gen_cp0(env, ctx, OPC_TLBR, 0, 0);
19605             break;
19606         case NM_TLBWI:
19607             gen_cp0(env, ctx, OPC_TLBWI, 0, 0);
19608             break;
19609         case NM_TLBWR:
19610             gen_cp0(env, ctx, OPC_TLBWR, 0, 0);
19611             break;
19612         case NM_TLBINV:
19613             gen_cp0(env, ctx, OPC_TLBINV, 0, 0);
19614             break;
19615         case NM_TLBINVF:
19616             gen_cp0(env, ctx, OPC_TLBINVF, 0, 0);
19617             break;
19618         case NM_DI:
19619             check_cp0_enabled(ctx);
19620             {
19621                 TCGv t0 = tcg_temp_new();
19622
19623                 save_cpu_state(ctx, 1);
19624                 gen_helper_di(t0, cpu_env);
19625                 gen_store_gpr(t0, rt);
19626             /* Stop translation as we may have switched the execution mode */
19627                 ctx->base.is_jmp = DISAS_STOP;
19628                 tcg_temp_free(t0);
19629             }
19630             break;
19631         case NM_EI:
19632             check_cp0_enabled(ctx);
19633             {
19634                 TCGv t0 = tcg_temp_new();
19635
19636                 save_cpu_state(ctx, 1);
19637                 gen_helper_ei(t0, cpu_env);
19638                 gen_store_gpr(t0, rt);
19639             /* Stop translation as we may have switched the execution mode */
19640                 ctx->base.is_jmp = DISAS_STOP;
19641                 tcg_temp_free(t0);
19642             }
19643             break;
19644         case NM_RDPGPR:
19645             gen_load_srsgpr(rs, rt);
19646             break;
19647         case NM_WRPGPR:
19648             gen_store_srsgpr(rs, rt);
19649             break;
19650         case NM_WAIT:
19651             gen_cp0(env, ctx, OPC_WAIT, 0, 0);
19652             break;
19653         case NM_DERET:
19654             gen_cp0(env, ctx, OPC_DERET, 0, 0);
19655             break;
19656         case NM_ERETX:
19657             gen_cp0(env, ctx, OPC_ERET, 0, 0);
19658             break;
19659 #endif
19660         default:
19661             generate_exception_end(ctx, EXCP_RI);
19662             break;
19663         }
19664         break;
19665     case NM_POOL32AXF_7:
19666         {
19667             int32_t op1 = extract32(ctx->opcode, 9, 3);
19668             gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd);
19669         }
19670         break;
19671     default:
19672         generate_exception_end(ctx, EXCP_RI);
19673         break;
19674     }
19675 }
19676
19677 /* Immediate Value Compact Branches */
19678 static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc,
19679                                    int rt, int32_t imm, int32_t offset)
19680 {
19681     TCGCond cond;
19682     int bcond_compute = 0;
19683     TCGv t0 = tcg_temp_new();
19684     TCGv t1 = tcg_temp_new();
19685
19686     gen_load_gpr(t0, rt);
19687     tcg_gen_movi_tl(t1, imm);
19688     ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19689
19690     /* Load needed operands and calculate btarget */
19691     switch (opc) {
19692     case NM_BEQIC:
19693         if (rt == 0 && imm == 0) {
19694             /* Unconditional branch */
19695         } else if (rt == 0 && imm != 0) {
19696             /* Treat as NOP */
19697             goto out;
19698         } else {
19699             bcond_compute = 1;
19700             cond = TCG_COND_EQ;
19701         }
19702         break;
19703     case NM_BBEQZC:
19704     case NM_BBNEZC:
19705         check_nms(ctx);
19706         if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) {
19707             generate_exception_end(ctx, EXCP_RI);
19708             goto out;
19709         } else if (rt == 0 && opc == NM_BBEQZC) {
19710             /* Unconditional branch */
19711         } else if (rt == 0 && opc == NM_BBNEZC) {
19712             /* Treat as NOP */
19713             goto out;
19714         } else {
19715             tcg_gen_shri_tl(t0, t0, imm);
19716             tcg_gen_andi_tl(t0, t0, 1);
19717             tcg_gen_movi_tl(t1, 0);
19718             bcond_compute = 1;
19719             if (opc == NM_BBEQZC) {
19720                 cond = TCG_COND_EQ;
19721             } else {
19722                 cond = TCG_COND_NE;
19723             }
19724         }
19725         break;
19726     case NM_BNEIC:
19727         if (rt == 0 && imm == 0) {
19728             /* Treat as NOP */
19729             goto out;
19730         } else if (rt == 0 && imm != 0) {
19731             /* Unconditional branch */
19732         } else {
19733             bcond_compute = 1;
19734             cond = TCG_COND_NE;
19735         }
19736         break;
19737     case NM_BGEIC:
19738         if (rt == 0 && imm == 0) {
19739             /* Unconditional branch */
19740         } else  {
19741             bcond_compute = 1;
19742             cond = TCG_COND_GE;
19743         }
19744         break;
19745     case NM_BLTIC:
19746         bcond_compute = 1;
19747         cond = TCG_COND_LT;
19748         break;
19749     case NM_BGEIUC:
19750         if (rt == 0 && imm == 0) {
19751             /* Unconditional branch */
19752         } else  {
19753             bcond_compute = 1;
19754             cond = TCG_COND_GEU;
19755         }
19756         break;
19757     case NM_BLTIUC:
19758         bcond_compute = 1;
19759         cond = TCG_COND_LTU;
19760         break;
19761     default:
19762         MIPS_INVAL("Immediate Value Compact branch");
19763         generate_exception_end(ctx, EXCP_RI);
19764         goto out;
19765     }
19766
19767     if (bcond_compute == 0) {
19768         /* Uncoditional compact branch */
19769         gen_goto_tb(ctx, 0, ctx->btarget);
19770     } else {
19771         /* Conditional compact branch */
19772         TCGLabel *fs = gen_new_label();
19773
19774         tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs);
19775
19776         gen_goto_tb(ctx, 1, ctx->btarget);
19777         gen_set_label(fs);
19778
19779         gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19780     }
19781
19782 out:
19783     tcg_temp_free(t0);
19784     tcg_temp_free(t1);
19785 }
19786
19787 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
19788 static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs,
19789                                                 int rt)
19790 {
19791     TCGv t0 = tcg_temp_new();
19792     TCGv t1 = tcg_temp_new();
19793
19794     /* load rs */
19795     gen_load_gpr(t0, rs);
19796
19797     /* link */
19798     if (rt != 0) {
19799         tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4);
19800     }
19801
19802     /* calculate btarget */
19803     tcg_gen_shli_tl(t0, t0, 1);
19804     tcg_gen_movi_tl(t1, ctx->base.pc_next + 4);
19805     gen_op_addr_add(ctx, btarget, t1, t0);
19806
19807     /* unconditional branch to register */
19808     tcg_gen_mov_tl(cpu_PC, btarget);
19809     tcg_gen_lookup_and_goto_ptr();
19810
19811     tcg_temp_free(t0);
19812     tcg_temp_free(t1);
19813 }
19814
19815 /* nanoMIPS Branches */
19816 static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc,
19817                                        int rs, int rt, int32_t offset)
19818 {
19819     int bcond_compute = 0;
19820     TCGv t0 = tcg_temp_new();
19821     TCGv t1 = tcg_temp_new();
19822
19823     /* Load needed operands and calculate btarget */
19824     switch (opc) {
19825     /* compact branch */
19826     case OPC_BGEC:
19827     case OPC_BLTC:
19828         gen_load_gpr(t0, rs);
19829         gen_load_gpr(t1, rt);
19830         bcond_compute = 1;
19831         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19832         break;
19833     case OPC_BGEUC:
19834     case OPC_BLTUC:
19835         if (rs == 0 || rs == rt) {
19836             /* OPC_BLEZALC, OPC_BGEZALC */
19837             /* OPC_BGTZALC, OPC_BLTZALC */
19838             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4);
19839         }
19840         gen_load_gpr(t0, rs);
19841         gen_load_gpr(t1, rt);
19842         bcond_compute = 1;
19843         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19844         break;
19845     case OPC_BC:
19846         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19847         break;
19848     case OPC_BEQZC:
19849         if (rs != 0) {
19850             /* OPC_BEQZC, OPC_BNEZC */
19851             gen_load_gpr(t0, rs);
19852             bcond_compute = 1;
19853             ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19854         } else {
19855             /* OPC_JIC, OPC_JIALC */
19856             TCGv tbase = tcg_temp_new();
19857             TCGv toffset = tcg_temp_new();
19858
19859             gen_load_gpr(tbase, rt);
19860             tcg_gen_movi_tl(toffset, offset);
19861             gen_op_addr_add(ctx, btarget, tbase, toffset);
19862             tcg_temp_free(tbase);
19863             tcg_temp_free(toffset);
19864         }
19865         break;
19866     default:
19867         MIPS_INVAL("Compact branch/jump");
19868         generate_exception_end(ctx, EXCP_RI);
19869         goto out;
19870     }
19871
19872     if (bcond_compute == 0) {
19873         /* Uncoditional compact branch */
19874         switch (opc) {
19875         case OPC_BC:
19876             gen_goto_tb(ctx, 0, ctx->btarget);
19877             break;
19878         default:
19879             MIPS_INVAL("Compact branch/jump");
19880             generate_exception_end(ctx, EXCP_RI);
19881             goto out;
19882         }
19883     } else {
19884         /* Conditional compact branch */
19885         TCGLabel *fs = gen_new_label();
19886
19887         switch (opc) {
19888         case OPC_BGEUC:
19889             if (rs == 0 && rt != 0) {
19890                 /* OPC_BLEZALC */
19891                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19892             } else if (rs != 0 && rt != 0 && rs == rt) {
19893                 /* OPC_BGEZALC */
19894                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19895             } else {
19896                 /* OPC_BGEUC */
19897                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
19898             }
19899             break;
19900         case OPC_BLTUC:
19901             if (rs == 0 && rt != 0) {
19902                 /* OPC_BGTZALC */
19903                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19904             } else if (rs != 0 && rt != 0 && rs == rt) {
19905                 /* OPC_BLTZALC */
19906                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19907             } else {
19908                 /* OPC_BLTUC */
19909                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
19910             }
19911             break;
19912         case OPC_BGEC:
19913             if (rs == 0 && rt != 0) {
19914                 /* OPC_BLEZC */
19915                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19916             } else if (rs != 0 && rt != 0 && rs == rt) {
19917                 /* OPC_BGEZC */
19918                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19919             } else {
19920                 /* OPC_BGEC */
19921                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
19922             }
19923             break;
19924         case OPC_BLTC:
19925             if (rs == 0 && rt != 0) {
19926                 /* OPC_BGTZC */
19927                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19928             } else if (rs != 0 && rt != 0 && rs == rt) {
19929                 /* OPC_BLTZC */
19930                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19931             } else {
19932                 /* OPC_BLTC */
19933                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
19934             }
19935             break;
19936         case OPC_BEQZC:
19937             tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
19938             break;
19939         default:
19940             MIPS_INVAL("Compact conditional branch/jump");
19941             generate_exception_end(ctx, EXCP_RI);
19942             goto out;
19943         }
19944
19945         /* Generating branch here as compact branches don't have delay slot */
19946         gen_goto_tb(ctx, 1, ctx->btarget);
19947         gen_set_label(fs);
19948
19949         gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19950     }
19951
19952 out:
19953     tcg_temp_free(t0);
19954     tcg_temp_free(t1);
19955 }
19956
19957
19958 /* nanoMIPS CP1 Branches */
19959 static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op,
19960                                    int32_t ft, int32_t offset)
19961 {
19962     target_ulong btarget;
19963     TCGv_i64 t0 = tcg_temp_new_i64();
19964
19965     gen_load_fpr64(ctx, t0, ft);
19966     tcg_gen_andi_i64(t0, t0, 1);
19967
19968     btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19969
19970     switch (op) {
19971     case NM_BC1EQZC:
19972         tcg_gen_xori_i64(t0, t0, 1);
19973         ctx->hflags |= MIPS_HFLAG_BC;
19974         break;
19975     case NM_BC1NEZC:
19976         /* t0 already set */
19977         ctx->hflags |= MIPS_HFLAG_BC;
19978         break;
19979     default:
19980         MIPS_INVAL("cp1 cond branch");
19981         generate_exception_end(ctx, EXCP_RI);
19982         goto out;
19983     }
19984
19985     tcg_gen_trunc_i64_tl(bcond, t0);
19986
19987     ctx->btarget = btarget;
19988
19989 out:
19990     tcg_temp_free_i64(t0);
19991 }
19992
19993
19994 static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt)
19995 {
19996     TCGv t0, t1;
19997     t0 = tcg_temp_new();
19998     t1 = tcg_temp_new();
19999
20000     gen_load_gpr(t0, rs);
20001     gen_load_gpr(t1, rt);
20002
20003     if ((extract32(ctx->opcode, 6, 1)) == 1) {
20004         /* PP.LSXS instructions require shifting */
20005         switch (extract32(ctx->opcode, 7, 4)) {
20006         case NM_SHXS:
20007             check_nms(ctx);
20008         case NM_LHXS:
20009         case NM_LHUXS:
20010             tcg_gen_shli_tl(t0, t0, 1);
20011             break;
20012         case NM_SWXS:
20013             check_nms(ctx);
20014         case NM_LWXS:
20015         case NM_LWC1XS:
20016         case NM_SWC1XS:
20017             tcg_gen_shli_tl(t0, t0, 2);
20018             break;
20019         case NM_LDC1XS:
20020         case NM_SDC1XS:
20021             tcg_gen_shli_tl(t0, t0, 3);
20022             break;
20023         }
20024     }
20025     gen_op_addr_add(ctx, t0, t0, t1);
20026
20027     switch (extract32(ctx->opcode, 7, 4)) {
20028     case NM_LBX:
20029         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20030                            MO_SB);
20031         gen_store_gpr(t0, rd);
20032         break;
20033     case NM_LHX:
20034     /*case NM_LHXS:*/
20035         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20036                            MO_TESW);
20037         gen_store_gpr(t0, rd);
20038         break;
20039     case NM_LWX:
20040     /*case NM_LWXS:*/
20041         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20042                            MO_TESL);
20043         gen_store_gpr(t0, rd);
20044         break;
20045     case NM_LBUX:
20046         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20047                            MO_UB);
20048         gen_store_gpr(t0, rd);
20049         break;
20050     case NM_LHUX:
20051     /*case NM_LHUXS:*/
20052         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20053                            MO_TEUW);
20054         gen_store_gpr(t0, rd);
20055         break;
20056     case NM_SBX:
20057         check_nms(ctx);
20058         gen_load_gpr(t1, rd);
20059         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20060                            MO_8);
20061         break;
20062     case NM_SHX:
20063     /*case NM_SHXS:*/
20064         check_nms(ctx);
20065         gen_load_gpr(t1, rd);
20066         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20067                            MO_TEUW);
20068         break;
20069     case NM_SWX:
20070     /*case NM_SWXS:*/
20071         check_nms(ctx);
20072         gen_load_gpr(t1, rd);
20073         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20074                            MO_TEUL);
20075         break;
20076     case NM_LWC1X:
20077     /*case NM_LWC1XS:*/
20078     case NM_LDC1X:
20079     /*case NM_LDC1XS:*/
20080     case NM_SWC1X:
20081     /*case NM_SWC1XS:*/
20082     case NM_SDC1X:
20083     /*case NM_SDC1XS:*/
20084         if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
20085             check_cp1_enabled(ctx);
20086             switch (extract32(ctx->opcode, 7, 4)) {
20087             case NM_LWC1X:
20088             /*case NM_LWC1XS:*/
20089                 gen_flt_ldst(ctx, OPC_LWC1, rd, t0);
20090                 break;
20091             case NM_LDC1X:
20092             /*case NM_LDC1XS:*/
20093                 gen_flt_ldst(ctx, OPC_LDC1, rd, t0);
20094                 break;
20095             case NM_SWC1X:
20096             /*case NM_SWC1XS:*/
20097                 gen_flt_ldst(ctx, OPC_SWC1, rd, t0);
20098                 break;
20099             case NM_SDC1X:
20100             /*case NM_SDC1XS:*/
20101                 gen_flt_ldst(ctx, OPC_SDC1, rd, t0);
20102                 break;
20103             }
20104         } else {
20105             generate_exception_err(ctx, EXCP_CpU, 1);
20106         }
20107         break;
20108     default:
20109         generate_exception_end(ctx, EXCP_RI);
20110         break;
20111     }
20112
20113     tcg_temp_free(t0);
20114     tcg_temp_free(t1);
20115 }
20116
20117 static void gen_pool32f_nanomips_insn(DisasContext *ctx)
20118 {
20119     int rt, rs, rd;
20120
20121     rt = extract32(ctx->opcode, 21, 5);
20122     rs = extract32(ctx->opcode, 16, 5);
20123     rd = extract32(ctx->opcode, 11, 5);
20124
20125     if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) {
20126         generate_exception_end(ctx, EXCP_RI);
20127         return;
20128     }
20129     check_cp1_enabled(ctx);
20130     switch (extract32(ctx->opcode, 0, 3)) {
20131     case NM_POOL32F_0:
20132         switch (extract32(ctx->opcode, 3, 7)) {
20133         case NM_RINT_S:
20134             gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
20135             break;
20136         case NM_RINT_D:
20137             gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
20138             break;
20139         case NM_CLASS_S:
20140             gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
20141             break;
20142         case NM_CLASS_D:
20143             gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
20144             break;
20145         case NM_ADD_S:
20146             gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0);
20147             break;
20148         case NM_ADD_D:
20149             gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0);
20150             break;
20151         case NM_SUB_S:
20152             gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0);
20153             break;
20154         case NM_SUB_D:
20155             gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0);
20156             break;
20157         case NM_MUL_S:
20158             gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0);
20159             break;
20160         case NM_MUL_D:
20161             gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0);
20162             break;
20163         case NM_DIV_S:
20164             gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0);
20165             break;
20166         case NM_DIV_D:
20167             gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0);
20168             break;
20169         case NM_SELEQZ_S:
20170             gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
20171             break;
20172         case NM_SELEQZ_D:
20173             gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
20174             break;
20175         case NM_SELNEZ_S:
20176             gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
20177             break;
20178         case NM_SELNEZ_D:
20179             gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
20180             break;
20181         case NM_SEL_S:
20182             gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
20183             break;
20184         case NM_SEL_D:
20185             gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
20186             break;
20187         case NM_MADDF_S:
20188             gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0);
20189             break;
20190         case NM_MADDF_D:
20191             gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0);
20192             break;
20193         case NM_MSUBF_S:
20194             gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0);
20195             break;
20196         case NM_MSUBF_D:
20197             gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0);
20198             break;
20199         default:
20200             generate_exception_end(ctx, EXCP_RI);
20201             break;
20202         }
20203         break;
20204     case NM_POOL32F_3:
20205         switch (extract32(ctx->opcode, 3, 3)) {
20206         case NM_MIN_FMT:
20207             switch (extract32(ctx->opcode, 9, 1)) {
20208             case FMT_SDPS_S:
20209                 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
20210                 break;
20211             case FMT_SDPS_D:
20212                 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
20213                 break;
20214             }
20215             break;
20216         case NM_MAX_FMT:
20217             switch (extract32(ctx->opcode, 9, 1)) {
20218             case FMT_SDPS_S:
20219                 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
20220                 break;
20221             case FMT_SDPS_D:
20222                 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
20223                 break;
20224             }
20225             break;
20226         case NM_MINA_FMT:
20227             switch (extract32(ctx->opcode, 9, 1)) {
20228             case FMT_SDPS_S:
20229                 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
20230                 break;
20231             case FMT_SDPS_D:
20232                 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
20233                 break;
20234             }
20235             break;
20236         case NM_MAXA_FMT:
20237             switch (extract32(ctx->opcode, 9, 1)) {
20238             case FMT_SDPS_S:
20239                 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
20240                 break;
20241             case FMT_SDPS_D:
20242                 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
20243                 break;
20244             }
20245             break;
20246         case NM_POOL32FXF:
20247             switch (extract32(ctx->opcode, 6, 8)) {
20248             case NM_CFC1:
20249                 gen_cp1(ctx, OPC_CFC1, rt, rs);
20250                 break;
20251             case NM_CTC1:
20252                 gen_cp1(ctx, OPC_CTC1, rt, rs);
20253                 break;
20254             case NM_MFC1:
20255                 gen_cp1(ctx, OPC_MFC1, rt, rs);
20256                 break;
20257             case NM_MTC1:
20258                 gen_cp1(ctx, OPC_MTC1, rt, rs);
20259                 break;
20260             case NM_MFHC1:
20261                 gen_cp1(ctx, OPC_MFHC1, rt, rs);
20262                 break;
20263             case NM_MTHC1:
20264                 gen_cp1(ctx, OPC_MTHC1, rt, rs);
20265                 break;
20266             case NM_CVT_S_PL:
20267                 gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0);
20268                 break;
20269             case NM_CVT_S_PU:
20270                 gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0);
20271                 break;
20272             default:
20273                 switch (extract32(ctx->opcode, 6, 9)) {
20274                 case NM_CVT_L_S:
20275                     gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0);
20276                     break;
20277                 case NM_CVT_L_D:
20278                     gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0);
20279                     break;
20280                 case NM_CVT_W_S:
20281                     gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0);
20282                     break;
20283                 case NM_CVT_W_D:
20284                     gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0);
20285                     break;
20286                 case NM_RSQRT_S:
20287                     gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0);
20288                     break;
20289                 case NM_RSQRT_D:
20290                     gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0);
20291                     break;
20292                 case NM_SQRT_S:
20293                     gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0);
20294                     break;
20295                 case NM_SQRT_D:
20296                     gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0);
20297                     break;
20298                 case NM_RECIP_S:
20299                     gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0);
20300                     break;
20301                 case NM_RECIP_D:
20302                     gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0);
20303                     break;
20304                 case NM_FLOOR_L_S:
20305                     gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0);
20306                     break;
20307                 case NM_FLOOR_L_D:
20308                     gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0);
20309                     break;
20310                 case NM_FLOOR_W_S:
20311                     gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0);
20312                     break;
20313                 case NM_FLOOR_W_D:
20314                     gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0);
20315                     break;
20316                 case NM_CEIL_L_S:
20317                     gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0);
20318                     break;
20319                 case NM_CEIL_L_D:
20320                     gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0);
20321                     break;
20322                 case NM_CEIL_W_S:
20323                     gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0);
20324                     break;
20325                 case NM_CEIL_W_D:
20326                     gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0);
20327                     break;
20328                 case NM_TRUNC_L_S:
20329                     gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0);
20330                     break;
20331                 case NM_TRUNC_L_D:
20332                     gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0);
20333                     break;
20334                 case NM_TRUNC_W_S:
20335                     gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0);
20336                     break;
20337                 case NM_TRUNC_W_D:
20338                     gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0);
20339                     break;
20340                 case NM_ROUND_L_S:
20341                     gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0);
20342                     break;
20343                 case NM_ROUND_L_D:
20344                     gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0);
20345                     break;
20346                 case NM_ROUND_W_S:
20347                     gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0);
20348                     break;
20349                 case NM_ROUND_W_D:
20350                     gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0);
20351                     break;
20352                 case NM_MOV_S:
20353                     gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0);
20354                     break;
20355                 case NM_MOV_D:
20356                     gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0);
20357                     break;
20358                 case NM_ABS_S:
20359                     gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0);
20360                     break;
20361                 case NM_ABS_D:
20362                     gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0);
20363                     break;
20364                 case NM_NEG_S:
20365                     gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0);
20366                     break;
20367                 case NM_NEG_D:
20368                     gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0);
20369                     break;
20370                 case NM_CVT_D_S:
20371                     gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0);
20372                     break;
20373                 case NM_CVT_D_W:
20374                     gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0);
20375                     break;
20376                 case NM_CVT_D_L:
20377                     gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0);
20378                     break;
20379                 case NM_CVT_S_D:
20380                     gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0);
20381                     break;
20382                 case NM_CVT_S_W:
20383                     gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0);
20384                     break;
20385                 case NM_CVT_S_L:
20386                     gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0);
20387                     break;
20388                 default:
20389                     generate_exception_end(ctx, EXCP_RI);
20390                     break;
20391                 }
20392                 break;
20393             }
20394             break;
20395         }
20396         break;
20397     case NM_POOL32F_5:
20398         switch (extract32(ctx->opcode, 3, 3)) {
20399         case NM_CMP_CONDN_S:
20400             gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20401             break;
20402         case NM_CMP_CONDN_D:
20403             gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20404             break;
20405         default:
20406             generate_exception_end(ctx, EXCP_RI);
20407             break;
20408         }
20409         break;
20410     default:
20411         generate_exception_end(ctx, EXCP_RI);
20412         break;
20413     }
20414 }
20415
20416 static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc,
20417                                        int rd, int rs, int rt)
20418 {
20419     int ret = rd;
20420     TCGv t0 = tcg_temp_new();
20421     TCGv v1_t = tcg_temp_new();
20422     TCGv v2_t = tcg_temp_new();
20423
20424     gen_load_gpr(v1_t, rs);
20425     gen_load_gpr(v2_t, rt);
20426
20427     switch (opc) {
20428     case NM_CMP_EQ_PH:
20429         check_dsp(ctx);
20430         gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
20431         break;
20432     case NM_CMP_LT_PH:
20433         check_dsp(ctx);
20434         gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
20435         break;
20436     case NM_CMP_LE_PH:
20437         check_dsp(ctx);
20438         gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
20439         break;
20440     case NM_CMPU_EQ_QB:
20441         check_dsp(ctx);
20442         gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
20443         break;
20444     case NM_CMPU_LT_QB:
20445         check_dsp(ctx);
20446         gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
20447         break;
20448     case NM_CMPU_LE_QB:
20449         check_dsp(ctx);
20450         gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
20451         break;
20452     case NM_CMPGU_EQ_QB:
20453         check_dsp(ctx);
20454         gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20455         gen_store_gpr(v1_t, ret);
20456         break;
20457     case NM_CMPGU_LT_QB:
20458         check_dsp(ctx);
20459         gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20460         gen_store_gpr(v1_t, ret);
20461         break;
20462     case NM_CMPGU_LE_QB:
20463         check_dsp(ctx);
20464         gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20465         gen_store_gpr(v1_t, ret);
20466         break;
20467     case NM_CMPGDU_EQ_QB:
20468         check_dsp_r2(ctx);
20469         gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20470         tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20471         gen_store_gpr(v1_t, ret);
20472         break;
20473     case NM_CMPGDU_LT_QB:
20474         check_dsp_r2(ctx);
20475         gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20476         tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20477         gen_store_gpr(v1_t, ret);
20478         break;
20479     case NM_CMPGDU_LE_QB:
20480         check_dsp_r2(ctx);
20481         gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20482         tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20483         gen_store_gpr(v1_t, ret);
20484         break;
20485     case NM_PACKRL_PH:
20486         check_dsp(ctx);
20487         gen_helper_packrl_ph(v1_t, v1_t, v2_t);
20488         gen_store_gpr(v1_t, ret);
20489         break;
20490     case NM_PICK_QB:
20491         check_dsp(ctx);
20492         gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env);
20493         gen_store_gpr(v1_t, ret);
20494         break;
20495     case NM_PICK_PH:
20496         check_dsp(ctx);
20497         gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env);
20498         gen_store_gpr(v1_t, ret);
20499         break;
20500     case NM_ADDQ_S_W:
20501         check_dsp(ctx);
20502         gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env);
20503         gen_store_gpr(v1_t, ret);
20504         break;
20505     case NM_SUBQ_S_W:
20506         check_dsp(ctx);
20507         gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env);
20508         gen_store_gpr(v1_t, ret);
20509         break;
20510     case NM_ADDSC:
20511         check_dsp(ctx);
20512         gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env);
20513         gen_store_gpr(v1_t, ret);
20514         break;
20515     case NM_ADDWC:
20516         check_dsp(ctx);
20517         gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env);
20518         gen_store_gpr(v1_t, ret);
20519         break;
20520     case NM_ADDQ_S_PH:
20521         check_dsp(ctx);
20522         switch (extract32(ctx->opcode, 10, 1)) {
20523         case 0:
20524             /* ADDQ_PH */
20525             gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env);
20526             gen_store_gpr(v1_t, ret);
20527             break;
20528         case 1:
20529             /* ADDQ_S_PH */
20530             gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20531             gen_store_gpr(v1_t, ret);
20532             break;
20533         }
20534         break;
20535     case NM_ADDQH_R_PH:
20536         check_dsp_r2(ctx);
20537         switch (extract32(ctx->opcode, 10, 1)) {
20538         case 0:
20539             /* ADDQH_PH */
20540             gen_helper_addqh_ph(v1_t, v1_t, v2_t);
20541             gen_store_gpr(v1_t, ret);
20542             break;
20543         case 1:
20544             /* ADDQH_R_PH */
20545             gen_helper_addqh_r_ph(v1_t, v1_t, v2_t);
20546             gen_store_gpr(v1_t, ret);
20547             break;
20548         }
20549         break;
20550     case NM_ADDQH_R_W:
20551         check_dsp_r2(ctx);
20552         switch (extract32(ctx->opcode, 10, 1)) {
20553         case 0:
20554             /* ADDQH_W */
20555             gen_helper_addqh_w(v1_t, v1_t, v2_t);
20556             gen_store_gpr(v1_t, ret);
20557             break;
20558         case 1:
20559             /* ADDQH_R_W */
20560             gen_helper_addqh_r_w(v1_t, v1_t, v2_t);
20561             gen_store_gpr(v1_t, ret);
20562             break;
20563         }
20564         break;
20565     case NM_ADDU_S_QB:
20566         check_dsp(ctx);
20567         switch (extract32(ctx->opcode, 10, 1)) {
20568         case 0:
20569             /* ADDU_QB */
20570             gen_helper_addu_qb(v1_t, v1_t, v2_t, cpu_env);
20571             gen_store_gpr(v1_t, ret);
20572             break;
20573         case 1:
20574             /* ADDU_S_QB */
20575             gen_helper_addu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20576             gen_store_gpr(v1_t, ret);
20577             break;
20578         }
20579         break;
20580     case NM_ADDU_S_PH:
20581         check_dsp_r2(ctx);
20582         switch (extract32(ctx->opcode, 10, 1)) {
20583         case 0:
20584             /* ADDU_PH */
20585             gen_helper_addu_ph(v1_t, v1_t, v2_t, cpu_env);
20586             gen_store_gpr(v1_t, ret);
20587             break;
20588         case 1:
20589             /* ADDU_S_PH */
20590             gen_helper_addu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20591             gen_store_gpr(v1_t, ret);
20592             break;
20593         }
20594         break;
20595     case NM_ADDUH_R_QB:
20596         check_dsp_r2(ctx);
20597         switch (extract32(ctx->opcode, 10, 1)) {
20598         case 0:
20599             /* ADDUH_QB */
20600             gen_helper_adduh_qb(v1_t, v1_t, v2_t);
20601             gen_store_gpr(v1_t, ret);
20602             break;
20603         case 1:
20604             /* ADDUH_R_QB */
20605             gen_helper_adduh_r_qb(v1_t, v1_t, v2_t);
20606             gen_store_gpr(v1_t, ret);
20607             break;
20608         }
20609         break;
20610     case NM_SHRAV_R_PH:
20611         check_dsp(ctx);
20612         switch (extract32(ctx->opcode, 10, 1)) {
20613         case 0:
20614             /* SHRAV_PH */
20615             gen_helper_shra_ph(v1_t, v1_t, v2_t);
20616             gen_store_gpr(v1_t, ret);
20617             break;
20618         case 1:
20619             /* SHRAV_R_PH */
20620             gen_helper_shra_r_ph(v1_t, v1_t, v2_t);
20621             gen_store_gpr(v1_t, ret);
20622             break;
20623         }
20624         break;
20625     case NM_SHRAV_R_QB:
20626         check_dsp_r2(ctx);
20627         switch (extract32(ctx->opcode, 10, 1)) {
20628         case 0:
20629             /* SHRAV_QB */
20630             gen_helper_shra_qb(v1_t, v1_t, v2_t);
20631             gen_store_gpr(v1_t, ret);
20632             break;
20633         case 1:
20634             /* SHRAV_R_QB */
20635             gen_helper_shra_r_qb(v1_t, v1_t, v2_t);
20636             gen_store_gpr(v1_t, ret);
20637             break;
20638         }
20639         break;
20640     case NM_SUBQ_S_PH:
20641         check_dsp(ctx);
20642         switch (extract32(ctx->opcode, 10, 1)) {
20643         case 0:
20644             /* SUBQ_PH */
20645             gen_helper_subq_ph(v1_t, v1_t, v2_t, cpu_env);
20646             gen_store_gpr(v1_t, ret);
20647             break;
20648         case 1:
20649             /* SUBQ_S_PH */
20650             gen_helper_subq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20651             gen_store_gpr(v1_t, ret);
20652             break;
20653         }
20654         break;
20655     case NM_SUBQH_R_PH:
20656         check_dsp_r2(ctx);
20657         switch (extract32(ctx->opcode, 10, 1)) {
20658         case 0:
20659             /* SUBQH_PH */
20660             gen_helper_subqh_ph(v1_t, v1_t, v2_t);
20661             gen_store_gpr(v1_t, ret);
20662             break;
20663         case 1:
20664             /* SUBQH_R_PH */
20665             gen_helper_subqh_r_ph(v1_t, v1_t, v2_t);
20666             gen_store_gpr(v1_t, ret);
20667             break;
20668         }
20669         break;
20670     case NM_SUBQH_R_W:
20671         check_dsp_r2(ctx);
20672         switch (extract32(ctx->opcode, 10, 1)) {
20673         case 0:
20674             /* SUBQH_W */
20675             gen_helper_subqh_w(v1_t, v1_t, v2_t);
20676             gen_store_gpr(v1_t, ret);
20677             break;
20678         case 1:
20679             /* SUBQH_R_W */
20680             gen_helper_subqh_r_w(v1_t, v1_t, v2_t);
20681             gen_store_gpr(v1_t, ret);
20682             break;
20683         }
20684         break;
20685     case NM_SUBU_S_QB:
20686         check_dsp(ctx);
20687         switch (extract32(ctx->opcode, 10, 1)) {
20688         case 0:
20689             /* SUBU_QB */
20690             gen_helper_subu_qb(v1_t, v1_t, v2_t, cpu_env);
20691             gen_store_gpr(v1_t, ret);
20692             break;
20693         case 1:
20694             /* SUBU_S_QB */
20695             gen_helper_subu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20696             gen_store_gpr(v1_t, ret);
20697             break;
20698         }
20699         break;
20700     case NM_SUBU_S_PH:
20701         check_dsp_r2(ctx);
20702         switch (extract32(ctx->opcode, 10, 1)) {
20703         case 0:
20704             /* SUBU_PH */
20705             gen_helper_subu_ph(v1_t, v1_t, v2_t, cpu_env);
20706             gen_store_gpr(v1_t, ret);
20707             break;
20708         case 1:
20709             /* SUBU_S_PH */
20710             gen_helper_subu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20711             gen_store_gpr(v1_t, ret);
20712             break;
20713         }
20714         break;
20715     case NM_SUBUH_R_QB:
20716         check_dsp_r2(ctx);
20717         switch (extract32(ctx->opcode, 10, 1)) {
20718         case 0:
20719             /* SUBUH_QB */
20720             gen_helper_subuh_qb(v1_t, v1_t, v2_t);
20721             gen_store_gpr(v1_t, ret);
20722             break;
20723         case 1:
20724             /* SUBUH_R_QB */
20725             gen_helper_subuh_r_qb(v1_t, v1_t, v2_t);
20726             gen_store_gpr(v1_t, ret);
20727             break;
20728         }
20729         break;
20730     case NM_SHLLV_S_PH:
20731         check_dsp(ctx);
20732         switch (extract32(ctx->opcode, 10, 1)) {
20733         case 0:
20734             /* SHLLV_PH */
20735             gen_helper_shll_ph(v1_t, v1_t, v2_t, cpu_env);
20736             gen_store_gpr(v1_t, ret);
20737             break;
20738         case 1:
20739             /* SHLLV_S_PH */
20740             gen_helper_shll_s_ph(v1_t, v1_t, v2_t, cpu_env);
20741             gen_store_gpr(v1_t, ret);
20742             break;
20743         }
20744         break;
20745     case NM_PRECR_SRA_R_PH_W:
20746         check_dsp_r2(ctx);
20747         switch (extract32(ctx->opcode, 10, 1)) {
20748         case 0:
20749             /* PRECR_SRA_PH_W */
20750             {
20751                 TCGv_i32 sa_t = tcg_const_i32(rd);
20752                 gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t,
20753                                           cpu_gpr[rt]);
20754                 gen_store_gpr(v1_t, rt);
20755                 tcg_temp_free_i32(sa_t);
20756             }
20757             break;
20758         case 1:
20759             /* PRECR_SRA_R_PH_W */
20760             {
20761                 TCGv_i32 sa_t = tcg_const_i32(rd);
20762                 gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t,
20763                                             cpu_gpr[rt]);
20764                 gen_store_gpr(v1_t, rt);
20765                 tcg_temp_free_i32(sa_t);
20766             }
20767             break;
20768        }
20769         break;
20770     case NM_MULEU_S_PH_QBL:
20771         check_dsp(ctx);
20772         gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, cpu_env);
20773         gen_store_gpr(v1_t, ret);
20774         break;
20775     case NM_MULEU_S_PH_QBR:
20776         check_dsp(ctx);
20777         gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, cpu_env);
20778         gen_store_gpr(v1_t, ret);
20779         break;
20780     case NM_MULQ_RS_PH:
20781         check_dsp(ctx);
20782         gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, cpu_env);
20783         gen_store_gpr(v1_t, ret);
20784         break;
20785     case NM_MULQ_S_PH:
20786         check_dsp_r2(ctx);
20787         gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20788         gen_store_gpr(v1_t, ret);
20789         break;
20790     case NM_MULQ_RS_W:
20791         check_dsp_r2(ctx);
20792         gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, cpu_env);
20793         gen_store_gpr(v1_t, ret);
20794         break;
20795     case NM_MULQ_S_W:
20796         check_dsp_r2(ctx);
20797         gen_helper_mulq_s_w(v1_t, v1_t, v2_t, cpu_env);
20798         gen_store_gpr(v1_t, ret);
20799         break;
20800     case NM_APPEND:
20801         check_dsp_r2(ctx);
20802         gen_load_gpr(t0, rs);
20803         if (rd != 0) {
20804             tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd);
20805         }
20806         tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20807         break;
20808     case NM_MODSUB:
20809         check_dsp(ctx);
20810         gen_helper_modsub(v1_t, v1_t, v2_t);
20811         gen_store_gpr(v1_t, ret);
20812         break;
20813     case NM_SHRAV_R_W:
20814         check_dsp(ctx);
20815         gen_helper_shra_r_w(v1_t, v1_t, v2_t);
20816         gen_store_gpr(v1_t, ret);
20817         break;
20818     case NM_SHRLV_PH:
20819         check_dsp_r2(ctx);
20820         gen_helper_shrl_ph(v1_t, v1_t, v2_t);
20821         gen_store_gpr(v1_t, ret);
20822         break;
20823     case NM_SHRLV_QB:
20824         check_dsp(ctx);
20825         gen_helper_shrl_qb(v1_t, v1_t, v2_t);
20826         gen_store_gpr(v1_t, ret);
20827         break;
20828     case NM_SHLLV_QB:
20829         check_dsp(ctx);
20830         gen_helper_shll_qb(v1_t, v1_t, v2_t, cpu_env);
20831         gen_store_gpr(v1_t, ret);
20832         break;
20833     case NM_SHLLV_S_W:
20834         check_dsp(ctx);
20835         gen_helper_shll_s_w(v1_t, v1_t, v2_t, cpu_env);
20836         gen_store_gpr(v1_t, ret);
20837         break;
20838     case NM_SHILO:
20839         check_dsp(ctx);
20840         {
20841             TCGv tv0 = tcg_temp_new();
20842             TCGv tv1 = tcg_temp_new();
20843             int16_t imm = extract32(ctx->opcode, 16, 7);
20844
20845             tcg_gen_movi_tl(tv0, rd >> 3);
20846             tcg_gen_movi_tl(tv1, imm);
20847             gen_helper_shilo(tv0, tv1, cpu_env);
20848         }
20849         break;
20850     case NM_MULEQ_S_W_PHL:
20851         check_dsp(ctx);
20852         gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, cpu_env);
20853         gen_store_gpr(v1_t, ret);
20854         break;
20855     case NM_MULEQ_S_W_PHR:
20856         check_dsp(ctx);
20857         gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, cpu_env);
20858         gen_store_gpr(v1_t, ret);
20859         break;
20860     case NM_MUL_S_PH:
20861         check_dsp_r2(ctx);
20862         switch (extract32(ctx->opcode, 10, 1)) {
20863         case 0:
20864             /* MUL_PH */
20865             gen_helper_mul_ph(v1_t, v1_t, v2_t, cpu_env);
20866             gen_store_gpr(v1_t, ret);
20867             break;
20868         case 1:
20869             /* MUL_S_PH */
20870             gen_helper_mul_s_ph(v1_t, v1_t, v2_t, cpu_env);
20871             gen_store_gpr(v1_t, ret);
20872             break;
20873         }
20874         break;
20875     case NM_PRECR_QB_PH:
20876         check_dsp_r2(ctx);
20877         gen_helper_precr_qb_ph(v1_t, v1_t, v2_t);
20878         gen_store_gpr(v1_t, ret);
20879         break;
20880     case NM_PRECRQ_QB_PH:
20881         check_dsp(ctx);
20882         gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t);
20883         gen_store_gpr(v1_t, ret);
20884         break;
20885     case NM_PRECRQ_PH_W:
20886         check_dsp(ctx);
20887         gen_helper_precrq_ph_w(v1_t, v1_t, v2_t);
20888         gen_store_gpr(v1_t, ret);
20889         break;
20890     case NM_PRECRQ_RS_PH_W:
20891         check_dsp(ctx);
20892         gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, cpu_env);
20893         gen_store_gpr(v1_t, ret);
20894         break;
20895     case NM_PRECRQU_S_QB_PH:
20896         check_dsp(ctx);
20897         gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, cpu_env);
20898         gen_store_gpr(v1_t, ret);
20899         break;
20900     case NM_SHRA_R_W:
20901         check_dsp(ctx);
20902         tcg_gen_movi_tl(t0, rd);
20903         gen_helper_shra_r_w(v1_t, t0, v1_t);
20904         gen_store_gpr(v1_t, rt);
20905         break;
20906     case NM_SHRA_R_PH:
20907         check_dsp(ctx);
20908         tcg_gen_movi_tl(t0, rd >> 1);
20909         switch (extract32(ctx->opcode, 10, 1)) {
20910         case 0:
20911             /* SHRA_PH */
20912             gen_helper_shra_ph(v1_t, t0, v1_t);
20913             gen_store_gpr(v1_t, rt);
20914             break;
20915         case 1:
20916             /* SHRA_R_PH */
20917             gen_helper_shra_r_ph(v1_t, t0, v1_t);
20918             gen_store_gpr(v1_t, rt);
20919             break;
20920         }
20921         break;
20922     case NM_SHLL_S_PH:
20923         check_dsp(ctx);
20924         tcg_gen_movi_tl(t0, rd >> 1);
20925         switch (extract32(ctx->opcode, 10, 2)) {
20926         case 0:
20927             /* SHLL_PH */
20928             gen_helper_shll_ph(v1_t, t0, v1_t, cpu_env);
20929             gen_store_gpr(v1_t, rt);
20930             break;
20931         case 2:
20932             /* SHLL_S_PH */
20933             gen_helper_shll_s_ph(v1_t, t0, v1_t, cpu_env);
20934             gen_store_gpr(v1_t, rt);
20935             break;
20936         default:
20937             generate_exception_end(ctx, EXCP_RI);
20938             break;
20939         }
20940         break;
20941     case NM_SHLL_S_W:
20942         check_dsp(ctx);
20943         tcg_gen_movi_tl(t0, rd);
20944         gen_helper_shll_s_w(v1_t, t0, v1_t, cpu_env);
20945         gen_store_gpr(v1_t, rt);
20946         break;
20947     case NM_REPL_PH:
20948         check_dsp(ctx);
20949         {
20950             int16_t imm;
20951             imm = sextract32(ctx->opcode, 11, 11);
20952             imm = (int16_t)(imm << 6) >> 6;
20953             if (rt != 0) {
20954                 tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm));
20955             }
20956         }
20957         break;
20958     default:
20959         generate_exception_end(ctx, EXCP_RI);
20960         break;
20961     }
20962 }
20963
20964 static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
20965 {
20966     uint16_t insn;
20967     uint32_t op;
20968     int rt, rs, rd;
20969     int offset;
20970     int imm;
20971
20972     insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
20973     ctx->opcode = (ctx->opcode << 16) | insn;
20974
20975     rt = extract32(ctx->opcode, 21, 5);
20976     rs = extract32(ctx->opcode, 16, 5);
20977     rd = extract32(ctx->opcode, 11, 5);
20978
20979     op = extract32(ctx->opcode, 26, 6);
20980     switch (op) {
20981     case NM_P_ADDIU:
20982         if (rt == 0) {
20983             /* P.RI */
20984             switch (extract32(ctx->opcode, 19, 2)) {
20985             case NM_SIGRIE:
20986             default:
20987                 generate_exception_end(ctx, EXCP_RI);
20988                 break;
20989             case NM_P_SYSCALL:
20990                 if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) {
20991                     generate_exception_end(ctx, EXCP_SYSCALL);
20992                 } else {
20993                     generate_exception_end(ctx, EXCP_RI);
20994                 }
20995                 break;
20996             case NM_BREAK:
20997                 generate_exception_end(ctx, EXCP_BREAK);
20998                 break;
20999             case NM_SDBBP:
21000                 if (is_uhi(extract32(ctx->opcode, 0, 19))) {
21001                     gen_helper_do_semihosting(cpu_env);
21002                 } else {
21003                     if (ctx->hflags & MIPS_HFLAG_SBRI) {
21004                         generate_exception_end(ctx, EXCP_RI);
21005                     } else {
21006                         generate_exception_end(ctx, EXCP_DBp);
21007                     }
21008                 }
21009                 break;
21010             }
21011         } else {
21012             /* NM_ADDIU */
21013             imm = extract32(ctx->opcode, 0, 16);
21014             if (rs != 0) {
21015                 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm);
21016             } else {
21017                 tcg_gen_movi_tl(cpu_gpr[rt], imm);
21018             }
21019             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
21020         }
21021         break;
21022     case NM_ADDIUPC:
21023         if (rt != 0) {
21024             offset = sextract32(ctx->opcode, 0, 1) << 21 |
21025                      extract32(ctx->opcode, 1, 20) << 1;
21026             target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset);
21027             tcg_gen_movi_tl(cpu_gpr[rt], addr);
21028         }
21029         break;
21030     case NM_POOL32A:
21031         switch (ctx->opcode & 0x07) {
21032         case NM_POOL32A0:
21033             gen_pool32a0_nanomips_insn(env, ctx);
21034             break;
21035         case NM_POOL32A5:
21036             {
21037                 int32_t op1 = extract32(ctx->opcode, 3, 7);
21038                 gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt);
21039             }
21040             break;
21041         case NM_POOL32A7:
21042             switch (extract32(ctx->opcode, 3, 3)) {
21043             case NM_P_LSX:
21044                 gen_p_lsx(ctx, rd, rs, rt);
21045                 break;
21046             case NM_LSA:
21047                 /* In nanoMIPS, the shift field directly encodes the shift
21048                  * amount, meaning that the supported shift values are in
21049                  * the range 0 to 3 (instead of 1 to 4 in MIPSR6). */
21050                 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
21051                         extract32(ctx->opcode, 9, 2) - 1);
21052                 break;
21053             case NM_EXTW:
21054                 gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5));
21055                 break;
21056             case NM_POOL32AXF:
21057                 gen_pool32axf_nanomips_insn(env, ctx);
21058                 break;
21059             default:
21060                 generate_exception_end(ctx, EXCP_RI);
21061                 break;
21062             }
21063             break;
21064         default:
21065             generate_exception_end(ctx, EXCP_RI);
21066             break;
21067         }
21068         break;
21069     case NM_P_GP_W:
21070         switch (ctx->opcode & 0x03) {
21071         case NM_ADDIUGP_W:
21072             if (rt != 0) {
21073                 offset = extract32(ctx->opcode, 0, 21);
21074                 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset);
21075             }
21076             break;
21077         case NM_LWGP:
21078             gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
21079             break;
21080         case NM_SWGP:
21081             gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
21082             break;
21083         default:
21084             generate_exception_end(ctx, EXCP_RI);
21085             break;
21086         }
21087         break;
21088     case NM_P48I:
21089         {
21090             insn = cpu_lduw_code(env, ctx->base.pc_next + 4);
21091             target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16;
21092             switch (extract32(ctx->opcode, 16, 5)) {
21093             case NM_LI48:
21094                 check_nms(ctx);
21095                 if (rt != 0) {
21096                     tcg_gen_movi_tl(cpu_gpr[rt], addr_off);
21097                 }
21098                 break;
21099             case NM_ADDIU48:
21100                 check_nms(ctx);
21101                 if (rt != 0) {
21102                     tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off);
21103                     tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
21104                 }
21105                 break;
21106             case NM_ADDIUGP48:
21107                 check_nms(ctx);
21108                 if (rt != 0) {
21109                     gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_off);
21110                 }
21111                 break;
21112             case NM_ADDIUPC48:
21113                 check_nms(ctx);
21114                 if (rt != 0) {
21115                     target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21116                                                 addr_off);
21117
21118                     tcg_gen_movi_tl(cpu_gpr[rt], addr);
21119                 }
21120                 break;
21121             case NM_LWPC48:
21122                 check_nms(ctx);
21123                 if (rt != 0) {
21124                     TCGv t0;
21125                     t0 = tcg_temp_new();
21126
21127                     target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21128                                                 addr_off);
21129
21130                     tcg_gen_movi_tl(t0, addr);
21131                     tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_TESL);
21132                     tcg_temp_free(t0);
21133                 }
21134                 break;
21135             case NM_SWPC48:
21136                 check_nms(ctx);
21137                 {
21138                     TCGv t0, t1;
21139                     t0 = tcg_temp_new();
21140                     t1 = tcg_temp_new();
21141
21142                     target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21143                                                 addr_off);
21144
21145                     tcg_gen_movi_tl(t0, addr);
21146                     gen_load_gpr(t1, rt);
21147
21148                     tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
21149
21150                     tcg_temp_free(t0);
21151                     tcg_temp_free(t1);
21152                 }
21153                 break;
21154             default:
21155                 generate_exception_end(ctx, EXCP_RI);
21156                 break;
21157             }
21158             return 6;
21159         }
21160     case NM_P_U12:
21161         switch (extract32(ctx->opcode, 12, 4)) {
21162         case NM_ORI:
21163             gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12));
21164             break;
21165         case NM_XORI:
21166             gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12));
21167             break;
21168         case NM_ANDI:
21169             gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12));
21170             break;
21171         case NM_P_SR:
21172             switch (extract32(ctx->opcode, 20, 1)) {
21173             case NM_PP_SR:
21174                 switch (ctx->opcode & 3) {
21175                 case NM_SAVE:
21176                     gen_save(ctx, rt, extract32(ctx->opcode, 16, 4),
21177                              extract32(ctx->opcode, 2, 1),
21178                              extract32(ctx->opcode, 3, 9) << 3);
21179                     break;
21180                 case NM_RESTORE:
21181                 case NM_RESTORE_JRC:
21182                     gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4),
21183                                 extract32(ctx->opcode, 2, 1),
21184                                 extract32(ctx->opcode, 3, 9) << 3);
21185                     if ((ctx->opcode & 3) == NM_RESTORE_JRC) {
21186                         gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
21187                     }
21188                     break;
21189                 default:
21190                     generate_exception_end(ctx, EXCP_RI);
21191                     break;
21192                 }
21193                 break;
21194             case NM_P_SR_F:
21195                 generate_exception_end(ctx, EXCP_RI);
21196                 break;
21197             }
21198             break;
21199         case NM_SLTI:
21200             gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12));
21201             break;
21202         case NM_SLTIU:
21203             gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12));
21204             break;
21205         case NM_SEQI:
21206             {
21207                 TCGv t0 = tcg_temp_new();
21208
21209                 imm = extract32(ctx->opcode, 0, 12);
21210                 gen_load_gpr(t0, rs);
21211                 tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm);
21212                 gen_store_gpr(t0, rt);
21213
21214                 tcg_temp_free(t0);
21215             }
21216             break;
21217         case NM_ADDIUNEG:
21218             imm = (int16_t) extract32(ctx->opcode, 0, 12);
21219             gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm);
21220             break;
21221         case NM_P_SHIFT:
21222             {
21223                 int shift = extract32(ctx->opcode, 0, 5);
21224                 switch (extract32(ctx->opcode, 5, 4)) {
21225                 case NM_P_SLL:
21226                     if (rt == 0 && shift == 0) {
21227                         /* NOP */
21228                     } else if (rt == 0 && shift == 3) {
21229                         /* EHB - treat as NOP */
21230                     } else if (rt == 0 && shift == 5) {
21231                         /* PAUSE - treat as NOP */
21232                     } else if (rt == 0 && shift == 6) {
21233                         /* SYNC */
21234                         gen_sync(extract32(ctx->opcode, 16, 5));
21235                     } else {
21236                         /* SLL */
21237                         gen_shift_imm(ctx, OPC_SLL, rt, rs,
21238                                       extract32(ctx->opcode, 0, 5));
21239                     }
21240                     break;
21241                 case NM_SRL:
21242                     gen_shift_imm(ctx, OPC_SRL, rt, rs,
21243                                   extract32(ctx->opcode, 0, 5));
21244                     break;
21245                 case NM_SRA:
21246                     gen_shift_imm(ctx, OPC_SRA, rt, rs,
21247                                   extract32(ctx->opcode, 0, 5));
21248                     break;
21249                 case NM_ROTR:
21250                     gen_shift_imm(ctx, OPC_ROTR, rt, rs,
21251                                   extract32(ctx->opcode, 0, 5));
21252                     break;
21253                 }
21254             }
21255             break;
21256         case NM_P_ROTX:
21257             check_nms(ctx);
21258             if (rt != 0) {
21259                 TCGv t0 = tcg_temp_new();
21260                 TCGv_i32 shift = tcg_const_i32(extract32(ctx->opcode, 0, 5));
21261                 TCGv_i32 shiftx = tcg_const_i32(extract32(ctx->opcode, 7, 4)
21262                                                 << 1);
21263                 TCGv_i32 stripe = tcg_const_i32(extract32(ctx->opcode, 6, 1));
21264
21265                 gen_load_gpr(t0, rs);
21266                 gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe);
21267                 tcg_temp_free(t0);
21268
21269                 tcg_temp_free_i32(shift);
21270                 tcg_temp_free_i32(shiftx);
21271                 tcg_temp_free_i32(stripe);
21272             }
21273             break;
21274         case NM_P_INS:
21275             switch (((ctx->opcode >> 10) & 2) |
21276                     (extract32(ctx->opcode, 5, 1))) {
21277             case NM_INS:
21278                 check_nms(ctx);
21279                 gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5),
21280                            extract32(ctx->opcode, 6, 5));
21281                 break;
21282             default:
21283                 generate_exception_end(ctx, EXCP_RI);
21284                 break;
21285             }
21286             break;
21287         case NM_P_EXT:
21288             switch (((ctx->opcode >> 10) & 2) |
21289                     (extract32(ctx->opcode, 5, 1))) {
21290             case NM_EXT:
21291                 check_nms(ctx);
21292                 gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5),
21293                            extract32(ctx->opcode, 6, 5));
21294                 break;
21295             default:
21296                 generate_exception_end(ctx, EXCP_RI);
21297                 break;
21298             }
21299             break;
21300         default:
21301             generate_exception_end(ctx, EXCP_RI);
21302             break;
21303         }
21304         break;
21305     case NM_POOL32F:
21306         gen_pool32f_nanomips_insn(ctx);
21307         break;
21308     case NM_POOL32S:
21309         break;
21310     case NM_P_LUI:
21311         switch (extract32(ctx->opcode, 1, 1)) {
21312         case NM_LUI:
21313             if (rt != 0) {
21314                 tcg_gen_movi_tl(cpu_gpr[rt],
21315                                 sextract32(ctx->opcode, 0, 1) << 31 |
21316                                 extract32(ctx->opcode, 2, 10) << 21 |
21317                                 extract32(ctx->opcode, 12, 9) << 12);
21318             }
21319             break;
21320         case NM_ALUIPC:
21321             if (rt != 0) {
21322                 offset = sextract32(ctx->opcode, 0, 1) << 31 |
21323                          extract32(ctx->opcode, 2, 10) << 21 |
21324                          extract32(ctx->opcode, 12, 9) << 12;
21325                 target_long addr;
21326                 addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset);
21327                 tcg_gen_movi_tl(cpu_gpr[rt], addr);
21328             }
21329             break;
21330         }
21331         break;
21332     case NM_P_GP_BH:
21333         {
21334             uint32_t u = extract32(ctx->opcode, 0, 18);
21335
21336             switch (extract32(ctx->opcode, 18, 3)) {
21337             case NM_LBGP:
21338                 gen_ld(ctx, OPC_LB, rt, 28, u);
21339                 break;
21340             case NM_SBGP:
21341                 gen_st(ctx, OPC_SB, rt, 28, u);
21342                 break;
21343             case NM_LBUGP:
21344                 gen_ld(ctx, OPC_LBU, rt, 28, u);
21345                 break;
21346             case NM_ADDIUGP_B:
21347                 if (rt != 0) {
21348                     gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u);
21349                 }
21350                 break;
21351             case NM_P_GP_LH:
21352                 u &= ~1;
21353                 switch (ctx->opcode & 1) {
21354                 case NM_LHGP:
21355                     gen_ld(ctx, OPC_LH, rt, 28, u);
21356                     break;
21357                 case NM_LHUGP:
21358                     gen_ld(ctx, OPC_LHU, rt, 28, u);
21359                     break;
21360                 }
21361                 break;
21362             case NM_P_GP_SH:
21363                 u &= ~1;
21364                 switch (ctx->opcode & 1) {
21365                 case NM_SHGP:
21366                     gen_st(ctx, OPC_SH, rt, 28, u);
21367                     break;
21368                 default:
21369                     generate_exception_end(ctx, EXCP_RI);
21370                     break;
21371                 }
21372                 break;
21373             case NM_P_GP_CP1:
21374                 u &= ~0x3;
21375                 switch (ctx->opcode & 0x3) {
21376                 case NM_LWC1GP:
21377                     gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u);
21378                     break;
21379                 case NM_LDC1GP:
21380                     gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u);
21381                     break;
21382                 case NM_SWC1GP:
21383                     gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u);
21384                     break;
21385                 case NM_SDC1GP:
21386                     gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u);
21387                     break;
21388                 }
21389                 break;
21390             default:
21391                 generate_exception_end(ctx, EXCP_RI);
21392                 break;
21393             }
21394         }
21395         break;
21396     case NM_P_LS_U12:
21397         {
21398             uint32_t u = extract32(ctx->opcode, 0, 12);
21399
21400             switch (extract32(ctx->opcode, 12, 4)) {
21401             case NM_P_PREFU12:
21402                 if (rt == 31) {
21403                     /* SYNCI */
21404                     /* Break the TB to be able to sync copied instructions
21405                        immediately */
21406                     ctx->base.is_jmp = DISAS_STOP;
21407                 } else {
21408                     /* PREF */
21409                     /* Treat as NOP. */
21410                 }
21411                 break;
21412             case NM_LB:
21413                 gen_ld(ctx, OPC_LB, rt, rs, u);
21414                 break;
21415             case NM_LH:
21416                 gen_ld(ctx, OPC_LH, rt, rs, u);
21417                 break;
21418             case NM_LW:
21419                 gen_ld(ctx, OPC_LW, rt, rs, u);
21420                 break;
21421             case NM_LBU:
21422                 gen_ld(ctx, OPC_LBU, rt, rs, u);
21423                 break;
21424             case NM_LHU:
21425                 gen_ld(ctx, OPC_LHU, rt, rs, u);
21426                 break;
21427             case NM_SB:
21428                 gen_st(ctx, OPC_SB, rt, rs, u);
21429                 break;
21430             case NM_SH:
21431                 gen_st(ctx, OPC_SH, rt, rs, u);
21432                 break;
21433             case NM_SW:
21434                 gen_st(ctx, OPC_SW, rt, rs, u);
21435                 break;
21436             case NM_LWC1:
21437                 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u);
21438                 break;
21439             case NM_LDC1:
21440                 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u);
21441                 break;
21442             case NM_SWC1:
21443                 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u);
21444                 break;
21445             case NM_SDC1:
21446                 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u);
21447                 break;
21448             default:
21449                 generate_exception_end(ctx, EXCP_RI);
21450                 break;
21451             }
21452         }
21453         break;
21454     case NM_P_LS_S9:
21455         {
21456             int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) |
21457                         extract32(ctx->opcode, 0, 8);
21458
21459             switch (extract32(ctx->opcode, 8, 3)) {
21460             case NM_P_LS_S0:
21461                 switch (extract32(ctx->opcode, 11, 4)) {
21462                 case NM_LBS9:
21463                     gen_ld(ctx, OPC_LB, rt, rs, s);
21464                     break;
21465                 case NM_LHS9:
21466                     gen_ld(ctx, OPC_LH, rt, rs, s);
21467                     break;
21468                 case NM_LWS9:
21469                     gen_ld(ctx, OPC_LW, rt, rs, s);
21470                     break;
21471                 case NM_LBUS9:
21472                     gen_ld(ctx, OPC_LBU, rt, rs, s);
21473                     break;
21474                 case NM_LHUS9:
21475                     gen_ld(ctx, OPC_LHU, rt, rs, s);
21476                     break;
21477                 case NM_SBS9:
21478                     gen_st(ctx, OPC_SB, rt, rs, s);
21479                     break;
21480                 case NM_SHS9:
21481                     gen_st(ctx, OPC_SH, rt, rs, s);
21482                     break;
21483                 case NM_SWS9:
21484                     gen_st(ctx, OPC_SW, rt, rs, s);
21485                     break;
21486                 case NM_LWC1S9:
21487                     gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s);
21488                     break;
21489                 case NM_LDC1S9:
21490                     gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s);
21491                     break;
21492                 case NM_SWC1S9:
21493                     gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s);
21494                     break;
21495                 case NM_SDC1S9:
21496                     gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s);
21497                     break;
21498                 case NM_P_PREFS9:
21499                     if (rt == 31) {
21500                         /* SYNCI */
21501                         /* Break the TB to be able to sync copied instructions
21502                            immediately */
21503                         ctx->base.is_jmp = DISAS_STOP;
21504                     } else {
21505                         /* PREF */
21506                         /* Treat as NOP. */
21507                     }
21508                     break;
21509                 default:
21510                     generate_exception_end(ctx, EXCP_RI);
21511                     break;
21512                 }
21513                 break;
21514             case NM_P_LS_S1:
21515                 switch (extract32(ctx->opcode, 11, 4)) {
21516                 case NM_UALH:
21517                 case NM_UASH:
21518                     check_nms(ctx);
21519                     {
21520                         TCGv t0 = tcg_temp_new();
21521                         TCGv t1 = tcg_temp_new();
21522
21523                         gen_base_offset_addr(ctx, t0, rs, s);
21524
21525                         switch (extract32(ctx->opcode, 11, 4)) {
21526                         case NM_UALH:
21527                             tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
21528                                                MO_UNALN);
21529                             gen_store_gpr(t0, rt);
21530                             break;
21531                         case NM_UASH:
21532                             gen_load_gpr(t1, rt);
21533                             tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
21534                                                MO_UNALN);
21535                             break;
21536                         }
21537                         tcg_temp_free(t0);
21538                         tcg_temp_free(t1);
21539                     }
21540                     break;
21541                 case NM_P_LL:
21542                     switch (ctx->opcode & 0x03) {
21543                     case NM_LL:
21544                         gen_ld(ctx, OPC_LL, rt, rs, s);
21545                         break;
21546                     case NM_LLWP:
21547                         check_xnp(ctx);
21548                         gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21549                         break;
21550                     }
21551                     break;
21552                 case NM_P_SC:
21553                     switch (ctx->opcode & 0x03) {
21554                     case NM_SC:
21555                         gen_st_cond(ctx, OPC_SC, rt, rs, s);
21556                         break;
21557                     case NM_SCWP:
21558                         check_xnp(ctx);
21559                         gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21560                         break;
21561                     }
21562                     break;
21563                 case NM_CACHE:
21564                     check_cp0_enabled(ctx);
21565                     if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
21566                         gen_cache_operation(ctx, rt, rs, s);
21567                     }
21568                     break;
21569                 }
21570                 break;
21571             case NM_P_LS_E0:
21572                 switch (extract32(ctx->opcode, 11, 4)) {
21573                 case NM_LBE:
21574                     check_eva(ctx);
21575                     check_cp0_enabled(ctx);
21576                     gen_ld(ctx, OPC_LBE, rt, rs, s);
21577                     break;
21578                 case NM_SBE:
21579                     check_eva(ctx);
21580                     check_cp0_enabled(ctx);
21581                     gen_st(ctx, OPC_SBE, rt, rs, s);
21582                     break;
21583                 case NM_LBUE:
21584                     check_eva(ctx);
21585                     check_cp0_enabled(ctx);
21586                     gen_ld(ctx, OPC_LBUE, rt, rs, s);
21587                     break;
21588                 case NM_P_PREFE:
21589                     if (rt == 31) {
21590                         /* case NM_SYNCIE */
21591                         check_eva(ctx);
21592                         check_cp0_enabled(ctx);
21593                         /* Break the TB to be able to sync copied instructions
21594                            immediately */
21595                         ctx->base.is_jmp = DISAS_STOP;
21596                     } else {
21597                         /* case NM_PREFE */
21598                         check_eva(ctx);
21599                         check_cp0_enabled(ctx);
21600                         /* Treat as NOP. */
21601                     }
21602                     break;
21603                 case NM_LHE:
21604                     check_eva(ctx);
21605                     check_cp0_enabled(ctx);
21606                     gen_ld(ctx, OPC_LHE, rt, rs, s);
21607                     break;
21608                 case NM_SHE:
21609                     check_eva(ctx);
21610                     check_cp0_enabled(ctx);
21611                     gen_st(ctx, OPC_SHE, rt, rs, s);
21612                     break;
21613                 case NM_LHUE:
21614                     check_eva(ctx);
21615                     check_cp0_enabled(ctx);
21616                     gen_ld(ctx, OPC_LHUE, rt, rs, s);
21617                     break;
21618                 case NM_CACHEE:
21619                     check_nms_dl_il_sl_tl_l2c(ctx);
21620                     gen_cache_operation(ctx, rt, rs, s);
21621                     break;
21622                 case NM_LWE:
21623                     check_eva(ctx);
21624                     check_cp0_enabled(ctx);
21625                     gen_ld(ctx, OPC_LWE, rt, rs, s);
21626                     break;
21627                 case NM_SWE:
21628                     check_eva(ctx);
21629                     check_cp0_enabled(ctx);
21630                     gen_st(ctx, OPC_SWE, rt, rs, s);
21631                     break;
21632                 case NM_P_LLE:
21633                     switch (extract32(ctx->opcode, 2, 2)) {
21634                     case NM_LLE:
21635                         check_xnp(ctx);
21636                         check_eva(ctx);
21637                         check_cp0_enabled(ctx);
21638                         gen_ld(ctx, OPC_LLE, rt, rs, s);
21639                         break;
21640                     case NM_LLWPE:
21641                         check_xnp(ctx);
21642                         check_eva(ctx);
21643                         check_cp0_enabled(ctx);
21644                         gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21645                         break;
21646                     default:
21647                         generate_exception_end(ctx, EXCP_RI);
21648                         break;
21649                     }
21650                     break;
21651                 case NM_P_SCE:
21652                     switch (extract32(ctx->opcode, 2, 2)) {
21653                     case NM_SCE:
21654                         check_xnp(ctx);
21655                         check_eva(ctx);
21656                         check_cp0_enabled(ctx);
21657                         gen_st_cond(ctx, OPC_SCE, rt, rs, s);
21658                         break;
21659                     case NM_SCWPE:
21660                         check_xnp(ctx);
21661                         check_eva(ctx);
21662                         check_cp0_enabled(ctx);
21663                         gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21664                         break;
21665                     default:
21666                         generate_exception_end(ctx, EXCP_RI);
21667                         break;
21668                     }
21669                     break;
21670                 }
21671                 break;
21672             case NM_P_LS_WM:
21673             case NM_P_LS_UAWM:
21674                 check_nms(ctx);
21675                 {
21676                     int count = extract32(ctx->opcode, 12, 3);
21677                     int counter = 0;
21678
21679                     offset = sextract32(ctx->opcode, 15, 1) << 8 |
21680                              extract32(ctx->opcode, 0, 8);
21681                     TCGv va = tcg_temp_new();
21682                     TCGv t1 = tcg_temp_new();
21683                     TCGMemOp memop = (extract32(ctx->opcode, 8, 3)) ==
21684                                       NM_P_LS_UAWM ? MO_UNALN : 0;
21685
21686                     count = (count == 0) ? 8 : count;
21687                     while (counter != count) {
21688                         int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10);
21689                         int this_offset = offset + (counter << 2);
21690
21691                         gen_base_offset_addr(ctx, va, rs, this_offset);
21692
21693                         switch (extract32(ctx->opcode, 11, 1)) {
21694                         case NM_LWM:
21695                             tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx,
21696                                                memop | MO_TESL);
21697                             gen_store_gpr(t1, this_rt);
21698                             if ((this_rt == rs) &&
21699                                 (counter != (count - 1))) {
21700                                 /* UNPREDICTABLE */
21701                             }
21702                             break;
21703                         case NM_SWM:
21704                             this_rt = (rt == 0) ? 0 : this_rt;
21705                             gen_load_gpr(t1, this_rt);
21706                             tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx,
21707                                                memop | MO_TEUL);
21708                             break;
21709                         }
21710                         counter++;
21711                     }
21712                     tcg_temp_free(va);
21713                     tcg_temp_free(t1);
21714                 }
21715                 break;
21716             default:
21717                 generate_exception_end(ctx, EXCP_RI);
21718                 break;
21719             }
21720         }
21721         break;
21722     case NM_MOVE_BALC:
21723         check_nms(ctx);
21724         {
21725             TCGv t0 = tcg_temp_new();
21726             int32_t s = sextract32(ctx->opcode, 0, 1) << 21 |
21727                         extract32(ctx->opcode, 1, 20) << 1;
21728             rd = (extract32(ctx->opcode, 24, 1)) == 0 ? 4 : 5;
21729             rt = decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3 |
21730                             extract32(ctx->opcode, 21, 3));
21731             gen_load_gpr(t0, rt);
21732             tcg_gen_mov_tl(cpu_gpr[rd], t0);
21733             gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21734             tcg_temp_free(t0);
21735         }
21736         break;
21737     case NM_P_BAL:
21738         {
21739             int32_t s = sextract32(ctx->opcode, 0, 1) << 25 |
21740                         extract32(ctx->opcode, 1, 24) << 1;
21741
21742             if ((extract32(ctx->opcode, 25, 1)) == 0) {
21743                 /* BC */
21744                 gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s);
21745             } else {
21746                 /* BALC */
21747                 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21748             }
21749         }
21750         break;
21751     case NM_P_J:
21752         switch (extract32(ctx->opcode, 12, 4)) {
21753         case NM_JALRC:
21754         case NM_JALRC_HB:
21755             gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0);
21756             break;
21757         case NM_P_BALRSC:
21758             gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt);
21759             break;
21760         default:
21761             generate_exception_end(ctx, EXCP_RI);
21762             break;
21763         }
21764         break;
21765     case NM_P_BR1:
21766         {
21767             int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21768                         extract32(ctx->opcode, 1, 13) << 1;
21769             switch (extract32(ctx->opcode, 14, 2)) {
21770             case NM_BEQC:
21771                 check_nms(ctx);
21772                 gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s);
21773                 break;
21774             case NM_P_BR3A:
21775                 s = sextract32(ctx->opcode, 0, 1) << 14 |
21776                     extract32(ctx->opcode, 1, 13) << 1;
21777                 check_cp1_enabled(ctx);
21778                 switch (extract32(ctx->opcode, 16, 5)) {
21779                 case NM_BC1EQZC:
21780                     gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s);
21781                     break;
21782                 case NM_BC1NEZC:
21783                     gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s);
21784                     break;
21785                 case NM_BPOSGE32C:
21786                     check_dsp_r3(ctx);
21787                     {
21788                         int32_t imm = extract32(ctx->opcode, 1, 13) |
21789                                       extract32(ctx->opcode, 0, 1) << 13;
21790
21791                         gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2,
21792                                               imm);
21793                     }
21794                     break;
21795                 default:
21796                     generate_exception_end(ctx, EXCP_RI);
21797                     break;
21798                 }
21799                 break;
21800             case NM_BGEC:
21801                 if (rs == rt) {
21802                     gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s);
21803                 } else {
21804                     gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s);
21805                 }
21806                 break;
21807             case NM_BGEUC:
21808                 if (rs == rt || rt == 0) {
21809                     gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s);
21810                 } else if (rs == 0) {
21811                     gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s);
21812                 } else {
21813                     gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, s);
21814                 }
21815                 break;
21816             }
21817         }
21818         break;
21819     case NM_P_BR2:
21820         {
21821             int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21822                         extract32(ctx->opcode, 1, 13) << 1;
21823             switch (extract32(ctx->opcode, 14, 2)) {
21824             case NM_BNEC:
21825                 check_nms(ctx);
21826                 gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s);
21827                 break;
21828             case NM_BLTC:
21829                 if (rs != 0 && rt != 0 && rs == rt) {
21830                     /* NOP */
21831                     ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21832                 } else {
21833                     gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s);
21834                 }
21835                 break;
21836             case NM_BLTUC:
21837                 if (rs == 0 || rs == rt) {
21838                     /* NOP */
21839                     ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21840                 } else {
21841                     gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, s);
21842                 }
21843                 break;
21844             default:
21845                 generate_exception_end(ctx, EXCP_RI);
21846                 break;
21847             }
21848         }
21849         break;
21850     case NM_P_BRI:
21851         {
21852             int32_t s = sextract32(ctx->opcode, 0, 1) << 11 |
21853                         extract32(ctx->opcode, 1, 10) << 1;
21854             uint32_t u = extract32(ctx->opcode, 11, 7);
21855
21856             gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3),
21857                                    rt, u, s);
21858         }
21859         break;
21860     default:
21861         generate_exception_end(ctx, EXCP_RI);
21862         break;
21863     }
21864     return 4;
21865 }
21866
21867 static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
21868 {
21869     uint32_t op;
21870     int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
21871     int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
21872     int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS1(ctx->opcode));
21873     int offset;
21874     int imm;
21875
21876     /* make sure instructions are on a halfword boundary */
21877     if (ctx->base.pc_next & 0x1) {
21878         TCGv tmp = tcg_const_tl(ctx->base.pc_next);
21879         tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
21880         tcg_temp_free(tmp);
21881         generate_exception_end(ctx, EXCP_AdEL);
21882         return 2;
21883     }
21884
21885     op = extract32(ctx->opcode, 10, 6);
21886     switch (op) {
21887     case NM_P16_MV:
21888         rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21889         if (rt != 0) {
21890             /* MOVE */
21891             rs = NANOMIPS_EXTRACT_RS5(ctx->opcode);
21892             gen_arith(ctx, OPC_ADDU, rt, rs, 0);
21893         } else {
21894             /* P16.RI */
21895             switch (extract32(ctx->opcode, 3, 2)) {
21896             case NM_P16_SYSCALL:
21897                 if (extract32(ctx->opcode, 2, 1) == 0) {
21898                     generate_exception_end(ctx, EXCP_SYSCALL);
21899                 } else {
21900                     generate_exception_end(ctx, EXCP_RI);
21901                 }
21902                 break;
21903             case NM_BREAK16:
21904                 generate_exception_end(ctx, EXCP_BREAK);
21905                 break;
21906             case NM_SDBBP16:
21907                 if (is_uhi(extract32(ctx->opcode, 0, 3))) {
21908                     gen_helper_do_semihosting(cpu_env);
21909                 } else {
21910                     if (ctx->hflags & MIPS_HFLAG_SBRI) {
21911                         generate_exception_end(ctx, EXCP_RI);
21912                     } else {
21913                         generate_exception_end(ctx, EXCP_DBp);
21914                     }
21915                 }
21916                 break;
21917             default:
21918                 generate_exception_end(ctx, EXCP_RI);
21919                 break;
21920             }
21921         }
21922         break;
21923     case NM_P16_SHIFT:
21924         {
21925             int shift = extract32(ctx->opcode, 0, 3);
21926             uint32_t opc = 0;
21927             shift = (shift == 0) ? 8 : shift;
21928
21929             switch (extract32(ctx->opcode, 3, 1)) {
21930             case NM_SLL16:
21931                 opc = OPC_SLL;
21932                 break;
21933             case NM_SRL16:
21934                 opc = OPC_SRL;
21935                 break;
21936             }
21937             gen_shift_imm(ctx, opc, rt, rs, shift);
21938         }
21939         break;
21940     case NM_P16C:
21941         switch (ctx->opcode & 1) {
21942         case NM_POOL16C_0:
21943             gen_pool16c_nanomips_insn(ctx);
21944             break;
21945         case NM_LWXS16:
21946             gen_ldxs(ctx, rt, rs, rd);
21947             break;
21948         }
21949         break;
21950     case NM_P16_A1:
21951         switch (extract32(ctx->opcode, 6, 1)) {
21952         case NM_ADDIUR1SP:
21953             imm = extract32(ctx->opcode, 0, 6) << 2;
21954             gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm);
21955             break;
21956         default:
21957             generate_exception_end(ctx, EXCP_RI);
21958             break;
21959         }
21960         break;
21961     case NM_P16_A2:
21962         switch (extract32(ctx->opcode, 3, 1)) {
21963         case NM_ADDIUR2:
21964             imm = extract32(ctx->opcode, 0, 3) << 2;
21965             gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm);
21966             break;
21967         case NM_P_ADDIURS5:
21968             rt = extract32(ctx->opcode, 5, 5);
21969             if (rt != 0) {
21970                 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
21971                 imm = (sextract32(ctx->opcode, 4, 1) << 3) |
21972                       (extract32(ctx->opcode, 0, 3));
21973                 gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm);
21974             }
21975             break;
21976         }
21977         break;
21978     case NM_P16_ADDU:
21979         switch (ctx->opcode & 0x1) {
21980         case NM_ADDU16:
21981             gen_arith(ctx, OPC_ADDU, rd, rs, rt);
21982             break;
21983         case NM_SUBU16:
21984             gen_arith(ctx, OPC_SUBU, rd, rs, rt);
21985             break;
21986         }
21987         break;
21988     case NM_P16_4X4:
21989         rt = (extract32(ctx->opcode, 9, 1) << 3) |
21990               extract32(ctx->opcode, 5, 3);
21991         rs = (extract32(ctx->opcode, 4, 1) << 3) |
21992               extract32(ctx->opcode, 0, 3);
21993         rt = decode_gpr_gpr4(rt);
21994         rs = decode_gpr_gpr4(rs);
21995         switch ((extract32(ctx->opcode, 7, 2) & 0x2) |
21996                 (extract32(ctx->opcode, 3, 1))) {
21997         case NM_ADDU4X4:
21998             check_nms(ctx);
21999             gen_arith(ctx, OPC_ADDU, rt, rs, rt);
22000             break;
22001         case NM_MUL4X4:
22002             check_nms(ctx);
22003             gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt);
22004             break;
22005         default:
22006             generate_exception_end(ctx, EXCP_RI);
22007             break;
22008         }
22009         break;
22010     case NM_LI16:
22011         {
22012             int imm = extract32(ctx->opcode, 0, 7);
22013             imm = (imm == 0x7f ? -1 : imm);
22014             if (rt != 0) {
22015                 tcg_gen_movi_tl(cpu_gpr[rt], imm);
22016             }
22017         }
22018         break;
22019     case NM_ANDI16:
22020         {
22021             uint32_t u = extract32(ctx->opcode, 0, 4);
22022             u = (u == 12) ? 0xff :
22023                 (u == 13) ? 0xffff : u;
22024             gen_logic_imm(ctx, OPC_ANDI, rt, rs, u);
22025         }
22026         break;
22027     case NM_P16_LB:
22028         offset = extract32(ctx->opcode, 0, 2);
22029         switch (extract32(ctx->opcode, 2, 2)) {
22030         case NM_LB16:
22031             gen_ld(ctx, OPC_LB, rt, rs, offset);
22032             break;
22033         case NM_SB16:
22034             rt = decode_gpr_gpr3_src_store(
22035                      NANOMIPS_EXTRACT_RD(ctx->opcode));
22036             gen_st(ctx, OPC_SB, rt, rs, offset);
22037             break;
22038         case NM_LBU16:
22039             gen_ld(ctx, OPC_LBU, rt, rs, offset);
22040             break;
22041         default:
22042             generate_exception_end(ctx, EXCP_RI);
22043             break;
22044         }
22045         break;
22046     case NM_P16_LH:
22047         offset = extract32(ctx->opcode, 1, 2) << 1;
22048         switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) {
22049         case NM_LH16:
22050             gen_ld(ctx, OPC_LH, rt, rs, offset);
22051             break;
22052         case NM_SH16:
22053             rt = decode_gpr_gpr3_src_store(
22054                      NANOMIPS_EXTRACT_RD(ctx->opcode));
22055             gen_st(ctx, OPC_SH, rt, rs, offset);
22056             break;
22057         case NM_LHU16:
22058             gen_ld(ctx, OPC_LHU, rt, rs, offset);
22059             break;
22060         default:
22061             generate_exception_end(ctx, EXCP_RI);
22062             break;
22063         }
22064         break;
22065     case NM_LW16:
22066         offset = extract32(ctx->opcode, 0, 4) << 2;
22067         gen_ld(ctx, OPC_LW, rt, rs, offset);
22068         break;
22069     case NM_LWSP16:
22070         rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22071         offset = extract32(ctx->opcode, 0, 5) << 2;
22072         gen_ld(ctx, OPC_LW, rt, 29, offset);
22073         break;
22074     case NM_LW4X4:
22075         check_nms(ctx);
22076         rt = (extract32(ctx->opcode, 9, 1) << 3) |
22077              extract32(ctx->opcode, 5, 3);
22078         rs = (extract32(ctx->opcode, 4, 1) << 3) |
22079              extract32(ctx->opcode, 0, 3);
22080         offset = (extract32(ctx->opcode, 3, 1) << 3) |
22081                  (extract32(ctx->opcode, 8, 1) << 2);
22082         rt = decode_gpr_gpr4(rt);
22083         rs = decode_gpr_gpr4(rs);
22084         gen_ld(ctx, OPC_LW, rt, rs, offset);
22085         break;
22086     case NM_SW4X4:
22087         check_nms(ctx);
22088         rt = (extract32(ctx->opcode, 9, 1) << 3) |
22089              extract32(ctx->opcode, 5, 3);
22090         rs = (extract32(ctx->opcode, 4, 1) << 3) |
22091              extract32(ctx->opcode, 0, 3);
22092         offset = (extract32(ctx->opcode, 3, 1) << 3) |
22093                  (extract32(ctx->opcode, 8, 1) << 2);
22094         rt = decode_gpr_gpr4_zero(rt);
22095         rs = decode_gpr_gpr4(rs);
22096         gen_st(ctx, OPC_SW, rt, rs, offset);
22097         break;
22098     case NM_LWGP16:
22099         offset = extract32(ctx->opcode, 0, 7) << 2;
22100         gen_ld(ctx, OPC_LW, rt, 28, offset);
22101         break;
22102     case NM_SWSP16:
22103         rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22104         offset = extract32(ctx->opcode, 0, 5) << 2;
22105         gen_st(ctx, OPC_SW, rt, 29, offset);
22106         break;
22107     case NM_SW16:
22108         rt = decode_gpr_gpr3_src_store(
22109                  NANOMIPS_EXTRACT_RD(ctx->opcode));
22110         rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
22111         offset = extract32(ctx->opcode, 0, 4) << 2;
22112         gen_st(ctx, OPC_SW, rt, rs, offset);
22113         break;
22114     case NM_SWGP16:
22115         rt = decode_gpr_gpr3_src_store(
22116                  NANOMIPS_EXTRACT_RD(ctx->opcode));
22117         offset = extract32(ctx->opcode, 0, 7) << 2;
22118         gen_st(ctx, OPC_SW, rt, 28, offset);
22119         break;
22120     case NM_BC16:
22121         gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0,
22122                            (sextract32(ctx->opcode, 0, 1) << 10) |
22123                            (extract32(ctx->opcode, 1, 9) << 1));
22124         break;
22125     case NM_BALC16:
22126         gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0,
22127                            (sextract32(ctx->opcode, 0, 1) << 10) |
22128                            (extract32(ctx->opcode, 1, 9) << 1));
22129         break;
22130     case NM_BEQZC16:
22131         gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0,
22132                            (sextract32(ctx->opcode, 0, 1) << 7) |
22133                            (extract32(ctx->opcode, 1, 6) << 1));
22134         break;
22135     case NM_BNEZC16:
22136         gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0,
22137                            (sextract32(ctx->opcode, 0, 1) << 7) |
22138                            (extract32(ctx->opcode, 1, 6) << 1));
22139         break;
22140     case NM_P16_BR:
22141         switch (ctx->opcode & 0xf) {
22142         case 0:
22143             /* P16.JRC */
22144             switch (extract32(ctx->opcode, 4, 1)) {
22145             case NM_JRC:
22146                 gen_compute_branch_nm(ctx, OPC_JR, 2,
22147                                    extract32(ctx->opcode, 5, 5), 0, 0);
22148                 break;
22149             case NM_JALRC16:
22150                 gen_compute_branch_nm(ctx, OPC_JALR, 2,
22151                                    extract32(ctx->opcode, 5, 5), 31, 0);
22152                 break;
22153             }
22154             break;
22155         default:
22156             {
22157                 /* P16.BRI */
22158                 uint32_t opc = extract32(ctx->opcode, 4, 3) <
22159                                extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE;
22160                 gen_compute_branch_nm(ctx, opc, 2, rs, rt,
22161                                    extract32(ctx->opcode, 0, 4) << 1);
22162             }
22163             break;
22164         }
22165         break;
22166     case NM_P16_SR:
22167         {
22168             int count = extract32(ctx->opcode, 0, 4);
22169             int u = extract32(ctx->opcode, 4, 4) << 4;
22170
22171             rt = 30 + extract32(ctx->opcode, 9, 1);
22172             switch (extract32(ctx->opcode, 8, 1)) {
22173             case NM_SAVE16:
22174                 gen_save(ctx, rt, count, 0, u);
22175                 break;
22176             case NM_RESTORE_JRC16:
22177                 gen_restore(ctx, rt, count, 0, u);
22178                 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
22179                 break;
22180             }
22181         }
22182         break;
22183     case NM_MOVEP:
22184     case NM_MOVEPREV:
22185         check_nms(ctx);
22186         {
22187             static const int gpr2reg1[] = {4, 5, 6, 7};
22188             static const int gpr2reg2[] = {5, 6, 7, 8};
22189             int re;
22190             int rd2 = extract32(ctx->opcode, 3, 1) << 1 |
22191                       extract32(ctx->opcode, 8, 1);
22192             int r1 = gpr2reg1[rd2];
22193             int r2 = gpr2reg2[rd2];
22194             int r3 = extract32(ctx->opcode, 4, 1) << 3 |
22195                      extract32(ctx->opcode, 0, 3);
22196             int r4 = extract32(ctx->opcode, 9, 1) << 3 |
22197                      extract32(ctx->opcode, 5, 3);
22198             TCGv t0 = tcg_temp_new();
22199             TCGv t1 = tcg_temp_new();
22200             if (op == NM_MOVEP) {
22201                 rd = r1;
22202                 re = r2;
22203                 rs = decode_gpr_gpr4_zero(r3);
22204                 rt = decode_gpr_gpr4_zero(r4);
22205             } else {
22206                 rd = decode_gpr_gpr4(r3);
22207                 re = decode_gpr_gpr4(r4);
22208                 rs = r1;
22209                 rt = r2;
22210             }
22211             gen_load_gpr(t0, rs);
22212             gen_load_gpr(t1, rt);
22213             tcg_gen_mov_tl(cpu_gpr[rd], t0);
22214             tcg_gen_mov_tl(cpu_gpr[re], t1);
22215             tcg_temp_free(t0);
22216             tcg_temp_free(t1);
22217         }
22218         break;
22219     default:
22220         return decode_nanomips_32_48_opc(env, ctx);
22221     }
22222
22223     return 2;
22224 }
22225
22226
22227 /* SmartMIPS extension to MIPS32 */
22228
22229 #if defined(TARGET_MIPS64)
22230
22231 /* MDMX extension to MIPS64 */
22232
22233 #endif
22234
22235 /* MIPSDSP functions. */
22236 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
22237                            int rd, int base, int offset)
22238 {
22239     TCGv t0;
22240
22241     check_dsp(ctx);
22242     t0 = tcg_temp_new();
22243
22244     if (base == 0) {
22245         gen_load_gpr(t0, offset);
22246     } else if (offset == 0) {
22247         gen_load_gpr(t0, base);
22248     } else {
22249         gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
22250     }
22251
22252     switch (opc) {
22253     case OPC_LBUX:
22254         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
22255         gen_store_gpr(t0, rd);
22256         break;
22257     case OPC_LHX:
22258         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
22259         gen_store_gpr(t0, rd);
22260         break;
22261     case OPC_LWX:
22262         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
22263         gen_store_gpr(t0, rd);
22264         break;
22265 #if defined(TARGET_MIPS64)
22266     case OPC_LDX:
22267         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
22268         gen_store_gpr(t0, rd);
22269         break;
22270 #endif
22271     }
22272     tcg_temp_free(t0);
22273 }
22274
22275 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
22276                               int ret, int v1, int v2)
22277 {
22278     TCGv v1_t;
22279     TCGv v2_t;
22280
22281     if (ret == 0) {
22282         /* Treat as NOP. */
22283         return;
22284     }
22285
22286     v1_t = tcg_temp_new();
22287     v2_t = tcg_temp_new();
22288
22289     gen_load_gpr(v1_t, v1);
22290     gen_load_gpr(v2_t, v2);
22291
22292     switch (op1) {
22293     /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
22294     case OPC_MULT_G_2E:
22295         check_dsp_r2(ctx);
22296         switch (op2) {
22297         case OPC_ADDUH_QB:
22298             gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
22299             break;
22300         case OPC_ADDUH_R_QB:
22301             gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22302             break;
22303         case OPC_ADDQH_PH:
22304             gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
22305             break;
22306         case OPC_ADDQH_R_PH:
22307             gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22308             break;
22309         case OPC_ADDQH_W:
22310             gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
22311             break;
22312         case OPC_ADDQH_R_W:
22313             gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22314             break;
22315         case OPC_SUBUH_QB:
22316             gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
22317             break;
22318         case OPC_SUBUH_R_QB:
22319             gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22320             break;
22321         case OPC_SUBQH_PH:
22322             gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
22323             break;
22324         case OPC_SUBQH_R_PH:
22325             gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22326             break;
22327         case OPC_SUBQH_W:
22328             gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
22329             break;
22330         case OPC_SUBQH_R_W:
22331             gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22332             break;
22333         }
22334         break;
22335     case OPC_ABSQ_S_PH_DSP:
22336         switch (op2) {
22337         case OPC_ABSQ_S_QB:
22338             check_dsp_r2(ctx);
22339             gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
22340             break;
22341         case OPC_ABSQ_S_PH:
22342             check_dsp(ctx);
22343             gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
22344             break;
22345         case OPC_ABSQ_S_W:
22346             check_dsp(ctx);
22347             gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
22348             break;
22349         case OPC_PRECEQ_W_PHL:
22350             check_dsp(ctx);
22351             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
22352             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22353             break;
22354         case OPC_PRECEQ_W_PHR:
22355             check_dsp(ctx);
22356             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
22357             tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
22358             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22359             break;
22360         case OPC_PRECEQU_PH_QBL:
22361             check_dsp(ctx);
22362             gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
22363             break;
22364         case OPC_PRECEQU_PH_QBR:
22365             check_dsp(ctx);
22366             gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
22367             break;
22368         case OPC_PRECEQU_PH_QBLA:
22369             check_dsp(ctx);
22370             gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
22371             break;
22372         case OPC_PRECEQU_PH_QBRA:
22373             check_dsp(ctx);
22374             gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
22375             break;
22376         case OPC_PRECEU_PH_QBL:
22377             check_dsp(ctx);
22378             gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
22379             break;
22380         case OPC_PRECEU_PH_QBR:
22381             check_dsp(ctx);
22382             gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
22383             break;
22384         case OPC_PRECEU_PH_QBLA:
22385             check_dsp(ctx);
22386             gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
22387             break;
22388         case OPC_PRECEU_PH_QBRA:
22389             check_dsp(ctx);
22390             gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
22391             break;
22392         }
22393         break;
22394     case OPC_ADDU_QB_DSP:
22395         switch (op2) {
22396         case OPC_ADDQ_PH:
22397             check_dsp(ctx);
22398             gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22399             break;
22400         case OPC_ADDQ_S_PH:
22401             check_dsp(ctx);
22402             gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22403             break;
22404         case OPC_ADDQ_S_W:
22405             check_dsp(ctx);
22406             gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22407             break;
22408         case OPC_ADDU_QB:
22409             check_dsp(ctx);
22410             gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22411             break;
22412         case OPC_ADDU_S_QB:
22413             check_dsp(ctx);
22414             gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22415             break;
22416         case OPC_ADDU_PH:
22417             check_dsp_r2(ctx);
22418             gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22419             break;
22420         case OPC_ADDU_S_PH:
22421             check_dsp_r2(ctx);
22422             gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22423             break;
22424         case OPC_SUBQ_PH:
22425             check_dsp(ctx);
22426             gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22427             break;
22428         case OPC_SUBQ_S_PH:
22429             check_dsp(ctx);
22430             gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22431             break;
22432         case OPC_SUBQ_S_W:
22433             check_dsp(ctx);
22434             gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22435             break;
22436         case OPC_SUBU_QB:
22437             check_dsp(ctx);
22438             gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22439             break;
22440         case OPC_SUBU_S_QB:
22441             check_dsp(ctx);
22442             gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22443             break;
22444         case OPC_SUBU_PH:
22445             check_dsp_r2(ctx);
22446             gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22447             break;
22448         case OPC_SUBU_S_PH:
22449             check_dsp_r2(ctx);
22450             gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22451             break;
22452         case OPC_ADDSC:
22453             check_dsp(ctx);
22454             gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22455             break;
22456         case OPC_ADDWC:
22457             check_dsp(ctx);
22458             gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22459             break;
22460         case OPC_MODSUB:
22461             check_dsp(ctx);
22462             gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
22463             break;
22464         case OPC_RADDU_W_QB:
22465             check_dsp(ctx);
22466             gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
22467             break;
22468         }
22469         break;
22470     case OPC_CMPU_EQ_QB_DSP:
22471         switch (op2) {
22472         case OPC_PRECR_QB_PH:
22473             check_dsp_r2(ctx);
22474             gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22475             break;
22476         case OPC_PRECRQ_QB_PH:
22477             check_dsp(ctx);
22478             gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22479             break;
22480         case OPC_PRECR_SRA_PH_W:
22481             check_dsp_r2(ctx);
22482             {
22483                 TCGv_i32 sa_t = tcg_const_i32(v2);
22484                 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
22485                                           cpu_gpr[ret]);
22486                 tcg_temp_free_i32(sa_t);
22487                 break;
22488             }
22489         case OPC_PRECR_SRA_R_PH_W:
22490             check_dsp_r2(ctx);
22491             {
22492                 TCGv_i32 sa_t = tcg_const_i32(v2);
22493                 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
22494                                             cpu_gpr[ret]);
22495                 tcg_temp_free_i32(sa_t);
22496                 break;
22497             }
22498         case OPC_PRECRQ_PH_W:
22499             check_dsp(ctx);
22500             gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
22501             break;
22502         case OPC_PRECRQ_RS_PH_W:
22503             check_dsp(ctx);
22504             gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22505             break;
22506         case OPC_PRECRQU_S_QB_PH:
22507             check_dsp(ctx);
22508             gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22509             break;
22510         }
22511         break;
22512 #ifdef TARGET_MIPS64
22513     case OPC_ABSQ_S_QH_DSP:
22514         switch (op2) {
22515         case OPC_PRECEQ_L_PWL:
22516             check_dsp(ctx);
22517             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
22518             break;
22519         case OPC_PRECEQ_L_PWR:
22520             check_dsp(ctx);
22521             tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
22522             break;
22523         case OPC_PRECEQ_PW_QHL:
22524             check_dsp(ctx);
22525             gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
22526             break;
22527         case OPC_PRECEQ_PW_QHR:
22528             check_dsp(ctx);
22529             gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
22530             break;
22531         case OPC_PRECEQ_PW_QHLA:
22532             check_dsp(ctx);
22533             gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
22534             break;
22535         case OPC_PRECEQ_PW_QHRA:
22536             check_dsp(ctx);
22537             gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
22538             break;
22539         case OPC_PRECEQU_QH_OBL:
22540             check_dsp(ctx);
22541             gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
22542             break;
22543         case OPC_PRECEQU_QH_OBR:
22544             check_dsp(ctx);
22545             gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
22546             break;
22547         case OPC_PRECEQU_QH_OBLA:
22548             check_dsp(ctx);
22549             gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
22550             break;
22551         case OPC_PRECEQU_QH_OBRA:
22552             check_dsp(ctx);
22553             gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
22554             break;
22555         case OPC_PRECEU_QH_OBL:
22556             check_dsp(ctx);
22557             gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
22558             break;
22559         case OPC_PRECEU_QH_OBR:
22560             check_dsp(ctx);
22561             gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
22562             break;
22563         case OPC_PRECEU_QH_OBLA:
22564             check_dsp(ctx);
22565             gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
22566             break;
22567         case OPC_PRECEU_QH_OBRA:
22568             check_dsp(ctx);
22569             gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
22570             break;
22571         case OPC_ABSQ_S_OB:
22572             check_dsp_r2(ctx);
22573             gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
22574             break;
22575         case OPC_ABSQ_S_PW:
22576             check_dsp(ctx);
22577             gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
22578             break;
22579         case OPC_ABSQ_S_QH:
22580             check_dsp(ctx);
22581             gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
22582             break;
22583         }
22584         break;
22585     case OPC_ADDU_OB_DSP:
22586         switch (op2) {
22587         case OPC_RADDU_L_OB:
22588             check_dsp(ctx);
22589             gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
22590             break;
22591         case OPC_SUBQ_PW:
22592             check_dsp(ctx);
22593             gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22594             break;
22595         case OPC_SUBQ_S_PW:
22596             check_dsp(ctx);
22597             gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22598             break;
22599         case OPC_SUBQ_QH:
22600             check_dsp(ctx);
22601             gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22602             break;
22603         case OPC_SUBQ_S_QH:
22604             check_dsp(ctx);
22605             gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22606             break;
22607         case OPC_SUBU_OB:
22608             check_dsp(ctx);
22609             gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22610             break;
22611         case OPC_SUBU_S_OB:
22612             check_dsp(ctx);
22613             gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22614             break;
22615         case OPC_SUBU_QH:
22616             check_dsp_r2(ctx);
22617             gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22618             break;
22619         case OPC_SUBU_S_QH:
22620             check_dsp_r2(ctx);
22621             gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22622             break;
22623         case OPC_SUBUH_OB:
22624             check_dsp_r2(ctx);
22625             gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
22626             break;
22627         case OPC_SUBUH_R_OB:
22628             check_dsp_r2(ctx);
22629             gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22630             break;
22631         case OPC_ADDQ_PW:
22632             check_dsp(ctx);
22633             gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22634             break;
22635         case OPC_ADDQ_S_PW:
22636             check_dsp(ctx);
22637             gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22638             break;
22639         case OPC_ADDQ_QH:
22640             check_dsp(ctx);
22641             gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22642             break;
22643         case OPC_ADDQ_S_QH:
22644             check_dsp(ctx);
22645             gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22646             break;
22647         case OPC_ADDU_OB:
22648             check_dsp(ctx);
22649             gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22650             break;
22651         case OPC_ADDU_S_OB:
22652             check_dsp(ctx);
22653             gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22654             break;
22655         case OPC_ADDU_QH:
22656             check_dsp_r2(ctx);
22657             gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22658             break;
22659         case OPC_ADDU_S_QH:
22660             check_dsp_r2(ctx);
22661             gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22662             break;
22663         case OPC_ADDUH_OB:
22664             check_dsp_r2(ctx);
22665             gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
22666             break;
22667         case OPC_ADDUH_R_OB:
22668             check_dsp_r2(ctx);
22669             gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22670             break;
22671         }
22672         break;
22673     case OPC_CMPU_EQ_OB_DSP:
22674         switch (op2) {
22675         case OPC_PRECR_OB_QH:
22676             check_dsp_r2(ctx);
22677             gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22678             break;
22679         case OPC_PRECR_SRA_QH_PW:
22680             check_dsp_r2(ctx);
22681             {
22682                 TCGv_i32 ret_t = tcg_const_i32(ret);
22683                 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
22684                 tcg_temp_free_i32(ret_t);
22685                 break;
22686             }
22687         case OPC_PRECR_SRA_R_QH_PW:
22688             check_dsp_r2(ctx);
22689             {
22690                 TCGv_i32 sa_v = tcg_const_i32(ret);
22691                 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
22692                 tcg_temp_free_i32(sa_v);
22693                 break;
22694             }
22695         case OPC_PRECRQ_OB_QH:
22696             check_dsp(ctx);
22697             gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22698             break;
22699         case OPC_PRECRQ_PW_L:
22700             check_dsp(ctx);
22701             gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
22702             break;
22703         case OPC_PRECRQ_QH_PW:
22704             check_dsp(ctx);
22705             gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
22706             break;
22707         case OPC_PRECRQ_RS_QH_PW:
22708             check_dsp(ctx);
22709             gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22710             break;
22711         case OPC_PRECRQU_S_OB_QH:
22712             check_dsp(ctx);
22713             gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22714             break;
22715         }
22716         break;
22717 #endif
22718     }
22719
22720     tcg_temp_free(v1_t);
22721     tcg_temp_free(v2_t);
22722 }
22723
22724 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
22725                               int ret, int v1, int v2)
22726 {
22727     uint32_t op2;
22728     TCGv t0;
22729     TCGv v1_t;
22730     TCGv v2_t;
22731
22732     if (ret == 0) {
22733         /* Treat as NOP. */
22734         return;
22735     }
22736
22737     t0 = tcg_temp_new();
22738     v1_t = tcg_temp_new();
22739     v2_t = tcg_temp_new();
22740
22741     tcg_gen_movi_tl(t0, v1);
22742     gen_load_gpr(v1_t, v1);
22743     gen_load_gpr(v2_t, v2);
22744
22745     switch (opc) {
22746     case OPC_SHLL_QB_DSP:
22747         {
22748             op2 = MASK_SHLL_QB(ctx->opcode);
22749             switch (op2) {
22750             case OPC_SHLL_QB:
22751                 check_dsp(ctx);
22752                 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
22753                 break;
22754             case OPC_SHLLV_QB:
22755                 check_dsp(ctx);
22756                 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22757                 break;
22758             case OPC_SHLL_PH:
22759                 check_dsp(ctx);
22760                 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22761                 break;
22762             case OPC_SHLLV_PH:
22763                 check_dsp(ctx);
22764                 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22765                 break;
22766             case OPC_SHLL_S_PH:
22767                 check_dsp(ctx);
22768                 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22769                 break;
22770             case OPC_SHLLV_S_PH:
22771                 check_dsp(ctx);
22772                 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22773                 break;
22774             case OPC_SHLL_S_W:
22775                 check_dsp(ctx);
22776                 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
22777                 break;
22778             case OPC_SHLLV_S_W:
22779                 check_dsp(ctx);
22780                 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22781                 break;
22782             case OPC_SHRL_QB:
22783                 check_dsp(ctx);
22784                 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
22785                 break;
22786             case OPC_SHRLV_QB:
22787                 check_dsp(ctx);
22788                 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
22789                 break;
22790             case OPC_SHRL_PH:
22791                 check_dsp_r2(ctx);
22792                 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
22793                 break;
22794             case OPC_SHRLV_PH:
22795                 check_dsp_r2(ctx);
22796                 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
22797                 break;
22798             case OPC_SHRA_QB:
22799                 check_dsp_r2(ctx);
22800                 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
22801                 break;
22802             case OPC_SHRA_R_QB:
22803                 check_dsp_r2(ctx);
22804                 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
22805                 break;
22806             case OPC_SHRAV_QB:
22807                 check_dsp_r2(ctx);
22808                 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
22809                 break;
22810             case OPC_SHRAV_R_QB:
22811                 check_dsp_r2(ctx);
22812                 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
22813                 break;
22814             case OPC_SHRA_PH:
22815                 check_dsp(ctx);
22816                 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
22817                 break;
22818             case OPC_SHRA_R_PH:
22819                 check_dsp(ctx);
22820                 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
22821                 break;
22822             case OPC_SHRAV_PH:
22823                 check_dsp(ctx);
22824                 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
22825                 break;
22826             case OPC_SHRAV_R_PH:
22827                 check_dsp(ctx);
22828                 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
22829                 break;
22830             case OPC_SHRA_R_W:
22831                 check_dsp(ctx);
22832                 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
22833                 break;
22834             case OPC_SHRAV_R_W:
22835                 check_dsp(ctx);
22836                 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
22837                 break;
22838             default:            /* Invalid */
22839                 MIPS_INVAL("MASK SHLL.QB");
22840                 generate_exception_end(ctx, EXCP_RI);
22841                 break;
22842             }
22843             break;
22844         }
22845 #ifdef TARGET_MIPS64
22846     case OPC_SHLL_OB_DSP:
22847         op2 = MASK_SHLL_OB(ctx->opcode);
22848         switch (op2) {
22849         case OPC_SHLL_PW:
22850             check_dsp(ctx);
22851             gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22852             break;
22853         case OPC_SHLLV_PW:
22854             check_dsp(ctx);
22855             gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22856             break;
22857         case OPC_SHLL_S_PW:
22858             check_dsp(ctx);
22859             gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22860             break;
22861         case OPC_SHLLV_S_PW:
22862             check_dsp(ctx);
22863             gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22864             break;
22865         case OPC_SHLL_OB:
22866             check_dsp(ctx);
22867             gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
22868             break;
22869         case OPC_SHLLV_OB:
22870             check_dsp(ctx);
22871             gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22872             break;
22873         case OPC_SHLL_QH:
22874             check_dsp(ctx);
22875             gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
22876             break;
22877         case OPC_SHLLV_QH:
22878             check_dsp(ctx);
22879             gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22880             break;
22881         case OPC_SHLL_S_QH:
22882             check_dsp(ctx);
22883             gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
22884             break;
22885         case OPC_SHLLV_S_QH:
22886             check_dsp(ctx);
22887             gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22888             break;
22889         case OPC_SHRA_OB:
22890             check_dsp_r2(ctx);
22891             gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
22892             break;
22893         case OPC_SHRAV_OB:
22894             check_dsp_r2(ctx);
22895             gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
22896             break;
22897         case OPC_SHRA_R_OB:
22898             check_dsp_r2(ctx);
22899             gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
22900             break;
22901         case OPC_SHRAV_R_OB:
22902             check_dsp_r2(ctx);
22903             gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
22904             break;
22905         case OPC_SHRA_PW:
22906             check_dsp(ctx);
22907             gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
22908             break;
22909         case OPC_SHRAV_PW:
22910             check_dsp(ctx);
22911             gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
22912             break;
22913         case OPC_SHRA_R_PW:
22914             check_dsp(ctx);
22915             gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
22916             break;
22917         case OPC_SHRAV_R_PW:
22918             check_dsp(ctx);
22919             gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
22920             break;
22921         case OPC_SHRA_QH:
22922             check_dsp(ctx);
22923             gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
22924             break;
22925         case OPC_SHRAV_QH:
22926             check_dsp(ctx);
22927             gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
22928             break;
22929         case OPC_SHRA_R_QH:
22930             check_dsp(ctx);
22931             gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
22932             break;
22933         case OPC_SHRAV_R_QH:
22934             check_dsp(ctx);
22935             gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
22936             break;
22937         case OPC_SHRL_OB:
22938             check_dsp(ctx);
22939             gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
22940             break;
22941         case OPC_SHRLV_OB:
22942             check_dsp(ctx);
22943             gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
22944             break;
22945         case OPC_SHRL_QH:
22946             check_dsp_r2(ctx);
22947             gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
22948             break;
22949         case OPC_SHRLV_QH:
22950             check_dsp_r2(ctx);
22951             gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
22952             break;
22953         default:            /* Invalid */
22954             MIPS_INVAL("MASK SHLL.OB");
22955             generate_exception_end(ctx, EXCP_RI);
22956             break;
22957         }
22958         break;
22959 #endif
22960     }
22961
22962     tcg_temp_free(t0);
22963     tcg_temp_free(v1_t);
22964     tcg_temp_free(v2_t);
22965 }
22966
22967 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
22968                                  int ret, int v1, int v2, int check_ret)
22969 {
22970     TCGv_i32 t0;
22971     TCGv v1_t;
22972     TCGv v2_t;
22973
22974     if ((ret == 0) && (check_ret == 1)) {
22975         /* Treat as NOP. */
22976         return;
22977     }
22978
22979     t0 = tcg_temp_new_i32();
22980     v1_t = tcg_temp_new();
22981     v2_t = tcg_temp_new();
22982
22983     tcg_gen_movi_i32(t0, ret);
22984     gen_load_gpr(v1_t, v1);
22985     gen_load_gpr(v2_t, v2);
22986
22987     switch (op1) {
22988     /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
22989      * the same mask and op1. */
22990     case OPC_MULT_G_2E:
22991         check_dsp_r2(ctx);
22992         switch (op2) {
22993         case  OPC_MUL_PH:
22994             gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22995             break;
22996         case  OPC_MUL_S_PH:
22997             gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22998             break;
22999         case OPC_MULQ_S_W:
23000             gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23001             break;
23002         case OPC_MULQ_RS_W:
23003             gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23004             break;
23005         }
23006         break;
23007     case OPC_DPA_W_PH_DSP:
23008         switch (op2) {
23009         case OPC_DPAU_H_QBL:
23010             check_dsp(ctx);
23011             gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
23012             break;
23013         case OPC_DPAU_H_QBR:
23014             check_dsp(ctx);
23015             gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
23016             break;
23017         case OPC_DPSU_H_QBL:
23018             check_dsp(ctx);
23019             gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
23020             break;
23021         case OPC_DPSU_H_QBR:
23022             check_dsp(ctx);
23023             gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
23024             break;
23025         case OPC_DPA_W_PH:
23026             check_dsp_r2(ctx);
23027             gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
23028             break;
23029         case OPC_DPAX_W_PH:
23030             check_dsp_r2(ctx);
23031             gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
23032             break;
23033         case OPC_DPAQ_S_W_PH:
23034             check_dsp(ctx);
23035             gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23036             break;
23037         case OPC_DPAQX_S_W_PH:
23038             check_dsp_r2(ctx);
23039             gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
23040             break;
23041         case OPC_DPAQX_SA_W_PH:
23042             check_dsp_r2(ctx);
23043             gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
23044             break;
23045         case OPC_DPS_W_PH:
23046             check_dsp_r2(ctx);
23047             gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
23048             break;
23049         case OPC_DPSX_W_PH:
23050             check_dsp_r2(ctx);
23051             gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
23052             break;
23053         case OPC_DPSQ_S_W_PH:
23054             check_dsp(ctx);
23055             gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23056             break;
23057         case OPC_DPSQX_S_W_PH:
23058             check_dsp_r2(ctx);
23059             gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
23060             break;
23061         case OPC_DPSQX_SA_W_PH:
23062             check_dsp_r2(ctx);
23063             gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
23064             break;
23065         case OPC_MULSAQ_S_W_PH:
23066             check_dsp(ctx);
23067             gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23068             break;
23069         case OPC_DPAQ_SA_L_W:
23070             check_dsp(ctx);
23071             gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
23072             break;
23073         case OPC_DPSQ_SA_L_W:
23074             check_dsp(ctx);
23075             gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
23076             break;
23077         case OPC_MAQ_S_W_PHL:
23078             check_dsp(ctx);
23079             gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
23080             break;
23081         case OPC_MAQ_S_W_PHR:
23082             check_dsp(ctx);
23083             gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
23084             break;
23085         case OPC_MAQ_SA_W_PHL:
23086             check_dsp(ctx);
23087             gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
23088             break;
23089         case OPC_MAQ_SA_W_PHR:
23090             check_dsp(ctx);
23091             gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
23092             break;
23093         case OPC_MULSA_W_PH:
23094             check_dsp_r2(ctx);
23095             gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
23096             break;
23097         }
23098         break;
23099 #ifdef TARGET_MIPS64
23100     case OPC_DPAQ_W_QH_DSP:
23101         {
23102             int ac = ret & 0x03;
23103             tcg_gen_movi_i32(t0, ac);
23104
23105             switch (op2) {
23106             case OPC_DMADD:
23107                 check_dsp(ctx);
23108                 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
23109                 break;
23110             case OPC_DMADDU:
23111                 check_dsp(ctx);
23112                 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
23113                 break;
23114             case OPC_DMSUB:
23115                 check_dsp(ctx);
23116                 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
23117                 break;
23118             case OPC_DMSUBU:
23119                 check_dsp(ctx);
23120                 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
23121                 break;
23122             case OPC_DPA_W_QH:
23123                 check_dsp_r2(ctx);
23124                 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
23125                 break;
23126             case OPC_DPAQ_S_W_QH:
23127                 check_dsp(ctx);
23128                 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23129                 break;
23130             case OPC_DPAQ_SA_L_PW:
23131                 check_dsp(ctx);
23132                 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
23133                 break;
23134             case OPC_DPAU_H_OBL:
23135                 check_dsp(ctx);
23136                 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
23137                 break;
23138             case OPC_DPAU_H_OBR:
23139                 check_dsp(ctx);
23140                 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
23141                 break;
23142             case OPC_DPS_W_QH:
23143                 check_dsp_r2(ctx);
23144                 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
23145                 break;
23146             case OPC_DPSQ_S_W_QH:
23147                 check_dsp(ctx);
23148                 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23149                 break;
23150             case OPC_DPSQ_SA_L_PW:
23151                 check_dsp(ctx);
23152                 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
23153                 break;
23154             case OPC_DPSU_H_OBL:
23155                 check_dsp(ctx);
23156                 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
23157                 break;
23158             case OPC_DPSU_H_OBR:
23159                 check_dsp(ctx);
23160                 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
23161                 break;
23162             case OPC_MAQ_S_L_PWL:
23163                 check_dsp(ctx);
23164                 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
23165                 break;
23166             case OPC_MAQ_S_L_PWR:
23167                 check_dsp(ctx);
23168                 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
23169                 break;
23170             case OPC_MAQ_S_W_QHLL:
23171                 check_dsp(ctx);
23172                 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
23173                 break;
23174             case OPC_MAQ_SA_W_QHLL:
23175                 check_dsp(ctx);
23176                 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
23177                 break;
23178             case OPC_MAQ_S_W_QHLR:
23179                 check_dsp(ctx);
23180                 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
23181                 break;
23182             case OPC_MAQ_SA_W_QHLR:
23183                 check_dsp(ctx);
23184                 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
23185                 break;
23186             case OPC_MAQ_S_W_QHRL:
23187                 check_dsp(ctx);
23188                 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
23189                 break;
23190             case OPC_MAQ_SA_W_QHRL:
23191                 check_dsp(ctx);
23192                 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
23193                 break;
23194             case OPC_MAQ_S_W_QHRR:
23195                 check_dsp(ctx);
23196                 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
23197                 break;
23198             case OPC_MAQ_SA_W_QHRR:
23199                 check_dsp(ctx);
23200                 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
23201                 break;
23202             case OPC_MULSAQ_S_L_PW:
23203                 check_dsp(ctx);
23204                 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
23205                 break;
23206             case OPC_MULSAQ_S_W_QH:
23207                 check_dsp(ctx);
23208                 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23209                 break;
23210             }
23211         }
23212         break;
23213 #endif
23214     case OPC_ADDU_QB_DSP:
23215         switch (op2) {
23216         case OPC_MULEU_S_PH_QBL:
23217             check_dsp(ctx);
23218             gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23219             break;
23220         case OPC_MULEU_S_PH_QBR:
23221             check_dsp(ctx);
23222             gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23223             break;
23224         case OPC_MULQ_RS_PH:
23225             check_dsp(ctx);
23226             gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23227             break;
23228         case OPC_MULEQ_S_W_PHL:
23229             check_dsp(ctx);
23230             gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23231             break;
23232         case OPC_MULEQ_S_W_PHR:
23233             check_dsp(ctx);
23234             gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23235             break;
23236         case OPC_MULQ_S_PH:
23237             check_dsp_r2(ctx);
23238             gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23239             break;
23240         }
23241         break;
23242 #ifdef TARGET_MIPS64
23243     case OPC_ADDU_OB_DSP:
23244         switch (op2) {
23245         case OPC_MULEQ_S_PW_QHL:
23246             check_dsp(ctx);
23247             gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23248             break;
23249         case OPC_MULEQ_S_PW_QHR:
23250             check_dsp(ctx);
23251             gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23252             break;
23253         case OPC_MULEU_S_QH_OBL:
23254             check_dsp(ctx);
23255             gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23256             break;
23257         case OPC_MULEU_S_QH_OBR:
23258             check_dsp(ctx);
23259             gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23260             break;
23261         case OPC_MULQ_RS_QH:
23262             check_dsp(ctx);
23263             gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23264             break;
23265         }
23266         break;
23267 #endif
23268     }
23269
23270     tcg_temp_free_i32(t0);
23271     tcg_temp_free(v1_t);
23272     tcg_temp_free(v2_t);
23273 }
23274
23275 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
23276                                 int ret, int val)
23277 {
23278     int16_t imm;
23279     TCGv t0;
23280     TCGv val_t;
23281
23282     if (ret == 0) {
23283         /* Treat as NOP. */
23284         return;
23285     }
23286
23287     t0 = tcg_temp_new();
23288     val_t = tcg_temp_new();
23289     gen_load_gpr(val_t, val);
23290
23291     switch (op1) {
23292     case OPC_ABSQ_S_PH_DSP:
23293         switch (op2) {
23294         case OPC_BITREV:
23295             check_dsp(ctx);
23296             gen_helper_bitrev(cpu_gpr[ret], val_t);
23297             break;
23298         case OPC_REPL_QB:
23299             check_dsp(ctx);
23300             {
23301                 target_long result;
23302                 imm = (ctx->opcode >> 16) & 0xFF;
23303                 result = (uint32_t)imm << 24 |
23304                          (uint32_t)imm << 16 |
23305                          (uint32_t)imm << 8  |
23306                          (uint32_t)imm;
23307                 result = (int32_t)result;
23308                 tcg_gen_movi_tl(cpu_gpr[ret], result);
23309             }
23310             break;
23311         case OPC_REPLV_QB:
23312             check_dsp(ctx);
23313             tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23314             tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23315             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23316             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23317             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23318             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23319             break;
23320         case OPC_REPL_PH:
23321             check_dsp(ctx);
23322             {
23323                 imm = (ctx->opcode >> 16) & 0x03FF;
23324                 imm = (int16_t)(imm << 6) >> 6;
23325                 tcg_gen_movi_tl(cpu_gpr[ret], \
23326                                 (target_long)((int32_t)imm << 16 | \
23327                                 (uint16_t)imm));
23328             }
23329             break;
23330         case OPC_REPLV_PH:
23331             check_dsp(ctx);
23332             tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23333             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23334             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23335             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23336             break;
23337         }
23338         break;
23339 #ifdef TARGET_MIPS64
23340     case OPC_ABSQ_S_QH_DSP:
23341         switch (op2) {
23342         case OPC_REPL_OB:
23343             check_dsp(ctx);
23344             {
23345                 target_long temp;
23346
23347                 imm = (ctx->opcode >> 16) & 0xFF;
23348                 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
23349                 temp = (temp << 16) | temp;
23350                 temp = (temp << 32) | temp;
23351                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23352                 break;
23353             }
23354         case OPC_REPL_PW:
23355             check_dsp(ctx);
23356             {
23357                 target_long temp;
23358
23359                 imm = (ctx->opcode >> 16) & 0x03FF;
23360                 imm = (int16_t)(imm << 6) >> 6;
23361                 temp = ((target_long)imm << 32) \
23362                        | ((target_long)imm & 0xFFFFFFFF);
23363                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23364                 break;
23365             }
23366         case OPC_REPL_QH:
23367             check_dsp(ctx);
23368             {
23369                 target_long temp;
23370
23371                 imm = (ctx->opcode >> 16) & 0x03FF;
23372                 imm = (int16_t)(imm << 6) >> 6;
23373
23374                 temp = ((uint64_t)(uint16_t)imm << 48) |
23375                        ((uint64_t)(uint16_t)imm << 32) |
23376                        ((uint64_t)(uint16_t)imm << 16) |
23377                        (uint64_t)(uint16_t)imm;
23378                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23379                 break;
23380             }
23381         case OPC_REPLV_OB:
23382             check_dsp(ctx);
23383             tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23384             tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23385             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23386             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23387             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23388             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23389             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23390             break;
23391         case OPC_REPLV_PW:
23392             check_dsp(ctx);
23393             tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
23394             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23395             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23396             break;
23397         case OPC_REPLV_QH:
23398             check_dsp(ctx);
23399             tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23400             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23401             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23402             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23403             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23404             break;
23405         }
23406         break;
23407 #endif
23408     }
23409     tcg_temp_free(t0);
23410     tcg_temp_free(val_t);
23411 }
23412
23413 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
23414                                      uint32_t op1, uint32_t op2,
23415                                      int ret, int v1, int v2, int check_ret)
23416 {
23417     TCGv t1;
23418     TCGv v1_t;
23419     TCGv v2_t;
23420
23421     if ((ret == 0) && (check_ret == 1)) {
23422         /* Treat as NOP. */
23423         return;
23424     }
23425
23426     t1 = tcg_temp_new();
23427     v1_t = tcg_temp_new();
23428     v2_t = tcg_temp_new();
23429
23430     gen_load_gpr(v1_t, v1);
23431     gen_load_gpr(v2_t, v2);
23432
23433     switch (op1) {
23434     case OPC_CMPU_EQ_QB_DSP:
23435         switch (op2) {
23436         case OPC_CMPU_EQ_QB:
23437             check_dsp(ctx);
23438             gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
23439             break;
23440         case OPC_CMPU_LT_QB:
23441             check_dsp(ctx);
23442             gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
23443             break;
23444         case OPC_CMPU_LE_QB:
23445             check_dsp(ctx);
23446             gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
23447             break;
23448         case OPC_CMPGU_EQ_QB:
23449             check_dsp(ctx);
23450             gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
23451             break;
23452         case OPC_CMPGU_LT_QB:
23453             check_dsp(ctx);
23454             gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
23455             break;
23456         case OPC_CMPGU_LE_QB:
23457             check_dsp(ctx);
23458             gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
23459             break;
23460         case OPC_CMPGDU_EQ_QB:
23461             check_dsp_r2(ctx);
23462             gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
23463             tcg_gen_mov_tl(cpu_gpr[ret], t1);
23464             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23465             tcg_gen_shli_tl(t1, t1, 24);
23466             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23467             break;
23468         case OPC_CMPGDU_LT_QB:
23469             check_dsp_r2(ctx);
23470             gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
23471             tcg_gen_mov_tl(cpu_gpr[ret], t1);
23472             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23473             tcg_gen_shli_tl(t1, t1, 24);
23474             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23475             break;
23476         case OPC_CMPGDU_LE_QB:
23477             check_dsp_r2(ctx);
23478             gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
23479             tcg_gen_mov_tl(cpu_gpr[ret], t1);
23480             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23481             tcg_gen_shli_tl(t1, t1, 24);
23482             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23483             break;
23484         case OPC_CMP_EQ_PH:
23485             check_dsp(ctx);
23486             gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
23487             break;
23488         case OPC_CMP_LT_PH:
23489             check_dsp(ctx);
23490             gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
23491             break;
23492         case OPC_CMP_LE_PH:
23493             check_dsp(ctx);
23494             gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
23495             break;
23496         case OPC_PICK_QB:
23497             check_dsp(ctx);
23498             gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23499             break;
23500         case OPC_PICK_PH:
23501             check_dsp(ctx);
23502             gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23503             break;
23504         case OPC_PACKRL_PH:
23505             check_dsp(ctx);
23506             gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
23507             break;
23508         }
23509         break;
23510 #ifdef TARGET_MIPS64
23511     case OPC_CMPU_EQ_OB_DSP:
23512         switch (op2) {
23513         case OPC_CMP_EQ_PW:
23514             check_dsp(ctx);
23515             gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
23516             break;
23517         case OPC_CMP_LT_PW:
23518             check_dsp(ctx);
23519             gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
23520             break;
23521         case OPC_CMP_LE_PW:
23522             check_dsp(ctx);
23523             gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
23524             break;
23525         case OPC_CMP_EQ_QH:
23526             check_dsp(ctx);
23527             gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
23528             break;
23529         case OPC_CMP_LT_QH:
23530             check_dsp(ctx);
23531             gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
23532             break;
23533         case OPC_CMP_LE_QH:
23534             check_dsp(ctx);
23535             gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
23536             break;
23537         case OPC_CMPGDU_EQ_OB:
23538             check_dsp_r2(ctx);
23539             gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23540             break;
23541         case OPC_CMPGDU_LT_OB:
23542             check_dsp_r2(ctx);
23543             gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23544             break;
23545         case OPC_CMPGDU_LE_OB:
23546             check_dsp_r2(ctx);
23547             gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23548             break;
23549         case OPC_CMPGU_EQ_OB:
23550             check_dsp(ctx);
23551             gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
23552             break;
23553         case OPC_CMPGU_LT_OB:
23554             check_dsp(ctx);
23555             gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
23556             break;
23557         case OPC_CMPGU_LE_OB:
23558             check_dsp(ctx);
23559             gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
23560             break;
23561         case OPC_CMPU_EQ_OB:
23562             check_dsp(ctx);
23563             gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
23564             break;
23565         case OPC_CMPU_LT_OB:
23566             check_dsp(ctx);
23567             gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
23568             break;
23569         case OPC_CMPU_LE_OB:
23570             check_dsp(ctx);
23571             gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
23572             break;
23573         case OPC_PACKRL_PW:
23574             check_dsp(ctx);
23575             gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
23576             break;
23577         case OPC_PICK_OB:
23578             check_dsp(ctx);
23579             gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23580             break;
23581         case OPC_PICK_PW:
23582             check_dsp(ctx);
23583             gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23584             break;
23585         case OPC_PICK_QH:
23586             check_dsp(ctx);
23587             gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23588             break;
23589         }
23590         break;
23591 #endif
23592     }
23593
23594     tcg_temp_free(t1);
23595     tcg_temp_free(v1_t);
23596     tcg_temp_free(v2_t);
23597 }
23598
23599 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
23600                                uint32_t op1, int rt, int rs, int sa)
23601 {
23602     TCGv t0;
23603
23604     check_dsp_r2(ctx);
23605
23606     if (rt == 0) {
23607         /* Treat as NOP. */
23608         return;
23609     }
23610
23611     t0 = tcg_temp_new();
23612     gen_load_gpr(t0, rs);
23613
23614     switch (op1) {
23615     case OPC_APPEND_DSP:
23616         switch (MASK_APPEND(ctx->opcode)) {
23617         case OPC_APPEND:
23618             if (sa != 0) {
23619                 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
23620             }
23621             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23622             break;
23623         case OPC_PREPEND:
23624             if (sa != 0) {
23625                 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
23626                 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23627                 tcg_gen_shli_tl(t0, t0, 32 - sa);
23628                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23629             }
23630             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23631             break;
23632         case OPC_BALIGN:
23633             sa &= 3;
23634             if (sa != 0 && sa != 2) {
23635                 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23636                 tcg_gen_ext32u_tl(t0, t0);
23637                 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
23638                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23639             }
23640             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23641             break;
23642         default:            /* Invalid */
23643             MIPS_INVAL("MASK APPEND");
23644             generate_exception_end(ctx, EXCP_RI);
23645             break;
23646         }
23647         break;
23648 #ifdef TARGET_MIPS64
23649     case OPC_DAPPEND_DSP:
23650         switch (MASK_DAPPEND(ctx->opcode)) {
23651         case OPC_DAPPEND:
23652             if (sa != 0) {
23653                 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
23654             }
23655             break;
23656         case OPC_PREPENDD:
23657             tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
23658             tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
23659             tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
23660             break;
23661         case OPC_PREPENDW:
23662             if (sa != 0) {
23663                 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23664                 tcg_gen_shli_tl(t0, t0, 64 - sa);
23665                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23666             }
23667             break;
23668         case OPC_DBALIGN:
23669             sa &= 7;
23670             if (sa != 0 && sa != 2 && sa != 4) {
23671                 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23672                 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
23673                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23674             }
23675             break;
23676         default:            /* Invalid */
23677             MIPS_INVAL("MASK DAPPEND");
23678             generate_exception_end(ctx, EXCP_RI);
23679             break;
23680         }
23681         break;
23682 #endif
23683     }
23684     tcg_temp_free(t0);
23685 }
23686
23687 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
23688                                 int ret, int v1, int v2, int check_ret)
23689
23690 {
23691     TCGv t0;
23692     TCGv t1;
23693     TCGv v1_t;
23694     TCGv v2_t;
23695     int16_t imm;
23696
23697     if ((ret == 0) && (check_ret == 1)) {
23698         /* Treat as NOP. */
23699         return;
23700     }
23701
23702     t0 = tcg_temp_new();
23703     t1 = tcg_temp_new();
23704     v1_t = tcg_temp_new();
23705     v2_t = tcg_temp_new();
23706
23707     gen_load_gpr(v1_t, v1);
23708     gen_load_gpr(v2_t, v2);
23709
23710     switch (op1) {
23711     case OPC_EXTR_W_DSP:
23712         check_dsp(ctx);
23713         switch (op2) {
23714         case OPC_EXTR_W:
23715             tcg_gen_movi_tl(t0, v2);
23716             tcg_gen_movi_tl(t1, v1);
23717             gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
23718             break;
23719         case OPC_EXTR_R_W:
23720             tcg_gen_movi_tl(t0, v2);
23721             tcg_gen_movi_tl(t1, v1);
23722             gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23723             break;
23724         case OPC_EXTR_RS_W:
23725             tcg_gen_movi_tl(t0, v2);
23726             tcg_gen_movi_tl(t1, v1);
23727             gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23728             break;
23729         case OPC_EXTR_S_H:
23730             tcg_gen_movi_tl(t0, v2);
23731             tcg_gen_movi_tl(t1, v1);
23732             gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23733             break;
23734         case OPC_EXTRV_S_H:
23735             tcg_gen_movi_tl(t0, v2);
23736             gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
23737             break;
23738         case OPC_EXTRV_W:
23739             tcg_gen_movi_tl(t0, v2);
23740             gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23741             break;
23742         case OPC_EXTRV_R_W:
23743             tcg_gen_movi_tl(t0, v2);
23744             gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23745             break;
23746         case OPC_EXTRV_RS_W:
23747             tcg_gen_movi_tl(t0, v2);
23748             gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23749             break;
23750         case OPC_EXTP:
23751             tcg_gen_movi_tl(t0, v2);
23752             tcg_gen_movi_tl(t1, v1);
23753             gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
23754             break;
23755         case OPC_EXTPV:
23756             tcg_gen_movi_tl(t0, v2);
23757             gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
23758             break;
23759         case OPC_EXTPDP:
23760             tcg_gen_movi_tl(t0, v2);
23761             tcg_gen_movi_tl(t1, v1);
23762             gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
23763             break;
23764         case OPC_EXTPDPV:
23765             tcg_gen_movi_tl(t0, v2);
23766             gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23767             break;
23768         case OPC_SHILO:
23769             imm = (ctx->opcode >> 20) & 0x3F;
23770             tcg_gen_movi_tl(t0, ret);
23771             tcg_gen_movi_tl(t1, imm);
23772             gen_helper_shilo(t0, t1, cpu_env);
23773             break;
23774         case OPC_SHILOV:
23775             tcg_gen_movi_tl(t0, ret);
23776             gen_helper_shilo(t0, v1_t, cpu_env);
23777             break;
23778         case OPC_MTHLIP:
23779             tcg_gen_movi_tl(t0, ret);
23780             gen_helper_mthlip(t0, v1_t, cpu_env);
23781             break;
23782         case OPC_WRDSP:
23783             imm = (ctx->opcode >> 11) & 0x3FF;
23784             tcg_gen_movi_tl(t0, imm);
23785             gen_helper_wrdsp(v1_t, t0, cpu_env);
23786             break;
23787         case OPC_RDDSP:
23788             imm = (ctx->opcode >> 16) & 0x03FF;
23789             tcg_gen_movi_tl(t0, imm);
23790             gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
23791             break;
23792         }
23793         break;
23794 #ifdef TARGET_MIPS64
23795     case OPC_DEXTR_W_DSP:
23796         check_dsp(ctx);
23797         switch (op2) {
23798         case OPC_DMTHLIP:
23799             tcg_gen_movi_tl(t0, ret);
23800             gen_helper_dmthlip(v1_t, t0, cpu_env);
23801             break;
23802         case OPC_DSHILO:
23803             {
23804                 int shift = (ctx->opcode >> 19) & 0x7F;
23805                 int ac = (ctx->opcode >> 11) & 0x03;
23806                 tcg_gen_movi_tl(t0, shift);
23807                 tcg_gen_movi_tl(t1, ac);
23808                 gen_helper_dshilo(t0, t1, cpu_env);
23809                 break;
23810             }
23811         case OPC_DSHILOV:
23812             {
23813                 int ac = (ctx->opcode >> 11) & 0x03;
23814                 tcg_gen_movi_tl(t0, ac);
23815                 gen_helper_dshilo(v1_t, t0, cpu_env);
23816                 break;
23817             }
23818         case OPC_DEXTP:
23819             tcg_gen_movi_tl(t0, v2);
23820             tcg_gen_movi_tl(t1, v1);
23821
23822             gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
23823             break;
23824         case OPC_DEXTPV:
23825             tcg_gen_movi_tl(t0, v2);
23826             gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
23827             break;
23828         case OPC_DEXTPDP:
23829             tcg_gen_movi_tl(t0, v2);
23830             tcg_gen_movi_tl(t1, v1);
23831             gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
23832             break;
23833         case OPC_DEXTPDPV:
23834             tcg_gen_movi_tl(t0, v2);
23835             gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23836             break;
23837         case OPC_DEXTR_L:
23838             tcg_gen_movi_tl(t0, v2);
23839             tcg_gen_movi_tl(t1, v1);
23840             gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
23841             break;
23842         case OPC_DEXTR_R_L:
23843             tcg_gen_movi_tl(t0, v2);
23844             tcg_gen_movi_tl(t1, v1);
23845             gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
23846             break;
23847         case OPC_DEXTR_RS_L:
23848             tcg_gen_movi_tl(t0, v2);
23849             tcg_gen_movi_tl(t1, v1);
23850             gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
23851             break;
23852         case OPC_DEXTR_W:
23853             tcg_gen_movi_tl(t0, v2);
23854             tcg_gen_movi_tl(t1, v1);
23855             gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
23856             break;
23857         case OPC_DEXTR_R_W:
23858             tcg_gen_movi_tl(t0, v2);
23859             tcg_gen_movi_tl(t1, v1);
23860             gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23861             break;
23862         case OPC_DEXTR_RS_W:
23863             tcg_gen_movi_tl(t0, v2);
23864             tcg_gen_movi_tl(t1, v1);
23865             gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23866             break;
23867         case OPC_DEXTR_S_H:
23868             tcg_gen_movi_tl(t0, v2);
23869             tcg_gen_movi_tl(t1, v1);
23870             gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23871             break;
23872         case OPC_DEXTRV_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_L:
23878             tcg_gen_movi_tl(t0, v2);
23879             gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23880             break;
23881         case OPC_DEXTRV_R_L:
23882             tcg_gen_movi_tl(t0, v2);
23883             gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23884             break;
23885         case OPC_DEXTRV_RS_L:
23886             tcg_gen_movi_tl(t0, v2);
23887             gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23888             break;
23889         case OPC_DEXTRV_W:
23890             tcg_gen_movi_tl(t0, v2);
23891             gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23892             break;
23893         case OPC_DEXTRV_R_W:
23894             tcg_gen_movi_tl(t0, v2);
23895             gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23896             break;
23897         case OPC_DEXTRV_RS_W:
23898             tcg_gen_movi_tl(t0, v2);
23899             gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23900             break;
23901         }
23902         break;
23903 #endif
23904     }
23905
23906     tcg_temp_free(t0);
23907     tcg_temp_free(t1);
23908     tcg_temp_free(v1_t);
23909     tcg_temp_free(v2_t);
23910 }
23911
23912 /* End MIPSDSP functions. */
23913
23914 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
23915 {
23916     int rs, rt, rd, sa;
23917     uint32_t op1, op2;
23918
23919     rs = (ctx->opcode >> 21) & 0x1f;
23920     rt = (ctx->opcode >> 16) & 0x1f;
23921     rd = (ctx->opcode >> 11) & 0x1f;
23922     sa = (ctx->opcode >> 6) & 0x1f;
23923
23924     op1 = MASK_SPECIAL(ctx->opcode);
23925     switch (op1) {
23926     case OPC_LSA:
23927         gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
23928         break;
23929     case OPC_MULT:
23930     case OPC_MULTU:
23931     case OPC_DIV:
23932     case OPC_DIVU:
23933         op2 = MASK_R6_MULDIV(ctx->opcode);
23934         switch (op2) {
23935         case R6_OPC_MUL:
23936         case R6_OPC_MUH:
23937         case R6_OPC_MULU:
23938         case R6_OPC_MUHU:
23939         case R6_OPC_DIV:
23940         case R6_OPC_MOD:
23941         case R6_OPC_DIVU:
23942         case R6_OPC_MODU:
23943             gen_r6_muldiv(ctx, op2, rd, rs, rt);
23944             break;
23945         default:
23946             MIPS_INVAL("special_r6 muldiv");
23947             generate_exception_end(ctx, EXCP_RI);
23948             break;
23949         }
23950         break;
23951     case OPC_SELEQZ:
23952     case OPC_SELNEZ:
23953         gen_cond_move(ctx, op1, rd, rs, rt);
23954         break;
23955     case R6_OPC_CLO:
23956     case R6_OPC_CLZ:
23957         if (rt == 0 && sa == 1) {
23958             /* Major opcode and function field is shared with preR6 MFHI/MTHI.
23959                We need additionally to check other fields */
23960             gen_cl(ctx, op1, rd, rs);
23961         } else {
23962             generate_exception_end(ctx, EXCP_RI);
23963         }
23964         break;
23965     case R6_OPC_SDBBP:
23966         if (is_uhi(extract32(ctx->opcode, 6, 20))) {
23967             gen_helper_do_semihosting(cpu_env);
23968         } else {
23969             if (ctx->hflags & MIPS_HFLAG_SBRI) {
23970                 generate_exception_end(ctx, EXCP_RI);
23971             } else {
23972                 generate_exception_end(ctx, EXCP_DBp);
23973             }
23974         }
23975         break;
23976 #if defined(TARGET_MIPS64)
23977     case OPC_DLSA:
23978         check_mips_64(ctx);
23979         gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
23980         break;
23981     case R6_OPC_DCLO:
23982     case R6_OPC_DCLZ:
23983         if (rt == 0 && sa == 1) {
23984             /* Major opcode and function field is shared with preR6 MFHI/MTHI.
23985                We need additionally to check other fields */
23986             check_mips_64(ctx);
23987             gen_cl(ctx, op1, rd, rs);
23988         } else {
23989             generate_exception_end(ctx, EXCP_RI);
23990         }
23991         break;
23992     case OPC_DMULT:
23993     case OPC_DMULTU:
23994     case OPC_DDIV:
23995     case OPC_DDIVU:
23996
23997         op2 = MASK_R6_MULDIV(ctx->opcode);
23998         switch (op2) {
23999         case R6_OPC_DMUL:
24000         case R6_OPC_DMUH:
24001         case R6_OPC_DMULU:
24002         case R6_OPC_DMUHU:
24003         case R6_OPC_DDIV:
24004         case R6_OPC_DMOD:
24005         case R6_OPC_DDIVU:
24006         case R6_OPC_DMODU:
24007             check_mips_64(ctx);
24008             gen_r6_muldiv(ctx, op2, rd, rs, rt);
24009             break;
24010         default:
24011             MIPS_INVAL("special_r6 muldiv");
24012             generate_exception_end(ctx, EXCP_RI);
24013             break;
24014         }
24015         break;
24016 #endif
24017     default:            /* Invalid */
24018         MIPS_INVAL("special_r6");
24019         generate_exception_end(ctx, EXCP_RI);
24020         break;
24021     }
24022 }
24023
24024 static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx)
24025 {
24026     int rs = extract32(ctx->opcode, 21, 5);
24027     int rt = extract32(ctx->opcode, 16, 5);
24028     int rd = extract32(ctx->opcode, 11, 5);
24029     uint32_t op1 = MASK_SPECIAL(ctx->opcode);
24030
24031     switch (op1) {
24032     case OPC_MOVN:         /* Conditional move */
24033     case OPC_MOVZ:
24034         gen_cond_move(ctx, op1, rd, rs, rt);
24035         break;
24036     case OPC_MFHI:          /* Move from HI/LO */
24037     case OPC_MFLO:
24038         gen_HILO(ctx, op1, 0, rd);
24039         break;
24040     case OPC_MTHI:
24041     case OPC_MTLO:          /* Move to HI/LO */
24042         gen_HILO(ctx, op1, 0, rs);
24043         break;
24044     case OPC_MULT:
24045     case OPC_MULTU:
24046         gen_mul_txx9(ctx, op1, rd, rs, rt);
24047         break;
24048     case OPC_DIV:
24049     case OPC_DIVU:
24050         gen_muldiv(ctx, op1, 0, rs, rt);
24051         break;
24052 #if defined(TARGET_MIPS64)
24053     case OPC_DMULT:
24054     case OPC_DMULTU:
24055     case OPC_DDIV:
24056     case OPC_DDIVU:
24057         check_insn_opc_user_only(ctx, INSN_R5900);
24058         gen_muldiv(ctx, op1, 0, rs, rt);
24059         break;
24060 #endif
24061     case OPC_JR:
24062         gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
24063         break;
24064     default:            /* Invalid */
24065         MIPS_INVAL("special_tx79");
24066         generate_exception_end(ctx, EXCP_RI);
24067         break;
24068     }
24069 }
24070
24071 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
24072 {
24073     int rs, rt, rd, sa;
24074     uint32_t op1;
24075
24076     rs = (ctx->opcode >> 21) & 0x1f;
24077     rt = (ctx->opcode >> 16) & 0x1f;
24078     rd = (ctx->opcode >> 11) & 0x1f;
24079     sa = (ctx->opcode >> 6) & 0x1f;
24080
24081     op1 = MASK_SPECIAL(ctx->opcode);
24082     switch (op1) {
24083     case OPC_MOVN:         /* Conditional move */
24084     case OPC_MOVZ:
24085         check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
24086                    INSN_LOONGSON2E | INSN_LOONGSON2F);
24087         gen_cond_move(ctx, op1, rd, rs, rt);
24088         break;
24089     case OPC_MFHI:          /* Move from HI/LO */
24090     case OPC_MFLO:
24091         gen_HILO(ctx, op1, rs & 3, rd);
24092         break;
24093     case OPC_MTHI:
24094     case OPC_MTLO:          /* Move to HI/LO */
24095         gen_HILO(ctx, op1, rd & 3, rs);
24096         break;
24097     case OPC_MOVCI:
24098         check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
24099         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
24100             check_cp1_enabled(ctx);
24101             gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
24102                       (ctx->opcode >> 16) & 1);
24103         } else {
24104             generate_exception_err(ctx, EXCP_CpU, 1);
24105         }
24106         break;
24107     case OPC_MULT:
24108     case OPC_MULTU:
24109         if (sa) {
24110             check_insn(ctx, INSN_VR54XX);
24111             op1 = MASK_MUL_VR54XX(ctx->opcode);
24112             gen_mul_vr54xx(ctx, op1, rd, rs, rt);
24113         } else {
24114             gen_muldiv(ctx, op1, rd & 3, rs, rt);
24115         }
24116         break;
24117     case OPC_DIV:
24118     case OPC_DIVU:
24119         gen_muldiv(ctx, op1, 0, rs, rt);
24120         break;
24121 #if defined(TARGET_MIPS64)
24122     case OPC_DMULT:
24123     case OPC_DMULTU:
24124     case OPC_DDIV:
24125     case OPC_DDIVU:
24126         check_insn(ctx, ISA_MIPS3);
24127         check_mips_64(ctx);
24128         gen_muldiv(ctx, op1, 0, rs, rt);
24129         break;
24130 #endif
24131     case OPC_JR:
24132         gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
24133         break;
24134     case OPC_SPIM:
24135 #ifdef MIPS_STRICT_STANDARD
24136         MIPS_INVAL("SPIM");
24137         generate_exception_end(ctx, EXCP_RI);
24138 #else
24139         /* Implemented as RI exception for now. */
24140         MIPS_INVAL("spim (unofficial)");
24141         generate_exception_end(ctx, EXCP_RI);
24142 #endif
24143         break;
24144     default:            /* Invalid */
24145         MIPS_INVAL("special_legacy");
24146         generate_exception_end(ctx, EXCP_RI);
24147         break;
24148     }
24149 }
24150
24151 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
24152 {
24153     int rs, rt, rd, sa;
24154     uint32_t op1;
24155
24156     rs = (ctx->opcode >> 21) & 0x1f;
24157     rt = (ctx->opcode >> 16) & 0x1f;
24158     rd = (ctx->opcode >> 11) & 0x1f;
24159     sa = (ctx->opcode >> 6) & 0x1f;
24160
24161     op1 = MASK_SPECIAL(ctx->opcode);
24162     switch (op1) {
24163     case OPC_SLL:          /* Shift with immediate */
24164         if (sa == 5 && rd == 0 &&
24165             rs == 0 && rt == 0) { /* PAUSE */
24166             if ((ctx->insn_flags & ISA_MIPS32R6) &&
24167                 (ctx->hflags & MIPS_HFLAG_BMASK)) {
24168                 generate_exception_end(ctx, EXCP_RI);
24169                 break;
24170             }
24171         }
24172         /* Fallthrough */
24173     case OPC_SRA:
24174         gen_shift_imm(ctx, op1, rd, rt, sa);
24175         break;
24176     case OPC_SRL:
24177         switch ((ctx->opcode >> 21) & 0x1f) {
24178         case 1:
24179             /* rotr is decoded as srl on non-R2 CPUs */
24180             if (ctx->insn_flags & ISA_MIPS32R2) {
24181                 op1 = OPC_ROTR;
24182             }
24183             /* Fallthrough */
24184         case 0:
24185             gen_shift_imm(ctx, op1, rd, rt, sa);
24186             break;
24187         default:
24188             generate_exception_end(ctx, EXCP_RI);
24189             break;
24190         }
24191         break;
24192     case OPC_ADD:
24193     case OPC_ADDU:
24194     case OPC_SUB:
24195     case OPC_SUBU:
24196         gen_arith(ctx, op1, rd, rs, rt);
24197         break;
24198     case OPC_SLLV:         /* Shifts */
24199     case OPC_SRAV:
24200         gen_shift(ctx, op1, rd, rs, rt);
24201         break;
24202     case OPC_SRLV:
24203         switch ((ctx->opcode >> 6) & 0x1f) {
24204         case 1:
24205             /* rotrv is decoded as srlv on non-R2 CPUs */
24206             if (ctx->insn_flags & ISA_MIPS32R2) {
24207                 op1 = OPC_ROTRV;
24208             }
24209             /* Fallthrough */
24210         case 0:
24211             gen_shift(ctx, op1, rd, rs, rt);
24212             break;
24213         default:
24214             generate_exception_end(ctx, EXCP_RI);
24215             break;
24216         }
24217         break;
24218     case OPC_SLT:          /* Set on less than */
24219     case OPC_SLTU:
24220         gen_slt(ctx, op1, rd, rs, rt);
24221         break;
24222     case OPC_AND:          /* Logic*/
24223     case OPC_OR:
24224     case OPC_NOR:
24225     case OPC_XOR:
24226         gen_logic(ctx, op1, rd, rs, rt);
24227         break;
24228     case OPC_JALR:
24229         gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
24230         break;
24231     case OPC_TGE: /* Traps */
24232     case OPC_TGEU:
24233     case OPC_TLT:
24234     case OPC_TLTU:
24235     case OPC_TEQ:
24236     case OPC_TNE:
24237         check_insn(ctx, ISA_MIPS2);
24238         gen_trap(ctx, op1, rs, rt, -1);
24239         break;
24240     case OPC_LSA: /* OPC_PMON */
24241         if ((ctx->insn_flags & ISA_MIPS32R6) ||
24242             (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
24243             decode_opc_special_r6(env, ctx);
24244         } else {
24245             /* Pmon entry point, also R4010 selsl */
24246 #ifdef MIPS_STRICT_STANDARD
24247             MIPS_INVAL("PMON / selsl");
24248             generate_exception_end(ctx, EXCP_RI);
24249 #else
24250             gen_helper_0e0i(pmon, sa);
24251 #endif
24252         }
24253         break;
24254     case OPC_SYSCALL:
24255         generate_exception_end(ctx, EXCP_SYSCALL);
24256         break;
24257     case OPC_BREAK:
24258         generate_exception_end(ctx, EXCP_BREAK);
24259         break;
24260     case OPC_SYNC:
24261         check_insn(ctx, ISA_MIPS2);
24262         gen_sync(extract32(ctx->opcode, 6, 5));
24263         break;
24264
24265 #if defined(TARGET_MIPS64)
24266         /* MIPS64 specific opcodes */
24267     case OPC_DSLL:
24268     case OPC_DSRA:
24269     case OPC_DSLL32:
24270     case OPC_DSRA32:
24271         check_insn(ctx, ISA_MIPS3);
24272         check_mips_64(ctx);
24273         gen_shift_imm(ctx, op1, rd, rt, sa);
24274         break;
24275     case OPC_DSRL:
24276         switch ((ctx->opcode >> 21) & 0x1f) {
24277         case 1:
24278             /* drotr is decoded as dsrl on non-R2 CPUs */
24279             if (ctx->insn_flags & ISA_MIPS32R2) {
24280                 op1 = OPC_DROTR;
24281             }
24282             /* Fallthrough */
24283         case 0:
24284             check_insn(ctx, ISA_MIPS3);
24285             check_mips_64(ctx);
24286             gen_shift_imm(ctx, op1, rd, rt, sa);
24287             break;
24288         default:
24289             generate_exception_end(ctx, EXCP_RI);
24290             break;
24291         }
24292         break;
24293     case OPC_DSRL32:
24294         switch ((ctx->opcode >> 21) & 0x1f) {
24295         case 1:
24296             /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
24297             if (ctx->insn_flags & ISA_MIPS32R2) {
24298                 op1 = OPC_DROTR32;
24299             }
24300             /* Fallthrough */
24301         case 0:
24302             check_insn(ctx, ISA_MIPS3);
24303             check_mips_64(ctx);
24304             gen_shift_imm(ctx, op1, rd, rt, sa);
24305             break;
24306         default:
24307             generate_exception_end(ctx, EXCP_RI);
24308             break;
24309         }
24310         break;
24311     case OPC_DADD:
24312     case OPC_DADDU:
24313     case OPC_DSUB:
24314     case OPC_DSUBU:
24315         check_insn(ctx, ISA_MIPS3);
24316         check_mips_64(ctx);
24317         gen_arith(ctx, op1, rd, rs, rt);
24318         break;
24319     case OPC_DSLLV:
24320     case OPC_DSRAV:
24321         check_insn(ctx, ISA_MIPS3);
24322         check_mips_64(ctx);
24323         gen_shift(ctx, op1, rd, rs, rt);
24324         break;
24325     case OPC_DSRLV:
24326         switch ((ctx->opcode >> 6) & 0x1f) {
24327         case 1:
24328             /* drotrv is decoded as dsrlv on non-R2 CPUs */
24329             if (ctx->insn_flags & ISA_MIPS32R2) {
24330                 op1 = OPC_DROTRV;
24331             }
24332             /* Fallthrough */
24333         case 0:
24334             check_insn(ctx, ISA_MIPS3);
24335             check_mips_64(ctx);
24336             gen_shift(ctx, op1, rd, rs, rt);
24337             break;
24338         default:
24339             generate_exception_end(ctx, EXCP_RI);
24340             break;
24341         }
24342         break;
24343     case OPC_DLSA:
24344         if ((ctx->insn_flags & ISA_MIPS32R6) ||
24345             (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
24346             decode_opc_special_r6(env, ctx);
24347         }
24348         break;
24349 #endif
24350     default:
24351         if (ctx->insn_flags & ISA_MIPS32R6) {
24352             decode_opc_special_r6(env, ctx);
24353         } else if (ctx->insn_flags & INSN_R5900) {
24354             decode_opc_special_tx79(env, ctx);
24355         } else {
24356             decode_opc_special_legacy(env, ctx);
24357         }
24358     }
24359 }
24360
24361
24362 #if !defined(TARGET_MIPS64)
24363
24364 /* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
24365 #define MXU_APTN1_A    0
24366 #define MXU_APTN1_S    1
24367
24368 /* MXU accumulate add/subtract 2-bit pattern 'aptn2' */
24369 #define MXU_APTN2_AA    0
24370 #define MXU_APTN2_AS    1
24371 #define MXU_APTN2_SA    2
24372 #define MXU_APTN2_SS    3
24373
24374 /* MXU execute add/subtract 2-bit pattern 'eptn2' */
24375 #define MXU_EPTN2_AA    0
24376 #define MXU_EPTN2_AS    1
24377 #define MXU_EPTN2_SA    2
24378 #define MXU_EPTN2_SS    3
24379
24380 /* MXU operand getting pattern 'optn2' */
24381 #define MXU_OPTN2_PTN0  0
24382 #define MXU_OPTN2_PTN1  1
24383 #define MXU_OPTN2_PTN2  2
24384 #define MXU_OPTN2_PTN3  3
24385 /* alternative naming scheme for 'optn2' */
24386 #define MXU_OPTN2_WW    0
24387 #define MXU_OPTN2_LW    1
24388 #define MXU_OPTN2_HW    2
24389 #define MXU_OPTN2_XW    3
24390
24391 /* MXU operand getting pattern 'optn3' */
24392 #define MXU_OPTN3_PTN0  0
24393 #define MXU_OPTN3_PTN1  1
24394 #define MXU_OPTN3_PTN2  2
24395 #define MXU_OPTN3_PTN3  3
24396 #define MXU_OPTN3_PTN4  4
24397 #define MXU_OPTN3_PTN5  5
24398 #define MXU_OPTN3_PTN6  6
24399 #define MXU_OPTN3_PTN7  7
24400
24401
24402 /*
24403  * S32I2M XRa, rb - Register move from GRF to XRF
24404  */
24405 static void gen_mxu_s32i2m(DisasContext *ctx)
24406 {
24407     TCGv t0;
24408     uint32_t XRa, Rb;
24409
24410     t0 = tcg_temp_new();
24411
24412     XRa = extract32(ctx->opcode, 6, 5);
24413     Rb = extract32(ctx->opcode, 16, 5);
24414
24415     gen_load_gpr(t0, Rb);
24416     if (XRa <= 15) {
24417         gen_store_mxu_gpr(t0, XRa);
24418     } else if (XRa == 16) {
24419         gen_store_mxu_cr(t0);
24420     }
24421
24422     tcg_temp_free(t0);
24423 }
24424
24425 /*
24426  * S32M2I XRa, rb - Register move from XRF to GRF
24427  */
24428 static void gen_mxu_s32m2i(DisasContext *ctx)
24429 {
24430     TCGv t0;
24431     uint32_t XRa, Rb;
24432
24433     t0 = tcg_temp_new();
24434
24435     XRa = extract32(ctx->opcode, 6, 5);
24436     Rb = extract32(ctx->opcode, 16, 5);
24437
24438     if (XRa <= 15) {
24439         gen_load_mxu_gpr(t0, XRa);
24440     } else if (XRa == 16) {
24441         gen_load_mxu_cr(t0);
24442     }
24443
24444     gen_store_gpr(t0, Rb);
24445
24446     tcg_temp_free(t0);
24447 }
24448
24449 /*
24450  * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF
24451  */
24452 static void gen_mxu_s8ldd(DisasContext *ctx)
24453 {
24454     TCGv t0, t1;
24455     uint32_t XRa, Rb, s8, optn3;
24456
24457     t0 = tcg_temp_new();
24458     t1 = tcg_temp_new();
24459
24460     XRa = extract32(ctx->opcode, 6, 4);
24461     s8 = extract32(ctx->opcode, 10, 8);
24462     optn3 = extract32(ctx->opcode, 18, 3);
24463     Rb = extract32(ctx->opcode, 21, 5);
24464
24465     gen_load_gpr(t0, Rb);
24466     tcg_gen_addi_tl(t0, t0, (int8_t)s8);
24467
24468     switch (optn3) {
24469     /* XRa[7:0] = tmp8 */
24470     case MXU_OPTN3_PTN0:
24471         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24472         gen_load_mxu_gpr(t0, XRa);
24473         tcg_gen_deposit_tl(t0, t0, t1, 0, 8);
24474         break;
24475     /* XRa[15:8] = tmp8 */
24476     case MXU_OPTN3_PTN1:
24477         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24478         gen_load_mxu_gpr(t0, XRa);
24479         tcg_gen_deposit_tl(t0, t0, t1, 8, 8);
24480         break;
24481     /* XRa[23:16] = tmp8 */
24482     case MXU_OPTN3_PTN2:
24483         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24484         gen_load_mxu_gpr(t0, XRa);
24485         tcg_gen_deposit_tl(t0, t0, t1, 16, 8);
24486         break;
24487     /* XRa[31:24] = tmp8 */
24488     case MXU_OPTN3_PTN3:
24489         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24490         gen_load_mxu_gpr(t0, XRa);
24491         tcg_gen_deposit_tl(t0, t0, t1, 24, 8);
24492         break;
24493     /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
24494     case MXU_OPTN3_PTN4:
24495         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24496         tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24497         break;
24498     /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
24499     case MXU_OPTN3_PTN5:
24500         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24501         tcg_gen_shli_tl(t1, t1, 8);
24502         tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24503         break;
24504     /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
24505     case MXU_OPTN3_PTN6:
24506         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_SB);
24507         tcg_gen_mov_tl(t0, t1);
24508         tcg_gen_andi_tl(t0, t0, 0xFF00FFFF);
24509         tcg_gen_shli_tl(t1, t1, 16);
24510         tcg_gen_or_tl(t0, t0, t1);
24511         break;
24512     /* XRa = {tmp8, tmp8, tmp8, tmp8} */
24513     case MXU_OPTN3_PTN7:
24514         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24515         tcg_gen_deposit_tl(t1, t1, t1, 8, 8);
24516         tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24517         break;
24518     }
24519
24520     gen_store_mxu_gpr(t0, XRa);
24521
24522     tcg_temp_free(t0);
24523     tcg_temp_free(t1);
24524 }
24525
24526 /*
24527  * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication
24528  */
24529 static void gen_mxu_d16mul(DisasContext *ctx)
24530 {
24531     TCGv t0, t1, t2, t3;
24532     uint32_t XRa, XRb, XRc, XRd, optn2;
24533
24534     t0 = tcg_temp_new();
24535     t1 = tcg_temp_new();
24536     t2 = tcg_temp_new();
24537     t3 = tcg_temp_new();
24538
24539     XRa = extract32(ctx->opcode, 6, 4);
24540     XRb = extract32(ctx->opcode, 10, 4);
24541     XRc = extract32(ctx->opcode, 14, 4);
24542     XRd = extract32(ctx->opcode, 18, 4);
24543     optn2 = extract32(ctx->opcode, 22, 2);
24544
24545     gen_load_mxu_gpr(t1, XRb);
24546     tcg_gen_sextract_tl(t0, t1, 0, 16);
24547     tcg_gen_sextract_tl(t1, t1, 16, 16);
24548     gen_load_mxu_gpr(t3, XRc);
24549     tcg_gen_sextract_tl(t2, t3, 0, 16);
24550     tcg_gen_sextract_tl(t3, t3, 16, 16);
24551
24552     switch (optn2) {
24553     case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
24554         tcg_gen_mul_tl(t3, t1, t3);
24555         tcg_gen_mul_tl(t2, t0, t2);
24556         break;
24557     case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
24558         tcg_gen_mul_tl(t3, t0, t3);
24559         tcg_gen_mul_tl(t2, t0, t2);
24560         break;
24561     case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
24562         tcg_gen_mul_tl(t3, t1, t3);
24563         tcg_gen_mul_tl(t2, t1, t2);
24564         break;
24565     case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
24566         tcg_gen_mul_tl(t3, t0, t3);
24567         tcg_gen_mul_tl(t2, t1, t2);
24568         break;
24569     }
24570     gen_store_mxu_gpr(t3, XRa);
24571     gen_store_mxu_gpr(t2, XRd);
24572
24573     tcg_temp_free(t0);
24574     tcg_temp_free(t1);
24575     tcg_temp_free(t2);
24576     tcg_temp_free(t3);
24577 }
24578
24579 /*
24580  * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply
24581  *                                           and accumulate
24582  */
24583 static void gen_mxu_d16mac(DisasContext *ctx)
24584 {
24585     TCGv t0, t1, t2, t3;
24586     uint32_t XRa, XRb, XRc, XRd, optn2, aptn2;
24587
24588     t0 = tcg_temp_new();
24589     t1 = tcg_temp_new();
24590     t2 = tcg_temp_new();
24591     t3 = tcg_temp_new();
24592
24593     XRa = extract32(ctx->opcode, 6, 4);
24594     XRb = extract32(ctx->opcode, 10, 4);
24595     XRc = extract32(ctx->opcode, 14, 4);
24596     XRd = extract32(ctx->opcode, 18, 4);
24597     optn2 = extract32(ctx->opcode, 22, 2);
24598     aptn2 = extract32(ctx->opcode, 24, 2);
24599
24600     gen_load_mxu_gpr(t1, XRb);
24601     tcg_gen_sextract_tl(t0, t1, 0, 16);
24602     tcg_gen_sextract_tl(t1, t1, 16, 16);
24603
24604     gen_load_mxu_gpr(t3, XRc);
24605     tcg_gen_sextract_tl(t2, t3, 0, 16);
24606     tcg_gen_sextract_tl(t3, t3, 16, 16);
24607
24608     switch (optn2) {
24609     case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
24610         tcg_gen_mul_tl(t3, t1, t3);
24611         tcg_gen_mul_tl(t2, t0, t2);
24612         break;
24613     case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
24614         tcg_gen_mul_tl(t3, t0, t3);
24615         tcg_gen_mul_tl(t2, t0, t2);
24616         break;
24617     case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
24618         tcg_gen_mul_tl(t3, t1, t3);
24619         tcg_gen_mul_tl(t2, t1, t2);
24620         break;
24621     case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
24622         tcg_gen_mul_tl(t3, t0, t3);
24623         tcg_gen_mul_tl(t2, t1, t2);
24624         break;
24625     }
24626     gen_load_mxu_gpr(t0, XRa);
24627     gen_load_mxu_gpr(t1, XRd);
24628
24629     switch (aptn2) {
24630     case MXU_APTN2_AA:
24631         tcg_gen_add_tl(t3, t0, t3);
24632         tcg_gen_add_tl(t2, t1, t2);
24633         break;
24634     case MXU_APTN2_AS:
24635         tcg_gen_add_tl(t3, t0, t3);
24636         tcg_gen_sub_tl(t2, t1, t2);
24637         break;
24638     case MXU_APTN2_SA:
24639         tcg_gen_sub_tl(t3, t0, t3);
24640         tcg_gen_add_tl(t2, t1, t2);
24641         break;
24642     case MXU_APTN2_SS:
24643         tcg_gen_sub_tl(t3, t0, t3);
24644         tcg_gen_sub_tl(t2, t1, t2);
24645         break;
24646     }
24647     gen_store_mxu_gpr(t3, XRa);
24648     gen_store_mxu_gpr(t2, XRd);
24649
24650     tcg_temp_free(t0);
24651     tcg_temp_free(t1);
24652     tcg_temp_free(t2);
24653     tcg_temp_free(t3);
24654 }
24655
24656 /*
24657  * Q8MUL   XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply
24658  * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply
24659  */
24660 static void gen_mxu_q8mul_q8mulsu(DisasContext *ctx)
24661 {
24662     TCGv t0, t1, t2, t3, t4, t5, t6, t7;
24663     uint32_t XRa, XRb, XRc, XRd, sel;
24664
24665     t0 = tcg_temp_new();
24666     t1 = tcg_temp_new();
24667     t2 = tcg_temp_new();
24668     t3 = tcg_temp_new();
24669     t4 = tcg_temp_new();
24670     t5 = tcg_temp_new();
24671     t6 = tcg_temp_new();
24672     t7 = tcg_temp_new();
24673
24674     XRa = extract32(ctx->opcode, 6, 4);
24675     XRb = extract32(ctx->opcode, 10, 4);
24676     XRc = extract32(ctx->opcode, 14, 4);
24677     XRd = extract32(ctx->opcode, 18, 4);
24678     sel = extract32(ctx->opcode, 22, 2);
24679
24680     gen_load_mxu_gpr(t3, XRb);
24681     gen_load_mxu_gpr(t7, XRc);
24682
24683     if (sel == 0x2) {
24684         /* Q8MULSU */
24685         tcg_gen_ext8s_tl(t0, t3);
24686         tcg_gen_shri_tl(t3, t3, 8);
24687         tcg_gen_ext8s_tl(t1, t3);
24688         tcg_gen_shri_tl(t3, t3, 8);
24689         tcg_gen_ext8s_tl(t2, t3);
24690         tcg_gen_shri_tl(t3, t3, 8);
24691         tcg_gen_ext8s_tl(t3, t3);
24692     } else {
24693         /* Q8MUL */
24694         tcg_gen_ext8u_tl(t0, t3);
24695         tcg_gen_shri_tl(t3, t3, 8);
24696         tcg_gen_ext8u_tl(t1, t3);
24697         tcg_gen_shri_tl(t3, t3, 8);
24698         tcg_gen_ext8u_tl(t2, t3);
24699         tcg_gen_shri_tl(t3, t3, 8);
24700         tcg_gen_ext8u_tl(t3, t3);
24701     }
24702
24703     tcg_gen_ext8u_tl(t4, t7);
24704     tcg_gen_shri_tl(t7, t7, 8);
24705     tcg_gen_ext8u_tl(t5, t7);
24706     tcg_gen_shri_tl(t7, t7, 8);
24707     tcg_gen_ext8u_tl(t6, t7);
24708     tcg_gen_shri_tl(t7, t7, 8);
24709     tcg_gen_ext8u_tl(t7, t7);
24710
24711     tcg_gen_mul_tl(t0, t0, t4);
24712     tcg_gen_mul_tl(t1, t1, t5);
24713     tcg_gen_mul_tl(t2, t2, t6);
24714     tcg_gen_mul_tl(t3, t3, t7);
24715
24716     tcg_gen_andi_tl(t0, t0, 0xFFFF);
24717     tcg_gen_andi_tl(t1, t1, 0xFFFF);
24718     tcg_gen_andi_tl(t2, t2, 0xFFFF);
24719     tcg_gen_andi_tl(t3, t3, 0xFFFF);
24720
24721     tcg_gen_shli_tl(t1, t1, 16);
24722     tcg_gen_shli_tl(t3, t3, 16);
24723
24724     tcg_gen_or_tl(t0, t0, t1);
24725     tcg_gen_or_tl(t1, t2, t3);
24726
24727     gen_store_mxu_gpr(t0, XRd);
24728     gen_store_mxu_gpr(t1, XRa);
24729
24730     tcg_temp_free(t0);
24731     tcg_temp_free(t1);
24732     tcg_temp_free(t2);
24733     tcg_temp_free(t3);
24734     tcg_temp_free(t4);
24735     tcg_temp_free(t5);
24736     tcg_temp_free(t6);
24737     tcg_temp_free(t7);
24738 }
24739
24740 /*
24741  * S32LDD  XRa, Rb, S12 - Load a word from memory to XRF
24742  * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF, reversed byte seq.
24743  */
24744 static void gen_mxu_s32ldd_s32lddr(DisasContext *ctx)
24745 {
24746     TCGv t0, t1;
24747     uint32_t XRa, Rb, s12, sel;
24748
24749     t0 = tcg_temp_new();
24750     t1 = tcg_temp_new();
24751
24752     XRa = extract32(ctx->opcode, 6, 4);
24753     s12 = extract32(ctx->opcode, 10, 10);
24754     sel = extract32(ctx->opcode, 20, 1);
24755     Rb = extract32(ctx->opcode, 21, 5);
24756
24757     gen_load_gpr(t0, Rb);
24758
24759     tcg_gen_movi_tl(t1, s12);
24760     tcg_gen_shli_tl(t1, t1, 2);
24761     if (s12 & 0x200) {
24762         tcg_gen_ori_tl(t1, t1, 0xFFFFF000);
24763     }
24764     tcg_gen_add_tl(t1, t0, t1);
24765     tcg_gen_qemu_ld_tl(t1, t1, ctx->mem_idx, MO_SL);
24766
24767     if (sel == 1) {
24768         /* S32LDDR */
24769         tcg_gen_bswap32_tl(t1, t1);
24770     }
24771     gen_store_mxu_gpr(t1, XRa);
24772
24773     tcg_temp_free(t0);
24774     tcg_temp_free(t1);
24775 }
24776
24777
24778 /*
24779  *                 MXU instruction category: logic
24780  *                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24781  *
24782  *               S32NOR    S32AND    S32OR    S32XOR
24783  */
24784
24785 /*
24786  *  S32NOR XRa, XRb, XRc
24787  *    Update XRa with the result of logical bitwise 'nor' operation
24788  *    applied to the content of XRb and XRc.
24789  *
24790  *   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
24791  *  +-----------+---------+-----+-------+-------+-------+-----------+
24792  *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
24793  *  +-----------+---------+-----+-------+-------+-------+-----------+
24794  */
24795 static void gen_mxu_S32NOR(DisasContext *ctx)
24796 {
24797     uint32_t pad, XRc, XRb, XRa;
24798
24799     pad = extract32(ctx->opcode, 21, 5);
24800     XRc = extract32(ctx->opcode, 14, 4);
24801     XRb = extract32(ctx->opcode, 10, 4);
24802     XRa = extract32(ctx->opcode,  6, 4);
24803
24804     if (unlikely(pad != 0)) {
24805         /* opcode padding incorrect -> do nothing */
24806     } else if (unlikely(XRa == 0)) {
24807         /* destination is zero register -> do nothing */
24808     } else if (unlikely((XRb == 0) && (XRc == 0))) {
24809         /* both operands zero registers -> just set destination to all 1s */
24810         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0xFFFFFFFF);
24811     } else if (unlikely(XRb == 0)) {
24812         /* XRb zero register -> just set destination to the negation of XRc */
24813         tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
24814     } else if (unlikely(XRc == 0)) {
24815         /* XRa zero register -> just set destination to the negation of XRb */
24816         tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24817     } else if (unlikely(XRb == XRc)) {
24818         /* both operands same -> just set destination to the negation of XRb */
24819         tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24820     } else {
24821         /* the most general case */
24822         tcg_gen_nor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
24823     }
24824 }
24825
24826 /*
24827  *  S32AND XRa, XRb, XRc
24828  *    Update XRa with the result of logical bitwise 'and' operation
24829  *    applied to the content of XRb and XRc.
24830  *
24831  *   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
24832  *  +-----------+---------+-----+-------+-------+-------+-----------+
24833  *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
24834  *  +-----------+---------+-----+-------+-------+-------+-----------+
24835  */
24836 static void gen_mxu_S32AND(DisasContext *ctx)
24837 {
24838     uint32_t pad, XRc, XRb, XRa;
24839
24840     pad = extract32(ctx->opcode, 21, 5);
24841     XRc = extract32(ctx->opcode, 14, 4);
24842     XRb = extract32(ctx->opcode, 10, 4);
24843     XRa = extract32(ctx->opcode,  6, 4);
24844
24845     if (unlikely(pad != 0)) {
24846         /* opcode padding incorrect -> do nothing */
24847     } else if (unlikely(XRa == 0)) {
24848         /* destination is zero register -> do nothing */
24849     } else if (unlikely((XRb == 0) || (XRc == 0))) {
24850         /* one of operands zero register -> just set destination to all 0s */
24851         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
24852     } else if (unlikely(XRb == XRc)) {
24853         /* both operands same -> just set destination to one of them */
24854         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24855     } else {
24856         /* the most general case */
24857         tcg_gen_and_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
24858     }
24859 }
24860
24861 /*
24862  *  S32OR XRa, XRb, XRc
24863  *    Update XRa with the result of logical bitwise 'or' operation
24864  *    applied to the content of XRb and XRc.
24865  *
24866  *   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
24867  *  +-----------+---------+-----+-------+-------+-------+-----------+
24868  *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
24869  *  +-----------+---------+-----+-------+-------+-------+-----------+
24870  */
24871 static void gen_mxu_S32OR(DisasContext *ctx)
24872 {
24873     uint32_t pad, XRc, XRb, XRa;
24874
24875     pad = extract32(ctx->opcode, 21, 5);
24876     XRc = extract32(ctx->opcode, 14, 4);
24877     XRb = extract32(ctx->opcode, 10, 4);
24878     XRa = extract32(ctx->opcode,  6, 4);
24879
24880     if (unlikely(pad != 0)) {
24881         /* opcode padding incorrect -> do nothing */
24882     } else if (unlikely(XRa == 0)) {
24883         /* destination is zero register -> do nothing */
24884     } else if (unlikely((XRb == 0) && (XRc == 0))) {
24885         /* both operands zero registers -> just set destination to all 0s */
24886         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
24887     } else if (unlikely(XRb == 0)) {
24888         /* XRb zero register -> just set destination to the content of XRc */
24889         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
24890     } else if (unlikely(XRc == 0)) {
24891         /* XRc zero register -> just set destination to the content of XRb */
24892         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24893     } else if (unlikely(XRb == XRc)) {
24894         /* both operands same -> just set destination to one of them */
24895         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24896     } else {
24897         /* the most general case */
24898         tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
24899     }
24900 }
24901
24902 /*
24903  *  S32XOR XRa, XRb, XRc
24904  *    Update XRa with the result of logical bitwise 'xor' operation
24905  *    applied to the content of XRb and XRc.
24906  *
24907  *   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
24908  *  +-----------+---------+-----+-------+-------+-------+-----------+
24909  *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
24910  *  +-----------+---------+-----+-------+-------+-------+-----------+
24911  */
24912 static void gen_mxu_S32XOR(DisasContext *ctx)
24913 {
24914     uint32_t pad, XRc, XRb, XRa;
24915
24916     pad = extract32(ctx->opcode, 21, 5);
24917     XRc = extract32(ctx->opcode, 14, 4);
24918     XRb = extract32(ctx->opcode, 10, 4);
24919     XRa = extract32(ctx->opcode,  6, 4);
24920
24921     if (unlikely(pad != 0)) {
24922         /* opcode padding incorrect -> do nothing */
24923     } else if (unlikely(XRa == 0)) {
24924         /* destination is zero register -> do nothing */
24925     } else if (unlikely((XRb == 0) && (XRc == 0))) {
24926         /* both operands zero registers -> just set destination to all 0s */
24927         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
24928     } else if (unlikely(XRb == 0)) {
24929         /* XRb zero register -> just set destination to the content of XRc */
24930         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
24931     } else if (unlikely(XRc == 0)) {
24932         /* XRc zero register -> just set destination to the content of XRb */
24933         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24934     } else if (unlikely(XRb == XRc)) {
24935         /* both operands same -> just set destination to all 0s */
24936         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
24937     } else {
24938         /* the most general case */
24939         tcg_gen_xor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
24940     }
24941 }
24942
24943
24944 /*
24945  *                   MXU instruction category max/min
24946  *                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24947  *
24948  *                     S32MAX     D16MAX     Q8MAX
24949  *                     S32MIN     D16MIN     Q8MIN
24950  */
24951
24952 /*
24953  *  S32MAX XRa, XRb, XRc
24954  *    Update XRa with the maximum of signed 32-bit integers contained
24955  *    in XRb and XRc.
24956  *
24957  *  S32MIN XRa, XRb, XRc
24958  *    Update XRa with the minimum of signed 32-bit integers contained
24959  *    in XRb and XRc.
24960  *
24961  *   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
24962  *  +-----------+---------+-----+-------+-------+-------+-----------+
24963  *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL00|
24964  *  +-----------+---------+-----+-------+-------+-------+-----------+
24965  */
24966 static void gen_mxu_S32MAX_S32MIN(DisasContext *ctx)
24967 {
24968     uint32_t pad, opc, XRc, XRb, XRa;
24969
24970     pad = extract32(ctx->opcode, 21, 5);
24971     opc = extract32(ctx->opcode, 18, 3);
24972     XRc = extract32(ctx->opcode, 14, 4);
24973     XRb = extract32(ctx->opcode, 10, 4);
24974     XRa = extract32(ctx->opcode,  6, 4);
24975
24976     if (unlikely(pad != 0)) {
24977         /* opcode padding incorrect -> do nothing */
24978     } else if (unlikely(XRa == 0)) {
24979         /* destination is zero register -> do nothing */
24980     } else if (unlikely((XRb == 0) && (XRc == 0))) {
24981         /* both operands zero registers -> just set destination to zero */
24982         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
24983     } else if (unlikely((XRb == 0) || (XRc == 0))) {
24984         /* exactly one operand is zero register - find which one is not...*/
24985         uint32_t XRx = XRb ? XRb : XRc;
24986         /* ...and do max/min operation with one operand 0 */
24987         if (opc == OPC_MXU_S32MAX) {
24988             tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
24989         } else {
24990             tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
24991         }
24992     } else if (unlikely(XRb == XRc)) {
24993         /* both operands same -> just set destination to one of them */
24994         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24995     } else {
24996         /* the most general case */
24997         if (opc == OPC_MXU_S32MAX) {
24998             tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
24999                                                mxu_gpr[XRc - 1]);
25000         } else {
25001             tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
25002                                                mxu_gpr[XRc - 1]);
25003         }
25004     }
25005 }
25006
25007 /*
25008  *  D16MAX
25009  *    Update XRa with the 16-bit-wise maximums of signed integers
25010  *    contained in XRb and XRc.
25011  *
25012  *  D16MIN
25013  *    Update XRa with the 16-bit-wise minimums of signed integers
25014  *    contained in XRb and XRc.
25015  *
25016  *   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
25017  *  +-----------+---------+-----+-------+-------+-------+-----------+
25018  *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL00|
25019  *  +-----------+---------+-----+-------+-------+-------+-----------+
25020  */
25021 static void gen_mxu_D16MAX_D16MIN(DisasContext *ctx)
25022 {
25023     uint32_t pad, opc, XRc, XRb, XRa;
25024
25025     pad = extract32(ctx->opcode, 21, 5);
25026     opc = extract32(ctx->opcode, 18, 3);
25027     XRc = extract32(ctx->opcode, 14, 4);
25028     XRb = extract32(ctx->opcode, 10, 4);
25029     XRa = extract32(ctx->opcode,  6, 4);
25030
25031     if (unlikely(pad != 0)) {
25032         /* opcode padding incorrect -> do nothing */
25033     } else if (unlikely(XRc == 0)) {
25034         /* destination is zero register -> do nothing */
25035     } else if (unlikely((XRb == 0) && (XRa == 0))) {
25036         /* both operands zero registers -> just set destination to zero */
25037         tcg_gen_movi_i32(mxu_gpr[XRc - 1], 0);
25038     } else if (unlikely((XRb == 0) || (XRa == 0))) {
25039         /* exactly one operand is zero register - find which one is not...*/
25040         uint32_t XRx = XRb ? XRb : XRc;
25041         /* ...and do half-word-wise max/min with one operand 0 */
25042         TCGv_i32 t0 = tcg_temp_new();
25043         TCGv_i32 t1 = tcg_const_i32(0);
25044
25045         /* the left half-word first */
25046         tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFFFF0000);
25047         if (opc == OPC_MXU_D16MAX) {
25048             tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25049         } else {
25050             tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25051         }
25052
25053         /* the right half-word */
25054         tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0x0000FFFF);
25055         /* move half-words to the leftmost position */
25056         tcg_gen_shli_i32(t0, t0, 16);
25057         /* t0 will be max/min of t0 and t1 */
25058         if (opc == OPC_MXU_D16MAX) {
25059             tcg_gen_smax_i32(t0, t0, t1);
25060         } else {
25061             tcg_gen_smin_i32(t0, t0, t1);
25062         }
25063         /* return resulting half-words to its original position */
25064         tcg_gen_shri_i32(t0, t0, 16);
25065         /* finaly update the destination */
25066         tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25067
25068         tcg_temp_free(t1);
25069         tcg_temp_free(t0);
25070     } else if (unlikely(XRb == XRc)) {
25071         /* both operands same -> just set destination to one of them */
25072         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25073     } else {
25074         /* the most general case */
25075         TCGv_i32 t0 = tcg_temp_new();
25076         TCGv_i32 t1 = tcg_temp_new();
25077
25078         /* the left half-word first */
25079         tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFFFF0000);
25080         tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
25081         if (opc == OPC_MXU_D16MAX) {
25082             tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25083         } else {
25084             tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25085         }
25086
25087         /* the right half-word */
25088         tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
25089         tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0x0000FFFF);
25090         /* move half-words to the leftmost position */
25091         tcg_gen_shli_i32(t0, t0, 16);
25092         tcg_gen_shli_i32(t1, t1, 16);
25093         /* t0 will be max/min of t0 and t1 */
25094         if (opc == OPC_MXU_D16MAX) {
25095             tcg_gen_smax_i32(t0, t0, t1);
25096         } else {
25097             tcg_gen_smin_i32(t0, t0, t1);
25098         }
25099         /* return resulting half-words to its original position */
25100         tcg_gen_shri_i32(t0, t0, 16);
25101         /* finaly update the destination */
25102         tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25103
25104         tcg_temp_free(t1);
25105         tcg_temp_free(t0);
25106     }
25107 }
25108
25109 /*
25110  *  Q8MAX
25111  *    Update XRa with the 8-bit-wise maximums of signed integers
25112  *    contained in XRb and XRc.
25113  *
25114  *  Q8MIN
25115  *    Update XRa with the 8-bit-wise minimums of signed integers
25116  *    contained in XRb and XRc.
25117  *
25118  *   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
25119  *  +-----------+---------+-----+-------+-------+-------+-----------+
25120  *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL00|
25121  *  +-----------+---------+-----+-------+-------+-------+-----------+
25122  */
25123 static void gen_mxu_Q8MAX_Q8MIN(DisasContext *ctx)
25124 {
25125     uint32_t pad, opc, XRc, XRb, XRa;
25126
25127     pad = extract32(ctx->opcode, 21, 5);
25128     opc = extract32(ctx->opcode, 18, 3);
25129     XRc = extract32(ctx->opcode, 14, 4);
25130     XRb = extract32(ctx->opcode, 10, 4);
25131     XRa = extract32(ctx->opcode,  6, 4);
25132
25133     if (unlikely(pad != 0)) {
25134         /* opcode padding incorrect -> do nothing */
25135     } else if (unlikely(XRa == 0)) {
25136         /* destination is zero register -> do nothing */
25137     } else if (unlikely((XRb == 0) && (XRc == 0))) {
25138         /* both operands zero registers -> just set destination to zero */
25139         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25140     } else if (unlikely((XRb == 0) || (XRc == 0))) {
25141         /* exactly one operand is zero register - make it be the first...*/
25142         uint32_t XRx = XRb ? XRb : XRc;
25143         /* ...and do byte-wise max/min with one operand 0 */
25144         TCGv_i32 t0 = tcg_temp_new();
25145         TCGv_i32 t1 = tcg_const_i32(0);
25146         int32_t i;
25147
25148         /* the leftmost byte (byte 3) first */
25149         tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF000000);
25150         if (opc == OPC_MXU_Q8MAX) {
25151             tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25152         } else {
25153             tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25154         }
25155
25156         /* bytes 2, 1, 0 */
25157         for (i = 2; i >= 0; i--) {
25158             /* extract the byte */
25159             tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF << (8 * i));
25160             /* move the byte to the leftmost position */
25161             tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
25162             /* t0 will be max/min of t0 and t1 */
25163             if (opc == OPC_MXU_Q8MAX) {
25164                 tcg_gen_smax_i32(t0, t0, t1);
25165             } else {
25166                 tcg_gen_smin_i32(t0, t0, t1);
25167             }
25168             /* return resulting byte to its original position */
25169             tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
25170             /* finaly update the destination */
25171             tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25172         }
25173
25174         tcg_temp_free(t1);
25175         tcg_temp_free(t0);
25176     } else if (unlikely(XRb == XRc)) {
25177         /* both operands same -> just set destination to one of them */
25178         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25179     } else {
25180         /* the most general case */
25181         TCGv_i32 t0 = tcg_temp_new();
25182         TCGv_i32 t1 = tcg_temp_new();
25183         int32_t i;
25184
25185         /* the leftmost bytes (bytes 3) first */
25186         tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF000000);
25187         tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
25188         if (opc == OPC_MXU_Q8MAX) {
25189             tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25190         } else {
25191             tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25192         }
25193
25194         /* bytes 2, 1, 0 */
25195         for (i = 2; i >= 0; i--) {
25196             /* extract corresponding bytes */
25197             tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF << (8 * i));
25198             tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF << (8 * i));
25199             /* move the bytes to the leftmost position */
25200             tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
25201             tcg_gen_shli_i32(t1, t1, 8 * (3 - i));
25202             /* t0 will be max/min of t0 and t1 */
25203             if (opc == OPC_MXU_Q8MAX) {
25204                 tcg_gen_smax_i32(t0, t0, t1);
25205             } else {
25206                 tcg_gen_smin_i32(t0, t0, t1);
25207             }
25208             /* return resulting byte to its original position */
25209             tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
25210             /* finaly update the destination */
25211             tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25212         }
25213
25214         tcg_temp_free(t1);
25215         tcg_temp_free(t0);
25216     }
25217 }
25218
25219
25220 /*
25221  *                 MXU instruction category: align
25222  *                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25223  *
25224  *                       S32ALN     S32ALNI
25225  */
25226
25227 /*
25228  *  S32ALNI XRc, XRb, XRa, optn3
25229  *    Arrange bytes from XRb and XRc according to one of five sets of
25230  *    rules determined by optn3, and place the result in XRa.
25231  *
25232  *   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
25233  *  +-----------+-----+---+-----+-------+-------+-------+-----------+
25234  *  |  SPECIAL2 |optn3|0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
25235  *  +-----------+-----+---+-----+-------+-------+-------+-----------+
25236  *
25237  */
25238 static void gen_mxu_S32ALNI(DisasContext *ctx)
25239 {
25240     uint32_t optn3, pad, XRc, XRb, XRa;
25241
25242     optn3 = extract32(ctx->opcode,  23, 3);
25243     pad   = extract32(ctx->opcode,  21, 2);
25244     XRc   = extract32(ctx->opcode, 14, 4);
25245     XRb   = extract32(ctx->opcode, 10, 4);
25246     XRa   = extract32(ctx->opcode,  6, 4);
25247
25248     if (unlikely(pad != 0)) {
25249         /* opcode padding incorrect -> do nothing */
25250     } else if (unlikely(XRa == 0)) {
25251         /* destination is zero register -> do nothing */
25252     } else if (unlikely((XRb == 0) && (XRc == 0))) {
25253         /* both operands zero registers -> just set destination to all 0s */
25254         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25255     } else if (unlikely(XRb == 0)) {
25256         /* XRb zero register -> just appropriatelly shift XRc into XRa */
25257         switch (optn3) {
25258         case MXU_OPTN3_PTN0:
25259             tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25260             break;
25261         case MXU_OPTN3_PTN1:
25262         case MXU_OPTN3_PTN2:
25263         case MXU_OPTN3_PTN3:
25264             tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1],
25265                              8 * (4 - optn3));
25266             break;
25267         case MXU_OPTN3_PTN4:
25268             tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25269             break;
25270         }
25271     } else if (unlikely(XRc == 0)) {
25272         /* XRc zero register -> just appropriatelly shift XRb into XRa */
25273         switch (optn3) {
25274         case MXU_OPTN3_PTN0:
25275             tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25276             break;
25277         case MXU_OPTN3_PTN1:
25278         case MXU_OPTN3_PTN2:
25279         case MXU_OPTN3_PTN3:
25280             tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
25281             break;
25282         case MXU_OPTN3_PTN4:
25283             tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25284             break;
25285         }
25286     } else if (unlikely(XRb == XRc)) {
25287         /* both operands same -> just rotation or moving from any of them */
25288         switch (optn3) {
25289         case MXU_OPTN3_PTN0:
25290         case MXU_OPTN3_PTN4:
25291             tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25292             break;
25293         case MXU_OPTN3_PTN1:
25294         case MXU_OPTN3_PTN2:
25295         case MXU_OPTN3_PTN3:
25296             tcg_gen_rotli_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
25297             break;
25298         }
25299     } else {
25300         /* the most general case */
25301         switch (optn3) {
25302         case MXU_OPTN3_PTN0:
25303             {
25304                 /*                                         */
25305                 /*         XRb                XRc          */
25306                 /*  +---------------+                      */
25307                 /*  | A   B   C   D |    E   F   G   H     */
25308                 /*  +-------+-------+                      */
25309                 /*          |                              */
25310                 /*         XRa                             */
25311                 /*                                         */
25312
25313                 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25314             }
25315             break;
25316         case MXU_OPTN3_PTN1:
25317             {
25318                 /*                                         */
25319                 /*         XRb                 XRc         */
25320                 /*      +-------------------+              */
25321                 /*    A | B   C   D       E | F   G   H    */
25322                 /*      +---------+---------+              */
25323                 /*                |                        */
25324                 /*               XRa                       */
25325                 /*                                         */
25326
25327                 TCGv_i32 t0 = tcg_temp_new();
25328                 TCGv_i32 t1 = tcg_temp_new();
25329
25330                 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x00FFFFFF);
25331                 tcg_gen_shli_i32(t0, t0, 8);
25332
25333                 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
25334                 tcg_gen_shri_i32(t1, t1, 24);
25335
25336                 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25337
25338                 tcg_temp_free(t1);
25339                 tcg_temp_free(t0);
25340             }
25341             break;
25342         case MXU_OPTN3_PTN2:
25343             {
25344                 /*                                         */
25345                 /*         XRb                 XRc         */
25346                 /*          +-------------------+          */
25347                 /*    A   B | C   D       E   F | G   H    */
25348                 /*          +---------+---------+          */
25349                 /*                    |                    */
25350                 /*                   XRa                   */
25351                 /*                                         */
25352
25353                 TCGv_i32 t0 = tcg_temp_new();
25354                 TCGv_i32 t1 = tcg_temp_new();
25355
25356                 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
25357                 tcg_gen_shli_i32(t0, t0, 16);
25358
25359                 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
25360                 tcg_gen_shri_i32(t1, t1, 16);
25361
25362                 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25363
25364                 tcg_temp_free(t1);
25365                 tcg_temp_free(t0);
25366             }
25367             break;
25368         case MXU_OPTN3_PTN3:
25369             {
25370                 /*                                         */
25371                 /*         XRb                 XRc         */
25372                 /*              +-------------------+      */
25373                 /*    A   B   C | D       E   F   G | H    */
25374                 /*              +---------+---------+      */
25375                 /*                        |                */
25376                 /*                       XRa               */
25377                 /*                                         */
25378
25379                 TCGv_i32 t0 = tcg_temp_new();
25380                 TCGv_i32 t1 = tcg_temp_new();
25381
25382                 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x000000FF);
25383                 tcg_gen_shli_i32(t0, t0, 24);
25384
25385                 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFFFF00);
25386                 tcg_gen_shri_i32(t1, t1, 8);
25387
25388                 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25389
25390                 tcg_temp_free(t1);
25391                 tcg_temp_free(t0);
25392             }
25393             break;
25394         case MXU_OPTN3_PTN4:
25395             {
25396                 /*                                         */
25397                 /*         XRb                 XRc         */
25398                 /*                     +---------------+   */
25399                 /*    A   B   C   D    | E   F   G   H |   */
25400                 /*                     +-------+-------+   */
25401                 /*                             |           */
25402                 /*                            XRa          */
25403                 /*                                         */
25404
25405                 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25406             }
25407             break;
25408         }
25409     }
25410 }
25411
25412
25413 /*
25414  * Decoding engine for MXU
25415  * =======================
25416  */
25417
25418 /*
25419  *
25420  * Decode MXU pool00
25421  *
25422  *   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
25423  *  +-----------+---------+-----+-------+-------+-------+-----------+
25424  *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL00|
25425  *  +-----------+---------+-----+-------+-------+-------+-----------+
25426  *
25427  */
25428 static void decode_opc_mxu__pool00(CPUMIPSState *env, DisasContext *ctx)
25429 {
25430     uint32_t opcode = extract32(ctx->opcode, 18, 3);
25431
25432     switch (opcode) {
25433     case OPC_MXU_S32MAX:
25434     case OPC_MXU_S32MIN:
25435         gen_mxu_S32MAX_S32MIN(ctx);
25436         break;
25437     case OPC_MXU_D16MAX:
25438     case OPC_MXU_D16MIN:
25439         gen_mxu_D16MAX_D16MIN(ctx);
25440         break;
25441     case OPC_MXU_Q8MAX:
25442     case OPC_MXU_Q8MIN:
25443         gen_mxu_Q8MAX_Q8MIN(ctx);
25444         break;
25445     case OPC_MXU_Q8SLT:
25446         /* TODO: Implement emulation of Q8SLT instruction. */
25447         MIPS_INVAL("OPC_MXU_Q8SLT");
25448         generate_exception_end(ctx, EXCP_RI);
25449         break;
25450     case OPC_MXU_Q8SLTU:
25451         /* TODO: Implement emulation of Q8SLTU instruction. */
25452         MIPS_INVAL("OPC_MXU_Q8SLTU");
25453         generate_exception_end(ctx, EXCP_RI);
25454         break;
25455     default:
25456         MIPS_INVAL("decode_opc_mxu");
25457         generate_exception_end(ctx, EXCP_RI);
25458         break;
25459     }
25460 }
25461
25462 /*
25463  *
25464  * Decode MXU pool01
25465  *
25466  *  S32SLT, D16SLT, D16AVG, D16AVGR, Q8AVG, Q8AVGR:
25467  *   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
25468  *  +-----------+---------+-----+-------+-------+-------+-----------+
25469  *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL01|
25470  *  +-----------+---------+-----+-------+-------+-------+-----------+
25471  *
25472  *  Q8ADD:
25473  *   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
25474  *  +-----------+---+-----+-----+-------+-------+-------+-----------+
25475  *  |  SPECIAL2 |en2|0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL01|
25476  *  +-----------+---+-----+-----+-------+-------+-------+-----------+
25477  *
25478  */
25479 static void decode_opc_mxu__pool01(CPUMIPSState *env, DisasContext *ctx)
25480 {
25481     uint32_t opcode = extract32(ctx->opcode, 18, 3);
25482
25483     switch (opcode) {
25484     case OPC_MXU_S32SLT:
25485         /* TODO: Implement emulation of S32SLT instruction. */
25486         MIPS_INVAL("OPC_MXU_S32SLT");
25487         generate_exception_end(ctx, EXCP_RI);
25488         break;
25489     case OPC_MXU_D16SLT:
25490         /* TODO: Implement emulation of D16SLT instruction. */
25491         MIPS_INVAL("OPC_MXU_D16SLT");
25492         generate_exception_end(ctx, EXCP_RI);
25493         break;
25494     case OPC_MXU_D16AVG:
25495         /* TODO: Implement emulation of D16AVG instruction. */
25496         MIPS_INVAL("OPC_MXU_D16AVG");
25497         generate_exception_end(ctx, EXCP_RI);
25498         break;
25499     case OPC_MXU_D16AVGR:
25500         /* TODO: Implement emulation of D16AVGR instruction. */
25501         MIPS_INVAL("OPC_MXU_D16AVGR");
25502         generate_exception_end(ctx, EXCP_RI);
25503         break;
25504     case OPC_MXU_Q8AVG:
25505         /* TODO: Implement emulation of Q8AVG instruction. */
25506         MIPS_INVAL("OPC_MXU_Q8AVG");
25507         generate_exception_end(ctx, EXCP_RI);
25508         break;
25509     case OPC_MXU_Q8AVGR:
25510         /* TODO: Implement emulation of Q8AVGR instruction. */
25511         MIPS_INVAL("OPC_MXU_Q8AVGR");
25512         generate_exception_end(ctx, EXCP_RI);
25513         break;
25514     case OPC_MXU_Q8ADD:
25515         /* TODO: Implement emulation of Q8ADD instruction. */
25516         MIPS_INVAL("OPC_MXU_Q8ADD");
25517         generate_exception_end(ctx, EXCP_RI);
25518         break;
25519     default:
25520         MIPS_INVAL("decode_opc_mxu");
25521         generate_exception_end(ctx, EXCP_RI);
25522         break;
25523     }
25524 }
25525
25526 /*
25527  *
25528  * Decode MXU pool02
25529  *
25530  *   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
25531  *  +-----------+---------+-----+-------+-------+-------+-----------+
25532  *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL02|
25533  *  +-----------+---------+-----+-------+-------+-------+-----------+
25534  *
25535  */
25536 static void decode_opc_mxu__pool02(CPUMIPSState *env, DisasContext *ctx)
25537 {
25538     uint32_t opcode = extract32(ctx->opcode, 18, 3);
25539
25540     switch (opcode) {
25541     case OPC_MXU_S32CPS:
25542         /* TODO: Implement emulation of S32CPS instruction. */
25543         MIPS_INVAL("OPC_MXU_S32CPS");
25544         generate_exception_end(ctx, EXCP_RI);
25545         break;
25546     case OPC_MXU_D16CPS:
25547         /* TODO: Implement emulation of D16CPS instruction. */
25548         MIPS_INVAL("OPC_MXU_D16CPS");
25549         generate_exception_end(ctx, EXCP_RI);
25550         break;
25551     case OPC_MXU_Q8ABD:
25552         /* TODO: Implement emulation of Q8ABD instruction. */
25553         MIPS_INVAL("OPC_MXU_Q8ABD");
25554         generate_exception_end(ctx, EXCP_RI);
25555         break;
25556     case OPC_MXU_Q16SAT:
25557         /* TODO: Implement emulation of Q16SAT instruction. */
25558         MIPS_INVAL("OPC_MXU_Q16SAT");
25559         generate_exception_end(ctx, EXCP_RI);
25560         break;
25561     default:
25562         MIPS_INVAL("decode_opc_mxu");
25563         generate_exception_end(ctx, EXCP_RI);
25564         break;
25565     }
25566 }
25567
25568 /*
25569  *
25570  * Decode MXU pool03
25571  *
25572  *  D16MULF:
25573  *   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
25574  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25575  *  |  SPECIAL2 |x x|on2|0 0 0 0|  XRc  |  XRb  |  XRa  |MXU__POOL03|
25576  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25577  *
25578  *  D16MULE:
25579  *   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
25580  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25581  *  |  SPECIAL2 |x x|on2|   Xd  |  XRc  |  XRb  |  XRa  |MXU__POOL03|
25582  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25583  *
25584  */
25585 static void decode_opc_mxu__pool03(CPUMIPSState *env, DisasContext *ctx)
25586 {
25587     uint32_t opcode = extract32(ctx->opcode, 24, 2);
25588
25589     switch (opcode) {
25590     case OPC_MXU_D16MULF:
25591         /* TODO: Implement emulation of D16MULF instruction. */
25592         MIPS_INVAL("OPC_MXU_D16MULF");
25593         generate_exception_end(ctx, EXCP_RI);
25594         break;
25595     case OPC_MXU_D16MULE:
25596         /* TODO: Implement emulation of D16MULE instruction. */
25597         MIPS_INVAL("OPC_MXU_D16MULE");
25598         generate_exception_end(ctx, EXCP_RI);
25599         break;
25600     default:
25601         MIPS_INVAL("decode_opc_mxu");
25602         generate_exception_end(ctx, EXCP_RI);
25603         break;
25604     }
25605 }
25606
25607 /*
25608  *
25609  * Decode MXU pool04
25610  *
25611  *   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
25612  *  +-----------+---------+-+-------------------+-------+-----------+
25613  *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL04|
25614  *  +-----------+---------+-+-------------------+-------+-----------+
25615  *
25616  */
25617 static void decode_opc_mxu__pool04(CPUMIPSState *env, DisasContext *ctx)
25618 {
25619     uint32_t opcode = extract32(ctx->opcode, 20, 1);
25620
25621     switch (opcode) {
25622     case OPC_MXU_S32LDD:
25623     case OPC_MXU_S32LDDR:
25624         gen_mxu_s32ldd_s32lddr(ctx);
25625         break;
25626     default:
25627         MIPS_INVAL("decode_opc_mxu");
25628         generate_exception_end(ctx, EXCP_RI);
25629         break;
25630     }
25631 }
25632
25633 /*
25634  *
25635  * Decode MXU pool05
25636  *
25637  *   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
25638  *  +-----------+---------+-+-------------------+-------+-----------+
25639  *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL05|
25640  *  +-----------+---------+-+-------------------+-------+-----------+
25641  *
25642  */
25643 static void decode_opc_mxu__pool05(CPUMIPSState *env, DisasContext *ctx)
25644 {
25645     uint32_t opcode = extract32(ctx->opcode, 20, 1);
25646
25647     switch (opcode) {
25648     case OPC_MXU_S32STD:
25649         /* TODO: Implement emulation of S32STD instruction. */
25650         MIPS_INVAL("OPC_MXU_S32STD");
25651         generate_exception_end(ctx, EXCP_RI);
25652         break;
25653     case OPC_MXU_S32STDR:
25654         /* TODO: Implement emulation of S32STDR instruction. */
25655         MIPS_INVAL("OPC_MXU_S32STDR");
25656         generate_exception_end(ctx, EXCP_RI);
25657         break;
25658     default:
25659         MIPS_INVAL("decode_opc_mxu");
25660         generate_exception_end(ctx, EXCP_RI);
25661         break;
25662     }
25663 }
25664
25665 /*
25666  *
25667  * Decode MXU pool06
25668  *
25669  *   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
25670  *  +-----------+---------+---------+---+-------+-------+-----------+
25671  *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL06|
25672  *  +-----------+---------+---------+---+-------+-------+-----------+
25673  *
25674  */
25675 static void decode_opc_mxu__pool06(CPUMIPSState *env, DisasContext *ctx)
25676 {
25677     uint32_t opcode = extract32(ctx->opcode, 10, 4);
25678
25679     switch (opcode) {
25680     case OPC_MXU_S32LDDV:
25681         /* TODO: Implement emulation of S32LDDV instruction. */
25682         MIPS_INVAL("OPC_MXU_S32LDDV");
25683         generate_exception_end(ctx, EXCP_RI);
25684         break;
25685     case OPC_MXU_S32LDDVR:
25686         /* TODO: Implement emulation of S32LDDVR instruction. */
25687         MIPS_INVAL("OPC_MXU_S32LDDVR");
25688         generate_exception_end(ctx, EXCP_RI);
25689         break;
25690     default:
25691         MIPS_INVAL("decode_opc_mxu");
25692         generate_exception_end(ctx, EXCP_RI);
25693         break;
25694     }
25695 }
25696
25697 /*
25698  *
25699  * Decode MXU pool07
25700  *
25701  *   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
25702  *  +-----------+---------+---------+---+-------+-------+-----------+
25703  *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL07|
25704  *  +-----------+---------+---------+---+-------+-------+-----------+
25705  *
25706  */
25707 static void decode_opc_mxu__pool07(CPUMIPSState *env, DisasContext *ctx)
25708 {
25709     uint32_t opcode = extract32(ctx->opcode, 10, 4);
25710
25711     switch (opcode) {
25712     case OPC_MXU_S32STDV:
25713         /* TODO: Implement emulation of S32TDV instruction. */
25714         MIPS_INVAL("OPC_MXU_S32TDV");
25715         generate_exception_end(ctx, EXCP_RI);
25716         break;
25717     case OPC_MXU_S32STDVR:
25718         /* TODO: Implement emulation of S32TDVR instruction. */
25719         MIPS_INVAL("OPC_MXU_S32TDVR");
25720         generate_exception_end(ctx, EXCP_RI);
25721         break;
25722     default:
25723         MIPS_INVAL("decode_opc_mxu");
25724         generate_exception_end(ctx, EXCP_RI);
25725         break;
25726     }
25727 }
25728
25729 /*
25730  *
25731  * Decode MXU pool08
25732  *
25733  *   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
25734  *  +-----------+---------+-+-------------------+-------+-----------+
25735  *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL08|
25736  *  +-----------+---------+-+-------------------+-------+-----------+
25737  *
25738 */
25739 static void decode_opc_mxu__pool08(CPUMIPSState *env, DisasContext *ctx)
25740 {
25741     uint32_t opcode = extract32(ctx->opcode, 20, 1);
25742
25743     switch (opcode) {
25744     case OPC_MXU_S32LDI:
25745         /* TODO: Implement emulation of S32LDI instruction. */
25746         MIPS_INVAL("OPC_MXU_S32LDI");
25747         generate_exception_end(ctx, EXCP_RI);
25748         break;
25749     case OPC_MXU_S32LDIR:
25750         /* TODO: Implement emulation of S32LDIR instruction. */
25751         MIPS_INVAL("OPC_MXU_S32LDIR");
25752         generate_exception_end(ctx, EXCP_RI);
25753         break;
25754     default:
25755         MIPS_INVAL("decode_opc_mxu");
25756         generate_exception_end(ctx, EXCP_RI);
25757         break;
25758     }
25759 }
25760
25761 /*
25762  *
25763  * Decode MXU pool09
25764  *
25765  *   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
25766  *  +-----------+---------+-+-------------------+-------+-----------+
25767  *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL09|
25768  *  +-----------+---------+-+-------------------+-------+-----------+
25769  *
25770  */
25771 static void decode_opc_mxu__pool09(CPUMIPSState *env, DisasContext *ctx)
25772 {
25773     uint32_t opcode = extract32(ctx->opcode, 5, 0);
25774
25775     switch (opcode) {
25776     case OPC_MXU_S32SDI:
25777         /* TODO: Implement emulation of S32SDI instruction. */
25778         MIPS_INVAL("OPC_MXU_S32SDI");
25779         generate_exception_end(ctx, EXCP_RI);
25780         break;
25781     case OPC_MXU_S32SDIR:
25782         /* TODO: Implement emulation of S32SDIR instruction. */
25783         MIPS_INVAL("OPC_MXU_S32SDIR");
25784         generate_exception_end(ctx, EXCP_RI);
25785         break;
25786     default:
25787         MIPS_INVAL("decode_opc_mxu");
25788         generate_exception_end(ctx, EXCP_RI);
25789         break;
25790     }
25791 }
25792
25793 /*
25794  *
25795  * Decode MXU pool10
25796  *
25797  *   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
25798  *  +-----------+---------+---------+---+-------+-------+-----------+
25799  *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL10|
25800  *  +-----------+---------+---------+---+-------+-------+-----------+
25801  *
25802  */
25803 static void decode_opc_mxu__pool10(CPUMIPSState *env, DisasContext *ctx)
25804 {
25805     uint32_t opcode = extract32(ctx->opcode, 5, 0);
25806
25807     switch (opcode) {
25808     case OPC_MXU_S32LDIV:
25809         /* TODO: Implement emulation of S32LDIV instruction. */
25810         MIPS_INVAL("OPC_MXU_S32LDIV");
25811         generate_exception_end(ctx, EXCP_RI);
25812         break;
25813     case OPC_MXU_S32LDIVR:
25814         /* TODO: Implement emulation of S32LDIVR instruction. */
25815         MIPS_INVAL("OPC_MXU_S32LDIVR");
25816         generate_exception_end(ctx, EXCP_RI);
25817         break;
25818     default:
25819         MIPS_INVAL("decode_opc_mxu");
25820         generate_exception_end(ctx, EXCP_RI);
25821         break;
25822     }
25823 }
25824
25825 /*
25826  *
25827  * Decode MXU pool11
25828  *
25829  *   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
25830  *  +-----------+---------+---------+---+-------+-------+-----------+
25831  *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL11|
25832  *  +-----------+---------+---------+---+-------+-------+-----------+
25833  *
25834  */
25835 static void decode_opc_mxu__pool11(CPUMIPSState *env, DisasContext *ctx)
25836 {
25837     uint32_t opcode = extract32(ctx->opcode, 10, 4);
25838
25839     switch (opcode) {
25840     case OPC_MXU_S32SDIV:
25841         /* TODO: Implement emulation of S32SDIV instruction. */
25842         MIPS_INVAL("OPC_MXU_S32SDIV");
25843         generate_exception_end(ctx, EXCP_RI);
25844         break;
25845     case OPC_MXU_S32SDIVR:
25846         /* TODO: Implement emulation of S32SDIVR instruction. */
25847         MIPS_INVAL("OPC_MXU_S32SDIVR");
25848         generate_exception_end(ctx, EXCP_RI);
25849         break;
25850     default:
25851         MIPS_INVAL("decode_opc_mxu");
25852         generate_exception_end(ctx, EXCP_RI);
25853         break;
25854     }
25855 }
25856
25857 /*
25858  *
25859  * Decode MXU pool12
25860  *
25861  *   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
25862  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25863  *  |  SPECIAL2 |an2|x x|   Xd  |  XRc  |  XRb  |  XRa  |MXU__POOL12|
25864  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25865  *
25866  */
25867 static void decode_opc_mxu__pool12(CPUMIPSState *env, DisasContext *ctx)
25868 {
25869     uint32_t opcode = extract32(ctx->opcode, 22, 2);
25870
25871     switch (opcode) {
25872     case OPC_MXU_D32ACC:
25873         /* TODO: Implement emulation of D32ACC instruction. */
25874         MIPS_INVAL("OPC_MXU_D32ACC");
25875         generate_exception_end(ctx, EXCP_RI);
25876         break;
25877     case OPC_MXU_D32ACCM:
25878         /* TODO: Implement emulation of D32ACCM instruction. */
25879         MIPS_INVAL("OPC_MXU_D32ACCM");
25880         generate_exception_end(ctx, EXCP_RI);
25881         break;
25882     case OPC_MXU_D32ASUM:
25883         /* TODO: Implement emulation of D32ASUM instruction. */
25884         MIPS_INVAL("OPC_MXU_D32ASUM");
25885         generate_exception_end(ctx, EXCP_RI);
25886         break;
25887     default:
25888         MIPS_INVAL("decode_opc_mxu");
25889         generate_exception_end(ctx, EXCP_RI);
25890         break;
25891     }
25892 }
25893
25894 /*
25895  *
25896  * Decode MXU pool13
25897  *
25898  *   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
25899  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25900  *  |  SPECIAL2 |en2|x x|0 0 0 0|  XRc  |  XRb  |  XRa  |MXU__POOL13|
25901  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25902  *
25903  */
25904 static void decode_opc_mxu__pool13(CPUMIPSState *env, DisasContext *ctx)
25905 {
25906     uint32_t opcode = extract32(ctx->opcode, 22, 2);
25907
25908     switch (opcode) {
25909     case OPC_MXU_Q16ACC:
25910         /* TODO: Implement emulation of Q16ACC instruction. */
25911         MIPS_INVAL("OPC_MXU_Q16ACC");
25912         generate_exception_end(ctx, EXCP_RI);
25913         break;
25914     case OPC_MXU_Q16ACCM:
25915         /* TODO: Implement emulation of Q16ACCM instruction. */
25916         MIPS_INVAL("OPC_MXU_Q16ACCM");
25917         generate_exception_end(ctx, EXCP_RI);
25918         break;
25919     case OPC_MXU_Q16ASUM:
25920         /* TODO: Implement emulation of Q16ASUM instruction. */
25921         MIPS_INVAL("OPC_MXU_Q16ASUM");
25922         generate_exception_end(ctx, EXCP_RI);
25923         break;
25924     default:
25925         MIPS_INVAL("decode_opc_mxu");
25926         generate_exception_end(ctx, EXCP_RI);
25927         break;
25928     }
25929 }
25930
25931 /*
25932  *
25933  * Decode MXU pool14
25934  *
25935  *  Q8ADDE, Q8ACCE:
25936  *   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
25937  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25938  *  |  SPECIAL2 |0 0|x x|  XRd  |  XRc  |  XRb  |  XRa  |MXU__POOL14|
25939  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25940  *
25941  *  D8SUM, D8SUMC:
25942  *   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
25943  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25944  *  |  SPECIAL2 |en2|x x|0 0 0 0|  XRc  |  XRb  |  XRa  |MXU__POOL14|
25945  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25946  *
25947  */
25948 static void decode_opc_mxu__pool14(CPUMIPSState *env, DisasContext *ctx)
25949 {
25950     uint32_t opcode = extract32(ctx->opcode, 22, 2);
25951
25952     switch (opcode) {
25953     case OPC_MXU_Q8ADDE:
25954         /* TODO: Implement emulation of Q8ADDE instruction. */
25955         MIPS_INVAL("OPC_MXU_Q8ADDE");
25956         generate_exception_end(ctx, EXCP_RI);
25957         break;
25958     case OPC_MXU_D8SUM:
25959         /* TODO: Implement emulation of D8SUM instruction. */
25960         MIPS_INVAL("OPC_MXU_D8SUM");
25961         generate_exception_end(ctx, EXCP_RI);
25962         break;
25963     case OPC_MXU_D8SUMC:
25964         /* TODO: Implement emulation of D8SUMC instruction. */
25965         MIPS_INVAL("OPC_MXU_D8SUMC");
25966         generate_exception_end(ctx, EXCP_RI);
25967         break;
25968     default:
25969         MIPS_INVAL("decode_opc_mxu");
25970         generate_exception_end(ctx, EXCP_RI);
25971         break;
25972     }
25973 }
25974
25975 /*
25976  *
25977  * Decode MXU pool15
25978  *
25979  *  S32MUL, S32MULU, S32EXTRV:
25980  *   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
25981  *  +-----------+---------+---------+---+-------+-------+-----------+
25982  *  |  SPECIAL2 |    rs   |    rt   |x x|  XRd  |  XRa  |MXU__POOL15|
25983  *  +-----------+---------+---------+---+-------+-------+-----------+
25984  *
25985  *  S32EXTR:
25986  *   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
25987  *  +-----------+---------+---------+---+-------+-------+-----------+
25988  *  |  SPECIAL2 |    rb   |   sft5  |x x|  XRd  |  XRa  |MXU__POOL15|
25989  *  +-----------+---------+---------+---+-------+-------+-----------+
25990  *
25991  */
25992 static void decode_opc_mxu__pool15(CPUMIPSState *env, DisasContext *ctx)
25993 {
25994     uint32_t opcode = extract32(ctx->opcode, 14, 2);
25995
25996     switch (opcode) {
25997     case OPC_MXU_S32MUL:
25998         /* TODO: Implement emulation of S32MUL instruction. */
25999         MIPS_INVAL("OPC_MXU_S32MUL");
26000         generate_exception_end(ctx, EXCP_RI);
26001         break;
26002     case OPC_MXU_S32MULU:
26003         /* TODO: Implement emulation of S32MULU instruction. */
26004         MIPS_INVAL("OPC_MXU_S32MULU");
26005         generate_exception_end(ctx, EXCP_RI);
26006         break;
26007     case OPC_MXU_S32EXTR:
26008         /* TODO: Implement emulation of S32EXTR instruction. */
26009         MIPS_INVAL("OPC_MXU_S32EXTR");
26010         generate_exception_end(ctx, EXCP_RI);
26011         break;
26012     case OPC_MXU_S32EXTRV:
26013         /* TODO: Implement emulation of S32EXTRV instruction. */
26014         MIPS_INVAL("OPC_MXU_S32EXTRV");
26015         generate_exception_end(ctx, EXCP_RI);
26016         break;
26017     default:
26018         MIPS_INVAL("decode_opc_mxu");
26019         generate_exception_end(ctx, EXCP_RI);
26020         break;
26021     }
26022 }
26023
26024 /*
26025  *
26026  * Decode MXU pool16
26027  *
26028  *  D32SARW:
26029  *   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
26030  *  +-----------+---------+-----+-------+-------+-------+-----------+
26031  *  |  SPECIAL2 |    rb   |x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
26032  *  +-----------+---------+-----+-------+-------+-------+-----------+
26033  *
26034  *  S32ALN:
26035  *   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
26036  *  +-----------+---------+-----+-------+-------+-------+-----------+
26037  *  |  SPECIAL2 |    rs   |x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
26038  *  +-----------+---------+-----+-------+-------+-------+-----------+
26039  *
26040  *  S32ALNI:
26041  *   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
26042  *  +-----------+-----+---+-----+-------+-------+-------+-----------+
26043  *  |  SPECIAL2 |  s3 |0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
26044  *  +-----------+-----+---+-----+-------+-------+-------+-----------+
26045  *
26046  *  S32LUI:
26047  *   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
26048  *  +-----------+-----+---+-----+-------+---------------+-----------+
26049  *  |  SPECIAL2 |optn3|0 0|x x x|  XRc  |       s8      |MXU__POOL16|
26050  *  +-----------+-----+---+-----+-------+---------------+-----------+
26051  *
26052  *  S32NOR, S32AND, S32OR, S32XOR:
26053  *   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
26054  *  +-----------+---------+-----+-------+-------+-------+-----------+
26055  *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
26056  *  +-----------+---------+-----+-------+-------+-------+-----------+
26057  *
26058  */
26059 static void decode_opc_mxu__pool16(CPUMIPSState *env, DisasContext *ctx)
26060 {
26061     uint32_t opcode = extract32(ctx->opcode, 18, 3);
26062
26063     switch (opcode) {
26064     case OPC_MXU_D32SARW:
26065         /* TODO: Implement emulation of D32SARW instruction. */
26066         MIPS_INVAL("OPC_MXU_D32SARW");
26067         generate_exception_end(ctx, EXCP_RI);
26068         break;
26069     case OPC_MXU_S32ALN:
26070         /* TODO: Implement emulation of S32ALN instruction. */
26071         MIPS_INVAL("OPC_MXU_S32ALN");
26072         generate_exception_end(ctx, EXCP_RI);
26073         break;
26074     case OPC_MXU_S32ALNI:
26075         gen_mxu_S32ALNI(ctx);
26076         break;
26077     case OPC_MXU_S32LUI:
26078         /* TODO: Implement emulation of S32LUI instruction. */
26079         MIPS_INVAL("OPC_MXU_S32LUI");
26080         generate_exception_end(ctx, EXCP_RI);
26081         break;
26082     case OPC_MXU_S32NOR:
26083         gen_mxu_S32NOR(ctx);
26084         break;
26085     case OPC_MXU_S32AND:
26086         gen_mxu_S32AND(ctx);
26087         break;
26088     case OPC_MXU_S32OR:
26089         gen_mxu_S32OR(ctx);
26090         break;
26091     case OPC_MXU_S32XOR:
26092         gen_mxu_S32XOR(ctx);
26093         break;
26094     default:
26095         MIPS_INVAL("decode_opc_mxu");
26096         generate_exception_end(ctx, EXCP_RI);
26097         break;
26098     }
26099 }
26100
26101 /*
26102  *
26103  * Decode MXU pool17
26104  *
26105  *   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
26106  *  +-----------+---------+---------+---+---------+-----+-----------+
26107  *  |  SPECIAL2 |    rs   |    rt   |0 0|    rd   |x x x|MXU__POOL15|
26108  *  +-----------+---------+---------+---+---------+-----+-----------+
26109  *
26110  */
26111 static void decode_opc_mxu__pool17(CPUMIPSState *env, DisasContext *ctx)
26112 {
26113     uint32_t opcode = extract32(ctx->opcode, 6, 2);
26114
26115     switch (opcode) {
26116     case OPC_MXU_LXW:
26117         /* TODO: Implement emulation of LXW instruction. */
26118         MIPS_INVAL("OPC_MXU_LXW");
26119         generate_exception_end(ctx, EXCP_RI);
26120         break;
26121     case OPC_MXU_LXH:
26122         /* TODO: Implement emulation of LXH instruction. */
26123         MIPS_INVAL("OPC_MXU_LXH");
26124         generate_exception_end(ctx, EXCP_RI);
26125         break;
26126     case OPC_MXU_LXHU:
26127         /* TODO: Implement emulation of LXHU instruction. */
26128         MIPS_INVAL("OPC_MXU_LXHU");
26129         generate_exception_end(ctx, EXCP_RI);
26130         break;
26131     case OPC_MXU_LXB:
26132         /* TODO: Implement emulation of LXB instruction. */
26133         MIPS_INVAL("OPC_MXU_LXB");
26134         generate_exception_end(ctx, EXCP_RI);
26135         break;
26136     case OPC_MXU_LXBU:
26137         /* TODO: Implement emulation of LXBU instruction. */
26138         MIPS_INVAL("OPC_MXU_LXBU");
26139         generate_exception_end(ctx, EXCP_RI);
26140         break;
26141     default:
26142         MIPS_INVAL("decode_opc_mxu");
26143         generate_exception_end(ctx, EXCP_RI);
26144         break;
26145     }
26146 }
26147 /*
26148  *
26149  * Decode MXU pool18
26150  *
26151  *   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
26152  *  +-----------+---------+-----+-------+-------+-------+-----------+
26153  *  |  SPECIAL2 |    rb   |x x x|  XRd  |  XRa  |0 0 0 0|MXU__POOL18|
26154  *  +-----------+---------+-----+-------+-------+-------+-----------+
26155  *
26156  */
26157 static void decode_opc_mxu__pool18(CPUMIPSState *env, DisasContext *ctx)
26158 {
26159     uint32_t opcode = extract32(ctx->opcode, 18, 3);
26160
26161     switch (opcode) {
26162     case OPC_MXU_D32SLLV:
26163         /* TODO: Implement emulation of D32SLLV instruction. */
26164         MIPS_INVAL("OPC_MXU_D32SLLV");
26165         generate_exception_end(ctx, EXCP_RI);
26166         break;
26167     case OPC_MXU_D32SLRV:
26168         /* TODO: Implement emulation of D32SLRV instruction. */
26169         MIPS_INVAL("OPC_MXU_D32SLRV");
26170         generate_exception_end(ctx, EXCP_RI);
26171         break;
26172     case OPC_MXU_D32SARV:
26173         /* TODO: Implement emulation of D32SARV instruction. */
26174         MIPS_INVAL("OPC_MXU_D32SARV");
26175         generate_exception_end(ctx, EXCP_RI);
26176         break;
26177     case OPC_MXU_Q16SLLV:
26178         /* TODO: Implement emulation of Q16SLLV instruction. */
26179         MIPS_INVAL("OPC_MXU_Q16SLLV");
26180         generate_exception_end(ctx, EXCP_RI);
26181         break;
26182     case OPC_MXU_Q16SLRV:
26183         /* TODO: Implement emulation of Q16SLRV instruction. */
26184         MIPS_INVAL("OPC_MXU_Q16SLRV");
26185         generate_exception_end(ctx, EXCP_RI);
26186         break;
26187     case OPC_MXU_Q16SARV:
26188         /* TODO: Implement emulation of Q16SARV instruction. */
26189         MIPS_INVAL("OPC_MXU_Q16SARV");
26190         generate_exception_end(ctx, EXCP_RI);
26191         break;
26192     default:
26193         MIPS_INVAL("decode_opc_mxu");
26194         generate_exception_end(ctx, EXCP_RI);
26195         break;
26196     }
26197 }
26198
26199 /*
26200  *
26201  * Decode MXU pool19
26202  *
26203  *   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
26204  *  +-----------+---+---+-------+-------+-------+-------+-----------+
26205  *  |  SPECIAL2 |0 0|x x|  XRd  |  XRc  |  XRb  |  XRa  |MXU__POOL19|
26206  *  +-----------+---+---+-------+-------+-------+-------+-----------+
26207  *
26208  */
26209 static void decode_opc_mxu__pool19(CPUMIPSState *env, DisasContext *ctx)
26210 {
26211     uint32_t opcode = extract32(ctx->opcode, 22, 2);
26212
26213     switch (opcode) {
26214     case OPC_MXU_Q8MUL:
26215     case OPC_MXU_Q8MULSU:
26216         gen_mxu_q8mul_q8mulsu(ctx);
26217         break;
26218     default:
26219         MIPS_INVAL("decode_opc_mxu");
26220         generate_exception_end(ctx, EXCP_RI);
26221         break;
26222     }
26223 }
26224
26225 /*
26226  *
26227  * Decode MXU pool20
26228  *
26229  *   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
26230  *  +-----------+---------+-----+-------+-------+-------+-----------+
26231  *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL20|
26232  *  +-----------+---------+-----+-------+-------+-------+-----------+
26233  *
26234  */
26235 static void decode_opc_mxu__pool20(CPUMIPSState *env, DisasContext *ctx)
26236 {
26237     uint32_t opcode = extract32(ctx->opcode, 18, 3);
26238
26239     switch (opcode) {
26240     case OPC_MXU_Q8MOVZ:
26241         /* TODO: Implement emulation of Q8MOVZ instruction. */
26242         MIPS_INVAL("OPC_MXU_Q8MOVZ");
26243         generate_exception_end(ctx, EXCP_RI);
26244         break;
26245     case OPC_MXU_Q8MOVN:
26246         /* TODO: Implement emulation of Q8MOVN instruction. */
26247         MIPS_INVAL("OPC_MXU_Q8MOVN");
26248         generate_exception_end(ctx, EXCP_RI);
26249         break;
26250     case OPC_MXU_D16MOVZ:
26251         /* TODO: Implement emulation of D16MOVZ instruction. */
26252         MIPS_INVAL("OPC_MXU_D16MOVZ");
26253         generate_exception_end(ctx, EXCP_RI);
26254         break;
26255     case OPC_MXU_D16MOVN:
26256         /* TODO: Implement emulation of D16MOVN instruction. */
26257         MIPS_INVAL("OPC_MXU_D16MOVN");
26258         generate_exception_end(ctx, EXCP_RI);
26259         break;
26260     case OPC_MXU_S32MOVZ:
26261         /* TODO: Implement emulation of S32MOVZ instruction. */
26262         MIPS_INVAL("OPC_MXU_S32MOVZ");
26263         generate_exception_end(ctx, EXCP_RI);
26264         break;
26265     case OPC_MXU_S32MOVN:
26266         /* TODO: Implement emulation of S32MOVN instruction. */
26267         MIPS_INVAL("OPC_MXU_S32MOVN");
26268         generate_exception_end(ctx, EXCP_RI);
26269         break;
26270     default:
26271         MIPS_INVAL("decode_opc_mxu");
26272         generate_exception_end(ctx, EXCP_RI);
26273         break;
26274     }
26275 }
26276
26277 /*
26278  *
26279  * Decode MXU pool21
26280  *
26281  *   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
26282  *  +-----------+---+---+-------+-------+-------+-------+-----------+
26283  *  |  SPECIAL2 |an2|x x|  XRd  |  XRc  |  XRb  |  XRa  |MXU__POOL21|
26284  *  +-----------+---+---+-------+-------+-------+-------+-----------+
26285  *
26286  */
26287 static void decode_opc_mxu__pool21(CPUMIPSState *env, DisasContext *ctx)
26288 {
26289     uint32_t opcode = extract32(ctx->opcode, 22, 2);
26290
26291     switch (opcode) {
26292     case OPC_MXU_Q8MAC:
26293         /* TODO: Implement emulation of Q8MAC instruction. */
26294         MIPS_INVAL("OPC_MXU_Q8MAC");
26295         generate_exception_end(ctx, EXCP_RI);
26296         break;
26297     case OPC_MXU_Q8MACSU:
26298         /* TODO: Implement emulation of Q8MACSU instruction. */
26299         MIPS_INVAL("OPC_MXU_Q8MACSU");
26300         generate_exception_end(ctx, EXCP_RI);
26301         break;
26302     default:
26303         MIPS_INVAL("decode_opc_mxu");
26304         generate_exception_end(ctx, EXCP_RI);
26305         break;
26306     }
26307 }
26308
26309
26310 /*
26311  * Main MXU decoding function
26312  *
26313  *   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
26314  *  +-----------+---------------------------------------+-----------+
26315  *  |  SPECIAL2 |                                       |x x x x x x|
26316  *  +-----------+---------------------------------------+-----------+
26317  *
26318  */
26319 static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx)
26320 {
26321     /*
26322      * TODO: Investigate necessity of including handling of
26323      * CLZ, CLO, SDBB in this function, as they belong to
26324      * SPECIAL2 opcode space for regular pre-R6 MIPS ISAs.
26325      */
26326     uint32_t opcode = extract32(ctx->opcode, 0, 6);
26327
26328     if (opcode == OPC__MXU_MUL) {
26329         uint32_t  rs, rt, rd, op1;
26330
26331         rs = extract32(ctx->opcode, 21, 5);
26332         rt = extract32(ctx->opcode, 16, 5);
26333         rd = extract32(ctx->opcode, 11, 5);
26334         op1 = MASK_SPECIAL2(ctx->opcode);
26335
26336         gen_arith(ctx, op1, rd, rs, rt);
26337
26338         return;
26339     }
26340
26341     if (opcode == OPC_MXU_S32M2I) {
26342         gen_mxu_s32m2i(ctx);
26343         return;
26344     }
26345
26346     if (opcode == OPC_MXU_S32I2M) {
26347         gen_mxu_s32i2m(ctx);
26348         return;
26349     }
26350
26351     {
26352         TCGv t_mxu_cr = tcg_temp_new();
26353         TCGLabel *l_exit = gen_new_label();
26354
26355         gen_load_mxu_cr(t_mxu_cr);
26356         tcg_gen_andi_tl(t_mxu_cr, t_mxu_cr, MXU_CR_MXU_EN);
26357         tcg_gen_brcondi_tl(TCG_COND_NE, t_mxu_cr, MXU_CR_MXU_EN, l_exit);
26358
26359         switch (opcode) {
26360         case OPC_MXU_S32MADD:
26361             /* TODO: Implement emulation of S32MADD instruction. */
26362             MIPS_INVAL("OPC_MXU_S32MADD");
26363             generate_exception_end(ctx, EXCP_RI);
26364             break;
26365         case OPC_MXU_S32MADDU:
26366             /* TODO: Implement emulation of S32MADDU instruction. */
26367             MIPS_INVAL("OPC_MXU_S32MADDU");
26368             generate_exception_end(ctx, EXCP_RI);
26369             break;
26370         case OPC_MXU__POOL00:
26371             decode_opc_mxu__pool00(env, ctx);
26372             break;
26373         case OPC_MXU_S32MSUB:
26374             /* TODO: Implement emulation of S32MSUB instruction. */
26375             MIPS_INVAL("OPC_MXU_S32MSUB");
26376             generate_exception_end(ctx, EXCP_RI);
26377             break;
26378         case OPC_MXU_S32MSUBU:
26379             /* TODO: Implement emulation of S32MSUBU instruction. */
26380             MIPS_INVAL("OPC_MXU_S32MSUBU");
26381             generate_exception_end(ctx, EXCP_RI);
26382             break;
26383         case OPC_MXU__POOL01:
26384             decode_opc_mxu__pool01(env, ctx);
26385             break;
26386         case OPC_MXU__POOL02:
26387             decode_opc_mxu__pool02(env, ctx);
26388             break;
26389         case OPC_MXU_D16MUL:
26390             gen_mxu_d16mul(ctx);
26391             break;
26392         case OPC_MXU__POOL03:
26393             decode_opc_mxu__pool03(env, ctx);
26394             break;
26395         case OPC_MXU_D16MAC:
26396             gen_mxu_d16mac(ctx);
26397             break;
26398         case OPC_MXU_D16MACF:
26399             /* TODO: Implement emulation of D16MACF instruction. */
26400             MIPS_INVAL("OPC_MXU_D16MACF");
26401             generate_exception_end(ctx, EXCP_RI);
26402             break;
26403         case OPC_MXU_D16MADL:
26404             /* TODO: Implement emulation of D16MADL instruction. */
26405             MIPS_INVAL("OPC_MXU_D16MADL");
26406             generate_exception_end(ctx, EXCP_RI);
26407             break;
26408         case OPC_MXU_S16MAD:
26409             /* TODO: Implement emulation of S16MAD instruction. */
26410             MIPS_INVAL("OPC_MXU_S16MAD");
26411             generate_exception_end(ctx, EXCP_RI);
26412             break;
26413         case OPC_MXU_Q16ADD:
26414             /* TODO: Implement emulation of Q16ADD instruction. */
26415             MIPS_INVAL("OPC_MXU_Q16ADD");
26416             generate_exception_end(ctx, EXCP_RI);
26417             break;
26418         case OPC_MXU_D16MACE:
26419             /* TODO: Implement emulation of D16MACE instruction. */
26420             MIPS_INVAL("OPC_MXU_D16MACE");
26421             generate_exception_end(ctx, EXCP_RI);
26422             break;
26423         case OPC_MXU__POOL04:
26424             decode_opc_mxu__pool04(env, ctx);
26425             break;
26426         case OPC_MXU__POOL05:
26427             decode_opc_mxu__pool05(env, ctx);
26428             break;
26429         case OPC_MXU__POOL06:
26430             decode_opc_mxu__pool06(env, ctx);
26431             break;
26432         case OPC_MXU__POOL07:
26433             decode_opc_mxu__pool07(env, ctx);
26434             break;
26435         case OPC_MXU__POOL08:
26436             decode_opc_mxu__pool08(env, ctx);
26437             break;
26438         case OPC_MXU__POOL09:
26439             decode_opc_mxu__pool09(env, ctx);
26440             break;
26441         case OPC_MXU__POOL10:
26442             decode_opc_mxu__pool10(env, ctx);
26443             break;
26444         case OPC_MXU__POOL11:
26445             decode_opc_mxu__pool11(env, ctx);
26446             break;
26447         case OPC_MXU_D32ADD:
26448             /* TODO: Implement emulation of D32ADD instruction. */
26449             MIPS_INVAL("OPC_MXU_D32ADD");
26450             generate_exception_end(ctx, EXCP_RI);
26451             break;
26452         case OPC_MXU__POOL12:
26453             decode_opc_mxu__pool12(env, ctx);
26454             break;
26455         case OPC_MXU__POOL13:
26456             decode_opc_mxu__pool13(env, ctx);
26457             break;
26458         case OPC_MXU__POOL14:
26459             decode_opc_mxu__pool14(env, ctx);
26460             break;
26461         case OPC_MXU_Q8ACCE:
26462             /* TODO: Implement emulation of Q8ACCE instruction. */
26463             MIPS_INVAL("OPC_MXU_Q8ACCE");
26464             generate_exception_end(ctx, EXCP_RI);
26465             break;
26466         case OPC_MXU_S8LDD:
26467             gen_mxu_s8ldd(ctx);
26468             break;
26469         case OPC_MXU_S8STD:
26470             /* TODO: Implement emulation of S8STD instruction. */
26471             MIPS_INVAL("OPC_MXU_S8STD");
26472             generate_exception_end(ctx, EXCP_RI);
26473             break;
26474         case OPC_MXU_S8LDI:
26475             /* TODO: Implement emulation of S8LDI instruction. */
26476             MIPS_INVAL("OPC_MXU_S8LDI");
26477             generate_exception_end(ctx, EXCP_RI);
26478             break;
26479         case OPC_MXU_S8SDI:
26480             /* TODO: Implement emulation of S8SDI instruction. */
26481             MIPS_INVAL("OPC_MXU_S8SDI");
26482             generate_exception_end(ctx, EXCP_RI);
26483             break;
26484         case OPC_MXU__POOL15:
26485             decode_opc_mxu__pool15(env, ctx);
26486             break;
26487         case OPC_MXU__POOL16:
26488             decode_opc_mxu__pool16(env, ctx);
26489             break;
26490         case OPC_MXU__POOL17:
26491             decode_opc_mxu__pool17(env, ctx);
26492             break;
26493         case OPC_MXU_S16LDD:
26494             /* TODO: Implement emulation of S16LDD instruction. */
26495             MIPS_INVAL("OPC_MXU_S16LDD");
26496             generate_exception_end(ctx, EXCP_RI);
26497             break;
26498         case OPC_MXU_S16STD:
26499             /* TODO: Implement emulation of S16STD instruction. */
26500             MIPS_INVAL("OPC_MXU_S16STD");
26501             generate_exception_end(ctx, EXCP_RI);
26502             break;
26503         case OPC_MXU_S16LDI:
26504             /* TODO: Implement emulation of S16LDI instruction. */
26505             MIPS_INVAL("OPC_MXU_S16LDI");
26506             generate_exception_end(ctx, EXCP_RI);
26507             break;
26508         case OPC_MXU_S16SDI:
26509             /* TODO: Implement emulation of S16SDI instruction. */
26510             MIPS_INVAL("OPC_MXU_S16SDI");
26511             generate_exception_end(ctx, EXCP_RI);
26512             break;
26513         case OPC_MXU_D32SLL:
26514             /* TODO: Implement emulation of D32SLL instruction. */
26515             MIPS_INVAL("OPC_MXU_D32SLL");
26516             generate_exception_end(ctx, EXCP_RI);
26517             break;
26518         case OPC_MXU_D32SLR:
26519             /* TODO: Implement emulation of D32SLR instruction. */
26520             MIPS_INVAL("OPC_MXU_D32SLR");
26521             generate_exception_end(ctx, EXCP_RI);
26522             break;
26523         case OPC_MXU_D32SARL:
26524             /* TODO: Implement emulation of D32SARL instruction. */
26525             MIPS_INVAL("OPC_MXU_D32SARL");
26526             generate_exception_end(ctx, EXCP_RI);
26527             break;
26528         case OPC_MXU_D32SAR:
26529             /* TODO: Implement emulation of D32SAR instruction. */
26530             MIPS_INVAL("OPC_MXU_D32SAR");
26531             generate_exception_end(ctx, EXCP_RI);
26532             break;
26533         case OPC_MXU_Q16SLL:
26534             /* TODO: Implement emulation of Q16SLL instruction. */
26535             MIPS_INVAL("OPC_MXU_Q16SLL");
26536             generate_exception_end(ctx, EXCP_RI);
26537             break;
26538         case OPC_MXU_Q16SLR:
26539             /* TODO: Implement emulation of Q16SLR instruction. */
26540             MIPS_INVAL("OPC_MXU_Q16SLR");
26541             generate_exception_end(ctx, EXCP_RI);
26542             break;
26543         case OPC_MXU__POOL18:
26544             decode_opc_mxu__pool18(env, ctx);
26545             break;
26546         case OPC_MXU_Q16SAR:
26547             /* TODO: Implement emulation of Q16SAR instruction. */
26548             MIPS_INVAL("OPC_MXU_Q16SAR");
26549             generate_exception_end(ctx, EXCP_RI);
26550             break;
26551         case OPC_MXU__POOL19:
26552             decode_opc_mxu__pool19(env, ctx);
26553             break;
26554         case OPC_MXU__POOL20:
26555             decode_opc_mxu__pool20(env, ctx);
26556             break;
26557         case OPC_MXU__POOL21:
26558             decode_opc_mxu__pool21(env, ctx);
26559             break;
26560         case OPC_MXU_Q16SCOP:
26561             /* TODO: Implement emulation of Q16SCOP instruction. */
26562             MIPS_INVAL("OPC_MXU_Q16SCOP");
26563             generate_exception_end(ctx, EXCP_RI);
26564             break;
26565         case OPC_MXU_Q8MADL:
26566             /* TODO: Implement emulation of Q8MADL instruction. */
26567             MIPS_INVAL("OPC_MXU_Q8MADL");
26568             generate_exception_end(ctx, EXCP_RI);
26569             break;
26570         case OPC_MXU_S32SFL:
26571             /* TODO: Implement emulation of S32SFL instruction. */
26572             MIPS_INVAL("OPC_MXU_S32SFL");
26573             generate_exception_end(ctx, EXCP_RI);
26574             break;
26575         case OPC_MXU_Q8SAD:
26576             /* TODO: Implement emulation of Q8SAD instruction. */
26577             MIPS_INVAL("OPC_MXU_Q8SAD");
26578             generate_exception_end(ctx, EXCP_RI);
26579             break;
26580         default:
26581             MIPS_INVAL("decode_opc_mxu");
26582             generate_exception_end(ctx, EXCP_RI);
26583         }
26584
26585         gen_set_label(l_exit);
26586         tcg_temp_free(t_mxu_cr);
26587     }
26588 }
26589
26590 #endif /* !defined(TARGET_MIPS64) */
26591
26592
26593 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
26594 {
26595     int rs, rt, rd;
26596     uint32_t op1;
26597
26598     check_insn_opc_removed(ctx, ISA_MIPS32R6);
26599
26600     rs = (ctx->opcode >> 21) & 0x1f;
26601     rt = (ctx->opcode >> 16) & 0x1f;
26602     rd = (ctx->opcode >> 11) & 0x1f;
26603
26604     op1 = MASK_SPECIAL2(ctx->opcode);
26605     switch (op1) {
26606     case OPC_MADD: /* Multiply and add/sub */
26607     case OPC_MADDU:
26608     case OPC_MSUB:
26609     case OPC_MSUBU:
26610         check_insn(ctx, ISA_MIPS32);
26611         gen_muldiv(ctx, op1, rd & 3, rs, rt);
26612         break;
26613     case OPC_MUL:
26614         gen_arith(ctx, op1, rd, rs, rt);
26615         break;
26616     case OPC_DIV_G_2F:
26617     case OPC_DIVU_G_2F:
26618     case OPC_MULT_G_2F:
26619     case OPC_MULTU_G_2F:
26620     case OPC_MOD_G_2F:
26621     case OPC_MODU_G_2F:
26622         check_insn(ctx, INSN_LOONGSON2F);
26623         gen_loongson_integer(ctx, op1, rd, rs, rt);
26624         break;
26625     case OPC_CLO:
26626     case OPC_CLZ:
26627         check_insn(ctx, ISA_MIPS32);
26628         gen_cl(ctx, op1, rd, rs);
26629         break;
26630     case OPC_SDBBP:
26631         if (is_uhi(extract32(ctx->opcode, 6, 20))) {
26632             gen_helper_do_semihosting(cpu_env);
26633         } else {
26634             /* XXX: not clear which exception should be raised
26635              *      when in debug mode...
26636              */
26637             check_insn(ctx, ISA_MIPS32);
26638             generate_exception_end(ctx, EXCP_DBp);
26639         }
26640         break;
26641 #if defined(TARGET_MIPS64)
26642     case OPC_DCLO:
26643     case OPC_DCLZ:
26644         check_insn(ctx, ISA_MIPS64);
26645         check_mips_64(ctx);
26646         gen_cl(ctx, op1, rd, rs);
26647         break;
26648     case OPC_DMULT_G_2F:
26649     case OPC_DMULTU_G_2F:
26650     case OPC_DDIV_G_2F:
26651     case OPC_DDIVU_G_2F:
26652     case OPC_DMOD_G_2F:
26653     case OPC_DMODU_G_2F:
26654         check_insn(ctx, INSN_LOONGSON2F);
26655         gen_loongson_integer(ctx, op1, rd, rs, rt);
26656         break;
26657 #endif
26658     default:            /* Invalid */
26659         MIPS_INVAL("special2_legacy");
26660         generate_exception_end(ctx, EXCP_RI);
26661         break;
26662     }
26663 }
26664
26665 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
26666 {
26667     int rs, rt, rd, sa;
26668     uint32_t op1, op2;
26669     int16_t imm;
26670
26671     rs = (ctx->opcode >> 21) & 0x1f;
26672     rt = (ctx->opcode >> 16) & 0x1f;
26673     rd = (ctx->opcode >> 11) & 0x1f;
26674     sa = (ctx->opcode >> 6) & 0x1f;
26675     imm = (int16_t)ctx->opcode >> 7;
26676
26677     op1 = MASK_SPECIAL3(ctx->opcode);
26678     switch (op1) {
26679     case R6_OPC_PREF:
26680         if (rt >= 24) {
26681             /* hint codes 24-31 are reserved and signal RI */
26682             generate_exception_end(ctx, EXCP_RI);
26683         }
26684         /* Treat as NOP. */
26685         break;
26686     case R6_OPC_CACHE:
26687         check_cp0_enabled(ctx);
26688         if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
26689             gen_cache_operation(ctx, rt, rs, imm);
26690         }
26691         break;
26692     case R6_OPC_SC:
26693         gen_st_cond(ctx, op1, rt, rs, imm);
26694         break;
26695     case R6_OPC_LL:
26696         gen_ld(ctx, op1, rt, rs, imm);
26697         break;
26698     case OPC_BSHFL:
26699         {
26700             if (rd == 0) {
26701                 /* Treat as NOP. */
26702                 break;
26703             }
26704             op2 = MASK_BSHFL(ctx->opcode);
26705             switch (op2) {
26706             case OPC_ALIGN:
26707             case OPC_ALIGN_1:
26708             case OPC_ALIGN_2:
26709             case OPC_ALIGN_3:
26710                 gen_align(ctx, 32, rd, rs, rt, sa & 3);
26711                 break;
26712             case OPC_BITSWAP:
26713                 gen_bitswap(ctx, op2, rd, rt);
26714                 break;
26715             }
26716         }
26717         break;
26718 #if defined(TARGET_MIPS64)
26719     case R6_OPC_SCD:
26720         gen_st_cond(ctx, op1, rt, rs, imm);
26721         break;
26722     case R6_OPC_LLD:
26723         gen_ld(ctx, op1, rt, rs, imm);
26724         break;
26725     case OPC_DBSHFL:
26726         check_mips_64(ctx);
26727         {
26728             if (rd == 0) {
26729                 /* Treat as NOP. */
26730                 break;
26731             }
26732             op2 = MASK_DBSHFL(ctx->opcode);
26733             switch (op2) {
26734             case OPC_DALIGN:
26735             case OPC_DALIGN_1:
26736             case OPC_DALIGN_2:
26737             case OPC_DALIGN_3:
26738             case OPC_DALIGN_4:
26739             case OPC_DALIGN_5:
26740             case OPC_DALIGN_6:
26741             case OPC_DALIGN_7:
26742                 gen_align(ctx, 64, rd, rs, rt, sa & 7);
26743                 break;
26744             case OPC_DBITSWAP:
26745                 gen_bitswap(ctx, op2, rd, rt);
26746                 break;
26747             }
26748
26749         }
26750         break;
26751 #endif
26752     default:            /* Invalid */
26753         MIPS_INVAL("special3_r6");
26754         generate_exception_end(ctx, EXCP_RI);
26755         break;
26756     }
26757 }
26758
26759 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
26760 {
26761     int rs, rt, rd;
26762     uint32_t op1, op2;
26763
26764     rs = (ctx->opcode >> 21) & 0x1f;
26765     rt = (ctx->opcode >> 16) & 0x1f;
26766     rd = (ctx->opcode >> 11) & 0x1f;
26767
26768     op1 = MASK_SPECIAL3(ctx->opcode);
26769     switch (op1) {
26770     case OPC_DIV_G_2E:
26771     case OPC_DIVU_G_2E:
26772     case OPC_MOD_G_2E:
26773     case OPC_MODU_G_2E:
26774     case OPC_MULT_G_2E:
26775     case OPC_MULTU_G_2E:
26776         /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
26777          * the same mask and op1. */
26778         if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
26779             op2 = MASK_ADDUH_QB(ctx->opcode);
26780             switch (op2) {
26781             case OPC_ADDUH_QB:
26782             case OPC_ADDUH_R_QB:
26783             case OPC_ADDQH_PH:
26784             case OPC_ADDQH_R_PH:
26785             case OPC_ADDQH_W:
26786             case OPC_ADDQH_R_W:
26787             case OPC_SUBUH_QB:
26788             case OPC_SUBUH_R_QB:
26789             case OPC_SUBQH_PH:
26790             case OPC_SUBQH_R_PH:
26791             case OPC_SUBQH_W:
26792             case OPC_SUBQH_R_W:
26793                 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26794                 break;
26795             case OPC_MUL_PH:
26796             case OPC_MUL_S_PH:
26797             case OPC_MULQ_S_W:
26798             case OPC_MULQ_RS_W:
26799                 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
26800                 break;
26801             default:
26802                 MIPS_INVAL("MASK ADDUH.QB");
26803                 generate_exception_end(ctx, EXCP_RI);
26804                 break;
26805             }
26806         } else if (ctx->insn_flags & INSN_LOONGSON2E) {
26807             gen_loongson_integer(ctx, op1, rd, rs, rt);
26808         } else {
26809             generate_exception_end(ctx, EXCP_RI);
26810         }
26811         break;
26812     case OPC_LX_DSP:
26813         op2 = MASK_LX(ctx->opcode);
26814         switch (op2) {
26815 #if defined(TARGET_MIPS64)
26816         case OPC_LDX:
26817 #endif
26818         case OPC_LBUX:
26819         case OPC_LHX:
26820         case OPC_LWX:
26821             gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
26822             break;
26823         default:            /* Invalid */
26824             MIPS_INVAL("MASK LX");
26825             generate_exception_end(ctx, EXCP_RI);
26826             break;
26827         }
26828         break;
26829     case OPC_ABSQ_S_PH_DSP:
26830         op2 = MASK_ABSQ_S_PH(ctx->opcode);
26831         switch (op2) {
26832         case OPC_ABSQ_S_QB:
26833         case OPC_ABSQ_S_PH:
26834         case OPC_ABSQ_S_W:
26835         case OPC_PRECEQ_W_PHL:
26836         case OPC_PRECEQ_W_PHR:
26837         case OPC_PRECEQU_PH_QBL:
26838         case OPC_PRECEQU_PH_QBR:
26839         case OPC_PRECEQU_PH_QBLA:
26840         case OPC_PRECEQU_PH_QBRA:
26841         case OPC_PRECEU_PH_QBL:
26842         case OPC_PRECEU_PH_QBR:
26843         case OPC_PRECEU_PH_QBLA:
26844         case OPC_PRECEU_PH_QBRA:
26845             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26846             break;
26847         case OPC_BITREV:
26848         case OPC_REPL_QB:
26849         case OPC_REPLV_QB:
26850         case OPC_REPL_PH:
26851         case OPC_REPLV_PH:
26852             gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
26853             break;
26854         default:
26855             MIPS_INVAL("MASK ABSQ_S.PH");
26856             generate_exception_end(ctx, EXCP_RI);
26857             break;
26858         }
26859         break;
26860     case OPC_ADDU_QB_DSP:
26861         op2 = MASK_ADDU_QB(ctx->opcode);
26862         switch (op2) {
26863         case OPC_ADDQ_PH:
26864         case OPC_ADDQ_S_PH:
26865         case OPC_ADDQ_S_W:
26866         case OPC_ADDU_QB:
26867         case OPC_ADDU_S_QB:
26868         case OPC_ADDU_PH:
26869         case OPC_ADDU_S_PH:
26870         case OPC_SUBQ_PH:
26871         case OPC_SUBQ_S_PH:
26872         case OPC_SUBQ_S_W:
26873         case OPC_SUBU_QB:
26874         case OPC_SUBU_S_QB:
26875         case OPC_SUBU_PH:
26876         case OPC_SUBU_S_PH:
26877         case OPC_ADDSC:
26878         case OPC_ADDWC:
26879         case OPC_MODSUB:
26880         case OPC_RADDU_W_QB:
26881             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26882             break;
26883         case OPC_MULEU_S_PH_QBL:
26884         case OPC_MULEU_S_PH_QBR:
26885         case OPC_MULQ_RS_PH:
26886         case OPC_MULEQ_S_W_PHL:
26887         case OPC_MULEQ_S_W_PHR:
26888         case OPC_MULQ_S_PH:
26889             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
26890             break;
26891         default:            /* Invalid */
26892             MIPS_INVAL("MASK ADDU.QB");
26893             generate_exception_end(ctx, EXCP_RI);
26894             break;
26895
26896         }
26897         break;
26898     case OPC_CMPU_EQ_QB_DSP:
26899         op2 = MASK_CMPU_EQ_QB(ctx->opcode);
26900         switch (op2) {
26901         case OPC_PRECR_SRA_PH_W:
26902         case OPC_PRECR_SRA_R_PH_W:
26903             gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
26904             break;
26905         case OPC_PRECR_QB_PH:
26906         case OPC_PRECRQ_QB_PH:
26907         case OPC_PRECRQ_PH_W:
26908         case OPC_PRECRQ_RS_PH_W:
26909         case OPC_PRECRQU_S_QB_PH:
26910             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26911             break;
26912         case OPC_CMPU_EQ_QB:
26913         case OPC_CMPU_LT_QB:
26914         case OPC_CMPU_LE_QB:
26915         case OPC_CMP_EQ_PH:
26916         case OPC_CMP_LT_PH:
26917         case OPC_CMP_LE_PH:
26918             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
26919             break;
26920         case OPC_CMPGU_EQ_QB:
26921         case OPC_CMPGU_LT_QB:
26922         case OPC_CMPGU_LE_QB:
26923         case OPC_CMPGDU_EQ_QB:
26924         case OPC_CMPGDU_LT_QB:
26925         case OPC_CMPGDU_LE_QB:
26926         case OPC_PICK_QB:
26927         case OPC_PICK_PH:
26928         case OPC_PACKRL_PH:
26929             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
26930             break;
26931         default:            /* Invalid */
26932             MIPS_INVAL("MASK CMPU.EQ.QB");
26933             generate_exception_end(ctx, EXCP_RI);
26934             break;
26935         }
26936         break;
26937     case OPC_SHLL_QB_DSP:
26938         gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
26939         break;
26940     case OPC_DPA_W_PH_DSP:
26941         op2 = MASK_DPA_W_PH(ctx->opcode);
26942         switch (op2) {
26943         case OPC_DPAU_H_QBL:
26944         case OPC_DPAU_H_QBR:
26945         case OPC_DPSU_H_QBL:
26946         case OPC_DPSU_H_QBR:
26947         case OPC_DPA_W_PH:
26948         case OPC_DPAX_W_PH:
26949         case OPC_DPAQ_S_W_PH:
26950         case OPC_DPAQX_S_W_PH:
26951         case OPC_DPAQX_SA_W_PH:
26952         case OPC_DPS_W_PH:
26953         case OPC_DPSX_W_PH:
26954         case OPC_DPSQ_S_W_PH:
26955         case OPC_DPSQX_S_W_PH:
26956         case OPC_DPSQX_SA_W_PH:
26957         case OPC_MULSAQ_S_W_PH:
26958         case OPC_DPAQ_SA_L_W:
26959         case OPC_DPSQ_SA_L_W:
26960         case OPC_MAQ_S_W_PHL:
26961         case OPC_MAQ_S_W_PHR:
26962         case OPC_MAQ_SA_W_PHL:
26963         case OPC_MAQ_SA_W_PHR:
26964         case OPC_MULSA_W_PH:
26965             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26966             break;
26967         default:            /* Invalid */
26968             MIPS_INVAL("MASK DPAW.PH");
26969             generate_exception_end(ctx, EXCP_RI);
26970             break;
26971         }
26972         break;
26973     case OPC_INSV_DSP:
26974         op2 = MASK_INSV(ctx->opcode);
26975         switch (op2) {
26976         case OPC_INSV:
26977             check_dsp(ctx);
26978             {
26979                 TCGv t0, t1;
26980
26981                 if (rt == 0) {
26982                     break;
26983                 }
26984
26985                 t0 = tcg_temp_new();
26986                 t1 = tcg_temp_new();
26987
26988                 gen_load_gpr(t0, rt);
26989                 gen_load_gpr(t1, rs);
26990
26991                 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
26992
26993                 tcg_temp_free(t0);
26994                 tcg_temp_free(t1);
26995                 break;
26996             }
26997         default:            /* Invalid */
26998             MIPS_INVAL("MASK INSV");
26999             generate_exception_end(ctx, EXCP_RI);
27000             break;
27001         }
27002         break;
27003     case OPC_APPEND_DSP:
27004         gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
27005         break;
27006     case OPC_EXTR_W_DSP:
27007         op2 = MASK_EXTR_W(ctx->opcode);
27008         switch (op2) {
27009         case OPC_EXTR_W:
27010         case OPC_EXTR_R_W:
27011         case OPC_EXTR_RS_W:
27012         case OPC_EXTR_S_H:
27013         case OPC_EXTRV_S_H:
27014         case OPC_EXTRV_W:
27015         case OPC_EXTRV_R_W:
27016         case OPC_EXTRV_RS_W:
27017         case OPC_EXTP:
27018         case OPC_EXTPV:
27019         case OPC_EXTPDP:
27020         case OPC_EXTPDPV:
27021             gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
27022             break;
27023         case OPC_RDDSP:
27024             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
27025             break;
27026         case OPC_SHILO:
27027         case OPC_SHILOV:
27028         case OPC_MTHLIP:
27029         case OPC_WRDSP:
27030             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
27031             break;
27032         default:            /* Invalid */
27033             MIPS_INVAL("MASK EXTR.W");
27034             generate_exception_end(ctx, EXCP_RI);
27035             break;
27036         }
27037         break;
27038 #if defined(TARGET_MIPS64)
27039     case OPC_DDIV_G_2E:
27040     case OPC_DDIVU_G_2E:
27041     case OPC_DMULT_G_2E:
27042     case OPC_DMULTU_G_2E:
27043     case OPC_DMOD_G_2E:
27044     case OPC_DMODU_G_2E:
27045         check_insn(ctx, INSN_LOONGSON2E);
27046         gen_loongson_integer(ctx, op1, rd, rs, rt);
27047         break;
27048     case OPC_ABSQ_S_QH_DSP:
27049         op2 = MASK_ABSQ_S_QH(ctx->opcode);
27050         switch (op2) {
27051         case OPC_PRECEQ_L_PWL:
27052         case OPC_PRECEQ_L_PWR:
27053         case OPC_PRECEQ_PW_QHL:
27054         case OPC_PRECEQ_PW_QHR:
27055         case OPC_PRECEQ_PW_QHLA:
27056         case OPC_PRECEQ_PW_QHRA:
27057         case OPC_PRECEQU_QH_OBL:
27058         case OPC_PRECEQU_QH_OBR:
27059         case OPC_PRECEQU_QH_OBLA:
27060         case OPC_PRECEQU_QH_OBRA:
27061         case OPC_PRECEU_QH_OBL:
27062         case OPC_PRECEU_QH_OBR:
27063         case OPC_PRECEU_QH_OBLA:
27064         case OPC_PRECEU_QH_OBRA:
27065         case OPC_ABSQ_S_OB:
27066         case OPC_ABSQ_S_PW:
27067         case OPC_ABSQ_S_QH:
27068             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27069             break;
27070         case OPC_REPL_OB:
27071         case OPC_REPL_PW:
27072         case OPC_REPL_QH:
27073         case OPC_REPLV_OB:
27074         case OPC_REPLV_PW:
27075         case OPC_REPLV_QH:
27076             gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
27077             break;
27078         default:            /* Invalid */
27079             MIPS_INVAL("MASK ABSQ_S.QH");
27080             generate_exception_end(ctx, EXCP_RI);
27081             break;
27082         }
27083         break;
27084     case OPC_ADDU_OB_DSP:
27085         op2 = MASK_ADDU_OB(ctx->opcode);
27086         switch (op2) {
27087         case OPC_RADDU_L_OB:
27088         case OPC_SUBQ_PW:
27089         case OPC_SUBQ_S_PW:
27090         case OPC_SUBQ_QH:
27091         case OPC_SUBQ_S_QH:
27092         case OPC_SUBU_OB:
27093         case OPC_SUBU_S_OB:
27094         case OPC_SUBU_QH:
27095         case OPC_SUBU_S_QH:
27096         case OPC_SUBUH_OB:
27097         case OPC_SUBUH_R_OB:
27098         case OPC_ADDQ_PW:
27099         case OPC_ADDQ_S_PW:
27100         case OPC_ADDQ_QH:
27101         case OPC_ADDQ_S_QH:
27102         case OPC_ADDU_OB:
27103         case OPC_ADDU_S_OB:
27104         case OPC_ADDU_QH:
27105         case OPC_ADDU_S_QH:
27106         case OPC_ADDUH_OB:
27107         case OPC_ADDUH_R_OB:
27108             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27109             break;
27110         case OPC_MULEQ_S_PW_QHL:
27111         case OPC_MULEQ_S_PW_QHR:
27112         case OPC_MULEU_S_QH_OBL:
27113         case OPC_MULEU_S_QH_OBR:
27114         case OPC_MULQ_RS_QH:
27115             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
27116             break;
27117         default:            /* Invalid */
27118             MIPS_INVAL("MASK ADDU.OB");
27119             generate_exception_end(ctx, EXCP_RI);
27120             break;
27121         }
27122         break;
27123     case OPC_CMPU_EQ_OB_DSP:
27124         op2 = MASK_CMPU_EQ_OB(ctx->opcode);
27125         switch (op2) {
27126         case OPC_PRECR_SRA_QH_PW:
27127         case OPC_PRECR_SRA_R_QH_PW:
27128             /* Return value is rt. */
27129             gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
27130             break;
27131         case OPC_PRECR_OB_QH:
27132         case OPC_PRECRQ_OB_QH:
27133         case OPC_PRECRQ_PW_L:
27134         case OPC_PRECRQ_QH_PW:
27135         case OPC_PRECRQ_RS_QH_PW:
27136         case OPC_PRECRQU_S_OB_QH:
27137             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27138             break;
27139         case OPC_CMPU_EQ_OB:
27140         case OPC_CMPU_LT_OB:
27141         case OPC_CMPU_LE_OB:
27142         case OPC_CMP_EQ_QH:
27143         case OPC_CMP_LT_QH:
27144         case OPC_CMP_LE_QH:
27145         case OPC_CMP_EQ_PW:
27146         case OPC_CMP_LT_PW:
27147         case OPC_CMP_LE_PW:
27148             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
27149             break;
27150         case OPC_CMPGDU_EQ_OB:
27151         case OPC_CMPGDU_LT_OB:
27152         case OPC_CMPGDU_LE_OB:
27153         case OPC_CMPGU_EQ_OB:
27154         case OPC_CMPGU_LT_OB:
27155         case OPC_CMPGU_LE_OB:
27156         case OPC_PACKRL_PW:
27157         case OPC_PICK_OB:
27158         case OPC_PICK_PW:
27159         case OPC_PICK_QH:
27160             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
27161             break;
27162         default:            /* Invalid */
27163             MIPS_INVAL("MASK CMPU_EQ.OB");
27164             generate_exception_end(ctx, EXCP_RI);
27165             break;
27166         }
27167         break;
27168     case OPC_DAPPEND_DSP:
27169         gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
27170         break;
27171     case OPC_DEXTR_W_DSP:
27172         op2 = MASK_DEXTR_W(ctx->opcode);
27173         switch (op2) {
27174         case OPC_DEXTP:
27175         case OPC_DEXTPDP:
27176         case OPC_DEXTPDPV:
27177         case OPC_DEXTPV:
27178         case OPC_DEXTR_L:
27179         case OPC_DEXTR_R_L:
27180         case OPC_DEXTR_RS_L:
27181         case OPC_DEXTR_W:
27182         case OPC_DEXTR_R_W:
27183         case OPC_DEXTR_RS_W:
27184         case OPC_DEXTR_S_H:
27185         case OPC_DEXTRV_L:
27186         case OPC_DEXTRV_R_L:
27187         case OPC_DEXTRV_RS_L:
27188         case OPC_DEXTRV_S_H:
27189         case OPC_DEXTRV_W:
27190         case OPC_DEXTRV_R_W:
27191         case OPC_DEXTRV_RS_W:
27192             gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
27193             break;
27194         case OPC_DMTHLIP:
27195         case OPC_DSHILO:
27196         case OPC_DSHILOV:
27197             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
27198             break;
27199         default:            /* Invalid */
27200             MIPS_INVAL("MASK EXTR.W");
27201             generate_exception_end(ctx, EXCP_RI);
27202             break;
27203         }
27204         break;
27205     case OPC_DPAQ_W_QH_DSP:
27206         op2 = MASK_DPAQ_W_QH(ctx->opcode);
27207         switch (op2) {
27208         case OPC_DPAU_H_OBL:
27209         case OPC_DPAU_H_OBR:
27210         case OPC_DPSU_H_OBL:
27211         case OPC_DPSU_H_OBR:
27212         case OPC_DPA_W_QH:
27213         case OPC_DPAQ_S_W_QH:
27214         case OPC_DPS_W_QH:
27215         case OPC_DPSQ_S_W_QH:
27216         case OPC_MULSAQ_S_W_QH:
27217         case OPC_DPAQ_SA_L_PW:
27218         case OPC_DPSQ_SA_L_PW:
27219         case OPC_MULSAQ_S_L_PW:
27220             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
27221             break;
27222         case OPC_MAQ_S_W_QHLL:
27223         case OPC_MAQ_S_W_QHLR:
27224         case OPC_MAQ_S_W_QHRL:
27225         case OPC_MAQ_S_W_QHRR:
27226         case OPC_MAQ_SA_W_QHLL:
27227         case OPC_MAQ_SA_W_QHLR:
27228         case OPC_MAQ_SA_W_QHRL:
27229         case OPC_MAQ_SA_W_QHRR:
27230         case OPC_MAQ_S_L_PWL:
27231         case OPC_MAQ_S_L_PWR:
27232         case OPC_DMADD:
27233         case OPC_DMADDU:
27234         case OPC_DMSUB:
27235         case OPC_DMSUBU:
27236             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
27237             break;
27238         default:            /* Invalid */
27239             MIPS_INVAL("MASK DPAQ.W.QH");
27240             generate_exception_end(ctx, EXCP_RI);
27241             break;
27242         }
27243         break;
27244     case OPC_DINSV_DSP:
27245         op2 = MASK_INSV(ctx->opcode);
27246         switch (op2) {
27247         case OPC_DINSV:
27248         {
27249             TCGv t0, t1;
27250
27251             if (rt == 0) {
27252                 break;
27253             }
27254             check_dsp(ctx);
27255
27256             t0 = tcg_temp_new();
27257             t1 = tcg_temp_new();
27258
27259             gen_load_gpr(t0, rt);
27260             gen_load_gpr(t1, rs);
27261
27262             gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
27263
27264             tcg_temp_free(t0);
27265             tcg_temp_free(t1);
27266             break;
27267         }
27268         default:            /* Invalid */
27269             MIPS_INVAL("MASK DINSV");
27270             generate_exception_end(ctx, EXCP_RI);
27271             break;
27272         }
27273         break;
27274     case OPC_SHLL_OB_DSP:
27275         gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
27276         break;
27277 #endif
27278     default:            /* Invalid */
27279         MIPS_INVAL("special3_legacy");
27280         generate_exception_end(ctx, EXCP_RI);
27281         break;
27282     }
27283 }
27284
27285 static void decode_mmi0(CPUMIPSState *env, DisasContext *ctx)
27286 {
27287     uint32_t opc = MASK_MMI0(ctx->opcode);
27288
27289     switch (opc) {
27290     case MMI_OPC_0_PADDW:     /* TODO: MMI_OPC_0_PADDW */
27291     case MMI_OPC_0_PSUBW:     /* TODO: MMI_OPC_0_PSUBW */
27292     case MMI_OPC_0_PCGTW:     /* TODO: MMI_OPC_0_PCGTW */
27293     case MMI_OPC_0_PMAXW:     /* TODO: MMI_OPC_0_PMAXW */
27294     case MMI_OPC_0_PADDH:     /* TODO: MMI_OPC_0_PADDH */
27295     case MMI_OPC_0_PSUBH:     /* TODO: MMI_OPC_0_PSUBH */
27296     case MMI_OPC_0_PCGTH:     /* TODO: MMI_OPC_0_PCGTH */
27297     case MMI_OPC_0_PMAXH:     /* TODO: MMI_OPC_0_PMAXH */
27298     case MMI_OPC_0_PADDB:     /* TODO: MMI_OPC_0_PADDB */
27299     case MMI_OPC_0_PSUBB:     /* TODO: MMI_OPC_0_PSUBB */
27300     case MMI_OPC_0_PCGTB:     /* TODO: MMI_OPC_0_PCGTB */
27301     case MMI_OPC_0_PADDSW:    /* TODO: MMI_OPC_0_PADDSW */
27302     case MMI_OPC_0_PSUBSW:    /* TODO: MMI_OPC_0_PSUBSW */
27303     case MMI_OPC_0_PEXTLW:    /* TODO: MMI_OPC_0_PEXTLW */
27304     case MMI_OPC_0_PPACW:     /* TODO: MMI_OPC_0_PPACW */
27305     case MMI_OPC_0_PADDSH:    /* TODO: MMI_OPC_0_PADDSH */
27306     case MMI_OPC_0_PSUBSH:    /* TODO: MMI_OPC_0_PSUBSH */
27307     case MMI_OPC_0_PEXTLH:    /* TODO: MMI_OPC_0_PEXTLH */
27308     case MMI_OPC_0_PPACH:     /* TODO: MMI_OPC_0_PPACH */
27309     case MMI_OPC_0_PADDSB:    /* TODO: MMI_OPC_0_PADDSB */
27310     case MMI_OPC_0_PSUBSB:    /* TODO: MMI_OPC_0_PSUBSB */
27311     case MMI_OPC_0_PEXTLB:    /* TODO: MMI_OPC_0_PEXTLB */
27312     case MMI_OPC_0_PPACB:     /* TODO: MMI_OPC_0_PPACB */
27313     case MMI_OPC_0_PEXT5:     /* TODO: MMI_OPC_0_PEXT5 */
27314     case MMI_OPC_0_PPAC5:     /* TODO: MMI_OPC_0_PPAC5 */
27315         generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI0 */
27316         break;
27317     default:
27318         MIPS_INVAL("TX79 MMI class MMI0");
27319         generate_exception_end(ctx, EXCP_RI);
27320         break;
27321     }
27322 }
27323
27324 static void decode_mmi1(CPUMIPSState *env, DisasContext *ctx)
27325 {
27326     uint32_t opc = MASK_MMI1(ctx->opcode);
27327
27328     switch (opc) {
27329     case MMI_OPC_1_PABSW:     /* TODO: MMI_OPC_1_PABSW */
27330     case MMI_OPC_1_PCEQW:     /* TODO: MMI_OPC_1_PCEQW */
27331     case MMI_OPC_1_PMINW:     /* TODO: MMI_OPC_1_PMINW */
27332     case MMI_OPC_1_PADSBH:    /* TODO: MMI_OPC_1_PADSBH */
27333     case MMI_OPC_1_PABSH:     /* TODO: MMI_OPC_1_PABSH */
27334     case MMI_OPC_1_PCEQH:     /* TODO: MMI_OPC_1_PCEQH */
27335     case MMI_OPC_1_PMINH:     /* TODO: MMI_OPC_1_PMINH */
27336     case MMI_OPC_1_PCEQB:     /* TODO: MMI_OPC_1_PCEQB */
27337     case MMI_OPC_1_PADDUW:    /* TODO: MMI_OPC_1_PADDUW */
27338     case MMI_OPC_1_PSUBUW:    /* TODO: MMI_OPC_1_PSUBUW */
27339     case MMI_OPC_1_PEXTUW:    /* TODO: MMI_OPC_1_PEXTUW */
27340     case MMI_OPC_1_PADDUH:    /* TODO: MMI_OPC_1_PADDUH */
27341     case MMI_OPC_1_PSUBUH:    /* TODO: MMI_OPC_1_PSUBUH */
27342     case MMI_OPC_1_PEXTUH:    /* TODO: MMI_OPC_1_PEXTUH */
27343     case MMI_OPC_1_PADDUB:    /* TODO: MMI_OPC_1_PADDUB */
27344     case MMI_OPC_1_PSUBUB:    /* TODO: MMI_OPC_1_PSUBUB */
27345     case MMI_OPC_1_PEXTUB:    /* TODO: MMI_OPC_1_PEXTUB */
27346     case MMI_OPC_1_QFSRV:     /* TODO: MMI_OPC_1_QFSRV */
27347         generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI1 */
27348         break;
27349     default:
27350         MIPS_INVAL("TX79 MMI class MMI1");
27351         generate_exception_end(ctx, EXCP_RI);
27352         break;
27353     }
27354 }
27355
27356 static void decode_mmi2(CPUMIPSState *env, DisasContext *ctx)
27357 {
27358     uint32_t opc = MASK_MMI2(ctx->opcode);
27359
27360     switch (opc) {
27361     case MMI_OPC_2_PMADDW:    /* TODO: MMI_OPC_2_PMADDW */
27362     case MMI_OPC_2_PSLLVW:    /* TODO: MMI_OPC_2_PSLLVW */
27363     case MMI_OPC_2_PSRLVW:    /* TODO: MMI_OPC_2_PSRLVW */
27364     case MMI_OPC_2_PMSUBW:    /* TODO: MMI_OPC_2_PMSUBW */
27365     case MMI_OPC_2_PMFHI:     /* TODO: MMI_OPC_2_PMFHI */
27366     case MMI_OPC_2_PMFLO:     /* TODO: MMI_OPC_2_PMFLO */
27367     case MMI_OPC_2_PINTH:     /* TODO: MMI_OPC_2_PINTH */
27368     case MMI_OPC_2_PMULTW:    /* TODO: MMI_OPC_2_PMULTW */
27369     case MMI_OPC_2_PDIVW:     /* TODO: MMI_OPC_2_PDIVW */
27370     case MMI_OPC_2_PCPYLD:    /* TODO: MMI_OPC_2_PCPYLD */
27371     case MMI_OPC_2_PMADDH:    /* TODO: MMI_OPC_2_PMADDH */
27372     case MMI_OPC_2_PHMADH:    /* TODO: MMI_OPC_2_PHMADH */
27373     case MMI_OPC_2_PAND:      /* TODO: MMI_OPC_2_PAND */
27374     case MMI_OPC_2_PXOR:      /* TODO: MMI_OPC_2_PXOR */
27375     case MMI_OPC_2_PMSUBH:    /* TODO: MMI_OPC_2_PMSUBH */
27376     case MMI_OPC_2_PHMSBH:    /* TODO: MMI_OPC_2_PHMSBH */
27377     case MMI_OPC_2_PEXEH:     /* TODO: MMI_OPC_2_PEXEH */
27378     case MMI_OPC_2_PREVH:     /* TODO: MMI_OPC_2_PREVH */
27379     case MMI_OPC_2_PMULTH:    /* TODO: MMI_OPC_2_PMULTH */
27380     case MMI_OPC_2_PDIVBW:    /* TODO: MMI_OPC_2_PDIVBW */
27381     case MMI_OPC_2_PEXEW:     /* TODO: MMI_OPC_2_PEXEW */
27382     case MMI_OPC_2_PROT3W:    /* TODO: MMI_OPC_2_PROT3W */
27383         generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI2 */
27384         break;
27385     default:
27386         MIPS_INVAL("TX79 MMI class MMI2");
27387         generate_exception_end(ctx, EXCP_RI);
27388         break;
27389     }
27390 }
27391
27392 static void decode_mmi3(CPUMIPSState *env, DisasContext *ctx)
27393 {
27394     uint32_t opc = MASK_MMI3(ctx->opcode);
27395
27396     switch (opc) {
27397     case MMI_OPC_3_PMADDUW:    /* TODO: MMI_OPC_3_PMADDUW */
27398     case MMI_OPC_3_PSRAVW:     /* TODO: MMI_OPC_3_PSRAVW */
27399     case MMI_OPC_3_PMTHI:      /* TODO: MMI_OPC_3_PMTHI */
27400     case MMI_OPC_3_PMTLO:      /* TODO: MMI_OPC_3_PMTLO */
27401     case MMI_OPC_3_PINTEH:     /* TODO: MMI_OPC_3_PINTEH */
27402     case MMI_OPC_3_PMULTUW:    /* TODO: MMI_OPC_3_PMULTUW */
27403     case MMI_OPC_3_PDIVUW:     /* TODO: MMI_OPC_3_PDIVUW */
27404     case MMI_OPC_3_PCPYUD:     /* TODO: MMI_OPC_3_PCPYUD */
27405     case MMI_OPC_3_POR:        /* TODO: MMI_OPC_3_POR */
27406     case MMI_OPC_3_PNOR:       /* TODO: MMI_OPC_3_PNOR */
27407     case MMI_OPC_3_PEXCH:      /* TODO: MMI_OPC_3_PEXCH */
27408     case MMI_OPC_3_PCPYH:      /* TODO: MMI_OPC_3_PCPYH */
27409     case MMI_OPC_3_PEXCW:      /* TODO: MMI_OPC_3_PEXCW */
27410         generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI3 */
27411         break;
27412     default:
27413         MIPS_INVAL("TX79 MMI class MMI3");
27414         generate_exception_end(ctx, EXCP_RI);
27415         break;
27416     }
27417 }
27418
27419 static void decode_mmi(CPUMIPSState *env, DisasContext *ctx)
27420 {
27421     uint32_t opc = MASK_MMI(ctx->opcode);
27422     int rs = extract32(ctx->opcode, 21, 5);
27423     int rt = extract32(ctx->opcode, 16, 5);
27424     int rd = extract32(ctx->opcode, 11, 5);
27425
27426     switch (opc) {
27427     case MMI_OPC_CLASS_MMI0:
27428         decode_mmi0(env, ctx);
27429         break;
27430     case MMI_OPC_CLASS_MMI1:
27431         decode_mmi1(env, ctx);
27432         break;
27433     case MMI_OPC_CLASS_MMI2:
27434         decode_mmi2(env, ctx);
27435         break;
27436     case MMI_OPC_CLASS_MMI3:
27437         decode_mmi3(env, ctx);
27438         break;
27439     case MMI_OPC_MULT1:
27440     case MMI_OPC_MULTU1:
27441     case MMI_OPC_MADD:
27442     case MMI_OPC_MADDU:
27443     case MMI_OPC_MADD1:
27444     case MMI_OPC_MADDU1:
27445         gen_mul_txx9(ctx, opc, rd, rs, rt);
27446         break;
27447     case MMI_OPC_DIV1:
27448     case MMI_OPC_DIVU1:
27449         gen_div1_tx79(ctx, opc, rs, rt);
27450         break;
27451     case MMI_OPC_MTLO1:
27452     case MMI_OPC_MTHI1:
27453         gen_HILO1_tx79(ctx, opc, rs);
27454         break;
27455     case MMI_OPC_MFLO1:
27456     case MMI_OPC_MFHI1:
27457         gen_HILO1_tx79(ctx, opc, rd);
27458         break;
27459     case MMI_OPC_PLZCW:         /* TODO: MMI_OPC_PLZCW */
27460     case MMI_OPC_PMFHL:         /* TODO: MMI_OPC_PMFHL */
27461     case MMI_OPC_PMTHL:         /* TODO: MMI_OPC_PMTHL */
27462     case MMI_OPC_PSLLH:         /* TODO: MMI_OPC_PSLLH */
27463     case MMI_OPC_PSRLH:         /* TODO: MMI_OPC_PSRLH */
27464     case MMI_OPC_PSRAH:         /* TODO: MMI_OPC_PSRAH */
27465     case MMI_OPC_PSLLW:         /* TODO: MMI_OPC_PSLLW */
27466     case MMI_OPC_PSRLW:         /* TODO: MMI_OPC_PSRLW */
27467     case MMI_OPC_PSRAW:         /* TODO: MMI_OPC_PSRAW */
27468         generate_exception_end(ctx, EXCP_RI);    /* TODO: MMI_OPC_CLASS_MMI */
27469         break;
27470     default:
27471         MIPS_INVAL("TX79 MMI class");
27472         generate_exception_end(ctx, EXCP_RI);
27473         break;
27474     }
27475 }
27476
27477 static void gen_mmi_lq(CPUMIPSState *env, DisasContext *ctx)
27478 {
27479     generate_exception_end(ctx, EXCP_RI);    /* TODO: MMI_OPC_LQ */
27480 }
27481
27482 static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset)
27483 {
27484     generate_exception_end(ctx, EXCP_RI);    /* TODO: MMI_OPC_SQ */
27485 }
27486
27487 /*
27488  * The TX79-specific instruction Store Quadword
27489  *
27490  * +--------+-------+-------+------------------------+
27491  * | 011111 |  base |   rt  |           offset       | SQ
27492  * +--------+-------+-------+------------------------+
27493  *      6       5       5                 16
27494  *
27495  * has the same opcode as the Read Hardware Register instruction
27496  *
27497  * +--------+-------+-------+-------+-------+--------+
27498  * | 011111 | 00000 |   rt  |   rd  | 00000 | 111011 | RDHWR
27499  * +--------+-------+-------+-------+-------+--------+
27500  *      6       5       5       5       5        6
27501  *
27502  * that is required, trapped and emulated by the Linux kernel. However, all
27503  * RDHWR encodings yield address error exceptions on the TX79 since the SQ
27504  * offset is odd. Therefore all valid SQ instructions can execute normally.
27505  * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
27506  * between SQ and RDHWR, as the Linux kernel does.
27507  */
27508 static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx)
27509 {
27510     int base = extract32(ctx->opcode, 21, 5);
27511     int rt = extract32(ctx->opcode, 16, 5);
27512     int offset = extract32(ctx->opcode, 0, 16);
27513
27514 #ifdef CONFIG_USER_ONLY
27515     uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
27516     uint32_t op2 = extract32(ctx->opcode, 6, 5);
27517
27518     if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
27519         int rd = extract32(ctx->opcode, 11, 5);
27520
27521         gen_rdhwr(ctx, rt, rd, 0);
27522         return;
27523     }
27524 #endif
27525
27526     gen_mmi_sq(ctx, base, rt, offset);
27527 }
27528
27529 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
27530 {
27531     int rs, rt, rd, sa;
27532     uint32_t op1, op2;
27533     int16_t imm;
27534
27535     rs = (ctx->opcode >> 21) & 0x1f;
27536     rt = (ctx->opcode >> 16) & 0x1f;
27537     rd = (ctx->opcode >> 11) & 0x1f;
27538     sa = (ctx->opcode >> 6) & 0x1f;
27539     imm = sextract32(ctx->opcode, 7, 9);
27540
27541     op1 = MASK_SPECIAL3(ctx->opcode);
27542
27543     /*
27544      * EVA loads and stores overlap Loongson 2E instructions decoded by
27545      * decode_opc_special3_legacy(), so be careful to allow their decoding when
27546      * EVA is absent.
27547      */
27548     if (ctx->eva) {
27549         switch (op1) {
27550         case OPC_LWLE:
27551         case OPC_LWRE:
27552             check_insn_opc_removed(ctx, ISA_MIPS32R6);
27553             /* fall through */
27554         case OPC_LBUE:
27555         case OPC_LHUE:
27556         case OPC_LBE:
27557         case OPC_LHE:
27558         case OPC_LLE:
27559         case OPC_LWE:
27560             check_cp0_enabled(ctx);
27561             gen_ld(ctx, op1, rt, rs, imm);
27562             return;
27563         case OPC_SWLE:
27564         case OPC_SWRE:
27565             check_insn_opc_removed(ctx, ISA_MIPS32R6);
27566             /* fall through */
27567         case OPC_SBE:
27568         case OPC_SHE:
27569         case OPC_SWE:
27570             check_cp0_enabled(ctx);
27571             gen_st(ctx, op1, rt, rs, imm);
27572             return;
27573         case OPC_SCE:
27574             check_cp0_enabled(ctx);
27575             gen_st_cond(ctx, op1, rt, rs, imm);
27576             return;
27577         case OPC_CACHEE:
27578             check_cp0_enabled(ctx);
27579             if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
27580                 gen_cache_operation(ctx, rt, rs, imm);
27581             }
27582             /* Treat as NOP. */
27583             return;
27584         case OPC_PREFE:
27585             check_cp0_enabled(ctx);
27586             /* Treat as NOP. */
27587             return;
27588         }
27589     }
27590
27591     switch (op1) {
27592     case OPC_EXT:
27593     case OPC_INS:
27594         check_insn(ctx, ISA_MIPS32R2);
27595         gen_bitops(ctx, op1, rt, rs, sa, rd);
27596         break;
27597     case OPC_BSHFL:
27598         op2 = MASK_BSHFL(ctx->opcode);
27599         switch (op2) {
27600         case OPC_ALIGN:
27601         case OPC_ALIGN_1:
27602         case OPC_ALIGN_2:
27603         case OPC_ALIGN_3:
27604         case OPC_BITSWAP:
27605             check_insn(ctx, ISA_MIPS32R6);
27606             decode_opc_special3_r6(env, ctx);
27607             break;
27608         default:
27609             check_insn(ctx, ISA_MIPS32R2);
27610             gen_bshfl(ctx, op2, rt, rd);
27611             break;
27612         }
27613         break;
27614 #if defined(TARGET_MIPS64)
27615     case OPC_DEXTM:
27616     case OPC_DEXTU:
27617     case OPC_DEXT:
27618     case OPC_DINSM:
27619     case OPC_DINSU:
27620     case OPC_DINS:
27621         check_insn(ctx, ISA_MIPS64R2);
27622         check_mips_64(ctx);
27623         gen_bitops(ctx, op1, rt, rs, sa, rd);
27624         break;
27625     case OPC_DBSHFL:
27626         op2 = MASK_DBSHFL(ctx->opcode);
27627         switch (op2) {
27628         case OPC_DALIGN:
27629         case OPC_DALIGN_1:
27630         case OPC_DALIGN_2:
27631         case OPC_DALIGN_3:
27632         case OPC_DALIGN_4:
27633         case OPC_DALIGN_5:
27634         case OPC_DALIGN_6:
27635         case OPC_DALIGN_7:
27636         case OPC_DBITSWAP:
27637             check_insn(ctx, ISA_MIPS32R6);
27638             decode_opc_special3_r6(env, ctx);
27639             break;
27640         default:
27641             check_insn(ctx, ISA_MIPS64R2);
27642             check_mips_64(ctx);
27643             op2 = MASK_DBSHFL(ctx->opcode);
27644             gen_bshfl(ctx, op2, rt, rd);
27645             break;
27646         }
27647         break;
27648 #endif
27649     case OPC_RDHWR:
27650         gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
27651         break;
27652     case OPC_FORK:
27653         check_mt(ctx);
27654         {
27655             TCGv t0 = tcg_temp_new();
27656             TCGv t1 = tcg_temp_new();
27657
27658             gen_load_gpr(t0, rt);
27659             gen_load_gpr(t1, rs);
27660             gen_helper_fork(t0, t1);
27661             tcg_temp_free(t0);
27662             tcg_temp_free(t1);
27663         }
27664         break;
27665     case OPC_YIELD:
27666         check_mt(ctx);
27667         {
27668             TCGv t0 = tcg_temp_new();
27669
27670             gen_load_gpr(t0, rs);
27671             gen_helper_yield(t0, cpu_env, t0);
27672             gen_store_gpr(t0, rd);
27673             tcg_temp_free(t0);
27674         }
27675         break;
27676     default:
27677         if (ctx->insn_flags & ISA_MIPS32R6) {
27678             decode_opc_special3_r6(env, ctx);
27679         } else {
27680             decode_opc_special3_legacy(env, ctx);
27681         }
27682     }
27683 }
27684
27685 /* MIPS SIMD Architecture (MSA)  */
27686 static inline int check_msa_access(DisasContext *ctx)
27687 {
27688     if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
27689                  !(ctx->hflags & MIPS_HFLAG_F64))) {
27690         generate_exception_end(ctx, EXCP_RI);
27691         return 0;
27692     }
27693
27694     if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
27695         if (ctx->insn_flags & ASE_MSA) {
27696             generate_exception_end(ctx, EXCP_MSADIS);
27697             return 0;
27698         } else {
27699             generate_exception_end(ctx, EXCP_RI);
27700             return 0;
27701         }
27702     }
27703     return 1;
27704 }
27705
27706 static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
27707 {
27708     /* generates tcg ops to check if any element is 0 */
27709     /* Note this function only works with MSA_WRLEN = 128 */
27710     uint64_t eval_zero_or_big = 0;
27711     uint64_t eval_big = 0;
27712     TCGv_i64 t0 = tcg_temp_new_i64();
27713     TCGv_i64 t1 = tcg_temp_new_i64();
27714     switch (df) {
27715     case DF_BYTE:
27716         eval_zero_or_big = 0x0101010101010101ULL;
27717         eval_big = 0x8080808080808080ULL;
27718         break;
27719     case DF_HALF:
27720         eval_zero_or_big = 0x0001000100010001ULL;
27721         eval_big = 0x8000800080008000ULL;
27722         break;
27723     case DF_WORD:
27724         eval_zero_or_big = 0x0000000100000001ULL;
27725         eval_big = 0x8000000080000000ULL;
27726         break;
27727     case DF_DOUBLE:
27728         eval_zero_or_big = 0x0000000000000001ULL;
27729         eval_big = 0x8000000000000000ULL;
27730         break;
27731     }
27732     tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
27733     tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
27734     tcg_gen_andi_i64(t0, t0, eval_big);
27735     tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
27736     tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
27737     tcg_gen_andi_i64(t1, t1, eval_big);
27738     tcg_gen_or_i64(t0, t0, t1);
27739     /* if all bits are zero then all elements are not zero */
27740     /* if some bit is non-zero then some element is zero */
27741     tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
27742     tcg_gen_trunc_i64_tl(tresult, t0);
27743     tcg_temp_free_i64(t0);
27744     tcg_temp_free_i64(t1);
27745 }
27746
27747 static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
27748 {
27749     uint8_t df = (ctx->opcode >> 21) & 0x3;
27750     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
27751     int64_t s16 = (int16_t)ctx->opcode;
27752
27753     check_msa_access(ctx);
27754
27755     if (ctx->hflags & MIPS_HFLAG_BMASK) {
27756         generate_exception_end(ctx, EXCP_RI);
27757         return;
27758     }
27759     switch (op1) {
27760     case OPC_BZ_V:
27761     case OPC_BNZ_V:
27762         {
27763             TCGv_i64 t0 = tcg_temp_new_i64();
27764             tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
27765             tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
27766                     TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
27767             tcg_gen_trunc_i64_tl(bcond, t0);
27768             tcg_temp_free_i64(t0);
27769         }
27770         break;
27771     case OPC_BZ_B:
27772     case OPC_BZ_H:
27773     case OPC_BZ_W:
27774     case OPC_BZ_D:
27775         gen_check_zero_element(bcond, df, wt);
27776         break;
27777     case OPC_BNZ_B:
27778     case OPC_BNZ_H:
27779     case OPC_BNZ_W:
27780     case OPC_BNZ_D:
27781         gen_check_zero_element(bcond, df, wt);
27782         tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
27783         break;
27784     }
27785
27786     ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
27787
27788     ctx->hflags |= MIPS_HFLAG_BC;
27789     ctx->hflags |= MIPS_HFLAG_BDS32;
27790 }
27791
27792 static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
27793 {
27794 #define MASK_MSA_I8(op)    (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
27795     uint8_t i8 = (ctx->opcode >> 16) & 0xff;
27796     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27797     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27798
27799     TCGv_i32 twd = tcg_const_i32(wd);
27800     TCGv_i32 tws = tcg_const_i32(ws);
27801     TCGv_i32 ti8 = tcg_const_i32(i8);
27802
27803     switch (MASK_MSA_I8(ctx->opcode)) {
27804     case OPC_ANDI_B:
27805         gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
27806         break;
27807     case OPC_ORI_B:
27808         gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
27809         break;
27810     case OPC_NORI_B:
27811         gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
27812         break;
27813     case OPC_XORI_B:
27814         gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
27815         break;
27816     case OPC_BMNZI_B:
27817         gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
27818         break;
27819     case OPC_BMZI_B:
27820         gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
27821         break;
27822     case OPC_BSELI_B:
27823         gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
27824         break;
27825     case OPC_SHF_B:
27826     case OPC_SHF_H:
27827     case OPC_SHF_W:
27828         {
27829             uint8_t df = (ctx->opcode >> 24) & 0x3;
27830             if (df == DF_DOUBLE) {
27831                 generate_exception_end(ctx, EXCP_RI);
27832             } else {
27833                 TCGv_i32 tdf = tcg_const_i32(df);
27834                 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
27835                 tcg_temp_free_i32(tdf);
27836             }
27837         }
27838         break;
27839     default:
27840         MIPS_INVAL("MSA instruction");
27841         generate_exception_end(ctx, EXCP_RI);
27842         break;
27843     }
27844
27845     tcg_temp_free_i32(twd);
27846     tcg_temp_free_i32(tws);
27847     tcg_temp_free_i32(ti8);
27848 }
27849
27850 static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
27851 {
27852 #define MASK_MSA_I5(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
27853     uint8_t df = (ctx->opcode >> 21) & 0x3;
27854     int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
27855     uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
27856     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27857     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27858
27859     TCGv_i32 tdf = tcg_const_i32(df);
27860     TCGv_i32 twd = tcg_const_i32(wd);
27861     TCGv_i32 tws = tcg_const_i32(ws);
27862     TCGv_i32 timm = tcg_temp_new_i32();
27863     tcg_gen_movi_i32(timm, u5);
27864
27865     switch (MASK_MSA_I5(ctx->opcode)) {
27866     case OPC_ADDVI_df:
27867         gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
27868         break;
27869     case OPC_SUBVI_df:
27870         gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
27871         break;
27872     case OPC_MAXI_S_df:
27873         tcg_gen_movi_i32(timm, s5);
27874         gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
27875         break;
27876     case OPC_MAXI_U_df:
27877         gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
27878         break;
27879     case OPC_MINI_S_df:
27880         tcg_gen_movi_i32(timm, s5);
27881         gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
27882         break;
27883     case OPC_MINI_U_df:
27884         gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
27885         break;
27886     case OPC_CEQI_df:
27887         tcg_gen_movi_i32(timm, s5);
27888         gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
27889         break;
27890     case OPC_CLTI_S_df:
27891         tcg_gen_movi_i32(timm, s5);
27892         gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
27893         break;
27894     case OPC_CLTI_U_df:
27895         gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
27896         break;
27897     case OPC_CLEI_S_df:
27898         tcg_gen_movi_i32(timm, s5);
27899         gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
27900         break;
27901     case OPC_CLEI_U_df:
27902         gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
27903         break;
27904     case OPC_LDI_df:
27905         {
27906             int32_t s10 = sextract32(ctx->opcode, 11, 10);
27907             tcg_gen_movi_i32(timm, s10);
27908             gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
27909         }
27910         break;
27911     default:
27912         MIPS_INVAL("MSA instruction");
27913         generate_exception_end(ctx, EXCP_RI);
27914         break;
27915     }
27916
27917     tcg_temp_free_i32(tdf);
27918     tcg_temp_free_i32(twd);
27919     tcg_temp_free_i32(tws);
27920     tcg_temp_free_i32(timm);
27921 }
27922
27923 static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
27924 {
27925 #define MASK_MSA_BIT(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
27926     uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
27927     uint32_t df = 0, m = 0;
27928     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27929     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27930
27931     TCGv_i32 tdf;
27932     TCGv_i32 tm;
27933     TCGv_i32 twd;
27934     TCGv_i32 tws;
27935
27936     if ((dfm & 0x40) == 0x00) {
27937         m = dfm & 0x3f;
27938         df = DF_DOUBLE;
27939     } else if ((dfm & 0x60) == 0x40) {
27940         m = dfm & 0x1f;
27941         df = DF_WORD;
27942     } else if ((dfm & 0x70) == 0x60) {
27943         m = dfm & 0x0f;
27944         df = DF_HALF;
27945     } else if ((dfm & 0x78) == 0x70) {
27946         m = dfm & 0x7;
27947         df = DF_BYTE;
27948     } else {
27949         generate_exception_end(ctx, EXCP_RI);
27950         return;
27951     }
27952
27953     tdf = tcg_const_i32(df);
27954     tm  = tcg_const_i32(m);
27955     twd = tcg_const_i32(wd);
27956     tws = tcg_const_i32(ws);
27957
27958     switch (MASK_MSA_BIT(ctx->opcode)) {
27959     case OPC_SLLI_df:
27960         gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
27961         break;
27962     case OPC_SRAI_df:
27963         gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
27964         break;
27965     case OPC_SRLI_df:
27966         gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
27967         break;
27968     case OPC_BCLRI_df:
27969         gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
27970         break;
27971     case OPC_BSETI_df:
27972         gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
27973         break;
27974     case OPC_BNEGI_df:
27975         gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
27976         break;
27977     case OPC_BINSLI_df:
27978         gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
27979         break;
27980     case OPC_BINSRI_df:
27981         gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
27982         break;
27983     case OPC_SAT_S_df:
27984         gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
27985         break;
27986     case OPC_SAT_U_df:
27987         gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
27988         break;
27989     case OPC_SRARI_df:
27990         gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
27991         break;
27992     case OPC_SRLRI_df:
27993         gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
27994         break;
27995     default:
27996         MIPS_INVAL("MSA instruction");
27997         generate_exception_end(ctx, EXCP_RI);
27998         break;
27999     }
28000
28001     tcg_temp_free_i32(tdf);
28002     tcg_temp_free_i32(tm);
28003     tcg_temp_free_i32(twd);
28004     tcg_temp_free_i32(tws);
28005 }
28006
28007 static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
28008 {
28009 #define MASK_MSA_3R(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28010     uint8_t df = (ctx->opcode >> 21) & 0x3;
28011     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28012     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28013     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28014
28015     TCGv_i32 tdf = tcg_const_i32(df);
28016     TCGv_i32 twd = tcg_const_i32(wd);
28017     TCGv_i32 tws = tcg_const_i32(ws);
28018     TCGv_i32 twt = tcg_const_i32(wt);
28019
28020     switch (MASK_MSA_3R(ctx->opcode)) {
28021     case OPC_SLL_df:
28022         gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
28023         break;
28024     case OPC_ADDV_df:
28025         gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
28026         break;
28027     case OPC_CEQ_df:
28028         gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
28029         break;
28030     case OPC_ADD_A_df:
28031         gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
28032         break;
28033     case OPC_SUBS_S_df:
28034         gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
28035         break;
28036     case OPC_MULV_df:
28037         gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
28038         break;
28039     case OPC_SLD_df:
28040         gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
28041         break;
28042     case OPC_VSHF_df:
28043         gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
28044         break;
28045     case OPC_SRA_df:
28046         gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
28047         break;
28048     case OPC_SUBV_df:
28049         gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
28050         break;
28051     case OPC_ADDS_A_df:
28052         gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
28053         break;
28054     case OPC_SUBS_U_df:
28055         gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
28056         break;
28057     case OPC_MADDV_df:
28058         gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
28059         break;
28060     case OPC_SPLAT_df:
28061         gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
28062         break;
28063     case OPC_SRAR_df:
28064         gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
28065         break;
28066     case OPC_SRL_df:
28067         gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
28068         break;
28069     case OPC_MAX_S_df:
28070         gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
28071         break;
28072     case OPC_CLT_S_df:
28073         gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
28074         break;
28075     case OPC_ADDS_S_df:
28076         gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
28077         break;
28078     case OPC_SUBSUS_U_df:
28079         gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
28080         break;
28081     case OPC_MSUBV_df:
28082         gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
28083         break;
28084     case OPC_PCKEV_df:
28085         gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
28086         break;
28087     case OPC_SRLR_df:
28088         gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
28089         break;
28090     case OPC_BCLR_df:
28091         gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
28092         break;
28093     case OPC_MAX_U_df:
28094         gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
28095         break;
28096     case OPC_CLT_U_df:
28097         gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
28098         break;
28099     case OPC_ADDS_U_df:
28100         gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
28101         break;
28102     case OPC_SUBSUU_S_df:
28103         gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
28104         break;
28105     case OPC_PCKOD_df:
28106         gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
28107         break;
28108     case OPC_BSET_df:
28109         gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
28110         break;
28111     case OPC_MIN_S_df:
28112         gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
28113         break;
28114     case OPC_CLE_S_df:
28115         gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
28116         break;
28117     case OPC_AVE_S_df:
28118         gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
28119         break;
28120     case OPC_ASUB_S_df:
28121         gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
28122         break;
28123     case OPC_DIV_S_df:
28124         gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
28125         break;
28126     case OPC_ILVL_df:
28127         gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
28128         break;
28129     case OPC_BNEG_df:
28130         gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
28131         break;
28132     case OPC_MIN_U_df:
28133         gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
28134         break;
28135     case OPC_CLE_U_df:
28136         gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
28137         break;
28138     case OPC_AVE_U_df:
28139         gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
28140         break;
28141     case OPC_ASUB_U_df:
28142         gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
28143         break;
28144     case OPC_DIV_U_df:
28145         gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
28146         break;
28147     case OPC_ILVR_df:
28148         gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
28149         break;
28150     case OPC_BINSL_df:
28151         gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
28152         break;
28153     case OPC_MAX_A_df:
28154         gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
28155         break;
28156     case OPC_AVER_S_df:
28157         gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
28158         break;
28159     case OPC_MOD_S_df:
28160         gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
28161         break;
28162     case OPC_ILVEV_df:
28163         gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
28164         break;
28165     case OPC_BINSR_df:
28166         gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
28167         break;
28168     case OPC_MIN_A_df:
28169         gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
28170         break;
28171     case OPC_AVER_U_df:
28172         gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
28173         break;
28174     case OPC_MOD_U_df:
28175         gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
28176         break;
28177     case OPC_ILVOD_df:
28178         gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
28179         break;
28180
28181     case OPC_DOTP_S_df:
28182     case OPC_DOTP_U_df:
28183     case OPC_DPADD_S_df:
28184     case OPC_DPADD_U_df:
28185     case OPC_DPSUB_S_df:
28186     case OPC_HADD_S_df:
28187     case OPC_DPSUB_U_df:
28188     case OPC_HADD_U_df:
28189     case OPC_HSUB_S_df:
28190     case OPC_HSUB_U_df:
28191         if (df == DF_BYTE) {
28192             generate_exception_end(ctx, EXCP_RI);
28193             break;
28194         }
28195         switch (MASK_MSA_3R(ctx->opcode)) {
28196         case OPC_DOTP_S_df:
28197             gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
28198             break;
28199         case OPC_DOTP_U_df:
28200             gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
28201             break;
28202         case OPC_DPADD_S_df:
28203             gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
28204             break;
28205         case OPC_DPADD_U_df:
28206             gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
28207             break;
28208         case OPC_DPSUB_S_df:
28209             gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
28210             break;
28211         case OPC_HADD_S_df:
28212             gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
28213             break;
28214         case OPC_DPSUB_U_df:
28215             gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
28216             break;
28217         case OPC_HADD_U_df:
28218             gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
28219             break;
28220         case OPC_HSUB_S_df:
28221             gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
28222             break;
28223         case OPC_HSUB_U_df:
28224             gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
28225             break;
28226         }
28227         break;
28228     default:
28229         MIPS_INVAL("MSA instruction");
28230         generate_exception_end(ctx, EXCP_RI);
28231         break;
28232     }
28233     tcg_temp_free_i32(twd);
28234     tcg_temp_free_i32(tws);
28235     tcg_temp_free_i32(twt);
28236     tcg_temp_free_i32(tdf);
28237 }
28238
28239 static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
28240 {
28241 #define MASK_MSA_ELM_DF3E(op)   (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
28242     uint8_t source = (ctx->opcode >> 11) & 0x1f;
28243     uint8_t dest = (ctx->opcode >> 6) & 0x1f;
28244     TCGv telm = tcg_temp_new();
28245     TCGv_i32 tsr = tcg_const_i32(source);
28246     TCGv_i32 tdt = tcg_const_i32(dest);
28247
28248     switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
28249     case OPC_CTCMSA:
28250         gen_load_gpr(telm, source);
28251         gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
28252         break;
28253     case OPC_CFCMSA:
28254         gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
28255         gen_store_gpr(telm, dest);
28256         break;
28257     case OPC_MOVE_V:
28258         gen_helper_msa_move_v(cpu_env, tdt, tsr);
28259         break;
28260     default:
28261         MIPS_INVAL("MSA instruction");
28262         generate_exception_end(ctx, EXCP_RI);
28263         break;
28264     }
28265
28266     tcg_temp_free(telm);
28267     tcg_temp_free_i32(tdt);
28268     tcg_temp_free_i32(tsr);
28269 }
28270
28271 static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
28272         uint32_t n)
28273 {
28274 #define MASK_MSA_ELM(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
28275     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28276     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28277
28278     TCGv_i32 tws = tcg_const_i32(ws);
28279     TCGv_i32 twd = tcg_const_i32(wd);
28280     TCGv_i32 tn  = tcg_const_i32(n);
28281     TCGv_i32 tdf = tcg_const_i32(df);
28282
28283     switch (MASK_MSA_ELM(ctx->opcode)) {
28284     case OPC_SLDI_df:
28285         gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
28286         break;
28287     case OPC_SPLATI_df:
28288         gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
28289         break;
28290     case OPC_INSVE_df:
28291         gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
28292         break;
28293     case OPC_COPY_S_df:
28294     case OPC_COPY_U_df:
28295     case OPC_INSERT_df:
28296 #if !defined(TARGET_MIPS64)
28297         /* Double format valid only for MIPS64 */
28298         if (df == DF_DOUBLE) {
28299             generate_exception_end(ctx, EXCP_RI);
28300             break;
28301         }
28302 #endif
28303         switch (MASK_MSA_ELM(ctx->opcode)) {
28304         case OPC_COPY_S_df:
28305             if (likely(wd != 0)) {
28306                 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
28307             }
28308             break;
28309         case OPC_COPY_U_df:
28310             if (likely(wd != 0)) {
28311                 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
28312             }
28313             break;
28314         case OPC_INSERT_df:
28315             gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
28316             break;
28317         }
28318         break;
28319     default:
28320         MIPS_INVAL("MSA instruction");
28321         generate_exception_end(ctx, EXCP_RI);
28322     }
28323     tcg_temp_free_i32(twd);
28324     tcg_temp_free_i32(tws);
28325     tcg_temp_free_i32(tn);
28326     tcg_temp_free_i32(tdf);
28327 }
28328
28329 static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
28330 {
28331     uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
28332     uint32_t df = 0, n = 0;
28333
28334     if ((dfn & 0x30) == 0x00) {
28335         n = dfn & 0x0f;
28336         df = DF_BYTE;
28337     } else if ((dfn & 0x38) == 0x20) {
28338         n = dfn & 0x07;
28339         df = DF_HALF;
28340     } else if ((dfn & 0x3c) == 0x30) {
28341         n = dfn & 0x03;
28342         df = DF_WORD;
28343     } else if ((dfn & 0x3e) == 0x38) {
28344         n = dfn & 0x01;
28345         df = DF_DOUBLE;
28346     } else if (dfn == 0x3E) {
28347         /* CTCMSA, CFCMSA, MOVE.V */
28348         gen_msa_elm_3e(env, ctx);
28349         return;
28350     } else {
28351         generate_exception_end(ctx, EXCP_RI);
28352         return;
28353     }
28354
28355     gen_msa_elm_df(env, ctx, df, n);
28356 }
28357
28358 static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
28359 {
28360 #define MASK_MSA_3RF(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
28361     uint8_t df = (ctx->opcode >> 21) & 0x1;
28362     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28363     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28364     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28365
28366     TCGv_i32 twd = tcg_const_i32(wd);
28367     TCGv_i32 tws = tcg_const_i32(ws);
28368     TCGv_i32 twt = tcg_const_i32(wt);
28369     TCGv_i32 tdf = tcg_temp_new_i32();
28370
28371     /* adjust df value for floating-point instruction */
28372     tcg_gen_movi_i32(tdf, df + 2);
28373
28374     switch (MASK_MSA_3RF(ctx->opcode)) {
28375     case OPC_FCAF_df:
28376         gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
28377         break;
28378     case OPC_FADD_df:
28379         gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
28380         break;
28381     case OPC_FCUN_df:
28382         gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
28383         break;
28384     case OPC_FSUB_df:
28385         gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
28386         break;
28387     case OPC_FCOR_df:
28388         gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
28389         break;
28390     case OPC_FCEQ_df:
28391         gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
28392         break;
28393     case OPC_FMUL_df:
28394         gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
28395         break;
28396     case OPC_FCUNE_df:
28397         gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
28398         break;
28399     case OPC_FCUEQ_df:
28400         gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
28401         break;
28402     case OPC_FDIV_df:
28403         gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
28404         break;
28405     case OPC_FCNE_df:
28406         gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
28407         break;
28408     case OPC_FCLT_df:
28409         gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
28410         break;
28411     case OPC_FMADD_df:
28412         gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
28413         break;
28414     case OPC_MUL_Q_df:
28415         tcg_gen_movi_i32(tdf, df + 1);
28416         gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
28417         break;
28418     case OPC_FCULT_df:
28419         gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
28420         break;
28421     case OPC_FMSUB_df:
28422         gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
28423         break;
28424     case OPC_MADD_Q_df:
28425         tcg_gen_movi_i32(tdf, df + 1);
28426         gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
28427         break;
28428     case OPC_FCLE_df:
28429         gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
28430         break;
28431     case OPC_MSUB_Q_df:
28432         tcg_gen_movi_i32(tdf, df + 1);
28433         gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
28434         break;
28435     case OPC_FCULE_df:
28436         gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
28437         break;
28438     case OPC_FEXP2_df:
28439         gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
28440         break;
28441     case OPC_FSAF_df:
28442         gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
28443         break;
28444     case OPC_FEXDO_df:
28445         gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
28446         break;
28447     case OPC_FSUN_df:
28448         gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
28449         break;
28450     case OPC_FSOR_df:
28451         gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
28452         break;
28453     case OPC_FSEQ_df:
28454         gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
28455         break;
28456     case OPC_FTQ_df:
28457         gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
28458         break;
28459     case OPC_FSUNE_df:
28460         gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
28461         break;
28462     case OPC_FSUEQ_df:
28463         gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
28464         break;
28465     case OPC_FSNE_df:
28466         gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
28467         break;
28468     case OPC_FSLT_df:
28469         gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
28470         break;
28471     case OPC_FMIN_df:
28472         gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
28473         break;
28474     case OPC_MULR_Q_df:
28475         tcg_gen_movi_i32(tdf, df + 1);
28476         gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
28477         break;
28478     case OPC_FSULT_df:
28479         gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
28480         break;
28481     case OPC_FMIN_A_df:
28482         gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
28483         break;
28484     case OPC_MADDR_Q_df:
28485         tcg_gen_movi_i32(tdf, df + 1);
28486         gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
28487         break;
28488     case OPC_FSLE_df:
28489         gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
28490         break;
28491     case OPC_FMAX_df:
28492         gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
28493         break;
28494     case OPC_MSUBR_Q_df:
28495         tcg_gen_movi_i32(tdf, df + 1);
28496         gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
28497         break;
28498     case OPC_FSULE_df:
28499         gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
28500         break;
28501     case OPC_FMAX_A_df:
28502         gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
28503         break;
28504     default:
28505         MIPS_INVAL("MSA instruction");
28506         generate_exception_end(ctx, EXCP_RI);
28507         break;
28508     }
28509
28510     tcg_temp_free_i32(twd);
28511     tcg_temp_free_i32(tws);
28512     tcg_temp_free_i32(twt);
28513     tcg_temp_free_i32(tdf);
28514 }
28515
28516 static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
28517 {
28518 #define MASK_MSA_2R(op)     (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
28519                             (op & (0x7 << 18)))
28520     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28521     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28522     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28523     uint8_t df = (ctx->opcode >> 16) & 0x3;
28524     TCGv_i32 twd = tcg_const_i32(wd);
28525     TCGv_i32 tws = tcg_const_i32(ws);
28526     TCGv_i32 twt = tcg_const_i32(wt);
28527     TCGv_i32 tdf = tcg_const_i32(df);
28528
28529     switch (MASK_MSA_2R(ctx->opcode)) {
28530     case OPC_FILL_df:
28531 #if !defined(TARGET_MIPS64)
28532         /* Double format valid only for MIPS64 */
28533         if (df == DF_DOUBLE) {
28534             generate_exception_end(ctx, EXCP_RI);
28535             break;
28536         }
28537 #endif
28538         gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
28539         break;
28540     case OPC_PCNT_df:
28541         gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
28542         break;
28543     case OPC_NLOC_df:
28544         gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
28545         break;
28546     case OPC_NLZC_df:
28547         gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
28548         break;
28549     default:
28550         MIPS_INVAL("MSA instruction");
28551         generate_exception_end(ctx, EXCP_RI);
28552         break;
28553     }
28554
28555     tcg_temp_free_i32(twd);
28556     tcg_temp_free_i32(tws);
28557     tcg_temp_free_i32(twt);
28558     tcg_temp_free_i32(tdf);
28559 }
28560
28561 static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
28562 {
28563 #define MASK_MSA_2RF(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
28564                             (op & (0xf << 17)))
28565     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28566     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28567     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28568     uint8_t df = (ctx->opcode >> 16) & 0x1;
28569     TCGv_i32 twd = tcg_const_i32(wd);
28570     TCGv_i32 tws = tcg_const_i32(ws);
28571     TCGv_i32 twt = tcg_const_i32(wt);
28572     /* adjust df value for floating-point instruction */
28573     TCGv_i32 tdf = tcg_const_i32(df + 2);
28574
28575     switch (MASK_MSA_2RF(ctx->opcode)) {
28576     case OPC_FCLASS_df:
28577         gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
28578         break;
28579     case OPC_FTRUNC_S_df:
28580         gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
28581         break;
28582     case OPC_FTRUNC_U_df:
28583         gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
28584         break;
28585     case OPC_FSQRT_df:
28586         gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
28587         break;
28588     case OPC_FRSQRT_df:
28589         gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
28590         break;
28591     case OPC_FRCP_df:
28592         gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
28593         break;
28594     case OPC_FRINT_df:
28595         gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
28596         break;
28597     case OPC_FLOG2_df:
28598         gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
28599         break;
28600     case OPC_FEXUPL_df:
28601         gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
28602         break;
28603     case OPC_FEXUPR_df:
28604         gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
28605         break;
28606     case OPC_FFQL_df:
28607         gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
28608         break;
28609     case OPC_FFQR_df:
28610         gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
28611         break;
28612     case OPC_FTINT_S_df:
28613         gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
28614         break;
28615     case OPC_FTINT_U_df:
28616         gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
28617         break;
28618     case OPC_FFINT_S_df:
28619         gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
28620         break;
28621     case OPC_FFINT_U_df:
28622         gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
28623         break;
28624     }
28625
28626     tcg_temp_free_i32(twd);
28627     tcg_temp_free_i32(tws);
28628     tcg_temp_free_i32(twt);
28629     tcg_temp_free_i32(tdf);
28630 }
28631
28632 static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
28633 {
28634 #define MASK_MSA_VEC(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
28635     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28636     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28637     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28638     TCGv_i32 twd = tcg_const_i32(wd);
28639     TCGv_i32 tws = tcg_const_i32(ws);
28640     TCGv_i32 twt = tcg_const_i32(wt);
28641
28642     switch (MASK_MSA_VEC(ctx->opcode)) {
28643     case OPC_AND_V:
28644         gen_helper_msa_and_v(cpu_env, twd, tws, twt);
28645         break;
28646     case OPC_OR_V:
28647         gen_helper_msa_or_v(cpu_env, twd, tws, twt);
28648         break;
28649     case OPC_NOR_V:
28650         gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
28651         break;
28652     case OPC_XOR_V:
28653         gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
28654         break;
28655     case OPC_BMNZ_V:
28656         gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
28657         break;
28658     case OPC_BMZ_V:
28659         gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
28660         break;
28661     case OPC_BSEL_V:
28662         gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
28663         break;
28664     default:
28665         MIPS_INVAL("MSA instruction");
28666         generate_exception_end(ctx, EXCP_RI);
28667         break;
28668     }
28669
28670     tcg_temp_free_i32(twd);
28671     tcg_temp_free_i32(tws);
28672     tcg_temp_free_i32(twt);
28673 }
28674
28675 static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
28676 {
28677     switch (MASK_MSA_VEC(ctx->opcode)) {
28678     case OPC_AND_V:
28679     case OPC_OR_V:
28680     case OPC_NOR_V:
28681     case OPC_XOR_V:
28682     case OPC_BMNZ_V:
28683     case OPC_BMZ_V:
28684     case OPC_BSEL_V:
28685         gen_msa_vec_v(env, ctx);
28686         break;
28687     case OPC_MSA_2R:
28688         gen_msa_2r(env, ctx);
28689         break;
28690     case OPC_MSA_2RF:
28691         gen_msa_2rf(env, ctx);
28692         break;
28693     default:
28694         MIPS_INVAL("MSA instruction");
28695         generate_exception_end(ctx, EXCP_RI);
28696         break;
28697     }
28698 }
28699
28700 static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
28701 {
28702     uint32_t opcode = ctx->opcode;
28703     check_insn(ctx, ASE_MSA);
28704     check_msa_access(ctx);
28705
28706     switch (MASK_MSA_MINOR(opcode)) {
28707     case OPC_MSA_I8_00:
28708     case OPC_MSA_I8_01:
28709     case OPC_MSA_I8_02:
28710         gen_msa_i8(env, ctx);
28711         break;
28712     case OPC_MSA_I5_06:
28713     case OPC_MSA_I5_07:
28714         gen_msa_i5(env, ctx);
28715         break;
28716     case OPC_MSA_BIT_09:
28717     case OPC_MSA_BIT_0A:
28718         gen_msa_bit(env, ctx);
28719         break;
28720     case OPC_MSA_3R_0D:
28721     case OPC_MSA_3R_0E:
28722     case OPC_MSA_3R_0F:
28723     case OPC_MSA_3R_10:
28724     case OPC_MSA_3R_11:
28725     case OPC_MSA_3R_12:
28726     case OPC_MSA_3R_13:
28727     case OPC_MSA_3R_14:
28728     case OPC_MSA_3R_15:
28729         gen_msa_3r(env, ctx);
28730         break;
28731     case OPC_MSA_ELM:
28732         gen_msa_elm(env, ctx);
28733         break;
28734     case OPC_MSA_3RF_1A:
28735     case OPC_MSA_3RF_1B:
28736     case OPC_MSA_3RF_1C:
28737         gen_msa_3rf(env, ctx);
28738         break;
28739     case OPC_MSA_VEC:
28740         gen_msa_vec(env, ctx);
28741         break;
28742     case OPC_LD_B:
28743     case OPC_LD_H:
28744     case OPC_LD_W:
28745     case OPC_LD_D:
28746     case OPC_ST_B:
28747     case OPC_ST_H:
28748     case OPC_ST_W:
28749     case OPC_ST_D:
28750         {
28751             int32_t s10 = sextract32(ctx->opcode, 16, 10);
28752             uint8_t rs = (ctx->opcode >> 11) & 0x1f;
28753             uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28754             uint8_t df = (ctx->opcode >> 0) & 0x3;
28755
28756             TCGv_i32 twd = tcg_const_i32(wd);
28757             TCGv taddr = tcg_temp_new();
28758             gen_base_offset_addr(ctx, taddr, rs, s10 << df);
28759
28760             switch (MASK_MSA_MINOR(opcode)) {
28761             case OPC_LD_B:
28762                 gen_helper_msa_ld_b(cpu_env, twd, taddr);
28763                 break;
28764             case OPC_LD_H:
28765                 gen_helper_msa_ld_h(cpu_env, twd, taddr);
28766                 break;
28767             case OPC_LD_W:
28768                 gen_helper_msa_ld_w(cpu_env, twd, taddr);
28769                 break;
28770             case OPC_LD_D:
28771                 gen_helper_msa_ld_d(cpu_env, twd, taddr);
28772                 break;
28773             case OPC_ST_B:
28774                 gen_helper_msa_st_b(cpu_env, twd, taddr);
28775                 break;
28776             case OPC_ST_H:
28777                 gen_helper_msa_st_h(cpu_env, twd, taddr);
28778                 break;
28779             case OPC_ST_W:
28780                 gen_helper_msa_st_w(cpu_env, twd, taddr);
28781                 break;
28782             case OPC_ST_D:
28783                 gen_helper_msa_st_d(cpu_env, twd, taddr);
28784                 break;
28785             }
28786
28787             tcg_temp_free_i32(twd);
28788             tcg_temp_free(taddr);
28789         }
28790         break;
28791     default:
28792         MIPS_INVAL("MSA instruction");
28793         generate_exception_end(ctx, EXCP_RI);
28794         break;
28795     }
28796
28797 }
28798
28799 static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
28800 {
28801     int32_t offset;
28802     int rs, rt, rd, sa;
28803     uint32_t op, op1;
28804     int16_t imm;
28805
28806     /* make sure instructions are on a word boundary */
28807     if (ctx->base.pc_next & 0x3) {
28808         env->CP0_BadVAddr = ctx->base.pc_next;
28809         generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
28810         return;
28811     }
28812
28813     /* Handle blikely not taken case */
28814     if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
28815         TCGLabel *l1 = gen_new_label();
28816
28817         tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
28818         tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
28819         gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
28820         gen_set_label(l1);
28821     }
28822
28823     op = MASK_OP_MAJOR(ctx->opcode);
28824     rs = (ctx->opcode >> 21) & 0x1f;
28825     rt = (ctx->opcode >> 16) & 0x1f;
28826     rd = (ctx->opcode >> 11) & 0x1f;
28827     sa = (ctx->opcode >> 6) & 0x1f;
28828     imm = (int16_t)ctx->opcode;
28829     switch (op) {
28830     case OPC_SPECIAL:
28831         decode_opc_special(env, ctx);
28832         break;
28833     case OPC_SPECIAL2:
28834         if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
28835             decode_mmi(env, ctx);
28836 #if !defined(TARGET_MIPS64)
28837         } else if (ctx->insn_flags & ASE_MXU) {
28838             decode_opc_mxu(env, ctx);
28839 #endif
28840         } else {
28841             decode_opc_special2_legacy(env, ctx);
28842         }
28843         break;
28844     case OPC_SPECIAL3:
28845         if (ctx->insn_flags & INSN_R5900) {
28846             decode_mmi_sq(env, ctx);    /* MMI_OPC_SQ */
28847         } else {
28848             decode_opc_special3(env, ctx);
28849         }
28850         break;
28851     case OPC_REGIMM:
28852         op1 = MASK_REGIMM(ctx->opcode);
28853         switch (op1) {
28854         case OPC_BLTZL: /* REGIMM branches */
28855         case OPC_BGEZL:
28856         case OPC_BLTZALL:
28857         case OPC_BGEZALL:
28858             check_insn(ctx, ISA_MIPS2);
28859             check_insn_opc_removed(ctx, ISA_MIPS32R6);
28860             /* Fallthrough */
28861         case OPC_BLTZ:
28862         case OPC_BGEZ:
28863             gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
28864             break;
28865         case OPC_BLTZAL:
28866         case OPC_BGEZAL:
28867             if (ctx->insn_flags & ISA_MIPS32R6) {
28868                 if (rs == 0) {
28869                     /* OPC_NAL, OPC_BAL */
28870                     gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
28871                 } else {
28872                     generate_exception_end(ctx, EXCP_RI);
28873                 }
28874             } else {
28875                 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
28876             }
28877             break;
28878         case OPC_TGEI: /* REGIMM traps */
28879         case OPC_TGEIU:
28880         case OPC_TLTI:
28881         case OPC_TLTIU:
28882         case OPC_TEQI:
28883
28884         case OPC_TNEI:
28885             check_insn(ctx, ISA_MIPS2);
28886             check_insn_opc_removed(ctx, ISA_MIPS32R6);
28887             gen_trap(ctx, op1, rs, -1, imm);
28888             break;
28889         case OPC_SIGRIE:
28890             check_insn(ctx, ISA_MIPS32R6);
28891             generate_exception_end(ctx, EXCP_RI);
28892             break;
28893         case OPC_SYNCI:
28894             check_insn(ctx, ISA_MIPS32R2);
28895             /* Break the TB to be able to sync copied instructions
28896                immediately */
28897             ctx->base.is_jmp = DISAS_STOP;
28898             break;
28899         case OPC_BPOSGE32:    /* MIPS DSP branch */
28900 #if defined(TARGET_MIPS64)
28901         case OPC_BPOSGE64:
28902 #endif
28903             check_dsp(ctx);
28904             gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
28905             break;
28906 #if defined(TARGET_MIPS64)
28907         case OPC_DAHI:
28908             check_insn(ctx, ISA_MIPS32R6);
28909             check_mips_64(ctx);
28910             if (rs != 0) {
28911                 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
28912             }
28913             break;
28914         case OPC_DATI:
28915             check_insn(ctx, ISA_MIPS32R6);
28916             check_mips_64(ctx);
28917             if (rs != 0) {
28918                 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
28919             }
28920             break;
28921 #endif
28922         default:            /* Invalid */
28923             MIPS_INVAL("regimm");
28924             generate_exception_end(ctx, EXCP_RI);
28925             break;
28926         }
28927         break;
28928     case OPC_CP0:
28929         check_cp0_enabled(ctx);
28930         op1 = MASK_CP0(ctx->opcode);
28931         switch (op1) {
28932         case OPC_MFC0:
28933         case OPC_MTC0:
28934         case OPC_MFTR:
28935         case OPC_MTTR:
28936         case OPC_MFHC0:
28937         case OPC_MTHC0:
28938 #if defined(TARGET_MIPS64)
28939         case OPC_DMFC0:
28940         case OPC_DMTC0:
28941 #endif
28942 #ifndef CONFIG_USER_ONLY
28943             gen_cp0(env, ctx, op1, rt, rd);
28944 #endif /* !CONFIG_USER_ONLY */
28945             break;
28946         case OPC_C0:
28947         case OPC_C0_1:
28948         case OPC_C0_2:
28949         case OPC_C0_3:
28950         case OPC_C0_4:
28951         case OPC_C0_5:
28952         case OPC_C0_6:
28953         case OPC_C0_7:
28954         case OPC_C0_8:
28955         case OPC_C0_9:
28956         case OPC_C0_A:
28957         case OPC_C0_B:
28958         case OPC_C0_C:
28959         case OPC_C0_D:
28960         case OPC_C0_E:
28961         case OPC_C0_F:
28962 #ifndef CONFIG_USER_ONLY
28963             gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
28964 #endif /* !CONFIG_USER_ONLY */
28965             break;
28966         case OPC_MFMC0:
28967 #ifndef CONFIG_USER_ONLY
28968             {
28969                 uint32_t op2;
28970                 TCGv t0 = tcg_temp_new();
28971
28972                 op2 = MASK_MFMC0(ctx->opcode);
28973                 switch (op2) {
28974                 case OPC_DMT:
28975                     check_cp0_mt(ctx);
28976                     gen_helper_dmt(t0);
28977                     gen_store_gpr(t0, rt);
28978                     break;
28979                 case OPC_EMT:
28980                     check_cp0_mt(ctx);
28981                     gen_helper_emt(t0);
28982                     gen_store_gpr(t0, rt);
28983                     break;
28984                 case OPC_DVPE:
28985                     check_cp0_mt(ctx);
28986                     gen_helper_dvpe(t0, cpu_env);
28987                     gen_store_gpr(t0, rt);
28988                     break;
28989                 case OPC_EVPE:
28990                     check_cp0_mt(ctx);
28991                     gen_helper_evpe(t0, cpu_env);
28992                     gen_store_gpr(t0, rt);
28993                     break;
28994                 case OPC_DVP:
28995                     check_insn(ctx, ISA_MIPS32R6);
28996                     if (ctx->vp) {
28997                         gen_helper_dvp(t0, cpu_env);
28998                         gen_store_gpr(t0, rt);
28999                     }
29000                     break;
29001                 case OPC_EVP:
29002                     check_insn(ctx, ISA_MIPS32R6);
29003                     if (ctx->vp) {
29004                         gen_helper_evp(t0, cpu_env);
29005                         gen_store_gpr(t0, rt);
29006                     }
29007                     break;
29008                 case OPC_DI:
29009                     check_insn(ctx, ISA_MIPS32R2);
29010                     save_cpu_state(ctx, 1);
29011                     gen_helper_di(t0, cpu_env);
29012                     gen_store_gpr(t0, rt);
29013                     /* Stop translation as we may have switched
29014                        the execution mode.  */
29015                     ctx->base.is_jmp = DISAS_STOP;
29016                     break;
29017                 case OPC_EI:
29018                     check_insn(ctx, ISA_MIPS32R2);
29019                     save_cpu_state(ctx, 1);
29020                     gen_helper_ei(t0, cpu_env);
29021                     gen_store_gpr(t0, rt);
29022                     /* DISAS_STOP isn't sufficient, we need to ensure we break
29023                        out of translated code to check for pending interrupts */
29024                     gen_save_pc(ctx->base.pc_next + 4);
29025                     ctx->base.is_jmp = DISAS_EXIT;
29026                     break;
29027                 default:            /* Invalid */
29028                     MIPS_INVAL("mfmc0");
29029                     generate_exception_end(ctx, EXCP_RI);
29030                     break;
29031                 }
29032                 tcg_temp_free(t0);
29033             }
29034 #endif /* !CONFIG_USER_ONLY */
29035             break;
29036         case OPC_RDPGPR:
29037             check_insn(ctx, ISA_MIPS32R2);
29038             gen_load_srsgpr(rt, rd);
29039             break;
29040         case OPC_WRPGPR:
29041             check_insn(ctx, ISA_MIPS32R2);
29042             gen_store_srsgpr(rt, rd);
29043             break;
29044         default:
29045             MIPS_INVAL("cp0");
29046             generate_exception_end(ctx, EXCP_RI);
29047             break;
29048         }
29049         break;
29050     case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
29051         if (ctx->insn_flags & ISA_MIPS32R6) {
29052             /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
29053             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29054         } else {
29055             /* OPC_ADDI */
29056             /* Arithmetic with immediate opcode */
29057             gen_arith_imm(ctx, op, rt, rs, imm);
29058         }
29059         break;
29060     case OPC_ADDIU:
29061          gen_arith_imm(ctx, op, rt, rs, imm);
29062          break;
29063     case OPC_SLTI: /* Set on less than with immediate opcode */
29064     case OPC_SLTIU:
29065          gen_slt_imm(ctx, op, rt, rs, imm);
29066          break;
29067     case OPC_ANDI: /* Arithmetic with immediate opcode */
29068     case OPC_LUI: /* OPC_AUI */
29069     case OPC_ORI:
29070     case OPC_XORI:
29071          gen_logic_imm(ctx, op, rt, rs, imm);
29072          break;
29073     case OPC_J: /* Jump */
29074     case OPC_JAL:
29075          offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
29076          gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
29077          break;
29078     /* Branch */
29079     case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
29080         if (ctx->insn_flags & ISA_MIPS32R6) {
29081             if (rt == 0) {
29082                 generate_exception_end(ctx, EXCP_RI);
29083                 break;
29084             }
29085             /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
29086             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29087         } else {
29088             /* OPC_BLEZL */
29089             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29090         }
29091         break;
29092     case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
29093         if (ctx->insn_flags & ISA_MIPS32R6) {
29094             if (rt == 0) {
29095                 generate_exception_end(ctx, EXCP_RI);
29096                 break;
29097             }
29098             /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
29099             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29100         } else {
29101             /* OPC_BGTZL */
29102             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29103         }
29104         break;
29105     case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
29106         if (rt == 0) {
29107             /* OPC_BLEZ */
29108             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29109         } else {
29110             check_insn(ctx, ISA_MIPS32R6);
29111             /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
29112             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29113         }
29114         break;
29115     case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
29116         if (rt == 0) {
29117             /* OPC_BGTZ */
29118             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29119         } else {
29120             check_insn(ctx, ISA_MIPS32R6);
29121             /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
29122             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29123         }
29124         break;
29125     case OPC_BEQL:
29126     case OPC_BNEL:
29127         check_insn(ctx, ISA_MIPS2);
29128          check_insn_opc_removed(ctx, ISA_MIPS32R6);
29129         /* Fallthrough */
29130     case OPC_BEQ:
29131     case OPC_BNE:
29132          gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29133          break;
29134     case OPC_LL: /* Load and stores */
29135         check_insn(ctx, ISA_MIPS2);
29136         if (ctx->insn_flags & INSN_R5900) {
29137             check_insn_opc_user_only(ctx, INSN_R5900);
29138         }
29139         /* Fallthrough */
29140     case OPC_LWL:
29141     case OPC_LWR:
29142         check_insn_opc_removed(ctx, ISA_MIPS32R6);
29143          /* Fallthrough */
29144     case OPC_LB:
29145     case OPC_LH:
29146     case OPC_LW:
29147     case OPC_LWPC:
29148     case OPC_LBU:
29149     case OPC_LHU:
29150          gen_ld(ctx, op, rt, rs, imm);
29151          break;
29152     case OPC_SWL:
29153     case OPC_SWR:
29154         check_insn_opc_removed(ctx, ISA_MIPS32R6);
29155         /* fall through */
29156     case OPC_SB:
29157     case OPC_SH:
29158     case OPC_SW:
29159          gen_st(ctx, op, rt, rs, imm);
29160          break;
29161     case OPC_SC:
29162         check_insn(ctx, ISA_MIPS2);
29163          check_insn_opc_removed(ctx, ISA_MIPS32R6);
29164         if (ctx->insn_flags & INSN_R5900) {
29165             check_insn_opc_user_only(ctx, INSN_R5900);
29166         }
29167          gen_st_cond(ctx, op, rt, rs, imm);
29168          break;
29169     case OPC_CACHE:
29170         check_insn_opc_removed(ctx, ISA_MIPS32R6);
29171         check_cp0_enabled(ctx);
29172         check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
29173         if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
29174             gen_cache_operation(ctx, rt, rs, imm);
29175         }
29176         /* Treat as NOP. */
29177         break;
29178     case OPC_PREF:
29179         check_insn_opc_removed(ctx, ISA_MIPS32R6);
29180         if (ctx->insn_flags & INSN_R5900) {
29181             /* Treat as NOP. */
29182         } else {
29183             check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
29184             /* Treat as NOP. */
29185         }
29186         break;
29187
29188     /* Floating point (COP1). */
29189     case OPC_LWC1:
29190     case OPC_LDC1:
29191     case OPC_SWC1:
29192     case OPC_SDC1:
29193         gen_cop1_ldst(ctx, op, rt, rs, imm);
29194         break;
29195
29196     case OPC_CP1:
29197         op1 = MASK_CP1(ctx->opcode);
29198
29199         switch (op1) {
29200         case OPC_MFHC1:
29201         case OPC_MTHC1:
29202             check_cp1_enabled(ctx);
29203             check_insn(ctx, ISA_MIPS32R2);
29204             /* fall through */
29205         case OPC_MFC1:
29206         case OPC_CFC1:
29207         case OPC_MTC1:
29208         case OPC_CTC1:
29209             check_cp1_enabled(ctx);
29210             gen_cp1(ctx, op1, rt, rd);
29211             break;
29212 #if defined(TARGET_MIPS64)
29213         case OPC_DMFC1:
29214         case OPC_DMTC1:
29215             check_cp1_enabled(ctx);
29216             check_insn(ctx, ISA_MIPS3);
29217             check_mips_64(ctx);
29218             gen_cp1(ctx, op1, rt, rd);
29219             break;
29220 #endif
29221         case OPC_BC1EQZ: /* OPC_BC1ANY2 */
29222             check_cp1_enabled(ctx);
29223             if (ctx->insn_flags & ISA_MIPS32R6) {
29224                 /* OPC_BC1EQZ */
29225                 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
29226                                        rt, imm << 2, 4);
29227             } else {
29228                 /* OPC_BC1ANY2 */
29229                 check_cop1x(ctx);
29230                 check_insn(ctx, ASE_MIPS3D);
29231                 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
29232                                     (rt >> 2) & 0x7, imm << 2);
29233             }
29234             break;
29235         case OPC_BC1NEZ:
29236             check_cp1_enabled(ctx);
29237             check_insn(ctx, ISA_MIPS32R6);
29238             gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
29239                                    rt, imm << 2, 4);
29240             break;
29241         case OPC_BC1ANY4:
29242             check_cp1_enabled(ctx);
29243             check_insn_opc_removed(ctx, ISA_MIPS32R6);
29244             check_cop1x(ctx);
29245             check_insn(ctx, ASE_MIPS3D);
29246             /* fall through */
29247         case OPC_BC1:
29248             check_cp1_enabled(ctx);
29249             check_insn_opc_removed(ctx, ISA_MIPS32R6);
29250             gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
29251                                 (rt >> 2) & 0x7, imm << 2);
29252             break;
29253         case OPC_PS_FMT:
29254             check_ps(ctx);
29255             /* fall through */
29256         case OPC_S_FMT:
29257         case OPC_D_FMT:
29258             check_cp1_enabled(ctx);
29259             gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
29260                        (imm >> 8) & 0x7);
29261             break;
29262         case OPC_W_FMT:
29263         case OPC_L_FMT:
29264         {
29265             int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
29266             check_cp1_enabled(ctx);
29267             if (ctx->insn_flags & ISA_MIPS32R6) {
29268                 switch (r6_op) {
29269                 case R6_OPC_CMP_AF_S:
29270                 case R6_OPC_CMP_UN_S:
29271                 case R6_OPC_CMP_EQ_S:
29272                 case R6_OPC_CMP_UEQ_S:
29273                 case R6_OPC_CMP_LT_S:
29274                 case R6_OPC_CMP_ULT_S:
29275                 case R6_OPC_CMP_LE_S:
29276                 case R6_OPC_CMP_ULE_S:
29277                 case R6_OPC_CMP_SAF_S:
29278                 case R6_OPC_CMP_SUN_S:
29279                 case R6_OPC_CMP_SEQ_S:
29280                 case R6_OPC_CMP_SEUQ_S:
29281                 case R6_OPC_CMP_SLT_S:
29282                 case R6_OPC_CMP_SULT_S:
29283                 case R6_OPC_CMP_SLE_S:
29284                 case R6_OPC_CMP_SULE_S:
29285                 case R6_OPC_CMP_OR_S:
29286                 case R6_OPC_CMP_UNE_S:
29287                 case R6_OPC_CMP_NE_S:
29288                 case R6_OPC_CMP_SOR_S:
29289                 case R6_OPC_CMP_SUNE_S:
29290                 case R6_OPC_CMP_SNE_S:
29291                     gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
29292                     break;
29293                 case R6_OPC_CMP_AF_D:
29294                 case R6_OPC_CMP_UN_D:
29295                 case R6_OPC_CMP_EQ_D:
29296                 case R6_OPC_CMP_UEQ_D:
29297                 case R6_OPC_CMP_LT_D:
29298                 case R6_OPC_CMP_ULT_D:
29299                 case R6_OPC_CMP_LE_D:
29300                 case R6_OPC_CMP_ULE_D:
29301                 case R6_OPC_CMP_SAF_D:
29302                 case R6_OPC_CMP_SUN_D:
29303                 case R6_OPC_CMP_SEQ_D:
29304                 case R6_OPC_CMP_SEUQ_D:
29305                 case R6_OPC_CMP_SLT_D:
29306                 case R6_OPC_CMP_SULT_D:
29307                 case R6_OPC_CMP_SLE_D:
29308                 case R6_OPC_CMP_SULE_D:
29309                 case R6_OPC_CMP_OR_D:
29310                 case R6_OPC_CMP_UNE_D:
29311                 case R6_OPC_CMP_NE_D:
29312                 case R6_OPC_CMP_SOR_D:
29313                 case R6_OPC_CMP_SUNE_D:
29314                 case R6_OPC_CMP_SNE_D:
29315                     gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
29316                     break;
29317                 default:
29318                     gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
29319                                rt, rd, sa, (imm >> 8) & 0x7);
29320
29321                     break;
29322                 }
29323             } else {
29324                 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
29325                            (imm >> 8) & 0x7);
29326             }
29327             break;
29328         }
29329         case OPC_BZ_V:
29330         case OPC_BNZ_V:
29331         case OPC_BZ_B:
29332         case OPC_BZ_H:
29333         case OPC_BZ_W:
29334         case OPC_BZ_D:
29335         case OPC_BNZ_B:
29336         case OPC_BNZ_H:
29337         case OPC_BNZ_W:
29338         case OPC_BNZ_D:
29339             check_insn(ctx, ASE_MSA);
29340             gen_msa_branch(env, ctx, op1);
29341             break;
29342         default:
29343             MIPS_INVAL("cp1");
29344             generate_exception_end(ctx, EXCP_RI);
29345             break;
29346         }
29347         break;
29348
29349     /* Compact branches [R6] and COP2 [non-R6] */
29350     case OPC_BC: /* OPC_LWC2 */
29351     case OPC_BALC: /* OPC_SWC2 */
29352         if (ctx->insn_flags & ISA_MIPS32R6) {
29353             /* OPC_BC, OPC_BALC */
29354             gen_compute_compact_branch(ctx, op, 0, 0,
29355                                        sextract32(ctx->opcode << 2, 0, 28));
29356         } else {
29357             /* OPC_LWC2, OPC_SWC2 */
29358             /* COP2: Not implemented. */
29359             generate_exception_err(ctx, EXCP_CpU, 2);
29360         }
29361         break;
29362     case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
29363     case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
29364         if (ctx->insn_flags & ISA_MIPS32R6) {
29365             if (rs != 0) {
29366                 /* OPC_BEQZC, OPC_BNEZC */
29367                 gen_compute_compact_branch(ctx, op, rs, 0,
29368                                            sextract32(ctx->opcode << 2, 0, 23));
29369             } else {
29370                 /* OPC_JIC, OPC_JIALC */
29371                 gen_compute_compact_branch(ctx, op, 0, rt, imm);
29372             }
29373         } else {
29374             /* OPC_LWC2, OPC_SWC2 */
29375             /* COP2: Not implemented. */
29376             generate_exception_err(ctx, EXCP_CpU, 2);
29377         }
29378         break;
29379     case OPC_CP2:
29380         check_insn(ctx, INSN_LOONGSON2F);
29381         /* Note that these instructions use different fields.  */
29382         gen_loongson_multimedia(ctx, sa, rd, rt);
29383         break;
29384
29385     case OPC_CP3:
29386         check_insn_opc_removed(ctx, ISA_MIPS32R6);
29387         if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
29388             check_cp1_enabled(ctx);
29389             op1 = MASK_CP3(ctx->opcode);
29390             switch (op1) {
29391             case OPC_LUXC1:
29392             case OPC_SUXC1:
29393                 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
29394                 /* Fallthrough */
29395             case OPC_LWXC1:
29396             case OPC_LDXC1:
29397             case OPC_SWXC1:
29398             case OPC_SDXC1:
29399                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
29400                 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
29401                 break;
29402             case OPC_PREFX:
29403                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
29404                 /* Treat as NOP. */
29405                 break;
29406             case OPC_ALNV_PS:
29407                 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
29408                 /* Fallthrough */
29409             case OPC_MADD_S:
29410             case OPC_MADD_D:
29411             case OPC_MADD_PS:
29412             case OPC_MSUB_S:
29413             case OPC_MSUB_D:
29414             case OPC_MSUB_PS:
29415             case OPC_NMADD_S:
29416             case OPC_NMADD_D:
29417             case OPC_NMADD_PS:
29418             case OPC_NMSUB_S:
29419             case OPC_NMSUB_D:
29420             case OPC_NMSUB_PS:
29421                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
29422                 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
29423                 break;
29424             default:
29425                 MIPS_INVAL("cp3");
29426                 generate_exception_end(ctx, EXCP_RI);
29427                 break;
29428             }
29429         } else {
29430             generate_exception_err(ctx, EXCP_CpU, 1);
29431         }
29432         break;
29433
29434 #if defined(TARGET_MIPS64)
29435     /* MIPS64 opcodes */
29436     case OPC_LLD:
29437         if (ctx->insn_flags & INSN_R5900) {
29438             check_insn_opc_user_only(ctx, INSN_R5900);
29439         }
29440         /* fall through */
29441     case OPC_LDL:
29442     case OPC_LDR:
29443         check_insn_opc_removed(ctx, ISA_MIPS32R6);
29444         /* fall through */
29445     case OPC_LWU:
29446     case OPC_LD:
29447         check_insn(ctx, ISA_MIPS3);
29448         check_mips_64(ctx);
29449         gen_ld(ctx, op, rt, rs, imm);
29450         break;
29451     case OPC_SDL:
29452     case OPC_SDR:
29453         check_insn_opc_removed(ctx, ISA_MIPS32R6);
29454         /* fall through */
29455     case OPC_SD:
29456         check_insn(ctx, ISA_MIPS3);
29457         check_mips_64(ctx);
29458         gen_st(ctx, op, rt, rs, imm);
29459         break;
29460     case OPC_SCD:
29461         check_insn_opc_removed(ctx, ISA_MIPS32R6);
29462         check_insn(ctx, ISA_MIPS3);
29463         if (ctx->insn_flags & INSN_R5900) {
29464             check_insn_opc_user_only(ctx, INSN_R5900);
29465         }
29466         check_mips_64(ctx);
29467         gen_st_cond(ctx, op, rt, rs, imm);
29468         break;
29469     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
29470         if (ctx->insn_flags & ISA_MIPS32R6) {
29471             /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
29472             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29473         } else {
29474             /* OPC_DADDI */
29475             check_insn(ctx, ISA_MIPS3);
29476             check_mips_64(ctx);
29477             gen_arith_imm(ctx, op, rt, rs, imm);
29478         }
29479         break;
29480     case OPC_DADDIU:
29481         check_insn(ctx, ISA_MIPS3);
29482         check_mips_64(ctx);
29483         gen_arith_imm(ctx, op, rt, rs, imm);
29484         break;
29485 #else
29486     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
29487         if (ctx->insn_flags & ISA_MIPS32R6) {
29488             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29489         } else {
29490             MIPS_INVAL("major opcode");
29491             generate_exception_end(ctx, EXCP_RI);
29492         }
29493         break;
29494 #endif
29495     case OPC_DAUI: /* OPC_JALX */
29496         if (ctx->insn_flags & ISA_MIPS32R6) {
29497 #if defined(TARGET_MIPS64)
29498             /* OPC_DAUI */
29499             check_mips_64(ctx);
29500             if (rs == 0) {
29501                 generate_exception(ctx, EXCP_RI);
29502             } else if (rt != 0) {
29503                 TCGv t0 = tcg_temp_new();
29504                 gen_load_gpr(t0, rs);
29505                 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
29506                 tcg_temp_free(t0);
29507             }
29508 #else
29509             generate_exception_end(ctx, EXCP_RI);
29510             MIPS_INVAL("major opcode");
29511 #endif
29512         } else {
29513             /* OPC_JALX */
29514             check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
29515             offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
29516             gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
29517         }
29518         break;
29519     case OPC_MSA: /* OPC_MDMX */
29520         if (ctx->insn_flags & INSN_R5900) {
29521             gen_mmi_lq(env, ctx);    /* MMI_OPC_LQ */
29522         } else {
29523             /* MDMX: Not implemented. */
29524             gen_msa(env, ctx);
29525         }
29526         break;
29527     case OPC_PCREL:
29528         check_insn(ctx, ISA_MIPS32R6);
29529         gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
29530         break;
29531     default:            /* Invalid */
29532         MIPS_INVAL("major opcode");
29533         generate_exception_end(ctx, EXCP_RI);
29534         break;
29535     }
29536 }
29537
29538 static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
29539 {
29540     DisasContext *ctx = container_of(dcbase, DisasContext, base);
29541     CPUMIPSState *env = cs->env_ptr;
29542
29543     ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
29544     ctx->saved_pc = -1;
29545     ctx->insn_flags = env->insn_flags;
29546     ctx->CP0_Config1 = env->CP0_Config1;
29547     ctx->CP0_Config2 = env->CP0_Config2;
29548     ctx->CP0_Config3 = env->CP0_Config3;
29549     ctx->CP0_Config5 = env->CP0_Config5;
29550     ctx->btarget = 0;
29551     ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
29552     ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
29553     ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
29554     ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
29555     ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
29556     ctx->PAMask = env->PAMask;
29557     ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
29558     ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
29559     ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
29560     ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
29561     ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
29562     /* Restore delay slot state from the tb context.  */
29563     ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
29564     ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
29565     ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
29566              (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
29567     ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
29568     ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
29569     ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
29570     ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
29571     restore_cpu_state(env, ctx);
29572 #ifdef CONFIG_USER_ONLY
29573         ctx->mem_idx = MIPS_HFLAG_UM;
29574 #else
29575         ctx->mem_idx = hflags_mmu_index(ctx->hflags);
29576 #endif
29577     ctx->default_tcg_memop_mask = (ctx->insn_flags & ISA_MIPS32R6) ?
29578                                   MO_UNALN : MO_ALIGN;
29579
29580     LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
29581               ctx->hflags);
29582 }
29583
29584 static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
29585 {
29586 }
29587
29588 static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
29589 {
29590     DisasContext *ctx = container_of(dcbase, DisasContext, base);
29591
29592     tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
29593                        ctx->btarget);
29594 }
29595
29596 static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
29597                                      const CPUBreakpoint *bp)
29598 {
29599     DisasContext *ctx = container_of(dcbase, DisasContext, base);
29600
29601     save_cpu_state(ctx, 1);
29602     ctx->base.is_jmp = DISAS_NORETURN;
29603     gen_helper_raise_exception_debug(cpu_env);
29604     /* The address covered by the breakpoint must be included in
29605        [tb->pc, tb->pc + tb->size) in order to for it to be
29606        properly cleared -- thus we increment the PC here so that
29607        the logic setting tb->size below does the right thing.  */
29608     ctx->base.pc_next += 4;
29609     return true;
29610 }
29611
29612 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
29613 {
29614     CPUMIPSState *env = cs->env_ptr;
29615     DisasContext *ctx = container_of(dcbase, DisasContext, base);
29616     int insn_bytes;
29617     int is_slot;
29618
29619     is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
29620     if (ctx->insn_flags & ISA_NANOMIPS32) {
29621         ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
29622         insn_bytes = decode_nanomips_opc(env, ctx);
29623     } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
29624         ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
29625         insn_bytes = 4;
29626         decode_opc(env, ctx);
29627     } else if (ctx->insn_flags & ASE_MICROMIPS) {
29628         ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
29629         insn_bytes = decode_micromips_opc(env, ctx);
29630     } else if (ctx->insn_flags & ASE_MIPS16) {
29631         ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
29632         insn_bytes = decode_mips16_opc(env, ctx);
29633     } else {
29634         generate_exception_end(ctx, EXCP_RI);
29635         g_assert(ctx->base.is_jmp == DISAS_NORETURN);
29636         return;
29637     }
29638
29639     if (ctx->hflags & MIPS_HFLAG_BMASK) {
29640         if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
29641                              MIPS_HFLAG_FBNSLOT))) {
29642             /* force to generate branch as there is neither delay nor
29643                forbidden slot */
29644             is_slot = 1;
29645         }
29646         if ((ctx->hflags & MIPS_HFLAG_M16) &&
29647             (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
29648             /* Force to generate branch as microMIPS R6 doesn't restrict
29649                branches in the forbidden slot. */
29650             is_slot = 1;
29651         }
29652     }
29653     if (is_slot) {
29654         gen_branch(ctx, insn_bytes);
29655     }
29656     ctx->base.pc_next += insn_bytes;
29657
29658     if (ctx->base.is_jmp != DISAS_NEXT) {
29659         return;
29660     }
29661     /* Execute a branch and its delay slot as a single instruction.
29662        This is what GDB expects and is consistent with what the
29663        hardware does (e.g. if a delay slot instruction faults, the
29664        reported PC is the PC of the branch).  */
29665     if (ctx->base.singlestep_enabled &&
29666         (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
29667         ctx->base.is_jmp = DISAS_TOO_MANY;
29668     }
29669     if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
29670         ctx->base.is_jmp = DISAS_TOO_MANY;
29671     }
29672 }
29673
29674 static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
29675 {
29676     DisasContext *ctx = container_of(dcbase, DisasContext, base);
29677
29678     if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
29679         save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
29680         gen_helper_raise_exception_debug(cpu_env);
29681     } else {
29682         switch (ctx->base.is_jmp) {
29683         case DISAS_STOP:
29684             gen_save_pc(ctx->base.pc_next);
29685             tcg_gen_lookup_and_goto_ptr();
29686             break;
29687         case DISAS_NEXT:
29688         case DISAS_TOO_MANY:
29689             save_cpu_state(ctx, 0);
29690             gen_goto_tb(ctx, 0, ctx->base.pc_next);
29691             break;
29692         case DISAS_EXIT:
29693             tcg_gen_exit_tb(NULL, 0);
29694             break;
29695         case DISAS_NORETURN:
29696             break;
29697         default:
29698             g_assert_not_reached();
29699         }
29700     }
29701 }
29702
29703 static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
29704 {
29705     qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
29706     log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
29707 }
29708
29709 static const TranslatorOps mips_tr_ops = {
29710     .init_disas_context = mips_tr_init_disas_context,
29711     .tb_start           = mips_tr_tb_start,
29712     .insn_start         = mips_tr_insn_start,
29713     .breakpoint_check   = mips_tr_breakpoint_check,
29714     .translate_insn     = mips_tr_translate_insn,
29715     .tb_stop            = mips_tr_tb_stop,
29716     .disas_log          = mips_tr_disas_log,
29717 };
29718
29719 void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
29720 {
29721     DisasContext ctx;
29722
29723     translator_loop(&mips_tr_ops, &ctx.base, cs, tb);
29724 }
29725
29726 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
29727                            int flags)
29728 {
29729     int i;
29730     int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
29731
29732 #define printfpr(fp)                                                    \
29733     do {                                                                \
29734         if (is_fpu64)                                                   \
29735             fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
29736                         " fd:%13g fs:%13g psu: %13g\n",                 \
29737                         (fp)->w[FP_ENDIAN_IDX], (fp)->d,                \
29738                         (double)(fp)->fd,                               \
29739                         (double)(fp)->fs[FP_ENDIAN_IDX],                \
29740                         (double)(fp)->fs[!FP_ENDIAN_IDX]);              \
29741         else {                                                          \
29742             fpr_t tmp;                                                  \
29743             tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];              \
29744             tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];       \
29745             fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
29746                         " fd:%13g fs:%13g psu:%13g\n",                  \
29747                         tmp.w[FP_ENDIAN_IDX], tmp.d,                    \
29748                         (double)tmp.fd,                                 \
29749                         (double)tmp.fs[FP_ENDIAN_IDX],                  \
29750                         (double)tmp.fs[!FP_ENDIAN_IDX]);                \
29751         }                                                               \
29752     } while(0)
29753
29754
29755     fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%02x\n",
29756                 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
29757                 get_float_exception_flags(&env->active_fpu.fp_status));
29758     for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
29759         fpu_fprintf(f, "%3s: ", fregnames[i]);
29760         printfpr(&env->active_fpu.fpr[i]);
29761     }
29762
29763 #undef printfpr
29764 }
29765
29766 void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
29767                          int flags)
29768 {
29769     MIPSCPU *cpu = MIPS_CPU(cs);
29770     CPUMIPSState *env = &cpu->env;
29771     int i;
29772
29773     cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
29774                 " LO=0x" TARGET_FMT_lx " ds %04x "
29775                 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
29776                 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
29777                 env->hflags, env->btarget, env->bcond);
29778     for (i = 0; i < 32; i++) {
29779         if ((i & 3) == 0)
29780             cpu_fprintf(f, "GPR%02d:", i);
29781         cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
29782         if ((i & 3) == 3)
29783             cpu_fprintf(f, "\n");
29784     }
29785
29786     cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
29787                 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
29788     cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
29789                 PRIx64 "\n",
29790                 env->CP0_Config0, env->CP0_Config1, env->lladdr);
29791     cpu_fprintf(f, "    Config2 0x%08x Config3 0x%08x\n",
29792                 env->CP0_Config2, env->CP0_Config3);
29793     cpu_fprintf(f, "    Config4 0x%08x Config5 0x%08x\n",
29794                 env->CP0_Config4, env->CP0_Config5);
29795     if ((flags & CPU_DUMP_FPU) && (env->hflags & MIPS_HFLAG_FPU)) {
29796         fpu_dump_state(env, f, cpu_fprintf, flags);
29797     }
29798 }
29799
29800 void mips_tcg_init(void)
29801 {
29802     int i;
29803
29804     cpu_gpr[0] = NULL;
29805     for (i = 1; i < 32; i++)
29806         cpu_gpr[i] = tcg_global_mem_new(cpu_env,
29807                                         offsetof(CPUMIPSState, active_tc.gpr[i]),
29808                                         regnames[i]);
29809
29810     for (i = 0; i < 32; i++) {
29811         int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
29812         msa_wr_d[i * 2] =
29813                 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
29814         /* The scalar floating-point unit (FPU) registers are mapped on
29815          * the MSA vector registers. */
29816         fpu_f64[i] = msa_wr_d[i * 2];
29817         off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
29818         msa_wr_d[i * 2 + 1] =
29819                 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
29820     }
29821
29822     cpu_PC = tcg_global_mem_new(cpu_env,
29823                                 offsetof(CPUMIPSState, active_tc.PC), "PC");
29824     for (i = 0; i < MIPS_DSP_ACC; i++) {
29825         cpu_HI[i] = tcg_global_mem_new(cpu_env,
29826                                        offsetof(CPUMIPSState, active_tc.HI[i]),
29827                                        regnames_HI[i]);
29828         cpu_LO[i] = tcg_global_mem_new(cpu_env,
29829                                        offsetof(CPUMIPSState, active_tc.LO[i]),
29830                                        regnames_LO[i]);
29831     }
29832     cpu_dspctrl = tcg_global_mem_new(cpu_env,
29833                                      offsetof(CPUMIPSState, active_tc.DSPControl),
29834                                      "DSPControl");
29835     bcond = tcg_global_mem_new(cpu_env,
29836                                offsetof(CPUMIPSState, bcond), "bcond");
29837     btarget = tcg_global_mem_new(cpu_env,
29838                                  offsetof(CPUMIPSState, btarget), "btarget");
29839     hflags = tcg_global_mem_new_i32(cpu_env,
29840                                     offsetof(CPUMIPSState, hflags), "hflags");
29841
29842     fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
29843                                       offsetof(CPUMIPSState, active_fpu.fcr0),
29844                                       "fcr0");
29845     fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
29846                                        offsetof(CPUMIPSState, active_fpu.fcr31),
29847                                        "fcr31");
29848 #if !defined(TARGET_MIPS64)
29849     for (i = 0; i < NUMBER_OF_MXU_REGISTERS - 1; i++) {
29850         mxu_gpr[i] = tcg_global_mem_new(cpu_env,
29851                                         offsetof(CPUMIPSState,
29852                                                  active_tc.mxu_gpr[i]),
29853                                         mxuregnames[i]);
29854     }
29855
29856     mxu_CR = tcg_global_mem_new(cpu_env,
29857                                 offsetof(CPUMIPSState, active_tc.mxu_cr),
29858                                 mxuregnames[NUMBER_OF_MXU_REGISTERS - 1]);
29859 #endif
29860 }
29861
29862 #include "translate_init.inc.c"
29863
29864 void cpu_mips_realize_env(CPUMIPSState *env)
29865 {
29866     env->exception_base = (int32_t)0xBFC00000;
29867
29868 #ifndef CONFIG_USER_ONLY
29869     mmu_init(env, env->cpu_model);
29870 #endif
29871     fpu_init(env, env->cpu_model);
29872     mvp_init(env, env->cpu_model);
29873 }
29874
29875 bool cpu_supports_cps_smp(const char *cpu_type)
29876 {
29877     const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
29878     return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
29879 }
29880
29881 bool cpu_supports_isa(const char *cpu_type, unsigned int isa)
29882 {
29883     const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
29884     return (mcc->cpu_def->insn_flags & isa) != 0;
29885 }
29886
29887 void cpu_set_exception_base(int vp_index, target_ulong address)
29888 {
29889     MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
29890     vp->env.exception_base = address;
29891 }
29892
29893 void cpu_state_reset(CPUMIPSState *env)
29894 {
29895     MIPSCPU *cpu = mips_env_get_cpu(env);
29896     CPUState *cs = CPU(cpu);
29897
29898     /* Reset registers to their default values */
29899     env->CP0_PRid = env->cpu_model->CP0_PRid;
29900     env->CP0_Config0 = env->cpu_model->CP0_Config0;
29901 #ifdef TARGET_WORDS_BIGENDIAN
29902     env->CP0_Config0 |= (1 << CP0C0_BE);
29903 #endif
29904     env->CP0_Config1 = env->cpu_model->CP0_Config1;
29905     env->CP0_Config2 = env->cpu_model->CP0_Config2;
29906     env->CP0_Config3 = env->cpu_model->CP0_Config3;
29907     env->CP0_Config4 = env->cpu_model->CP0_Config4;
29908     env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
29909     env->CP0_Config5 = env->cpu_model->CP0_Config5;
29910     env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
29911     env->CP0_Config6 = env->cpu_model->CP0_Config6;
29912     env->CP0_Config7 = env->cpu_model->CP0_Config7;
29913     env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
29914                                  << env->cpu_model->CP0_LLAddr_shift;
29915     env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
29916     env->SYNCI_Step = env->cpu_model->SYNCI_Step;
29917     env->CCRes = env->cpu_model->CCRes;
29918     env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
29919     env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
29920     env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
29921     env->current_tc = 0;
29922     env->SEGBITS = env->cpu_model->SEGBITS;
29923     env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
29924 #if defined(TARGET_MIPS64)
29925     if (env->cpu_model->insn_flags & ISA_MIPS3) {
29926         env->SEGMask |= 3ULL << 62;
29927     }
29928 #endif
29929     env->PABITS = env->cpu_model->PABITS;
29930     env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
29931     env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
29932     env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
29933     env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
29934     env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
29935     env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
29936     env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
29937     env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
29938     env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
29939     env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
29940     env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
29941     env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
29942     env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
29943     env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
29944     env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
29945     env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
29946     env->msair = env->cpu_model->MSAIR;
29947     env->insn_flags = env->cpu_model->insn_flags;
29948
29949 #if defined(CONFIG_USER_ONLY)
29950     env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
29951 # ifdef TARGET_MIPS64
29952     /* Enable 64-bit register mode.  */
29953     env->CP0_Status |= (1 << CP0St_PX);
29954 # endif
29955 # ifdef TARGET_ABI_MIPSN64
29956     /* Enable 64-bit address mode.  */
29957     env->CP0_Status |= (1 << CP0St_UX);
29958 # endif
29959     /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
29960        hardware registers.  */
29961     env->CP0_HWREna |= 0x0000000F;
29962     if (env->CP0_Config1 & (1 << CP0C1_FP)) {
29963         env->CP0_Status |= (1 << CP0St_CU1);
29964     }
29965     if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
29966         env->CP0_Status |= (1 << CP0St_MX);
29967     }
29968 # if defined(TARGET_MIPS64)
29969     /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
29970     if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
29971         (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
29972         env->CP0_Status |= (1 << CP0St_FR);
29973     }
29974 # endif
29975 #else
29976     if (env->hflags & MIPS_HFLAG_BMASK) {
29977         /* If the exception was raised from a delay slot,
29978            come back to the jump.  */
29979         env->CP0_ErrorEPC = (env->active_tc.PC
29980                              - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
29981     } else {
29982         env->CP0_ErrorEPC = env->active_tc.PC;
29983     }
29984     env->active_tc.PC = env->exception_base;
29985     env->CP0_Random = env->tlb->nb_tlb - 1;
29986     env->tlb->tlb_in_use = env->tlb->nb_tlb;
29987     env->CP0_Wired = 0;
29988     env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
29989     env->CP0_EBase = (cs->cpu_index & 0x3FF);
29990     if (mips_um_ksegs_enabled()) {
29991         env->CP0_EBase |= 0x40000000;
29992     } else {
29993         env->CP0_EBase |= (int32_t)0x80000000;
29994     }
29995     if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
29996         env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
29997     }
29998     env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
29999                                  0x3ff : 0xff;
30000     env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
30001     /* vectored interrupts not implemented, timer on int 7,
30002        no performance counters. */
30003     env->CP0_IntCtl = 0xe0000000;
30004     {
30005         int i;
30006
30007         for (i = 0; i < 7; i++) {
30008             env->CP0_WatchLo[i] = 0;
30009             env->CP0_WatchHi[i] = 0x80000000;
30010         }
30011         env->CP0_WatchLo[7] = 0;
30012         env->CP0_WatchHi[7] = 0;
30013     }
30014     /* Count register increments in debug mode, EJTAG version 1 */
30015     env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
30016
30017     cpu_mips_store_count(env, 1);
30018
30019     if (env->CP0_Config3 & (1 << CP0C3_MT)) {
30020         int i;
30021
30022         /* Only TC0 on VPE 0 starts as active.  */
30023         for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
30024             env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
30025             env->tcs[i].CP0_TCHalt = 1;
30026         }
30027         env->active_tc.CP0_TCHalt = 1;
30028         cs->halted = 1;
30029
30030         if (cs->cpu_index == 0) {
30031             /* VPE0 starts up enabled.  */
30032             env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
30033             env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
30034
30035             /* TC0 starts up unhalted.  */
30036             cs->halted = 0;
30037             env->active_tc.CP0_TCHalt = 0;
30038             env->tcs[0].CP0_TCHalt = 0;
30039             /* With thread 0 active.  */
30040             env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
30041             env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
30042         }
30043     }
30044
30045     /*
30046      * Configure default legacy segmentation control. We use this regardless of
30047      * whether segmentation control is presented to the guest.
30048      */
30049     /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
30050     env->CP0_SegCtl0 =   (CP0SC_AM_MK << CP0SC_AM);
30051     /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
30052     env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
30053     /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
30054     env->CP0_SegCtl1 =   (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
30055                          (2 << CP0SC_C);
30056     /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
30057     env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
30058                          (3 << CP0SC_C)) << 16;
30059     /* USeg (seg4 0x40000000..0x7FFFFFFF) */
30060     env->CP0_SegCtl2 =   (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
30061                          (1 << CP0SC_EU) | (2 << CP0SC_C);
30062     /* USeg (seg5 0x00000000..0x3FFFFFFF) */
30063     env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
30064                          (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
30065     /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
30066     env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
30067 #endif
30068     if ((env->insn_flags & ISA_MIPS32R6) &&
30069         (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
30070         /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
30071         env->CP0_Status |= (1 << CP0St_FR);
30072     }
30073
30074     if (env->insn_flags & ISA_MIPS32R6) {
30075         /* PTW  =  1 */
30076         env->CP0_PWSize = 0x40;
30077         /* GDI  = 12 */
30078         /* UDI  = 12 */
30079         /* MDI  = 12 */
30080         /* PRI  = 12 */
30081         /* PTEI =  2 */
30082         env->CP0_PWField = 0x0C30C302;
30083     } else {
30084         /* GDI  =  0 */
30085         /* UDI  =  0 */
30086         /* MDI  =  0 */
30087         /* PRI  =  0 */
30088         /* PTEI =  2 */
30089         env->CP0_PWField = 0x02;
30090     }
30091
30092     if (env->CP0_Config3 & (1 << CP0C3_ISA) & (1 << (CP0C3_ISA + 1))) {
30093         /*  microMIPS on reset when Config3.ISA is 3 */
30094         env->hflags |= MIPS_HFLAG_M16;
30095     }
30096
30097     /* MSA */
30098     if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
30099         msa_reset(env);
30100     }
30101
30102     compute_hflags(env);
30103     restore_fp_status(env);
30104     restore_pamask(env);
30105     cs->exception_index = EXCP_NONE;
30106
30107     if (semihosting_get_argc()) {
30108         /* UHI interface can be used to obtain argc and argv */
30109         env->active_tc.gpr[4] = -1;
30110     }
30111 }
30112
30113 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
30114                           target_ulong *data)
30115 {
30116     env->active_tc.PC = data[0];
30117     env->hflags &= ~MIPS_HFLAG_BMASK;
30118     env->hflags |= data[1];
30119     switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
30120     case MIPS_HFLAG_BR:
30121         break;
30122     case MIPS_HFLAG_BC:
30123     case MIPS_HFLAG_BL:
30124     case MIPS_HFLAG_B:
30125         env->btarget = data[2];
30126         break;
30127     }
30128 }
This page took 1.726344 seconds and 4 git commands to generate.