]> Git Repo - qemu.git/blob - target/mips/translate.c
Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-4.1-20190612' into staging
[qemu.git] / target / mips / translate.c
1 /*
2  *  MIPS emulation for QEMU - main translation routines
3  *
4  *  Copyright (c) 2004-2005 Jocelyn Mayer
5  *  Copyright (c) 2006 Marius Groeger (FPU operations)
6  *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7  *  Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
8  *  Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
22  */
23
24 #include "qemu/osdep.h"
25 #include "cpu.h"
26 #include "internal.h"
27 #include "disas/disas.h"
28 #include "exec/exec-all.h"
29 #include "tcg-op.h"
30 #include "exec/cpu_ldst.h"
31 #include "hw/mips/cpudevs.h"
32
33 #include "exec/helper-proto.h"
34 #include "exec/helper-gen.h"
35 #include "hw/semihosting/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 #include "qemu/qemu-print.h"
42
43 #define MIPS_DEBUG_DISAS 0
44
45 /* MIPS major opcodes */
46 #define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
47
48 enum {
49     /* indirect opcode tables */
50     OPC_SPECIAL  = (0x00 << 26),
51     OPC_REGIMM   = (0x01 << 26),
52     OPC_CP0      = (0x10 << 26),
53     OPC_CP1      = (0x11 << 26),
54     OPC_CP2      = (0x12 << 26),
55     OPC_CP3      = (0x13 << 26),
56     OPC_SPECIAL2 = (0x1C << 26),
57     OPC_SPECIAL3 = (0x1F << 26),
58     /* arithmetic with immediate */
59     OPC_ADDI     = (0x08 << 26),
60     OPC_ADDIU    = (0x09 << 26),
61     OPC_SLTI     = (0x0A << 26),
62     OPC_SLTIU    = (0x0B << 26),
63     /* logic with immediate */
64     OPC_ANDI     = (0x0C << 26),
65     OPC_ORI      = (0x0D << 26),
66     OPC_XORI     = (0x0E << 26),
67     OPC_LUI      = (0x0F << 26),
68     /* arithmetic with immediate */
69     OPC_DADDI    = (0x18 << 26),
70     OPC_DADDIU   = (0x19 << 26),
71     /* Jump and branches */
72     OPC_J        = (0x02 << 26),
73     OPC_JAL      = (0x03 << 26),
74     OPC_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
75     OPC_BEQL     = (0x14 << 26),
76     OPC_BNE      = (0x05 << 26),
77     OPC_BNEL     = (0x15 << 26),
78     OPC_BLEZ     = (0x06 << 26),
79     OPC_BLEZL    = (0x16 << 26),
80     OPC_BGTZ     = (0x07 << 26),
81     OPC_BGTZL    = (0x17 << 26),
82     OPC_JALX     = (0x1D << 26),
83     OPC_DAUI     = (0x1D << 26),
84     /* Load and stores */
85     OPC_LDL      = (0x1A << 26),
86     OPC_LDR      = (0x1B << 26),
87     OPC_LB       = (0x20 << 26),
88     OPC_LH       = (0x21 << 26),
89     OPC_LWL      = (0x22 << 26),
90     OPC_LW       = (0x23 << 26),
91     OPC_LWPC     = OPC_LW | 0x5,
92     OPC_LBU      = (0x24 << 26),
93     OPC_LHU      = (0x25 << 26),
94     OPC_LWR      = (0x26 << 26),
95     OPC_LWU      = (0x27 << 26),
96     OPC_SB       = (0x28 << 26),
97     OPC_SH       = (0x29 << 26),
98     OPC_SWL      = (0x2A << 26),
99     OPC_SW       = (0x2B << 26),
100     OPC_SDL      = (0x2C << 26),
101     OPC_SDR      = (0x2D << 26),
102     OPC_SWR      = (0x2E << 26),
103     OPC_LL       = (0x30 << 26),
104     OPC_LLD      = (0x34 << 26),
105     OPC_LD       = (0x37 << 26),
106     OPC_LDPC     = OPC_LD | 0x5,
107     OPC_SC       = (0x38 << 26),
108     OPC_SCD      = (0x3C << 26),
109     OPC_SD       = (0x3F << 26),
110     /* Floating point load/store */
111     OPC_LWC1     = (0x31 << 26),
112     OPC_LWC2     = (0x32 << 26),
113     OPC_LDC1     = (0x35 << 26),
114     OPC_LDC2     = (0x36 << 26),
115     OPC_SWC1     = (0x39 << 26),
116     OPC_SWC2     = (0x3A << 26),
117     OPC_SDC1     = (0x3D << 26),
118     OPC_SDC2     = (0x3E << 26),
119     /* Compact Branches */
120     OPC_BLEZALC  = (0x06 << 26),
121     OPC_BGEZALC  = (0x06 << 26),
122     OPC_BGEUC    = (0x06 << 26),
123     OPC_BGTZALC  = (0x07 << 26),
124     OPC_BLTZALC  = (0x07 << 26),
125     OPC_BLTUC    = (0x07 << 26),
126     OPC_BOVC     = (0x08 << 26),
127     OPC_BEQZALC  = (0x08 << 26),
128     OPC_BEQC     = (0x08 << 26),
129     OPC_BLEZC    = (0x16 << 26),
130     OPC_BGEZC    = (0x16 << 26),
131     OPC_BGEC     = (0x16 << 26),
132     OPC_BGTZC    = (0x17 << 26),
133     OPC_BLTZC    = (0x17 << 26),
134     OPC_BLTC     = (0x17 << 26),
135     OPC_BNVC     = (0x18 << 26),
136     OPC_BNEZALC  = (0x18 << 26),
137     OPC_BNEC     = (0x18 << 26),
138     OPC_BC       = (0x32 << 26),
139     OPC_BEQZC    = (0x36 << 26),
140     OPC_JIC      = (0x36 << 26),
141     OPC_BALC     = (0x3A << 26),
142     OPC_BNEZC    = (0x3E << 26),
143     OPC_JIALC    = (0x3E << 26),
144     /* MDMX ASE specific */
145     OPC_MDMX     = (0x1E << 26),
146     /* MSA ASE, same as MDMX */
147     OPC_MSA      = OPC_MDMX,
148     /* Cache and prefetch */
149     OPC_CACHE    = (0x2F << 26),
150     OPC_PREF     = (0x33 << 26),
151     /* PC-relative address computation / loads */
152     OPC_PCREL    = (0x3B << 26),
153 };
154
155 /* PC-relative address computation / loads  */
156 #define MASK_OPC_PCREL_TOP2BITS(op)  (MASK_OP_MAJOR(op) | (op & (3 << 19)))
157 #define MASK_OPC_PCREL_TOP5BITS(op)  (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
158 enum {
159     /* Instructions determined by bits 19 and 20 */
160     OPC_ADDIUPC = OPC_PCREL | (0 << 19),
161     R6_OPC_LWPC = OPC_PCREL | (1 << 19),
162     OPC_LWUPC   = OPC_PCREL | (2 << 19),
163
164     /* Instructions determined by bits 16 ... 20 */
165     OPC_AUIPC   = OPC_PCREL | (0x1e << 16),
166     OPC_ALUIPC  = OPC_PCREL | (0x1f << 16),
167
168     /* Other */
169     R6_OPC_LDPC = OPC_PCREL | (6 << 18),
170 };
171
172 /* MIPS special opcodes */
173 #define MASK_SPECIAL(op)   MASK_OP_MAJOR(op) | (op & 0x3F)
174
175 enum {
176     /* Shifts */
177     OPC_SLL      = 0x00 | OPC_SPECIAL,
178     /* NOP is SLL r0, r0, 0   */
179     /* SSNOP is SLL r0, r0, 1 */
180     /* EHB is SLL r0, r0, 3 */
181     OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
182     OPC_ROTR     = OPC_SRL | (1 << 21),
183     OPC_SRA      = 0x03 | OPC_SPECIAL,
184     OPC_SLLV     = 0x04 | OPC_SPECIAL,
185     OPC_SRLV     = 0x06 | OPC_SPECIAL, /* also ROTRV */
186     OPC_ROTRV    = OPC_SRLV | (1 << 6),
187     OPC_SRAV     = 0x07 | OPC_SPECIAL,
188     OPC_DSLLV    = 0x14 | OPC_SPECIAL,
189     OPC_DSRLV    = 0x16 | OPC_SPECIAL, /* also DROTRV */
190     OPC_DROTRV   = OPC_DSRLV | (1 << 6),
191     OPC_DSRAV    = 0x17 | OPC_SPECIAL,
192     OPC_DSLL     = 0x38 | OPC_SPECIAL,
193     OPC_DSRL     = 0x3A | OPC_SPECIAL, /* also DROTR */
194     OPC_DROTR    = OPC_DSRL | (1 << 21),
195     OPC_DSRA     = 0x3B | OPC_SPECIAL,
196     OPC_DSLL32   = 0x3C | OPC_SPECIAL,
197     OPC_DSRL32   = 0x3E | OPC_SPECIAL, /* also DROTR32 */
198     OPC_DROTR32  = OPC_DSRL32 | (1 << 21),
199     OPC_DSRA32   = 0x3F | OPC_SPECIAL,
200     /* Multiplication / division */
201     OPC_MULT     = 0x18 | OPC_SPECIAL,
202     OPC_MULTU    = 0x19 | OPC_SPECIAL,
203     OPC_DIV      = 0x1A | OPC_SPECIAL,
204     OPC_DIVU     = 0x1B | OPC_SPECIAL,
205     OPC_DMULT    = 0x1C | OPC_SPECIAL,
206     OPC_DMULTU   = 0x1D | OPC_SPECIAL,
207     OPC_DDIV     = 0x1E | OPC_SPECIAL,
208     OPC_DDIVU    = 0x1F | OPC_SPECIAL,
209
210     /* 2 registers arithmetic / logic */
211     OPC_ADD      = 0x20 | OPC_SPECIAL,
212     OPC_ADDU     = 0x21 | OPC_SPECIAL,
213     OPC_SUB      = 0x22 | OPC_SPECIAL,
214     OPC_SUBU     = 0x23 | OPC_SPECIAL,
215     OPC_AND      = 0x24 | OPC_SPECIAL,
216     OPC_OR       = 0x25 | OPC_SPECIAL,
217     OPC_XOR      = 0x26 | OPC_SPECIAL,
218     OPC_NOR      = 0x27 | OPC_SPECIAL,
219     OPC_SLT      = 0x2A | OPC_SPECIAL,
220     OPC_SLTU     = 0x2B | OPC_SPECIAL,
221     OPC_DADD     = 0x2C | OPC_SPECIAL,
222     OPC_DADDU    = 0x2D | OPC_SPECIAL,
223     OPC_DSUB     = 0x2E | OPC_SPECIAL,
224     OPC_DSUBU    = 0x2F | OPC_SPECIAL,
225     /* Jumps */
226     OPC_JR       = 0x08 | OPC_SPECIAL, /* Also JR.HB */
227     OPC_JALR     = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
228     /* Traps */
229     OPC_TGE      = 0x30 | OPC_SPECIAL,
230     OPC_TGEU     = 0x31 | OPC_SPECIAL,
231     OPC_TLT      = 0x32 | OPC_SPECIAL,
232     OPC_TLTU     = 0x33 | OPC_SPECIAL,
233     OPC_TEQ      = 0x34 | OPC_SPECIAL,
234     OPC_TNE      = 0x36 | OPC_SPECIAL,
235     /* HI / LO registers load & stores */
236     OPC_MFHI     = 0x10 | OPC_SPECIAL,
237     OPC_MTHI     = 0x11 | OPC_SPECIAL,
238     OPC_MFLO     = 0x12 | OPC_SPECIAL,
239     OPC_MTLO     = 0x13 | OPC_SPECIAL,
240     /* Conditional moves */
241     OPC_MOVZ     = 0x0A | OPC_SPECIAL,
242     OPC_MOVN     = 0x0B | OPC_SPECIAL,
243
244     OPC_SELEQZ   = 0x35 | OPC_SPECIAL,
245     OPC_SELNEZ   = 0x37 | OPC_SPECIAL,
246
247     OPC_MOVCI    = 0x01 | OPC_SPECIAL,
248
249     /* Special */
250     OPC_PMON     = 0x05 | OPC_SPECIAL, /* unofficial */
251     OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
252     OPC_BREAK    = 0x0D | OPC_SPECIAL,
253     OPC_SPIM     = 0x0E | OPC_SPECIAL, /* unofficial */
254     OPC_SYNC     = 0x0F | OPC_SPECIAL,
255
256     OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
257     OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
258     OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
259     OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
260 };
261
262 /* R6 Multiply and Divide instructions have the same Opcode
263    and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
264 #define MASK_R6_MULDIV(op)   (MASK_SPECIAL(op) | (op & (0x7ff)))
265
266 enum {
267     R6_OPC_MUL   = OPC_MULT  | (2 << 6),
268     R6_OPC_MUH   = OPC_MULT  | (3 << 6),
269     R6_OPC_MULU  = OPC_MULTU | (2 << 6),
270     R6_OPC_MUHU  = OPC_MULTU | (3 << 6),
271     R6_OPC_DIV   = OPC_DIV   | (2 << 6),
272     R6_OPC_MOD   = OPC_DIV   | (3 << 6),
273     R6_OPC_DIVU  = OPC_DIVU  | (2 << 6),
274     R6_OPC_MODU  = OPC_DIVU  | (3 << 6),
275
276     R6_OPC_DMUL   = OPC_DMULT  | (2 << 6),
277     R6_OPC_DMUH   = OPC_DMULT  | (3 << 6),
278     R6_OPC_DMULU  = OPC_DMULTU | (2 << 6),
279     R6_OPC_DMUHU  = OPC_DMULTU | (3 << 6),
280     R6_OPC_DDIV   = OPC_DDIV   | (2 << 6),
281     R6_OPC_DMOD   = OPC_DDIV   | (3 << 6),
282     R6_OPC_DDIVU  = OPC_DDIVU  | (2 << 6),
283     R6_OPC_DMODU  = OPC_DDIVU  | (3 << 6),
284
285     R6_OPC_CLZ      = 0x10 | OPC_SPECIAL,
286     R6_OPC_CLO      = 0x11 | OPC_SPECIAL,
287     R6_OPC_DCLZ     = 0x12 | OPC_SPECIAL,
288     R6_OPC_DCLO     = 0x13 | OPC_SPECIAL,
289     R6_OPC_SDBBP    = 0x0e | OPC_SPECIAL,
290
291     OPC_LSA  = 0x05 | OPC_SPECIAL,
292     OPC_DLSA = 0x15 | OPC_SPECIAL,
293 };
294
295 /* Multiplication variants of the vr54xx. */
296 #define MASK_MUL_VR54XX(op)   MASK_SPECIAL(op) | (op & (0x1F << 6))
297
298 enum {
299     OPC_VR54XX_MULS    = (0x03 << 6) | OPC_MULT,
300     OPC_VR54XX_MULSU   = (0x03 << 6) | OPC_MULTU,
301     OPC_VR54XX_MACC    = (0x05 << 6) | OPC_MULT,
302     OPC_VR54XX_MACCU   = (0x05 << 6) | OPC_MULTU,
303     OPC_VR54XX_MSAC    = (0x07 << 6) | OPC_MULT,
304     OPC_VR54XX_MSACU   = (0x07 << 6) | OPC_MULTU,
305     OPC_VR54XX_MULHI   = (0x09 << 6) | OPC_MULT,
306     OPC_VR54XX_MULHIU  = (0x09 << 6) | OPC_MULTU,
307     OPC_VR54XX_MULSHI  = (0x0B << 6) | OPC_MULT,
308     OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
309     OPC_VR54XX_MACCHI  = (0x0D << 6) | OPC_MULT,
310     OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
311     OPC_VR54XX_MSACHI  = (0x0F << 6) | OPC_MULT,
312     OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
313 };
314
315 /* REGIMM (rt field) opcodes */
316 #define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
317
318 enum {
319     OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
320     OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
321     OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
322     OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
323     OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
324     OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
325     OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
326     OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
327     OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
328     OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
329     OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
330     OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
331     OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
332     OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
333     OPC_SIGRIE   = (0x17 << 16) | OPC_REGIMM,
334     OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
335
336     OPC_DAHI     = (0x06 << 16) | OPC_REGIMM,
337     OPC_DATI     = (0x1e << 16) | OPC_REGIMM,
338 };
339
340 /* Special2 opcodes */
341 #define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
342
343 enum {
344     /* Multiply & xxx operations */
345     OPC_MADD     = 0x00 | OPC_SPECIAL2,
346     OPC_MADDU    = 0x01 | OPC_SPECIAL2,
347     OPC_MUL      = 0x02 | OPC_SPECIAL2,
348     OPC_MSUB     = 0x04 | OPC_SPECIAL2,
349     OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
350     /* Loongson 2F */
351     OPC_MULT_G_2F   = 0x10 | OPC_SPECIAL2,
352     OPC_DMULT_G_2F  = 0x11 | OPC_SPECIAL2,
353     OPC_MULTU_G_2F  = 0x12 | OPC_SPECIAL2,
354     OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
355     OPC_DIV_G_2F    = 0x14 | OPC_SPECIAL2,
356     OPC_DDIV_G_2F   = 0x15 | OPC_SPECIAL2,
357     OPC_DIVU_G_2F   = 0x16 | OPC_SPECIAL2,
358     OPC_DDIVU_G_2F  = 0x17 | OPC_SPECIAL2,
359     OPC_MOD_G_2F    = 0x1c | OPC_SPECIAL2,
360     OPC_DMOD_G_2F   = 0x1d | OPC_SPECIAL2,
361     OPC_MODU_G_2F   = 0x1e | OPC_SPECIAL2,
362     OPC_DMODU_G_2F  = 0x1f | OPC_SPECIAL2,
363     /* Misc */
364     OPC_CLZ      = 0x20 | OPC_SPECIAL2,
365     OPC_CLO      = 0x21 | OPC_SPECIAL2,
366     OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
367     OPC_DCLO     = 0x25 | OPC_SPECIAL2,
368     /* Special */
369     OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
370 };
371
372 /* Special3 opcodes */
373 #define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
374
375 enum {
376     OPC_EXT      = 0x00 | OPC_SPECIAL3,
377     OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
378     OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
379     OPC_DEXT     = 0x03 | OPC_SPECIAL3,
380     OPC_INS      = 0x04 | OPC_SPECIAL3,
381     OPC_DINSM    = 0x05 | OPC_SPECIAL3,
382     OPC_DINSU    = 0x06 | OPC_SPECIAL3,
383     OPC_DINS     = 0x07 | OPC_SPECIAL3,
384     OPC_FORK     = 0x08 | OPC_SPECIAL3,
385     OPC_YIELD    = 0x09 | OPC_SPECIAL3,
386     OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
387     OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
388     OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
389
390     /* Loongson 2E */
391     OPC_MULT_G_2E   = 0x18 | OPC_SPECIAL3,
392     OPC_MULTU_G_2E  = 0x19 | OPC_SPECIAL3,
393     OPC_DIV_G_2E    = 0x1A | OPC_SPECIAL3,
394     OPC_DIVU_G_2E   = 0x1B | OPC_SPECIAL3,
395     OPC_DMULT_G_2E  = 0x1C | OPC_SPECIAL3,
396     OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
397     OPC_DDIV_G_2E   = 0x1E | OPC_SPECIAL3,
398     OPC_DDIVU_G_2E  = 0x1F | OPC_SPECIAL3,
399     OPC_MOD_G_2E    = 0x22 | OPC_SPECIAL3,
400     OPC_MODU_G_2E   = 0x23 | OPC_SPECIAL3,
401     OPC_DMOD_G_2E   = 0x26 | OPC_SPECIAL3,
402     OPC_DMODU_G_2E  = 0x27 | OPC_SPECIAL3,
403
404     /* MIPS DSP Load */
405     OPC_LX_DSP         = 0x0A | OPC_SPECIAL3,
406     /* MIPS DSP Arithmetic */
407     OPC_ADDU_QB_DSP    = 0x10 | OPC_SPECIAL3,
408     OPC_ADDU_OB_DSP    = 0x14 | OPC_SPECIAL3,
409     OPC_ABSQ_S_PH_DSP  = 0x12 | OPC_SPECIAL3,
410     OPC_ABSQ_S_QH_DSP  = 0x16 | OPC_SPECIAL3,
411     /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E.  */
412     /* OPC_ADDUH_QB_DSP   = 0x18 | OPC_SPECIAL3,  */
413     OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
414     OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
415     /* MIPS DSP GPR-Based Shift Sub-class */
416     OPC_SHLL_QB_DSP    = 0x13 | OPC_SPECIAL3,
417     OPC_SHLL_OB_DSP    = 0x17 | OPC_SPECIAL3,
418     /* MIPS DSP Multiply Sub-class insns */
419     /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP.  */
420     /* OPC_MUL_PH_DSP     = 0x18 | OPC_SPECIAL3,  */
421     OPC_DPA_W_PH_DSP   = 0x30 | OPC_SPECIAL3,
422     OPC_DPAQ_W_QH_DSP  = 0x34 | OPC_SPECIAL3,
423     /* DSP Bit/Manipulation Sub-class */
424     OPC_INSV_DSP       = 0x0C | OPC_SPECIAL3,
425     OPC_DINSV_DSP      = 0x0D | OPC_SPECIAL3,
426     /* MIPS DSP Append Sub-class */
427     OPC_APPEND_DSP     = 0x31 | OPC_SPECIAL3,
428     OPC_DAPPEND_DSP    = 0x35 | OPC_SPECIAL3,
429     /* MIPS DSP Accumulator and DSPControl Access Sub-class */
430     OPC_EXTR_W_DSP     = 0x38 | OPC_SPECIAL3,
431     OPC_DEXTR_W_DSP    = 0x3C | OPC_SPECIAL3,
432
433     /* EVA */
434     OPC_LWLE           = 0x19 | OPC_SPECIAL3,
435     OPC_LWRE           = 0x1A | OPC_SPECIAL3,
436     OPC_CACHEE         = 0x1B | OPC_SPECIAL3,
437     OPC_SBE            = 0x1C | OPC_SPECIAL3,
438     OPC_SHE            = 0x1D | OPC_SPECIAL3,
439     OPC_SCE            = 0x1E | OPC_SPECIAL3,
440     OPC_SWE            = 0x1F | OPC_SPECIAL3,
441     OPC_SWLE           = 0x21 | OPC_SPECIAL3,
442     OPC_SWRE           = 0x22 | OPC_SPECIAL3,
443     OPC_PREFE          = 0x23 | OPC_SPECIAL3,
444     OPC_LBUE           = 0x28 | OPC_SPECIAL3,
445     OPC_LHUE           = 0x29 | OPC_SPECIAL3,
446     OPC_LBE            = 0x2C | OPC_SPECIAL3,
447     OPC_LHE            = 0x2D | OPC_SPECIAL3,
448     OPC_LLE            = 0x2E | OPC_SPECIAL3,
449     OPC_LWE            = 0x2F | OPC_SPECIAL3,
450
451     /* R6 */
452     R6_OPC_PREF        = 0x35 | OPC_SPECIAL3,
453     R6_OPC_CACHE       = 0x25 | OPC_SPECIAL3,
454     R6_OPC_LL          = 0x36 | OPC_SPECIAL3,
455     R6_OPC_SC          = 0x26 | OPC_SPECIAL3,
456     R6_OPC_LLD         = 0x37 | OPC_SPECIAL3,
457     R6_OPC_SCD         = 0x27 | OPC_SPECIAL3,
458 };
459
460 /* BSHFL opcodes */
461 #define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
462
463 enum {
464     OPC_WSBH      = (0x02 << 6) | OPC_BSHFL,
465     OPC_SEB       = (0x10 << 6) | OPC_BSHFL,
466     OPC_SEH       = (0x18 << 6) | OPC_BSHFL,
467     OPC_ALIGN     = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */
468     OPC_ALIGN_1   = (0x09 << 6) | OPC_BSHFL,
469     OPC_ALIGN_2   = (0x0A << 6) | OPC_BSHFL,
470     OPC_ALIGN_3   = (0x0B << 6) | OPC_BSHFL,
471     OPC_BITSWAP   = (0x00 << 6) | OPC_BSHFL  /* 00000 */
472 };
473
474 /* DBSHFL opcodes */
475 #define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
476
477 enum {
478     OPC_DSBH       = (0x02 << 6) | OPC_DBSHFL,
479     OPC_DSHD       = (0x05 << 6) | OPC_DBSHFL,
480     OPC_DALIGN     = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */
481     OPC_DALIGN_1   = (0x09 << 6) | OPC_DBSHFL,
482     OPC_DALIGN_2   = (0x0A << 6) | OPC_DBSHFL,
483     OPC_DALIGN_3   = (0x0B << 6) | OPC_DBSHFL,
484     OPC_DALIGN_4   = (0x0C << 6) | OPC_DBSHFL,
485     OPC_DALIGN_5   = (0x0D << 6) | OPC_DBSHFL,
486     OPC_DALIGN_6   = (0x0E << 6) | OPC_DBSHFL,
487     OPC_DALIGN_7   = (0x0F << 6) | OPC_DBSHFL,
488     OPC_DBITSWAP   = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
489 };
490
491 /* MIPS DSP REGIMM opcodes */
492 enum {
493     OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
494     OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
495 };
496
497 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
498 /* MIPS DSP Load */
499 enum {
500     OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
501     OPC_LHX  = (0x04 << 6) | OPC_LX_DSP,
502     OPC_LWX  = (0x00 << 6) | OPC_LX_DSP,
503     OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
504 };
505
506 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
507 enum {
508     /* MIPS DSP Arithmetic Sub-class */
509     OPC_ADDQ_PH        = (0x0A << 6) | OPC_ADDU_QB_DSP,
510     OPC_ADDQ_S_PH      = (0x0E << 6) | OPC_ADDU_QB_DSP,
511     OPC_ADDQ_S_W       = (0x16 << 6) | OPC_ADDU_QB_DSP,
512     OPC_ADDU_QB        = (0x00 << 6) | OPC_ADDU_QB_DSP,
513     OPC_ADDU_S_QB      = (0x04 << 6) | OPC_ADDU_QB_DSP,
514     OPC_ADDU_PH        = (0x08 << 6) | OPC_ADDU_QB_DSP,
515     OPC_ADDU_S_PH      = (0x0C << 6) | OPC_ADDU_QB_DSP,
516     OPC_SUBQ_PH        = (0x0B << 6) | OPC_ADDU_QB_DSP,
517     OPC_SUBQ_S_PH      = (0x0F << 6) | OPC_ADDU_QB_DSP,
518     OPC_SUBQ_S_W       = (0x17 << 6) | OPC_ADDU_QB_DSP,
519     OPC_SUBU_QB        = (0x01 << 6) | OPC_ADDU_QB_DSP,
520     OPC_SUBU_S_QB      = (0x05 << 6) | OPC_ADDU_QB_DSP,
521     OPC_SUBU_PH        = (0x09 << 6) | OPC_ADDU_QB_DSP,
522     OPC_SUBU_S_PH      = (0x0D << 6) | OPC_ADDU_QB_DSP,
523     OPC_ADDSC          = (0x10 << 6) | OPC_ADDU_QB_DSP,
524     OPC_ADDWC          = (0x11 << 6) | OPC_ADDU_QB_DSP,
525     OPC_MODSUB         = (0x12 << 6) | OPC_ADDU_QB_DSP,
526     OPC_RADDU_W_QB     = (0x14 << 6) | OPC_ADDU_QB_DSP,
527     /* MIPS DSP Multiply Sub-class insns */
528     OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
529     OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
530     OPC_MULQ_RS_PH     = (0x1F << 6) | OPC_ADDU_QB_DSP,
531     OPC_MULEQ_S_W_PHL  = (0x1C << 6) | OPC_ADDU_QB_DSP,
532     OPC_MULEQ_S_W_PHR  = (0x1D << 6) | OPC_ADDU_QB_DSP,
533     OPC_MULQ_S_PH      = (0x1E << 6) | OPC_ADDU_QB_DSP,
534 };
535
536 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
537 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
538 enum {
539     /* MIPS DSP Arithmetic Sub-class */
540     OPC_ADDUH_QB   = (0x00 << 6) | OPC_ADDUH_QB_DSP,
541     OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
542     OPC_ADDQH_PH   = (0x08 << 6) | OPC_ADDUH_QB_DSP,
543     OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
544     OPC_ADDQH_W    = (0x10 << 6) | OPC_ADDUH_QB_DSP,
545     OPC_ADDQH_R_W  = (0x12 << 6) | OPC_ADDUH_QB_DSP,
546     OPC_SUBUH_QB   = (0x01 << 6) | OPC_ADDUH_QB_DSP,
547     OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
548     OPC_SUBQH_PH   = (0x09 << 6) | OPC_ADDUH_QB_DSP,
549     OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
550     OPC_SUBQH_W    = (0x11 << 6) | OPC_ADDUH_QB_DSP,
551     OPC_SUBQH_R_W  = (0x13 << 6) | OPC_ADDUH_QB_DSP,
552     /* MIPS DSP Multiply Sub-class insns */
553     OPC_MUL_PH     = (0x0C << 6) | OPC_ADDUH_QB_DSP,
554     OPC_MUL_S_PH   = (0x0E << 6) | OPC_ADDUH_QB_DSP,
555     OPC_MULQ_S_W   = (0x16 << 6) | OPC_ADDUH_QB_DSP,
556     OPC_MULQ_RS_W  = (0x17 << 6) | OPC_ADDUH_QB_DSP,
557 };
558
559 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
560 enum {
561     /* MIPS DSP Arithmetic Sub-class */
562     OPC_ABSQ_S_QB       = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
563     OPC_ABSQ_S_PH       = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
564     OPC_ABSQ_S_W        = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
565     OPC_PRECEQ_W_PHL    = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
566     OPC_PRECEQ_W_PHR    = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
567     OPC_PRECEQU_PH_QBL  = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
568     OPC_PRECEQU_PH_QBR  = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
569     OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
570     OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
571     OPC_PRECEU_PH_QBL   = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
572     OPC_PRECEU_PH_QBR   = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
573     OPC_PRECEU_PH_QBLA  = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
574     OPC_PRECEU_PH_QBRA  = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
575     /* DSP Bit/Manipulation Sub-class */
576     OPC_BITREV          = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
577     OPC_REPL_QB         = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
578     OPC_REPLV_QB        = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
579     OPC_REPL_PH         = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
580     OPC_REPLV_PH        = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
581 };
582
583 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
584 enum {
585     /* MIPS DSP Arithmetic Sub-class */
586     OPC_PRECR_QB_PH      = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
587     OPC_PRECRQ_QB_PH     = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
588     OPC_PRECR_SRA_PH_W   = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
589     OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
590     OPC_PRECRQ_PH_W      = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
591     OPC_PRECRQ_RS_PH_W   = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
592     OPC_PRECRQU_S_QB_PH  = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
593     /* DSP Compare-Pick Sub-class */
594     OPC_CMPU_EQ_QB       = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
595     OPC_CMPU_LT_QB       = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
596     OPC_CMPU_LE_QB       = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
597     OPC_CMPGU_EQ_QB      = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
598     OPC_CMPGU_LT_QB      = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
599     OPC_CMPGU_LE_QB      = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
600     OPC_CMPGDU_EQ_QB     = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
601     OPC_CMPGDU_LT_QB     = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
602     OPC_CMPGDU_LE_QB     = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
603     OPC_CMP_EQ_PH        = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
604     OPC_CMP_LT_PH        = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
605     OPC_CMP_LE_PH        = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
606     OPC_PICK_QB          = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
607     OPC_PICK_PH          = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
608     OPC_PACKRL_PH        = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
609 };
610
611 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
612 enum {
613     /* MIPS DSP GPR-Based Shift Sub-class */
614     OPC_SHLL_QB    = (0x00 << 6) | OPC_SHLL_QB_DSP,
615     OPC_SHLLV_QB   = (0x02 << 6) | OPC_SHLL_QB_DSP,
616     OPC_SHLL_PH    = (0x08 << 6) | OPC_SHLL_QB_DSP,
617     OPC_SHLLV_PH   = (0x0A << 6) | OPC_SHLL_QB_DSP,
618     OPC_SHLL_S_PH  = (0x0C << 6) | OPC_SHLL_QB_DSP,
619     OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
620     OPC_SHLL_S_W   = (0x14 << 6) | OPC_SHLL_QB_DSP,
621     OPC_SHLLV_S_W  = (0x16 << 6) | OPC_SHLL_QB_DSP,
622     OPC_SHRL_QB    = (0x01 << 6) | OPC_SHLL_QB_DSP,
623     OPC_SHRLV_QB   = (0x03 << 6) | OPC_SHLL_QB_DSP,
624     OPC_SHRL_PH    = (0x19 << 6) | OPC_SHLL_QB_DSP,
625     OPC_SHRLV_PH   = (0x1B << 6) | OPC_SHLL_QB_DSP,
626     OPC_SHRA_QB    = (0x04 << 6) | OPC_SHLL_QB_DSP,
627     OPC_SHRA_R_QB  = (0x05 << 6) | OPC_SHLL_QB_DSP,
628     OPC_SHRAV_QB   = (0x06 << 6) | OPC_SHLL_QB_DSP,
629     OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
630     OPC_SHRA_PH    = (0x09 << 6) | OPC_SHLL_QB_DSP,
631     OPC_SHRAV_PH   = (0x0B << 6) | OPC_SHLL_QB_DSP,
632     OPC_SHRA_R_PH  = (0x0D << 6) | OPC_SHLL_QB_DSP,
633     OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
634     OPC_SHRA_R_W   = (0x15 << 6) | OPC_SHLL_QB_DSP,
635     OPC_SHRAV_R_W  = (0x17 << 6) | OPC_SHLL_QB_DSP,
636 };
637
638 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
639 enum {
640     /* MIPS DSP Multiply Sub-class insns */
641     OPC_DPAU_H_QBL    = (0x03 << 6) | OPC_DPA_W_PH_DSP,
642     OPC_DPAU_H_QBR    = (0x07 << 6) | OPC_DPA_W_PH_DSP,
643     OPC_DPSU_H_QBL    = (0x0B << 6) | OPC_DPA_W_PH_DSP,
644     OPC_DPSU_H_QBR    = (0x0F << 6) | OPC_DPA_W_PH_DSP,
645     OPC_DPA_W_PH      = (0x00 << 6) | OPC_DPA_W_PH_DSP,
646     OPC_DPAX_W_PH     = (0x08 << 6) | OPC_DPA_W_PH_DSP,
647     OPC_DPAQ_S_W_PH   = (0x04 << 6) | OPC_DPA_W_PH_DSP,
648     OPC_DPAQX_S_W_PH  = (0x18 << 6) | OPC_DPA_W_PH_DSP,
649     OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
650     OPC_DPS_W_PH      = (0x01 << 6) | OPC_DPA_W_PH_DSP,
651     OPC_DPSX_W_PH     = (0x09 << 6) | OPC_DPA_W_PH_DSP,
652     OPC_DPSQ_S_W_PH   = (0x05 << 6) | OPC_DPA_W_PH_DSP,
653     OPC_DPSQX_S_W_PH  = (0x19 << 6) | OPC_DPA_W_PH_DSP,
654     OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
655     OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
656     OPC_DPAQ_SA_L_W   = (0x0C << 6) | OPC_DPA_W_PH_DSP,
657     OPC_DPSQ_SA_L_W   = (0x0D << 6) | OPC_DPA_W_PH_DSP,
658     OPC_MAQ_S_W_PHL   = (0x14 << 6) | OPC_DPA_W_PH_DSP,
659     OPC_MAQ_S_W_PHR   = (0x16 << 6) | OPC_DPA_W_PH_DSP,
660     OPC_MAQ_SA_W_PHL  = (0x10 << 6) | OPC_DPA_W_PH_DSP,
661     OPC_MAQ_SA_W_PHR  = (0x12 << 6) | OPC_DPA_W_PH_DSP,
662     OPC_MULSA_W_PH    = (0x02 << 6) | OPC_DPA_W_PH_DSP,
663 };
664
665 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
666 enum {
667     /* DSP Bit/Manipulation Sub-class */
668     OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
669 };
670
671 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
672 enum {
673     /* MIPS DSP Append Sub-class */
674     OPC_APPEND  = (0x00 << 6) | OPC_APPEND_DSP,
675     OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
676     OPC_BALIGN  = (0x10 << 6) | OPC_APPEND_DSP,
677 };
678
679 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
680 enum {
681     /* MIPS DSP Accumulator and DSPControl Access Sub-class */
682     OPC_EXTR_W     = (0x00 << 6) | OPC_EXTR_W_DSP,
683     OPC_EXTR_R_W   = (0x04 << 6) | OPC_EXTR_W_DSP,
684     OPC_EXTR_RS_W  = (0x06 << 6) | OPC_EXTR_W_DSP,
685     OPC_EXTR_S_H   = (0x0E << 6) | OPC_EXTR_W_DSP,
686     OPC_EXTRV_S_H  = (0x0F << 6) | OPC_EXTR_W_DSP,
687     OPC_EXTRV_W    = (0x01 << 6) | OPC_EXTR_W_DSP,
688     OPC_EXTRV_R_W  = (0x05 << 6) | OPC_EXTR_W_DSP,
689     OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
690     OPC_EXTP       = (0x02 << 6) | OPC_EXTR_W_DSP,
691     OPC_EXTPV      = (0x03 << 6) | OPC_EXTR_W_DSP,
692     OPC_EXTPDP     = (0x0A << 6) | OPC_EXTR_W_DSP,
693     OPC_EXTPDPV    = (0x0B << 6) | OPC_EXTR_W_DSP,
694     OPC_SHILO      = (0x1A << 6) | OPC_EXTR_W_DSP,
695     OPC_SHILOV     = (0x1B << 6) | OPC_EXTR_W_DSP,
696     OPC_MTHLIP     = (0x1F << 6) | OPC_EXTR_W_DSP,
697     OPC_WRDSP      = (0x13 << 6) | OPC_EXTR_W_DSP,
698     OPC_RDDSP      = (0x12 << 6) | OPC_EXTR_W_DSP,
699 };
700
701 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
702 enum {
703     /* MIPS DSP Arithmetic Sub-class */
704     OPC_PRECEQ_L_PWL    = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
705     OPC_PRECEQ_L_PWR    = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
706     OPC_PRECEQ_PW_QHL   = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
707     OPC_PRECEQ_PW_QHR   = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
708     OPC_PRECEQ_PW_QHLA  = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
709     OPC_PRECEQ_PW_QHRA  = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
710     OPC_PRECEQU_QH_OBL  = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
711     OPC_PRECEQU_QH_OBR  = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
712     OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
713     OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
714     OPC_PRECEU_QH_OBL   = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
715     OPC_PRECEU_QH_OBR   = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
716     OPC_PRECEU_QH_OBLA  = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
717     OPC_PRECEU_QH_OBRA  = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
718     OPC_ABSQ_S_OB       = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
719     OPC_ABSQ_S_PW       = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
720     OPC_ABSQ_S_QH       = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
721     /* DSP Bit/Manipulation Sub-class */
722     OPC_REPL_OB         = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
723     OPC_REPL_PW         = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
724     OPC_REPL_QH         = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
725     OPC_REPLV_OB        = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
726     OPC_REPLV_PW        = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
727     OPC_REPLV_QH        = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
728 };
729
730 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
731 enum {
732     /* MIPS DSP Multiply Sub-class insns */
733     OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
734     OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
735     OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
736     OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
737     OPC_MULQ_RS_QH     = (0x1F << 6) | OPC_ADDU_OB_DSP,
738     /* MIPS DSP Arithmetic Sub-class */
739     OPC_RADDU_L_OB     = (0x14 << 6) | OPC_ADDU_OB_DSP,
740     OPC_SUBQ_PW        = (0x13 << 6) | OPC_ADDU_OB_DSP,
741     OPC_SUBQ_S_PW      = (0x17 << 6) | OPC_ADDU_OB_DSP,
742     OPC_SUBQ_QH        = (0x0B << 6) | OPC_ADDU_OB_DSP,
743     OPC_SUBQ_S_QH      = (0x0F << 6) | OPC_ADDU_OB_DSP,
744     OPC_SUBU_OB        = (0x01 << 6) | OPC_ADDU_OB_DSP,
745     OPC_SUBU_S_OB      = (0x05 << 6) | OPC_ADDU_OB_DSP,
746     OPC_SUBU_QH        = (0x09 << 6) | OPC_ADDU_OB_DSP,
747     OPC_SUBU_S_QH      = (0x0D << 6) | OPC_ADDU_OB_DSP,
748     OPC_SUBUH_OB       = (0x19 << 6) | OPC_ADDU_OB_DSP,
749     OPC_SUBUH_R_OB     = (0x1B << 6) | OPC_ADDU_OB_DSP,
750     OPC_ADDQ_PW        = (0x12 << 6) | OPC_ADDU_OB_DSP,
751     OPC_ADDQ_S_PW      = (0x16 << 6) | OPC_ADDU_OB_DSP,
752     OPC_ADDQ_QH        = (0x0A << 6) | OPC_ADDU_OB_DSP,
753     OPC_ADDQ_S_QH      = (0x0E << 6) | OPC_ADDU_OB_DSP,
754     OPC_ADDU_OB        = (0x00 << 6) | OPC_ADDU_OB_DSP,
755     OPC_ADDU_S_OB      = (0x04 << 6) | OPC_ADDU_OB_DSP,
756     OPC_ADDU_QH        = (0x08 << 6) | OPC_ADDU_OB_DSP,
757     OPC_ADDU_S_QH      = (0x0C << 6) | OPC_ADDU_OB_DSP,
758     OPC_ADDUH_OB       = (0x18 << 6) | OPC_ADDU_OB_DSP,
759     OPC_ADDUH_R_OB     = (0x1A << 6) | OPC_ADDU_OB_DSP,
760 };
761
762 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
763 enum {
764     /* DSP Compare-Pick Sub-class */
765     OPC_CMP_EQ_PW         = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
766     OPC_CMP_LT_PW         = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
767     OPC_CMP_LE_PW         = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
768     OPC_CMP_EQ_QH         = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
769     OPC_CMP_LT_QH         = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
770     OPC_CMP_LE_QH         = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
771     OPC_CMPGDU_EQ_OB      = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
772     OPC_CMPGDU_LT_OB      = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
773     OPC_CMPGDU_LE_OB      = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
774     OPC_CMPGU_EQ_OB       = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
775     OPC_CMPGU_LT_OB       = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
776     OPC_CMPGU_LE_OB       = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
777     OPC_CMPU_EQ_OB        = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
778     OPC_CMPU_LT_OB        = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
779     OPC_CMPU_LE_OB        = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
780     OPC_PACKRL_PW         = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
781     OPC_PICK_OB           = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
782     OPC_PICK_PW           = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
783     OPC_PICK_QH           = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
784     /* MIPS DSP Arithmetic Sub-class */
785     OPC_PRECR_OB_QH       = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
786     OPC_PRECR_SRA_QH_PW   = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
787     OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
788     OPC_PRECRQ_OB_QH      = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
789     OPC_PRECRQ_PW_L       = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
790     OPC_PRECRQ_QH_PW      = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
791     OPC_PRECRQ_RS_QH_PW   = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
792     OPC_PRECRQU_S_OB_QH   = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
793 };
794
795 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
796 enum {
797     /* DSP Append Sub-class */
798     OPC_DAPPEND  = (0x00 << 6) | OPC_DAPPEND_DSP,
799     OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
800     OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
801     OPC_DBALIGN  = (0x10 << 6) | OPC_DAPPEND_DSP,
802 };
803
804 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
805 enum {
806     /* MIPS DSP Accumulator and DSPControl Access Sub-class */
807     OPC_DMTHLIP     = (0x1F << 6) | OPC_DEXTR_W_DSP,
808     OPC_DSHILO      = (0x1A << 6) | OPC_DEXTR_W_DSP,
809     OPC_DEXTP       = (0x02 << 6) | OPC_DEXTR_W_DSP,
810     OPC_DEXTPDP     = (0x0A << 6) | OPC_DEXTR_W_DSP,
811     OPC_DEXTPDPV    = (0x0B << 6) | OPC_DEXTR_W_DSP,
812     OPC_DEXTPV      = (0x03 << 6) | OPC_DEXTR_W_DSP,
813     OPC_DEXTR_L     = (0x10 << 6) | OPC_DEXTR_W_DSP,
814     OPC_DEXTR_R_L   = (0x14 << 6) | OPC_DEXTR_W_DSP,
815     OPC_DEXTR_RS_L  = (0x16 << 6) | OPC_DEXTR_W_DSP,
816     OPC_DEXTR_W     = (0x00 << 6) | OPC_DEXTR_W_DSP,
817     OPC_DEXTR_R_W   = (0x04 << 6) | OPC_DEXTR_W_DSP,
818     OPC_DEXTR_RS_W  = (0x06 << 6) | OPC_DEXTR_W_DSP,
819     OPC_DEXTR_S_H   = (0x0E << 6) | OPC_DEXTR_W_DSP,
820     OPC_DEXTRV_L    = (0x11 << 6) | OPC_DEXTR_W_DSP,
821     OPC_DEXTRV_R_L  = (0x15 << 6) | OPC_DEXTR_W_DSP,
822     OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
823     OPC_DEXTRV_S_H  = (0x0F << 6) | OPC_DEXTR_W_DSP,
824     OPC_DEXTRV_W    = (0x01 << 6) | OPC_DEXTR_W_DSP,
825     OPC_DEXTRV_R_W  = (0x05 << 6) | OPC_DEXTR_W_DSP,
826     OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
827     OPC_DSHILOV     = (0x1B << 6) | OPC_DEXTR_W_DSP,
828 };
829
830 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
831 enum {
832     /* DSP Bit/Manipulation Sub-class */
833     OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
834 };
835
836 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
837 enum {
838     /* MIPS DSP Multiply Sub-class insns */
839     OPC_DMADD         = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
840     OPC_DMADDU        = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
841     OPC_DMSUB         = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
842     OPC_DMSUBU        = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
843     OPC_DPA_W_QH      = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
844     OPC_DPAQ_S_W_QH   = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
845     OPC_DPAQ_SA_L_PW  = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
846     OPC_DPAU_H_OBL    = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
847     OPC_DPAU_H_OBR    = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
848     OPC_DPS_W_QH      = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
849     OPC_DPSQ_S_W_QH   = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
850     OPC_DPSQ_SA_L_PW  = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
851     OPC_DPSU_H_OBL    = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
852     OPC_DPSU_H_OBR    = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
853     OPC_MAQ_S_L_PWL   = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
854     OPC_MAQ_S_L_PWR   = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
855     OPC_MAQ_S_W_QHLL  = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
856     OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
857     OPC_MAQ_S_W_QHLR  = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
858     OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
859     OPC_MAQ_S_W_QHRL  = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
860     OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
861     OPC_MAQ_S_W_QHRR  = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
862     OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
863     OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
864     OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
865 };
866
867 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
868 enum {
869     /* MIPS DSP GPR-Based Shift Sub-class */
870     OPC_SHLL_PW    = (0x10 << 6) | OPC_SHLL_OB_DSP,
871     OPC_SHLL_S_PW  = (0x14 << 6) | OPC_SHLL_OB_DSP,
872     OPC_SHLLV_OB   = (0x02 << 6) | OPC_SHLL_OB_DSP,
873     OPC_SHLLV_PW   = (0x12 << 6) | OPC_SHLL_OB_DSP,
874     OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
875     OPC_SHLLV_QH   = (0x0A << 6) | OPC_SHLL_OB_DSP,
876     OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
877     OPC_SHRA_PW    = (0x11 << 6) | OPC_SHLL_OB_DSP,
878     OPC_SHRA_R_PW  = (0x15 << 6) | OPC_SHLL_OB_DSP,
879     OPC_SHRAV_OB   = (0x06 << 6) | OPC_SHLL_OB_DSP,
880     OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
881     OPC_SHRAV_PW   = (0x13 << 6) | OPC_SHLL_OB_DSP,
882     OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
883     OPC_SHRAV_QH   = (0x0B << 6) | OPC_SHLL_OB_DSP,
884     OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
885     OPC_SHRLV_OB   = (0x03 << 6) | OPC_SHLL_OB_DSP,
886     OPC_SHRLV_QH   = (0x1B << 6) | OPC_SHLL_OB_DSP,
887     OPC_SHLL_OB    = (0x00 << 6) | OPC_SHLL_OB_DSP,
888     OPC_SHLL_QH    = (0x08 << 6) | OPC_SHLL_OB_DSP,
889     OPC_SHLL_S_QH  = (0x0C << 6) | OPC_SHLL_OB_DSP,
890     OPC_SHRA_OB    = (0x04 << 6) | OPC_SHLL_OB_DSP,
891     OPC_SHRA_R_OB  = (0x05 << 6) | OPC_SHLL_OB_DSP,
892     OPC_SHRA_QH    = (0x09 << 6) | OPC_SHLL_OB_DSP,
893     OPC_SHRA_R_QH  = (0x0D << 6) | OPC_SHLL_OB_DSP,
894     OPC_SHRL_OB    = (0x01 << 6) | OPC_SHLL_OB_DSP,
895     OPC_SHRL_QH    = (0x19 << 6) | OPC_SHLL_OB_DSP,
896 };
897
898 /* Coprocessor 0 (rs field) */
899 #define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
900
901 enum {
902     OPC_MFC0     = (0x00 << 21) | OPC_CP0,
903     OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
904     OPC_MFHC0    = (0x02 << 21) | OPC_CP0,
905     OPC_MTC0     = (0x04 << 21) | OPC_CP0,
906     OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
907     OPC_MTHC0    = (0x06 << 21) | OPC_CP0,
908     OPC_MFTR     = (0x08 << 21) | OPC_CP0,
909     OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
910     OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
911     OPC_MTTR     = (0x0C << 21) | OPC_CP0,
912     OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
913     OPC_C0       = (0x10 << 21) | OPC_CP0,
914     OPC_C0_1     = (0x11 << 21) | OPC_CP0,
915     OPC_C0_2     = (0x12 << 21) | OPC_CP0,
916     OPC_C0_3     = (0x13 << 21) | OPC_CP0,
917     OPC_C0_4     = (0x14 << 21) | OPC_CP0,
918     OPC_C0_5     = (0x15 << 21) | OPC_CP0,
919     OPC_C0_6     = (0x16 << 21) | OPC_CP0,
920     OPC_C0_7     = (0x17 << 21) | OPC_CP0,
921     OPC_C0_8     = (0x18 << 21) | OPC_CP0,
922     OPC_C0_9     = (0x19 << 21) | OPC_CP0,
923     OPC_C0_A     = (0x1A << 21) | OPC_CP0,
924     OPC_C0_B     = (0x1B << 21) | OPC_CP0,
925     OPC_C0_C     = (0x1C << 21) | OPC_CP0,
926     OPC_C0_D     = (0x1D << 21) | OPC_CP0,
927     OPC_C0_E     = (0x1E << 21) | OPC_CP0,
928     OPC_C0_F     = (0x1F << 21) | OPC_CP0,
929 };
930
931 /* MFMC0 opcodes */
932 #define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
933
934 enum {
935     OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
936     OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
937     OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
938     OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
939     OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
940     OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
941     OPC_DVP      = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
942     OPC_EVP      = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
943 };
944
945 /* Coprocessor 0 (with rs == C0) */
946 #define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
947
948 enum {
949     OPC_TLBR     = 0x01 | OPC_C0,
950     OPC_TLBWI    = 0x02 | OPC_C0,
951     OPC_TLBINV   = 0x03 | OPC_C0,
952     OPC_TLBINVF  = 0x04 | OPC_C0,
953     OPC_TLBWR    = 0x06 | OPC_C0,
954     OPC_TLBP     = 0x08 | OPC_C0,
955     OPC_RFE      = 0x10 | OPC_C0,
956     OPC_ERET     = 0x18 | OPC_C0,
957     OPC_DERET    = 0x1F | OPC_C0,
958     OPC_WAIT     = 0x20 | OPC_C0,
959 };
960
961 /* Coprocessor 1 (rs field) */
962 #define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
963
964 /* Values for the fmt field in FP instructions */
965 enum {
966     /* 0 - 15 are reserved */
967     FMT_S = 16,          /* single fp */
968     FMT_D = 17,          /* double fp */
969     FMT_E = 18,          /* extended fp */
970     FMT_Q = 19,          /* quad fp */
971     FMT_W = 20,          /* 32-bit fixed */
972     FMT_L = 21,          /* 64-bit fixed */
973     FMT_PS = 22,         /* paired single fp */
974     /* 23 - 31 are reserved */
975 };
976
977 enum {
978     OPC_MFC1     = (0x00 << 21) | OPC_CP1,
979     OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
980     OPC_CFC1     = (0x02 << 21) | OPC_CP1,
981     OPC_MFHC1    = (0x03 << 21) | OPC_CP1,
982     OPC_MTC1     = (0x04 << 21) | OPC_CP1,
983     OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
984     OPC_CTC1     = (0x06 << 21) | OPC_CP1,
985     OPC_MTHC1    = (0x07 << 21) | OPC_CP1,
986     OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
987     OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
988     OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
989     OPC_BZ_V     = (0x0B << 21) | OPC_CP1,
990     OPC_BNZ_V    = (0x0F << 21) | OPC_CP1,
991     OPC_S_FMT    = (FMT_S << 21) | OPC_CP1,
992     OPC_D_FMT    = (FMT_D << 21) | OPC_CP1,
993     OPC_E_FMT    = (FMT_E << 21) | OPC_CP1,
994     OPC_Q_FMT    = (FMT_Q << 21) | OPC_CP1,
995     OPC_W_FMT    = (FMT_W << 21) | OPC_CP1,
996     OPC_L_FMT    = (FMT_L << 21) | OPC_CP1,
997     OPC_PS_FMT   = (FMT_PS << 21) | OPC_CP1,
998     OPC_BC1EQZ   = (0x09 << 21) | OPC_CP1,
999     OPC_BC1NEZ   = (0x0D << 21) | OPC_CP1,
1000     OPC_BZ_B     = (0x18 << 21) | OPC_CP1,
1001     OPC_BZ_H     = (0x19 << 21) | OPC_CP1,
1002     OPC_BZ_W     = (0x1A << 21) | OPC_CP1,
1003     OPC_BZ_D     = (0x1B << 21) | OPC_CP1,
1004     OPC_BNZ_B    = (0x1C << 21) | OPC_CP1,
1005     OPC_BNZ_H    = (0x1D << 21) | OPC_CP1,
1006     OPC_BNZ_W    = (0x1E << 21) | OPC_CP1,
1007     OPC_BNZ_D    = (0x1F << 21) | OPC_CP1,
1008 };
1009
1010 #define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
1011 #define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
1012
1013 enum {
1014     OPC_BC1F     = (0x00 << 16) | OPC_BC1,
1015     OPC_BC1T     = (0x01 << 16) | OPC_BC1,
1016     OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
1017     OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
1018 };
1019
1020 enum {
1021     OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
1022     OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
1023 };
1024
1025 enum {
1026     OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
1027     OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
1028 };
1029
1030 #define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
1031
1032 enum {
1033     OPC_MFC2    = (0x00 << 21) | OPC_CP2,
1034     OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
1035     OPC_CFC2    = (0x02 << 21) | OPC_CP2,
1036     OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
1037     OPC_MTC2    = (0x04 << 21) | OPC_CP2,
1038     OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
1039     OPC_CTC2    = (0x06 << 21) | OPC_CP2,
1040     OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
1041     OPC_BC2     = (0x08 << 21) | OPC_CP2,
1042     OPC_BC2EQZ  = (0x09 << 21) | OPC_CP2,
1043     OPC_BC2NEZ  = (0x0D << 21) | OPC_CP2,
1044 };
1045
1046 #define MASK_LMI(op)  (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1047
1048 enum {
1049     OPC_PADDSH  = (24 << 21) | (0x00) | OPC_CP2,
1050     OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1051     OPC_PADDH   = (26 << 21) | (0x00) | OPC_CP2,
1052     OPC_PADDW   = (27 << 21) | (0x00) | OPC_CP2,
1053     OPC_PADDSB  = (28 << 21) | (0x00) | OPC_CP2,
1054     OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1055     OPC_PADDB   = (30 << 21) | (0x00) | OPC_CP2,
1056     OPC_PADDD   = (31 << 21) | (0x00) | OPC_CP2,
1057
1058     OPC_PSUBSH  = (24 << 21) | (0x01) | OPC_CP2,
1059     OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1060     OPC_PSUBH   = (26 << 21) | (0x01) | OPC_CP2,
1061     OPC_PSUBW   = (27 << 21) | (0x01) | OPC_CP2,
1062     OPC_PSUBSB  = (28 << 21) | (0x01) | OPC_CP2,
1063     OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1064     OPC_PSUBB   = (30 << 21) | (0x01) | OPC_CP2,
1065     OPC_PSUBD   = (31 << 21) | (0x01) | OPC_CP2,
1066
1067     OPC_PSHUFH   = (24 << 21) | (0x02) | OPC_CP2,
1068     OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1069     OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1070     OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1071     OPC_XOR_CP2  = (28 << 21) | (0x02) | OPC_CP2,
1072     OPC_NOR_CP2  = (29 << 21) | (0x02) | OPC_CP2,
1073     OPC_AND_CP2  = (30 << 21) | (0x02) | OPC_CP2,
1074     OPC_PANDN    = (31 << 21) | (0x02) | OPC_CP2,
1075
1076     OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1077     OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1078     OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1079     OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1080     OPC_PINSRH_0  = (28 << 21) | (0x03) | OPC_CP2,
1081     OPC_PINSRH_1  = (29 << 21) | (0x03) | OPC_CP2,
1082     OPC_PINSRH_2  = (30 << 21) | (0x03) | OPC_CP2,
1083     OPC_PINSRH_3  = (31 << 21) | (0x03) | OPC_CP2,
1084
1085     OPC_PAVGH   = (24 << 21) | (0x08) | OPC_CP2,
1086     OPC_PAVGB   = (25 << 21) | (0x08) | OPC_CP2,
1087     OPC_PMAXSH  = (26 << 21) | (0x08) | OPC_CP2,
1088     OPC_PMINSH  = (27 << 21) | (0x08) | OPC_CP2,
1089     OPC_PMAXUB  = (28 << 21) | (0x08) | OPC_CP2,
1090     OPC_PMINUB  = (29 << 21) | (0x08) | OPC_CP2,
1091
1092     OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1093     OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1094     OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1095     OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1096     OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1097     OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1098
1099     OPC_PSLLW   = (24 << 21) | (0x0A) | OPC_CP2,
1100     OPC_PSLLH   = (25 << 21) | (0x0A) | OPC_CP2,
1101     OPC_PMULLH  = (26 << 21) | (0x0A) | OPC_CP2,
1102     OPC_PMULHH  = (27 << 21) | (0x0A) | OPC_CP2,
1103     OPC_PMULUW  = (28 << 21) | (0x0A) | OPC_CP2,
1104     OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1105
1106     OPC_PSRLW     = (24 << 21) | (0x0B) | OPC_CP2,
1107     OPC_PSRLH     = (25 << 21) | (0x0B) | OPC_CP2,
1108     OPC_PSRAW     = (26 << 21) | (0x0B) | OPC_CP2,
1109     OPC_PSRAH     = (27 << 21) | (0x0B) | OPC_CP2,
1110     OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1111     OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1112
1113     OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1114     OPC_OR_CP2   = (25 << 21) | (0x0C) | OPC_CP2,
1115     OPC_ADD_CP2  = (26 << 21) | (0x0C) | OPC_CP2,
1116     OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1117     OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1118     OPC_SEQ_CP2  = (29 << 21) | (0x0C) | OPC_CP2,
1119
1120     OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1121     OPC_PASUBUB  = (25 << 21) | (0x0D) | OPC_CP2,
1122     OPC_SUB_CP2  = (26 << 21) | (0x0D) | OPC_CP2,
1123     OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1124     OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1125     OPC_SLT_CP2  = (29 << 21) | (0x0D) | OPC_CP2,
1126
1127     OPC_SLL_CP2  = (24 << 21) | (0x0E) | OPC_CP2,
1128     OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1129     OPC_PEXTRH   = (26 << 21) | (0x0E) | OPC_CP2,
1130     OPC_PMADDHW  = (27 << 21) | (0x0E) | OPC_CP2,
1131     OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1132     OPC_SLE_CP2  = (29 << 21) | (0x0E) | OPC_CP2,
1133
1134     OPC_SRL_CP2  = (24 << 21) | (0x0F) | OPC_CP2,
1135     OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1136     OPC_SRA_CP2  = (26 << 21) | (0x0F) | OPC_CP2,
1137     OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1138     OPC_BIADD    = (28 << 21) | (0x0F) | OPC_CP2,
1139     OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1140 };
1141
1142
1143 #define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
1144
1145 enum {
1146     OPC_LWXC1   = 0x00 | OPC_CP3,
1147     OPC_LDXC1   = 0x01 | OPC_CP3,
1148     OPC_LUXC1   = 0x05 | OPC_CP3,
1149     OPC_SWXC1   = 0x08 | OPC_CP3,
1150     OPC_SDXC1   = 0x09 | OPC_CP3,
1151     OPC_SUXC1   = 0x0D | OPC_CP3,
1152     OPC_PREFX   = 0x0F | OPC_CP3,
1153     OPC_ALNV_PS = 0x1E | OPC_CP3,
1154     OPC_MADD_S  = 0x20 | OPC_CP3,
1155     OPC_MADD_D  = 0x21 | OPC_CP3,
1156     OPC_MADD_PS = 0x26 | OPC_CP3,
1157     OPC_MSUB_S  = 0x28 | OPC_CP3,
1158     OPC_MSUB_D  = 0x29 | OPC_CP3,
1159     OPC_MSUB_PS = 0x2E | OPC_CP3,
1160     OPC_NMADD_S = 0x30 | OPC_CP3,
1161     OPC_NMADD_D = 0x31 | OPC_CP3,
1162     OPC_NMADD_PS= 0x36 | OPC_CP3,
1163     OPC_NMSUB_S = 0x38 | OPC_CP3,
1164     OPC_NMSUB_D = 0x39 | OPC_CP3,
1165     OPC_NMSUB_PS= 0x3E | OPC_CP3,
1166 };
1167
1168 /* MSA Opcodes */
1169 #define MASK_MSA_MINOR(op)    (MASK_OP_MAJOR(op) | (op & 0x3F))
1170 enum {
1171     OPC_MSA_I8_00   = 0x00 | OPC_MSA,
1172     OPC_MSA_I8_01   = 0x01 | OPC_MSA,
1173     OPC_MSA_I8_02   = 0x02 | OPC_MSA,
1174     OPC_MSA_I5_06   = 0x06 | OPC_MSA,
1175     OPC_MSA_I5_07   = 0x07 | OPC_MSA,
1176     OPC_MSA_BIT_09  = 0x09 | OPC_MSA,
1177     OPC_MSA_BIT_0A  = 0x0A | OPC_MSA,
1178     OPC_MSA_3R_0D   = 0x0D | OPC_MSA,
1179     OPC_MSA_3R_0E   = 0x0E | OPC_MSA,
1180     OPC_MSA_3R_0F   = 0x0F | OPC_MSA,
1181     OPC_MSA_3R_10   = 0x10 | OPC_MSA,
1182     OPC_MSA_3R_11   = 0x11 | OPC_MSA,
1183     OPC_MSA_3R_12   = 0x12 | OPC_MSA,
1184     OPC_MSA_3R_13   = 0x13 | OPC_MSA,
1185     OPC_MSA_3R_14   = 0x14 | OPC_MSA,
1186     OPC_MSA_3R_15   = 0x15 | OPC_MSA,
1187     OPC_MSA_ELM     = 0x19 | OPC_MSA,
1188     OPC_MSA_3RF_1A  = 0x1A | OPC_MSA,
1189     OPC_MSA_3RF_1B  = 0x1B | OPC_MSA,
1190     OPC_MSA_3RF_1C  = 0x1C | OPC_MSA,
1191     OPC_MSA_VEC     = 0x1E | OPC_MSA,
1192
1193     /* MI10 instruction */
1194     OPC_LD_B    = (0x20) | OPC_MSA,
1195     OPC_LD_H    = (0x21) | OPC_MSA,
1196     OPC_LD_W    = (0x22) | OPC_MSA,
1197     OPC_LD_D    = (0x23) | OPC_MSA,
1198     OPC_ST_B    = (0x24) | OPC_MSA,
1199     OPC_ST_H    = (0x25) | OPC_MSA,
1200     OPC_ST_W    = (0x26) | OPC_MSA,
1201     OPC_ST_D    = (0x27) | OPC_MSA,
1202 };
1203
1204 enum {
1205     /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1206     OPC_ADDVI_df    = (0x0 << 23) | OPC_MSA_I5_06,
1207     OPC_CEQI_df     = (0x0 << 23) | OPC_MSA_I5_07,
1208     OPC_SUBVI_df    = (0x1 << 23) | OPC_MSA_I5_06,
1209     OPC_MAXI_S_df   = (0x2 << 23) | OPC_MSA_I5_06,
1210     OPC_CLTI_S_df   = (0x2 << 23) | OPC_MSA_I5_07,
1211     OPC_MAXI_U_df   = (0x3 << 23) | OPC_MSA_I5_06,
1212     OPC_CLTI_U_df   = (0x3 << 23) | OPC_MSA_I5_07,
1213     OPC_MINI_S_df   = (0x4 << 23) | OPC_MSA_I5_06,
1214     OPC_CLEI_S_df   = (0x4 << 23) | OPC_MSA_I5_07,
1215     OPC_MINI_U_df   = (0x5 << 23) | OPC_MSA_I5_06,
1216     OPC_CLEI_U_df   = (0x5 << 23) | OPC_MSA_I5_07,
1217     OPC_LDI_df      = (0x6 << 23) | OPC_MSA_I5_07,
1218
1219     /* I8 instruction */
1220     OPC_ANDI_B  = (0x0 << 24) | OPC_MSA_I8_00,
1221     OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1222     OPC_SHF_B   = (0x0 << 24) | OPC_MSA_I8_02,
1223     OPC_ORI_B   = (0x1 << 24) | OPC_MSA_I8_00,
1224     OPC_BMZI_B  = (0x1 << 24) | OPC_MSA_I8_01,
1225     OPC_SHF_H   = (0x1 << 24) | OPC_MSA_I8_02,
1226     OPC_NORI_B  = (0x2 << 24) | OPC_MSA_I8_00,
1227     OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1228     OPC_SHF_W   = (0x2 << 24) | OPC_MSA_I8_02,
1229     OPC_XORI_B  = (0x3 << 24) | OPC_MSA_I8_00,
1230
1231     /* VEC/2R/2RF instruction */
1232     OPC_AND_V   = (0x00 << 21) | OPC_MSA_VEC,
1233     OPC_OR_V    = (0x01 << 21) | OPC_MSA_VEC,
1234     OPC_NOR_V   = (0x02 << 21) | OPC_MSA_VEC,
1235     OPC_XOR_V   = (0x03 << 21) | OPC_MSA_VEC,
1236     OPC_BMNZ_V  = (0x04 << 21) | OPC_MSA_VEC,
1237     OPC_BMZ_V   = (0x05 << 21) | OPC_MSA_VEC,
1238     OPC_BSEL_V  = (0x06 << 21) | OPC_MSA_VEC,
1239
1240     OPC_MSA_2R      = (0x18 << 21) | OPC_MSA_VEC,
1241     OPC_MSA_2RF     = (0x19 << 21) | OPC_MSA_VEC,
1242
1243     /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1244     OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1245     OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1246     OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1247     OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1248
1249     /* 2RF instruction df(bit 16) = _w, _d */
1250     OPC_FCLASS_df   = (0x00 << 17) | OPC_MSA_2RF,
1251     OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1252     OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1253     OPC_FSQRT_df    = (0x03 << 17) | OPC_MSA_2RF,
1254     OPC_FRSQRT_df   = (0x04 << 17) | OPC_MSA_2RF,
1255     OPC_FRCP_df     = (0x05 << 17) | OPC_MSA_2RF,
1256     OPC_FRINT_df    = (0x06 << 17) | OPC_MSA_2RF,
1257     OPC_FLOG2_df    = (0x07 << 17) | OPC_MSA_2RF,
1258     OPC_FEXUPL_df   = (0x08 << 17) | OPC_MSA_2RF,
1259     OPC_FEXUPR_df   = (0x09 << 17) | OPC_MSA_2RF,
1260     OPC_FFQL_df     = (0x0A << 17) | OPC_MSA_2RF,
1261     OPC_FFQR_df     = (0x0B << 17) | OPC_MSA_2RF,
1262     OPC_FTINT_S_df  = (0x0C << 17) | OPC_MSA_2RF,
1263     OPC_FTINT_U_df  = (0x0D << 17) | OPC_MSA_2RF,
1264     OPC_FFINT_S_df  = (0x0E << 17) | OPC_MSA_2RF,
1265     OPC_FFINT_U_df  = (0x0F << 17) | OPC_MSA_2RF,
1266
1267     /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1268     OPC_SLL_df      = (0x0 << 23) | OPC_MSA_3R_0D,
1269     OPC_ADDV_df     = (0x0 << 23) | OPC_MSA_3R_0E,
1270     OPC_CEQ_df      = (0x0 << 23) | OPC_MSA_3R_0F,
1271     OPC_ADD_A_df    = (0x0 << 23) | OPC_MSA_3R_10,
1272     OPC_SUBS_S_df   = (0x0 << 23) | OPC_MSA_3R_11,
1273     OPC_MULV_df     = (0x0 << 23) | OPC_MSA_3R_12,
1274     OPC_DOTP_S_df   = (0x0 << 23) | OPC_MSA_3R_13,
1275     OPC_SLD_df      = (0x0 << 23) | OPC_MSA_3R_14,
1276     OPC_VSHF_df     = (0x0 << 23) | OPC_MSA_3R_15,
1277     OPC_SRA_df      = (0x1 << 23) | OPC_MSA_3R_0D,
1278     OPC_SUBV_df     = (0x1 << 23) | OPC_MSA_3R_0E,
1279     OPC_ADDS_A_df   = (0x1 << 23) | OPC_MSA_3R_10,
1280     OPC_SUBS_U_df   = (0x1 << 23) | OPC_MSA_3R_11,
1281     OPC_MADDV_df    = (0x1 << 23) | OPC_MSA_3R_12,
1282     OPC_DOTP_U_df   = (0x1 << 23) | OPC_MSA_3R_13,
1283     OPC_SPLAT_df    = (0x1 << 23) | OPC_MSA_3R_14,
1284     OPC_SRAR_df     = (0x1 << 23) | OPC_MSA_3R_15,
1285     OPC_SRL_df      = (0x2 << 23) | OPC_MSA_3R_0D,
1286     OPC_MAX_S_df    = (0x2 << 23) | OPC_MSA_3R_0E,
1287     OPC_CLT_S_df    = (0x2 << 23) | OPC_MSA_3R_0F,
1288     OPC_ADDS_S_df   = (0x2 << 23) | OPC_MSA_3R_10,
1289     OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1290     OPC_MSUBV_df    = (0x2 << 23) | OPC_MSA_3R_12,
1291     OPC_DPADD_S_df  = (0x2 << 23) | OPC_MSA_3R_13,
1292     OPC_PCKEV_df    = (0x2 << 23) | OPC_MSA_3R_14,
1293     OPC_SRLR_df     = (0x2 << 23) | OPC_MSA_3R_15,
1294     OPC_BCLR_df     = (0x3 << 23) | OPC_MSA_3R_0D,
1295     OPC_MAX_U_df    = (0x3 << 23) | OPC_MSA_3R_0E,
1296     OPC_CLT_U_df    = (0x3 << 23) | OPC_MSA_3R_0F,
1297     OPC_ADDS_U_df   = (0x3 << 23) | OPC_MSA_3R_10,
1298     OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1299     OPC_DPADD_U_df  = (0x3 << 23) | OPC_MSA_3R_13,
1300     OPC_PCKOD_df    = (0x3 << 23) | OPC_MSA_3R_14,
1301     OPC_BSET_df     = (0x4 << 23) | OPC_MSA_3R_0D,
1302     OPC_MIN_S_df    = (0x4 << 23) | OPC_MSA_3R_0E,
1303     OPC_CLE_S_df    = (0x4 << 23) | OPC_MSA_3R_0F,
1304     OPC_AVE_S_df    = (0x4 << 23) | OPC_MSA_3R_10,
1305     OPC_ASUB_S_df   = (0x4 << 23) | OPC_MSA_3R_11,
1306     OPC_DIV_S_df    = (0x4 << 23) | OPC_MSA_3R_12,
1307     OPC_DPSUB_S_df  = (0x4 << 23) | OPC_MSA_3R_13,
1308     OPC_ILVL_df     = (0x4 << 23) | OPC_MSA_3R_14,
1309     OPC_HADD_S_df   = (0x4 << 23) | OPC_MSA_3R_15,
1310     OPC_BNEG_df     = (0x5 << 23) | OPC_MSA_3R_0D,
1311     OPC_MIN_U_df    = (0x5 << 23) | OPC_MSA_3R_0E,
1312     OPC_CLE_U_df    = (0x5 << 23) | OPC_MSA_3R_0F,
1313     OPC_AVE_U_df    = (0x5 << 23) | OPC_MSA_3R_10,
1314     OPC_ASUB_U_df   = (0x5 << 23) | OPC_MSA_3R_11,
1315     OPC_DIV_U_df    = (0x5 << 23) | OPC_MSA_3R_12,
1316     OPC_DPSUB_U_df  = (0x5 << 23) | OPC_MSA_3R_13,
1317     OPC_ILVR_df     = (0x5 << 23) | OPC_MSA_3R_14,
1318     OPC_HADD_U_df   = (0x5 << 23) | OPC_MSA_3R_15,
1319     OPC_BINSL_df    = (0x6 << 23) | OPC_MSA_3R_0D,
1320     OPC_MAX_A_df    = (0x6 << 23) | OPC_MSA_3R_0E,
1321     OPC_AVER_S_df   = (0x6 << 23) | OPC_MSA_3R_10,
1322     OPC_MOD_S_df    = (0x6 << 23) | OPC_MSA_3R_12,
1323     OPC_ILVEV_df    = (0x6 << 23) | OPC_MSA_3R_14,
1324     OPC_HSUB_S_df   = (0x6 << 23) | OPC_MSA_3R_15,
1325     OPC_BINSR_df    = (0x7 << 23) | OPC_MSA_3R_0D,
1326     OPC_MIN_A_df    = (0x7 << 23) | OPC_MSA_3R_0E,
1327     OPC_AVER_U_df   = (0x7 << 23) | OPC_MSA_3R_10,
1328     OPC_MOD_U_df    = (0x7 << 23) | OPC_MSA_3R_12,
1329     OPC_ILVOD_df    = (0x7 << 23) | OPC_MSA_3R_14,
1330     OPC_HSUB_U_df   = (0x7 << 23) | OPC_MSA_3R_15,
1331
1332     /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1333     OPC_SLDI_df     = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1334     OPC_CTCMSA      = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1335     OPC_SPLATI_df   = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1336     OPC_CFCMSA      = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1337     OPC_COPY_S_df   = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1338     OPC_MOVE_V      = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1339     OPC_COPY_U_df   = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1340     OPC_INSERT_df   = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1341     OPC_INSVE_df    = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1342
1343     /* 3RF instruction _df(bit 21) = _w, _d */
1344     OPC_FCAF_df     = (0x0 << 22) | OPC_MSA_3RF_1A,
1345     OPC_FADD_df     = (0x0 << 22) | OPC_MSA_3RF_1B,
1346     OPC_FCUN_df     = (0x1 << 22) | OPC_MSA_3RF_1A,
1347     OPC_FSUB_df     = (0x1 << 22) | OPC_MSA_3RF_1B,
1348     OPC_FCOR_df     = (0x1 << 22) | OPC_MSA_3RF_1C,
1349     OPC_FCEQ_df     = (0x2 << 22) | OPC_MSA_3RF_1A,
1350     OPC_FMUL_df     = (0x2 << 22) | OPC_MSA_3RF_1B,
1351     OPC_FCUNE_df    = (0x2 << 22) | OPC_MSA_3RF_1C,
1352     OPC_FCUEQ_df    = (0x3 << 22) | OPC_MSA_3RF_1A,
1353     OPC_FDIV_df     = (0x3 << 22) | OPC_MSA_3RF_1B,
1354     OPC_FCNE_df     = (0x3 << 22) | OPC_MSA_3RF_1C,
1355     OPC_FCLT_df     = (0x4 << 22) | OPC_MSA_3RF_1A,
1356     OPC_FMADD_df    = (0x4 << 22) | OPC_MSA_3RF_1B,
1357     OPC_MUL_Q_df    = (0x4 << 22) | OPC_MSA_3RF_1C,
1358     OPC_FCULT_df    = (0x5 << 22) | OPC_MSA_3RF_1A,
1359     OPC_FMSUB_df    = (0x5 << 22) | OPC_MSA_3RF_1B,
1360     OPC_MADD_Q_df   = (0x5 << 22) | OPC_MSA_3RF_1C,
1361     OPC_FCLE_df     = (0x6 << 22) | OPC_MSA_3RF_1A,
1362     OPC_MSUB_Q_df   = (0x6 << 22) | OPC_MSA_3RF_1C,
1363     OPC_FCULE_df    = (0x7 << 22) | OPC_MSA_3RF_1A,
1364     OPC_FEXP2_df    = (0x7 << 22) | OPC_MSA_3RF_1B,
1365     OPC_FSAF_df     = (0x8 << 22) | OPC_MSA_3RF_1A,
1366     OPC_FEXDO_df    = (0x8 << 22) | OPC_MSA_3RF_1B,
1367     OPC_FSUN_df     = (0x9 << 22) | OPC_MSA_3RF_1A,
1368     OPC_FSOR_df     = (0x9 << 22) | OPC_MSA_3RF_1C,
1369     OPC_FSEQ_df     = (0xA << 22) | OPC_MSA_3RF_1A,
1370     OPC_FTQ_df      = (0xA << 22) | OPC_MSA_3RF_1B,
1371     OPC_FSUNE_df    = (0xA << 22) | OPC_MSA_3RF_1C,
1372     OPC_FSUEQ_df    = (0xB << 22) | OPC_MSA_3RF_1A,
1373     OPC_FSNE_df     = (0xB << 22) | OPC_MSA_3RF_1C,
1374     OPC_FSLT_df     = (0xC << 22) | OPC_MSA_3RF_1A,
1375     OPC_FMIN_df     = (0xC << 22) | OPC_MSA_3RF_1B,
1376     OPC_MULR_Q_df   = (0xC << 22) | OPC_MSA_3RF_1C,
1377     OPC_FSULT_df    = (0xD << 22) | OPC_MSA_3RF_1A,
1378     OPC_FMIN_A_df   = (0xD << 22) | OPC_MSA_3RF_1B,
1379     OPC_MADDR_Q_df  = (0xD << 22) | OPC_MSA_3RF_1C,
1380     OPC_FSLE_df     = (0xE << 22) | OPC_MSA_3RF_1A,
1381     OPC_FMAX_df     = (0xE << 22) | OPC_MSA_3RF_1B,
1382     OPC_MSUBR_Q_df  = (0xE << 22) | OPC_MSA_3RF_1C,
1383     OPC_FSULE_df    = (0xF << 22) | OPC_MSA_3RF_1A,
1384     OPC_FMAX_A_df   = (0xF << 22) | OPC_MSA_3RF_1B,
1385
1386     /* BIT instruction df(bits 22..16) = _B _H _W _D */
1387     OPC_SLLI_df     = (0x0 << 23) | OPC_MSA_BIT_09,
1388     OPC_SAT_S_df    = (0x0 << 23) | OPC_MSA_BIT_0A,
1389     OPC_SRAI_df     = (0x1 << 23) | OPC_MSA_BIT_09,
1390     OPC_SAT_U_df    = (0x1 << 23) | OPC_MSA_BIT_0A,
1391     OPC_SRLI_df     = (0x2 << 23) | OPC_MSA_BIT_09,
1392     OPC_SRARI_df    = (0x2 << 23) | OPC_MSA_BIT_0A,
1393     OPC_BCLRI_df    = (0x3 << 23) | OPC_MSA_BIT_09,
1394     OPC_SRLRI_df    = (0x3 << 23) | OPC_MSA_BIT_0A,
1395     OPC_BSETI_df    = (0x4 << 23) | OPC_MSA_BIT_09,
1396     OPC_BNEGI_df    = (0x5 << 23) | OPC_MSA_BIT_09,
1397     OPC_BINSLI_df   = (0x6 << 23) | OPC_MSA_BIT_09,
1398     OPC_BINSRI_df   = (0x7 << 23) | OPC_MSA_BIT_09,
1399 };
1400
1401
1402 /*
1403  *
1404  *       AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
1405  *       ============================================
1406  *
1407  *
1408  * MXU (full name: MIPS eXtension/enhanced Unit) is a SIMD extension of MIPS32
1409  * instructions set. It is designed to fit the needs of signal, graphical and
1410  * video processing applications. MXU instruction set is used in Xburst family
1411  * of microprocessors by Ingenic.
1412  *
1413  * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X16 is
1414  * the control register.
1415  *
1416  *
1417  *     The notation used in MXU assembler mnemonics
1418  *     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1419  *
1420  *  Register operands:
1421  *
1422  *   XRa, XRb, XRc, XRd - MXU registers
1423  *   Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
1424  *
1425  *  Non-register operands:
1426  *
1427  *   aptn1 - 1-bit accumulate add/subtract pattern
1428  *   aptn2 - 2-bit accumulate add/subtract pattern
1429  *   eptn2 - 2-bit execute add/subtract pattern
1430  *   optn2 - 2-bit operand pattern
1431  *   optn3 - 3-bit operand pattern
1432  *   sft4  - 4-bit shift amount
1433  *   strd2 - 2-bit stride amount
1434  *
1435  *  Prefixes:
1436  *
1437  *   Level of parallelism:                Operand size:
1438  *    S - single operation at a time       32 - word
1439  *    D - two operations in parallel       16 - half word
1440  *    Q - four operations in parallel       8 - byte
1441  *
1442  *  Operations:
1443  *
1444  *   ADD   - Add or subtract
1445  *   ADDC  - Add with carry-in
1446  *   ACC   - Accumulate
1447  *   ASUM  - Sum together then accumulate (add or subtract)
1448  *   ASUMC - Sum together then accumulate (add or subtract) with carry-in
1449  *   AVG   - Average between 2 operands
1450  *   ABD   - Absolute difference
1451  *   ALN   - Align data
1452  *   AND   - Logical bitwise 'and' operation
1453  *   CPS   - Copy sign
1454  *   EXTR  - Extract bits
1455  *   I2M   - Move from GPR register to MXU register
1456  *   LDD   - Load data from memory to XRF
1457  *   LDI   - Load data from memory to XRF (and increase the address base)
1458  *   LUI   - Load unsigned immediate
1459  *   MUL   - Multiply
1460  *   MULU  - Unsigned multiply
1461  *   MADD  - 64-bit operand add 32x32 product
1462  *   MSUB  - 64-bit operand subtract 32x32 product
1463  *   MAC   - Multiply and accumulate (add or subtract)
1464  *   MAD   - Multiply and add or subtract
1465  *   MAX   - Maximum between 2 operands
1466  *   MIN   - Minimum between 2 operands
1467  *   M2I   - Move from MXU register to GPR register
1468  *   MOVZ  - Move if zero
1469  *   MOVN  - Move if non-zero
1470  *   NOR   - Logical bitwise 'nor' operation
1471  *   OR    - Logical bitwise 'or' operation
1472  *   STD   - Store data from XRF to memory
1473  *   SDI   - Store data from XRF to memory (and increase the address base)
1474  *   SLT   - Set of less than comparison
1475  *   SAD   - Sum of absolute differences
1476  *   SLL   - Logical shift left
1477  *   SLR   - Logical shift right
1478  *   SAR   - Arithmetic shift right
1479  *   SAT   - Saturation
1480  *   SFL   - Shuffle
1481  *   SCOP  - Calculate x’s scope (-1, means x<0; 0, means x==0; 1, means x>0)
1482  *   XOR   - Logical bitwise 'exclusive or' operation
1483  *
1484  *  Suffixes:
1485  *
1486  *   E - Expand results
1487  *   F - Fixed point multiplication
1488  *   L - Low part result
1489  *   R - Doing rounding
1490  *   V - Variable instead of immediate
1491  *   W - Combine above L and V
1492  *
1493  *
1494  *     The list of MXU instructions grouped by functionality
1495  *     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1496  *
1497  * Load/Store instructions           Multiplication instructions
1498  * -----------------------           ---------------------------
1499  *
1500  *  S32LDD XRa, Rb, s12               S32MADD XRa, XRd, Rs, Rt
1501  *  S32STD XRa, Rb, s12               S32MADDU XRa, XRd, Rs, Rt
1502  *  S32LDDV XRa, Rb, rc, strd2        S32MSUB XRa, XRd, Rs, Rt
1503  *  S32STDV XRa, Rb, rc, strd2        S32MSUBU XRa, XRd, Rs, Rt
1504  *  S32LDI XRa, Rb, s12               S32MUL XRa, XRd, Rs, Rt
1505  *  S32SDI XRa, Rb, s12               S32MULU XRa, XRd, Rs, Rt
1506  *  S32LDIV XRa, Rb, rc, strd2        D16MUL XRa, XRb, XRc, XRd, optn2
1507  *  S32SDIV XRa, Rb, rc, strd2        D16MULE XRa, XRb, XRc, optn2
1508  *  S32LDDR XRa, Rb, s12              D16MULF XRa, XRb, XRc, optn2
1509  *  S32STDR XRa, Rb, s12              D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
1510  *  S32LDDVR XRa, Rb, rc, strd2       D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
1511  *  S32STDVR XRa, Rb, rc, strd2       D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
1512  *  S32LDIR XRa, Rb, s12              D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
1513  *  S32SDIR XRa, Rb, s12              S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
1514  *  S32LDIVR XRa, Rb, rc, strd2       Q8MUL XRa, XRb, XRc, XRd
1515  *  S32SDIVR XRa, Rb, rc, strd2       Q8MULSU XRa, XRb, XRc, XRd
1516  *  S16LDD XRa, Rb, s10, eptn2        Q8MAC XRa, XRb, XRc, XRd, aptn2
1517  *  S16STD XRa, Rb, s10, eptn2        Q8MACSU XRa, XRb, XRc, XRd, aptn2
1518  *  S16LDI XRa, Rb, s10, eptn2        Q8MADL XRa, XRb, XRc, XRd, aptn2
1519  *  S16SDI XRa, Rb, s10, eptn2
1520  *  S8LDD XRa, Rb, s8, eptn3
1521  *  S8STD XRa, Rb, s8, eptn3         Addition and subtraction instructions
1522  *  S8LDI XRa, Rb, s8, eptn3         -------------------------------------
1523  *  S8SDI XRa, Rb, s8, eptn3
1524  *  LXW Rd, Rs, Rt, strd2             D32ADD XRa, XRb, XRc, XRd, eptn2
1525  *  LXH Rd, Rs, Rt, strd2             D32ADDC XRa, XRb, XRc, XRd
1526  *  LXHU Rd, Rs, Rt, strd2            D32ACC XRa, XRb, XRc, XRd, eptn2
1527  *  LXB Rd, Rs, Rt, strd2             D32ACCM XRa, XRb, XRc, XRd, eptn2
1528  *  LXBU Rd, Rs, Rt, strd2            D32ASUM XRa, XRb, XRc, XRd, eptn2
1529  *                                    S32CPS XRa, XRb, XRc
1530  *                                    Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
1531  * Comparison instructions            Q16ACC XRa, XRb, XRc, XRd, eptn2
1532  * -----------------------            Q16ACCM XRa, XRb, XRc, XRd, eptn2
1533  *                                    D16ASUM XRa, XRb, XRc, XRd, eptn2
1534  *  S32MAX XRa, XRb, XRc              D16CPS XRa, XRb,
1535  *  S32MIN XRa, XRb, XRc              D16AVG XRa, XRb, XRc
1536  *  S32SLT XRa, XRb, XRc              D16AVGR XRa, XRb, XRc
1537  *  S32MOVZ XRa, XRb, XRc             Q8ADD XRa, XRb, XRc, eptn2
1538  *  S32MOVN XRa, XRb, XRc             Q8ADDE XRa, XRb, XRc, XRd, eptn2
1539  *  D16MAX XRa, XRb, XRc              Q8ACCE XRa, XRb, XRc, XRd, eptn2
1540  *  D16MIN XRa, XRb, XRc              Q8ABD XRa, XRb, XRc
1541  *  D16SLT XRa, XRb, XRc              Q8SAD XRa, XRb, XRc, XRd
1542  *  D16MOVZ XRa, XRb, XRc             Q8AVG XRa, XRb, XRc
1543  *  D16MOVN XRa, XRb, XRc             Q8AVGR XRa, XRb, XRc
1544  *  Q8MAX XRa, XRb, XRc               D8SUM XRa, XRb, XRc, XRd
1545  *  Q8MIN XRa, XRb, XRc               D8SUMC XRa, XRb, XRc, XRd
1546  *  Q8SLT XRa, XRb, XRc
1547  *  Q8SLTU XRa, XRb, XRc
1548  *  Q8MOVZ XRa, XRb, XRc             Shift instructions
1549  *  Q8MOVN XRa, XRb, XRc             ------------------
1550  *
1551  *                                    D32SLL XRa, XRb, XRc, XRd, sft4
1552  * Bitwise instructions               D32SLR XRa, XRb, XRc, XRd, sft4
1553  * --------------------               D32SAR XRa, XRb, XRc, XRd, sft4
1554  *                                    D32SARL XRa, XRb, XRc, sft4
1555  *  S32NOR XRa, XRb, XRc              D32SLLV XRa, XRb, Rb
1556  *  S32AND XRa, XRb, XRc              D32SLRV XRa, XRb, Rb
1557  *  S32XOR XRa, XRb, XRc              D32SARV XRa, XRb, Rb
1558  *  S32OR XRa, XRb, XRc               D32SARW XRa, XRb, XRc, Rb
1559  *                                    Q16SLL XRa, XRb, XRc, XRd, sft4
1560  *                                    Q16SLR XRa, XRb, XRc, XRd, sft4
1561  * Miscellaneous instructions         Q16SAR XRa, XRb, XRc, XRd, sft4
1562  * -------------------------          Q16SLLV XRa, XRb, Rb
1563  *                                    Q16SLRV XRa, XRb, Rb
1564  *  S32SFL XRa, XRb, XRc, XRd, optn2  Q16SARV XRa, XRb, Rb
1565  *  S32ALN XRa, XRb, XRc, Rb
1566  *  S32ALNI XRa, XRb, XRc, s3
1567  *  S32LUI XRa, s8, optn3            Move instructions
1568  *  S32EXTR XRa, XRb, Rb, bits5      -----------------
1569  *  S32EXTRV XRa, XRb, Rs, Rt
1570  *  Q16SCOP XRa, XRb, XRc, XRd        S32M2I XRa, Rb
1571  *  Q16SAT XRa, XRb, XRc              S32I2M XRa, Rb
1572  *
1573  *
1574  *     The opcode organization of MXU instructions
1575  *     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1576  *
1577  * The bits 31..26 of all MXU instructions are equal to 0x1C (also referred
1578  * as opcode SPECIAL2 in the base MIPS ISA). The organization and meaning of
1579  * other bits up to the instruction level is as follows:
1580  *
1581  *              bits
1582  *             05..00
1583  *
1584  *          â”Œâ”€ 000000 â”€ OPC_MXU_S32MADD
1585  *          â”œâ”€ 000001 â”€ OPC_MXU_S32MADDU
1586  *          â”œâ”€ 000010 â”€ <not assigned>   (non-MXU OPC_MUL)
1587  *          â”‚
1588  *          â”‚                               20..18
1589  *          â”œâ”€ 000011 â”€ OPC_MXU__POOL00 â”€â”¬â”€ 000 â”€ OPC_MXU_S32MAX
1590  *          â”‚                            â”œâ”€ 001 â”€ OPC_MXU_S32MIN
1591  *          â”‚                            â”œâ”€ 010 â”€ OPC_MXU_D16MAX
1592  *          â”‚                            â”œâ”€ 011 â”€ OPC_MXU_D16MIN
1593  *          â”‚                            â”œâ”€ 100 â”€ OPC_MXU_Q8MAX
1594  *          â”‚                            â”œâ”€ 101 â”€ OPC_MXU_Q8MIN
1595  *          â”‚                            â”œâ”€ 110 â”€ OPC_MXU_Q8SLT
1596  *          â”‚                            â””─ 111 â”€ OPC_MXU_Q8SLTU
1597  *          â”œâ”€ 000100 â”€ OPC_MXU_S32MSUB
1598  *          â”œâ”€ 000101 â”€ OPC_MXU_S32MSUBU    20..18
1599  *          â”œâ”€ 000110 â”€ OPC_MXU__POOL01 â”€â”¬â”€ 000 â”€ OPC_MXU_S32SLT
1600  *          â”‚                            â”œâ”€ 001 â”€ OPC_MXU_D16SLT
1601  *          â”‚                            â”œâ”€ 010 â”€ OPC_MXU_D16AVG
1602  *          â”‚                            â”œâ”€ 011 â”€ OPC_MXU_D16AVGR
1603  *          â”‚                            â”œâ”€ 100 â”€ OPC_MXU_Q8AVG
1604  *          â”‚                            â”œâ”€ 101 â”€ OPC_MXU_Q8AVGR
1605  *          â”‚                            â””─ 111 â”€ OPC_MXU_Q8ADD
1606  *          â”‚
1607  *          â”‚                               20..18
1608  *          â”œâ”€ 000111 â”€ OPC_MXU__POOL02 â”€â”¬â”€ 000 â”€ OPC_MXU_S32CPS
1609  *          â”‚                            â”œâ”€ 010 â”€ OPC_MXU_D16CPS
1610  *          â”‚                            â”œâ”€ 100 â”€ OPC_MXU_Q8ABD
1611  *          â”‚                            â””─ 110 â”€ OPC_MXU_Q16SAT
1612  *          â”œâ”€ 001000 â”€ OPC_MXU_D16MUL
1613  *          â”‚                               25..24
1614  *          â”œâ”€ 001001 â”€ OPC_MXU__POOL03 â”€â”¬â”€ 00 â”€ OPC_MXU_D16MULF
1615  *          â”‚                            â””─ 01 â”€ OPC_MXU_D16MULE
1616  *          â”œâ”€ 001010 â”€ OPC_MXU_D16MAC
1617  *          â”œâ”€ 001011 â”€ OPC_MXU_D16MACF
1618  *          â”œâ”€ 001100 â”€ OPC_MXU_D16MADL
1619  *          â”œâ”€ 001101 â”€ OPC_MXU_S16MAD
1620  *          â”œâ”€ 001110 â”€ OPC_MXU_Q16ADD
1621  *          â”œâ”€ 001111 â”€ OPC_MXU_D16MACE     23
1622  *          â”‚                            â”Œâ”€ 0 â”€ OPC_MXU_S32LDD
1623  *          â”œâ”€ 010000 â”€ OPC_MXU__POOL04 â”€â”´â”€ 1 â”€ OPC_MXU_S32LDDR
1624  *          â”‚
1625  *          â”‚                               23
1626  *          â”œâ”€ 010001 â”€ OPC_MXU__POOL05 â”€â”¬â”€ 0 â”€ OPC_MXU_S32STD
1627  *          â”‚                            â””─ 1 â”€ OPC_MXU_S32STDR
1628  *          â”‚
1629  *          â”‚                               13..10
1630  *          â”œâ”€ 010010 â”€ OPC_MXU__POOL06 â”€â”¬â”€ 0000 â”€ OPC_MXU_S32LDDV
1631  *          â”‚                            â””─ 0001 â”€ OPC_MXU_S32LDDVR
1632  *          â”‚
1633  *          â”‚                               13..10
1634  *          â”œâ”€ 010011 â”€ OPC_MXU__POOL07 â”€â”¬â”€ 0000 â”€ OPC_MXU_S32STDV
1635  *          â”‚                            â””─ 0001 â”€ OPC_MXU_S32STDVR
1636  *          â”‚
1637  *          â”‚                               23
1638  *          â”œâ”€ 010100 â”€ OPC_MXU__POOL08 â”€â”¬â”€ 0 â”€ OPC_MXU_S32LDI
1639  *          â”‚                            â””─ 1 â”€ OPC_MXU_S32LDIR
1640  *          â”‚
1641  *          â”‚                               23
1642  *          â”œâ”€ 010101 â”€ OPC_MXU__POOL09 â”€â”¬â”€ 0 â”€ OPC_MXU_S32SDI
1643  *          â”‚                            â””─ 1 â”€ OPC_MXU_S32SDIR
1644  *          â”‚
1645  *          â”‚                               13..10
1646  *          â”œâ”€ 010110 â”€ OPC_MXU__POOL10 â”€â”¬â”€ 0000 â”€ OPC_MXU_S32LDIV
1647  *          â”‚                            â””─ 0001 â”€ OPC_MXU_S32LDIVR
1648  *          â”‚
1649  *          â”‚                               13..10
1650  *          â”œâ”€ 010111 â”€ OPC_MXU__POOL11 â”€â”¬â”€ 0000 â”€ OPC_MXU_S32SDIV
1651  *          â”‚                            â””─ 0001 â”€ OPC_MXU_S32SDIVR
1652  *          â”œâ”€ 011000 â”€ OPC_MXU_D32ADD
1653  *          â”‚                               23..22
1654  *   MXU    â”œâ”€ 011001 â”€ OPC_MXU__POOL12 â”€â”¬â”€ 00 â”€ OPC_MXU_D32ACC
1655  * opcodes â”€â”¤                            â”œâ”€ 01 â”€ OPC_MXU_D32ACCM
1656  *          â”‚                            â””─ 10 â”€ OPC_MXU_D32ASUM
1657  *          â”œâ”€ 011010 â”€ <not assigned>
1658  *          â”‚                               23..22
1659  *          â”œâ”€ 011011 â”€ OPC_MXU__POOL13 â”€â”¬â”€ 00 â”€ OPC_MXU_Q16ACC
1660  *          â”‚                            â”œâ”€ 01 â”€ OPC_MXU_Q16ACCM
1661  *          â”‚                            â””─ 10 â”€ OPC_MXU_Q16ASUM
1662  *          â”‚
1663  *          â”‚                               23..22
1664  *          â”œâ”€ 011100 â”€ OPC_MXU__POOL14 â”€â”¬â”€ 00 â”€ OPC_MXU_Q8ADDE
1665  *          â”‚                            â”œâ”€ 01 â”€ OPC_MXU_D8SUM
1666  *          â”œâ”€ 011101 â”€ OPC_MXU_Q8ACCE   â””─ 10 â”€ OPC_MXU_D8SUMC
1667  *          â”œâ”€ 011110 â”€ <not assigned>
1668  *          â”œâ”€ 011111 â”€ <not assigned>
1669  *          â”œâ”€ 100000 â”€ <not assigned>   (overlaps with CLZ)
1670  *          â”œâ”€ 100001 â”€ <not assigned>   (overlaps with CLO)
1671  *          â”œâ”€ 100010 â”€ OPC_MXU_S8LDD
1672  *          â”œâ”€ 100011 â”€ OPC_MXU_S8STD       15..14
1673  *          â”œâ”€ 100100 â”€ OPC_MXU_S8LDI    â”Œâ”€ 00 â”€ OPC_MXU_S32MUL
1674  *          â”œâ”€ 100101 â”€ OPC_MXU_S8SDI    â”œâ”€ 00 â”€ OPC_MXU_S32MULU
1675  *          â”‚                            â”œâ”€ 00 â”€ OPC_MXU_S32EXTR
1676  *          â”œâ”€ 100110 â”€ OPC_MXU__POOL15 â”€â”´â”€ 00 â”€ OPC_MXU_S32EXTRV
1677  *          â”‚
1678  *          â”‚                               20..18
1679  *          â”œâ”€ 100111 â”€ OPC_MXU__POOL16 â”€â”¬â”€ 000 â”€ OPC_MXU_D32SARW
1680  *          â”‚                            â”œâ”€ 001 â”€ OPC_MXU_S32ALN
1681  *          â”‚                            â”œâ”€ 010 â”€ OPC_MXU_S32ALNI
1682  *          â”‚                            â”œâ”€ 011 â”€ OPC_MXU_S32LUI
1683  *          â”‚                            â”œâ”€ 100 â”€ OPC_MXU_S32NOR
1684  *          â”‚                            â”œâ”€ 101 â”€ OPC_MXU_S32AND
1685  *          â”‚                            â”œâ”€ 110 â”€ OPC_MXU_S32OR
1686  *          â”‚                            â””─ 111 â”€ OPC_MXU_S32XOR
1687  *          â”‚
1688  *          â”‚                               7..5
1689  *          â”œâ”€ 101000 â”€ OPC_MXU__POOL17 â”€â”¬â”€ 000 â”€ OPC_MXU_LXB
1690  *          â”‚                            â”œâ”€ 001 â”€ OPC_MXU_LXH
1691  *          â”œâ”€ 101001 â”€ <not assigned>   â”œâ”€ 011 â”€ OPC_MXU_LXW
1692  *          â”œâ”€ 101010 â”€ OPC_MXU_S16LDD   â”œâ”€ 100 â”€ OPC_MXU_LXBU
1693  *          â”œâ”€ 101011 â”€ OPC_MXU_S16STD   â””─ 101 â”€ OPC_MXU_LXHU
1694  *          â”œâ”€ 101100 â”€ OPC_MXU_S16LDI
1695  *          â”œâ”€ 101101 â”€ OPC_MXU_S16SDI
1696  *          â”œâ”€ 101110 â”€ OPC_MXU_S32M2I
1697  *          â”œâ”€ 101111 â”€ OPC_MXU_S32I2M
1698  *          â”œâ”€ 110000 â”€ OPC_MXU_D32SLL
1699  *          â”œâ”€ 110001 â”€ OPC_MXU_D32SLR      20..18
1700  *          â”œâ”€ 110010 â”€ OPC_MXU_D32SARL  â”Œâ”€ 000 â”€ OPC_MXU_D32SLLV
1701  *          â”œâ”€ 110011 â”€ OPC_MXU_D32SAR   â”œâ”€ 001 â”€ OPC_MXU_D32SLRV
1702  *          â”œâ”€ 110100 â”€ OPC_MXU_Q16SLL   â”œâ”€ 010 â”€ OPC_MXU_D32SARV
1703  *          â”œâ”€ 110101 â”€ OPC_MXU_Q16SLR   â”œâ”€ 011 â”€ OPC_MXU_Q16SLLV
1704  *          â”‚                            â”œâ”€ 100 â”€ OPC_MXU_Q16SLRV
1705  *          â”œâ”€ 110110 â”€ OPC_MXU__POOL18 â”€â”´â”€ 101 â”€ OPC_MXU_Q16SARV
1706  *          â”‚
1707  *          â”œâ”€ 110111 â”€ OPC_MXU_Q16SAR
1708  *          â”‚                               23..22
1709  *          â”œâ”€ 111000 â”€ OPC_MXU__POOL19 â”€â”¬â”€ 00 â”€ OPC_MXU_Q8MUL
1710  *          â”‚                            â””─ 01 â”€ OPC_MXU_Q8MULSU
1711  *          â”‚
1712  *          â”‚                               20..18
1713  *          â”œâ”€ 111001 â”€ OPC_MXU__POOL20 â”€â”¬â”€ 000 â”€ OPC_MXU_Q8MOVZ
1714  *          â”‚                            â”œâ”€ 001 â”€ OPC_MXU_Q8MOVN
1715  *          â”‚                            â”œâ”€ 010 â”€ OPC_MXU_D16MOVZ
1716  *          â”‚                            â”œâ”€ 011 â”€ OPC_MXU_D16MOVN
1717  *          â”‚                            â”œâ”€ 100 â”€ OPC_MXU_S32MOVZ
1718  *          â”‚                            â””─ 101 â”€ OPC_MXU_S32MOVN
1719  *          â”‚
1720  *          â”‚                               23..22
1721  *          â”œâ”€ 111010 â”€ OPC_MXU__POOL21 â”€â”¬â”€ 00 â”€ OPC_MXU_Q8MAC
1722  *          â”‚                            â””─ 10 â”€ OPC_MXU_Q8MACSU
1723  *          â”œâ”€ 111011 â”€ OPC_MXU_Q16SCOP
1724  *          â”œâ”€ 111100 â”€ OPC_MXU_Q8MADL
1725  *          â”œâ”€ 111101 â”€ OPC_MXU_S32SFL
1726  *          â”œâ”€ 111110 â”€ OPC_MXU_Q8SAD
1727  *          â””─ 111111 â”€ <not assigned>   (overlaps with SDBBP)
1728  *
1729  *
1730  * Compiled after:
1731  *
1732  *   "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
1733  *   Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2, 2017
1734  */
1735
1736 enum {
1737     OPC_MXU_S32MADD  = 0x00,
1738     OPC_MXU_S32MADDU = 0x01,
1739     OPC__MXU_MUL     = 0x02,
1740     OPC_MXU__POOL00  = 0x03,
1741     OPC_MXU_S32MSUB  = 0x04,
1742     OPC_MXU_S32MSUBU = 0x05,
1743     OPC_MXU__POOL01  = 0x06,
1744     OPC_MXU__POOL02  = 0x07,
1745     OPC_MXU_D16MUL   = 0x08,
1746     OPC_MXU__POOL03  = 0x09,
1747     OPC_MXU_D16MAC   = 0x0A,
1748     OPC_MXU_D16MACF  = 0x0B,
1749     OPC_MXU_D16MADL  = 0x0C,
1750     OPC_MXU_S16MAD   = 0x0D,
1751     OPC_MXU_Q16ADD   = 0x0E,
1752     OPC_MXU_D16MACE  = 0x0F,
1753     OPC_MXU__POOL04  = 0x10,
1754     OPC_MXU__POOL05  = 0x11,
1755     OPC_MXU__POOL06  = 0x12,
1756     OPC_MXU__POOL07  = 0x13,
1757     OPC_MXU__POOL08  = 0x14,
1758     OPC_MXU__POOL09  = 0x15,
1759     OPC_MXU__POOL10  = 0x16,
1760     OPC_MXU__POOL11  = 0x17,
1761     OPC_MXU_D32ADD   = 0x18,
1762     OPC_MXU__POOL12  = 0x19,
1763     /* not assigned 0x1A */
1764     OPC_MXU__POOL13  = 0x1B,
1765     OPC_MXU__POOL14  = 0x1C,
1766     OPC_MXU_Q8ACCE   = 0x1D,
1767     /* not assigned 0x1E */
1768     /* not assigned 0x1F */
1769     /* not assigned 0x20 */
1770     /* not assigned 0x21 */
1771     OPC_MXU_S8LDD    = 0x22,
1772     OPC_MXU_S8STD    = 0x23,
1773     OPC_MXU_S8LDI    = 0x24,
1774     OPC_MXU_S8SDI    = 0x25,
1775     OPC_MXU__POOL15  = 0x26,
1776     OPC_MXU__POOL16  = 0x27,
1777     OPC_MXU__POOL17  = 0x28,
1778     /* not assigned 0x29 */
1779     OPC_MXU_S16LDD   = 0x2A,
1780     OPC_MXU_S16STD   = 0x2B,
1781     OPC_MXU_S16LDI   = 0x2C,
1782     OPC_MXU_S16SDI   = 0x2D,
1783     OPC_MXU_S32M2I   = 0x2E,
1784     OPC_MXU_S32I2M   = 0x2F,
1785     OPC_MXU_D32SLL   = 0x30,
1786     OPC_MXU_D32SLR   = 0x31,
1787     OPC_MXU_D32SARL  = 0x32,
1788     OPC_MXU_D32SAR   = 0x33,
1789     OPC_MXU_Q16SLL   = 0x34,
1790     OPC_MXU_Q16SLR   = 0x35,
1791     OPC_MXU__POOL18  = 0x36,
1792     OPC_MXU_Q16SAR   = 0x37,
1793     OPC_MXU__POOL19  = 0x38,
1794     OPC_MXU__POOL20  = 0x39,
1795     OPC_MXU__POOL21  = 0x3A,
1796     OPC_MXU_Q16SCOP  = 0x3B,
1797     OPC_MXU_Q8MADL   = 0x3C,
1798     OPC_MXU_S32SFL   = 0x3D,
1799     OPC_MXU_Q8SAD    = 0x3E,
1800     /* not assigned 0x3F */
1801 };
1802
1803
1804 /*
1805  * MXU pool 00
1806  */
1807 enum {
1808     OPC_MXU_S32MAX   = 0x00,
1809     OPC_MXU_S32MIN   = 0x01,
1810     OPC_MXU_D16MAX   = 0x02,
1811     OPC_MXU_D16MIN   = 0x03,
1812     OPC_MXU_Q8MAX    = 0x04,
1813     OPC_MXU_Q8MIN    = 0x05,
1814     OPC_MXU_Q8SLT    = 0x06,
1815     OPC_MXU_Q8SLTU   = 0x07,
1816 };
1817
1818 /*
1819  * MXU pool 01
1820  */
1821 enum {
1822     OPC_MXU_S32SLT   = 0x00,
1823     OPC_MXU_D16SLT   = 0x01,
1824     OPC_MXU_D16AVG   = 0x02,
1825     OPC_MXU_D16AVGR  = 0x03,
1826     OPC_MXU_Q8AVG    = 0x04,
1827     OPC_MXU_Q8AVGR   = 0x05,
1828     OPC_MXU_Q8ADD    = 0x07,
1829 };
1830
1831 /*
1832  * MXU pool 02
1833  */
1834 enum {
1835     OPC_MXU_S32CPS   = 0x00,
1836     OPC_MXU_D16CPS   = 0x02,
1837     OPC_MXU_Q8ABD    = 0x04,
1838     OPC_MXU_Q16SAT   = 0x06,
1839 };
1840
1841 /*
1842  * MXU pool 03
1843  */
1844 enum {
1845     OPC_MXU_D16MULF  = 0x00,
1846     OPC_MXU_D16MULE  = 0x01,
1847 };
1848
1849 /*
1850  * MXU pool 04
1851  */
1852 enum {
1853     OPC_MXU_S32LDD   = 0x00,
1854     OPC_MXU_S32LDDR  = 0x01,
1855 };
1856
1857 /*
1858  * MXU pool 05
1859  */
1860 enum {
1861     OPC_MXU_S32STD   = 0x00,
1862     OPC_MXU_S32STDR  = 0x01,
1863 };
1864
1865 /*
1866  * MXU pool 06
1867  */
1868 enum {
1869     OPC_MXU_S32LDDV  = 0x00,
1870     OPC_MXU_S32LDDVR = 0x01,
1871 };
1872
1873 /*
1874  * MXU pool 07
1875  */
1876 enum {
1877     OPC_MXU_S32STDV  = 0x00,
1878     OPC_MXU_S32STDVR = 0x01,
1879 };
1880
1881 /*
1882  * MXU pool 08
1883  */
1884 enum {
1885     OPC_MXU_S32LDI   = 0x00,
1886     OPC_MXU_S32LDIR  = 0x01,
1887 };
1888
1889 /*
1890  * MXU pool 09
1891  */
1892 enum {
1893     OPC_MXU_S32SDI   = 0x00,
1894     OPC_MXU_S32SDIR  = 0x01,
1895 };
1896
1897 /*
1898  * MXU pool 10
1899  */
1900 enum {
1901     OPC_MXU_S32LDIV  = 0x00,
1902     OPC_MXU_S32LDIVR = 0x01,
1903 };
1904
1905 /*
1906  * MXU pool 11
1907  */
1908 enum {
1909     OPC_MXU_S32SDIV  = 0x00,
1910     OPC_MXU_S32SDIVR = 0x01,
1911 };
1912
1913 /*
1914  * MXU pool 12
1915  */
1916 enum {
1917     OPC_MXU_D32ACC   = 0x00,
1918     OPC_MXU_D32ACCM  = 0x01,
1919     OPC_MXU_D32ASUM  = 0x02,
1920 };
1921
1922 /*
1923  * MXU pool 13
1924  */
1925 enum {
1926     OPC_MXU_Q16ACC   = 0x00,
1927     OPC_MXU_Q16ACCM  = 0x01,
1928     OPC_MXU_Q16ASUM  = 0x02,
1929 };
1930
1931 /*
1932  * MXU pool 14
1933  */
1934 enum {
1935     OPC_MXU_Q8ADDE   = 0x00,
1936     OPC_MXU_D8SUM    = 0x01,
1937     OPC_MXU_D8SUMC   = 0x02,
1938 };
1939
1940 /*
1941  * MXU pool 15
1942  */
1943 enum {
1944     OPC_MXU_S32MUL   = 0x00,
1945     OPC_MXU_S32MULU  = 0x01,
1946     OPC_MXU_S32EXTR  = 0x02,
1947     OPC_MXU_S32EXTRV = 0x03,
1948 };
1949
1950 /*
1951  * MXU pool 16
1952  */
1953 enum {
1954     OPC_MXU_D32SARW  = 0x00,
1955     OPC_MXU_S32ALN   = 0x01,
1956     OPC_MXU_S32ALNI  = 0x02,
1957     OPC_MXU_S32LUI   = 0x03,
1958     OPC_MXU_S32NOR   = 0x04,
1959     OPC_MXU_S32AND   = 0x05,
1960     OPC_MXU_S32OR    = 0x06,
1961     OPC_MXU_S32XOR   = 0x07,
1962 };
1963
1964 /*
1965  * MXU pool 17
1966  */
1967 enum {
1968     OPC_MXU_LXB      = 0x00,
1969     OPC_MXU_LXH      = 0x01,
1970     OPC_MXU_LXW      = 0x03,
1971     OPC_MXU_LXBU     = 0x04,
1972     OPC_MXU_LXHU     = 0x05,
1973 };
1974
1975 /*
1976  * MXU pool 18
1977  */
1978 enum {
1979     OPC_MXU_D32SLLV  = 0x00,
1980     OPC_MXU_D32SLRV  = 0x01,
1981     OPC_MXU_D32SARV  = 0x03,
1982     OPC_MXU_Q16SLLV  = 0x04,
1983     OPC_MXU_Q16SLRV  = 0x05,
1984     OPC_MXU_Q16SARV  = 0x07,
1985 };
1986
1987 /*
1988  * MXU pool 19
1989  */
1990 enum {
1991     OPC_MXU_Q8MUL    = 0x00,
1992     OPC_MXU_Q8MULSU  = 0x01,
1993 };
1994
1995 /*
1996  * MXU pool 20
1997  */
1998 enum {
1999     OPC_MXU_Q8MOVZ   = 0x00,
2000     OPC_MXU_Q8MOVN   = 0x01,
2001     OPC_MXU_D16MOVZ  = 0x02,
2002     OPC_MXU_D16MOVN  = 0x03,
2003     OPC_MXU_S32MOVZ  = 0x04,
2004     OPC_MXU_S32MOVN  = 0x05,
2005 };
2006
2007 /*
2008  * MXU pool 21
2009  */
2010 enum {
2011     OPC_MXU_Q8MAC    = 0x00,
2012     OPC_MXU_Q8MACSU  = 0x01,
2013 };
2014
2015 /*
2016  *     Overview of the TX79-specific instruction set
2017  *     =============================================
2018  *
2019  * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits
2020  * are only used by the specific quadword (128-bit) LQ/SQ load/store
2021  * instructions and certain multimedia instructions (MMIs). These MMIs
2022  * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
2023  * or sixteen 8-bit paths.
2024  *
2025  * Reference:
2026  *
2027  * The Toshiba TX System RISC TX79 Core Architecture manual,
2028  * https://wiki.qemu.org/File:C790.pdf
2029  *
2030  *     Three-Operand Multiply and Multiply-Add (4 instructions)
2031  *     --------------------------------------------------------
2032  * MADD    [rd,] rs, rt      Multiply/Add
2033  * MADDU   [rd,] rs, rt      Multiply/Add Unsigned
2034  * MULT    [rd,] rs, rt      Multiply (3-operand)
2035  * MULTU   [rd,] rs, rt      Multiply Unsigned (3-operand)
2036  *
2037  *     Multiply Instructions for Pipeline 1 (10 instructions)
2038  *     ------------------------------------------------------
2039  * MULT1   [rd,] rs, rt      Multiply Pipeline 1
2040  * MULTU1  [rd,] rs, rt      Multiply Unsigned Pipeline 1
2041  * DIV1    rs, rt            Divide Pipeline 1
2042  * DIVU1   rs, rt            Divide Unsigned Pipeline 1
2043  * MADD1   [rd,] rs, rt      Multiply-Add Pipeline 1
2044  * MADDU1  [rd,] rs, rt      Multiply-Add Unsigned Pipeline 1
2045  * MFHI1   rd                Move From HI1 Register
2046  * MFLO1   rd                Move From LO1 Register
2047  * MTHI1   rs                Move To HI1 Register
2048  * MTLO1   rs                Move To LO1 Register
2049  *
2050  *     Arithmetic (19 instructions)
2051  *     ----------------------------
2052  * PADDB   rd, rs, rt        Parallel Add Byte
2053  * PSUBB   rd, rs, rt        Parallel Subtract Byte
2054  * PADDH   rd, rs, rt        Parallel Add Halfword
2055  * PSUBH   rd, rs, rt        Parallel Subtract Halfword
2056  * PADDW   rd, rs, rt        Parallel Add Word
2057  * PSUBW   rd, rs, rt        Parallel Subtract Word
2058  * PADSBH  rd, rs, rt        Parallel Add/Subtract Halfword
2059  * PADDSB  rd, rs, rt        Parallel Add with Signed Saturation Byte
2060  * PSUBSB  rd, rs, rt        Parallel Subtract with Signed Saturation Byte
2061  * PADDSH  rd, rs, rt        Parallel Add with Signed Saturation Halfword
2062  * PSUBSH  rd, rs, rt        Parallel Subtract with Signed Saturation Halfword
2063  * PADDSW  rd, rs, rt        Parallel Add with Signed Saturation Word
2064  * PSUBSW  rd, rs, rt        Parallel Subtract with Signed Saturation Word
2065  * PADDUB  rd, rs, rt        Parallel Add with Unsigned saturation Byte
2066  * PSUBUB  rd, rs, rt        Parallel Subtract with Unsigned saturation Byte
2067  * PADDUH  rd, rs, rt        Parallel Add with Unsigned saturation Halfword
2068  * PSUBUH  rd, rs, rt        Parallel Subtract with Unsigned saturation Halfword
2069  * PADDUW  rd, rs, rt        Parallel Add with Unsigned saturation Word
2070  * PSUBUW  rd, rs, rt        Parallel Subtract with Unsigned saturation Word
2071  *
2072  *     Min/Max (4 instructions)
2073  *     ------------------------
2074  * PMAXH   rd, rs, rt        Parallel Maximum Halfword
2075  * PMINH   rd, rs, rt        Parallel Minimum Halfword
2076  * PMAXW   rd, rs, rt        Parallel Maximum Word
2077  * PMINW   rd, rs, rt        Parallel Minimum Word
2078  *
2079  *     Absolute (2 instructions)
2080  *     -------------------------
2081  * PABSH   rd, rt            Parallel Absolute Halfword
2082  * PABSW   rd, rt            Parallel Absolute Word
2083  *
2084  *     Logical (4 instructions)
2085  *     ------------------------
2086  * PAND    rd, rs, rt        Parallel AND
2087  * POR     rd, rs, rt        Parallel OR
2088  * PXOR    rd, rs, rt        Parallel XOR
2089  * PNOR    rd, rs, rt        Parallel NOR
2090  *
2091  *     Shift (9 instructions)
2092  *     ----------------------
2093  * PSLLH   rd, rt, sa        Parallel Shift Left Logical Halfword
2094  * PSRLH   rd, rt, sa        Parallel Shift Right Logical Halfword
2095  * PSRAH   rd, rt, sa        Parallel Shift Right Arithmetic Halfword
2096  * PSLLW   rd, rt, sa        Parallel Shift Left Logical Word
2097  * PSRLW   rd, rt, sa        Parallel Shift Right Logical Word
2098  * PSRAW   rd, rt, sa        Parallel Shift Right Arithmetic Word
2099  * PSLLVW  rd, rt, rs        Parallel Shift Left Logical Variable Word
2100  * PSRLVW  rd, rt, rs        Parallel Shift Right Logical Variable Word
2101  * PSRAVW  rd, rt, rs        Parallel Shift Right Arithmetic Variable Word
2102  *
2103  *     Compare (6 instructions)
2104  *     ------------------------
2105  * PCGTB   rd, rs, rt        Parallel Compare for Greater Than Byte
2106  * PCEQB   rd, rs, rt        Parallel Compare for Equal Byte
2107  * PCGTH   rd, rs, rt        Parallel Compare for Greater Than Halfword
2108  * PCEQH   rd, rs, rt        Parallel Compare for Equal Halfword
2109  * PCGTW   rd, rs, rt        Parallel Compare for Greater Than Word
2110  * PCEQW   rd, rs, rt        Parallel Compare for Equal Word
2111  *
2112  *     LZC (1 instruction)
2113  *     -------------------
2114  * PLZCW   rd, rs            Parallel Leading Zero or One Count Word
2115  *
2116  *     Quadword Load and Store (2 instructions)
2117  *     ----------------------------------------
2118  * LQ      rt, offset(base)  Load Quadword
2119  * SQ      rt, offset(base)  Store Quadword
2120  *
2121  *     Multiply and Divide (19 instructions)
2122  *     -------------------------------------
2123  * PMULTW  rd, rs, rt        Parallel Multiply Word
2124  * PMULTUW rd, rs, rt        Parallel Multiply Unsigned Word
2125  * PDIVW   rs, rt            Parallel Divide Word
2126  * PDIVUW  rs, rt            Parallel Divide Unsigned Word
2127  * PMADDW  rd, rs, rt        Parallel Multiply-Add Word
2128  * PMADDUW rd, rs, rt        Parallel Multiply-Add Unsigned Word
2129  * PMSUBW  rd, rs, rt        Parallel Multiply-Subtract Word
2130  * PMULTH  rd, rs, rt        Parallel Multiply Halfword
2131  * PMADDH  rd, rs, rt        Parallel Multiply-Add Halfword
2132  * PMSUBH  rd, rs, rt        Parallel Multiply-Subtract Halfword
2133  * PHMADH  rd, rs, rt        Parallel Horizontal Multiply-Add Halfword
2134  * PHMSBH  rd, rs, rt        Parallel Horizontal Multiply-Subtract Halfword
2135  * PDIVBW  rs, rt            Parallel Divide Broadcast Word
2136  * PMFHI   rd                Parallel Move From HI Register
2137  * PMFLO   rd                Parallel Move From LO Register
2138  * PMTHI   rs                Parallel Move To HI Register
2139  * PMTLO   rs                Parallel Move To LO Register
2140  * PMFHL   rd                Parallel Move From HI/LO Register
2141  * PMTHL   rs                Parallel Move To HI/LO Register
2142  *
2143  *     Pack/Extend (11 instructions)
2144  *     -----------------------------
2145  * PPAC5   rd, rt            Parallel Pack to 5 bits
2146  * PPACB   rd, rs, rt        Parallel Pack to Byte
2147  * PPACH   rd, rs, rt        Parallel Pack to Halfword
2148  * PPACW   rd, rs, rt        Parallel Pack to Word
2149  * PEXT5   rd, rt            Parallel Extend Upper from 5 bits
2150  * PEXTUB  rd, rs, rt        Parallel Extend Upper from Byte
2151  * PEXTLB  rd, rs, rt        Parallel Extend Lower from Byte
2152  * PEXTUH  rd, rs, rt        Parallel Extend Upper from Halfword
2153  * PEXTLH  rd, rs, rt        Parallel Extend Lower from Halfword
2154  * PEXTUW  rd, rs, rt        Parallel Extend Upper from Word
2155  * PEXTLW  rd, rs, rt        Parallel Extend Lower from Word
2156  *
2157  *     Others (16 instructions)
2158  *     ------------------------
2159  * PCPYH   rd, rt            Parallel Copy Halfword
2160  * PCPYLD  rd, rs, rt        Parallel Copy Lower Doubleword
2161  * PCPYUD  rd, rs, rt        Parallel Copy Upper Doubleword
2162  * PREVH   rd, rt            Parallel Reverse Halfword
2163  * PINTH   rd, rs, rt        Parallel Interleave Halfword
2164  * PINTEH  rd, rs, rt        Parallel Interleave Even Halfword
2165  * PEXEH   rd, rt            Parallel Exchange Even Halfword
2166  * PEXCH   rd, rt            Parallel Exchange Center Halfword
2167  * PEXEW   rd, rt            Parallel Exchange Even Word
2168  * PEXCW   rd, rt            Parallel Exchange Center Word
2169  * QFSRV   rd, rs, rt        Quadword Funnel Shift Right Variable
2170  * MFSA    rd                Move from Shift Amount Register
2171  * MTSA    rs                Move to Shift Amount Register
2172  * MTSAB   rs, immediate     Move Byte Count to Shift Amount Register
2173  * MTSAH   rs, immediate     Move Halfword Count to Shift Amount Register
2174  * PROT3W  rd, rt            Parallel Rotate 3 Words
2175  *
2176  *     MMI (MultiMedia Instruction) encodings
2177  *     ======================================
2178  *
2179  * MMI instructions encoding table keys:
2180  *
2181  *     *   This code is reserved for future use. An attempt to execute it
2182  *         causes a Reserved Instruction exception.
2183  *     %   This code indicates an instruction class. The instruction word
2184  *         must be further decoded by examining additional tables that show
2185  *         the values for other instruction fields.
2186  *     #   This code is reserved for the unsupported instructions DMULT,
2187  *         DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
2188  *         to execute it causes a Reserved Instruction exception.
2189  *
2190  * MMI instructions encoded by opcode field (MMI, LQ, SQ):
2191  *
2192  *  31    26                                        0
2193  * +--------+----------------------------------------+
2194  * | opcode |                                        |
2195  * +--------+----------------------------------------+
2196  *
2197  *   opcode  bits 28..26
2198  *     bits |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7
2199  *   31..29 |  000  |  001  |  010  |  011  |  100  |  101  |  110  |  111
2200  *   -------+-------+-------+-------+-------+-------+-------+-------+-------
2201  *    0 000 |SPECIAL| REGIMM|   J   |  JAL  |  BEQ  |  BNE  |  BLEZ |  BGTZ
2202  *    1 001 |  ADDI | ADDIU |  SLTI | SLTIU |  ANDI |  ORI  |  XORI |  LUI
2203  *    2 010 |  COP0 |  COP1 |   *   |   *   |  BEQL |  BNEL | BLEZL | BGTZL
2204  *    3 011 | DADDI | DADDIU|  LDL  |  LDR  |  MMI% |   *   |   LQ  |   SQ
2205  *    4 100 |   LB  |   LH  |  LWL  |   LW  |  LBU  |  LHU  |  LWR  |  LWU
2206  *    5 101 |   SB  |   SH  |  SWL  |   SW  |  SDL  |  SDR  |  SWR  | CACHE
2207  *    6 110 |   #   |  LWC1 |   #   |  PREF |   #   |  LDC1 |   #   |   LD
2208  *    7 111 |   #   |  SWC1 |   #   |   *   |   #   |  SDC1 |   #   |   SD
2209  */
2210
2211 enum {
2212     MMI_OPC_CLASS_MMI = 0x1C << 26,    /* Same as OPC_SPECIAL2 */
2213     MMI_OPC_LQ        = 0x1E << 26,    /* Same as OPC_MSA */
2214     MMI_OPC_SQ        = 0x1F << 26,    /* Same as OPC_SPECIAL3 */
2215 };
2216
2217 /*
2218  * MMI instructions with opcode field = MMI:
2219  *
2220  *  31    26                                 5      0
2221  * +--------+-------------------------------+--------+
2222  * |   MMI  |                               |function|
2223  * +--------+-------------------------------+--------+
2224  *
2225  * function  bits 2..0
2226  *     bits |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7
2227  *     5..3 |  000  |  001  |  010  |  011  |  100  |  101  |  110  |  111
2228  *   -------+-------+-------+-------+-------+-------+-------+-------+-------
2229  *    0 000 |  MADD | MADDU |   *   |   *   | PLZCW |   *   |   *   |   *
2230  *    1 001 | MMI0% | MMI2% |   *   |   *   |   *   |   *   |   *   |   *
2231  *    2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 |   *   |   *   |   *   |   *
2232  *    3 011 | MULT1 | MULTU1|  DIV1 | DIVU1 |   *   |   *   |   *   |   *
2233  *    4 100 | MADD1 | MADDU1|   *   |   *   |   *   |   *   |   *   |   *
2234  *    5 101 | MMI1% | MMI3% |   *   |   *   |   *   |   *   |   *   |   *
2235  *    6 110 | PMFHL | PMTHL |   *   |   *   | PSLLH |   *   | PSRLH | PSRAH
2236  *    7 111 |   *   |   *   |   *   |   *   | PSLLW |   *   | PSRLW | PSRAW
2237  */
2238
2239 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
2240 enum {
2241     MMI_OPC_MADD       = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */
2242     MMI_OPC_MADDU      = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */
2243     MMI_OPC_PLZCW      = 0x04 | MMI_OPC_CLASS_MMI,
2244     MMI_OPC_CLASS_MMI0 = 0x08 | MMI_OPC_CLASS_MMI,
2245     MMI_OPC_CLASS_MMI2 = 0x09 | MMI_OPC_CLASS_MMI,
2246     MMI_OPC_MFHI1      = 0x10 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MFHI */
2247     MMI_OPC_MTHI1      = 0x11 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MTHI */
2248     MMI_OPC_MFLO1      = 0x12 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MFLO */
2249     MMI_OPC_MTLO1      = 0x13 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MTLO */
2250     MMI_OPC_MULT1      = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */
2251     MMI_OPC_MULTU1     = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */
2252     MMI_OPC_DIV1       = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV  */
2253     MMI_OPC_DIVU1      = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */
2254     MMI_OPC_MADD1      = 0x20 | MMI_OPC_CLASS_MMI,
2255     MMI_OPC_MADDU1     = 0x21 | MMI_OPC_CLASS_MMI,
2256     MMI_OPC_CLASS_MMI1 = 0x28 | MMI_OPC_CLASS_MMI,
2257     MMI_OPC_CLASS_MMI3 = 0x29 | MMI_OPC_CLASS_MMI,
2258     MMI_OPC_PMFHL      = 0x30 | MMI_OPC_CLASS_MMI,
2259     MMI_OPC_PMTHL      = 0x31 | MMI_OPC_CLASS_MMI,
2260     MMI_OPC_PSLLH      = 0x34 | MMI_OPC_CLASS_MMI,
2261     MMI_OPC_PSRLH      = 0x36 | MMI_OPC_CLASS_MMI,
2262     MMI_OPC_PSRAH      = 0x37 | MMI_OPC_CLASS_MMI,
2263     MMI_OPC_PSLLW      = 0x3C | MMI_OPC_CLASS_MMI,
2264     MMI_OPC_PSRLW      = 0x3E | MMI_OPC_CLASS_MMI,
2265     MMI_OPC_PSRAW      = 0x3F | MMI_OPC_CLASS_MMI,
2266 };
2267
2268 /*
2269  * MMI instructions with opcode field = MMI and bits 5..0 = MMI0:
2270  *
2271  *  31    26                        10     6 5      0
2272  * +--------+----------------------+--------+--------+
2273  * |   MMI  |                      |function|  MMI0  |
2274  * +--------+----------------------+--------+--------+
2275  *
2276  * function  bits 7..6
2277  *     bits |   0   |   1   |   2   |   3
2278  *    10..8 |   00  |   01  |   10  |   11
2279  *   -------+-------+-------+-------+-------
2280  *    0 000 | PADDW | PSUBW | PCGTW | PMAXW
2281  *    1 001 | PADDH | PSUBH | PCGTH | PMAXH
2282  *    2 010 | PADDB | PSUBB | PCGTB |   *
2283  *    3 011 |   *   |   *   |   *   |   *
2284  *    4 100 | PADDSW| PSUBSW| PEXTLW| PPACW
2285  *    5 101 | PADDSH| PSUBSH| PEXTLH| PPACH
2286  *    6 110 | PADDSB| PSUBSB| PEXTLB| PPACB
2287  *    7 111 |   *   |   *   | PEXT5 | PPAC5
2288  */
2289
2290 #define MASK_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2291 enum {
2292     MMI_OPC_0_PADDW  = (0x00 << 6) | MMI_OPC_CLASS_MMI0,
2293     MMI_OPC_0_PSUBW  = (0x01 << 6) | MMI_OPC_CLASS_MMI0,
2294     MMI_OPC_0_PCGTW  = (0x02 << 6) | MMI_OPC_CLASS_MMI0,
2295     MMI_OPC_0_PMAXW  = (0x03 << 6) | MMI_OPC_CLASS_MMI0,
2296     MMI_OPC_0_PADDH  = (0x04 << 6) | MMI_OPC_CLASS_MMI0,
2297     MMI_OPC_0_PSUBH  = (0x05 << 6) | MMI_OPC_CLASS_MMI0,
2298     MMI_OPC_0_PCGTH  = (0x06 << 6) | MMI_OPC_CLASS_MMI0,
2299     MMI_OPC_0_PMAXH  = (0x07 << 6) | MMI_OPC_CLASS_MMI0,
2300     MMI_OPC_0_PADDB  = (0x08 << 6) | MMI_OPC_CLASS_MMI0,
2301     MMI_OPC_0_PSUBB  = (0x09 << 6) | MMI_OPC_CLASS_MMI0,
2302     MMI_OPC_0_PCGTB  = (0x0A << 6) | MMI_OPC_CLASS_MMI0,
2303     MMI_OPC_0_PADDSW = (0x10 << 6) | MMI_OPC_CLASS_MMI0,
2304     MMI_OPC_0_PSUBSW = (0x11 << 6) | MMI_OPC_CLASS_MMI0,
2305     MMI_OPC_0_PEXTLW = (0x12 << 6) | MMI_OPC_CLASS_MMI0,
2306     MMI_OPC_0_PPACW  = (0x13 << 6) | MMI_OPC_CLASS_MMI0,
2307     MMI_OPC_0_PADDSH = (0x14 << 6) | MMI_OPC_CLASS_MMI0,
2308     MMI_OPC_0_PSUBSH = (0x15 << 6) | MMI_OPC_CLASS_MMI0,
2309     MMI_OPC_0_PEXTLH = (0x16 << 6) | MMI_OPC_CLASS_MMI0,
2310     MMI_OPC_0_PPACH  = (0x17 << 6) | MMI_OPC_CLASS_MMI0,
2311     MMI_OPC_0_PADDSB = (0x18 << 6) | MMI_OPC_CLASS_MMI0,
2312     MMI_OPC_0_PSUBSB = (0x19 << 6) | MMI_OPC_CLASS_MMI0,
2313     MMI_OPC_0_PEXTLB = (0x1A << 6) | MMI_OPC_CLASS_MMI0,
2314     MMI_OPC_0_PPACB  = (0x1B << 6) | MMI_OPC_CLASS_MMI0,
2315     MMI_OPC_0_PEXT5  = (0x1E << 6) | MMI_OPC_CLASS_MMI0,
2316     MMI_OPC_0_PPAC5  = (0x1F << 6) | MMI_OPC_CLASS_MMI0,
2317 };
2318
2319 /*
2320  * MMI instructions with opcode field = MMI and bits 5..0 = MMI1:
2321  *
2322  *  31    26                        10     6 5      0
2323  * +--------+----------------------+--------+--------+
2324  * |   MMI  |                      |function|  MMI1  |
2325  * +--------+----------------------+--------+--------+
2326  *
2327  * function  bits 7..6
2328  *     bits |   0   |   1   |   2   |   3
2329  *    10..8 |   00  |   01  |   10  |   11
2330  *   -------+-------+-------+-------+-------
2331  *    0 000 |   *   | PABSW | PCEQW | PMINW
2332  *    1 001 | PADSBH| PABSH | PCEQH | PMINH
2333  *    2 010 |   *   |   *   | PCEQB |   *
2334  *    3 011 |   *   |   *   |   *   |   *
2335  *    4 100 | PADDUW| PSUBUW| PEXTUW|   *
2336  *    5 101 | PADDUH| PSUBUH| PEXTUH|   *
2337  *    6 110 | PADDUB| PSUBUB| PEXTUB| QFSRV
2338  *    7 111 |   *   |   *   |   *   |   *
2339  */
2340
2341 #define MASK_MMI1(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2342 enum {
2343     MMI_OPC_1_PABSW  = (0x01 << 6) | MMI_OPC_CLASS_MMI1,
2344     MMI_OPC_1_PCEQW  = (0x02 << 6) | MMI_OPC_CLASS_MMI1,
2345     MMI_OPC_1_PMINW  = (0x03 << 6) | MMI_OPC_CLASS_MMI1,
2346     MMI_OPC_1_PADSBH = (0x04 << 6) | MMI_OPC_CLASS_MMI1,
2347     MMI_OPC_1_PABSH  = (0x05 << 6) | MMI_OPC_CLASS_MMI1,
2348     MMI_OPC_1_PCEQH  = (0x06 << 6) | MMI_OPC_CLASS_MMI1,
2349     MMI_OPC_1_PMINH  = (0x07 << 6) | MMI_OPC_CLASS_MMI1,
2350     MMI_OPC_1_PCEQB  = (0x0A << 6) | MMI_OPC_CLASS_MMI1,
2351     MMI_OPC_1_PADDUW = (0x10 << 6) | MMI_OPC_CLASS_MMI1,
2352     MMI_OPC_1_PSUBUW = (0x11 << 6) | MMI_OPC_CLASS_MMI1,
2353     MMI_OPC_1_PEXTUW = (0x12 << 6) | MMI_OPC_CLASS_MMI1,
2354     MMI_OPC_1_PADDUH = (0x14 << 6) | MMI_OPC_CLASS_MMI1,
2355     MMI_OPC_1_PSUBUH = (0x15 << 6) | MMI_OPC_CLASS_MMI1,
2356     MMI_OPC_1_PEXTUH = (0x16 << 6) | MMI_OPC_CLASS_MMI1,
2357     MMI_OPC_1_PADDUB = (0x18 << 6) | MMI_OPC_CLASS_MMI1,
2358     MMI_OPC_1_PSUBUB = (0x19 << 6) | MMI_OPC_CLASS_MMI1,
2359     MMI_OPC_1_PEXTUB = (0x1A << 6) | MMI_OPC_CLASS_MMI1,
2360     MMI_OPC_1_QFSRV  = (0x1B << 6) | MMI_OPC_CLASS_MMI1,
2361 };
2362
2363 /*
2364  * MMI instructions with opcode field = MMI and bits 5..0 = MMI2:
2365  *
2366  *  31    26                        10     6 5      0
2367  * +--------+----------------------+--------+--------+
2368  * |   MMI  |                      |function|  MMI2  |
2369  * +--------+----------------------+--------+--------+
2370  *
2371  * function  bits 7..6
2372  *     bits |   0   |   1   |   2   |   3
2373  *    10..8 |   00  |   01  |   10  |   11
2374  *   -------+-------+-------+-------+-------
2375  *    0 000 | PMADDW|   *   | PSLLVW| PSRLVW
2376  *    1 001 | PMSUBW|   *   |   *   |   *
2377  *    2 010 | PMFHI | PMFLO | PINTH |   *
2378  *    3 011 | PMULTW| PDIVW | PCPYLD|   *
2379  *    4 100 | PMADDH| PHMADH|  PAND |  PXOR
2380  *    5 101 | PMSUBH| PHMSBH|   *   |   *
2381  *    6 110 |   *   |   *   | PEXEH | PREVH
2382  *    7 111 | PMULTH| PDIVBW| PEXEW | PROT3W
2383  */
2384
2385 #define MASK_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2386 enum {
2387     MMI_OPC_2_PMADDW = (0x00 << 6) | MMI_OPC_CLASS_MMI2,
2388     MMI_OPC_2_PSLLVW = (0x02 << 6) | MMI_OPC_CLASS_MMI2,
2389     MMI_OPC_2_PSRLVW = (0x03 << 6) | MMI_OPC_CLASS_MMI2,
2390     MMI_OPC_2_PMSUBW = (0x04 << 6) | MMI_OPC_CLASS_MMI2,
2391     MMI_OPC_2_PMFHI  = (0x08 << 6) | MMI_OPC_CLASS_MMI2,
2392     MMI_OPC_2_PMFLO  = (0x09 << 6) | MMI_OPC_CLASS_MMI2,
2393     MMI_OPC_2_PINTH  = (0x0A << 6) | MMI_OPC_CLASS_MMI2,
2394     MMI_OPC_2_PMULTW = (0x0C << 6) | MMI_OPC_CLASS_MMI2,
2395     MMI_OPC_2_PDIVW  = (0x0D << 6) | MMI_OPC_CLASS_MMI2,
2396     MMI_OPC_2_PCPYLD = (0x0E << 6) | MMI_OPC_CLASS_MMI2,
2397     MMI_OPC_2_PMADDH = (0x10 << 6) | MMI_OPC_CLASS_MMI2,
2398     MMI_OPC_2_PHMADH = (0x11 << 6) | MMI_OPC_CLASS_MMI2,
2399     MMI_OPC_2_PAND   = (0x12 << 6) | MMI_OPC_CLASS_MMI2,
2400     MMI_OPC_2_PXOR   = (0x13 << 6) | MMI_OPC_CLASS_MMI2,
2401     MMI_OPC_2_PMSUBH = (0x14 << 6) | MMI_OPC_CLASS_MMI2,
2402     MMI_OPC_2_PHMSBH = (0x15 << 6) | MMI_OPC_CLASS_MMI2,
2403     MMI_OPC_2_PEXEH  = (0x1A << 6) | MMI_OPC_CLASS_MMI2,
2404     MMI_OPC_2_PREVH  = (0x1B << 6) | MMI_OPC_CLASS_MMI2,
2405     MMI_OPC_2_PMULTH = (0x1C << 6) | MMI_OPC_CLASS_MMI2,
2406     MMI_OPC_2_PDIVBW = (0x1D << 6) | MMI_OPC_CLASS_MMI2,
2407     MMI_OPC_2_PEXEW  = (0x1E << 6) | MMI_OPC_CLASS_MMI2,
2408     MMI_OPC_2_PROT3W = (0x1F << 6) | MMI_OPC_CLASS_MMI2,
2409 };
2410
2411 /*
2412  * MMI instructions with opcode field = MMI and bits 5..0 = MMI3:
2413  *
2414  *  31    26                        10     6 5      0
2415  * +--------+----------------------+--------+--------+
2416  * |   MMI  |                      |function|  MMI3  |
2417  * +--------+----------------------+--------+--------+
2418  *
2419  * function  bits 7..6
2420  *     bits |   0   |   1   |   2   |   3
2421  *    10..8 |   00  |   01  |   10  |   11
2422  *   -------+-------+-------+-------+-------
2423  *    0 000 |PMADDUW|   *   |   *   | PSRAVW
2424  *    1 001 |   *   |   *   |   *   |   *
2425  *    2 010 | PMTHI | PMTLO | PINTEH|   *
2426  *    3 011 |PMULTUW| PDIVUW| PCPYUD|   *
2427  *    4 100 |   *   |   *   |  POR  |  PNOR
2428  *    5 101 |   *   |   *   |   *   |   *
2429  *    6 110 |   *   |   *   | PEXCH | PCPYH
2430  *    7 111 |   *   |   *   | PEXCW |   *
2431  */
2432
2433 #define MASK_MMI3(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2434 enum {
2435     MMI_OPC_3_PMADDUW = (0x00 << 6) | MMI_OPC_CLASS_MMI3,
2436     MMI_OPC_3_PSRAVW  = (0x03 << 6) | MMI_OPC_CLASS_MMI3,
2437     MMI_OPC_3_PMTHI   = (0x08 << 6) | MMI_OPC_CLASS_MMI3,
2438     MMI_OPC_3_PMTLO   = (0x09 << 6) | MMI_OPC_CLASS_MMI3,
2439     MMI_OPC_3_PINTEH  = (0x0A << 6) | MMI_OPC_CLASS_MMI3,
2440     MMI_OPC_3_PMULTUW = (0x0C << 6) | MMI_OPC_CLASS_MMI3,
2441     MMI_OPC_3_PDIVUW  = (0x0D << 6) | MMI_OPC_CLASS_MMI3,
2442     MMI_OPC_3_PCPYUD  = (0x0E << 6) | MMI_OPC_CLASS_MMI3,
2443     MMI_OPC_3_POR     = (0x12 << 6) | MMI_OPC_CLASS_MMI3,
2444     MMI_OPC_3_PNOR    = (0x13 << 6) | MMI_OPC_CLASS_MMI3,
2445     MMI_OPC_3_PEXCH   = (0x1A << 6) | MMI_OPC_CLASS_MMI3,
2446     MMI_OPC_3_PCPYH   = (0x1B << 6) | MMI_OPC_CLASS_MMI3,
2447     MMI_OPC_3_PEXCW   = (0x1E << 6) | MMI_OPC_CLASS_MMI3,
2448 };
2449
2450 /* global register indices */
2451 static TCGv cpu_gpr[32], cpu_PC;
2452 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
2453 static TCGv cpu_dspctrl, btarget, bcond;
2454 static TCGv cpu_lladdr, cpu_llval;
2455 static TCGv_i32 hflags;
2456 static TCGv_i32 fpu_fcr0, fpu_fcr31;
2457 static TCGv_i64 fpu_f64[32];
2458 static TCGv_i64 msa_wr_d[64];
2459
2460 #if defined(TARGET_MIPS64)
2461 /* Upper halves of R5900's 128-bit registers: MMRs (multimedia registers) */
2462 static TCGv_i64 cpu_mmr[32];
2463 #endif
2464
2465 #if !defined(TARGET_MIPS64)
2466 /* MXU registers */
2467 static TCGv mxu_gpr[NUMBER_OF_MXU_REGISTERS - 1];
2468 static TCGv mxu_CR;
2469 #endif
2470
2471 #include "exec/gen-icount.h"
2472
2473 #define gen_helper_0e0i(name, arg) do {                           \
2474     TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
2475     gen_helper_##name(cpu_env, helper_tmp);                       \
2476     tcg_temp_free_i32(helper_tmp);                                \
2477     } while(0)
2478
2479 #define gen_helper_0e1i(name, arg1, arg2) do {                    \
2480     TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
2481     gen_helper_##name(cpu_env, arg1, helper_tmp);                 \
2482     tcg_temp_free_i32(helper_tmp);                                \
2483     } while(0)
2484
2485 #define gen_helper_1e0i(name, ret, arg1) do {                     \
2486     TCGv_i32 helper_tmp = tcg_const_i32(arg1);                    \
2487     gen_helper_##name(ret, cpu_env, helper_tmp);                  \
2488     tcg_temp_free_i32(helper_tmp);                                \
2489     } while(0)
2490
2491 #define gen_helper_1e1i(name, ret, arg1, arg2) do {               \
2492     TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
2493     gen_helper_##name(ret, cpu_env, arg1, helper_tmp);            \
2494     tcg_temp_free_i32(helper_tmp);                                \
2495     } while(0)
2496
2497 #define gen_helper_0e2i(name, arg1, arg2, arg3) do {              \
2498     TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
2499     gen_helper_##name(cpu_env, arg1, arg2, helper_tmp);           \
2500     tcg_temp_free_i32(helper_tmp);                                \
2501     } while(0)
2502
2503 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do {         \
2504     TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
2505     gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp);      \
2506     tcg_temp_free_i32(helper_tmp);                                \
2507     } while(0)
2508
2509 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do {        \
2510     TCGv_i32 helper_tmp = tcg_const_i32(arg4);                    \
2511     gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp);     \
2512     tcg_temp_free_i32(helper_tmp);                                \
2513     } while(0)
2514
2515 typedef struct DisasContext {
2516     DisasContextBase base;
2517     target_ulong saved_pc;
2518     target_ulong page_start;
2519     uint32_t opcode;
2520     uint64_t insn_flags;
2521     int32_t CP0_Config1;
2522     int32_t CP0_Config2;
2523     int32_t CP0_Config3;
2524     int32_t CP0_Config5;
2525     /* Routine used to access memory */
2526     int mem_idx;
2527     TCGMemOp default_tcg_memop_mask;
2528     uint32_t hflags, saved_hflags;
2529     target_ulong btarget;
2530     bool ulri;
2531     int kscrexist;
2532     bool rxi;
2533     int ie;
2534     bool bi;
2535     bool bp;
2536     uint64_t PAMask;
2537     bool mvh;
2538     bool eva;
2539     bool sc;
2540     int CP0_LLAddr_shift;
2541     bool ps;
2542     bool vp;
2543     bool cmgcr;
2544     bool mrp;
2545     bool nan2008;
2546     bool abs2008;
2547     bool saar;
2548 } DisasContext;
2549
2550 #define DISAS_STOP       DISAS_TARGET_0
2551 #define DISAS_EXIT       DISAS_TARGET_1
2552
2553 static const char * const regnames[] = {
2554     "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2555     "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2556     "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2557     "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2558 };
2559
2560 static const char * const regnames_HI[] = {
2561     "HI0", "HI1", "HI2", "HI3",
2562 };
2563
2564 static const char * const regnames_LO[] = {
2565     "LO0", "LO1", "LO2", "LO3",
2566 };
2567
2568 static const char * const fregnames[] = {
2569     "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
2570     "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
2571     "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2572     "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2573 };
2574
2575 static const char * const msaregnames[] = {
2576     "w0.d0",  "w0.d1",  "w1.d0",  "w1.d1",
2577     "w2.d0",  "w2.d1",  "w3.d0",  "w3.d1",
2578     "w4.d0",  "w4.d1",  "w5.d0",  "w5.d1",
2579     "w6.d0",  "w6.d1",  "w7.d0",  "w7.d1",
2580     "w8.d0",  "w8.d1",  "w9.d0",  "w9.d1",
2581     "w10.d0", "w10.d1", "w11.d0", "w11.d1",
2582     "w12.d0", "w12.d1", "w13.d0", "w13.d1",
2583     "w14.d0", "w14.d1", "w15.d0", "w15.d1",
2584     "w16.d0", "w16.d1", "w17.d0", "w17.d1",
2585     "w18.d0", "w18.d1", "w19.d0", "w19.d1",
2586     "w20.d0", "w20.d1", "w21.d0", "w21.d1",
2587     "w22.d0", "w22.d1", "w23.d0", "w23.d1",
2588     "w24.d0", "w24.d1", "w25.d0", "w25.d1",
2589     "w26.d0", "w26.d1", "w27.d0", "w27.d1",
2590     "w28.d0", "w28.d1", "w29.d0", "w29.d1",
2591     "w30.d0", "w30.d1", "w31.d0", "w31.d1",
2592 };
2593
2594 #if !defined(TARGET_MIPS64)
2595 static const char * const mxuregnames[] = {
2596     "XR1",  "XR2",  "XR3",  "XR4",  "XR5",  "XR6",  "XR7",  "XR8",
2597     "XR9",  "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
2598 };
2599 #endif
2600
2601 #define LOG_DISAS(...)                                                        \
2602     do {                                                                      \
2603         if (MIPS_DEBUG_DISAS) {                                               \
2604             qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__);                 \
2605         }                                                                     \
2606     } while (0)
2607
2608 #define MIPS_INVAL(op)                                                        \
2609     do {                                                                      \
2610         if (MIPS_DEBUG_DISAS) {                                               \
2611             qemu_log_mask(CPU_LOG_TB_IN_ASM,                                  \
2612                           TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
2613                           ctx->base.pc_next, ctx->opcode, op,                 \
2614                           ctx->opcode >> 26, ctx->opcode & 0x3F,              \
2615                           ((ctx->opcode >> 16) & 0x1F));                      \
2616         }                                                                     \
2617     } while (0)
2618
2619 /* General purpose registers moves. */
2620 static inline void gen_load_gpr (TCGv t, int reg)
2621 {
2622     if (reg == 0)
2623         tcg_gen_movi_tl(t, 0);
2624     else
2625         tcg_gen_mov_tl(t, cpu_gpr[reg]);
2626 }
2627
2628 static inline void gen_store_gpr (TCGv t, int reg)
2629 {
2630     if (reg != 0)
2631         tcg_gen_mov_tl(cpu_gpr[reg], t);
2632 }
2633
2634 /* Moves to/from shadow registers. */
2635 static inline void gen_load_srsgpr (int from, int to)
2636 {
2637     TCGv t0 = tcg_temp_new();
2638
2639     if (from == 0)
2640         tcg_gen_movi_tl(t0, 0);
2641     else {
2642         TCGv_i32 t2 = tcg_temp_new_i32();
2643         TCGv_ptr addr = tcg_temp_new_ptr();
2644
2645         tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2646         tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2647         tcg_gen_andi_i32(t2, t2, 0xf);
2648         tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2649         tcg_gen_ext_i32_ptr(addr, t2);
2650         tcg_gen_add_ptr(addr, cpu_env, addr);
2651
2652         tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
2653         tcg_temp_free_ptr(addr);
2654         tcg_temp_free_i32(t2);
2655     }
2656     gen_store_gpr(t0, to);
2657     tcg_temp_free(t0);
2658 }
2659
2660 static inline void gen_store_srsgpr (int from, int to)
2661 {
2662     if (to != 0) {
2663         TCGv t0 = tcg_temp_new();
2664         TCGv_i32 t2 = tcg_temp_new_i32();
2665         TCGv_ptr addr = tcg_temp_new_ptr();
2666
2667         gen_load_gpr(t0, from);
2668         tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2669         tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2670         tcg_gen_andi_i32(t2, t2, 0xf);
2671         tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2672         tcg_gen_ext_i32_ptr(addr, t2);
2673         tcg_gen_add_ptr(addr, cpu_env, addr);
2674
2675         tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
2676         tcg_temp_free_ptr(addr);
2677         tcg_temp_free_i32(t2);
2678         tcg_temp_free(t0);
2679     }
2680 }
2681
2682 #if !defined(TARGET_MIPS64)
2683 /* MXU General purpose registers moves. */
2684 static inline void gen_load_mxu_gpr(TCGv t, unsigned int reg)
2685 {
2686     if (reg == 0) {
2687         tcg_gen_movi_tl(t, 0);
2688     } else if (reg <= 15) {
2689         tcg_gen_mov_tl(t, mxu_gpr[reg - 1]);
2690     }
2691 }
2692
2693 static inline void gen_store_mxu_gpr(TCGv t, unsigned int reg)
2694 {
2695     if (reg > 0 && reg <= 15) {
2696         tcg_gen_mov_tl(mxu_gpr[reg - 1], t);
2697     }
2698 }
2699
2700 /* MXU control register moves. */
2701 static inline void gen_load_mxu_cr(TCGv t)
2702 {
2703     tcg_gen_mov_tl(t, mxu_CR);
2704 }
2705
2706 static inline void gen_store_mxu_cr(TCGv t)
2707 {
2708     /* TODO: Add handling of RW rules for MXU_CR. */
2709     tcg_gen_mov_tl(mxu_CR, t);
2710 }
2711 #endif
2712
2713
2714 /* Tests */
2715 static inline void gen_save_pc(target_ulong pc)
2716 {
2717     tcg_gen_movi_tl(cpu_PC, pc);
2718 }
2719
2720 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
2721 {
2722     LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
2723     if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
2724         gen_save_pc(ctx->base.pc_next);
2725         ctx->saved_pc = ctx->base.pc_next;
2726     }
2727     if (ctx->hflags != ctx->saved_hflags) {
2728         tcg_gen_movi_i32(hflags, ctx->hflags);
2729         ctx->saved_hflags = ctx->hflags;
2730         switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2731         case MIPS_HFLAG_BR:
2732             break;
2733         case MIPS_HFLAG_BC:
2734         case MIPS_HFLAG_BL:
2735         case MIPS_HFLAG_B:
2736             tcg_gen_movi_tl(btarget, ctx->btarget);
2737             break;
2738         }
2739     }
2740 }
2741
2742 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
2743 {
2744     ctx->saved_hflags = ctx->hflags;
2745     switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2746     case MIPS_HFLAG_BR:
2747         break;
2748     case MIPS_HFLAG_BC:
2749     case MIPS_HFLAG_BL:
2750     case MIPS_HFLAG_B:
2751         ctx->btarget = env->btarget;
2752         break;
2753     }
2754 }
2755
2756 static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
2757 {
2758     TCGv_i32 texcp = tcg_const_i32(excp);
2759     TCGv_i32 terr = tcg_const_i32(err);
2760     save_cpu_state(ctx, 1);
2761     gen_helper_raise_exception_err(cpu_env, texcp, terr);
2762     tcg_temp_free_i32(terr);
2763     tcg_temp_free_i32(texcp);
2764     ctx->base.is_jmp = DISAS_NORETURN;
2765 }
2766
2767 static inline void generate_exception(DisasContext *ctx, int excp)
2768 {
2769     gen_helper_0e0i(raise_exception, excp);
2770 }
2771
2772 static inline void generate_exception_end(DisasContext *ctx, int excp)
2773 {
2774     generate_exception_err(ctx, excp, 0);
2775 }
2776
2777 /* Floating point register moves. */
2778 static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2779 {
2780     if (ctx->hflags & MIPS_HFLAG_FRE) {
2781         generate_exception(ctx, EXCP_RI);
2782     }
2783     tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
2784 }
2785
2786 static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2787 {
2788     TCGv_i64 t64;
2789     if (ctx->hflags & MIPS_HFLAG_FRE) {
2790         generate_exception(ctx, EXCP_RI);
2791     }
2792     t64 = tcg_temp_new_i64();
2793     tcg_gen_extu_i32_i64(t64, t);
2794     tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
2795     tcg_temp_free_i64(t64);
2796 }
2797
2798 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2799 {
2800     if (ctx->hflags & MIPS_HFLAG_F64) {
2801         tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
2802     } else {
2803         gen_load_fpr32(ctx, t, reg | 1);
2804     }
2805 }
2806
2807 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2808 {
2809     if (ctx->hflags & MIPS_HFLAG_F64) {
2810         TCGv_i64 t64 = tcg_temp_new_i64();
2811         tcg_gen_extu_i32_i64(t64, t);
2812         tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
2813         tcg_temp_free_i64(t64);
2814     } else {
2815         gen_store_fpr32(ctx, t, reg | 1);
2816     }
2817 }
2818
2819 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2820 {
2821     if (ctx->hflags & MIPS_HFLAG_F64) {
2822         tcg_gen_mov_i64(t, fpu_f64[reg]);
2823     } else {
2824         tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
2825     }
2826 }
2827
2828 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2829 {
2830     if (ctx->hflags & MIPS_HFLAG_F64) {
2831         tcg_gen_mov_i64(fpu_f64[reg], t);
2832     } else {
2833         TCGv_i64 t0;
2834         tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
2835         t0 = tcg_temp_new_i64();
2836         tcg_gen_shri_i64(t0, t, 32);
2837         tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
2838         tcg_temp_free_i64(t0);
2839     }
2840 }
2841
2842 static inline int get_fp_bit (int cc)
2843 {
2844     if (cc)
2845         return 24 + cc;
2846     else
2847         return 23;
2848 }
2849
2850 /* Addresses computation */
2851 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
2852 {
2853     tcg_gen_add_tl(ret, arg0, arg1);
2854
2855 #if defined(TARGET_MIPS64)
2856     if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2857         tcg_gen_ext32s_i64(ret, ret);
2858     }
2859 #endif
2860 }
2861
2862 static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
2863                                     target_long ofs)
2864 {
2865     tcg_gen_addi_tl(ret, base, ofs);
2866
2867 #if defined(TARGET_MIPS64)
2868     if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2869         tcg_gen_ext32s_i64(ret, ret);
2870     }
2871 #endif
2872 }
2873
2874 /* Addresses computation (translation time) */
2875 static target_long addr_add(DisasContext *ctx, target_long base,
2876                             target_long offset)
2877 {
2878     target_long sum = base + offset;
2879
2880 #if defined(TARGET_MIPS64)
2881     if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2882         sum = (int32_t)sum;
2883     }
2884 #endif
2885     return sum;
2886 }
2887
2888 /* Sign-extract the low 32-bits to a target_long.  */
2889 static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
2890 {
2891 #if defined(TARGET_MIPS64)
2892     tcg_gen_ext32s_i64(ret, arg);
2893 #else
2894     tcg_gen_extrl_i64_i32(ret, arg);
2895 #endif
2896 }
2897
2898 /* Sign-extract the high 32-bits to a target_long.  */
2899 static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
2900 {
2901 #if defined(TARGET_MIPS64)
2902     tcg_gen_sari_i64(ret, arg, 32);
2903 #else
2904     tcg_gen_extrh_i64_i32(ret, arg);
2905 #endif
2906 }
2907
2908 static inline void check_cp0_enabled(DisasContext *ctx)
2909 {
2910     if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
2911         generate_exception_err(ctx, EXCP_CpU, 0);
2912 }
2913
2914 static inline void check_cp1_enabled(DisasContext *ctx)
2915 {
2916     if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
2917         generate_exception_err(ctx, EXCP_CpU, 1);
2918 }
2919
2920 /* Verify that the processor is running with COP1X instructions enabled.
2921    This is associated with the nabla symbol in the MIPS32 and MIPS64
2922    opcode tables.  */
2923
2924 static inline void check_cop1x(DisasContext *ctx)
2925 {
2926     if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
2927         generate_exception_end(ctx, EXCP_RI);
2928 }
2929
2930 /* Verify that the processor is running with 64-bit floating-point
2931    operations enabled.  */
2932
2933 static inline void check_cp1_64bitmode(DisasContext *ctx)
2934 {
2935     if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
2936         generate_exception_end(ctx, EXCP_RI);
2937 }
2938
2939 /*
2940  * Verify if floating point register is valid; an operation is not defined
2941  * if bit 0 of any register specification is set and the FR bit in the
2942  * Status register equals zero, since the register numbers specify an
2943  * even-odd pair of adjacent coprocessor general registers. When the FR bit
2944  * in the Status register equals one, both even and odd register numbers
2945  * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
2946  *
2947  * Multiple 64 bit wide registers can be checked by calling
2948  * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
2949  */
2950 static inline void check_cp1_registers(DisasContext *ctx, int regs)
2951 {
2952     if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
2953         generate_exception_end(ctx, EXCP_RI);
2954 }
2955
2956 /* Verify that the processor is running with DSP instructions enabled.
2957    This is enabled by CP0 Status register MX(24) bit.
2958  */
2959
2960 static inline void check_dsp(DisasContext *ctx)
2961 {
2962     if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
2963         if (ctx->insn_flags & ASE_DSP) {
2964             generate_exception_end(ctx, EXCP_DSPDIS);
2965         } else {
2966             generate_exception_end(ctx, EXCP_RI);
2967         }
2968     }
2969 }
2970
2971 static inline void check_dsp_r2(DisasContext *ctx)
2972 {
2973     if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
2974         if (ctx->insn_flags & ASE_DSP) {
2975             generate_exception_end(ctx, EXCP_DSPDIS);
2976         } else {
2977             generate_exception_end(ctx, EXCP_RI);
2978         }
2979     }
2980 }
2981
2982 static inline void check_dsp_r3(DisasContext *ctx)
2983 {
2984     if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
2985         if (ctx->insn_flags & ASE_DSP) {
2986             generate_exception_end(ctx, EXCP_DSPDIS);
2987         } else {
2988             generate_exception_end(ctx, EXCP_RI);
2989         }
2990     }
2991 }
2992
2993 /* This code generates a "reserved instruction" exception if the
2994    CPU does not support the instruction set corresponding to flags. */
2995 static inline void check_insn(DisasContext *ctx, uint64_t flags)
2996 {
2997     if (unlikely(!(ctx->insn_flags & flags))) {
2998         generate_exception_end(ctx, EXCP_RI);
2999     }
3000 }
3001
3002 /* This code generates a "reserved instruction" exception if the
3003    CPU has corresponding flag set which indicates that the instruction
3004    has been removed. */
3005 static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
3006 {
3007     if (unlikely(ctx->insn_flags & flags)) {
3008         generate_exception_end(ctx, EXCP_RI);
3009     }
3010 }
3011
3012 /*
3013  * The Linux kernel traps certain reserved instruction exceptions to
3014  * emulate the corresponding instructions. QEMU is the kernel in user
3015  * mode, so those traps are emulated by accepting the instructions.
3016  *
3017  * A reserved instruction exception is generated for flagged CPUs if
3018  * QEMU runs in system mode.
3019  */
3020 static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
3021 {
3022 #ifndef CONFIG_USER_ONLY
3023     check_insn_opc_removed(ctx, flags);
3024 #endif
3025 }
3026
3027 /* This code generates a "reserved instruction" exception if the
3028    CPU does not support 64-bit paired-single (PS) floating point data type */
3029 static inline void check_ps(DisasContext *ctx)
3030 {
3031     if (unlikely(!ctx->ps)) {
3032         generate_exception(ctx, EXCP_RI);
3033     }
3034     check_cp1_64bitmode(ctx);
3035 }
3036
3037 #ifdef TARGET_MIPS64
3038 /* This code generates a "reserved instruction" exception if 64-bit
3039    instructions are not enabled. */
3040 static inline void check_mips_64(DisasContext *ctx)
3041 {
3042     if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
3043         generate_exception_end(ctx, EXCP_RI);
3044 }
3045 #endif
3046
3047 #ifndef CONFIG_USER_ONLY
3048 static inline void check_mvh(DisasContext *ctx)
3049 {
3050     if (unlikely(!ctx->mvh)) {
3051         generate_exception(ctx, EXCP_RI);
3052     }
3053 }
3054 #endif
3055
3056 /*
3057  * This code generates a "reserved instruction" exception if the
3058  * Config5 XNP bit is set.
3059  */
3060 static inline void check_xnp(DisasContext *ctx)
3061 {
3062     if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
3063         generate_exception_end(ctx, EXCP_RI);
3064     }
3065 }
3066
3067 #ifndef CONFIG_USER_ONLY
3068 /*
3069  * This code generates a "reserved instruction" exception if the
3070  * Config3 PW bit is NOT set.
3071  */
3072 static inline void check_pw(DisasContext *ctx)
3073 {
3074     if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
3075         generate_exception_end(ctx, EXCP_RI);
3076     }
3077 }
3078 #endif
3079
3080 /*
3081  * This code generates a "reserved instruction" exception if the
3082  * Config3 MT bit is NOT set.
3083  */
3084 static inline void check_mt(DisasContext *ctx)
3085 {
3086     if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3087         generate_exception_end(ctx, EXCP_RI);
3088     }
3089 }
3090
3091 #ifndef CONFIG_USER_ONLY
3092 /*
3093  * This code generates a "coprocessor unusable" exception if CP0 is not
3094  * available, and, if that is not the case, generates a "reserved instruction"
3095  * exception if the Config5 MT bit is NOT set. This is needed for availability
3096  * control of some of MT ASE instructions.
3097  */
3098 static inline void check_cp0_mt(DisasContext *ctx)
3099 {
3100     if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
3101         generate_exception_err(ctx, EXCP_CpU, 0);
3102     } else {
3103         if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3104             generate_exception_err(ctx, EXCP_RI, 0);
3105         }
3106     }
3107 }
3108 #endif
3109
3110 /*
3111  * This code generates a "reserved instruction" exception if the
3112  * Config5 NMS bit is set.
3113  */
3114 static inline void check_nms(DisasContext *ctx)
3115 {
3116     if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
3117         generate_exception_end(ctx, EXCP_RI);
3118     }
3119 }
3120
3121 /*
3122  * This code generates a "reserved instruction" exception if the
3123  * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
3124  * Config2 TL, and Config5 L2C are unset.
3125  */
3126 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
3127 {
3128     if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
3129         !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
3130         !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
3131         !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
3132         !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
3133         !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))
3134     {
3135         generate_exception_end(ctx, EXCP_RI);
3136     }
3137 }
3138
3139 /*
3140  * This code generates a "reserved instruction" exception if the
3141  * Config5 EVA bit is NOT set.
3142  */
3143 static inline void check_eva(DisasContext *ctx)
3144 {
3145     if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
3146         generate_exception_end(ctx, EXCP_RI);
3147     }
3148 }
3149
3150
3151 /* Define small wrappers for gen_load_fpr* so that we have a uniform
3152    calling interface for 32 and 64-bit FPRs.  No sense in changing
3153    all callers for gen_load_fpr32 when we need the CTX parameter for
3154    this one use.  */
3155 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
3156 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
3157 #define FOP_CONDS(type, abs, fmt, ifmt, bits)                                 \
3158 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
3159                                                int ft, int fs, int cc)        \
3160 {                                                                             \
3161     TCGv_i##bits fp0 = tcg_temp_new_i##bits ();                               \
3162     TCGv_i##bits fp1 = tcg_temp_new_i##bits ();                               \
3163     switch (ifmt) {                                                           \
3164     case FMT_PS:                                                              \
3165         check_ps(ctx);                                                        \
3166         break;                                                                \
3167     case FMT_D:                                                               \
3168         if (abs) {                                                            \
3169             check_cop1x(ctx);                                                 \
3170         }                                                                     \
3171         check_cp1_registers(ctx, fs | ft);                                    \
3172         break;                                                                \
3173     case FMT_S:                                                               \
3174         if (abs) {                                                            \
3175             check_cop1x(ctx);                                                 \
3176         }                                                                     \
3177         break;                                                                \
3178     }                                                                         \
3179     gen_ldcmp_fpr##bits (ctx, fp0, fs);                                       \
3180     gen_ldcmp_fpr##bits (ctx, fp1, ft);                                       \
3181     switch (n) {                                                              \
3182     case  0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc);    break;\
3183     case  1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc);   break;\
3184     case  2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc);   break;\
3185     case  3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc);  break;\
3186     case  4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc);  break;\
3187     case  5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc);  break;\
3188     case  6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc);  break;\
3189     case  7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc);  break;\
3190     case  8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc);   break;\
3191     case  9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
3192     case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc);  break;\
3193     case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc);  break;\
3194     case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc);   break;\
3195     case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc);  break;\
3196     case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc);   break;\
3197     case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc);  break;\
3198     default: abort();                                                         \
3199     }                                                                         \
3200     tcg_temp_free_i##bits (fp0);                                              \
3201     tcg_temp_free_i##bits (fp1);                                              \
3202 }
3203
3204 FOP_CONDS(, 0, d, FMT_D, 64)
3205 FOP_CONDS(abs, 1, d, FMT_D, 64)
3206 FOP_CONDS(, 0, s, FMT_S, 32)
3207 FOP_CONDS(abs, 1, s, FMT_S, 32)
3208 FOP_CONDS(, 0, ps, FMT_PS, 64)
3209 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
3210 #undef FOP_CONDS
3211
3212 #define FOP_CONDNS(fmt, ifmt, bits, STORE)                              \
3213 static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n,        \
3214                                       int ft, int fs, int fd)           \
3215 {                                                                       \
3216     TCGv_i ## bits fp0 = tcg_temp_new_i ## bits();                      \
3217     TCGv_i ## bits fp1 = tcg_temp_new_i ## bits();                      \
3218     if (ifmt == FMT_D) {                                                \
3219         check_cp1_registers(ctx, fs | ft | fd);                         \
3220     }                                                                   \
3221     gen_ldcmp_fpr ## bits(ctx, fp0, fs);                                \
3222     gen_ldcmp_fpr ## bits(ctx, fp1, ft);                                \
3223     switch (n) {                                                        \
3224     case  0:                                                            \
3225         gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1);       \
3226         break;                                                          \
3227     case  1:                                                            \
3228         gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1);       \
3229         break;                                                          \
3230     case  2:                                                            \
3231         gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1);       \
3232         break;                                                          \
3233     case  3:                                                            \
3234         gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1);      \
3235         break;                                                          \
3236     case  4:                                                            \
3237         gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1);       \
3238         break;                                                          \
3239     case  5:                                                            \
3240         gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1);      \
3241         break;                                                          \
3242     case  6:                                                            \
3243         gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1);       \
3244         break;                                                          \
3245     case  7:                                                            \
3246         gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1);      \
3247         break;                                                          \
3248     case  8:                                                            \
3249         gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1);      \
3250         break;                                                          \
3251     case  9:                                                            \
3252         gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1);      \
3253         break;                                                          \
3254     case 10:                                                            \
3255         gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1);      \
3256         break;                                                          \
3257     case 11:                                                            \
3258         gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1);     \
3259         break;                                                          \
3260     case 12:                                                            \
3261         gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1);      \
3262         break;                                                          \
3263     case 13:                                                            \
3264         gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1);     \
3265         break;                                                          \
3266     case 14:                                                            \
3267         gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1);      \
3268         break;                                                          \
3269     case 15:                                                            \
3270         gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1);     \
3271         break;                                                          \
3272     case 17:                                                            \
3273         gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1);       \
3274         break;                                                          \
3275     case 18:                                                            \
3276         gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1);      \
3277         break;                                                          \
3278     case 19:                                                            \
3279         gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1);       \
3280         break;                                                          \
3281     case 25:                                                            \
3282         gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1);      \
3283         break;                                                          \
3284     case 26:                                                            \
3285         gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1);     \
3286         break;                                                          \
3287     case 27:                                                            \
3288         gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1);      \
3289         break;                                                          \
3290     default:                                                            \
3291         abort();                                                        \
3292     }                                                                   \
3293     STORE;                                                              \
3294     tcg_temp_free_i ## bits (fp0);                                      \
3295     tcg_temp_free_i ## bits (fp1);                                      \
3296 }
3297
3298 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
3299 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3300 #undef FOP_CONDNS
3301 #undef gen_ldcmp_fpr32
3302 #undef gen_ldcmp_fpr64
3303
3304 /* load/store instructions. */
3305 #ifdef CONFIG_USER_ONLY
3306 #define OP_LD_ATOMIC(insn,fname)                                           \
3307 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
3308                                 DisasContext *ctx)                         \
3309 {                                                                          \
3310     TCGv t0 = tcg_temp_new();                                              \
3311     tcg_gen_mov_tl(t0, arg1);                                              \
3312     tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
3313     tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));                \
3314     tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval));                \
3315     tcg_temp_free(t0);                                                     \
3316 }
3317 #else
3318 #define OP_LD_ATOMIC(insn,fname)                                           \
3319 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
3320                                 DisasContext *ctx)                         \
3321 {                                                                          \
3322     gen_helper_1e1i(insn, ret, arg1, mem_idx);                             \
3323 }
3324 #endif
3325 OP_LD_ATOMIC(ll,ld32s);
3326 #if defined(TARGET_MIPS64)
3327 OP_LD_ATOMIC(lld,ld64);
3328 #endif
3329 #undef OP_LD_ATOMIC
3330
3331 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
3332                                   int base, int offset)
3333 {
3334     if (base == 0) {
3335         tcg_gen_movi_tl(addr, offset);
3336     } else if (offset == 0) {
3337         gen_load_gpr(addr, base);
3338     } else {
3339         tcg_gen_movi_tl(addr, offset);
3340         gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
3341     }
3342 }
3343
3344 static target_ulong pc_relative_pc (DisasContext *ctx)
3345 {
3346     target_ulong pc = ctx->base.pc_next;
3347
3348     if (ctx->hflags & MIPS_HFLAG_BMASK) {
3349         int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
3350
3351         pc -= branch_bytes;
3352     }
3353
3354     pc &= ~(target_ulong)3;
3355     return pc;
3356 }
3357
3358 /* Load */
3359 static void gen_ld(DisasContext *ctx, uint32_t opc,
3360                    int rt, int base, int offset)
3361 {
3362     TCGv t0, t1, t2;
3363     int mem_idx = ctx->mem_idx;
3364
3365     if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
3366         /* Loongson CPU uses a load to zero register for prefetch.
3367            We emulate it as a NOP. On other CPU we must perform the
3368            actual memory access. */
3369         return;
3370     }
3371
3372     t0 = tcg_temp_new();
3373     gen_base_offset_addr(ctx, t0, base, offset);
3374
3375     switch (opc) {
3376 #if defined(TARGET_MIPS64)
3377     case OPC_LWU:
3378         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
3379                            ctx->default_tcg_memop_mask);
3380         gen_store_gpr(t0, rt);
3381         break;
3382     case OPC_LD:
3383         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
3384                            ctx->default_tcg_memop_mask);
3385         gen_store_gpr(t0, rt);
3386         break;
3387     case OPC_LLD:
3388     case R6_OPC_LLD:
3389         op_ld_lld(t0, t0, mem_idx, ctx);
3390         gen_store_gpr(t0, rt);
3391         break;
3392     case OPC_LDL:
3393         t1 = tcg_temp_new();
3394         /* Do a byte access to possibly trigger a page
3395            fault with the unaligned address.  */
3396         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3397         tcg_gen_andi_tl(t1, t0, 7);
3398 #ifndef TARGET_WORDS_BIGENDIAN
3399         tcg_gen_xori_tl(t1, t1, 7);
3400 #endif
3401         tcg_gen_shli_tl(t1, t1, 3);
3402         tcg_gen_andi_tl(t0, t0, ~7);
3403         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3404         tcg_gen_shl_tl(t0, t0, t1);
3405         t2 = tcg_const_tl(-1);
3406         tcg_gen_shl_tl(t2, t2, t1);
3407         gen_load_gpr(t1, rt);
3408         tcg_gen_andc_tl(t1, t1, t2);
3409         tcg_temp_free(t2);
3410         tcg_gen_or_tl(t0, t0, t1);
3411         tcg_temp_free(t1);
3412         gen_store_gpr(t0, rt);
3413         break;
3414     case OPC_LDR:
3415         t1 = tcg_temp_new();
3416         /* Do a byte access to possibly trigger a page
3417            fault with the unaligned address.  */
3418         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3419         tcg_gen_andi_tl(t1, t0, 7);
3420 #ifdef TARGET_WORDS_BIGENDIAN
3421         tcg_gen_xori_tl(t1, t1, 7);
3422 #endif
3423         tcg_gen_shli_tl(t1, t1, 3);
3424         tcg_gen_andi_tl(t0, t0, ~7);
3425         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3426         tcg_gen_shr_tl(t0, t0, t1);
3427         tcg_gen_xori_tl(t1, t1, 63);
3428         t2 = tcg_const_tl(0xfffffffffffffffeull);
3429         tcg_gen_shl_tl(t2, t2, t1);
3430         gen_load_gpr(t1, rt);
3431         tcg_gen_and_tl(t1, t1, t2);
3432         tcg_temp_free(t2);
3433         tcg_gen_or_tl(t0, t0, t1);
3434         tcg_temp_free(t1);
3435         gen_store_gpr(t0, rt);
3436         break;
3437     case OPC_LDPC:
3438         t1 = tcg_const_tl(pc_relative_pc(ctx));
3439         gen_op_addr_add(ctx, t0, t0, t1);
3440         tcg_temp_free(t1);
3441         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3442         gen_store_gpr(t0, rt);
3443         break;
3444 #endif
3445     case OPC_LWPC:
3446         t1 = tcg_const_tl(pc_relative_pc(ctx));
3447         gen_op_addr_add(ctx, t0, t0, t1);
3448         tcg_temp_free(t1);
3449         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
3450         gen_store_gpr(t0, rt);
3451         break;
3452     case OPC_LWE:
3453         mem_idx = MIPS_HFLAG_UM;
3454         /* fall through */
3455     case OPC_LW:
3456         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
3457                            ctx->default_tcg_memop_mask);
3458         gen_store_gpr(t0, rt);
3459         break;
3460     case OPC_LHE:
3461         mem_idx = MIPS_HFLAG_UM;
3462         /* fall through */
3463     case OPC_LH:
3464         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
3465                            ctx->default_tcg_memop_mask);
3466         gen_store_gpr(t0, rt);
3467         break;
3468     case OPC_LHUE:
3469         mem_idx = MIPS_HFLAG_UM;
3470         /* fall through */
3471     case OPC_LHU:
3472         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
3473                            ctx->default_tcg_memop_mask);
3474         gen_store_gpr(t0, rt);
3475         break;
3476     case OPC_LBE:
3477         mem_idx = MIPS_HFLAG_UM;
3478         /* fall through */
3479     case OPC_LB:
3480         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
3481         gen_store_gpr(t0, rt);
3482         break;
3483     case OPC_LBUE:
3484         mem_idx = MIPS_HFLAG_UM;
3485         /* fall through */
3486     case OPC_LBU:
3487         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
3488         gen_store_gpr(t0, rt);
3489         break;
3490     case OPC_LWLE:
3491         mem_idx = MIPS_HFLAG_UM;
3492         /* fall through */
3493     case OPC_LWL:
3494         t1 = tcg_temp_new();
3495         /* Do a byte access to possibly trigger a page
3496            fault with the unaligned address.  */
3497         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3498         tcg_gen_andi_tl(t1, t0, 3);
3499 #ifndef TARGET_WORDS_BIGENDIAN
3500         tcg_gen_xori_tl(t1, t1, 3);
3501 #endif
3502         tcg_gen_shli_tl(t1, t1, 3);
3503         tcg_gen_andi_tl(t0, t0, ~3);
3504         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3505         tcg_gen_shl_tl(t0, t0, t1);
3506         t2 = tcg_const_tl(-1);
3507         tcg_gen_shl_tl(t2, t2, t1);
3508         gen_load_gpr(t1, rt);
3509         tcg_gen_andc_tl(t1, t1, t2);
3510         tcg_temp_free(t2);
3511         tcg_gen_or_tl(t0, t0, t1);
3512         tcg_temp_free(t1);
3513         tcg_gen_ext32s_tl(t0, t0);
3514         gen_store_gpr(t0, rt);
3515         break;
3516     case OPC_LWRE:
3517         mem_idx = MIPS_HFLAG_UM;
3518         /* fall through */
3519     case OPC_LWR:
3520         t1 = tcg_temp_new();
3521         /* Do a byte access to possibly trigger a page
3522            fault with the unaligned address.  */
3523         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3524         tcg_gen_andi_tl(t1, t0, 3);
3525 #ifdef TARGET_WORDS_BIGENDIAN
3526         tcg_gen_xori_tl(t1, t1, 3);
3527 #endif
3528         tcg_gen_shli_tl(t1, t1, 3);
3529         tcg_gen_andi_tl(t0, t0, ~3);
3530         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3531         tcg_gen_shr_tl(t0, t0, t1);
3532         tcg_gen_xori_tl(t1, t1, 31);
3533         t2 = tcg_const_tl(0xfffffffeull);
3534         tcg_gen_shl_tl(t2, t2, t1);
3535         gen_load_gpr(t1, rt);
3536         tcg_gen_and_tl(t1, t1, t2);
3537         tcg_temp_free(t2);
3538         tcg_gen_or_tl(t0, t0, t1);
3539         tcg_temp_free(t1);
3540         tcg_gen_ext32s_tl(t0, t0);
3541         gen_store_gpr(t0, rt);
3542         break;
3543     case OPC_LLE:
3544         mem_idx = MIPS_HFLAG_UM;
3545         /* fall through */
3546     case OPC_LL:
3547     case R6_OPC_LL:
3548         op_ld_ll(t0, t0, mem_idx, ctx);
3549         gen_store_gpr(t0, rt);
3550         break;
3551     }
3552     tcg_temp_free(t0);
3553 }
3554
3555 static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
3556                     uint32_t reg1, uint32_t reg2)
3557 {
3558     TCGv taddr = tcg_temp_new();
3559     TCGv_i64 tval = tcg_temp_new_i64();
3560     TCGv tmp1 = tcg_temp_new();
3561     TCGv tmp2 = tcg_temp_new();
3562
3563     gen_base_offset_addr(ctx, taddr, base, offset);
3564     tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx);
3565 #ifdef TARGET_WORDS_BIGENDIAN
3566     tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
3567 #else
3568     tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
3569 #endif
3570     gen_store_gpr(tmp1, reg1);
3571     tcg_temp_free(tmp1);
3572     gen_store_gpr(tmp2, reg2);
3573     tcg_temp_free(tmp2);
3574     tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3575     tcg_temp_free_i64(tval);
3576     tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr));
3577     tcg_temp_free(taddr);
3578 }
3579
3580 /* Store */
3581 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
3582                     int base, int offset)
3583 {
3584     TCGv t0 = tcg_temp_new();
3585     TCGv t1 = tcg_temp_new();
3586     int mem_idx = ctx->mem_idx;
3587
3588     gen_base_offset_addr(ctx, t0, base, offset);
3589     gen_load_gpr(t1, rt);
3590     switch (opc) {
3591 #if defined(TARGET_MIPS64)
3592     case OPC_SD:
3593         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
3594                            ctx->default_tcg_memop_mask);
3595         break;
3596     case OPC_SDL:
3597         gen_helper_0e2i(sdl, t1, t0, mem_idx);
3598         break;
3599     case OPC_SDR:
3600         gen_helper_0e2i(sdr, t1, t0, mem_idx);
3601         break;
3602 #endif
3603     case OPC_SWE:
3604         mem_idx = MIPS_HFLAG_UM;
3605         /* fall through */
3606     case OPC_SW:
3607         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
3608                            ctx->default_tcg_memop_mask);
3609         break;
3610     case OPC_SHE:
3611         mem_idx = MIPS_HFLAG_UM;
3612         /* fall through */
3613     case OPC_SH:
3614         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
3615                            ctx->default_tcg_memop_mask);
3616         break;
3617     case OPC_SBE:
3618         mem_idx = MIPS_HFLAG_UM;
3619         /* fall through */
3620     case OPC_SB:
3621         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
3622         break;
3623     case OPC_SWLE:
3624         mem_idx = MIPS_HFLAG_UM;
3625         /* fall through */
3626     case OPC_SWL:
3627         gen_helper_0e2i(swl, t1, t0, mem_idx);
3628         break;
3629     case OPC_SWRE:
3630         mem_idx = MIPS_HFLAG_UM;
3631         /* fall through */
3632     case OPC_SWR:
3633         gen_helper_0e2i(swr, t1, t0, mem_idx);
3634         break;
3635     }
3636     tcg_temp_free(t0);
3637     tcg_temp_free(t1);
3638 }
3639
3640
3641 /* Store conditional */
3642 static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset,
3643                         TCGMemOp tcg_mo, bool eva)
3644 {
3645     TCGv addr, t0, val;
3646     TCGLabel *l1 = gen_new_label();
3647     TCGLabel *done = gen_new_label();
3648
3649     t0 = tcg_temp_new();
3650     addr = tcg_temp_new();
3651     /* compare the address against that of the preceeding LL */
3652     gen_base_offset_addr(ctx, addr, base, offset);
3653     tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1);
3654     tcg_temp_free(addr);
3655     tcg_gen_movi_tl(t0, 0);
3656     gen_store_gpr(t0, rt);
3657     tcg_gen_br(done);
3658
3659     gen_set_label(l1);
3660     /* generate cmpxchg */
3661     val = tcg_temp_new();
3662     gen_load_gpr(val, rt);
3663     tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val,
3664                               eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo);
3665     tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval);
3666     gen_store_gpr(t0, rt);
3667     tcg_temp_free(val);
3668
3669     gen_set_label(done);
3670     tcg_temp_free(t0);
3671 }
3672
3673
3674 static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
3675                     uint32_t reg1, uint32_t reg2, bool eva)
3676 {
3677     TCGv taddr = tcg_temp_local_new();
3678     TCGv lladdr = tcg_temp_local_new();
3679     TCGv_i64 tval = tcg_temp_new_i64();
3680     TCGv_i64 llval = tcg_temp_new_i64();
3681     TCGv_i64 val = tcg_temp_new_i64();
3682     TCGv tmp1 = tcg_temp_new();
3683     TCGv tmp2 = tcg_temp_new();
3684     TCGLabel *lab_fail = gen_new_label();
3685     TCGLabel *lab_done = gen_new_label();
3686
3687     gen_base_offset_addr(ctx, taddr, base, offset);
3688
3689     tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3690     tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail);
3691
3692     gen_load_gpr(tmp1, reg1);
3693     gen_load_gpr(tmp2, reg2);
3694
3695 #ifdef TARGET_WORDS_BIGENDIAN
3696     tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
3697 #else
3698     tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
3699 #endif
3700
3701     tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3702     tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
3703                                eva ? MIPS_HFLAG_UM : ctx->mem_idx, MO_64);
3704     if (reg1 != 0) {
3705         tcg_gen_movi_tl(cpu_gpr[reg1], 1);
3706     }
3707     tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done);
3708
3709     gen_set_label(lab_fail);
3710
3711     if (reg1 != 0) {
3712         tcg_gen_movi_tl(cpu_gpr[reg1], 0);
3713     }
3714     gen_set_label(lab_done);
3715     tcg_gen_movi_tl(lladdr, -1);
3716     tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3717 }
3718
3719 /* Load and store */
3720 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
3721                           TCGv t0)
3722 {
3723     /* Don't do NOP if destination is zero: we must perform the actual
3724        memory access. */
3725     switch (opc) {
3726     case OPC_LWC1:
3727         {
3728             TCGv_i32 fp0 = tcg_temp_new_i32();
3729             tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
3730                                 ctx->default_tcg_memop_mask);
3731             gen_store_fpr32(ctx, fp0, ft);
3732             tcg_temp_free_i32(fp0);
3733         }
3734         break;
3735     case OPC_SWC1:
3736         {
3737             TCGv_i32 fp0 = tcg_temp_new_i32();
3738             gen_load_fpr32(ctx, fp0, ft);
3739             tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
3740                                 ctx->default_tcg_memop_mask);
3741             tcg_temp_free_i32(fp0);
3742         }
3743         break;
3744     case OPC_LDC1:
3745         {
3746             TCGv_i64 fp0 = tcg_temp_new_i64();
3747             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3748                                 ctx->default_tcg_memop_mask);
3749             gen_store_fpr64(ctx, fp0, ft);
3750             tcg_temp_free_i64(fp0);
3751         }
3752         break;
3753     case OPC_SDC1:
3754         {
3755             TCGv_i64 fp0 = tcg_temp_new_i64();
3756             gen_load_fpr64(ctx, fp0, ft);
3757             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3758                                 ctx->default_tcg_memop_mask);
3759             tcg_temp_free_i64(fp0);
3760         }
3761         break;
3762     default:
3763         MIPS_INVAL("flt_ldst");
3764         generate_exception_end(ctx, EXCP_RI);
3765         break;
3766     }
3767 }
3768
3769 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
3770                           int rs, int16_t imm)
3771 {
3772     TCGv t0 = tcg_temp_new();
3773
3774     if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3775         check_cp1_enabled(ctx);
3776         switch (op) {
3777         case OPC_LDC1:
3778         case OPC_SDC1:
3779             check_insn(ctx, ISA_MIPS2);
3780             /* Fallthrough */
3781         default:
3782             gen_base_offset_addr(ctx, t0, rs, imm);
3783             gen_flt_ldst(ctx, op, rt, t0);
3784         }
3785     } else {
3786         generate_exception_err(ctx, EXCP_CpU, 1);
3787     }
3788     tcg_temp_free(t0);
3789 }
3790
3791 /* Arithmetic with immediate operand */
3792 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
3793                           int rt, int rs, int imm)
3794 {
3795     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3796
3797     if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
3798         /* If no destination, treat it as a NOP.
3799            For addi, we must generate the overflow exception when needed. */
3800         return;
3801     }
3802     switch (opc) {
3803     case OPC_ADDI:
3804         {
3805             TCGv t0 = tcg_temp_local_new();
3806             TCGv t1 = tcg_temp_new();
3807             TCGv t2 = tcg_temp_new();
3808             TCGLabel *l1 = gen_new_label();
3809
3810             gen_load_gpr(t1, rs);
3811             tcg_gen_addi_tl(t0, t1, uimm);
3812             tcg_gen_ext32s_tl(t0, t0);
3813
3814             tcg_gen_xori_tl(t1, t1, ~uimm);
3815             tcg_gen_xori_tl(t2, t0, uimm);
3816             tcg_gen_and_tl(t1, t1, t2);
3817             tcg_temp_free(t2);
3818             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3819             tcg_temp_free(t1);
3820             /* operands of same sign, result different sign */
3821             generate_exception(ctx, EXCP_OVERFLOW);
3822             gen_set_label(l1);
3823             tcg_gen_ext32s_tl(t0, t0);
3824             gen_store_gpr(t0, rt);
3825             tcg_temp_free(t0);
3826         }
3827         break;
3828     case OPC_ADDIU:
3829         if (rs != 0) {
3830             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3831             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3832         } else {
3833             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3834         }
3835         break;
3836 #if defined(TARGET_MIPS64)
3837     case OPC_DADDI:
3838         {
3839             TCGv t0 = tcg_temp_local_new();
3840             TCGv t1 = tcg_temp_new();
3841             TCGv t2 = tcg_temp_new();
3842             TCGLabel *l1 = gen_new_label();
3843
3844             gen_load_gpr(t1, rs);
3845             tcg_gen_addi_tl(t0, t1, uimm);
3846
3847             tcg_gen_xori_tl(t1, t1, ~uimm);
3848             tcg_gen_xori_tl(t2, t0, uimm);
3849             tcg_gen_and_tl(t1, t1, t2);
3850             tcg_temp_free(t2);
3851             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3852             tcg_temp_free(t1);
3853             /* operands of same sign, result different sign */
3854             generate_exception(ctx, EXCP_OVERFLOW);
3855             gen_set_label(l1);
3856             gen_store_gpr(t0, rt);
3857             tcg_temp_free(t0);
3858         }
3859         break;
3860     case OPC_DADDIU:
3861         if (rs != 0) {
3862             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3863         } else {
3864             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3865         }
3866         break;
3867 #endif
3868     }
3869 }
3870
3871 /* Logic with immediate operand */
3872 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
3873                           int rt, int rs, int16_t imm)
3874 {
3875     target_ulong uimm;
3876
3877     if (rt == 0) {
3878         /* If no destination, treat it as a NOP. */
3879         return;
3880     }
3881     uimm = (uint16_t)imm;
3882     switch (opc) {
3883     case OPC_ANDI:
3884         if (likely(rs != 0))
3885             tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3886         else
3887             tcg_gen_movi_tl(cpu_gpr[rt], 0);
3888         break;
3889     case OPC_ORI:
3890         if (rs != 0)
3891             tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3892         else
3893             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3894         break;
3895     case OPC_XORI:
3896         if (likely(rs != 0))
3897             tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3898         else
3899             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3900         break;
3901     case OPC_LUI:
3902         if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
3903             /* OPC_AUI */
3904             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
3905             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3906         } else {
3907             tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
3908         }
3909         break;
3910
3911     default:
3912         break;
3913     }
3914 }
3915
3916 /* Set on less than with immediate operand */
3917 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
3918                         int rt, int rs, int16_t imm)
3919 {
3920     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3921     TCGv t0;
3922
3923     if (rt == 0) {
3924         /* If no destination, treat it as a NOP. */
3925         return;
3926     }
3927     t0 = tcg_temp_new();
3928     gen_load_gpr(t0, rs);
3929     switch (opc) {
3930     case OPC_SLTI:
3931         tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
3932         break;
3933     case OPC_SLTIU:
3934         tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
3935         break;
3936     }
3937     tcg_temp_free(t0);
3938 }
3939
3940 /* Shifts with immediate operand */
3941 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
3942                           int rt, int rs, int16_t imm)
3943 {
3944     target_ulong uimm = ((uint16_t)imm) & 0x1f;
3945     TCGv t0;
3946
3947     if (rt == 0) {
3948         /* If no destination, treat it as a NOP. */
3949         return;
3950     }
3951
3952     t0 = tcg_temp_new();
3953     gen_load_gpr(t0, rs);
3954     switch (opc) {
3955     case OPC_SLL:
3956         tcg_gen_shli_tl(t0, t0, uimm);
3957         tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3958         break;
3959     case OPC_SRA:
3960         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
3961         break;
3962     case OPC_SRL:
3963         if (uimm != 0) {
3964             tcg_gen_ext32u_tl(t0, t0);
3965             tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3966         } else {
3967             tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3968         }
3969         break;
3970     case OPC_ROTR:
3971         if (uimm != 0) {
3972             TCGv_i32 t1 = tcg_temp_new_i32();
3973
3974             tcg_gen_trunc_tl_i32(t1, t0);
3975             tcg_gen_rotri_i32(t1, t1, uimm);
3976             tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
3977             tcg_temp_free_i32(t1);
3978         } else {
3979             tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3980         }
3981         break;
3982 #if defined(TARGET_MIPS64)
3983     case OPC_DSLL:
3984         tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
3985         break;
3986     case OPC_DSRA:
3987         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
3988         break;
3989     case OPC_DSRL:
3990         tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3991         break;
3992     case OPC_DROTR:
3993         if (uimm != 0) {
3994             tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3995         } else {
3996             tcg_gen_mov_tl(cpu_gpr[rt], t0);
3997         }
3998         break;
3999     case OPC_DSLL32:
4000         tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
4001         break;
4002     case OPC_DSRA32:
4003         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
4004         break;
4005     case OPC_DSRL32:
4006         tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
4007         break;
4008     case OPC_DROTR32:
4009         tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
4010         break;
4011 #endif
4012     }
4013     tcg_temp_free(t0);
4014 }
4015
4016 /* Arithmetic */
4017 static void gen_arith(DisasContext *ctx, uint32_t opc,
4018                       int rd, int rs, int rt)
4019 {
4020     if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
4021        && opc != OPC_DADD && opc != OPC_DSUB) {
4022         /* If no destination, treat it as a NOP.
4023            For add & sub, we must generate the overflow exception when needed. */
4024         return;
4025     }
4026
4027     switch (opc) {
4028     case OPC_ADD:
4029         {
4030             TCGv t0 = tcg_temp_local_new();
4031             TCGv t1 = tcg_temp_new();
4032             TCGv t2 = tcg_temp_new();
4033             TCGLabel *l1 = gen_new_label();
4034
4035             gen_load_gpr(t1, rs);
4036             gen_load_gpr(t2, rt);
4037             tcg_gen_add_tl(t0, t1, t2);
4038             tcg_gen_ext32s_tl(t0, t0);
4039             tcg_gen_xor_tl(t1, t1, t2);
4040             tcg_gen_xor_tl(t2, t0, t2);
4041             tcg_gen_andc_tl(t1, t2, t1);
4042             tcg_temp_free(t2);
4043             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4044             tcg_temp_free(t1);
4045             /* operands of same sign, result different sign */
4046             generate_exception(ctx, EXCP_OVERFLOW);
4047             gen_set_label(l1);
4048             gen_store_gpr(t0, rd);
4049             tcg_temp_free(t0);
4050         }
4051         break;
4052     case OPC_ADDU:
4053         if (rs != 0 && rt != 0) {
4054             tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4055             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4056         } else if (rs == 0 && rt != 0) {
4057             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4058         } else if (rs != 0 && rt == 0) {
4059             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4060         } else {
4061             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4062         }
4063         break;
4064     case OPC_SUB:
4065         {
4066             TCGv t0 = tcg_temp_local_new();
4067             TCGv t1 = tcg_temp_new();
4068             TCGv t2 = tcg_temp_new();
4069             TCGLabel *l1 = gen_new_label();
4070
4071             gen_load_gpr(t1, rs);
4072             gen_load_gpr(t2, rt);
4073             tcg_gen_sub_tl(t0, t1, t2);
4074             tcg_gen_ext32s_tl(t0, t0);
4075             tcg_gen_xor_tl(t2, t1, t2);
4076             tcg_gen_xor_tl(t1, t0, t1);
4077             tcg_gen_and_tl(t1, t1, t2);
4078             tcg_temp_free(t2);
4079             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4080             tcg_temp_free(t1);
4081             /* operands of different sign, first operand and result different sign */
4082             generate_exception(ctx, EXCP_OVERFLOW);
4083             gen_set_label(l1);
4084             gen_store_gpr(t0, rd);
4085             tcg_temp_free(t0);
4086         }
4087         break;
4088     case OPC_SUBU:
4089         if (rs != 0 && rt != 0) {
4090             tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4091             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4092         } else if (rs == 0 && rt != 0) {
4093             tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4094             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
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 #if defined(TARGET_MIPS64)
4102     case OPC_DADD:
4103         {
4104             TCGv t0 = tcg_temp_local_new();
4105             TCGv t1 = tcg_temp_new();
4106             TCGv t2 = tcg_temp_new();
4107             TCGLabel *l1 = gen_new_label();
4108
4109             gen_load_gpr(t1, rs);
4110             gen_load_gpr(t2, rt);
4111             tcg_gen_add_tl(t0, t1, t2);
4112             tcg_gen_xor_tl(t1, t1, t2);
4113             tcg_gen_xor_tl(t2, t0, t2);
4114             tcg_gen_andc_tl(t1, t2, t1);
4115             tcg_temp_free(t2);
4116             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4117             tcg_temp_free(t1);
4118             /* operands of same sign, 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_DADDU:
4126         if (rs != 0 && rt != 0) {
4127             tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4128         } else if (rs == 0 && rt != 0) {
4129             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4130         } else if (rs != 0 && rt == 0) {
4131             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4132         } else {
4133             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4134         }
4135         break;
4136     case OPC_DSUB:
4137         {
4138             TCGv t0 = tcg_temp_local_new();
4139             TCGv t1 = tcg_temp_new();
4140             TCGv t2 = tcg_temp_new();
4141             TCGLabel *l1 = gen_new_label();
4142
4143             gen_load_gpr(t1, rs);
4144             gen_load_gpr(t2, rt);
4145             tcg_gen_sub_tl(t0, t1, t2);
4146             tcg_gen_xor_tl(t2, t1, t2);
4147             tcg_gen_xor_tl(t1, t0, t1);
4148             tcg_gen_and_tl(t1, t1, t2);
4149             tcg_temp_free(t2);
4150             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4151             tcg_temp_free(t1);
4152             /* operands of different sign, first operand and result different sign */
4153             generate_exception(ctx, EXCP_OVERFLOW);
4154             gen_set_label(l1);
4155             gen_store_gpr(t0, rd);
4156             tcg_temp_free(t0);
4157         }
4158         break;
4159     case OPC_DSUBU:
4160         if (rs != 0 && rt != 0) {
4161             tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4162         } else if (rs == 0 && rt != 0) {
4163             tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4164         } else if (rs != 0 && rt == 0) {
4165             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4166         } else {
4167             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4168         }
4169         break;
4170 #endif
4171     case OPC_MUL:
4172         if (likely(rs != 0 && rt != 0)) {
4173             tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4174             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4175         } else {
4176             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4177         }
4178         break;
4179     }
4180 }
4181
4182 /* Conditional move */
4183 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
4184                           int rd, int rs, int rt)
4185 {
4186     TCGv t0, t1, t2;
4187
4188     if (rd == 0) {
4189         /* If no destination, treat it as a NOP. */
4190         return;
4191     }
4192
4193     t0 = tcg_temp_new();
4194     gen_load_gpr(t0, rt);
4195     t1 = tcg_const_tl(0);
4196     t2 = tcg_temp_new();
4197     gen_load_gpr(t2, rs);
4198     switch (opc) {
4199     case OPC_MOVN:
4200         tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4201         break;
4202     case OPC_MOVZ:
4203         tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4204         break;
4205     case OPC_SELNEZ:
4206         tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
4207         break;
4208     case OPC_SELEQZ:
4209         tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
4210         break;
4211     }
4212     tcg_temp_free(t2);
4213     tcg_temp_free(t1);
4214     tcg_temp_free(t0);
4215 }
4216
4217 /* Logic */
4218 static void gen_logic(DisasContext *ctx, uint32_t opc,
4219                       int rd, int rs, int rt)
4220 {
4221     if (rd == 0) {
4222         /* If no destination, treat it as a NOP. */
4223         return;
4224     }
4225
4226     switch (opc) {
4227     case OPC_AND:
4228         if (likely(rs != 0 && rt != 0)) {
4229             tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4230         } else {
4231             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4232         }
4233         break;
4234     case OPC_NOR:
4235         if (rs != 0 && rt != 0) {
4236             tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4237         } else if (rs == 0 && rt != 0) {
4238             tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
4239         } else if (rs != 0 && rt == 0) {
4240             tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
4241         } else {
4242             tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
4243         }
4244         break;
4245     case OPC_OR:
4246         if (likely(rs != 0 && rt != 0)) {
4247             tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4248         } else if (rs == 0 && rt != 0) {
4249             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4250         } else if (rs != 0 && rt == 0) {
4251             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4252         } else {
4253             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4254         }
4255         break;
4256     case OPC_XOR:
4257         if (likely(rs != 0 && rt != 0)) {
4258             tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4259         } else if (rs == 0 && rt != 0) {
4260             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4261         } else if (rs != 0 && rt == 0) {
4262             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4263         } else {
4264             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4265         }
4266         break;
4267     }
4268 }
4269
4270 /* Set on lower than */
4271 static void gen_slt(DisasContext *ctx, uint32_t opc,
4272                     int rd, int rs, int rt)
4273 {
4274     TCGv t0, t1;
4275
4276     if (rd == 0) {
4277         /* If no destination, treat it as a NOP. */
4278         return;
4279     }
4280
4281     t0 = tcg_temp_new();
4282     t1 = tcg_temp_new();
4283     gen_load_gpr(t0, rs);
4284     gen_load_gpr(t1, rt);
4285     switch (opc) {
4286     case OPC_SLT:
4287         tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
4288         break;
4289     case OPC_SLTU:
4290         tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
4291         break;
4292     }
4293     tcg_temp_free(t0);
4294     tcg_temp_free(t1);
4295 }
4296
4297 /* Shifts */
4298 static void gen_shift(DisasContext *ctx, uint32_t opc,
4299                       int rd, int rs, int rt)
4300 {
4301     TCGv t0, t1;
4302
4303     if (rd == 0) {
4304         /* If no destination, treat it as a NOP.
4305            For add & sub, we must generate the overflow exception when needed. */
4306         return;
4307     }
4308
4309     t0 = tcg_temp_new();
4310     t1 = tcg_temp_new();
4311     gen_load_gpr(t0, rs);
4312     gen_load_gpr(t1, rt);
4313     switch (opc) {
4314     case OPC_SLLV:
4315         tcg_gen_andi_tl(t0, t0, 0x1f);
4316         tcg_gen_shl_tl(t0, t1, t0);
4317         tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4318         break;
4319     case OPC_SRAV:
4320         tcg_gen_andi_tl(t0, t0, 0x1f);
4321         tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4322         break;
4323     case OPC_SRLV:
4324         tcg_gen_ext32u_tl(t1, t1);
4325         tcg_gen_andi_tl(t0, t0, 0x1f);
4326         tcg_gen_shr_tl(t0, t1, t0);
4327         tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4328         break;
4329     case OPC_ROTRV:
4330         {
4331             TCGv_i32 t2 = tcg_temp_new_i32();
4332             TCGv_i32 t3 = tcg_temp_new_i32();
4333
4334             tcg_gen_trunc_tl_i32(t2, t0);
4335             tcg_gen_trunc_tl_i32(t3, t1);
4336             tcg_gen_andi_i32(t2, t2, 0x1f);
4337             tcg_gen_rotr_i32(t2, t3, t2);
4338             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4339             tcg_temp_free_i32(t2);
4340             tcg_temp_free_i32(t3);
4341         }
4342         break;
4343 #if defined(TARGET_MIPS64)
4344     case OPC_DSLLV:
4345         tcg_gen_andi_tl(t0, t0, 0x3f);
4346         tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
4347         break;
4348     case OPC_DSRAV:
4349         tcg_gen_andi_tl(t0, t0, 0x3f);
4350         tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4351         break;
4352     case OPC_DSRLV:
4353         tcg_gen_andi_tl(t0, t0, 0x3f);
4354         tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
4355         break;
4356     case OPC_DROTRV:
4357         tcg_gen_andi_tl(t0, t0, 0x3f);
4358         tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
4359         break;
4360 #endif
4361     }
4362     tcg_temp_free(t0);
4363     tcg_temp_free(t1);
4364 }
4365
4366 #if defined(TARGET_MIPS64)
4367 /* Copy GPR to and from TX79 HI1/LO1 register. */
4368 static void gen_HILO1_tx79(DisasContext *ctx, uint32_t opc, int reg)
4369 {
4370     if (reg == 0 && (opc == MMI_OPC_MFHI1 || opc == MMI_OPC_MFLO1)) {
4371         /* Treat as NOP. */
4372         return;
4373     }
4374
4375     switch (opc) {
4376     case MMI_OPC_MFHI1:
4377         tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]);
4378         break;
4379     case MMI_OPC_MFLO1:
4380         tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[1]);
4381         break;
4382     case MMI_OPC_MTHI1:
4383         if (reg != 0) {
4384             tcg_gen_mov_tl(cpu_HI[1], cpu_gpr[reg]);
4385         } else {
4386             tcg_gen_movi_tl(cpu_HI[1], 0);
4387         }
4388         break;
4389     case MMI_OPC_MTLO1:
4390         if (reg != 0) {
4391             tcg_gen_mov_tl(cpu_LO[1], cpu_gpr[reg]);
4392         } else {
4393             tcg_gen_movi_tl(cpu_LO[1], 0);
4394         }
4395         break;
4396     default:
4397         MIPS_INVAL("mfthilo1 TX79");
4398         generate_exception_end(ctx, EXCP_RI);
4399         break;
4400     }
4401 }
4402 #endif
4403
4404 /* Arithmetic on HI/LO registers */
4405 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
4406 {
4407     if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
4408         /* Treat as NOP. */
4409         return;
4410     }
4411
4412     if (acc != 0) {
4413         check_dsp(ctx);
4414     }
4415
4416     switch (opc) {
4417     case OPC_MFHI:
4418 #if defined(TARGET_MIPS64)
4419         if (acc != 0) {
4420             tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
4421         } else
4422 #endif
4423         {
4424             tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
4425         }
4426         break;
4427     case OPC_MFLO:
4428 #if defined(TARGET_MIPS64)
4429         if (acc != 0) {
4430             tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
4431         } else
4432 #endif
4433         {
4434             tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
4435         }
4436         break;
4437     case OPC_MTHI:
4438         if (reg != 0) {
4439 #if defined(TARGET_MIPS64)
4440             if (acc != 0) {
4441                 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
4442             } else
4443 #endif
4444             {
4445                 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
4446             }
4447         } else {
4448             tcg_gen_movi_tl(cpu_HI[acc], 0);
4449         }
4450         break;
4451     case OPC_MTLO:
4452         if (reg != 0) {
4453 #if defined(TARGET_MIPS64)
4454             if (acc != 0) {
4455                 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
4456             } else
4457 #endif
4458             {
4459                 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
4460             }
4461         } else {
4462             tcg_gen_movi_tl(cpu_LO[acc], 0);
4463         }
4464         break;
4465     }
4466 }
4467
4468 static inline void gen_r6_ld(target_long addr, int reg, int memidx,
4469                              TCGMemOp memop)
4470 {
4471     TCGv t0 = tcg_const_tl(addr);
4472     tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
4473     gen_store_gpr(t0, reg);
4474     tcg_temp_free(t0);
4475 }
4476
4477 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
4478                              int rs)
4479 {
4480     target_long offset;
4481     target_long addr;
4482
4483     switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
4484     case OPC_ADDIUPC:
4485         if (rs != 0) {
4486             offset = sextract32(ctx->opcode << 2, 0, 21);
4487             addr = addr_add(ctx, pc, offset);
4488             tcg_gen_movi_tl(cpu_gpr[rs], addr);
4489         }
4490         break;
4491     case R6_OPC_LWPC:
4492         offset = sextract32(ctx->opcode << 2, 0, 21);
4493         addr = addr_add(ctx, pc, offset);
4494         gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
4495         break;
4496 #if defined(TARGET_MIPS64)
4497     case OPC_LWUPC:
4498         check_mips_64(ctx);
4499         offset = sextract32(ctx->opcode << 2, 0, 21);
4500         addr = addr_add(ctx, pc, offset);
4501         gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
4502         break;
4503 #endif
4504     default:
4505         switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
4506         case OPC_AUIPC:
4507             if (rs != 0) {
4508                 offset = sextract32(ctx->opcode, 0, 16) << 16;
4509                 addr = addr_add(ctx, pc, offset);
4510                 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4511             }
4512             break;
4513         case OPC_ALUIPC:
4514             if (rs != 0) {
4515                 offset = sextract32(ctx->opcode, 0, 16) << 16;
4516                 addr = ~0xFFFF & addr_add(ctx, pc, offset);
4517                 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4518             }
4519             break;
4520 #if defined(TARGET_MIPS64)
4521         case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
4522         case R6_OPC_LDPC + (1 << 16):
4523         case R6_OPC_LDPC + (2 << 16):
4524         case R6_OPC_LDPC + (3 << 16):
4525             check_mips_64(ctx);
4526             offset = sextract32(ctx->opcode << 3, 0, 21);
4527             addr = addr_add(ctx, (pc & ~0x7), offset);
4528             gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
4529             break;
4530 #endif
4531         default:
4532             MIPS_INVAL("OPC_PCREL");
4533             generate_exception_end(ctx, EXCP_RI);
4534             break;
4535         }
4536         break;
4537     }
4538 }
4539
4540 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
4541 {
4542     TCGv t0, t1;
4543
4544     if (rd == 0) {
4545         /* Treat as NOP. */
4546         return;
4547     }
4548
4549     t0 = tcg_temp_new();
4550     t1 = tcg_temp_new();
4551
4552     gen_load_gpr(t0, rs);
4553     gen_load_gpr(t1, rt);
4554
4555     switch (opc) {
4556     case R6_OPC_DIV:
4557         {
4558             TCGv t2 = tcg_temp_new();
4559             TCGv t3 = tcg_temp_new();
4560             tcg_gen_ext32s_tl(t0, t0);
4561             tcg_gen_ext32s_tl(t1, t1);
4562             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4563             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4564             tcg_gen_and_tl(t2, t2, t3);
4565             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4566             tcg_gen_or_tl(t2, t2, t3);
4567             tcg_gen_movi_tl(t3, 0);
4568             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4569             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4570             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4571             tcg_temp_free(t3);
4572             tcg_temp_free(t2);
4573         }
4574         break;
4575     case R6_OPC_MOD:
4576         {
4577             TCGv t2 = tcg_temp_new();
4578             TCGv t3 = tcg_temp_new();
4579             tcg_gen_ext32s_tl(t0, t0);
4580             tcg_gen_ext32s_tl(t1, t1);
4581             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4582             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4583             tcg_gen_and_tl(t2, t2, t3);
4584             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4585             tcg_gen_or_tl(t2, t2, t3);
4586             tcg_gen_movi_tl(t3, 0);
4587             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4588             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4589             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4590             tcg_temp_free(t3);
4591             tcg_temp_free(t2);
4592         }
4593         break;
4594     case R6_OPC_DIVU:
4595         {
4596             TCGv t2 = tcg_const_tl(0);
4597             TCGv t3 = tcg_const_tl(1);
4598             tcg_gen_ext32u_tl(t0, t0);
4599             tcg_gen_ext32u_tl(t1, t1);
4600             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4601             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4602             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4603             tcg_temp_free(t3);
4604             tcg_temp_free(t2);
4605         }
4606         break;
4607     case R6_OPC_MODU:
4608         {
4609             TCGv t2 = tcg_const_tl(0);
4610             TCGv t3 = tcg_const_tl(1);
4611             tcg_gen_ext32u_tl(t0, t0);
4612             tcg_gen_ext32u_tl(t1, t1);
4613             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4614             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4615             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4616             tcg_temp_free(t3);
4617             tcg_temp_free(t2);
4618         }
4619         break;
4620     case R6_OPC_MUL:
4621         {
4622             TCGv_i32 t2 = tcg_temp_new_i32();
4623             TCGv_i32 t3 = tcg_temp_new_i32();
4624             tcg_gen_trunc_tl_i32(t2, t0);
4625             tcg_gen_trunc_tl_i32(t3, t1);
4626             tcg_gen_mul_i32(t2, t2, t3);
4627             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4628             tcg_temp_free_i32(t2);
4629             tcg_temp_free_i32(t3);
4630         }
4631         break;
4632     case R6_OPC_MUH:
4633         {
4634             TCGv_i32 t2 = tcg_temp_new_i32();
4635             TCGv_i32 t3 = tcg_temp_new_i32();
4636             tcg_gen_trunc_tl_i32(t2, t0);
4637             tcg_gen_trunc_tl_i32(t3, t1);
4638             tcg_gen_muls2_i32(t2, t3, t2, t3);
4639             tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4640             tcg_temp_free_i32(t2);
4641             tcg_temp_free_i32(t3);
4642         }
4643         break;
4644     case R6_OPC_MULU:
4645         {
4646             TCGv_i32 t2 = tcg_temp_new_i32();
4647             TCGv_i32 t3 = tcg_temp_new_i32();
4648             tcg_gen_trunc_tl_i32(t2, t0);
4649             tcg_gen_trunc_tl_i32(t3, t1);
4650             tcg_gen_mul_i32(t2, t2, t3);
4651             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4652             tcg_temp_free_i32(t2);
4653             tcg_temp_free_i32(t3);
4654         }
4655         break;
4656     case R6_OPC_MUHU:
4657         {
4658             TCGv_i32 t2 = tcg_temp_new_i32();
4659             TCGv_i32 t3 = tcg_temp_new_i32();
4660             tcg_gen_trunc_tl_i32(t2, t0);
4661             tcg_gen_trunc_tl_i32(t3, t1);
4662             tcg_gen_mulu2_i32(t2, t3, t2, t3);
4663             tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4664             tcg_temp_free_i32(t2);
4665             tcg_temp_free_i32(t3);
4666         }
4667         break;
4668 #if defined(TARGET_MIPS64)
4669     case R6_OPC_DDIV:
4670         {
4671             TCGv t2 = tcg_temp_new();
4672             TCGv t3 = tcg_temp_new();
4673             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4674             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4675             tcg_gen_and_tl(t2, t2, t3);
4676             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4677             tcg_gen_or_tl(t2, t2, t3);
4678             tcg_gen_movi_tl(t3, 0);
4679             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4680             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4681             tcg_temp_free(t3);
4682             tcg_temp_free(t2);
4683         }
4684         break;
4685     case R6_OPC_DMOD:
4686         {
4687             TCGv t2 = tcg_temp_new();
4688             TCGv t3 = tcg_temp_new();
4689             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4690             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4691             tcg_gen_and_tl(t2, t2, t3);
4692             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4693             tcg_gen_or_tl(t2, t2, t3);
4694             tcg_gen_movi_tl(t3, 0);
4695             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4696             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4697             tcg_temp_free(t3);
4698             tcg_temp_free(t2);
4699         }
4700         break;
4701     case R6_OPC_DDIVU:
4702         {
4703             TCGv t2 = tcg_const_tl(0);
4704             TCGv t3 = tcg_const_tl(1);
4705             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4706             tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
4707             tcg_temp_free(t3);
4708             tcg_temp_free(t2);
4709         }
4710         break;
4711     case R6_OPC_DMODU:
4712         {
4713             TCGv t2 = tcg_const_tl(0);
4714             TCGv t3 = tcg_const_tl(1);
4715             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4716             tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
4717             tcg_temp_free(t3);
4718             tcg_temp_free(t2);
4719         }
4720         break;
4721     case R6_OPC_DMUL:
4722         tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4723         break;
4724     case R6_OPC_DMUH:
4725         {
4726             TCGv t2 = tcg_temp_new();
4727             tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
4728             tcg_temp_free(t2);
4729         }
4730         break;
4731     case R6_OPC_DMULU:
4732         tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4733         break;
4734     case R6_OPC_DMUHU:
4735         {
4736             TCGv t2 = tcg_temp_new();
4737             tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
4738             tcg_temp_free(t2);
4739         }
4740         break;
4741 #endif
4742     default:
4743         MIPS_INVAL("r6 mul/div");
4744         generate_exception_end(ctx, EXCP_RI);
4745         goto out;
4746     }
4747  out:
4748     tcg_temp_free(t0);
4749     tcg_temp_free(t1);
4750 }
4751
4752 #if defined(TARGET_MIPS64)
4753 static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
4754 {
4755     TCGv t0, t1;
4756
4757     t0 = tcg_temp_new();
4758     t1 = tcg_temp_new();
4759
4760     gen_load_gpr(t0, rs);
4761     gen_load_gpr(t1, rt);
4762
4763     switch (opc) {
4764     case MMI_OPC_DIV1:
4765         {
4766             TCGv t2 = tcg_temp_new();
4767             TCGv t3 = tcg_temp_new();
4768             tcg_gen_ext32s_tl(t0, t0);
4769             tcg_gen_ext32s_tl(t1, t1);
4770             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4771             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4772             tcg_gen_and_tl(t2, t2, t3);
4773             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4774             tcg_gen_or_tl(t2, t2, t3);
4775             tcg_gen_movi_tl(t3, 0);
4776             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4777             tcg_gen_div_tl(cpu_LO[1], t0, t1);
4778             tcg_gen_rem_tl(cpu_HI[1], t0, t1);
4779             tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
4780             tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
4781             tcg_temp_free(t3);
4782             tcg_temp_free(t2);
4783         }
4784         break;
4785     case MMI_OPC_DIVU1:
4786         {
4787             TCGv t2 = tcg_const_tl(0);
4788             TCGv t3 = tcg_const_tl(1);
4789             tcg_gen_ext32u_tl(t0, t0);
4790             tcg_gen_ext32u_tl(t1, t1);
4791             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4792             tcg_gen_divu_tl(cpu_LO[1], t0, t1);
4793             tcg_gen_remu_tl(cpu_HI[1], t0, t1);
4794             tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
4795             tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
4796             tcg_temp_free(t3);
4797             tcg_temp_free(t2);
4798         }
4799         break;
4800     default:
4801         MIPS_INVAL("div1 TX79");
4802         generate_exception_end(ctx, EXCP_RI);
4803         goto out;
4804     }
4805  out:
4806     tcg_temp_free(t0);
4807     tcg_temp_free(t1);
4808 }
4809 #endif
4810
4811 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
4812                        int acc, int rs, int rt)
4813 {
4814     TCGv t0, t1;
4815
4816     t0 = tcg_temp_new();
4817     t1 = tcg_temp_new();
4818
4819     gen_load_gpr(t0, rs);
4820     gen_load_gpr(t1, rt);
4821
4822     if (acc != 0) {
4823         check_dsp(ctx);
4824     }
4825
4826     switch (opc) {
4827     case OPC_DIV:
4828         {
4829             TCGv t2 = tcg_temp_new();
4830             TCGv t3 = tcg_temp_new();
4831             tcg_gen_ext32s_tl(t0, t0);
4832             tcg_gen_ext32s_tl(t1, t1);
4833             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4834             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4835             tcg_gen_and_tl(t2, t2, t3);
4836             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4837             tcg_gen_or_tl(t2, t2, t3);
4838             tcg_gen_movi_tl(t3, 0);
4839             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4840             tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4841             tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4842             tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4843             tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4844             tcg_temp_free(t3);
4845             tcg_temp_free(t2);
4846         }
4847         break;
4848     case OPC_DIVU:
4849         {
4850             TCGv t2 = tcg_const_tl(0);
4851             TCGv t3 = tcg_const_tl(1);
4852             tcg_gen_ext32u_tl(t0, t0);
4853             tcg_gen_ext32u_tl(t1, t1);
4854             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4855             tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
4856             tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
4857             tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4858             tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4859             tcg_temp_free(t3);
4860             tcg_temp_free(t2);
4861         }
4862         break;
4863     case OPC_MULT:
4864         {
4865             TCGv_i32 t2 = tcg_temp_new_i32();
4866             TCGv_i32 t3 = tcg_temp_new_i32();
4867             tcg_gen_trunc_tl_i32(t2, t0);
4868             tcg_gen_trunc_tl_i32(t3, t1);
4869             tcg_gen_muls2_i32(t2, t3, t2, t3);
4870             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4871             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4872             tcg_temp_free_i32(t2);
4873             tcg_temp_free_i32(t3);
4874         }
4875         break;
4876     case OPC_MULTU:
4877         {
4878             TCGv_i32 t2 = tcg_temp_new_i32();
4879             TCGv_i32 t3 = tcg_temp_new_i32();
4880             tcg_gen_trunc_tl_i32(t2, t0);
4881             tcg_gen_trunc_tl_i32(t3, t1);
4882             tcg_gen_mulu2_i32(t2, t3, t2, t3);
4883             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4884             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4885             tcg_temp_free_i32(t2);
4886             tcg_temp_free_i32(t3);
4887         }
4888         break;
4889 #if defined(TARGET_MIPS64)
4890     case OPC_DDIV:
4891         {
4892             TCGv t2 = tcg_temp_new();
4893             TCGv t3 = tcg_temp_new();
4894             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4895             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4896             tcg_gen_and_tl(t2, t2, t3);
4897             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4898             tcg_gen_or_tl(t2, t2, t3);
4899             tcg_gen_movi_tl(t3, 0);
4900             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4901             tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4902             tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4903             tcg_temp_free(t3);
4904             tcg_temp_free(t2);
4905         }
4906         break;
4907     case OPC_DDIVU:
4908         {
4909             TCGv t2 = tcg_const_tl(0);
4910             TCGv t3 = tcg_const_tl(1);
4911             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4912             tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
4913             tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
4914             tcg_temp_free(t3);
4915             tcg_temp_free(t2);
4916         }
4917         break;
4918     case OPC_DMULT:
4919         tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
4920         break;
4921     case OPC_DMULTU:
4922         tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
4923         break;
4924 #endif
4925     case OPC_MADD:
4926         {
4927             TCGv_i64 t2 = tcg_temp_new_i64();
4928             TCGv_i64 t3 = tcg_temp_new_i64();
4929
4930             tcg_gen_ext_tl_i64(t2, t0);
4931             tcg_gen_ext_tl_i64(t3, t1);
4932             tcg_gen_mul_i64(t2, t2, t3);
4933             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4934             tcg_gen_add_i64(t2, t2, t3);
4935             tcg_temp_free_i64(t3);
4936             gen_move_low32(cpu_LO[acc], t2);
4937             gen_move_high32(cpu_HI[acc], t2);
4938             tcg_temp_free_i64(t2);
4939         }
4940         break;
4941     case OPC_MADDU:
4942         {
4943             TCGv_i64 t2 = tcg_temp_new_i64();
4944             TCGv_i64 t3 = tcg_temp_new_i64();
4945
4946             tcg_gen_ext32u_tl(t0, t0);
4947             tcg_gen_ext32u_tl(t1, t1);
4948             tcg_gen_extu_tl_i64(t2, t0);
4949             tcg_gen_extu_tl_i64(t3, t1);
4950             tcg_gen_mul_i64(t2, t2, t3);
4951             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4952             tcg_gen_add_i64(t2, t2, t3);
4953             tcg_temp_free_i64(t3);
4954             gen_move_low32(cpu_LO[acc], t2);
4955             gen_move_high32(cpu_HI[acc], t2);
4956             tcg_temp_free_i64(t2);
4957         }
4958         break;
4959     case OPC_MSUB:
4960         {
4961             TCGv_i64 t2 = tcg_temp_new_i64();
4962             TCGv_i64 t3 = tcg_temp_new_i64();
4963
4964             tcg_gen_ext_tl_i64(t2, t0);
4965             tcg_gen_ext_tl_i64(t3, t1);
4966             tcg_gen_mul_i64(t2, t2, t3);
4967             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4968             tcg_gen_sub_i64(t2, t3, t2);
4969             tcg_temp_free_i64(t3);
4970             gen_move_low32(cpu_LO[acc], t2);
4971             gen_move_high32(cpu_HI[acc], t2);
4972             tcg_temp_free_i64(t2);
4973         }
4974         break;
4975     case OPC_MSUBU:
4976         {
4977             TCGv_i64 t2 = tcg_temp_new_i64();
4978             TCGv_i64 t3 = tcg_temp_new_i64();
4979
4980             tcg_gen_ext32u_tl(t0, t0);
4981             tcg_gen_ext32u_tl(t1, t1);
4982             tcg_gen_extu_tl_i64(t2, t0);
4983             tcg_gen_extu_tl_i64(t3, t1);
4984             tcg_gen_mul_i64(t2, t2, t3);
4985             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4986             tcg_gen_sub_i64(t2, t3, t2);
4987             tcg_temp_free_i64(t3);
4988             gen_move_low32(cpu_LO[acc], t2);
4989             gen_move_high32(cpu_HI[acc], t2);
4990             tcg_temp_free_i64(t2);
4991         }
4992         break;
4993     default:
4994         MIPS_INVAL("mul/div");
4995         generate_exception_end(ctx, EXCP_RI);
4996         goto out;
4997     }
4998  out:
4999     tcg_temp_free(t0);
5000     tcg_temp_free(t1);
5001 }
5002
5003 /*
5004  * These MULT[U] and MADD[U] instructions implemented in for example
5005  * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
5006  * architectures are special three-operand variants with the syntax
5007  *
5008  *     MULT[U][1] rd, rs, rt
5009  *
5010  * such that
5011  *
5012  *     (rd, LO, HI) <- rs * rt
5013  *
5014  * and
5015  *
5016  *     MADD[U][1] rd, rs, rt
5017  *
5018  * such that
5019  *
5020  *     (rd, LO, HI) <- (LO, HI) + rs * rt
5021  *
5022  * where the low-order 32-bits of the result is placed into both the
5023  * GPR rd and the special register LO. The high-order 32-bits of the
5024  * result is placed into the special register HI.
5025  *
5026  * If the GPR rd is omitted in assembly language, it is taken to be 0,
5027  * which is the zero register that always reads as 0.
5028  */
5029 static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
5030                          int rd, int rs, int rt)
5031 {
5032     TCGv t0 = tcg_temp_new();
5033     TCGv t1 = tcg_temp_new();
5034     int acc = 0;
5035
5036     gen_load_gpr(t0, rs);
5037     gen_load_gpr(t1, rt);
5038
5039     switch (opc) {
5040     case MMI_OPC_MULT1:
5041         acc = 1;
5042         /* Fall through */
5043     case OPC_MULT:
5044         {
5045             TCGv_i32 t2 = tcg_temp_new_i32();
5046             TCGv_i32 t3 = tcg_temp_new_i32();
5047             tcg_gen_trunc_tl_i32(t2, t0);
5048             tcg_gen_trunc_tl_i32(t3, t1);
5049             tcg_gen_muls2_i32(t2, t3, t2, t3);
5050             if (rd) {
5051                 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
5052             }
5053             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
5054             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
5055             tcg_temp_free_i32(t2);
5056             tcg_temp_free_i32(t3);
5057         }
5058         break;
5059     case MMI_OPC_MULTU1:
5060         acc = 1;
5061         /* Fall through */
5062     case OPC_MULTU:
5063         {
5064             TCGv_i32 t2 = tcg_temp_new_i32();
5065             TCGv_i32 t3 = tcg_temp_new_i32();
5066             tcg_gen_trunc_tl_i32(t2, t0);
5067             tcg_gen_trunc_tl_i32(t3, t1);
5068             tcg_gen_mulu2_i32(t2, t3, t2, t3);
5069             if (rd) {
5070                 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
5071             }
5072             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
5073             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
5074             tcg_temp_free_i32(t2);
5075             tcg_temp_free_i32(t3);
5076         }
5077         break;
5078     case MMI_OPC_MADD1:
5079         acc = 1;
5080         /* Fall through */
5081     case MMI_OPC_MADD:
5082         {
5083             TCGv_i64 t2 = tcg_temp_new_i64();
5084             TCGv_i64 t3 = tcg_temp_new_i64();
5085
5086             tcg_gen_ext_tl_i64(t2, t0);
5087             tcg_gen_ext_tl_i64(t3, t1);
5088             tcg_gen_mul_i64(t2, t2, t3);
5089             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5090             tcg_gen_add_i64(t2, t2, t3);
5091             tcg_temp_free_i64(t3);
5092             gen_move_low32(cpu_LO[acc], t2);
5093             gen_move_high32(cpu_HI[acc], t2);
5094             if (rd) {
5095                 gen_move_low32(cpu_gpr[rd], t2);
5096             }
5097             tcg_temp_free_i64(t2);
5098         }
5099         break;
5100     case MMI_OPC_MADDU1:
5101         acc = 1;
5102         /* Fall through */
5103     case MMI_OPC_MADDU:
5104         {
5105             TCGv_i64 t2 = tcg_temp_new_i64();
5106             TCGv_i64 t3 = tcg_temp_new_i64();
5107
5108             tcg_gen_ext32u_tl(t0, t0);
5109             tcg_gen_ext32u_tl(t1, t1);
5110             tcg_gen_extu_tl_i64(t2, t0);
5111             tcg_gen_extu_tl_i64(t3, t1);
5112             tcg_gen_mul_i64(t2, t2, t3);
5113             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5114             tcg_gen_add_i64(t2, t2, t3);
5115             tcg_temp_free_i64(t3);
5116             gen_move_low32(cpu_LO[acc], t2);
5117             gen_move_high32(cpu_HI[acc], t2);
5118             if (rd) {
5119                 gen_move_low32(cpu_gpr[rd], t2);
5120             }
5121             tcg_temp_free_i64(t2);
5122         }
5123         break;
5124     default:
5125         MIPS_INVAL("mul/madd TXx9");
5126         generate_exception_end(ctx, EXCP_RI);
5127         goto out;
5128     }
5129
5130  out:
5131     tcg_temp_free(t0);
5132     tcg_temp_free(t1);
5133 }
5134
5135 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
5136                             int rd, int rs, int rt)
5137 {
5138     TCGv t0 = tcg_temp_new();
5139     TCGv t1 = tcg_temp_new();
5140
5141     gen_load_gpr(t0, rs);
5142     gen_load_gpr(t1, rt);
5143
5144     switch (opc) {
5145     case OPC_VR54XX_MULS:
5146         gen_helper_muls(t0, cpu_env, t0, t1);
5147         break;
5148     case OPC_VR54XX_MULSU:
5149         gen_helper_mulsu(t0, cpu_env, t0, t1);
5150         break;
5151     case OPC_VR54XX_MACC:
5152         gen_helper_macc(t0, cpu_env, t0, t1);
5153         break;
5154     case OPC_VR54XX_MACCU:
5155         gen_helper_maccu(t0, cpu_env, t0, t1);
5156         break;
5157     case OPC_VR54XX_MSAC:
5158         gen_helper_msac(t0, cpu_env, t0, t1);
5159         break;
5160     case OPC_VR54XX_MSACU:
5161         gen_helper_msacu(t0, cpu_env, t0, t1);
5162         break;
5163     case OPC_VR54XX_MULHI:
5164         gen_helper_mulhi(t0, cpu_env, t0, t1);
5165         break;
5166     case OPC_VR54XX_MULHIU:
5167         gen_helper_mulhiu(t0, cpu_env, t0, t1);
5168         break;
5169     case OPC_VR54XX_MULSHI:
5170         gen_helper_mulshi(t0, cpu_env, t0, t1);
5171         break;
5172     case OPC_VR54XX_MULSHIU:
5173         gen_helper_mulshiu(t0, cpu_env, t0, t1);
5174         break;
5175     case OPC_VR54XX_MACCHI:
5176         gen_helper_macchi(t0, cpu_env, t0, t1);
5177         break;
5178     case OPC_VR54XX_MACCHIU:
5179         gen_helper_macchiu(t0, cpu_env, t0, t1);
5180         break;
5181     case OPC_VR54XX_MSACHI:
5182         gen_helper_msachi(t0, cpu_env, t0, t1);
5183         break;
5184     case OPC_VR54XX_MSACHIU:
5185         gen_helper_msachiu(t0, cpu_env, t0, t1);
5186         break;
5187     default:
5188         MIPS_INVAL("mul vr54xx");
5189         generate_exception_end(ctx, EXCP_RI);
5190         goto out;
5191     }
5192     gen_store_gpr(t0, rd);
5193
5194  out:
5195     tcg_temp_free(t0);
5196     tcg_temp_free(t1);
5197 }
5198
5199 static void gen_cl (DisasContext *ctx, uint32_t opc,
5200                     int rd, int rs)
5201 {
5202     TCGv t0;
5203
5204     if (rd == 0) {
5205         /* Treat as NOP. */
5206         return;
5207     }
5208     t0 = cpu_gpr[rd];
5209     gen_load_gpr(t0, rs);
5210
5211     switch (opc) {
5212     case OPC_CLO:
5213     case R6_OPC_CLO:
5214 #if defined(TARGET_MIPS64)
5215     case OPC_DCLO:
5216     case R6_OPC_DCLO:
5217 #endif
5218         tcg_gen_not_tl(t0, t0);
5219         break;
5220     }
5221
5222     switch (opc) {
5223     case OPC_CLO:
5224     case R6_OPC_CLO:
5225     case OPC_CLZ:
5226     case R6_OPC_CLZ:
5227         tcg_gen_ext32u_tl(t0, t0);
5228         tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
5229         tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
5230         break;
5231 #if defined(TARGET_MIPS64)
5232     case OPC_DCLO:
5233     case R6_OPC_DCLO:
5234     case OPC_DCLZ:
5235     case R6_OPC_DCLZ:
5236         tcg_gen_clzi_i64(t0, t0, 64);
5237         break;
5238 #endif
5239     }
5240 }
5241
5242 /* Godson integer instructions */
5243 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
5244                                  int rd, int rs, int rt)
5245 {
5246     TCGv t0, t1;
5247
5248     if (rd == 0) {
5249         /* Treat as NOP. */
5250         return;
5251     }
5252
5253     switch (opc) {
5254     case OPC_MULT_G_2E:
5255     case OPC_MULT_G_2F:
5256     case OPC_MULTU_G_2E:
5257     case OPC_MULTU_G_2F:
5258 #if defined(TARGET_MIPS64)
5259     case OPC_DMULT_G_2E:
5260     case OPC_DMULT_G_2F:
5261     case OPC_DMULTU_G_2E:
5262     case OPC_DMULTU_G_2F:
5263 #endif
5264         t0 = tcg_temp_new();
5265         t1 = tcg_temp_new();
5266         break;
5267     default:
5268         t0 = tcg_temp_local_new();
5269         t1 = tcg_temp_local_new();
5270         break;
5271     }
5272
5273     gen_load_gpr(t0, rs);
5274     gen_load_gpr(t1, rt);
5275
5276     switch (opc) {
5277     case OPC_MULT_G_2E:
5278     case OPC_MULT_G_2F:
5279         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5280         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5281         break;
5282     case OPC_MULTU_G_2E:
5283     case OPC_MULTU_G_2F:
5284         tcg_gen_ext32u_tl(t0, t0);
5285         tcg_gen_ext32u_tl(t1, t1);
5286         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5287         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5288         break;
5289     case OPC_DIV_G_2E:
5290     case OPC_DIV_G_2F:
5291         {
5292             TCGLabel *l1 = gen_new_label();
5293             TCGLabel *l2 = gen_new_label();
5294             TCGLabel *l3 = gen_new_label();
5295             tcg_gen_ext32s_tl(t0, t0);
5296             tcg_gen_ext32s_tl(t1, t1);
5297             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5298             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5299             tcg_gen_br(l3);
5300             gen_set_label(l1);
5301             tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5302             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5303             tcg_gen_mov_tl(cpu_gpr[rd], t0);
5304             tcg_gen_br(l3);
5305             gen_set_label(l2);
5306             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5307             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5308             gen_set_label(l3);
5309         }
5310         break;
5311     case OPC_DIVU_G_2E:
5312     case OPC_DIVU_G_2F:
5313         {
5314             TCGLabel *l1 = gen_new_label();
5315             TCGLabel *l2 = gen_new_label();
5316             tcg_gen_ext32u_tl(t0, t0);
5317             tcg_gen_ext32u_tl(t1, t1);
5318             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5319             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5320             tcg_gen_br(l2);
5321             gen_set_label(l1);
5322             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5323             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5324             gen_set_label(l2);
5325         }
5326         break;
5327     case OPC_MOD_G_2E:
5328     case OPC_MOD_G_2F:
5329         {
5330             TCGLabel *l1 = gen_new_label();
5331             TCGLabel *l2 = gen_new_label();
5332             TCGLabel *l3 = gen_new_label();
5333             tcg_gen_ext32u_tl(t0, t0);
5334             tcg_gen_ext32u_tl(t1, t1);
5335             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5336             tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5337             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5338             gen_set_label(l1);
5339             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5340             tcg_gen_br(l3);
5341             gen_set_label(l2);
5342             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5343             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5344             gen_set_label(l3);
5345         }
5346         break;
5347     case OPC_MODU_G_2E:
5348     case OPC_MODU_G_2F:
5349         {
5350             TCGLabel *l1 = gen_new_label();
5351             TCGLabel *l2 = gen_new_label();
5352             tcg_gen_ext32u_tl(t0, t0);
5353             tcg_gen_ext32u_tl(t1, t1);
5354             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5355             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5356             tcg_gen_br(l2);
5357             gen_set_label(l1);
5358             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5359             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5360             gen_set_label(l2);
5361         }
5362         break;
5363 #if defined(TARGET_MIPS64)
5364     case OPC_DMULT_G_2E:
5365     case OPC_DMULT_G_2F:
5366         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5367         break;
5368     case OPC_DMULTU_G_2E:
5369     case OPC_DMULTU_G_2F:
5370         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5371         break;
5372     case OPC_DDIV_G_2E:
5373     case OPC_DDIV_G_2F:
5374         {
5375             TCGLabel *l1 = gen_new_label();
5376             TCGLabel *l2 = gen_new_label();
5377             TCGLabel *l3 = gen_new_label();
5378             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5379             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5380             tcg_gen_br(l3);
5381             gen_set_label(l1);
5382             tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5383             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5384             tcg_gen_mov_tl(cpu_gpr[rd], t0);
5385             tcg_gen_br(l3);
5386             gen_set_label(l2);
5387             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5388             gen_set_label(l3);
5389         }
5390         break;
5391     case OPC_DDIVU_G_2E:
5392     case OPC_DDIVU_G_2F:
5393         {
5394             TCGLabel *l1 = gen_new_label();
5395             TCGLabel *l2 = gen_new_label();
5396             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5397             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5398             tcg_gen_br(l2);
5399             gen_set_label(l1);
5400             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5401             gen_set_label(l2);
5402         }
5403         break;
5404     case OPC_DMOD_G_2E:
5405     case OPC_DMOD_G_2F:
5406         {
5407             TCGLabel *l1 = gen_new_label();
5408             TCGLabel *l2 = gen_new_label();
5409             TCGLabel *l3 = gen_new_label();
5410             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5411             tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5412             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5413             gen_set_label(l1);
5414             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5415             tcg_gen_br(l3);
5416             gen_set_label(l2);
5417             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5418             gen_set_label(l3);
5419         }
5420         break;
5421     case OPC_DMODU_G_2E:
5422     case OPC_DMODU_G_2F:
5423         {
5424             TCGLabel *l1 = gen_new_label();
5425             TCGLabel *l2 = gen_new_label();
5426             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5427             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5428             tcg_gen_br(l2);
5429             gen_set_label(l1);
5430             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5431             gen_set_label(l2);
5432         }
5433         break;
5434 #endif
5435     }
5436
5437     tcg_temp_free(t0);
5438     tcg_temp_free(t1);
5439 }
5440
5441 /* Loongson multimedia instructions */
5442 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
5443 {
5444     uint32_t opc, shift_max;
5445     TCGv_i64 t0, t1;
5446
5447     opc = MASK_LMI(ctx->opcode);
5448     switch (opc) {
5449     case OPC_ADD_CP2:
5450     case OPC_SUB_CP2:
5451     case OPC_DADD_CP2:
5452     case OPC_DSUB_CP2:
5453         t0 = tcg_temp_local_new_i64();
5454         t1 = tcg_temp_local_new_i64();
5455         break;
5456     default:
5457         t0 = tcg_temp_new_i64();
5458         t1 = tcg_temp_new_i64();
5459         break;
5460     }
5461
5462     check_cp1_enabled(ctx);
5463     gen_load_fpr64(ctx, t0, rs);
5464     gen_load_fpr64(ctx, t1, rt);
5465
5466 #define LMI_HELPER(UP, LO) \
5467     case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
5468 #define LMI_HELPER_1(UP, LO) \
5469     case OPC_##UP: gen_helper_##LO(t0, t0); break
5470 #define LMI_DIRECT(UP, LO, OP) \
5471     case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
5472
5473     switch (opc) {
5474     LMI_HELPER(PADDSH, paddsh);
5475     LMI_HELPER(PADDUSH, paddush);
5476     LMI_HELPER(PADDH, paddh);
5477     LMI_HELPER(PADDW, paddw);
5478     LMI_HELPER(PADDSB, paddsb);
5479     LMI_HELPER(PADDUSB, paddusb);
5480     LMI_HELPER(PADDB, paddb);
5481
5482     LMI_HELPER(PSUBSH, psubsh);
5483     LMI_HELPER(PSUBUSH, psubush);
5484     LMI_HELPER(PSUBH, psubh);
5485     LMI_HELPER(PSUBW, psubw);
5486     LMI_HELPER(PSUBSB, psubsb);
5487     LMI_HELPER(PSUBUSB, psubusb);
5488     LMI_HELPER(PSUBB, psubb);
5489
5490     LMI_HELPER(PSHUFH, pshufh);
5491     LMI_HELPER(PACKSSWH, packsswh);
5492     LMI_HELPER(PACKSSHB, packsshb);
5493     LMI_HELPER(PACKUSHB, packushb);
5494
5495     LMI_HELPER(PUNPCKLHW, punpcklhw);
5496     LMI_HELPER(PUNPCKHHW, punpckhhw);
5497     LMI_HELPER(PUNPCKLBH, punpcklbh);
5498     LMI_HELPER(PUNPCKHBH, punpckhbh);
5499     LMI_HELPER(PUNPCKLWD, punpcklwd);
5500     LMI_HELPER(PUNPCKHWD, punpckhwd);
5501
5502     LMI_HELPER(PAVGH, pavgh);
5503     LMI_HELPER(PAVGB, pavgb);
5504     LMI_HELPER(PMAXSH, pmaxsh);
5505     LMI_HELPER(PMINSH, pminsh);
5506     LMI_HELPER(PMAXUB, pmaxub);
5507     LMI_HELPER(PMINUB, pminub);
5508
5509     LMI_HELPER(PCMPEQW, pcmpeqw);
5510     LMI_HELPER(PCMPGTW, pcmpgtw);
5511     LMI_HELPER(PCMPEQH, pcmpeqh);
5512     LMI_HELPER(PCMPGTH, pcmpgth);
5513     LMI_HELPER(PCMPEQB, pcmpeqb);
5514     LMI_HELPER(PCMPGTB, pcmpgtb);
5515
5516     LMI_HELPER(PSLLW, psllw);
5517     LMI_HELPER(PSLLH, psllh);
5518     LMI_HELPER(PSRLW, psrlw);
5519     LMI_HELPER(PSRLH, psrlh);
5520     LMI_HELPER(PSRAW, psraw);
5521     LMI_HELPER(PSRAH, psrah);
5522
5523     LMI_HELPER(PMULLH, pmullh);
5524     LMI_HELPER(PMULHH, pmulhh);
5525     LMI_HELPER(PMULHUH, pmulhuh);
5526     LMI_HELPER(PMADDHW, pmaddhw);
5527
5528     LMI_HELPER(PASUBUB, pasubub);
5529     LMI_HELPER_1(BIADD, biadd);
5530     LMI_HELPER_1(PMOVMSKB, pmovmskb);
5531
5532     LMI_DIRECT(PADDD, paddd, add);
5533     LMI_DIRECT(PSUBD, psubd, sub);
5534     LMI_DIRECT(XOR_CP2, xor, xor);
5535     LMI_DIRECT(NOR_CP2, nor, nor);
5536     LMI_DIRECT(AND_CP2, and, and);
5537     LMI_DIRECT(OR_CP2, or, or);
5538
5539     case OPC_PANDN:
5540         tcg_gen_andc_i64(t0, t1, t0);
5541         break;
5542
5543     case OPC_PINSRH_0:
5544         tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
5545         break;
5546     case OPC_PINSRH_1:
5547         tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
5548         break;
5549     case OPC_PINSRH_2:
5550         tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
5551         break;
5552     case OPC_PINSRH_3:
5553         tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
5554         break;
5555
5556     case OPC_PEXTRH:
5557         tcg_gen_andi_i64(t1, t1, 3);
5558         tcg_gen_shli_i64(t1, t1, 4);
5559         tcg_gen_shr_i64(t0, t0, t1);
5560         tcg_gen_ext16u_i64(t0, t0);
5561         break;
5562
5563     case OPC_ADDU_CP2:
5564         tcg_gen_add_i64(t0, t0, t1);
5565         tcg_gen_ext32s_i64(t0, t0);
5566         break;
5567     case OPC_SUBU_CP2:
5568         tcg_gen_sub_i64(t0, t0, t1);
5569         tcg_gen_ext32s_i64(t0, t0);
5570         break;
5571
5572     case OPC_SLL_CP2:
5573         shift_max = 32;
5574         goto do_shift;
5575     case OPC_SRL_CP2:
5576         shift_max = 32;
5577         goto do_shift;
5578     case OPC_SRA_CP2:
5579         shift_max = 32;
5580         goto do_shift;
5581     case OPC_DSLL_CP2:
5582         shift_max = 64;
5583         goto do_shift;
5584     case OPC_DSRL_CP2:
5585         shift_max = 64;
5586         goto do_shift;
5587     case OPC_DSRA_CP2:
5588         shift_max = 64;
5589         goto do_shift;
5590     do_shift:
5591         /* Make sure shift count isn't TCG undefined behaviour.  */
5592         tcg_gen_andi_i64(t1, t1, shift_max - 1);
5593
5594         switch (opc) {
5595         case OPC_SLL_CP2:
5596         case OPC_DSLL_CP2:
5597             tcg_gen_shl_i64(t0, t0, t1);
5598             break;
5599         case OPC_SRA_CP2:
5600         case OPC_DSRA_CP2:
5601             /* Since SRA is UndefinedResult without sign-extended inputs,
5602                we can treat SRA and DSRA the same.  */
5603             tcg_gen_sar_i64(t0, t0, t1);
5604             break;
5605         case OPC_SRL_CP2:
5606             /* We want to shift in zeros for SRL; zero-extend first.  */
5607             tcg_gen_ext32u_i64(t0, t0);
5608             /* FALLTHRU */
5609         case OPC_DSRL_CP2:
5610             tcg_gen_shr_i64(t0, t0, t1);
5611             break;
5612         }
5613
5614         if (shift_max == 32) {
5615             tcg_gen_ext32s_i64(t0, t0);
5616         }
5617
5618         /* Shifts larger than MAX produce zero.  */
5619         tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
5620         tcg_gen_neg_i64(t1, t1);
5621         tcg_gen_and_i64(t0, t0, t1);
5622         break;
5623
5624     case OPC_ADD_CP2:
5625     case OPC_DADD_CP2:
5626         {
5627             TCGv_i64 t2 = tcg_temp_new_i64();
5628             TCGLabel *lab = gen_new_label();
5629
5630             tcg_gen_mov_i64(t2, t0);
5631             tcg_gen_add_i64(t0, t1, t2);
5632             if (opc == OPC_ADD_CP2) {
5633                 tcg_gen_ext32s_i64(t0, t0);
5634             }
5635             tcg_gen_xor_i64(t1, t1, t2);
5636             tcg_gen_xor_i64(t2, t2, t0);
5637             tcg_gen_andc_i64(t1, t2, t1);
5638             tcg_temp_free_i64(t2);
5639             tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5640             generate_exception(ctx, EXCP_OVERFLOW);
5641             gen_set_label(lab);
5642             break;
5643         }
5644
5645     case OPC_SUB_CP2:
5646     case OPC_DSUB_CP2:
5647         {
5648             TCGv_i64 t2 = tcg_temp_new_i64();
5649             TCGLabel *lab = gen_new_label();
5650
5651             tcg_gen_mov_i64(t2, t0);
5652             tcg_gen_sub_i64(t0, t1, t2);
5653             if (opc == OPC_SUB_CP2) {
5654                 tcg_gen_ext32s_i64(t0, t0);
5655             }
5656             tcg_gen_xor_i64(t1, t1, t2);
5657             tcg_gen_xor_i64(t2, t2, t0);
5658             tcg_gen_and_i64(t1, t1, t2);
5659             tcg_temp_free_i64(t2);
5660             tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5661             generate_exception(ctx, EXCP_OVERFLOW);
5662             gen_set_label(lab);
5663             break;
5664         }
5665
5666     case OPC_PMULUW:
5667         tcg_gen_ext32u_i64(t0, t0);
5668         tcg_gen_ext32u_i64(t1, t1);
5669         tcg_gen_mul_i64(t0, t0, t1);
5670         break;
5671
5672     case OPC_SEQU_CP2:
5673     case OPC_SEQ_CP2:
5674     case OPC_SLTU_CP2:
5675     case OPC_SLT_CP2:
5676     case OPC_SLEU_CP2:
5677     case OPC_SLE_CP2:
5678         /* ??? Document is unclear: Set FCC[CC].  Does that mean the
5679            FD field is the CC field?  */
5680     default:
5681         MIPS_INVAL("loongson_cp2");
5682         generate_exception_end(ctx, EXCP_RI);
5683         return;
5684     }
5685
5686 #undef LMI_HELPER
5687 #undef LMI_DIRECT
5688
5689     gen_store_fpr64(ctx, t0, rd);
5690
5691     tcg_temp_free_i64(t0);
5692     tcg_temp_free_i64(t1);
5693 }
5694
5695 /* Traps */
5696 static void gen_trap (DisasContext *ctx, uint32_t opc,
5697                       int rs, int rt, int16_t imm)
5698 {
5699     int cond;
5700     TCGv t0 = tcg_temp_new();
5701     TCGv t1 = tcg_temp_new();
5702
5703     cond = 0;
5704     /* Load needed operands */
5705     switch (opc) {
5706     case OPC_TEQ:
5707     case OPC_TGE:
5708     case OPC_TGEU:
5709     case OPC_TLT:
5710     case OPC_TLTU:
5711     case OPC_TNE:
5712         /* Compare two registers */
5713         if (rs != rt) {
5714             gen_load_gpr(t0, rs);
5715             gen_load_gpr(t1, rt);
5716             cond = 1;
5717         }
5718         break;
5719     case OPC_TEQI:
5720     case OPC_TGEI:
5721     case OPC_TGEIU:
5722     case OPC_TLTI:
5723     case OPC_TLTIU:
5724     case OPC_TNEI:
5725         /* Compare register to immediate */
5726         if (rs != 0 || imm != 0) {
5727             gen_load_gpr(t0, rs);
5728             tcg_gen_movi_tl(t1, (int32_t)imm);
5729             cond = 1;
5730         }
5731         break;
5732     }
5733     if (cond == 0) {
5734         switch (opc) {
5735         case OPC_TEQ:   /* rs == rs */
5736         case OPC_TEQI:  /* r0 == 0  */
5737         case OPC_TGE:   /* rs >= rs */
5738         case OPC_TGEI:  /* r0 >= 0  */
5739         case OPC_TGEU:  /* rs >= rs unsigned */
5740         case OPC_TGEIU: /* r0 >= 0  unsigned */
5741             /* Always trap */
5742             generate_exception_end(ctx, EXCP_TRAP);
5743             break;
5744         case OPC_TLT:   /* rs < rs           */
5745         case OPC_TLTI:  /* r0 < 0            */
5746         case OPC_TLTU:  /* rs < rs unsigned  */
5747         case OPC_TLTIU: /* r0 < 0  unsigned  */
5748         case OPC_TNE:   /* rs != rs          */
5749         case OPC_TNEI:  /* r0 != 0           */
5750             /* Never trap: treat as NOP. */
5751             break;
5752         }
5753     } else {
5754         TCGLabel *l1 = gen_new_label();
5755
5756         switch (opc) {
5757         case OPC_TEQ:
5758         case OPC_TEQI:
5759             tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
5760             break;
5761         case OPC_TGE:
5762         case OPC_TGEI:
5763             tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
5764             break;
5765         case OPC_TGEU:
5766         case OPC_TGEIU:
5767             tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
5768             break;
5769         case OPC_TLT:
5770         case OPC_TLTI:
5771             tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
5772             break;
5773         case OPC_TLTU:
5774         case OPC_TLTIU:
5775             tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
5776             break;
5777         case OPC_TNE:
5778         case OPC_TNEI:
5779             tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
5780             break;
5781         }
5782         generate_exception(ctx, EXCP_TRAP);
5783         gen_set_label(l1);
5784     }
5785     tcg_temp_free(t0);
5786     tcg_temp_free(t1);
5787 }
5788
5789 static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
5790 {
5791     if (unlikely(ctx->base.singlestep_enabled)) {
5792         return false;
5793     }
5794
5795 #ifndef CONFIG_USER_ONLY
5796     return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
5797 #else
5798     return true;
5799 #endif
5800 }
5801
5802 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
5803 {
5804     if (use_goto_tb(ctx, dest)) {
5805         tcg_gen_goto_tb(n);
5806         gen_save_pc(dest);
5807         tcg_gen_exit_tb(ctx->base.tb, n);
5808     } else {
5809         gen_save_pc(dest);
5810         if (ctx->base.singlestep_enabled) {
5811             save_cpu_state(ctx, 0);
5812             gen_helper_raise_exception_debug(cpu_env);
5813         }
5814         tcg_gen_lookup_and_goto_ptr();
5815     }
5816 }
5817
5818 /* Branches (before delay slot) */
5819 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
5820                                 int insn_bytes,
5821                                 int rs, int rt, int32_t offset,
5822                                 int delayslot_size)
5823 {
5824     target_ulong btgt = -1;
5825     int blink = 0;
5826     int bcond_compute = 0;
5827     TCGv t0 = tcg_temp_new();
5828     TCGv t1 = tcg_temp_new();
5829
5830     if (ctx->hflags & MIPS_HFLAG_BMASK) {
5831 #ifdef MIPS_DEBUG_DISAS
5832         LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
5833                   TARGET_FMT_lx "\n", ctx->base.pc_next);
5834 #endif
5835         generate_exception_end(ctx, EXCP_RI);
5836         goto out;
5837     }
5838
5839     /* Load needed operands */
5840     switch (opc) {
5841     case OPC_BEQ:
5842     case OPC_BEQL:
5843     case OPC_BNE:
5844     case OPC_BNEL:
5845         /* Compare two registers */
5846         if (rs != rt) {
5847             gen_load_gpr(t0, rs);
5848             gen_load_gpr(t1, rt);
5849             bcond_compute = 1;
5850         }
5851         btgt = ctx->base.pc_next + insn_bytes + offset;
5852         break;
5853     case OPC_BGEZ:
5854     case OPC_BGEZAL:
5855     case OPC_BGEZALL:
5856     case OPC_BGEZL:
5857     case OPC_BGTZ:
5858     case OPC_BGTZL:
5859     case OPC_BLEZ:
5860     case OPC_BLEZL:
5861     case OPC_BLTZ:
5862     case OPC_BLTZAL:
5863     case OPC_BLTZALL:
5864     case OPC_BLTZL:
5865         /* Compare to zero */
5866         if (rs != 0) {
5867             gen_load_gpr(t0, rs);
5868             bcond_compute = 1;
5869         }
5870         btgt = ctx->base.pc_next + insn_bytes + offset;
5871         break;
5872     case OPC_BPOSGE32:
5873 #if defined(TARGET_MIPS64)
5874     case OPC_BPOSGE64:
5875         tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
5876 #else
5877         tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5878 #endif
5879         bcond_compute = 1;
5880         btgt = ctx->base.pc_next + insn_bytes + offset;
5881         break;
5882     case OPC_J:
5883     case OPC_JAL:
5884     case OPC_JALX:
5885         /* Jump to immediate */
5886         btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
5887             (uint32_t)offset;
5888         break;
5889     case OPC_JR:
5890     case OPC_JALR:
5891         /* Jump to register */
5892         if (offset != 0 && offset != 16) {
5893             /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5894                others are reserved. */
5895             MIPS_INVAL("jump hint");
5896             generate_exception_end(ctx, EXCP_RI);
5897             goto out;
5898         }
5899         gen_load_gpr(btarget, rs);
5900         break;
5901     default:
5902         MIPS_INVAL("branch/jump");
5903         generate_exception_end(ctx, EXCP_RI);
5904         goto out;
5905     }
5906     if (bcond_compute == 0) {
5907         /* No condition to be computed */
5908         switch (opc) {
5909         case OPC_BEQ:     /* rx == rx        */
5910         case OPC_BEQL:    /* rx == rx likely */
5911         case OPC_BGEZ:    /* 0 >= 0          */
5912         case OPC_BGEZL:   /* 0 >= 0 likely   */
5913         case OPC_BLEZ:    /* 0 <= 0          */
5914         case OPC_BLEZL:   /* 0 <= 0 likely   */
5915             /* Always take */
5916             ctx->hflags |= MIPS_HFLAG_B;
5917             break;
5918         case OPC_BGEZAL:  /* 0 >= 0          */
5919         case OPC_BGEZALL: /* 0 >= 0 likely   */
5920             /* Always take and link */
5921             blink = 31;
5922             ctx->hflags |= MIPS_HFLAG_B;
5923             break;
5924         case OPC_BNE:     /* rx != rx        */
5925         case OPC_BGTZ:    /* 0 > 0           */
5926         case OPC_BLTZ:    /* 0 < 0           */
5927             /* Treat as NOP. */
5928             goto out;
5929         case OPC_BLTZAL:  /* 0 < 0           */
5930             /* Handle as an unconditional branch to get correct delay
5931                slot checking.  */
5932             blink = 31;
5933             btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
5934             ctx->hflags |= MIPS_HFLAG_B;
5935             break;
5936         case OPC_BLTZALL: /* 0 < 0 likely */
5937             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
5938             /* Skip the instruction in the delay slot */
5939             ctx->base.pc_next += 4;
5940             goto out;
5941         case OPC_BNEL:    /* rx != rx likely */
5942         case OPC_BGTZL:   /* 0 > 0 likely */
5943         case OPC_BLTZL:   /* 0 < 0 likely */
5944             /* Skip the instruction in the delay slot */
5945             ctx->base.pc_next += 4;
5946             goto out;
5947         case OPC_J:
5948             ctx->hflags |= MIPS_HFLAG_B;
5949             break;
5950         case OPC_JALX:
5951             ctx->hflags |= MIPS_HFLAG_BX;
5952             /* Fallthrough */
5953         case OPC_JAL:
5954             blink = 31;
5955             ctx->hflags |= MIPS_HFLAG_B;
5956             break;
5957         case OPC_JR:
5958             ctx->hflags |= MIPS_HFLAG_BR;
5959             break;
5960         case OPC_JALR:
5961             blink = rt;
5962             ctx->hflags |= MIPS_HFLAG_BR;
5963             break;
5964         default:
5965             MIPS_INVAL("branch/jump");
5966             generate_exception_end(ctx, EXCP_RI);
5967             goto out;
5968         }
5969     } else {
5970         switch (opc) {
5971         case OPC_BEQ:
5972             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5973             goto not_likely;
5974         case OPC_BEQL:
5975             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5976             goto likely;
5977         case OPC_BNE:
5978             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5979             goto not_likely;
5980         case OPC_BNEL:
5981             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5982             goto likely;
5983         case OPC_BGEZ:
5984             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5985             goto not_likely;
5986         case OPC_BGEZL:
5987             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5988             goto likely;
5989         case OPC_BGEZAL:
5990             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5991             blink = 31;
5992             goto not_likely;
5993         case OPC_BGEZALL:
5994             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5995             blink = 31;
5996             goto likely;
5997         case OPC_BGTZ:
5998             tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5999             goto not_likely;
6000         case OPC_BGTZL:
6001             tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6002             goto likely;
6003         case OPC_BLEZ:
6004             tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6005             goto not_likely;
6006         case OPC_BLEZL:
6007             tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6008             goto likely;
6009         case OPC_BLTZ:
6010             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6011             goto not_likely;
6012         case OPC_BLTZL:
6013             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6014             goto likely;
6015         case OPC_BPOSGE32:
6016             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
6017             goto not_likely;
6018 #if defined(TARGET_MIPS64)
6019         case OPC_BPOSGE64:
6020             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
6021             goto not_likely;
6022 #endif
6023         case OPC_BLTZAL:
6024             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6025             blink = 31;
6026         not_likely:
6027             ctx->hflags |= MIPS_HFLAG_BC;
6028             break;
6029         case OPC_BLTZALL:
6030             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6031             blink = 31;
6032         likely:
6033             ctx->hflags |= MIPS_HFLAG_BL;
6034             break;
6035         default:
6036             MIPS_INVAL("conditional branch/jump");
6037             generate_exception_end(ctx, EXCP_RI);
6038             goto out;
6039         }
6040     }
6041
6042     ctx->btarget = btgt;
6043
6044     switch (delayslot_size) {
6045     case 2:
6046         ctx->hflags |= MIPS_HFLAG_BDS16;
6047         break;
6048     case 4:
6049         ctx->hflags |= MIPS_HFLAG_BDS32;
6050         break;
6051     }
6052
6053     if (blink > 0) {
6054         int post_delay = insn_bytes + delayslot_size;
6055         int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
6056
6057         tcg_gen_movi_tl(cpu_gpr[blink],
6058                         ctx->base.pc_next + post_delay + lowbit);
6059     }
6060
6061  out:
6062     if (insn_bytes == 2)
6063         ctx->hflags |= MIPS_HFLAG_B16;
6064     tcg_temp_free(t0);
6065     tcg_temp_free(t1);
6066 }
6067
6068
6069 /* nanoMIPS Branches */
6070 static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc,
6071                                 int insn_bytes,
6072                                 int rs, int rt, int32_t offset)
6073 {
6074     target_ulong btgt = -1;
6075     int bcond_compute = 0;
6076     TCGv t0 = tcg_temp_new();
6077     TCGv t1 = tcg_temp_new();
6078
6079     /* Load needed operands */
6080     switch (opc) {
6081     case OPC_BEQ:
6082     case OPC_BNE:
6083         /* Compare two registers */
6084         if (rs != rt) {
6085             gen_load_gpr(t0, rs);
6086             gen_load_gpr(t1, rt);
6087             bcond_compute = 1;
6088         }
6089         btgt = ctx->base.pc_next + insn_bytes + offset;
6090         break;
6091     case OPC_BGEZAL:
6092         /* Compare to zero */
6093         if (rs != 0) {
6094             gen_load_gpr(t0, rs);
6095             bcond_compute = 1;
6096         }
6097         btgt = ctx->base.pc_next + insn_bytes + offset;
6098         break;
6099     case OPC_BPOSGE32:
6100         tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
6101         bcond_compute = 1;
6102         btgt = ctx->base.pc_next + insn_bytes + offset;
6103         break;
6104     case OPC_JR:
6105     case OPC_JALR:
6106         /* Jump to register */
6107         if (offset != 0 && offset != 16) {
6108             /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6109                others are reserved. */
6110             MIPS_INVAL("jump hint");
6111             generate_exception_end(ctx, EXCP_RI);
6112             goto out;
6113         }
6114         gen_load_gpr(btarget, rs);
6115         break;
6116     default:
6117         MIPS_INVAL("branch/jump");
6118         generate_exception_end(ctx, EXCP_RI);
6119         goto out;
6120     }
6121     if (bcond_compute == 0) {
6122         /* No condition to be computed */
6123         switch (opc) {
6124         case OPC_BEQ:     /* rx == rx        */
6125             /* Always take */
6126             ctx->hflags |= MIPS_HFLAG_B;
6127             break;
6128         case OPC_BGEZAL:  /* 0 >= 0          */
6129             /* Always take and link */
6130             tcg_gen_movi_tl(cpu_gpr[31],
6131                             ctx->base.pc_next + insn_bytes);
6132             ctx->hflags |= MIPS_HFLAG_B;
6133             break;
6134         case OPC_BNE:     /* rx != rx        */
6135             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
6136             /* Skip the instruction in the delay slot */
6137             ctx->base.pc_next += 4;
6138             goto out;
6139         case OPC_JR:
6140             ctx->hflags |= MIPS_HFLAG_BR;
6141             break;
6142         case OPC_JALR:
6143             if (rt > 0) {
6144                 tcg_gen_movi_tl(cpu_gpr[rt],
6145                                 ctx->base.pc_next + insn_bytes);
6146             }
6147             ctx->hflags |= MIPS_HFLAG_BR;
6148             break;
6149         default:
6150             MIPS_INVAL("branch/jump");
6151             generate_exception_end(ctx, EXCP_RI);
6152             goto out;
6153         }
6154     } else {
6155         switch (opc) {
6156         case OPC_BEQ:
6157             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6158             goto not_likely;
6159         case OPC_BNE:
6160             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6161             goto not_likely;
6162         case OPC_BGEZAL:
6163             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6164             tcg_gen_movi_tl(cpu_gpr[31],
6165                             ctx->base.pc_next + insn_bytes);
6166             goto not_likely;
6167         case OPC_BPOSGE32:
6168             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
6169         not_likely:
6170             ctx->hflags |= MIPS_HFLAG_BC;
6171             break;
6172         default:
6173             MIPS_INVAL("conditional branch/jump");
6174             generate_exception_end(ctx, EXCP_RI);
6175             goto out;
6176         }
6177     }
6178
6179     ctx->btarget = btgt;
6180
6181  out:
6182     if (insn_bytes == 2) {
6183         ctx->hflags |= MIPS_HFLAG_B16;
6184     }
6185     tcg_temp_free(t0);
6186     tcg_temp_free(t1);
6187 }
6188
6189
6190 /* special3 bitfield operations */
6191 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
6192                         int rs, int lsb, int msb)
6193 {
6194     TCGv t0 = tcg_temp_new();
6195     TCGv t1 = tcg_temp_new();
6196
6197     gen_load_gpr(t1, rs);
6198     switch (opc) {
6199     case OPC_EXT:
6200         if (lsb + msb > 31) {
6201             goto fail;
6202         }
6203         if (msb != 31) {
6204             tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
6205         } else {
6206             /* The two checks together imply that lsb == 0,
6207                so this is a simple sign-extension.  */
6208             tcg_gen_ext32s_tl(t0, t1);
6209         }
6210         break;
6211 #if defined(TARGET_MIPS64)
6212     case OPC_DEXTU:
6213         lsb += 32;
6214         goto do_dext;
6215     case OPC_DEXTM:
6216         msb += 32;
6217         goto do_dext;
6218     case OPC_DEXT:
6219     do_dext:
6220         if (lsb + msb > 63) {
6221             goto fail;
6222         }
6223         tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
6224         break;
6225 #endif
6226     case OPC_INS:
6227         if (lsb > msb) {
6228             goto fail;
6229         }
6230         gen_load_gpr(t0, rt);
6231         tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
6232         tcg_gen_ext32s_tl(t0, t0);
6233         break;
6234 #if defined(TARGET_MIPS64)
6235     case OPC_DINSU:
6236         lsb += 32;
6237         /* FALLTHRU */
6238     case OPC_DINSM:
6239         msb += 32;
6240         /* FALLTHRU */
6241     case OPC_DINS:
6242         if (lsb > msb) {
6243             goto fail;
6244         }
6245         gen_load_gpr(t0, rt);
6246         tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
6247         break;
6248 #endif
6249     default:
6250 fail:
6251         MIPS_INVAL("bitops");
6252         generate_exception_end(ctx, EXCP_RI);
6253         tcg_temp_free(t0);
6254         tcg_temp_free(t1);
6255         return;
6256     }
6257     gen_store_gpr(t0, rt);
6258     tcg_temp_free(t0);
6259     tcg_temp_free(t1);
6260 }
6261
6262 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
6263 {
6264     TCGv t0;
6265
6266     if (rd == 0) {
6267         /* If no destination, treat it as a NOP. */
6268         return;
6269     }
6270
6271     t0 = tcg_temp_new();
6272     gen_load_gpr(t0, rt);
6273     switch (op2) {
6274     case OPC_WSBH:
6275         {
6276             TCGv t1 = tcg_temp_new();
6277             TCGv t2 = tcg_const_tl(0x00FF00FF);
6278
6279             tcg_gen_shri_tl(t1, t0, 8);
6280             tcg_gen_and_tl(t1, t1, t2);
6281             tcg_gen_and_tl(t0, t0, t2);
6282             tcg_gen_shli_tl(t0, t0, 8);
6283             tcg_gen_or_tl(t0, t0, t1);
6284             tcg_temp_free(t2);
6285             tcg_temp_free(t1);
6286             tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6287         }
6288         break;
6289     case OPC_SEB:
6290         tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
6291         break;
6292     case OPC_SEH:
6293         tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
6294         break;
6295 #if defined(TARGET_MIPS64)
6296     case OPC_DSBH:
6297         {
6298             TCGv t1 = tcg_temp_new();
6299             TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
6300
6301             tcg_gen_shri_tl(t1, t0, 8);
6302             tcg_gen_and_tl(t1, t1, t2);
6303             tcg_gen_and_tl(t0, t0, t2);
6304             tcg_gen_shli_tl(t0, t0, 8);
6305             tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
6306             tcg_temp_free(t2);
6307             tcg_temp_free(t1);
6308         }
6309         break;
6310     case OPC_DSHD:
6311         {
6312             TCGv t1 = tcg_temp_new();
6313             TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
6314
6315             tcg_gen_shri_tl(t1, t0, 16);
6316             tcg_gen_and_tl(t1, t1, t2);
6317             tcg_gen_and_tl(t0, t0, t2);
6318             tcg_gen_shli_tl(t0, t0, 16);
6319             tcg_gen_or_tl(t0, t0, t1);
6320             tcg_gen_shri_tl(t1, t0, 32);
6321             tcg_gen_shli_tl(t0, t0, 32);
6322             tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
6323             tcg_temp_free(t2);
6324             tcg_temp_free(t1);
6325         }
6326         break;
6327 #endif
6328     default:
6329         MIPS_INVAL("bsfhl");
6330         generate_exception_end(ctx, EXCP_RI);
6331         tcg_temp_free(t0);
6332         return;
6333     }
6334     tcg_temp_free(t0);
6335 }
6336
6337 static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
6338                     int imm2)
6339 {
6340     TCGv t0;
6341     TCGv t1;
6342     if (rd == 0) {
6343         /* Treat as NOP. */
6344         return;
6345     }
6346     t0 = tcg_temp_new();
6347     t1 = tcg_temp_new();
6348     gen_load_gpr(t0, rs);
6349     gen_load_gpr(t1, rt);
6350     tcg_gen_shli_tl(t0, t0, imm2 + 1);
6351     tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
6352     if (opc == OPC_LSA) {
6353         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
6354     }
6355
6356     tcg_temp_free(t1);
6357     tcg_temp_free(t0);
6358
6359     return;
6360 }
6361
6362 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
6363                            int rt, int bits)
6364 {
6365     TCGv t0;
6366     if (rd == 0) {
6367         /* Treat as NOP. */
6368         return;
6369     }
6370     t0 = tcg_temp_new();
6371     if (bits == 0 || bits == wordsz) {
6372         if (bits == 0) {
6373             gen_load_gpr(t0, rt);
6374         } else {
6375             gen_load_gpr(t0, rs);
6376         }
6377         switch (wordsz) {
6378         case 32:
6379             tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6380             break;
6381 #if defined(TARGET_MIPS64)
6382         case 64:
6383             tcg_gen_mov_tl(cpu_gpr[rd], t0);
6384             break;
6385 #endif
6386         }
6387     } else {
6388         TCGv t1 = tcg_temp_new();
6389         gen_load_gpr(t0, rt);
6390         gen_load_gpr(t1, rs);
6391         switch (wordsz) {
6392         case 32:
6393             {
6394                 TCGv_i64 t2 = tcg_temp_new_i64();
6395                 tcg_gen_concat_tl_i64(t2, t1, t0);
6396                 tcg_gen_shri_i64(t2, t2, 32 - bits);
6397                 gen_move_low32(cpu_gpr[rd], t2);
6398                 tcg_temp_free_i64(t2);
6399             }
6400             break;
6401 #if defined(TARGET_MIPS64)
6402         case 64:
6403             tcg_gen_shli_tl(t0, t0, bits);
6404             tcg_gen_shri_tl(t1, t1, 64 - bits);
6405             tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
6406             break;
6407 #endif
6408         }
6409         tcg_temp_free(t1);
6410     }
6411
6412     tcg_temp_free(t0);
6413 }
6414
6415 static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6416                       int bp)
6417 {
6418     gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
6419 }
6420
6421 static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6422                     int shift)
6423 {
6424     gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift);
6425 }
6426
6427 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
6428 {
6429     TCGv t0;
6430     if (rd == 0) {
6431         /* Treat as NOP. */
6432         return;
6433     }
6434     t0 = tcg_temp_new();
6435     gen_load_gpr(t0, rt);
6436     switch (opc) {
6437     case OPC_BITSWAP:
6438         gen_helper_bitswap(cpu_gpr[rd], t0);
6439         break;
6440 #if defined(TARGET_MIPS64)
6441     case OPC_DBITSWAP:
6442         gen_helper_dbitswap(cpu_gpr[rd], t0);
6443         break;
6444 #endif
6445     }
6446     tcg_temp_free(t0);
6447 }
6448
6449 #ifndef CONFIG_USER_ONLY
6450 /* CP0 (MMU and control) */
6451 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
6452 {
6453     TCGv_i64 t0 = tcg_temp_new_i64();
6454     TCGv_i64 t1 = tcg_temp_new_i64();
6455
6456     tcg_gen_ext_tl_i64(t0, arg);
6457     tcg_gen_ld_i64(t1, cpu_env, off);
6458 #if defined(TARGET_MIPS64)
6459     tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
6460 #else
6461     tcg_gen_concat32_i64(t1, t1, t0);
6462 #endif
6463     tcg_gen_st_i64(t1, cpu_env, off);
6464     tcg_temp_free_i64(t1);
6465     tcg_temp_free_i64(t0);
6466 }
6467
6468 static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
6469 {
6470     TCGv_i64 t0 = tcg_temp_new_i64();
6471     TCGv_i64 t1 = tcg_temp_new_i64();
6472
6473     tcg_gen_ext_tl_i64(t0, arg);
6474     tcg_gen_ld_i64(t1, cpu_env, off);
6475     tcg_gen_concat32_i64(t1, t1, t0);
6476     tcg_gen_st_i64(t1, cpu_env, off);
6477     tcg_temp_free_i64(t1);
6478     tcg_temp_free_i64(t0);
6479 }
6480
6481 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
6482 {
6483     TCGv_i64 t0 = tcg_temp_new_i64();
6484
6485     tcg_gen_ld_i64(t0, cpu_env, off);
6486 #if defined(TARGET_MIPS64)
6487     tcg_gen_shri_i64(t0, t0, 30);
6488 #else
6489     tcg_gen_shri_i64(t0, t0, 32);
6490 #endif
6491     gen_move_low32(arg, t0);
6492     tcg_temp_free_i64(t0);
6493 }
6494
6495 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
6496 {
6497     TCGv_i64 t0 = tcg_temp_new_i64();
6498
6499     tcg_gen_ld_i64(t0, cpu_env, off);
6500     tcg_gen_shri_i64(t0, t0, 32 + shift);
6501     gen_move_low32(arg, t0);
6502     tcg_temp_free_i64(t0);
6503 }
6504
6505 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
6506 {
6507     TCGv_i32 t0 = tcg_temp_new_i32();
6508
6509     tcg_gen_ld_i32(t0, cpu_env, off);
6510     tcg_gen_ext_i32_tl(arg, t0);
6511     tcg_temp_free_i32(t0);
6512 }
6513
6514 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
6515 {
6516     tcg_gen_ld_tl(arg, cpu_env, off);
6517     tcg_gen_ext32s_tl(arg, arg);
6518 }
6519
6520 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
6521 {
6522     TCGv_i32 t0 = tcg_temp_new_i32();
6523
6524     tcg_gen_trunc_tl_i32(t0, arg);
6525     tcg_gen_st_i32(t0, cpu_env, off);
6526     tcg_temp_free_i32(t0);
6527 }
6528
6529 #define CP0_CHECK(c)                            \
6530     do {                                        \
6531         if (!(c)) {                             \
6532             goto cp0_unimplemented;             \
6533         }                                       \
6534     } while (0)
6535
6536 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6537 {
6538     const char *register_name = "invalid";
6539
6540     switch (reg) {
6541     case CP0_REGISTER_02:
6542         switch (sel) {
6543         case 0:
6544             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6545             gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6546             register_name = "EntryLo0";
6547             break;
6548         default:
6549             goto cp0_unimplemented;
6550         }
6551         break;
6552     case CP0_REGISTER_03:
6553         switch (sel) {
6554         case 0:
6555             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6556             gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6557             register_name = "EntryLo1";
6558             break;
6559         default:
6560             goto cp0_unimplemented;
6561         }
6562         break;
6563     case CP0_REGISTER_09:
6564         switch (sel) {
6565         case 7:
6566             CP0_CHECK(ctx->saar);
6567             gen_helper_mfhc0_saar(arg, cpu_env);
6568             register_name = "SAAR";
6569             break;
6570         default:
6571             goto cp0_unimplemented;
6572         }
6573         break;
6574     case CP0_REGISTER_17:
6575         switch (sel) {
6576         case 0:
6577             gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr),
6578                              ctx->CP0_LLAddr_shift);
6579             register_name = "LLAddr";
6580             break;
6581         case 1:
6582             CP0_CHECK(ctx->mrp);
6583             gen_helper_mfhc0_maar(arg, cpu_env);
6584             register_name = "MAAR";
6585             break;
6586         default:
6587             goto cp0_unimplemented;
6588         }
6589         break;
6590     case CP0_REGISTER_28:
6591         switch (sel) {
6592         case 0:
6593         case 2:
6594         case 4:
6595         case 6:
6596             gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
6597             register_name = "TagLo";
6598             break;
6599         default:
6600             goto cp0_unimplemented;
6601         }
6602         break;
6603     default:
6604         goto cp0_unimplemented;
6605     }
6606     trace_mips_translate_c0("mfhc0", register_name, reg, sel);
6607     return;
6608
6609 cp0_unimplemented:
6610     qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n",
6611                   register_name, reg, sel);
6612     tcg_gen_movi_tl(arg, 0);
6613 }
6614
6615 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6616 {
6617     const char *register_name = "invalid";
6618     uint64_t mask = ctx->PAMask >> 36;
6619
6620     switch (reg) {
6621     case CP0_REGISTER_02:
6622         switch (sel) {
6623         case 0:
6624             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6625             tcg_gen_andi_tl(arg, arg, mask);
6626             gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6627             register_name = "EntryLo0";
6628             break;
6629         default:
6630             goto cp0_unimplemented;
6631         }
6632         break;
6633     case CP0_REGISTER_03:
6634         switch (sel) {
6635         case 0:
6636             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6637             tcg_gen_andi_tl(arg, arg, mask);
6638             gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6639             register_name = "EntryLo1";
6640             break;
6641         default:
6642             goto cp0_unimplemented;
6643         }
6644         break;
6645     case CP0_REGISTER_09:
6646         switch (sel) {
6647         case 7:
6648             CP0_CHECK(ctx->saar);
6649             gen_helper_mthc0_saar(cpu_env, arg);
6650             register_name = "SAAR";
6651             break;
6652         default:
6653             goto cp0_unimplemented;
6654         }
6655     case CP0_REGISTER_17:
6656         switch (sel) {
6657         case 0:
6658             /* LLAddr is read-only (the only exception is bit 0 if LLB is
6659                supported); the CP0_LLAddr_rw_bitmask does not seem to be
6660                relevant for modern MIPS cores supporting MTHC0, therefore
6661                treating MTHC0 to LLAddr as NOP. */
6662             register_name = "LLAddr";
6663             break;
6664         case 1:
6665             CP0_CHECK(ctx->mrp);
6666             gen_helper_mthc0_maar(cpu_env, arg);
6667             register_name = "MAAR";
6668             break;
6669         default:
6670             goto cp0_unimplemented;
6671         }
6672         break;
6673     case CP0_REGISTER_28:
6674         switch (sel) {
6675         case 0:
6676         case 2:
6677         case 4:
6678         case 6:
6679             tcg_gen_andi_tl(arg, arg, mask);
6680             gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
6681             register_name = "TagLo";
6682             break;
6683         default:
6684             goto cp0_unimplemented;
6685         }
6686         break;
6687     default:
6688         goto cp0_unimplemented;
6689     }
6690     trace_mips_translate_c0("mthc0", register_name, reg, sel);
6691
6692 cp0_unimplemented:
6693     qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n",
6694                   register_name, reg, sel);
6695 }
6696
6697 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
6698 {
6699     if (ctx->insn_flags & ISA_MIPS32R6) {
6700         tcg_gen_movi_tl(arg, 0);
6701     } else {
6702         tcg_gen_movi_tl(arg, ~0);
6703     }
6704 }
6705
6706 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6707 {
6708     const char *register_name = "invalid";
6709
6710     if (sel != 0)
6711         check_insn(ctx, ISA_MIPS32);
6712
6713     switch (reg) {
6714     case CP0_REGISTER_00:
6715         switch (sel) {
6716         case 0:
6717             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
6718             register_name = "Index";
6719             break;
6720         case 1:
6721             CP0_CHECK(ctx->insn_flags & ASE_MT);
6722             gen_helper_mfc0_mvpcontrol(arg, cpu_env);
6723             register_name = "MVPControl";
6724             break;
6725         case 2:
6726             CP0_CHECK(ctx->insn_flags & ASE_MT);
6727             gen_helper_mfc0_mvpconf0(arg, cpu_env);
6728             register_name = "MVPConf0";
6729             break;
6730         case 3:
6731             CP0_CHECK(ctx->insn_flags & ASE_MT);
6732             gen_helper_mfc0_mvpconf1(arg, cpu_env);
6733             register_name = "MVPConf1";
6734             break;
6735         case 4:
6736             CP0_CHECK(ctx->vp);
6737             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6738             register_name = "VPControl";
6739             break;
6740         default:
6741             goto cp0_unimplemented;
6742         }
6743         break;
6744     case CP0_REGISTER_01:
6745         switch (sel) {
6746         case 0:
6747             CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6748             gen_helper_mfc0_random(arg, cpu_env);
6749             register_name = "Random";
6750             break;
6751         case 1:
6752             CP0_CHECK(ctx->insn_flags & ASE_MT);
6753             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
6754             register_name = "VPEControl";
6755             break;
6756         case 2:
6757             CP0_CHECK(ctx->insn_flags & ASE_MT);
6758             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
6759             register_name = "VPEConf0";
6760             break;
6761         case 3:
6762             CP0_CHECK(ctx->insn_flags & ASE_MT);
6763             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
6764             register_name = "VPEConf1";
6765             break;
6766         case 4:
6767             CP0_CHECK(ctx->insn_flags & ASE_MT);
6768             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
6769             register_name = "YQMask";
6770             break;
6771         case 5:
6772             CP0_CHECK(ctx->insn_flags & ASE_MT);
6773             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
6774             register_name = "VPESchedule";
6775             break;
6776         case 6:
6777             CP0_CHECK(ctx->insn_flags & ASE_MT);
6778             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6779             register_name = "VPEScheFBack";
6780             break;
6781         case 7:
6782             CP0_CHECK(ctx->insn_flags & ASE_MT);
6783             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
6784             register_name = "VPEOpt";
6785             break;
6786         default:
6787             goto cp0_unimplemented;
6788         }
6789         break;
6790     case CP0_REGISTER_02:
6791         switch (sel) {
6792         case 0:
6793             {
6794                 TCGv_i64 tmp = tcg_temp_new_i64();
6795                 tcg_gen_ld_i64(tmp, cpu_env,
6796                                offsetof(CPUMIPSState, CP0_EntryLo0));
6797 #if defined(TARGET_MIPS64)
6798                 if (ctx->rxi) {
6799                     /* Move RI/XI fields to bits 31:30 */
6800                     tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6801                     tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6802                 }
6803 #endif
6804                 gen_move_low32(arg, tmp);
6805                 tcg_temp_free_i64(tmp);
6806             }
6807             register_name = "EntryLo0";
6808             break;
6809         case 1:
6810             CP0_CHECK(ctx->insn_flags & ASE_MT);
6811             gen_helper_mfc0_tcstatus(arg, cpu_env);
6812             register_name = "TCStatus";
6813             break;
6814         case 2:
6815             CP0_CHECK(ctx->insn_flags & ASE_MT);
6816             gen_helper_mfc0_tcbind(arg, cpu_env);
6817             register_name = "TCBind";
6818             break;
6819         case 3:
6820             CP0_CHECK(ctx->insn_flags & ASE_MT);
6821             gen_helper_mfc0_tcrestart(arg, cpu_env);
6822             register_name = "TCRestart";
6823             break;
6824         case 4:
6825             CP0_CHECK(ctx->insn_flags & ASE_MT);
6826             gen_helper_mfc0_tchalt(arg, cpu_env);
6827             register_name = "TCHalt";
6828             break;
6829         case 5:
6830             CP0_CHECK(ctx->insn_flags & ASE_MT);
6831             gen_helper_mfc0_tccontext(arg, cpu_env);
6832             register_name = "TCContext";
6833             break;
6834         case 6:
6835             CP0_CHECK(ctx->insn_flags & ASE_MT);
6836             gen_helper_mfc0_tcschedule(arg, cpu_env);
6837             register_name = "TCSchedule";
6838             break;
6839         case 7:
6840             CP0_CHECK(ctx->insn_flags & ASE_MT);
6841             gen_helper_mfc0_tcschefback(arg, cpu_env);
6842             register_name = "TCScheFBack";
6843             break;
6844         default:
6845             goto cp0_unimplemented;
6846         }
6847         break;
6848     case CP0_REGISTER_03:
6849         switch (sel) {
6850         case 0:
6851             {
6852                 TCGv_i64 tmp = tcg_temp_new_i64();
6853                 tcg_gen_ld_i64(tmp, cpu_env,
6854                                offsetof(CPUMIPSState, CP0_EntryLo1));
6855 #if defined(TARGET_MIPS64)
6856                 if (ctx->rxi) {
6857                     /* Move RI/XI fields to bits 31:30 */
6858                     tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6859                     tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6860                 }
6861 #endif
6862                 gen_move_low32(arg, tmp);
6863                 tcg_temp_free_i64(tmp);
6864             }
6865             register_name = "EntryLo1";
6866             break;
6867         case 1:
6868             CP0_CHECK(ctx->vp);
6869             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6870             register_name = "GlobalNumber";
6871             break;
6872         default:
6873             goto cp0_unimplemented;
6874         }
6875         break;
6876     case CP0_REGISTER_04:
6877         switch (sel) {
6878         case 0:
6879             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
6880             tcg_gen_ext32s_tl(arg, arg);
6881             register_name = "Context";
6882             break;
6883         case 1:
6884 //            gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
6885             register_name = "ContextConfig";
6886             goto cp0_unimplemented;
6887         case 2:
6888             CP0_CHECK(ctx->ulri);
6889             tcg_gen_ld_tl(arg, cpu_env,
6890                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6891             tcg_gen_ext32s_tl(arg, arg);
6892             register_name = "UserLocal";
6893             break;
6894         default:
6895             goto cp0_unimplemented;
6896         }
6897         break;
6898     case CP0_REGISTER_05:
6899         switch (sel) {
6900         case 0:
6901             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
6902             register_name = "PageMask";
6903             break;
6904         case 1:
6905             check_insn(ctx, ISA_MIPS32R2);
6906             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
6907             register_name = "PageGrain";
6908             break;
6909         case 2:
6910             CP0_CHECK(ctx->sc);
6911             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
6912             tcg_gen_ext32s_tl(arg, arg);
6913             register_name = "SegCtl0";
6914             break;
6915         case 3:
6916             CP0_CHECK(ctx->sc);
6917             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
6918             tcg_gen_ext32s_tl(arg, arg);
6919             register_name = "SegCtl1";
6920             break;
6921         case 4:
6922             CP0_CHECK(ctx->sc);
6923             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
6924             tcg_gen_ext32s_tl(arg, arg);
6925             register_name = "SegCtl2";
6926             break;
6927         case 5:
6928             check_pw(ctx);
6929             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6930             register_name = "PWBase";
6931             break;
6932         case 6:
6933             check_pw(ctx);
6934             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
6935             register_name = "PWField";
6936             break;
6937         case 7:
6938             check_pw(ctx);
6939             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
6940             register_name = "PWSize";
6941             break;
6942         default:
6943             goto cp0_unimplemented;
6944         }
6945         break;
6946     case CP0_REGISTER_06:
6947         switch (sel) {
6948         case 0:
6949             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
6950             register_name = "Wired";
6951             break;
6952         case 1:
6953             check_insn(ctx, ISA_MIPS32R2);
6954             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
6955             register_name = "SRSConf0";
6956             break;
6957         case 2:
6958             check_insn(ctx, ISA_MIPS32R2);
6959             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
6960             register_name = "SRSConf1";
6961             break;
6962         case 3:
6963             check_insn(ctx, ISA_MIPS32R2);
6964             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
6965             register_name = "SRSConf2";
6966             break;
6967         case 4:
6968             check_insn(ctx, ISA_MIPS32R2);
6969             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
6970             register_name = "SRSConf3";
6971             break;
6972         case 5:
6973             check_insn(ctx, ISA_MIPS32R2);
6974             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
6975             register_name = "SRSConf4";
6976             break;
6977         case 6:
6978             check_pw(ctx);
6979             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
6980             register_name = "PWCtl";
6981             break;
6982         default:
6983             goto cp0_unimplemented;
6984         }
6985         break;
6986     case CP0_REGISTER_07:
6987         switch (sel) {
6988         case 0:
6989             check_insn(ctx, ISA_MIPS32R2);
6990             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
6991             register_name = "HWREna";
6992             break;
6993         default:
6994             goto cp0_unimplemented;
6995         }
6996         break;
6997     case CP0_REGISTER_08:
6998         switch (sel) {
6999         case 0:
7000             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
7001             tcg_gen_ext32s_tl(arg, arg);
7002             register_name = "BadVAddr";
7003             break;
7004         case 1:
7005             CP0_CHECK(ctx->bi);
7006             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
7007             register_name = "BadInstr";
7008             break;
7009         case 2:
7010             CP0_CHECK(ctx->bp);
7011             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
7012             register_name = "BadInstrP";
7013             break;
7014         case 3:
7015             CP0_CHECK(ctx->bi);
7016             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
7017             tcg_gen_andi_tl(arg, arg, ~0xffff);
7018             register_name = "BadInstrX";
7019             break;
7020        default:
7021             goto cp0_unimplemented;
7022         }
7023         break;
7024     case CP0_REGISTER_09:
7025         switch (sel) {
7026         case 0:
7027             /* Mark as an IO operation because we read the time.  */
7028             if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7029                 gen_io_start();
7030             }
7031             gen_helper_mfc0_count(arg, cpu_env);
7032             if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7033                 gen_io_end();
7034             }
7035             /* Break the TB to be able to take timer interrupts immediately
7036                after reading count. DISAS_STOP isn't sufficient, we need to
7037                ensure we break completely out of translated code.  */
7038             gen_save_pc(ctx->base.pc_next + 4);
7039             ctx->base.is_jmp = DISAS_EXIT;
7040             register_name = "Count";
7041             break;
7042         case 6:
7043             CP0_CHECK(ctx->saar);
7044             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
7045             register_name = "SAARI";
7046             break;
7047         case 7:
7048             CP0_CHECK(ctx->saar);
7049             gen_helper_mfc0_saar(arg, cpu_env);
7050             register_name = "SAAR";
7051             break;
7052         default:
7053             goto cp0_unimplemented;
7054         }
7055         break;
7056     case CP0_REGISTER_10:
7057         switch (sel) {
7058         case 0:
7059             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
7060             tcg_gen_ext32s_tl(arg, arg);
7061             register_name = "EntryHi";
7062             break;
7063         default:
7064             goto cp0_unimplemented;
7065         }
7066         break;
7067     case CP0_REGISTER_11:
7068         switch (sel) {
7069         case 0:
7070             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
7071             register_name = "Compare";
7072             break;
7073         /* 6,7 are implementation dependent */
7074         default:
7075             goto cp0_unimplemented;
7076         }
7077         break;
7078     case CP0_REGISTER_12:
7079         switch (sel) {
7080         case 0:
7081             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
7082             register_name = "Status";
7083             break;
7084         case 1:
7085             check_insn(ctx, ISA_MIPS32R2);
7086             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
7087             register_name = "IntCtl";
7088             break;
7089         case 2:
7090             check_insn(ctx, ISA_MIPS32R2);
7091             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
7092             register_name = "SRSCtl";
7093             break;
7094         case 3:
7095             check_insn(ctx, ISA_MIPS32R2);
7096             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7097             register_name = "SRSMap";
7098             break;
7099         default:
7100             goto cp0_unimplemented;
7101        }
7102         break;
7103     case CP0_REGISTER_13:
7104         switch (sel) {
7105         case 0:
7106             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
7107             register_name = "Cause";
7108             break;
7109         default:
7110             goto cp0_unimplemented;
7111        }
7112         break;
7113     case CP0_REGISTER_14:
7114         switch (sel) {
7115         case 0:
7116             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7117             tcg_gen_ext32s_tl(arg, arg);
7118             register_name = "EPC";
7119             break;
7120         default:
7121             goto cp0_unimplemented;
7122         }
7123         break;
7124     case CP0_REGISTER_15:
7125         switch (sel) {
7126         case 0:
7127             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
7128             register_name = "PRid";
7129             break;
7130         case 1:
7131             check_insn(ctx, ISA_MIPS32R2);
7132             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
7133             tcg_gen_ext32s_tl(arg, arg);
7134             register_name = "EBase";
7135             break;
7136         case 3:
7137             check_insn(ctx, ISA_MIPS32R2);
7138             CP0_CHECK(ctx->cmgcr);
7139             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7140             tcg_gen_ext32s_tl(arg, arg);
7141             register_name = "CMGCRBase";
7142             break;
7143         default:
7144             goto cp0_unimplemented;
7145        }
7146         break;
7147     case CP0_REGISTER_16:
7148         switch (sel) {
7149         case 0:
7150             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
7151             register_name = "Config";
7152             break;
7153         case 1:
7154             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
7155             register_name = "Config1";
7156             break;
7157         case 2:
7158             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7159             register_name = "Config2";
7160             break;
7161         case 3:
7162             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7163             register_name = "Config3";
7164             break;
7165         case 4:
7166             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7167             register_name = "Config4";
7168             break;
7169         case 5:
7170             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7171             register_name = "Config5";
7172             break;
7173         /* 6,7 are implementation dependent */
7174         case 6:
7175             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
7176             register_name = "Config6";
7177             break;
7178         case 7:
7179             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
7180             register_name = "Config7";
7181             break;
7182         default:
7183             goto cp0_unimplemented;
7184         }
7185         break;
7186     case CP0_REGISTER_17:
7187         switch (sel) {
7188         case 0:
7189             gen_helper_mfc0_lladdr(arg, cpu_env);
7190             register_name = "LLAddr";
7191             break;
7192         case 1:
7193             CP0_CHECK(ctx->mrp);
7194             gen_helper_mfc0_maar(arg, cpu_env);
7195             register_name = "MAAR";
7196             break;
7197         case 2:
7198             CP0_CHECK(ctx->mrp);
7199             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7200             register_name = "MAARI";
7201             break;
7202         default:
7203             goto cp0_unimplemented;
7204         }
7205         break;
7206     case CP0_REGISTER_18:
7207         switch (sel) {
7208         case 0:
7209         case 1:
7210         case 2:
7211         case 3:
7212         case 4:
7213         case 5:
7214         case 6:
7215         case 7:
7216             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7217             gen_helper_1e0i(mfc0_watchlo, arg, sel);
7218             register_name = "WatchLo";
7219             break;
7220         default:
7221             goto cp0_unimplemented;
7222         }
7223         break;
7224     case CP0_REGISTER_19:
7225         switch (sel) {
7226         case 0:
7227         case 1:
7228         case 2:
7229         case 3:
7230         case 4:
7231         case 5:
7232         case 6:
7233         case 7:
7234             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7235             gen_helper_1e0i(mfc0_watchhi, arg, sel);
7236             register_name = "WatchHi";
7237             break;
7238         default:
7239             goto cp0_unimplemented;
7240         }
7241         break;
7242     case CP0_REGISTER_20:
7243         switch (sel) {
7244         case 0:
7245 #if defined(TARGET_MIPS64)
7246             check_insn(ctx, ISA_MIPS3);
7247             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
7248             tcg_gen_ext32s_tl(arg, arg);
7249             register_name = "XContext";
7250             break;
7251 #endif
7252         default:
7253             goto cp0_unimplemented;
7254         }
7255         break;
7256     case CP0_REGISTER_21:
7257        /* Officially reserved, but sel 0 is used for R1x000 framemask */
7258         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7259         switch (sel) {
7260         case 0:
7261             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
7262             register_name = "Framemask";
7263             break;
7264         default:
7265             goto cp0_unimplemented;
7266         }
7267         break;
7268     case CP0_REGISTER_22:
7269         tcg_gen_movi_tl(arg, 0); /* unimplemented */
7270         register_name = "'Diagnostic"; /* implementation dependent */
7271         break;
7272     case CP0_REGISTER_23:
7273         switch (sel) {
7274         case 0:
7275             gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
7276             register_name = "Debug";
7277             break;
7278         case 1:
7279 //            gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
7280             register_name = "TraceControl";
7281             goto cp0_unimplemented;
7282         case 2:
7283 //            gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
7284             register_name = "TraceControl2";
7285             goto cp0_unimplemented;
7286         case 3:
7287 //            gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
7288             register_name = "UserTraceData";
7289             goto cp0_unimplemented;
7290         case 4:
7291 //            gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
7292             register_name = "TraceBPC";
7293             goto cp0_unimplemented;
7294         default:
7295             goto cp0_unimplemented;
7296         }
7297         break;
7298     case CP0_REGISTER_24:
7299         switch (sel) {
7300         case 0:
7301             /* EJTAG support */
7302             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7303             tcg_gen_ext32s_tl(arg, arg);
7304             register_name = "DEPC";
7305             break;
7306         default:
7307             goto cp0_unimplemented;
7308         }
7309         break;
7310     case CP0_REGISTER_25:
7311         switch (sel) {
7312         case 0:
7313             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
7314             register_name = "Performance0";
7315             break;
7316         case 1:
7317 //            gen_helper_mfc0_performance1(arg);
7318             register_name = "Performance1";
7319             goto cp0_unimplemented;
7320         case 2:
7321 //            gen_helper_mfc0_performance2(arg);
7322             register_name = "Performance2";
7323             goto cp0_unimplemented;
7324         case 3:
7325 //            gen_helper_mfc0_performance3(arg);
7326             register_name = "Performance3";
7327             goto cp0_unimplemented;
7328         case 4:
7329 //            gen_helper_mfc0_performance4(arg);
7330             register_name = "Performance4";
7331             goto cp0_unimplemented;
7332         case 5:
7333 //            gen_helper_mfc0_performance5(arg);
7334             register_name = "Performance5";
7335             goto cp0_unimplemented;
7336         case 6:
7337 //            gen_helper_mfc0_performance6(arg);
7338             register_name = "Performance6";
7339             goto cp0_unimplemented;
7340         case 7:
7341 //            gen_helper_mfc0_performance7(arg);
7342             register_name = "Performance7";
7343             goto cp0_unimplemented;
7344         default:
7345             goto cp0_unimplemented;
7346         }
7347         break;
7348     case CP0_REGISTER_26:
7349         switch (sel) {
7350         case 0:
7351             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7352             register_name = "ErrCtl";
7353             break;
7354         default:
7355             goto cp0_unimplemented;
7356         }
7357         break;
7358     case CP0_REGISTER_27:
7359         switch (sel) {
7360         case 0:
7361         case 1:
7362         case 2:
7363         case 3:
7364             tcg_gen_movi_tl(arg, 0); /* unimplemented */
7365             register_name = "CacheErr";
7366             break;
7367         default:
7368             goto cp0_unimplemented;
7369         }
7370         break;
7371     case CP0_REGISTER_28:
7372         switch (sel) {
7373         case 0:
7374         case 2:
7375         case 4:
7376         case 6:
7377             {
7378                 TCGv_i64 tmp = tcg_temp_new_i64();
7379                 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
7380                 gen_move_low32(arg, tmp);
7381                 tcg_temp_free_i64(tmp);
7382             }
7383             register_name = "TagLo";
7384             break;
7385         case 1:
7386         case 3:
7387         case 5:
7388         case 7:
7389             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
7390             register_name = "DataLo";
7391             break;
7392         default:
7393             goto cp0_unimplemented;
7394         }
7395         break;
7396     case CP0_REGISTER_29:
7397         switch (sel) {
7398         case 0:
7399         case 2:
7400         case 4:
7401         case 6:
7402             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7403             register_name = "TagHi";
7404             break;
7405         case 1:
7406         case 3:
7407         case 5:
7408         case 7:
7409             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7410             register_name = "DataHi";
7411             break;
7412         default:
7413             goto cp0_unimplemented;
7414         }
7415         break;
7416     case CP0_REGISTER_30:
7417         switch (sel) {
7418         case 0:
7419             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7420             tcg_gen_ext32s_tl(arg, arg);
7421             register_name = "ErrorEPC";
7422             break;
7423         default:
7424             goto cp0_unimplemented;
7425         }
7426         break;
7427     case CP0_REGISTER_31:
7428         switch (sel) {
7429         case 0:
7430             /* EJTAG support */
7431             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7432             register_name = "DESAVE";
7433             break;
7434         case 2:
7435         case 3:
7436         case 4:
7437         case 5:
7438         case 6:
7439         case 7:
7440             CP0_CHECK(ctx->kscrexist & (1 << sel));
7441             tcg_gen_ld_tl(arg, cpu_env,
7442                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7443             tcg_gen_ext32s_tl(arg, arg);
7444             register_name = "KScratch";
7445             break;
7446         default:
7447             goto cp0_unimplemented;
7448         }
7449         break;
7450     default:
7451        goto cp0_unimplemented;
7452     }
7453     trace_mips_translate_c0("mfc0", register_name, reg, sel);
7454     return;
7455
7456 cp0_unimplemented:
7457     qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n",
7458                   register_name, reg, sel);
7459     gen_mfc0_unimplemented(ctx, arg);
7460 }
7461
7462 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7463 {
7464     const char *register_name = "invalid";
7465
7466     if (sel != 0)
7467         check_insn(ctx, ISA_MIPS32);
7468
7469     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7470         gen_io_start();
7471     }
7472
7473     switch (reg) {
7474     case CP0_REGISTER_00:
7475         switch (sel) {
7476         case 0:
7477             gen_helper_mtc0_index(cpu_env, arg);
7478             register_name = "Index";
7479             break;
7480         case 1:
7481             CP0_CHECK(ctx->insn_flags & ASE_MT);
7482             gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7483             register_name = "MVPControl";
7484             break;
7485         case 2:
7486             CP0_CHECK(ctx->insn_flags & ASE_MT);
7487             /* ignored */
7488             register_name = "MVPConf0";
7489             break;
7490         case 3:
7491             CP0_CHECK(ctx->insn_flags & ASE_MT);
7492             /* ignored */
7493             register_name = "MVPConf1";
7494             break;
7495         case 4:
7496             CP0_CHECK(ctx->vp);
7497             /* ignored */
7498             register_name = "VPControl";
7499             break;
7500         default:
7501             goto cp0_unimplemented;
7502         }
7503         break;
7504     case CP0_REGISTER_01:
7505         switch (sel) {
7506         case 0:
7507             /* ignored */
7508             register_name = "Random";
7509             break;
7510         case 1:
7511             CP0_CHECK(ctx->insn_flags & ASE_MT);
7512             gen_helper_mtc0_vpecontrol(cpu_env, arg);
7513             register_name = "VPEControl";
7514             break;
7515         case 2:
7516             CP0_CHECK(ctx->insn_flags & ASE_MT);
7517             gen_helper_mtc0_vpeconf0(cpu_env, arg);
7518             register_name = "VPEConf0";
7519             break;
7520         case 3:
7521             CP0_CHECK(ctx->insn_flags & ASE_MT);
7522             gen_helper_mtc0_vpeconf1(cpu_env, arg);
7523             register_name = "VPEConf1";
7524             break;
7525         case 4:
7526             CP0_CHECK(ctx->insn_flags & ASE_MT);
7527             gen_helper_mtc0_yqmask(cpu_env, arg);
7528             register_name = "YQMask";
7529             break;
7530         case 5:
7531             CP0_CHECK(ctx->insn_flags & ASE_MT);
7532             tcg_gen_st_tl(arg, cpu_env,
7533                           offsetof(CPUMIPSState, CP0_VPESchedule));
7534             register_name = "VPESchedule";
7535             break;
7536         case 6:
7537             CP0_CHECK(ctx->insn_flags & ASE_MT);
7538             tcg_gen_st_tl(arg, cpu_env,
7539                           offsetof(CPUMIPSState, CP0_VPEScheFBack));
7540             register_name = "VPEScheFBack";
7541             break;
7542         case 7:
7543             CP0_CHECK(ctx->insn_flags & ASE_MT);
7544             gen_helper_mtc0_vpeopt(cpu_env, arg);
7545             register_name = "VPEOpt";
7546             break;
7547         default:
7548             goto cp0_unimplemented;
7549         }
7550         break;
7551     case CP0_REGISTER_02:
7552         switch (sel) {
7553         case 0:
7554             gen_helper_mtc0_entrylo0(cpu_env, arg);
7555             register_name = "EntryLo0";
7556             break;
7557         case 1:
7558             CP0_CHECK(ctx->insn_flags & ASE_MT);
7559             gen_helper_mtc0_tcstatus(cpu_env, arg);
7560             register_name = "TCStatus";
7561             break;
7562         case 2:
7563             CP0_CHECK(ctx->insn_flags & ASE_MT);
7564             gen_helper_mtc0_tcbind(cpu_env, arg);
7565             register_name = "TCBind";
7566             break;
7567         case 3:
7568             CP0_CHECK(ctx->insn_flags & ASE_MT);
7569             gen_helper_mtc0_tcrestart(cpu_env, arg);
7570             register_name = "TCRestart";
7571             break;
7572         case 4:
7573             CP0_CHECK(ctx->insn_flags & ASE_MT);
7574             gen_helper_mtc0_tchalt(cpu_env, arg);
7575             register_name = "TCHalt";
7576             break;
7577         case 5:
7578             CP0_CHECK(ctx->insn_flags & ASE_MT);
7579             gen_helper_mtc0_tccontext(cpu_env, arg);
7580             register_name = "TCContext";
7581             break;
7582         case 6:
7583             CP0_CHECK(ctx->insn_flags & ASE_MT);
7584             gen_helper_mtc0_tcschedule(cpu_env, arg);
7585             register_name = "TCSchedule";
7586             break;
7587         case 7:
7588             CP0_CHECK(ctx->insn_flags & ASE_MT);
7589             gen_helper_mtc0_tcschefback(cpu_env, arg);
7590             register_name = "TCScheFBack";
7591             break;
7592         default:
7593             goto cp0_unimplemented;
7594         }
7595         break;
7596     case CP0_REGISTER_03:
7597         switch (sel) {
7598         case 0:
7599             gen_helper_mtc0_entrylo1(cpu_env, arg);
7600             register_name = "EntryLo1";
7601             break;
7602         case 1:
7603             CP0_CHECK(ctx->vp);
7604             /* ignored */
7605             register_name = "GlobalNumber";
7606             break;
7607         default:
7608             goto cp0_unimplemented;
7609         }
7610         break;
7611     case CP0_REGISTER_04:
7612         switch (sel) {
7613         case 0:
7614             gen_helper_mtc0_context(cpu_env, arg);
7615             register_name = "Context";
7616             break;
7617         case 1:
7618 //            gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
7619             register_name = "ContextConfig";
7620             goto cp0_unimplemented;
7621         case 2:
7622             CP0_CHECK(ctx->ulri);
7623             tcg_gen_st_tl(arg, cpu_env,
7624                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7625             register_name = "UserLocal";
7626             break;
7627         default:
7628             goto cp0_unimplemented;
7629         }
7630         break;
7631     case CP0_REGISTER_05:
7632         switch (sel) {
7633         case 0:
7634             gen_helper_mtc0_pagemask(cpu_env, arg);
7635             register_name = "PageMask";
7636             break;
7637         case 1:
7638             check_insn(ctx, ISA_MIPS32R2);
7639             gen_helper_mtc0_pagegrain(cpu_env, arg);
7640             register_name = "PageGrain";
7641             ctx->base.is_jmp = DISAS_STOP;
7642             break;
7643         case 2:
7644             CP0_CHECK(ctx->sc);
7645             gen_helper_mtc0_segctl0(cpu_env, arg);
7646             register_name = "SegCtl0";
7647             break;
7648         case 3:
7649             CP0_CHECK(ctx->sc);
7650             gen_helper_mtc0_segctl1(cpu_env, arg);
7651             register_name = "SegCtl1";
7652             break;
7653         case 4:
7654             CP0_CHECK(ctx->sc);
7655             gen_helper_mtc0_segctl2(cpu_env, arg);
7656             register_name = "SegCtl2";
7657             break;
7658         case 5:
7659             check_pw(ctx);
7660             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
7661             register_name = "PWBase";
7662             break;
7663         case 6:
7664             check_pw(ctx);
7665             gen_helper_mtc0_pwfield(cpu_env, arg);
7666             register_name = "PWField";
7667             break;
7668         case 7:
7669             check_pw(ctx);
7670             gen_helper_mtc0_pwsize(cpu_env, arg);
7671             register_name = "PWSize";
7672             break;
7673         default:
7674             goto cp0_unimplemented;
7675         }
7676         break;
7677     case CP0_REGISTER_06:
7678         switch (sel) {
7679         case 0:
7680             gen_helper_mtc0_wired(cpu_env, arg);
7681             register_name = "Wired";
7682             break;
7683         case 1:
7684             check_insn(ctx, ISA_MIPS32R2);
7685             gen_helper_mtc0_srsconf0(cpu_env, arg);
7686             register_name = "SRSConf0";
7687             break;
7688         case 2:
7689             check_insn(ctx, ISA_MIPS32R2);
7690             gen_helper_mtc0_srsconf1(cpu_env, arg);
7691             register_name = "SRSConf1";
7692             break;
7693         case 3:
7694             check_insn(ctx, ISA_MIPS32R2);
7695             gen_helper_mtc0_srsconf2(cpu_env, arg);
7696             register_name = "SRSConf2";
7697             break;
7698         case 4:
7699             check_insn(ctx, ISA_MIPS32R2);
7700             gen_helper_mtc0_srsconf3(cpu_env, arg);
7701             register_name = "SRSConf3";
7702             break;
7703         case 5:
7704             check_insn(ctx, ISA_MIPS32R2);
7705             gen_helper_mtc0_srsconf4(cpu_env, arg);
7706             register_name = "SRSConf4";
7707             break;
7708         case 6:
7709             check_pw(ctx);
7710             gen_helper_mtc0_pwctl(cpu_env, arg);
7711             register_name = "PWCtl";
7712             break;
7713         default:
7714             goto cp0_unimplemented;
7715         }
7716         break;
7717     case CP0_REGISTER_07:
7718         switch (sel) {
7719         case 0:
7720             check_insn(ctx, ISA_MIPS32R2);
7721             gen_helper_mtc0_hwrena(cpu_env, arg);
7722             ctx->base.is_jmp = DISAS_STOP;
7723             register_name = "HWREna";
7724             break;
7725         default:
7726             goto cp0_unimplemented;
7727         }
7728         break;
7729     case CP0_REGISTER_08:
7730         switch (sel) {
7731         case 0:
7732             /* ignored */
7733             register_name = "BadVAddr";
7734             break;
7735         case 1:
7736             /* ignored */
7737             register_name = "BadInstr";
7738             break;
7739         case 2:
7740             /* ignored */
7741             register_name = "BadInstrP";
7742             break;
7743         case 3:
7744             /* ignored */
7745             register_name = "BadInstrX";
7746             break;
7747         default:
7748             goto cp0_unimplemented;
7749         }
7750         break;
7751     case CP0_REGISTER_09:
7752         switch (sel) {
7753         case 0:
7754             gen_helper_mtc0_count(cpu_env, arg);
7755             register_name = "Count";
7756             break;
7757         case 6:
7758             CP0_CHECK(ctx->saar);
7759             gen_helper_mtc0_saari(cpu_env, arg);
7760             register_name = "SAARI";
7761             break;
7762         case 7:
7763             CP0_CHECK(ctx->saar);
7764             gen_helper_mtc0_saar(cpu_env, arg);
7765             register_name = "SAAR";
7766             break;
7767         default:
7768             goto cp0_unimplemented;
7769         }
7770         break;
7771     case CP0_REGISTER_10:
7772         switch (sel) {
7773         case 0:
7774             gen_helper_mtc0_entryhi(cpu_env, arg);
7775             register_name = "EntryHi";
7776             break;
7777         default:
7778             goto cp0_unimplemented;
7779         }
7780         break;
7781     case CP0_REGISTER_11:
7782         switch (sel) {
7783         case 0:
7784             gen_helper_mtc0_compare(cpu_env, arg);
7785             register_name = "Compare";
7786             break;
7787         /* 6,7 are implementation dependent */
7788         default:
7789             goto cp0_unimplemented;
7790         }
7791         break;
7792     case CP0_REGISTER_12:
7793         switch (sel) {
7794         case 0:
7795             save_cpu_state(ctx, 1);
7796             gen_helper_mtc0_status(cpu_env, arg);
7797             /* DISAS_STOP isn't good enough here, hflags may have changed. */
7798             gen_save_pc(ctx->base.pc_next + 4);
7799             ctx->base.is_jmp = DISAS_EXIT;
7800             register_name = "Status";
7801             break;
7802         case 1:
7803             check_insn(ctx, ISA_MIPS32R2);
7804             gen_helper_mtc0_intctl(cpu_env, arg);
7805             /* Stop translation as we may have switched the execution mode */
7806             ctx->base.is_jmp = DISAS_STOP;
7807             register_name = "IntCtl";
7808             break;
7809         case 2:
7810             check_insn(ctx, ISA_MIPS32R2);
7811             gen_helper_mtc0_srsctl(cpu_env, arg);
7812             /* Stop translation as we may have switched the execution mode */
7813             ctx->base.is_jmp = DISAS_STOP;
7814             register_name = "SRSCtl";
7815             break;
7816         case 3:
7817             check_insn(ctx, ISA_MIPS32R2);
7818             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7819             /* Stop translation as we may have switched the execution mode */
7820             ctx->base.is_jmp = DISAS_STOP;
7821             register_name = "SRSMap";
7822             break;
7823         default:
7824             goto cp0_unimplemented;
7825         }
7826         break;
7827     case CP0_REGISTER_13:
7828         switch (sel) {
7829         case 0:
7830             save_cpu_state(ctx, 1);
7831             gen_helper_mtc0_cause(cpu_env, arg);
7832             /* Stop translation as we may have triggered an interrupt.
7833              * DISAS_STOP isn't sufficient, we need to ensure we break out of
7834              * translated code to check for pending interrupts.  */
7835             gen_save_pc(ctx->base.pc_next + 4);
7836             ctx->base.is_jmp = DISAS_EXIT;
7837             register_name = "Cause";
7838             break;
7839         default:
7840             goto cp0_unimplemented;
7841         }
7842         break;
7843     case CP0_REGISTER_14:
7844         switch (sel) {
7845         case 0:
7846             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7847             register_name = "EPC";
7848             break;
7849         default:
7850             goto cp0_unimplemented;
7851         }
7852         break;
7853     case CP0_REGISTER_15:
7854         switch (sel) {
7855         case 0:
7856             /* ignored */
7857             register_name = "PRid";
7858             break;
7859         case 1:
7860             check_insn(ctx, ISA_MIPS32R2);
7861             gen_helper_mtc0_ebase(cpu_env, arg);
7862             register_name = "EBase";
7863             break;
7864         default:
7865             goto cp0_unimplemented;
7866         }
7867         break;
7868     case CP0_REGISTER_16:
7869         switch (sel) {
7870         case 0:
7871             gen_helper_mtc0_config0(cpu_env, arg);
7872             register_name = "Config";
7873             /* Stop translation as we may have switched the execution mode */
7874             ctx->base.is_jmp = DISAS_STOP;
7875             break;
7876         case 1:
7877             /* ignored, read only */
7878             register_name = "Config1";
7879             break;
7880         case 2:
7881             gen_helper_mtc0_config2(cpu_env, arg);
7882             register_name = "Config2";
7883             /* Stop translation as we may have switched the execution mode */
7884             ctx->base.is_jmp = DISAS_STOP;
7885             break;
7886         case 3:
7887             gen_helper_mtc0_config3(cpu_env, arg);
7888             register_name = "Config3";
7889             /* Stop translation as we may have switched the execution mode */
7890             ctx->base.is_jmp = DISAS_STOP;
7891             break;
7892         case 4:
7893             gen_helper_mtc0_config4(cpu_env, arg);
7894             register_name = "Config4";
7895             ctx->base.is_jmp = DISAS_STOP;
7896             break;
7897         case 5:
7898             gen_helper_mtc0_config5(cpu_env, arg);
7899             register_name = "Config5";
7900             /* Stop translation as we may have switched the execution mode */
7901             ctx->base.is_jmp = DISAS_STOP;
7902             break;
7903         /* 6,7 are implementation dependent */
7904         case 6:
7905             /* ignored */
7906             register_name = "Config6";
7907             break;
7908         case 7:
7909             /* ignored */
7910             register_name = "Config7";
7911             break;
7912         default:
7913             register_name = "Invalid config selector";
7914             goto cp0_unimplemented;
7915         }
7916         break;
7917     case CP0_REGISTER_17:
7918         switch (sel) {
7919         case 0:
7920             gen_helper_mtc0_lladdr(cpu_env, arg);
7921             register_name = "LLAddr";
7922             break;
7923         case 1:
7924             CP0_CHECK(ctx->mrp);
7925             gen_helper_mtc0_maar(cpu_env, arg);
7926             register_name = "MAAR";
7927             break;
7928         case 2:
7929             CP0_CHECK(ctx->mrp);
7930             gen_helper_mtc0_maari(cpu_env, arg);
7931             register_name = "MAARI";
7932             break;
7933         default:
7934             goto cp0_unimplemented;
7935         }
7936         break;
7937     case CP0_REGISTER_18:
7938         switch (sel) {
7939         case 0:
7940         case 1:
7941         case 2:
7942         case 3:
7943         case 4:
7944         case 5:
7945         case 6:
7946         case 7:
7947             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7948             gen_helper_0e1i(mtc0_watchlo, arg, sel);
7949             register_name = "WatchLo";
7950             break;
7951         default:
7952             goto cp0_unimplemented;
7953         }
7954         break;
7955     case CP0_REGISTER_19:
7956         switch (sel) {
7957         case 0:
7958         case 1:
7959         case 2:
7960         case 3:
7961         case 4:
7962         case 5:
7963         case 6:
7964         case 7:
7965             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7966             gen_helper_0e1i(mtc0_watchhi, arg, sel);
7967             register_name = "WatchHi";
7968             break;
7969         default:
7970             goto cp0_unimplemented;
7971         }
7972         break;
7973     case CP0_REGISTER_20:
7974         switch (sel) {
7975         case 0:
7976 #if defined(TARGET_MIPS64)
7977             check_insn(ctx, ISA_MIPS3);
7978             gen_helper_mtc0_xcontext(cpu_env, arg);
7979             register_name = "XContext";
7980             break;
7981 #endif
7982         default:
7983             goto cp0_unimplemented;
7984         }
7985         break;
7986     case CP0_REGISTER_21:
7987        /* Officially reserved, but sel 0 is used for R1x000 framemask */
7988         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7989         switch (sel) {
7990         case 0:
7991             gen_helper_mtc0_framemask(cpu_env, arg);
7992             register_name = "Framemask";
7993             break;
7994         default:
7995             goto cp0_unimplemented;
7996         }
7997         break;
7998     case CP0_REGISTER_22:
7999         /* ignored */
8000         register_name = "Diagnostic"; /* implementation dependent */
8001         break;
8002     case CP0_REGISTER_23:
8003         switch (sel) {
8004         case 0:
8005             gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8006             /* DISAS_STOP isn't good enough here, hflags may have changed. */
8007             gen_save_pc(ctx->base.pc_next + 4);
8008             ctx->base.is_jmp = DISAS_EXIT;
8009             register_name = "Debug";
8010             break;
8011         case 1:
8012 //            gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8013             register_name = "TraceControl";
8014             /* Stop translation as we may have switched the execution mode */
8015             ctx->base.is_jmp = DISAS_STOP;
8016             goto cp0_unimplemented;
8017         case 2:
8018 //            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8019             register_name = "TraceControl2";
8020             /* Stop translation as we may have switched the execution mode */
8021             ctx->base.is_jmp = DISAS_STOP;
8022             goto cp0_unimplemented;
8023         case 3:
8024             /* Stop translation as we may have switched the execution mode */
8025             ctx->base.is_jmp = DISAS_STOP;
8026 //            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8027             register_name = "UserTraceData";
8028             /* Stop translation as we may have switched the execution mode */
8029             ctx->base.is_jmp = DISAS_STOP;
8030             goto cp0_unimplemented;
8031         case 4:
8032 //            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8033             /* Stop translation as we may have switched the execution mode */
8034             ctx->base.is_jmp = DISAS_STOP;
8035             register_name = "TraceBPC";
8036             goto cp0_unimplemented;
8037         default:
8038             goto cp0_unimplemented;
8039         }
8040         break;
8041     case CP0_REGISTER_24:
8042         switch (sel) {
8043         case 0:
8044             /* EJTAG support */
8045             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8046             register_name = "DEPC";
8047             break;
8048         default:
8049             goto cp0_unimplemented;
8050         }
8051         break;
8052     case CP0_REGISTER_25:
8053         switch (sel) {
8054         case 0:
8055             gen_helper_mtc0_performance0(cpu_env, arg);
8056             register_name = "Performance0";
8057             break;
8058         case 1:
8059 //            gen_helper_mtc0_performance1(arg);
8060             register_name = "Performance1";
8061             goto cp0_unimplemented;
8062         case 2:
8063 //            gen_helper_mtc0_performance2(arg);
8064             register_name = "Performance2";
8065             goto cp0_unimplemented;
8066         case 3:
8067 //            gen_helper_mtc0_performance3(arg);
8068             register_name = "Performance3";
8069             goto cp0_unimplemented;
8070         case 4:
8071 //            gen_helper_mtc0_performance4(arg);
8072             register_name = "Performance4";
8073             goto cp0_unimplemented;
8074         case 5:
8075 //            gen_helper_mtc0_performance5(arg);
8076             register_name = "Performance5";
8077             goto cp0_unimplemented;
8078         case 6:
8079 //            gen_helper_mtc0_performance6(arg);
8080             register_name = "Performance6";
8081             goto cp0_unimplemented;
8082         case 7:
8083 //            gen_helper_mtc0_performance7(arg);
8084             register_name = "Performance7";
8085             goto cp0_unimplemented;
8086         default:
8087             goto cp0_unimplemented;
8088         }
8089        break;
8090     case CP0_REGISTER_26:
8091         switch (sel) {
8092         case 0:
8093             gen_helper_mtc0_errctl(cpu_env, arg);
8094             ctx->base.is_jmp = DISAS_STOP;
8095             register_name = "ErrCtl";
8096             break;
8097         default:
8098             goto cp0_unimplemented;
8099         }
8100         break;
8101     case CP0_REGISTER_27:
8102         switch (sel) {
8103         case 0:
8104         case 1:
8105         case 2:
8106         case 3:
8107             /* ignored */
8108             register_name = "CacheErr";
8109             break;
8110         default:
8111             goto cp0_unimplemented;
8112         }
8113        break;
8114     case CP0_REGISTER_28:
8115         switch (sel) {
8116         case 0:
8117         case 2:
8118         case 4:
8119         case 6:
8120             gen_helper_mtc0_taglo(cpu_env, arg);
8121             register_name = "TagLo";
8122             break;
8123         case 1:
8124         case 3:
8125         case 5:
8126         case 7:
8127             gen_helper_mtc0_datalo(cpu_env, arg);
8128             register_name = "DataLo";
8129             break;
8130         default:
8131             goto cp0_unimplemented;
8132         }
8133         break;
8134     case CP0_REGISTER_29:
8135         switch (sel) {
8136         case 0:
8137         case 2:
8138         case 4:
8139         case 6:
8140             gen_helper_mtc0_taghi(cpu_env, arg);
8141             register_name = "TagHi";
8142             break;
8143         case 1:
8144         case 3:
8145         case 5:
8146         case 7:
8147             gen_helper_mtc0_datahi(cpu_env, arg);
8148             register_name = "DataHi";
8149             break;
8150         default:
8151             register_name = "invalid sel";
8152             goto cp0_unimplemented;
8153         }
8154        break;
8155     case CP0_REGISTER_30:
8156         switch (sel) {
8157         case 0:
8158             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8159             register_name = "ErrorEPC";
8160             break;
8161         default:
8162             goto cp0_unimplemented;
8163         }
8164         break;
8165     case CP0_REGISTER_31:
8166         switch (sel) {
8167         case 0:
8168             /* EJTAG support */
8169             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8170             register_name = "DESAVE";
8171             break;
8172         case 2:
8173         case 3:
8174         case 4:
8175         case 5:
8176         case 6:
8177         case 7:
8178             CP0_CHECK(ctx->kscrexist & (1 << sel));
8179             tcg_gen_st_tl(arg, cpu_env,
8180                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8181             register_name = "KScratch";
8182             break;
8183         default:
8184             goto cp0_unimplemented;
8185         }
8186         break;
8187     default:
8188        goto cp0_unimplemented;
8189     }
8190     trace_mips_translate_c0("mtc0", register_name, reg, sel);
8191
8192     /* For simplicity assume that all writes can cause interrupts.  */
8193     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8194         gen_io_end();
8195         /* DISAS_STOP isn't sufficient, we need to ensure we break out of
8196          * translated code to check for pending interrupts.  */
8197         gen_save_pc(ctx->base.pc_next + 4);
8198         ctx->base.is_jmp = DISAS_EXIT;
8199     }
8200     return;
8201
8202 cp0_unimplemented:
8203     qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n",
8204                   register_name, reg, sel);
8205 }
8206
8207 #if defined(TARGET_MIPS64)
8208 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8209 {
8210     const char *register_name = "invalid";
8211
8212     if (sel != 0)
8213         check_insn(ctx, ISA_MIPS64);
8214
8215     switch (reg) {
8216     case CP0_REGISTER_00:
8217         switch (sel) {
8218         case 0:
8219             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
8220             register_name = "Index";
8221             break;
8222         case 1:
8223             CP0_CHECK(ctx->insn_flags & ASE_MT);
8224             gen_helper_mfc0_mvpcontrol(arg, cpu_env);
8225             register_name = "MVPControl";
8226             break;
8227         case 2:
8228             CP0_CHECK(ctx->insn_flags & ASE_MT);
8229             gen_helper_mfc0_mvpconf0(arg, cpu_env);
8230             register_name = "MVPConf0";
8231             break;
8232         case 3:
8233             CP0_CHECK(ctx->insn_flags & ASE_MT);
8234             gen_helper_mfc0_mvpconf1(arg, cpu_env);
8235             register_name = "MVPConf1";
8236             break;
8237         case 4:
8238             CP0_CHECK(ctx->vp);
8239             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
8240             register_name = "VPControl";
8241             break;
8242         default:
8243             goto cp0_unimplemented;
8244         }
8245         break;
8246     case CP0_REGISTER_01:
8247         switch (sel) {
8248         case 0:
8249             CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8250             gen_helper_mfc0_random(arg, cpu_env);
8251             register_name = "Random";
8252             break;
8253         case 1:
8254             CP0_CHECK(ctx->insn_flags & ASE_MT);
8255             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
8256             register_name = "VPEControl";
8257             break;
8258         case 2:
8259             CP0_CHECK(ctx->insn_flags & ASE_MT);
8260             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
8261             register_name = "VPEConf0";
8262             break;
8263         case 3:
8264             CP0_CHECK(ctx->insn_flags & ASE_MT);
8265             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
8266             register_name = "VPEConf1";
8267             break;
8268         case 4:
8269             CP0_CHECK(ctx->insn_flags & ASE_MT);
8270             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
8271             register_name = "YQMask";
8272             break;
8273         case 5:
8274             CP0_CHECK(ctx->insn_flags & ASE_MT);
8275             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
8276             register_name = "VPESchedule";
8277             break;
8278         case 6:
8279             CP0_CHECK(ctx->insn_flags & ASE_MT);
8280             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
8281             register_name = "VPEScheFBack";
8282             break;
8283         case 7:
8284             CP0_CHECK(ctx->insn_flags & ASE_MT);
8285             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
8286             register_name = "VPEOpt";
8287             break;
8288         default:
8289             goto cp0_unimplemented;
8290         }
8291         break;
8292     case CP0_REGISTER_02:
8293         switch (sel) {
8294         case 0:
8295             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
8296             register_name = "EntryLo0";
8297             break;
8298         case 1:
8299             CP0_CHECK(ctx->insn_flags & ASE_MT);
8300             gen_helper_mfc0_tcstatus(arg, cpu_env);
8301             register_name = "TCStatus";
8302             break;
8303         case 2:
8304             CP0_CHECK(ctx->insn_flags & ASE_MT);
8305             gen_helper_mfc0_tcbind(arg, cpu_env);
8306             register_name = "TCBind";
8307             break;
8308         case 3:
8309             CP0_CHECK(ctx->insn_flags & ASE_MT);
8310             gen_helper_dmfc0_tcrestart(arg, cpu_env);
8311             register_name = "TCRestart";
8312             break;
8313         case 4:
8314             CP0_CHECK(ctx->insn_flags & ASE_MT);
8315             gen_helper_dmfc0_tchalt(arg, cpu_env);
8316             register_name = "TCHalt";
8317             break;
8318         case 5:
8319             CP0_CHECK(ctx->insn_flags & ASE_MT);
8320             gen_helper_dmfc0_tccontext(arg, cpu_env);
8321             register_name = "TCContext";
8322             break;
8323         case 6:
8324             CP0_CHECK(ctx->insn_flags & ASE_MT);
8325             gen_helper_dmfc0_tcschedule(arg, cpu_env);
8326             register_name = "TCSchedule";
8327             break;
8328         case 7:
8329             CP0_CHECK(ctx->insn_flags & ASE_MT);
8330             gen_helper_dmfc0_tcschefback(arg, cpu_env);
8331             register_name = "TCScheFBack";
8332             break;
8333         default:
8334             goto cp0_unimplemented;
8335         }
8336         break;
8337     case CP0_REGISTER_03:
8338         switch (sel) {
8339         case 0:
8340             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
8341             register_name = "EntryLo1";
8342             break;
8343         case 1:
8344             CP0_CHECK(ctx->vp);
8345             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
8346             register_name = "GlobalNumber";
8347             break;
8348         default:
8349             goto cp0_unimplemented;
8350         }
8351         break;
8352     case CP0_REGISTER_04:
8353         switch (sel) {
8354         case 0:
8355             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
8356             register_name = "Context";
8357             break;
8358         case 1:
8359 //            gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
8360             register_name = "ContextConfig";
8361             goto cp0_unimplemented;
8362         case 2:
8363             CP0_CHECK(ctx->ulri);
8364             tcg_gen_ld_tl(arg, cpu_env,
8365                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8366             register_name = "UserLocal";
8367             break;
8368         default:
8369             goto cp0_unimplemented;
8370         }
8371         break;
8372     case CP0_REGISTER_05:
8373         switch (sel) {
8374         case 0:
8375             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
8376             register_name = "PageMask";
8377             break;
8378         case 1:
8379             check_insn(ctx, ISA_MIPS32R2);
8380             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
8381             register_name = "PageGrain";
8382             break;
8383         case 2:
8384             CP0_CHECK(ctx->sc);
8385             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
8386             register_name = "SegCtl0";
8387             break;
8388         case 3:
8389             CP0_CHECK(ctx->sc);
8390             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
8391             register_name = "SegCtl1";
8392             break;
8393         case 4:
8394             CP0_CHECK(ctx->sc);
8395             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
8396             register_name = "SegCtl2";
8397             break;
8398         case 5:
8399             check_pw(ctx);
8400             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8401             register_name = "PWBase";
8402             break;
8403         case 6:
8404             check_pw(ctx);
8405             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
8406             register_name = "PWField";
8407             break;
8408         case 7:
8409             check_pw(ctx);
8410             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
8411             register_name = "PWSize";
8412             break;
8413         default:
8414             goto cp0_unimplemented;
8415         }
8416         break;
8417     case CP0_REGISTER_06:
8418         switch (sel) {
8419         case 0:
8420             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
8421             register_name = "Wired";
8422             break;
8423         case 1:
8424             check_insn(ctx, ISA_MIPS32R2);
8425             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
8426             register_name = "SRSConf0";
8427             break;
8428         case 2:
8429             check_insn(ctx, ISA_MIPS32R2);
8430             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
8431             register_name = "SRSConf1";
8432             break;
8433         case 3:
8434             check_insn(ctx, ISA_MIPS32R2);
8435             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
8436             register_name = "SRSConf2";
8437             break;
8438         case 4:
8439             check_insn(ctx, ISA_MIPS32R2);
8440             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
8441             register_name = "SRSConf3";
8442             break;
8443         case 5:
8444             check_insn(ctx, ISA_MIPS32R2);
8445             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
8446             register_name = "SRSConf4";
8447             break;
8448         case 6:
8449             check_pw(ctx);
8450             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
8451             register_name = "PWCtl";
8452             break;
8453         default:
8454             goto cp0_unimplemented;
8455         }
8456         break;
8457     case CP0_REGISTER_07:
8458         switch (sel) {
8459         case 0:
8460             check_insn(ctx, ISA_MIPS32R2);
8461             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
8462             register_name = "HWREna";
8463             break;
8464         default:
8465             goto cp0_unimplemented;
8466         }
8467         break;
8468     case CP0_REGISTER_08:
8469         switch (sel) {
8470         case 0:
8471             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
8472             register_name = "BadVAddr";
8473             break;
8474         case 1:
8475             CP0_CHECK(ctx->bi);
8476             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
8477             register_name = "BadInstr";
8478             break;
8479         case 2:
8480             CP0_CHECK(ctx->bp);
8481             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
8482             register_name = "BadInstrP";
8483             break;
8484         case 3:
8485             CP0_CHECK(ctx->bi);
8486             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
8487             tcg_gen_andi_tl(arg, arg, ~0xffff);
8488             register_name = "BadInstrX";
8489             break;
8490         default:
8491             goto cp0_unimplemented;
8492         }
8493         break;
8494     case CP0_REGISTER_09:
8495         switch (sel) {
8496         case 0:
8497             /* Mark as an IO operation because we read the time.  */
8498             if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8499                 gen_io_start();
8500             }
8501             gen_helper_mfc0_count(arg, cpu_env);
8502             if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8503                 gen_io_end();
8504             }
8505             /* Break the TB to be able to take timer interrupts immediately
8506                after reading count. DISAS_STOP isn't sufficient, we need to
8507                ensure we break completely out of translated code.  */
8508             gen_save_pc(ctx->base.pc_next + 4);
8509             ctx->base.is_jmp = DISAS_EXIT;
8510             register_name = "Count";
8511             break;
8512         case 6:
8513             CP0_CHECK(ctx->saar);
8514             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
8515             register_name = "SAARI";
8516             break;
8517         case 7:
8518             CP0_CHECK(ctx->saar);
8519             gen_helper_dmfc0_saar(arg, cpu_env);
8520             register_name = "SAAR";
8521             break;
8522         default:
8523             goto cp0_unimplemented;
8524         }
8525         break;
8526     case CP0_REGISTER_10:
8527         switch (sel) {
8528         case 0:
8529             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
8530             register_name = "EntryHi";
8531             break;
8532         default:
8533             goto cp0_unimplemented;
8534         }
8535         break;
8536     case CP0_REGISTER_11:
8537         switch (sel) {
8538         case 0:
8539             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
8540             register_name = "Compare";
8541             break;
8542         /* 6,7 are implementation dependent */
8543         default:
8544             goto cp0_unimplemented;
8545         }
8546         break;
8547     case CP0_REGISTER_12:
8548         switch (sel) {
8549         case 0:
8550             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
8551             register_name = "Status";
8552             break;
8553         case 1:
8554             check_insn(ctx, ISA_MIPS32R2);
8555             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
8556             register_name = "IntCtl";
8557             break;
8558         case 2:
8559             check_insn(ctx, ISA_MIPS32R2);
8560             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
8561             register_name = "SRSCtl";
8562             break;
8563         case 3:
8564             check_insn(ctx, ISA_MIPS32R2);
8565             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8566             register_name = "SRSMap";
8567             break;
8568         default:
8569             goto cp0_unimplemented;
8570         }
8571         break;
8572     case CP0_REGISTER_13:
8573         switch (sel) {
8574         case 0:
8575             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
8576             register_name = "Cause";
8577             break;
8578         default:
8579             goto cp0_unimplemented;
8580         }
8581         break;
8582     case CP0_REGISTER_14:
8583         switch (sel) {
8584         case 0:
8585             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
8586             register_name = "EPC";
8587             break;
8588         default:
8589             goto cp0_unimplemented;
8590         }
8591         break;
8592     case CP0_REGISTER_15:
8593         switch (sel) {
8594         case 0:
8595             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
8596             register_name = "PRid";
8597             break;
8598         case 1:
8599             check_insn(ctx, ISA_MIPS32R2);
8600             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
8601             register_name = "EBase";
8602             break;
8603         case 3:
8604             check_insn(ctx, ISA_MIPS32R2);
8605             CP0_CHECK(ctx->cmgcr);
8606             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
8607             register_name = "CMGCRBase";
8608             break;
8609         default:
8610             goto cp0_unimplemented;
8611         }
8612         break;
8613     case CP0_REGISTER_16:
8614         switch (sel) {
8615         case 0:
8616             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
8617             register_name = "Config";
8618             break;
8619         case 1:
8620             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
8621             register_name = "Config1";
8622             break;
8623         case 2:
8624             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
8625             register_name = "Config2";
8626             break;
8627         case 3:
8628             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
8629             register_name = "Config3";
8630             break;
8631         case 4:
8632             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
8633             register_name = "Config4";
8634             break;
8635         case 5:
8636             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
8637             register_name = "Config5";
8638             break;
8639        /* 6,7 are implementation dependent */
8640         case 6:
8641             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
8642             register_name = "Config6";
8643             break;
8644         case 7:
8645             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
8646             register_name = "Config7";
8647             break;
8648         default:
8649             goto cp0_unimplemented;
8650         }
8651         break;
8652     case CP0_REGISTER_17:
8653         switch (sel) {
8654         case 0:
8655             gen_helper_dmfc0_lladdr(arg, cpu_env);
8656             register_name = "LLAddr";
8657             break;
8658         case 1:
8659             CP0_CHECK(ctx->mrp);
8660             gen_helper_dmfc0_maar(arg, cpu_env);
8661             register_name = "MAAR";
8662             break;
8663         case 2:
8664             CP0_CHECK(ctx->mrp);
8665             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
8666             register_name = "MAARI";
8667             break;
8668         default:
8669             goto cp0_unimplemented;
8670         }
8671         break;
8672     case CP0_REGISTER_18:
8673         switch (sel) {
8674         case 0:
8675         case 1:
8676         case 2:
8677         case 3:
8678         case 4:
8679         case 5:
8680         case 6:
8681         case 7:
8682             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8683             gen_helper_1e0i(dmfc0_watchlo, arg, sel);
8684             register_name = "WatchLo";
8685             break;
8686         default:
8687             goto cp0_unimplemented;
8688         }
8689         break;
8690     case CP0_REGISTER_19:
8691         switch (sel) {
8692         case 0:
8693         case 1:
8694         case 2:
8695         case 3:
8696         case 4:
8697         case 5:
8698         case 6:
8699         case 7:
8700             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8701             gen_helper_1e0i(mfc0_watchhi, arg, sel);
8702             register_name = "WatchHi";
8703             break;
8704         default:
8705             goto cp0_unimplemented;
8706         }
8707         break;
8708     case CP0_REGISTER_20:
8709         switch (sel) {
8710         case 0:
8711             check_insn(ctx, ISA_MIPS3);
8712             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
8713             register_name = "XContext";
8714             break;
8715         default:
8716             goto cp0_unimplemented;
8717         }
8718         break;
8719     case CP0_REGISTER_21:
8720        /* Officially reserved, but sel 0 is used for R1x000 framemask */
8721         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8722         switch (sel) {
8723         case 0:
8724             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
8725             register_name = "Framemask";
8726             break;
8727         default:
8728             goto cp0_unimplemented;
8729         }
8730         break;
8731     case CP0_REGISTER_22:
8732         tcg_gen_movi_tl(arg, 0); /* unimplemented */
8733         register_name = "'Diagnostic"; /* implementation dependent */
8734         break;
8735     case CP0_REGISTER_23:
8736         switch (sel) {
8737         case 0:
8738             gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
8739             register_name = "Debug";
8740             break;
8741         case 1:
8742 //            gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
8743             register_name = "TraceControl";
8744             goto cp0_unimplemented;
8745         case 2:
8746 //            gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
8747             register_name = "TraceControl2";
8748             goto cp0_unimplemented;
8749         case 3:
8750 //            gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
8751             register_name = "UserTraceData";
8752             goto cp0_unimplemented;
8753         case 4:
8754 //            gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
8755             register_name = "TraceBPC";
8756             goto cp0_unimplemented;
8757         default:
8758             goto cp0_unimplemented;
8759         }
8760         break;
8761     case CP0_REGISTER_24:
8762         switch (sel) {
8763         case 0:
8764             /* EJTAG support */
8765             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8766             register_name = "DEPC";
8767             break;
8768         default:
8769             goto cp0_unimplemented;
8770         }
8771         break;
8772     case CP0_REGISTER_25:
8773         switch (sel) {
8774         case 0:
8775             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
8776             register_name = "Performance0";
8777             break;
8778         case 1:
8779 //            gen_helper_dmfc0_performance1(arg);
8780             register_name = "Performance1";
8781             goto cp0_unimplemented;
8782         case 2:
8783 //            gen_helper_dmfc0_performance2(arg);
8784             register_name = "Performance2";
8785             goto cp0_unimplemented;
8786         case 3:
8787 //            gen_helper_dmfc0_performance3(arg);
8788             register_name = "Performance3";
8789             goto cp0_unimplemented;
8790         case 4:
8791 //            gen_helper_dmfc0_performance4(arg);
8792             register_name = "Performance4";
8793             goto cp0_unimplemented;
8794         case 5:
8795 //            gen_helper_dmfc0_performance5(arg);
8796             register_name = "Performance5";
8797             goto cp0_unimplemented;
8798         case 6:
8799 //            gen_helper_dmfc0_performance6(arg);
8800             register_name = "Performance6";
8801             goto cp0_unimplemented;
8802         case 7:
8803 //            gen_helper_dmfc0_performance7(arg);
8804             register_name = "Performance7";
8805             goto cp0_unimplemented;
8806         default:
8807             goto cp0_unimplemented;
8808         }
8809         break;
8810     case CP0_REGISTER_26:
8811         switch (sel) {
8812         case 0:
8813             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
8814             register_name = "ErrCtl";
8815             break;
8816         default:
8817             goto cp0_unimplemented;
8818         }
8819         break;
8820     case CP0_REGISTER_27:
8821         switch (sel) {
8822         /* ignored */
8823         case 0:
8824         case 1:
8825         case 2:
8826         case 3:
8827             tcg_gen_movi_tl(arg, 0); /* unimplemented */
8828             register_name = "CacheErr";
8829             break;
8830         default:
8831             goto cp0_unimplemented;
8832         }
8833         break;
8834     case CP0_REGISTER_28:
8835         switch (sel) {
8836         case 0:
8837         case 2:
8838         case 4:
8839         case 6:
8840             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
8841             register_name = "TagLo";
8842             break;
8843         case 1:
8844         case 3:
8845         case 5:
8846         case 7:
8847             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
8848             register_name = "DataLo";
8849             break;
8850         default:
8851             goto cp0_unimplemented;
8852         }
8853         break;
8854     case CP0_REGISTER_29:
8855         switch (sel) {
8856         case 0:
8857         case 2:
8858         case 4:
8859         case 6:
8860             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
8861             register_name = "TagHi";
8862             break;
8863         case 1:
8864         case 3:
8865         case 5:
8866         case 7:
8867             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
8868             register_name = "DataHi";
8869             break;
8870         default:
8871             goto cp0_unimplemented;
8872         }
8873         break;
8874     case CP0_REGISTER_30:
8875         switch (sel) {
8876         case 0:
8877             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8878             register_name = "ErrorEPC";
8879             break;
8880         default:
8881             goto cp0_unimplemented;
8882         }
8883         break;
8884     case CP0_REGISTER_31:
8885         switch (sel) {
8886         case 0:
8887             /* EJTAG support */
8888             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8889             register_name = "DESAVE";
8890             break;
8891         case 2:
8892         case 3:
8893         case 4:
8894         case 5:
8895         case 6:
8896         case 7:
8897             CP0_CHECK(ctx->kscrexist & (1 << sel));
8898             tcg_gen_ld_tl(arg, cpu_env,
8899                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8900             register_name = "KScratch";
8901             break;
8902         default:
8903             goto cp0_unimplemented;
8904         }
8905         break;
8906     default:
8907         goto cp0_unimplemented;
8908     }
8909     trace_mips_translate_c0("dmfc0", register_name, reg, sel);
8910     return;
8911
8912 cp0_unimplemented:
8913     qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n",
8914                   register_name, reg, sel);
8915     gen_mfc0_unimplemented(ctx, arg);
8916 }
8917
8918 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8919 {
8920     const char *register_name = "invalid";
8921
8922     if (sel != 0)
8923         check_insn(ctx, ISA_MIPS64);
8924
8925     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8926         gen_io_start();
8927     }
8928
8929     switch (reg) {
8930     case CP0_REGISTER_00:
8931         switch (sel) {
8932         case 0:
8933             gen_helper_mtc0_index(cpu_env, arg);
8934             register_name = "Index";
8935             break;
8936         case 1:
8937             CP0_CHECK(ctx->insn_flags & ASE_MT);
8938             gen_helper_mtc0_mvpcontrol(cpu_env, arg);
8939             register_name = "MVPControl";
8940             break;
8941         case 2:
8942             CP0_CHECK(ctx->insn_flags & ASE_MT);
8943             /* ignored */
8944             register_name = "MVPConf0";
8945             break;
8946         case 3:
8947             CP0_CHECK(ctx->insn_flags & ASE_MT);
8948             /* ignored */
8949             register_name = "MVPConf1";
8950             break;
8951         case 4:
8952             CP0_CHECK(ctx->vp);
8953             /* ignored */
8954             register_name = "VPControl";
8955             break;
8956         default:
8957             goto cp0_unimplemented;
8958         }
8959         break;
8960     case CP0_REGISTER_01:
8961         switch (sel) {
8962         case 0:
8963             /* ignored */
8964             register_name = "Random";
8965             break;
8966         case 1:
8967             CP0_CHECK(ctx->insn_flags & ASE_MT);
8968             gen_helper_mtc0_vpecontrol(cpu_env, arg);
8969             register_name = "VPEControl";
8970             break;
8971         case 2:
8972             CP0_CHECK(ctx->insn_flags & ASE_MT);
8973             gen_helper_mtc0_vpeconf0(cpu_env, arg);
8974             register_name = "VPEConf0";
8975             break;
8976         case 3:
8977             CP0_CHECK(ctx->insn_flags & ASE_MT);
8978             gen_helper_mtc0_vpeconf1(cpu_env, arg);
8979             register_name = "VPEConf1";
8980             break;
8981         case 4:
8982             CP0_CHECK(ctx->insn_flags & ASE_MT);
8983             gen_helper_mtc0_yqmask(cpu_env, arg);
8984             register_name = "YQMask";
8985             break;
8986         case 5:
8987             CP0_CHECK(ctx->insn_flags & ASE_MT);
8988             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
8989             register_name = "VPESchedule";
8990             break;
8991         case 6:
8992             CP0_CHECK(ctx->insn_flags & ASE_MT);
8993             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
8994             register_name = "VPEScheFBack";
8995             break;
8996         case 7:
8997             CP0_CHECK(ctx->insn_flags & ASE_MT);
8998             gen_helper_mtc0_vpeopt(cpu_env, arg);
8999             register_name = "VPEOpt";
9000             break;
9001         default:
9002             goto cp0_unimplemented;
9003         }
9004         break;
9005     case CP0_REGISTER_02:
9006         switch (sel) {
9007         case 0:
9008             gen_helper_dmtc0_entrylo0(cpu_env, arg);
9009             register_name = "EntryLo0";
9010             break;
9011         case 1:
9012             CP0_CHECK(ctx->insn_flags & ASE_MT);
9013             gen_helper_mtc0_tcstatus(cpu_env, arg);
9014             register_name = "TCStatus";
9015             break;
9016         case 2:
9017             CP0_CHECK(ctx->insn_flags & ASE_MT);
9018             gen_helper_mtc0_tcbind(cpu_env, arg);
9019             register_name = "TCBind";
9020             break;
9021         case 3:
9022             CP0_CHECK(ctx->insn_flags & ASE_MT);
9023             gen_helper_mtc0_tcrestart(cpu_env, arg);
9024             register_name = "TCRestart";
9025             break;
9026         case 4:
9027             CP0_CHECK(ctx->insn_flags & ASE_MT);
9028             gen_helper_mtc0_tchalt(cpu_env, arg);
9029             register_name = "TCHalt";
9030             break;
9031         case 5:
9032             CP0_CHECK(ctx->insn_flags & ASE_MT);
9033             gen_helper_mtc0_tccontext(cpu_env, arg);
9034             register_name = "TCContext";
9035             break;
9036         case 6:
9037             CP0_CHECK(ctx->insn_flags & ASE_MT);
9038             gen_helper_mtc0_tcschedule(cpu_env, arg);
9039             register_name = "TCSchedule";
9040             break;
9041         case 7:
9042             CP0_CHECK(ctx->insn_flags & ASE_MT);
9043             gen_helper_mtc0_tcschefback(cpu_env, arg);
9044             register_name = "TCScheFBack";
9045             break;
9046         default:
9047             goto cp0_unimplemented;
9048         }
9049         break;
9050     case CP0_REGISTER_03:
9051         switch (sel) {
9052         case 0:
9053             gen_helper_dmtc0_entrylo1(cpu_env, arg);
9054             register_name = "EntryLo1";
9055             break;
9056         case 1:
9057             CP0_CHECK(ctx->vp);
9058             /* ignored */
9059             register_name = "GlobalNumber";
9060             break;
9061         default:
9062             goto cp0_unimplemented;
9063         }
9064         break;
9065     case CP0_REGISTER_04:
9066         switch (sel) {
9067         case 0:
9068             gen_helper_mtc0_context(cpu_env, arg);
9069             register_name = "Context";
9070             break;
9071         case 1:
9072 //           gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
9073             register_name = "ContextConfig";
9074             goto cp0_unimplemented;
9075         case 2:
9076             CP0_CHECK(ctx->ulri);
9077             tcg_gen_st_tl(arg, cpu_env,
9078                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
9079             register_name = "UserLocal";
9080             break;
9081         default:
9082             goto cp0_unimplemented;
9083         }
9084         break;
9085     case CP0_REGISTER_05:
9086         switch (sel) {
9087         case 0:
9088             gen_helper_mtc0_pagemask(cpu_env, arg);
9089             register_name = "PageMask";
9090             break;
9091         case 1:
9092             check_insn(ctx, ISA_MIPS32R2);
9093             gen_helper_mtc0_pagegrain(cpu_env, arg);
9094             register_name = "PageGrain";
9095             break;
9096         case 2:
9097             CP0_CHECK(ctx->sc);
9098             gen_helper_mtc0_segctl0(cpu_env, arg);
9099             register_name = "SegCtl0";
9100             break;
9101         case 3:
9102             CP0_CHECK(ctx->sc);
9103             gen_helper_mtc0_segctl1(cpu_env, arg);
9104             register_name = "SegCtl1";
9105             break;
9106         case 4:
9107             CP0_CHECK(ctx->sc);
9108             gen_helper_mtc0_segctl2(cpu_env, arg);
9109             register_name = "SegCtl2";
9110             break;
9111         case 5:
9112             check_pw(ctx);
9113             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
9114             register_name = "PWBase";
9115             break;
9116         case 6:
9117             check_pw(ctx);
9118             gen_helper_mtc0_pwfield(cpu_env, arg);
9119             register_name = "PWField";
9120             break;
9121         case 7:
9122             check_pw(ctx);
9123             gen_helper_mtc0_pwsize(cpu_env, arg);
9124             register_name = "PWSize";
9125             break;
9126         default:
9127             goto cp0_unimplemented;
9128         }
9129         break;
9130     case CP0_REGISTER_06:
9131         switch (sel) {
9132         case 0:
9133             gen_helper_mtc0_wired(cpu_env, arg);
9134             register_name = "Wired";
9135             break;
9136         case 1:
9137             check_insn(ctx, ISA_MIPS32R2);
9138             gen_helper_mtc0_srsconf0(cpu_env, arg);
9139             register_name = "SRSConf0";
9140             break;
9141         case 2:
9142             check_insn(ctx, ISA_MIPS32R2);
9143             gen_helper_mtc0_srsconf1(cpu_env, arg);
9144             register_name = "SRSConf1";
9145             break;
9146         case 3:
9147             check_insn(ctx, ISA_MIPS32R2);
9148             gen_helper_mtc0_srsconf2(cpu_env, arg);
9149             register_name = "SRSConf2";
9150             break;
9151         case 4:
9152             check_insn(ctx, ISA_MIPS32R2);
9153             gen_helper_mtc0_srsconf3(cpu_env, arg);
9154             register_name = "SRSConf3";
9155             break;
9156         case 5:
9157             check_insn(ctx, ISA_MIPS32R2);
9158             gen_helper_mtc0_srsconf4(cpu_env, arg);
9159             register_name = "SRSConf4";
9160             break;
9161         case 6:
9162             check_pw(ctx);
9163             gen_helper_mtc0_pwctl(cpu_env, arg);
9164             register_name = "PWCtl";
9165             break;
9166         default:
9167             goto cp0_unimplemented;
9168         }
9169         break;
9170     case CP0_REGISTER_07:
9171         switch (sel) {
9172         case 0:
9173             check_insn(ctx, ISA_MIPS32R2);
9174             gen_helper_mtc0_hwrena(cpu_env, arg);
9175             ctx->base.is_jmp = DISAS_STOP;
9176             register_name = "HWREna";
9177             break;
9178         default:
9179             goto cp0_unimplemented;
9180         }
9181         break;
9182     case CP0_REGISTER_08:
9183         switch (sel) {
9184         case 0:
9185             /* ignored */
9186             register_name = "BadVAddr";
9187             break;
9188         case 1:
9189             /* ignored */
9190             register_name = "BadInstr";
9191             break;
9192         case 2:
9193             /* ignored */
9194             register_name = "BadInstrP";
9195             break;
9196         case 3:
9197             /* ignored */
9198             register_name = "BadInstrX";
9199             break;
9200         default:
9201             goto cp0_unimplemented;
9202         }
9203         break;
9204     case CP0_REGISTER_09:
9205         switch (sel) {
9206         case 0:
9207             gen_helper_mtc0_count(cpu_env, arg);
9208             register_name = "Count";
9209             break;
9210         case 6:
9211             CP0_CHECK(ctx->saar);
9212             gen_helper_mtc0_saari(cpu_env, arg);
9213             register_name = "SAARI";
9214             break;
9215         case 7:
9216             CP0_CHECK(ctx->saar);
9217             gen_helper_mtc0_saar(cpu_env, arg);
9218             register_name = "SAAR";
9219             break;
9220         default:
9221             goto cp0_unimplemented;
9222         }
9223         /* Stop translation as we may have switched the execution mode */
9224         ctx->base.is_jmp = DISAS_STOP;
9225         break;
9226     case CP0_REGISTER_10:
9227         switch (sel) {
9228         case 0:
9229             gen_helper_mtc0_entryhi(cpu_env, arg);
9230             register_name = "EntryHi";
9231             break;
9232         default:
9233             goto cp0_unimplemented;
9234         }
9235         break;
9236     case CP0_REGISTER_11:
9237         switch (sel) {
9238         case 0:
9239             gen_helper_mtc0_compare(cpu_env, arg);
9240             register_name = "Compare";
9241             break;
9242         /* 6,7 are implementation dependent */
9243         default:
9244             goto cp0_unimplemented;
9245         }
9246         /* Stop translation as we may have switched the execution mode */
9247         ctx->base.is_jmp = DISAS_STOP;
9248         break;
9249     case CP0_REGISTER_12:
9250         switch (sel) {
9251         case 0:
9252             save_cpu_state(ctx, 1);
9253             gen_helper_mtc0_status(cpu_env, arg);
9254             /* DISAS_STOP isn't good enough here, hflags may have changed. */
9255             gen_save_pc(ctx->base.pc_next + 4);
9256             ctx->base.is_jmp = DISAS_EXIT;
9257             register_name = "Status";
9258             break;
9259         case 1:
9260             check_insn(ctx, ISA_MIPS32R2);
9261             gen_helper_mtc0_intctl(cpu_env, arg);
9262             /* Stop translation as we may have switched the execution mode */
9263             ctx->base.is_jmp = DISAS_STOP;
9264             register_name = "IntCtl";
9265             break;
9266         case 2:
9267             check_insn(ctx, ISA_MIPS32R2);
9268             gen_helper_mtc0_srsctl(cpu_env, arg);
9269             /* Stop translation as we may have switched the execution mode */
9270             ctx->base.is_jmp = DISAS_STOP;
9271             register_name = "SRSCtl";
9272             break;
9273         case 3:
9274             check_insn(ctx, ISA_MIPS32R2);
9275             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
9276             /* Stop translation as we may have switched the execution mode */
9277             ctx->base.is_jmp = DISAS_STOP;
9278             register_name = "SRSMap";
9279             break;
9280         default:
9281             goto cp0_unimplemented;
9282         }
9283         break;
9284     case CP0_REGISTER_13:
9285         switch (sel) {
9286         case 0:
9287             save_cpu_state(ctx, 1);
9288             gen_helper_mtc0_cause(cpu_env, arg);
9289             /* Stop translation as we may have triggered an interrupt.
9290              * DISAS_STOP isn't sufficient, we need to ensure we break out of
9291              * translated code to check for pending interrupts.  */
9292             gen_save_pc(ctx->base.pc_next + 4);
9293             ctx->base.is_jmp = DISAS_EXIT;
9294             register_name = "Cause";
9295             break;
9296         default:
9297             goto cp0_unimplemented;
9298         }
9299         break;
9300     case CP0_REGISTER_14:
9301         switch (sel) {
9302         case 0:
9303             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
9304             register_name = "EPC";
9305             break;
9306         default:
9307             goto cp0_unimplemented;
9308         }
9309         break;
9310     case CP0_REGISTER_15:
9311         switch (sel) {
9312         case 0:
9313             /* ignored */
9314             register_name = "PRid";
9315             break;
9316         case 1:
9317             check_insn(ctx, ISA_MIPS32R2);
9318             gen_helper_mtc0_ebase(cpu_env, arg);
9319             register_name = "EBase";
9320             break;
9321         default:
9322             goto cp0_unimplemented;
9323         }
9324         break;
9325     case CP0_REGISTER_16:
9326         switch (sel) {
9327         case 0:
9328             gen_helper_mtc0_config0(cpu_env, arg);
9329             register_name = "Config";
9330             /* Stop translation as we may have switched the execution mode */
9331             ctx->base.is_jmp = DISAS_STOP;
9332             break;
9333         case 1:
9334             /* ignored, read only */
9335             register_name = "Config1";
9336             break;
9337         case 2:
9338             gen_helper_mtc0_config2(cpu_env, arg);
9339             register_name = "Config2";
9340             /* Stop translation as we may have switched the execution mode */
9341             ctx->base.is_jmp = DISAS_STOP;
9342             break;
9343         case 3:
9344             gen_helper_mtc0_config3(cpu_env, arg);
9345             register_name = "Config3";
9346             /* Stop translation as we may have switched the execution mode */
9347             ctx->base.is_jmp = DISAS_STOP;
9348             break;
9349         case 4:
9350             /* currently ignored */
9351             register_name = "Config4";
9352             break;
9353         case 5:
9354             gen_helper_mtc0_config5(cpu_env, arg);
9355             register_name = "Config5";
9356             /* Stop translation as we may have switched the execution mode */
9357             ctx->base.is_jmp = DISAS_STOP;
9358             break;
9359         /* 6,7 are implementation dependent */
9360         default:
9361             register_name = "Invalid config selector";
9362             goto cp0_unimplemented;
9363         }
9364         break;
9365     case CP0_REGISTER_17:
9366         switch (sel) {
9367         case 0:
9368             gen_helper_mtc0_lladdr(cpu_env, arg);
9369             register_name = "LLAddr";
9370             break;
9371         case 1:
9372             CP0_CHECK(ctx->mrp);
9373             gen_helper_mtc0_maar(cpu_env, arg);
9374             register_name = "MAAR";
9375             break;
9376         case 2:
9377             CP0_CHECK(ctx->mrp);
9378             gen_helper_mtc0_maari(cpu_env, arg);
9379             register_name = "MAARI";
9380             break;
9381         default:
9382             goto cp0_unimplemented;
9383         }
9384         break;
9385     case CP0_REGISTER_18:
9386         switch (sel) {
9387         case 0:
9388         case 1:
9389         case 2:
9390         case 3:
9391         case 4:
9392         case 5:
9393         case 6:
9394         case 7:
9395             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9396             gen_helper_0e1i(mtc0_watchlo, arg, sel);
9397             register_name = "WatchLo";
9398             break;
9399         default:
9400             goto cp0_unimplemented;
9401         }
9402         break;
9403     case CP0_REGISTER_19:
9404         switch (sel) {
9405         case 0:
9406         case 1:
9407         case 2:
9408         case 3:
9409         case 4:
9410         case 5:
9411         case 6:
9412         case 7:
9413             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9414             gen_helper_0e1i(mtc0_watchhi, arg, sel);
9415             register_name = "WatchHi";
9416             break;
9417         default:
9418             goto cp0_unimplemented;
9419         }
9420         break;
9421     case CP0_REGISTER_20:
9422         switch (sel) {
9423         case 0:
9424             check_insn(ctx, ISA_MIPS3);
9425             gen_helper_mtc0_xcontext(cpu_env, arg);
9426             register_name = "XContext";
9427             break;
9428         default:
9429             goto cp0_unimplemented;
9430         }
9431         break;
9432     case CP0_REGISTER_21:
9433        /* Officially reserved, but sel 0 is used for R1x000 framemask */
9434         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9435         switch (sel) {
9436         case 0:
9437             gen_helper_mtc0_framemask(cpu_env, arg);
9438             register_name = "Framemask";
9439             break;
9440         default:
9441             goto cp0_unimplemented;
9442         }
9443         break;
9444     case CP0_REGISTER_22:
9445         /* ignored */
9446         register_name = "Diagnostic"; /* implementation dependent */
9447         break;
9448     case CP0_REGISTER_23:
9449         switch (sel) {
9450         case 0:
9451             gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
9452             /* DISAS_STOP isn't good enough here, hflags may have changed. */
9453             gen_save_pc(ctx->base.pc_next + 4);
9454             ctx->base.is_jmp = DISAS_EXIT;
9455             register_name = "Debug";
9456             break;
9457         case 1:
9458 //            gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
9459             /* Stop translation as we may have switched the execution mode */
9460             ctx->base.is_jmp = DISAS_STOP;
9461             register_name = "TraceControl";
9462             goto cp0_unimplemented;
9463         case 2:
9464 //            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
9465             /* Stop translation as we may have switched the execution mode */
9466             ctx->base.is_jmp = DISAS_STOP;
9467             register_name = "TraceControl2";
9468             goto cp0_unimplemented;
9469         case 3:
9470 //            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
9471             /* Stop translation as we may have switched the execution mode */
9472             ctx->base.is_jmp = DISAS_STOP;
9473             register_name = "UserTraceData";
9474             goto cp0_unimplemented;
9475         case 4:
9476 //            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
9477             /* Stop translation as we may have switched the execution mode */
9478             ctx->base.is_jmp = DISAS_STOP;
9479             register_name = "TraceBPC";
9480             goto cp0_unimplemented;
9481         default:
9482             goto cp0_unimplemented;
9483         }
9484         break;
9485     case CP0_REGISTER_24:
9486         switch (sel) {
9487         case 0:
9488             /* EJTAG support */
9489             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
9490             register_name = "DEPC";
9491             break;
9492         default:
9493             goto cp0_unimplemented;
9494         }
9495         break;
9496     case CP0_REGISTER_25:
9497         switch (sel) {
9498         case 0:
9499             gen_helper_mtc0_performance0(cpu_env, arg);
9500             register_name = "Performance0";
9501             break;
9502         case 1:
9503 //            gen_helper_mtc0_performance1(cpu_env, arg);
9504             register_name = "Performance1";
9505             goto cp0_unimplemented;
9506         case 2:
9507 //            gen_helper_mtc0_performance2(cpu_env, arg);
9508             register_name = "Performance2";
9509             goto cp0_unimplemented;
9510         case 3:
9511 //            gen_helper_mtc0_performance3(cpu_env, arg);
9512             register_name = "Performance3";
9513             goto cp0_unimplemented;
9514         case 4:
9515 //            gen_helper_mtc0_performance4(cpu_env, arg);
9516             register_name = "Performance4";
9517             goto cp0_unimplemented;
9518         case 5:
9519 //            gen_helper_mtc0_performance5(cpu_env, arg);
9520             register_name = "Performance5";
9521             goto cp0_unimplemented;
9522         case 6:
9523 //            gen_helper_mtc0_performance6(cpu_env, arg);
9524             register_name = "Performance6";
9525             goto cp0_unimplemented;
9526         case 7:
9527 //            gen_helper_mtc0_performance7(cpu_env, arg);
9528             register_name = "Performance7";
9529             goto cp0_unimplemented;
9530         default:
9531             goto cp0_unimplemented;
9532         }
9533         break;
9534     case CP0_REGISTER_26:
9535         switch (sel) {
9536         case 0:
9537             gen_helper_mtc0_errctl(cpu_env, arg);
9538             ctx->base.is_jmp = DISAS_STOP;
9539             register_name = "ErrCtl";
9540             break;
9541         default:
9542             goto cp0_unimplemented;
9543         }
9544         break;
9545     case CP0_REGISTER_27:
9546         switch (sel) {
9547         case 0:
9548         case 1:
9549         case 2:
9550         case 3:
9551             /* ignored */
9552             register_name = "CacheErr";
9553             break;
9554         default:
9555             goto cp0_unimplemented;
9556         }
9557         break;
9558     case CP0_REGISTER_28:
9559         switch (sel) {
9560         case 0:
9561         case 2:
9562         case 4:
9563         case 6:
9564             gen_helper_mtc0_taglo(cpu_env, arg);
9565             register_name = "TagLo";
9566             break;
9567         case 1:
9568         case 3:
9569         case 5:
9570         case 7:
9571             gen_helper_mtc0_datalo(cpu_env, arg);
9572             register_name = "DataLo";
9573             break;
9574         default:
9575             goto cp0_unimplemented;
9576         }
9577         break;
9578     case CP0_REGISTER_29:
9579         switch (sel) {
9580         case 0:
9581         case 2:
9582         case 4:
9583         case 6:
9584             gen_helper_mtc0_taghi(cpu_env, arg);
9585             register_name = "TagHi";
9586             break;
9587         case 1:
9588         case 3:
9589         case 5:
9590         case 7:
9591             gen_helper_mtc0_datahi(cpu_env, arg);
9592             register_name = "DataHi";
9593             break;
9594         default:
9595             register_name = "invalid sel";
9596             goto cp0_unimplemented;
9597         }
9598         break;
9599     case CP0_REGISTER_30:
9600         switch (sel) {
9601         case 0:
9602             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
9603             register_name = "ErrorEPC";
9604             break;
9605         default:
9606             goto cp0_unimplemented;
9607         }
9608         break;
9609     case CP0_REGISTER_31:
9610         switch (sel) {
9611         case 0:
9612             /* EJTAG support */
9613             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
9614             register_name = "DESAVE";
9615             break;
9616         case 2:
9617         case 3:
9618         case 4:
9619         case 5:
9620         case 6:
9621         case 7:
9622             CP0_CHECK(ctx->kscrexist & (1 << sel));
9623             tcg_gen_st_tl(arg, cpu_env,
9624                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
9625             register_name = "KScratch";
9626             break;
9627         default:
9628             goto cp0_unimplemented;
9629         }
9630         break;
9631     default:
9632         goto cp0_unimplemented;
9633     }
9634     trace_mips_translate_c0("dmtc0", register_name, reg, sel);
9635
9636     /* For simplicity assume that all writes can cause interrupts.  */
9637     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
9638         gen_io_end();
9639         /* DISAS_STOP isn't sufficient, we need to ensure we break out of
9640          * translated code to check for pending interrupts.  */
9641         gen_save_pc(ctx->base.pc_next + 4);
9642         ctx->base.is_jmp = DISAS_EXIT;
9643     }
9644     return;
9645
9646 cp0_unimplemented:
9647     qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n",
9648                   register_name, reg, sel);
9649 }
9650 #endif /* TARGET_MIPS64 */
9651
9652 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
9653                      int u, int sel, int h)
9654 {
9655     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9656     TCGv t0 = tcg_temp_local_new();
9657
9658     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9659         ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9660          (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
9661         tcg_gen_movi_tl(t0, -1);
9662     else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9663              (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
9664         tcg_gen_movi_tl(t0, -1);
9665     else if (u == 0) {
9666         switch (rt) {
9667         case 1:
9668             switch (sel) {
9669             case 1:
9670                 gen_helper_mftc0_vpecontrol(t0, cpu_env);
9671                 break;
9672             case 2:
9673                 gen_helper_mftc0_vpeconf0(t0, cpu_env);
9674                 break;
9675             default:
9676                 goto die;
9677                 break;
9678             }
9679             break;
9680         case 2:
9681             switch (sel) {
9682             case 1:
9683                 gen_helper_mftc0_tcstatus(t0, cpu_env);
9684                 break;
9685             case 2:
9686                 gen_helper_mftc0_tcbind(t0, cpu_env);
9687                 break;
9688             case 3:
9689                 gen_helper_mftc0_tcrestart(t0, cpu_env);
9690                 break;
9691             case 4:
9692                 gen_helper_mftc0_tchalt(t0, cpu_env);
9693                 break;
9694             case 5:
9695                 gen_helper_mftc0_tccontext(t0, cpu_env);
9696                 break;
9697             case 6:
9698                 gen_helper_mftc0_tcschedule(t0, cpu_env);
9699                 break;
9700             case 7:
9701                 gen_helper_mftc0_tcschefback(t0, cpu_env);
9702                 break;
9703             default:
9704                 gen_mfc0(ctx, t0, rt, sel);
9705                 break;
9706             }
9707             break;
9708         case 10:
9709             switch (sel) {
9710             case 0:
9711                 gen_helper_mftc0_entryhi(t0, cpu_env);
9712                 break;
9713             default:
9714                 gen_mfc0(ctx, t0, rt, sel);
9715                 break;
9716             }
9717         case 12:
9718             switch (sel) {
9719             case 0:
9720                 gen_helper_mftc0_status(t0, cpu_env);
9721                 break;
9722             default:
9723                 gen_mfc0(ctx, t0, rt, sel);
9724                 break;
9725             }
9726         case 13:
9727             switch (sel) {
9728             case 0:
9729                 gen_helper_mftc0_cause(t0, cpu_env);
9730                 break;
9731             default:
9732                 goto die;
9733                 break;
9734             }
9735             break;
9736         case 14:
9737             switch (sel) {
9738             case 0:
9739                 gen_helper_mftc0_epc(t0, cpu_env);
9740                 break;
9741             default:
9742                 goto die;
9743                 break;
9744             }
9745             break;
9746         case 15:
9747             switch (sel) {
9748             case 1:
9749                 gen_helper_mftc0_ebase(t0, cpu_env);
9750                 break;
9751             default:
9752                 goto die;
9753                 break;
9754             }
9755             break;
9756         case 16:
9757             switch (sel) {
9758             case 0:
9759             case 1:
9760             case 2:
9761             case 3:
9762             case 4:
9763             case 5:
9764             case 6:
9765             case 7:
9766                 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
9767                 break;
9768             default:
9769                 goto die;
9770                 break;
9771             }
9772             break;
9773         case 23:
9774             switch (sel) {
9775             case 0:
9776                 gen_helper_mftc0_debug(t0, cpu_env);
9777                 break;
9778             default:
9779                 gen_mfc0(ctx, t0, rt, sel);
9780                 break;
9781             }
9782             break;
9783         default:
9784             gen_mfc0(ctx, t0, rt, sel);
9785         }
9786     } else switch (sel) {
9787     /* GPR registers. */
9788     case 0:
9789         gen_helper_1e0i(mftgpr, t0, rt);
9790         break;
9791     /* Auxiliary CPU registers */
9792     case 1:
9793         switch (rt) {
9794         case 0:
9795             gen_helper_1e0i(mftlo, t0, 0);
9796             break;
9797         case 1:
9798             gen_helper_1e0i(mfthi, t0, 0);
9799             break;
9800         case 2:
9801             gen_helper_1e0i(mftacx, t0, 0);
9802             break;
9803         case 4:
9804             gen_helper_1e0i(mftlo, t0, 1);
9805             break;
9806         case 5:
9807             gen_helper_1e0i(mfthi, t0, 1);
9808             break;
9809         case 6:
9810             gen_helper_1e0i(mftacx, t0, 1);
9811             break;
9812         case 8:
9813             gen_helper_1e0i(mftlo, t0, 2);
9814             break;
9815         case 9:
9816             gen_helper_1e0i(mfthi, t0, 2);
9817             break;
9818         case 10:
9819             gen_helper_1e0i(mftacx, t0, 2);
9820             break;
9821         case 12:
9822             gen_helper_1e0i(mftlo, t0, 3);
9823             break;
9824         case 13:
9825             gen_helper_1e0i(mfthi, t0, 3);
9826             break;
9827         case 14:
9828             gen_helper_1e0i(mftacx, t0, 3);
9829             break;
9830         case 16:
9831             gen_helper_mftdsp(t0, cpu_env);
9832             break;
9833         default:
9834             goto die;
9835         }
9836         break;
9837     /* Floating point (COP1). */
9838     case 2:
9839         /* XXX: For now we support only a single FPU context. */
9840         if (h == 0) {
9841             TCGv_i32 fp0 = tcg_temp_new_i32();
9842
9843             gen_load_fpr32(ctx, fp0, rt);
9844             tcg_gen_ext_i32_tl(t0, fp0);
9845             tcg_temp_free_i32(fp0);
9846         } else {
9847             TCGv_i32 fp0 = tcg_temp_new_i32();
9848
9849             gen_load_fpr32h(ctx, fp0, rt);
9850             tcg_gen_ext_i32_tl(t0, fp0);
9851             tcg_temp_free_i32(fp0);
9852         }
9853         break;
9854     case 3:
9855         /* XXX: For now we support only a single FPU context. */
9856         gen_helper_1e0i(cfc1, t0, rt);
9857         break;
9858     /* COP2: Not implemented. */
9859     case 4:
9860     case 5:
9861         /* fall through */
9862     default:
9863         goto die;
9864     }
9865     trace_mips_translate_tr("mftr", rt, u, sel, h);
9866     gen_store_gpr(t0, rd);
9867     tcg_temp_free(t0);
9868     return;
9869
9870 die:
9871     tcg_temp_free(t0);
9872     LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
9873     generate_exception_end(ctx, EXCP_RI);
9874 }
9875
9876 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
9877                      int u, int sel, int h)
9878 {
9879     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9880     TCGv t0 = tcg_temp_local_new();
9881
9882     gen_load_gpr(t0, rt);
9883     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9884         ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9885          (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
9886         /* NOP */ ;
9887     else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9888              (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
9889         /* NOP */ ;
9890     else if (u == 0) {
9891         switch (rd) {
9892         case 1:
9893             switch (sel) {
9894             case 1:
9895                 gen_helper_mttc0_vpecontrol(cpu_env, t0);
9896                 break;
9897             case 2:
9898                 gen_helper_mttc0_vpeconf0(cpu_env, t0);
9899                 break;
9900             default:
9901                 goto die;
9902                 break;
9903             }
9904             break;
9905         case 2:
9906             switch (sel) {
9907             case 1:
9908                 gen_helper_mttc0_tcstatus(cpu_env, t0);
9909                 break;
9910             case 2:
9911                 gen_helper_mttc0_tcbind(cpu_env, t0);
9912                 break;
9913             case 3:
9914                 gen_helper_mttc0_tcrestart(cpu_env, t0);
9915                 break;
9916             case 4:
9917                 gen_helper_mttc0_tchalt(cpu_env, t0);
9918                 break;
9919             case 5:
9920                 gen_helper_mttc0_tccontext(cpu_env, t0);
9921                 break;
9922             case 6:
9923                 gen_helper_mttc0_tcschedule(cpu_env, t0);
9924                 break;
9925             case 7:
9926                 gen_helper_mttc0_tcschefback(cpu_env, t0);
9927                 break;
9928             default:
9929                 gen_mtc0(ctx, t0, rd, sel);
9930                 break;
9931             }
9932             break;
9933         case 10:
9934             switch (sel) {
9935             case 0:
9936                 gen_helper_mttc0_entryhi(cpu_env, t0);
9937                 break;
9938             default:
9939                 gen_mtc0(ctx, t0, rd, sel);
9940                 break;
9941             }
9942         case 12:
9943             switch (sel) {
9944             case 0:
9945                 gen_helper_mttc0_status(cpu_env, t0);
9946                 break;
9947             default:
9948                 gen_mtc0(ctx, t0, rd, sel);
9949                 break;
9950             }
9951         case 13:
9952             switch (sel) {
9953             case 0:
9954                 gen_helper_mttc0_cause(cpu_env, t0);
9955                 break;
9956             default:
9957                 goto die;
9958                 break;
9959             }
9960             break;
9961         case 15:
9962             switch (sel) {
9963             case 1:
9964                 gen_helper_mttc0_ebase(cpu_env, t0);
9965                 break;
9966             default:
9967                 goto die;
9968                 break;
9969             }
9970             break;
9971         case 23:
9972             switch (sel) {
9973             case 0:
9974                 gen_helper_mttc0_debug(cpu_env, t0);
9975                 break;
9976             default:
9977                 gen_mtc0(ctx, t0, rd, sel);
9978                 break;
9979             }
9980             break;
9981         default:
9982             gen_mtc0(ctx, t0, rd, sel);
9983         }
9984     } else switch (sel) {
9985     /* GPR registers. */
9986     case 0:
9987         gen_helper_0e1i(mttgpr, t0, rd);
9988         break;
9989     /* Auxiliary CPU registers */
9990     case 1:
9991         switch (rd) {
9992         case 0:
9993             gen_helper_0e1i(mttlo, t0, 0);
9994             break;
9995         case 1:
9996             gen_helper_0e1i(mtthi, t0, 0);
9997             break;
9998         case 2:
9999             gen_helper_0e1i(mttacx, t0, 0);
10000             break;
10001         case 4:
10002             gen_helper_0e1i(mttlo, t0, 1);
10003             break;
10004         case 5:
10005             gen_helper_0e1i(mtthi, t0, 1);
10006             break;
10007         case 6:
10008             gen_helper_0e1i(mttacx, t0, 1);
10009             break;
10010         case 8:
10011             gen_helper_0e1i(mttlo, t0, 2);
10012             break;
10013         case 9:
10014             gen_helper_0e1i(mtthi, t0, 2);
10015             break;
10016         case 10:
10017             gen_helper_0e1i(mttacx, t0, 2);
10018             break;
10019         case 12:
10020             gen_helper_0e1i(mttlo, t0, 3);
10021             break;
10022         case 13:
10023             gen_helper_0e1i(mtthi, t0, 3);
10024             break;
10025         case 14:
10026             gen_helper_0e1i(mttacx, t0, 3);
10027             break;
10028         case 16:
10029             gen_helper_mttdsp(cpu_env, t0);
10030             break;
10031         default:
10032             goto die;
10033         }
10034         break;
10035     /* Floating point (COP1). */
10036     case 2:
10037         /* XXX: For now we support only a single FPU context. */
10038         if (h == 0) {
10039             TCGv_i32 fp0 = tcg_temp_new_i32();
10040
10041             tcg_gen_trunc_tl_i32(fp0, t0);
10042             gen_store_fpr32(ctx, fp0, rd);
10043             tcg_temp_free_i32(fp0);
10044         } else {
10045             TCGv_i32 fp0 = tcg_temp_new_i32();
10046
10047             tcg_gen_trunc_tl_i32(fp0, t0);
10048             gen_store_fpr32h(ctx, fp0, rd);
10049             tcg_temp_free_i32(fp0);
10050         }
10051         break;
10052     case 3:
10053         /* XXX: For now we support only a single FPU context. */
10054         {
10055             TCGv_i32 fs_tmp = tcg_const_i32(rd);
10056
10057             gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10058             tcg_temp_free_i32(fs_tmp);
10059         }
10060         /* Stop translation as we may have changed hflags */
10061         ctx->base.is_jmp = DISAS_STOP;
10062         break;
10063     /* COP2: Not implemented. */
10064     case 4:
10065     case 5:
10066         /* fall through */
10067     default:
10068         goto die;
10069     }
10070     trace_mips_translate_tr("mttr", rd, u, sel, h);
10071     tcg_temp_free(t0);
10072     return;
10073
10074 die:
10075     tcg_temp_free(t0);
10076     LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
10077     generate_exception_end(ctx, EXCP_RI);
10078 }
10079
10080 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
10081 {
10082     const char *opn = "ldst";
10083
10084     check_cp0_enabled(ctx);
10085     switch (opc) {
10086     case OPC_MFC0:
10087         if (rt == 0) {
10088             /* Treat as NOP. */
10089             return;
10090         }
10091         gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10092         opn = "mfc0";
10093         break;
10094     case OPC_MTC0:
10095         {
10096             TCGv t0 = tcg_temp_new();
10097
10098             gen_load_gpr(t0, rt);
10099             gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
10100             tcg_temp_free(t0);
10101         }
10102         opn = "mtc0";
10103         break;
10104 #if defined(TARGET_MIPS64)
10105     case OPC_DMFC0:
10106         check_insn(ctx, ISA_MIPS3);
10107         if (rt == 0) {
10108             /* Treat as NOP. */
10109             return;
10110         }
10111         gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10112         opn = "dmfc0";
10113         break;
10114     case OPC_DMTC0:
10115         check_insn(ctx, ISA_MIPS3);
10116         {
10117             TCGv t0 = tcg_temp_new();
10118
10119             gen_load_gpr(t0, rt);
10120             gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
10121             tcg_temp_free(t0);
10122         }
10123         opn = "dmtc0";
10124         break;
10125 #endif
10126     case OPC_MFHC0:
10127         check_mvh(ctx);
10128         if (rt == 0) {
10129             /* Treat as NOP. */
10130             return;
10131         }
10132         gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10133         opn = "mfhc0";
10134         break;
10135     case OPC_MTHC0:
10136         check_mvh(ctx);
10137         {
10138             TCGv t0 = tcg_temp_new();
10139             gen_load_gpr(t0, rt);
10140             gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
10141             tcg_temp_free(t0);
10142         }
10143         opn = "mthc0";
10144         break;
10145     case OPC_MFTR:
10146         check_cp0_enabled(ctx);
10147         if (rd == 0) {
10148             /* Treat as NOP. */
10149             return;
10150         }
10151         gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
10152                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
10153         opn = "mftr";
10154         break;
10155     case OPC_MTTR:
10156         check_cp0_enabled(ctx);
10157         gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
10158                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
10159         opn = "mttr";
10160         break;
10161     case OPC_TLBWI:
10162         opn = "tlbwi";
10163         if (!env->tlb->helper_tlbwi)
10164             goto die;
10165         gen_helper_tlbwi(cpu_env);
10166         break;
10167     case OPC_TLBINV:
10168         opn = "tlbinv";
10169         if (ctx->ie >= 2) {
10170             if (!env->tlb->helper_tlbinv) {
10171                 goto die;
10172             }
10173             gen_helper_tlbinv(cpu_env);
10174         } /* treat as nop if TLBINV not supported */
10175         break;
10176     case OPC_TLBINVF:
10177         opn = "tlbinvf";
10178         if (ctx->ie >= 2) {
10179             if (!env->tlb->helper_tlbinvf) {
10180                 goto die;
10181             }
10182             gen_helper_tlbinvf(cpu_env);
10183         } /* treat as nop if TLBINV not supported */
10184         break;
10185     case OPC_TLBWR:
10186         opn = "tlbwr";
10187         if (!env->tlb->helper_tlbwr)
10188             goto die;
10189         gen_helper_tlbwr(cpu_env);
10190         break;
10191     case OPC_TLBP:
10192         opn = "tlbp";
10193         if (!env->tlb->helper_tlbp)
10194             goto die;
10195         gen_helper_tlbp(cpu_env);
10196         break;
10197     case OPC_TLBR:
10198         opn = "tlbr";
10199         if (!env->tlb->helper_tlbr)
10200             goto die;
10201         gen_helper_tlbr(cpu_env);
10202         break;
10203     case OPC_ERET: /* OPC_ERETNC */
10204         if ((ctx->insn_flags & ISA_MIPS32R6) &&
10205             (ctx->hflags & MIPS_HFLAG_BMASK)) {
10206             goto die;
10207         } else {
10208             int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
10209             if (ctx->opcode & (1 << bit_shift)) {
10210                 /* OPC_ERETNC */
10211                 opn = "eretnc";
10212                 check_insn(ctx, ISA_MIPS32R5);
10213                 gen_helper_eretnc(cpu_env);
10214             } else {
10215                 /* OPC_ERET */
10216                 opn = "eret";
10217                 check_insn(ctx, ISA_MIPS2);
10218                 gen_helper_eret(cpu_env);
10219             }
10220             ctx->base.is_jmp = DISAS_EXIT;
10221         }
10222         break;
10223     case OPC_DERET:
10224         opn = "deret";
10225         check_insn(ctx, ISA_MIPS32);
10226         if ((ctx->insn_flags & ISA_MIPS32R6) &&
10227             (ctx->hflags & MIPS_HFLAG_BMASK)) {
10228             goto die;
10229         }
10230         if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10231             MIPS_INVAL(opn);
10232             generate_exception_end(ctx, EXCP_RI);
10233         } else {
10234             gen_helper_deret(cpu_env);
10235             ctx->base.is_jmp = DISAS_EXIT;
10236         }
10237         break;
10238     case OPC_WAIT:
10239         opn = "wait";
10240         check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
10241         if ((ctx->insn_flags & ISA_MIPS32R6) &&
10242             (ctx->hflags & MIPS_HFLAG_BMASK)) {
10243             goto die;
10244         }
10245         /* If we get an exception, we want to restart at next instruction */
10246         ctx->base.pc_next += 4;
10247         save_cpu_state(ctx, 1);
10248         ctx->base.pc_next -= 4;
10249         gen_helper_wait(cpu_env);
10250         ctx->base.is_jmp = DISAS_NORETURN;
10251         break;
10252     default:
10253  die:
10254         MIPS_INVAL(opn);
10255         generate_exception_end(ctx, EXCP_RI);
10256         return;
10257     }
10258     (void)opn; /* avoid a compiler warning */
10259 }
10260 #endif /* !CONFIG_USER_ONLY */
10261
10262 /* CP1 Branches (before delay slot) */
10263 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
10264                                 int32_t cc, int32_t offset)
10265 {
10266     target_ulong btarget;
10267     TCGv_i32 t0 = tcg_temp_new_i32();
10268
10269     if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
10270         generate_exception_end(ctx, EXCP_RI);
10271         goto out;
10272     }
10273
10274     if (cc != 0)
10275         check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
10276
10277     btarget = ctx->base.pc_next + 4 + offset;
10278
10279     switch (op) {
10280     case OPC_BC1F:
10281         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10282         tcg_gen_not_i32(t0, t0);
10283         tcg_gen_andi_i32(t0, t0, 1);
10284         tcg_gen_extu_i32_tl(bcond, t0);
10285         goto not_likely;
10286     case OPC_BC1FL:
10287         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10288         tcg_gen_not_i32(t0, t0);
10289         tcg_gen_andi_i32(t0, t0, 1);
10290         tcg_gen_extu_i32_tl(bcond, t0);
10291         goto likely;
10292     case OPC_BC1T:
10293         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10294         tcg_gen_andi_i32(t0, t0, 1);
10295         tcg_gen_extu_i32_tl(bcond, t0);
10296         goto not_likely;
10297     case OPC_BC1TL:
10298         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10299         tcg_gen_andi_i32(t0, t0, 1);
10300         tcg_gen_extu_i32_tl(bcond, t0);
10301     likely:
10302         ctx->hflags |= MIPS_HFLAG_BL;
10303         break;
10304     case OPC_BC1FANY2:
10305         {
10306             TCGv_i32 t1 = tcg_temp_new_i32();
10307             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10308             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10309             tcg_gen_nand_i32(t0, t0, t1);
10310             tcg_temp_free_i32(t1);
10311             tcg_gen_andi_i32(t0, t0, 1);
10312             tcg_gen_extu_i32_tl(bcond, t0);
10313         }
10314         goto not_likely;
10315     case OPC_BC1TANY2:
10316         {
10317             TCGv_i32 t1 = tcg_temp_new_i32();
10318             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10319             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10320             tcg_gen_or_i32(t0, t0, t1);
10321             tcg_temp_free_i32(t1);
10322             tcg_gen_andi_i32(t0, t0, 1);
10323             tcg_gen_extu_i32_tl(bcond, t0);
10324         }
10325         goto not_likely;
10326     case OPC_BC1FANY4:
10327         {
10328             TCGv_i32 t1 = tcg_temp_new_i32();
10329             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10330             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10331             tcg_gen_and_i32(t0, t0, t1);
10332             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
10333             tcg_gen_and_i32(t0, t0, t1);
10334             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
10335             tcg_gen_nand_i32(t0, t0, t1);
10336             tcg_temp_free_i32(t1);
10337             tcg_gen_andi_i32(t0, t0, 1);
10338             tcg_gen_extu_i32_tl(bcond, t0);
10339         }
10340         goto not_likely;
10341     case OPC_BC1TANY4:
10342         {
10343             TCGv_i32 t1 = tcg_temp_new_i32();
10344             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10345             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10346             tcg_gen_or_i32(t0, t0, t1);
10347             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
10348             tcg_gen_or_i32(t0, t0, t1);
10349             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
10350             tcg_gen_or_i32(t0, t0, t1);
10351             tcg_temp_free_i32(t1);
10352             tcg_gen_andi_i32(t0, t0, 1);
10353             tcg_gen_extu_i32_tl(bcond, t0);
10354         }
10355     not_likely:
10356         ctx->hflags |= MIPS_HFLAG_BC;
10357         break;
10358     default:
10359         MIPS_INVAL("cp1 cond branch");
10360         generate_exception_end(ctx, EXCP_RI);
10361         goto out;
10362     }
10363     ctx->btarget = btarget;
10364     ctx->hflags |= MIPS_HFLAG_BDS32;
10365  out:
10366     tcg_temp_free_i32(t0);
10367 }
10368
10369 /* R6 CP1 Branches */
10370 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
10371                                    int32_t ft, int32_t offset,
10372                                    int delayslot_size)
10373 {
10374     target_ulong btarget;
10375     TCGv_i64 t0 = tcg_temp_new_i64();
10376
10377     if (ctx->hflags & MIPS_HFLAG_BMASK) {
10378 #ifdef MIPS_DEBUG_DISAS
10379         LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10380                   "\n", ctx->base.pc_next);
10381 #endif
10382         generate_exception_end(ctx, EXCP_RI);
10383         goto out;
10384     }
10385
10386     gen_load_fpr64(ctx, t0, ft);
10387     tcg_gen_andi_i64(t0, t0, 1);
10388
10389     btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
10390
10391     switch (op) {
10392     case OPC_BC1EQZ:
10393         tcg_gen_xori_i64(t0, t0, 1);
10394         ctx->hflags |= MIPS_HFLAG_BC;
10395         break;
10396     case OPC_BC1NEZ:
10397         /* t0 already set */
10398         ctx->hflags |= MIPS_HFLAG_BC;
10399         break;
10400     default:
10401         MIPS_INVAL("cp1 cond branch");
10402         generate_exception_end(ctx, EXCP_RI);
10403         goto out;
10404     }
10405
10406     tcg_gen_trunc_i64_tl(bcond, t0);
10407
10408     ctx->btarget = btarget;
10409
10410     switch (delayslot_size) {
10411     case 2:
10412         ctx->hflags |= MIPS_HFLAG_BDS16;
10413         break;
10414     case 4:
10415         ctx->hflags |= MIPS_HFLAG_BDS32;
10416         break;
10417     }
10418
10419 out:
10420     tcg_temp_free_i64(t0);
10421 }
10422
10423 /* Coprocessor 1 (FPU) */
10424
10425 #define FOP(func, fmt) (((fmt) << 21) | (func))
10426
10427 enum fopcode {
10428     OPC_ADD_S = FOP(0, FMT_S),
10429     OPC_SUB_S = FOP(1, FMT_S),
10430     OPC_MUL_S = FOP(2, FMT_S),
10431     OPC_DIV_S = FOP(3, FMT_S),
10432     OPC_SQRT_S = FOP(4, FMT_S),
10433     OPC_ABS_S = FOP(5, FMT_S),
10434     OPC_MOV_S = FOP(6, FMT_S),
10435     OPC_NEG_S = FOP(7, FMT_S),
10436     OPC_ROUND_L_S = FOP(8, FMT_S),
10437     OPC_TRUNC_L_S = FOP(9, FMT_S),
10438     OPC_CEIL_L_S = FOP(10, FMT_S),
10439     OPC_FLOOR_L_S = FOP(11, FMT_S),
10440     OPC_ROUND_W_S = FOP(12, FMT_S),
10441     OPC_TRUNC_W_S = FOP(13, FMT_S),
10442     OPC_CEIL_W_S = FOP(14, FMT_S),
10443     OPC_FLOOR_W_S = FOP(15, FMT_S),
10444     OPC_SEL_S = FOP(16, FMT_S),
10445     OPC_MOVCF_S = FOP(17, FMT_S),
10446     OPC_MOVZ_S = FOP(18, FMT_S),
10447     OPC_MOVN_S = FOP(19, FMT_S),
10448     OPC_SELEQZ_S = FOP(20, FMT_S),
10449     OPC_RECIP_S = FOP(21, FMT_S),
10450     OPC_RSQRT_S = FOP(22, FMT_S),
10451     OPC_SELNEZ_S = FOP(23, FMT_S),
10452     OPC_MADDF_S = FOP(24, FMT_S),
10453     OPC_MSUBF_S = FOP(25, FMT_S),
10454     OPC_RINT_S = FOP(26, FMT_S),
10455     OPC_CLASS_S = FOP(27, FMT_S),
10456     OPC_MIN_S = FOP(28, FMT_S),
10457     OPC_RECIP2_S = FOP(28, FMT_S),
10458     OPC_MINA_S = FOP(29, FMT_S),
10459     OPC_RECIP1_S = FOP(29, FMT_S),
10460     OPC_MAX_S = FOP(30, FMT_S),
10461     OPC_RSQRT1_S = FOP(30, FMT_S),
10462     OPC_MAXA_S = FOP(31, FMT_S),
10463     OPC_RSQRT2_S = FOP(31, FMT_S),
10464     OPC_CVT_D_S = FOP(33, FMT_S),
10465     OPC_CVT_W_S = FOP(36, FMT_S),
10466     OPC_CVT_L_S = FOP(37, FMT_S),
10467     OPC_CVT_PS_S = FOP(38, FMT_S),
10468     OPC_CMP_F_S = FOP (48, FMT_S),
10469     OPC_CMP_UN_S = FOP (49, FMT_S),
10470     OPC_CMP_EQ_S = FOP (50, FMT_S),
10471     OPC_CMP_UEQ_S = FOP (51, FMT_S),
10472     OPC_CMP_OLT_S = FOP (52, FMT_S),
10473     OPC_CMP_ULT_S = FOP (53, FMT_S),
10474     OPC_CMP_OLE_S = FOP (54, FMT_S),
10475     OPC_CMP_ULE_S = FOP (55, FMT_S),
10476     OPC_CMP_SF_S = FOP (56, FMT_S),
10477     OPC_CMP_NGLE_S = FOP (57, FMT_S),
10478     OPC_CMP_SEQ_S = FOP (58, FMT_S),
10479     OPC_CMP_NGL_S = FOP (59, FMT_S),
10480     OPC_CMP_LT_S = FOP (60, FMT_S),
10481     OPC_CMP_NGE_S = FOP (61, FMT_S),
10482     OPC_CMP_LE_S = FOP (62, FMT_S),
10483     OPC_CMP_NGT_S = FOP (63, FMT_S),
10484
10485     OPC_ADD_D = FOP(0, FMT_D),
10486     OPC_SUB_D = FOP(1, FMT_D),
10487     OPC_MUL_D = FOP(2, FMT_D),
10488     OPC_DIV_D = FOP(3, FMT_D),
10489     OPC_SQRT_D = FOP(4, FMT_D),
10490     OPC_ABS_D = FOP(5, FMT_D),
10491     OPC_MOV_D = FOP(6, FMT_D),
10492     OPC_NEG_D = FOP(7, FMT_D),
10493     OPC_ROUND_L_D = FOP(8, FMT_D),
10494     OPC_TRUNC_L_D = FOP(9, FMT_D),
10495     OPC_CEIL_L_D = FOP(10, FMT_D),
10496     OPC_FLOOR_L_D = FOP(11, FMT_D),
10497     OPC_ROUND_W_D = FOP(12, FMT_D),
10498     OPC_TRUNC_W_D = FOP(13, FMT_D),
10499     OPC_CEIL_W_D = FOP(14, FMT_D),
10500     OPC_FLOOR_W_D = FOP(15, FMT_D),
10501     OPC_SEL_D = FOP(16, FMT_D),
10502     OPC_MOVCF_D = FOP(17, FMT_D),
10503     OPC_MOVZ_D = FOP(18, FMT_D),
10504     OPC_MOVN_D = FOP(19, FMT_D),
10505     OPC_SELEQZ_D = FOP(20, FMT_D),
10506     OPC_RECIP_D = FOP(21, FMT_D),
10507     OPC_RSQRT_D = FOP(22, FMT_D),
10508     OPC_SELNEZ_D = FOP(23, FMT_D),
10509     OPC_MADDF_D = FOP(24, FMT_D),
10510     OPC_MSUBF_D = FOP(25, FMT_D),
10511     OPC_RINT_D = FOP(26, FMT_D),
10512     OPC_CLASS_D = FOP(27, FMT_D),
10513     OPC_MIN_D = FOP(28, FMT_D),
10514     OPC_RECIP2_D = FOP(28, FMT_D),
10515     OPC_MINA_D = FOP(29, FMT_D),
10516     OPC_RECIP1_D = FOP(29, FMT_D),
10517     OPC_MAX_D = FOP(30, FMT_D),
10518     OPC_RSQRT1_D = FOP(30, FMT_D),
10519     OPC_MAXA_D = FOP(31, FMT_D),
10520     OPC_RSQRT2_D = FOP(31, FMT_D),
10521     OPC_CVT_S_D = FOP(32, FMT_D),
10522     OPC_CVT_W_D = FOP(36, FMT_D),
10523     OPC_CVT_L_D = FOP(37, FMT_D),
10524     OPC_CMP_F_D = FOP (48, FMT_D),
10525     OPC_CMP_UN_D = FOP (49, FMT_D),
10526     OPC_CMP_EQ_D = FOP (50, FMT_D),
10527     OPC_CMP_UEQ_D = FOP (51, FMT_D),
10528     OPC_CMP_OLT_D = FOP (52, FMT_D),
10529     OPC_CMP_ULT_D = FOP (53, FMT_D),
10530     OPC_CMP_OLE_D = FOP (54, FMT_D),
10531     OPC_CMP_ULE_D = FOP (55, FMT_D),
10532     OPC_CMP_SF_D = FOP (56, FMT_D),
10533     OPC_CMP_NGLE_D = FOP (57, FMT_D),
10534     OPC_CMP_SEQ_D = FOP (58, FMT_D),
10535     OPC_CMP_NGL_D = FOP (59, FMT_D),
10536     OPC_CMP_LT_D = FOP (60, FMT_D),
10537     OPC_CMP_NGE_D = FOP (61, FMT_D),
10538     OPC_CMP_LE_D = FOP (62, FMT_D),
10539     OPC_CMP_NGT_D = FOP (63, FMT_D),
10540
10541     OPC_CVT_S_W = FOP(32, FMT_W),
10542     OPC_CVT_D_W = FOP(33, FMT_W),
10543     OPC_CVT_S_L = FOP(32, FMT_L),
10544     OPC_CVT_D_L = FOP(33, FMT_L),
10545     OPC_CVT_PS_PW = FOP(38, FMT_W),
10546
10547     OPC_ADD_PS = FOP(0, FMT_PS),
10548     OPC_SUB_PS = FOP(1, FMT_PS),
10549     OPC_MUL_PS = FOP(2, FMT_PS),
10550     OPC_DIV_PS = FOP(3, FMT_PS),
10551     OPC_ABS_PS = FOP(5, FMT_PS),
10552     OPC_MOV_PS = FOP(6, FMT_PS),
10553     OPC_NEG_PS = FOP(7, FMT_PS),
10554     OPC_MOVCF_PS = FOP(17, FMT_PS),
10555     OPC_MOVZ_PS = FOP(18, FMT_PS),
10556     OPC_MOVN_PS = FOP(19, FMT_PS),
10557     OPC_ADDR_PS = FOP(24, FMT_PS),
10558     OPC_MULR_PS = FOP(26, FMT_PS),
10559     OPC_RECIP2_PS = FOP(28, FMT_PS),
10560     OPC_RECIP1_PS = FOP(29, FMT_PS),
10561     OPC_RSQRT1_PS = FOP(30, FMT_PS),
10562     OPC_RSQRT2_PS = FOP(31, FMT_PS),
10563
10564     OPC_CVT_S_PU = FOP(32, FMT_PS),
10565     OPC_CVT_PW_PS = FOP(36, FMT_PS),
10566     OPC_CVT_S_PL = FOP(40, FMT_PS),
10567     OPC_PLL_PS = FOP(44, FMT_PS),
10568     OPC_PLU_PS = FOP(45, FMT_PS),
10569     OPC_PUL_PS = FOP(46, FMT_PS),
10570     OPC_PUU_PS = FOP(47, FMT_PS),
10571     OPC_CMP_F_PS = FOP (48, FMT_PS),
10572     OPC_CMP_UN_PS = FOP (49, FMT_PS),
10573     OPC_CMP_EQ_PS = FOP (50, FMT_PS),
10574     OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
10575     OPC_CMP_OLT_PS = FOP (52, FMT_PS),
10576     OPC_CMP_ULT_PS = FOP (53, FMT_PS),
10577     OPC_CMP_OLE_PS = FOP (54, FMT_PS),
10578     OPC_CMP_ULE_PS = FOP (55, FMT_PS),
10579     OPC_CMP_SF_PS = FOP (56, FMT_PS),
10580     OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
10581     OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
10582     OPC_CMP_NGL_PS = FOP (59, FMT_PS),
10583     OPC_CMP_LT_PS = FOP (60, FMT_PS),
10584     OPC_CMP_NGE_PS = FOP (61, FMT_PS),
10585     OPC_CMP_LE_PS = FOP (62, FMT_PS),
10586     OPC_CMP_NGT_PS = FOP (63, FMT_PS),
10587 };
10588
10589 enum r6_f_cmp_op {
10590     R6_OPC_CMP_AF_S   = FOP(0, FMT_W),
10591     R6_OPC_CMP_UN_S   = FOP(1, FMT_W),
10592     R6_OPC_CMP_EQ_S   = FOP(2, FMT_W),
10593     R6_OPC_CMP_UEQ_S  = FOP(3, FMT_W),
10594     R6_OPC_CMP_LT_S   = FOP(4, FMT_W),
10595     R6_OPC_CMP_ULT_S  = FOP(5, FMT_W),
10596     R6_OPC_CMP_LE_S   = FOP(6, FMT_W),
10597     R6_OPC_CMP_ULE_S  = FOP(7, FMT_W),
10598     R6_OPC_CMP_SAF_S  = FOP(8, FMT_W),
10599     R6_OPC_CMP_SUN_S  = FOP(9, FMT_W),
10600     R6_OPC_CMP_SEQ_S  = FOP(10, FMT_W),
10601     R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
10602     R6_OPC_CMP_SLT_S  = FOP(12, FMT_W),
10603     R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
10604     R6_OPC_CMP_SLE_S  = FOP(14, FMT_W),
10605     R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
10606     R6_OPC_CMP_OR_S   = FOP(17, FMT_W),
10607     R6_OPC_CMP_UNE_S  = FOP(18, FMT_W),
10608     R6_OPC_CMP_NE_S   = FOP(19, FMT_W),
10609     R6_OPC_CMP_SOR_S  = FOP(25, FMT_W),
10610     R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
10611     R6_OPC_CMP_SNE_S  = FOP(27, FMT_W),
10612
10613     R6_OPC_CMP_AF_D   = FOP(0, FMT_L),
10614     R6_OPC_CMP_UN_D   = FOP(1, FMT_L),
10615     R6_OPC_CMP_EQ_D   = FOP(2, FMT_L),
10616     R6_OPC_CMP_UEQ_D  = FOP(3, FMT_L),
10617     R6_OPC_CMP_LT_D   = FOP(4, FMT_L),
10618     R6_OPC_CMP_ULT_D  = FOP(5, FMT_L),
10619     R6_OPC_CMP_LE_D   = FOP(6, FMT_L),
10620     R6_OPC_CMP_ULE_D  = FOP(7, FMT_L),
10621     R6_OPC_CMP_SAF_D  = FOP(8, FMT_L),
10622     R6_OPC_CMP_SUN_D  = FOP(9, FMT_L),
10623     R6_OPC_CMP_SEQ_D  = FOP(10, FMT_L),
10624     R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
10625     R6_OPC_CMP_SLT_D  = FOP(12, FMT_L),
10626     R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
10627     R6_OPC_CMP_SLE_D  = FOP(14, FMT_L),
10628     R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
10629     R6_OPC_CMP_OR_D   = FOP(17, FMT_L),
10630     R6_OPC_CMP_UNE_D  = FOP(18, FMT_L),
10631     R6_OPC_CMP_NE_D   = FOP(19, FMT_L),
10632     R6_OPC_CMP_SOR_D  = FOP(25, FMT_L),
10633     R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
10634     R6_OPC_CMP_SNE_D  = FOP(27, FMT_L),
10635 };
10636 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
10637 {
10638     TCGv t0 = tcg_temp_new();
10639
10640     switch (opc) {
10641     case OPC_MFC1:
10642         {
10643             TCGv_i32 fp0 = tcg_temp_new_i32();
10644
10645             gen_load_fpr32(ctx, fp0, fs);
10646             tcg_gen_ext_i32_tl(t0, fp0);
10647             tcg_temp_free_i32(fp0);
10648         }
10649         gen_store_gpr(t0, rt);
10650         break;
10651     case OPC_MTC1:
10652         gen_load_gpr(t0, rt);
10653         {
10654             TCGv_i32 fp0 = tcg_temp_new_i32();
10655
10656             tcg_gen_trunc_tl_i32(fp0, t0);
10657             gen_store_fpr32(ctx, fp0, fs);
10658             tcg_temp_free_i32(fp0);
10659         }
10660         break;
10661     case OPC_CFC1:
10662         gen_helper_1e0i(cfc1, t0, fs);
10663         gen_store_gpr(t0, rt);
10664         break;
10665     case OPC_CTC1:
10666         gen_load_gpr(t0, rt);
10667         save_cpu_state(ctx, 0);
10668         {
10669             TCGv_i32 fs_tmp = tcg_const_i32(fs);
10670
10671             gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10672             tcg_temp_free_i32(fs_tmp);
10673         }
10674         /* Stop translation as we may have changed hflags */
10675         ctx->base.is_jmp = DISAS_STOP;
10676         break;
10677 #if defined(TARGET_MIPS64)
10678     case OPC_DMFC1:
10679         gen_load_fpr64(ctx, t0, fs);
10680         gen_store_gpr(t0, rt);
10681         break;
10682     case OPC_DMTC1:
10683         gen_load_gpr(t0, rt);
10684         gen_store_fpr64(ctx, t0, fs);
10685         break;
10686 #endif
10687     case OPC_MFHC1:
10688         {
10689             TCGv_i32 fp0 = tcg_temp_new_i32();
10690
10691             gen_load_fpr32h(ctx, fp0, fs);
10692             tcg_gen_ext_i32_tl(t0, fp0);
10693             tcg_temp_free_i32(fp0);
10694         }
10695         gen_store_gpr(t0, rt);
10696         break;
10697     case OPC_MTHC1:
10698         gen_load_gpr(t0, rt);
10699         {
10700             TCGv_i32 fp0 = tcg_temp_new_i32();
10701
10702             tcg_gen_trunc_tl_i32(fp0, t0);
10703             gen_store_fpr32h(ctx, fp0, fs);
10704             tcg_temp_free_i32(fp0);
10705         }
10706         break;
10707     default:
10708         MIPS_INVAL("cp1 move");
10709         generate_exception_end(ctx, EXCP_RI);
10710         goto out;
10711     }
10712
10713  out:
10714     tcg_temp_free(t0);
10715 }
10716
10717 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
10718 {
10719     TCGLabel *l1;
10720     TCGCond cond;
10721     TCGv_i32 t0;
10722
10723     if (rd == 0) {
10724         /* Treat as NOP. */
10725         return;
10726     }
10727
10728     if (tf)
10729         cond = TCG_COND_EQ;
10730     else
10731         cond = TCG_COND_NE;
10732
10733     l1 = gen_new_label();
10734     t0 = tcg_temp_new_i32();
10735     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10736     tcg_gen_brcondi_i32(cond, t0, 0, l1);
10737     tcg_temp_free_i32(t0);
10738     if (rs == 0) {
10739         tcg_gen_movi_tl(cpu_gpr[rd], 0);
10740     } else {
10741         tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
10742     }
10743     gen_set_label(l1);
10744 }
10745
10746 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
10747                                int tf)
10748 {
10749     int cond;
10750     TCGv_i32 t0 = tcg_temp_new_i32();
10751     TCGLabel *l1 = gen_new_label();
10752
10753     if (tf)
10754         cond = TCG_COND_EQ;
10755     else
10756         cond = TCG_COND_NE;
10757
10758     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10759     tcg_gen_brcondi_i32(cond, t0, 0, l1);
10760     gen_load_fpr32(ctx, t0, fs);
10761     gen_store_fpr32(ctx, t0, fd);
10762     gen_set_label(l1);
10763     tcg_temp_free_i32(t0);
10764 }
10765
10766 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
10767 {
10768     int cond;
10769     TCGv_i32 t0 = tcg_temp_new_i32();
10770     TCGv_i64 fp0;
10771     TCGLabel *l1 = gen_new_label();
10772
10773     if (tf)
10774         cond = TCG_COND_EQ;
10775     else
10776         cond = TCG_COND_NE;
10777
10778     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10779     tcg_gen_brcondi_i32(cond, t0, 0, l1);
10780     tcg_temp_free_i32(t0);
10781     fp0 = tcg_temp_new_i64();
10782     gen_load_fpr64(ctx, fp0, fs);
10783     gen_store_fpr64(ctx, fp0, fd);
10784     tcg_temp_free_i64(fp0);
10785     gen_set_label(l1);
10786 }
10787
10788 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
10789                                 int cc, int tf)
10790 {
10791     int cond;
10792     TCGv_i32 t0 = tcg_temp_new_i32();
10793     TCGLabel *l1 = gen_new_label();
10794     TCGLabel *l2 = gen_new_label();
10795
10796     if (tf)
10797         cond = TCG_COND_EQ;
10798     else
10799         cond = TCG_COND_NE;
10800
10801     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10802     tcg_gen_brcondi_i32(cond, t0, 0, l1);
10803     gen_load_fpr32(ctx, t0, fs);
10804     gen_store_fpr32(ctx, t0, fd);
10805     gen_set_label(l1);
10806
10807     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
10808     tcg_gen_brcondi_i32(cond, t0, 0, l2);
10809     gen_load_fpr32h(ctx, t0, fs);
10810     gen_store_fpr32h(ctx, t0, fd);
10811     tcg_temp_free_i32(t0);
10812     gen_set_label(l2);
10813 }
10814
10815 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10816                       int fs)
10817 {
10818     TCGv_i32 t1 = tcg_const_i32(0);
10819     TCGv_i32 fp0 = tcg_temp_new_i32();
10820     TCGv_i32 fp1 = tcg_temp_new_i32();
10821     TCGv_i32 fp2 = tcg_temp_new_i32();
10822     gen_load_fpr32(ctx, fp0, fd);
10823     gen_load_fpr32(ctx, fp1, ft);
10824     gen_load_fpr32(ctx, fp2, fs);
10825
10826     switch (op1) {
10827     case OPC_SEL_S:
10828         tcg_gen_andi_i32(fp0, fp0, 1);
10829         tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10830         break;
10831     case OPC_SELEQZ_S:
10832         tcg_gen_andi_i32(fp1, fp1, 1);
10833         tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10834         break;
10835     case OPC_SELNEZ_S:
10836         tcg_gen_andi_i32(fp1, fp1, 1);
10837         tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10838         break;
10839     default:
10840         MIPS_INVAL("gen_sel_s");
10841         generate_exception_end(ctx, EXCP_RI);
10842         break;
10843     }
10844
10845     gen_store_fpr32(ctx, fp0, fd);
10846     tcg_temp_free_i32(fp2);
10847     tcg_temp_free_i32(fp1);
10848     tcg_temp_free_i32(fp0);
10849     tcg_temp_free_i32(t1);
10850 }
10851
10852 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10853                       int fs)
10854 {
10855     TCGv_i64 t1 = tcg_const_i64(0);
10856     TCGv_i64 fp0 = tcg_temp_new_i64();
10857     TCGv_i64 fp1 = tcg_temp_new_i64();
10858     TCGv_i64 fp2 = tcg_temp_new_i64();
10859     gen_load_fpr64(ctx, fp0, fd);
10860     gen_load_fpr64(ctx, fp1, ft);
10861     gen_load_fpr64(ctx, fp2, fs);
10862
10863     switch (op1) {
10864     case OPC_SEL_D:
10865         tcg_gen_andi_i64(fp0, fp0, 1);
10866         tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10867         break;
10868     case OPC_SELEQZ_D:
10869         tcg_gen_andi_i64(fp1, fp1, 1);
10870         tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10871         break;
10872     case OPC_SELNEZ_D:
10873         tcg_gen_andi_i64(fp1, fp1, 1);
10874         tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10875         break;
10876     default:
10877         MIPS_INVAL("gen_sel_d");
10878         generate_exception_end(ctx, EXCP_RI);
10879         break;
10880     }
10881
10882     gen_store_fpr64(ctx, fp0, fd);
10883     tcg_temp_free_i64(fp2);
10884     tcg_temp_free_i64(fp1);
10885     tcg_temp_free_i64(fp0);
10886     tcg_temp_free_i64(t1);
10887 }
10888
10889 static void gen_farith (DisasContext *ctx, enum fopcode op1,
10890                         int ft, int fs, int fd, int cc)
10891 {
10892     uint32_t func = ctx->opcode & 0x3f;
10893     switch (op1) {
10894     case OPC_ADD_S:
10895         {
10896             TCGv_i32 fp0 = tcg_temp_new_i32();
10897             TCGv_i32 fp1 = tcg_temp_new_i32();
10898
10899             gen_load_fpr32(ctx, fp0, fs);
10900             gen_load_fpr32(ctx, fp1, ft);
10901             gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
10902             tcg_temp_free_i32(fp1);
10903             gen_store_fpr32(ctx, fp0, fd);
10904             tcg_temp_free_i32(fp0);
10905         }
10906         break;
10907     case OPC_SUB_S:
10908         {
10909             TCGv_i32 fp0 = tcg_temp_new_i32();
10910             TCGv_i32 fp1 = tcg_temp_new_i32();
10911
10912             gen_load_fpr32(ctx, fp0, fs);
10913             gen_load_fpr32(ctx, fp1, ft);
10914             gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
10915             tcg_temp_free_i32(fp1);
10916             gen_store_fpr32(ctx, fp0, fd);
10917             tcg_temp_free_i32(fp0);
10918         }
10919         break;
10920     case OPC_MUL_S:
10921         {
10922             TCGv_i32 fp0 = tcg_temp_new_i32();
10923             TCGv_i32 fp1 = tcg_temp_new_i32();
10924
10925             gen_load_fpr32(ctx, fp0, fs);
10926             gen_load_fpr32(ctx, fp1, ft);
10927             gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
10928             tcg_temp_free_i32(fp1);
10929             gen_store_fpr32(ctx, fp0, fd);
10930             tcg_temp_free_i32(fp0);
10931         }
10932         break;
10933     case OPC_DIV_S:
10934         {
10935             TCGv_i32 fp0 = tcg_temp_new_i32();
10936             TCGv_i32 fp1 = tcg_temp_new_i32();
10937
10938             gen_load_fpr32(ctx, fp0, fs);
10939             gen_load_fpr32(ctx, fp1, ft);
10940             gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
10941             tcg_temp_free_i32(fp1);
10942             gen_store_fpr32(ctx, fp0, fd);
10943             tcg_temp_free_i32(fp0);
10944         }
10945         break;
10946     case OPC_SQRT_S:
10947         {
10948             TCGv_i32 fp0 = tcg_temp_new_i32();
10949
10950             gen_load_fpr32(ctx, fp0, fs);
10951             gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
10952             gen_store_fpr32(ctx, fp0, fd);
10953             tcg_temp_free_i32(fp0);
10954         }
10955         break;
10956     case OPC_ABS_S:
10957         {
10958             TCGv_i32 fp0 = tcg_temp_new_i32();
10959
10960             gen_load_fpr32(ctx, fp0, fs);
10961             if (ctx->abs2008) {
10962                 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
10963             } else {
10964                 gen_helper_float_abs_s(fp0, fp0);
10965             }
10966             gen_store_fpr32(ctx, fp0, fd);
10967             tcg_temp_free_i32(fp0);
10968         }
10969         break;
10970     case OPC_MOV_S:
10971         {
10972             TCGv_i32 fp0 = tcg_temp_new_i32();
10973
10974             gen_load_fpr32(ctx, fp0, fs);
10975             gen_store_fpr32(ctx, fp0, fd);
10976             tcg_temp_free_i32(fp0);
10977         }
10978         break;
10979     case OPC_NEG_S:
10980         {
10981             TCGv_i32 fp0 = tcg_temp_new_i32();
10982
10983             gen_load_fpr32(ctx, fp0, fs);
10984             if (ctx->abs2008) {
10985                 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
10986             } else {
10987                 gen_helper_float_chs_s(fp0, fp0);
10988             }
10989             gen_store_fpr32(ctx, fp0, fd);
10990             tcg_temp_free_i32(fp0);
10991         }
10992         break;
10993     case OPC_ROUND_L_S:
10994         check_cp1_64bitmode(ctx);
10995         {
10996             TCGv_i32 fp32 = tcg_temp_new_i32();
10997             TCGv_i64 fp64 = tcg_temp_new_i64();
10998
10999             gen_load_fpr32(ctx, fp32, fs);
11000             if (ctx->nan2008) {
11001                 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
11002             } else {
11003                 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
11004             }
11005             tcg_temp_free_i32(fp32);
11006             gen_store_fpr64(ctx, fp64, fd);
11007             tcg_temp_free_i64(fp64);
11008         }
11009         break;
11010     case OPC_TRUNC_L_S:
11011         check_cp1_64bitmode(ctx);
11012         {
11013             TCGv_i32 fp32 = tcg_temp_new_i32();
11014             TCGv_i64 fp64 = tcg_temp_new_i64();
11015
11016             gen_load_fpr32(ctx, fp32, fs);
11017             if (ctx->nan2008) {
11018                 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
11019             } else {
11020                 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
11021             }
11022             tcg_temp_free_i32(fp32);
11023             gen_store_fpr64(ctx, fp64, fd);
11024             tcg_temp_free_i64(fp64);
11025         }
11026         break;
11027     case OPC_CEIL_L_S:
11028         check_cp1_64bitmode(ctx);
11029         {
11030             TCGv_i32 fp32 = tcg_temp_new_i32();
11031             TCGv_i64 fp64 = tcg_temp_new_i64();
11032
11033             gen_load_fpr32(ctx, fp32, fs);
11034             if (ctx->nan2008) {
11035                 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
11036             } else {
11037                 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
11038             }
11039             tcg_temp_free_i32(fp32);
11040             gen_store_fpr64(ctx, fp64, fd);
11041             tcg_temp_free_i64(fp64);
11042         }
11043         break;
11044     case OPC_FLOOR_L_S:
11045         check_cp1_64bitmode(ctx);
11046         {
11047             TCGv_i32 fp32 = tcg_temp_new_i32();
11048             TCGv_i64 fp64 = tcg_temp_new_i64();
11049
11050             gen_load_fpr32(ctx, fp32, fs);
11051             if (ctx->nan2008) {
11052                 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
11053             } else {
11054                 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
11055             }
11056             tcg_temp_free_i32(fp32);
11057             gen_store_fpr64(ctx, fp64, fd);
11058             tcg_temp_free_i64(fp64);
11059         }
11060         break;
11061     case OPC_ROUND_W_S:
11062         {
11063             TCGv_i32 fp0 = tcg_temp_new_i32();
11064
11065             gen_load_fpr32(ctx, fp0, fs);
11066             if (ctx->nan2008) {
11067                 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
11068             } else {
11069                 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
11070             }
11071             gen_store_fpr32(ctx, fp0, fd);
11072             tcg_temp_free_i32(fp0);
11073         }
11074         break;
11075     case OPC_TRUNC_W_S:
11076         {
11077             TCGv_i32 fp0 = tcg_temp_new_i32();
11078
11079             gen_load_fpr32(ctx, fp0, fs);
11080             if (ctx->nan2008) {
11081                 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
11082             } else {
11083                 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
11084             }
11085             gen_store_fpr32(ctx, fp0, fd);
11086             tcg_temp_free_i32(fp0);
11087         }
11088         break;
11089     case OPC_CEIL_W_S:
11090         {
11091             TCGv_i32 fp0 = tcg_temp_new_i32();
11092
11093             gen_load_fpr32(ctx, fp0, fs);
11094             if (ctx->nan2008) {
11095                 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
11096             } else {
11097                 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
11098             }
11099             gen_store_fpr32(ctx, fp0, fd);
11100             tcg_temp_free_i32(fp0);
11101         }
11102         break;
11103     case OPC_FLOOR_W_S:
11104         {
11105             TCGv_i32 fp0 = tcg_temp_new_i32();
11106
11107             gen_load_fpr32(ctx, fp0, fs);
11108             if (ctx->nan2008) {
11109                 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
11110             } else {
11111                 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
11112             }
11113             gen_store_fpr32(ctx, fp0, fd);
11114             tcg_temp_free_i32(fp0);
11115         }
11116         break;
11117     case OPC_SEL_S:
11118         check_insn(ctx, ISA_MIPS32R6);
11119         gen_sel_s(ctx, op1, fd, ft, fs);
11120         break;
11121     case OPC_SELEQZ_S:
11122         check_insn(ctx, ISA_MIPS32R6);
11123         gen_sel_s(ctx, op1, fd, ft, fs);
11124         break;
11125     case OPC_SELNEZ_S:
11126         check_insn(ctx, ISA_MIPS32R6);
11127         gen_sel_s(ctx, op1, fd, ft, fs);
11128         break;
11129     case OPC_MOVCF_S:
11130         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11131         gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11132         break;
11133     case OPC_MOVZ_S:
11134         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11135         {
11136             TCGLabel *l1 = gen_new_label();
11137             TCGv_i32 fp0;
11138
11139             if (ft != 0) {
11140                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11141             }
11142             fp0 = tcg_temp_new_i32();
11143             gen_load_fpr32(ctx, fp0, fs);
11144             gen_store_fpr32(ctx, fp0, fd);
11145             tcg_temp_free_i32(fp0);
11146             gen_set_label(l1);
11147         }
11148         break;
11149     case OPC_MOVN_S:
11150         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11151         {
11152             TCGLabel *l1 = gen_new_label();
11153             TCGv_i32 fp0;
11154
11155             if (ft != 0) {
11156                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11157                 fp0 = tcg_temp_new_i32();
11158                 gen_load_fpr32(ctx, fp0, fs);
11159                 gen_store_fpr32(ctx, fp0, fd);
11160                 tcg_temp_free_i32(fp0);
11161                 gen_set_label(l1);
11162             }
11163         }
11164         break;
11165     case OPC_RECIP_S:
11166         {
11167             TCGv_i32 fp0 = tcg_temp_new_i32();
11168
11169             gen_load_fpr32(ctx, fp0, fs);
11170             gen_helper_float_recip_s(fp0, cpu_env, fp0);
11171             gen_store_fpr32(ctx, fp0, fd);
11172             tcg_temp_free_i32(fp0);
11173         }
11174         break;
11175     case OPC_RSQRT_S:
11176         {
11177             TCGv_i32 fp0 = tcg_temp_new_i32();
11178
11179             gen_load_fpr32(ctx, fp0, fs);
11180             gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
11181             gen_store_fpr32(ctx, fp0, fd);
11182             tcg_temp_free_i32(fp0);
11183         }
11184         break;
11185     case OPC_MADDF_S:
11186         check_insn(ctx, ISA_MIPS32R6);
11187         {
11188             TCGv_i32 fp0 = tcg_temp_new_i32();
11189             TCGv_i32 fp1 = tcg_temp_new_i32();
11190             TCGv_i32 fp2 = tcg_temp_new_i32();
11191             gen_load_fpr32(ctx, fp0, fs);
11192             gen_load_fpr32(ctx, fp1, ft);
11193             gen_load_fpr32(ctx, fp2, fd);
11194             gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
11195             gen_store_fpr32(ctx, fp2, fd);
11196             tcg_temp_free_i32(fp2);
11197             tcg_temp_free_i32(fp1);
11198             tcg_temp_free_i32(fp0);
11199         }
11200         break;
11201     case OPC_MSUBF_S:
11202         check_insn(ctx, ISA_MIPS32R6);
11203         {
11204             TCGv_i32 fp0 = tcg_temp_new_i32();
11205             TCGv_i32 fp1 = tcg_temp_new_i32();
11206             TCGv_i32 fp2 = tcg_temp_new_i32();
11207             gen_load_fpr32(ctx, fp0, fs);
11208             gen_load_fpr32(ctx, fp1, ft);
11209             gen_load_fpr32(ctx, fp2, fd);
11210             gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
11211             gen_store_fpr32(ctx, fp2, fd);
11212             tcg_temp_free_i32(fp2);
11213             tcg_temp_free_i32(fp1);
11214             tcg_temp_free_i32(fp0);
11215         }
11216         break;
11217     case OPC_RINT_S:
11218         check_insn(ctx, ISA_MIPS32R6);
11219         {
11220             TCGv_i32 fp0 = tcg_temp_new_i32();
11221             gen_load_fpr32(ctx, fp0, fs);
11222             gen_helper_float_rint_s(fp0, cpu_env, fp0);
11223             gen_store_fpr32(ctx, fp0, fd);
11224             tcg_temp_free_i32(fp0);
11225         }
11226         break;
11227     case OPC_CLASS_S:
11228         check_insn(ctx, ISA_MIPS32R6);
11229         {
11230             TCGv_i32 fp0 = tcg_temp_new_i32();
11231             gen_load_fpr32(ctx, fp0, fs);
11232             gen_helper_float_class_s(fp0, cpu_env, fp0);
11233             gen_store_fpr32(ctx, fp0, fd);
11234             tcg_temp_free_i32(fp0);
11235         }
11236         break;
11237     case OPC_MIN_S: /* OPC_RECIP2_S */
11238         if (ctx->insn_flags & ISA_MIPS32R6) {
11239             /* OPC_MIN_S */
11240             TCGv_i32 fp0 = tcg_temp_new_i32();
11241             TCGv_i32 fp1 = tcg_temp_new_i32();
11242             TCGv_i32 fp2 = tcg_temp_new_i32();
11243             gen_load_fpr32(ctx, fp0, fs);
11244             gen_load_fpr32(ctx, fp1, ft);
11245             gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
11246             gen_store_fpr32(ctx, fp2, fd);
11247             tcg_temp_free_i32(fp2);
11248             tcg_temp_free_i32(fp1);
11249             tcg_temp_free_i32(fp0);
11250         } else {
11251             /* OPC_RECIP2_S */
11252             check_cp1_64bitmode(ctx);
11253             {
11254                 TCGv_i32 fp0 = tcg_temp_new_i32();
11255                 TCGv_i32 fp1 = tcg_temp_new_i32();
11256
11257                 gen_load_fpr32(ctx, fp0, fs);
11258                 gen_load_fpr32(ctx, fp1, ft);
11259                 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
11260                 tcg_temp_free_i32(fp1);
11261                 gen_store_fpr32(ctx, fp0, fd);
11262                 tcg_temp_free_i32(fp0);
11263             }
11264         }
11265         break;
11266     case OPC_MINA_S: /* OPC_RECIP1_S */
11267         if (ctx->insn_flags & ISA_MIPS32R6) {
11268             /* OPC_MINA_S */
11269             TCGv_i32 fp0 = tcg_temp_new_i32();
11270             TCGv_i32 fp1 = tcg_temp_new_i32();
11271             TCGv_i32 fp2 = tcg_temp_new_i32();
11272             gen_load_fpr32(ctx, fp0, fs);
11273             gen_load_fpr32(ctx, fp1, ft);
11274             gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
11275             gen_store_fpr32(ctx, fp2, fd);
11276             tcg_temp_free_i32(fp2);
11277             tcg_temp_free_i32(fp1);
11278             tcg_temp_free_i32(fp0);
11279         } else {
11280             /* OPC_RECIP1_S */
11281             check_cp1_64bitmode(ctx);
11282             {
11283                 TCGv_i32 fp0 = tcg_temp_new_i32();
11284
11285                 gen_load_fpr32(ctx, fp0, fs);
11286                 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
11287                 gen_store_fpr32(ctx, fp0, fd);
11288                 tcg_temp_free_i32(fp0);
11289             }
11290         }
11291         break;
11292     case OPC_MAX_S: /* OPC_RSQRT1_S */
11293         if (ctx->insn_flags & ISA_MIPS32R6) {
11294             /* OPC_MAX_S */
11295             TCGv_i32 fp0 = tcg_temp_new_i32();
11296             TCGv_i32 fp1 = tcg_temp_new_i32();
11297             gen_load_fpr32(ctx, fp0, fs);
11298             gen_load_fpr32(ctx, fp1, ft);
11299             gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
11300             gen_store_fpr32(ctx, fp1, fd);
11301             tcg_temp_free_i32(fp1);
11302             tcg_temp_free_i32(fp0);
11303         } else {
11304             /* OPC_RSQRT1_S */
11305             check_cp1_64bitmode(ctx);
11306             {
11307                 TCGv_i32 fp0 = tcg_temp_new_i32();
11308
11309                 gen_load_fpr32(ctx, fp0, fs);
11310                 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
11311                 gen_store_fpr32(ctx, fp0, fd);
11312                 tcg_temp_free_i32(fp0);
11313             }
11314         }
11315         break;
11316     case OPC_MAXA_S: /* OPC_RSQRT2_S */
11317         if (ctx->insn_flags & ISA_MIPS32R6) {
11318             /* OPC_MAXA_S */
11319             TCGv_i32 fp0 = tcg_temp_new_i32();
11320             TCGv_i32 fp1 = tcg_temp_new_i32();
11321             gen_load_fpr32(ctx, fp0, fs);
11322             gen_load_fpr32(ctx, fp1, ft);
11323             gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
11324             gen_store_fpr32(ctx, fp1, fd);
11325             tcg_temp_free_i32(fp1);
11326             tcg_temp_free_i32(fp0);
11327         } else {
11328             /* OPC_RSQRT2_S */
11329             check_cp1_64bitmode(ctx);
11330             {
11331                 TCGv_i32 fp0 = tcg_temp_new_i32();
11332                 TCGv_i32 fp1 = tcg_temp_new_i32();
11333
11334                 gen_load_fpr32(ctx, fp0, fs);
11335                 gen_load_fpr32(ctx, fp1, ft);
11336                 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
11337                 tcg_temp_free_i32(fp1);
11338                 gen_store_fpr32(ctx, fp0, fd);
11339                 tcg_temp_free_i32(fp0);
11340             }
11341         }
11342         break;
11343     case OPC_CVT_D_S:
11344         check_cp1_registers(ctx, fd);
11345         {
11346             TCGv_i32 fp32 = tcg_temp_new_i32();
11347             TCGv_i64 fp64 = tcg_temp_new_i64();
11348
11349             gen_load_fpr32(ctx, fp32, fs);
11350             gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
11351             tcg_temp_free_i32(fp32);
11352             gen_store_fpr64(ctx, fp64, fd);
11353             tcg_temp_free_i64(fp64);
11354         }
11355         break;
11356     case OPC_CVT_W_S:
11357         {
11358             TCGv_i32 fp0 = tcg_temp_new_i32();
11359
11360             gen_load_fpr32(ctx, fp0, fs);
11361             if (ctx->nan2008) {
11362                 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
11363             } else {
11364                 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
11365             }
11366             gen_store_fpr32(ctx, fp0, fd);
11367             tcg_temp_free_i32(fp0);
11368         }
11369         break;
11370     case OPC_CVT_L_S:
11371         check_cp1_64bitmode(ctx);
11372         {
11373             TCGv_i32 fp32 = tcg_temp_new_i32();
11374             TCGv_i64 fp64 = tcg_temp_new_i64();
11375
11376             gen_load_fpr32(ctx, fp32, fs);
11377             if (ctx->nan2008) {
11378                 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
11379             } else {
11380                 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
11381             }
11382             tcg_temp_free_i32(fp32);
11383             gen_store_fpr64(ctx, fp64, fd);
11384             tcg_temp_free_i64(fp64);
11385         }
11386         break;
11387     case OPC_CVT_PS_S:
11388         check_ps(ctx);
11389         {
11390             TCGv_i64 fp64 = tcg_temp_new_i64();
11391             TCGv_i32 fp32_0 = tcg_temp_new_i32();
11392             TCGv_i32 fp32_1 = tcg_temp_new_i32();
11393
11394             gen_load_fpr32(ctx, fp32_0, fs);
11395             gen_load_fpr32(ctx, fp32_1, ft);
11396             tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
11397             tcg_temp_free_i32(fp32_1);
11398             tcg_temp_free_i32(fp32_0);
11399             gen_store_fpr64(ctx, fp64, fd);
11400             tcg_temp_free_i64(fp64);
11401         }
11402         break;
11403     case OPC_CMP_F_S:
11404     case OPC_CMP_UN_S:
11405     case OPC_CMP_EQ_S:
11406     case OPC_CMP_UEQ_S:
11407     case OPC_CMP_OLT_S:
11408     case OPC_CMP_ULT_S:
11409     case OPC_CMP_OLE_S:
11410     case OPC_CMP_ULE_S:
11411     case OPC_CMP_SF_S:
11412     case OPC_CMP_NGLE_S:
11413     case OPC_CMP_SEQ_S:
11414     case OPC_CMP_NGL_S:
11415     case OPC_CMP_LT_S:
11416     case OPC_CMP_NGE_S:
11417     case OPC_CMP_LE_S:
11418     case OPC_CMP_NGT_S:
11419         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11420         if (ctx->opcode & (1 << 6)) {
11421             gen_cmpabs_s(ctx, func-48, ft, fs, cc);
11422         } else {
11423             gen_cmp_s(ctx, func-48, ft, fs, cc);
11424         }
11425         break;
11426     case OPC_ADD_D:
11427         check_cp1_registers(ctx, fs | ft | fd);
11428         {
11429             TCGv_i64 fp0 = tcg_temp_new_i64();
11430             TCGv_i64 fp1 = tcg_temp_new_i64();
11431
11432             gen_load_fpr64(ctx, fp0, fs);
11433             gen_load_fpr64(ctx, fp1, ft);
11434             gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
11435             tcg_temp_free_i64(fp1);
11436             gen_store_fpr64(ctx, fp0, fd);
11437             tcg_temp_free_i64(fp0);
11438         }
11439         break;
11440     case OPC_SUB_D:
11441         check_cp1_registers(ctx, fs | ft | fd);
11442         {
11443             TCGv_i64 fp0 = tcg_temp_new_i64();
11444             TCGv_i64 fp1 = tcg_temp_new_i64();
11445
11446             gen_load_fpr64(ctx, fp0, fs);
11447             gen_load_fpr64(ctx, fp1, ft);
11448             gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
11449             tcg_temp_free_i64(fp1);
11450             gen_store_fpr64(ctx, fp0, fd);
11451             tcg_temp_free_i64(fp0);
11452         }
11453         break;
11454     case OPC_MUL_D:
11455         check_cp1_registers(ctx, fs | ft | fd);
11456         {
11457             TCGv_i64 fp0 = tcg_temp_new_i64();
11458             TCGv_i64 fp1 = tcg_temp_new_i64();
11459
11460             gen_load_fpr64(ctx, fp0, fs);
11461             gen_load_fpr64(ctx, fp1, ft);
11462             gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
11463             tcg_temp_free_i64(fp1);
11464             gen_store_fpr64(ctx, fp0, fd);
11465             tcg_temp_free_i64(fp0);
11466         }
11467         break;
11468     case OPC_DIV_D:
11469         check_cp1_registers(ctx, fs | ft | fd);
11470         {
11471             TCGv_i64 fp0 = tcg_temp_new_i64();
11472             TCGv_i64 fp1 = tcg_temp_new_i64();
11473
11474             gen_load_fpr64(ctx, fp0, fs);
11475             gen_load_fpr64(ctx, fp1, ft);
11476             gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
11477             tcg_temp_free_i64(fp1);
11478             gen_store_fpr64(ctx, fp0, fd);
11479             tcg_temp_free_i64(fp0);
11480         }
11481         break;
11482     case OPC_SQRT_D:
11483         check_cp1_registers(ctx, fs | fd);
11484         {
11485             TCGv_i64 fp0 = tcg_temp_new_i64();
11486
11487             gen_load_fpr64(ctx, fp0, fs);
11488             gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
11489             gen_store_fpr64(ctx, fp0, fd);
11490             tcg_temp_free_i64(fp0);
11491         }
11492         break;
11493     case OPC_ABS_D:
11494         check_cp1_registers(ctx, fs | fd);
11495         {
11496             TCGv_i64 fp0 = tcg_temp_new_i64();
11497
11498             gen_load_fpr64(ctx, fp0, fs);
11499             if (ctx->abs2008) {
11500                 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
11501             } else {
11502                 gen_helper_float_abs_d(fp0, fp0);
11503             }
11504             gen_store_fpr64(ctx, fp0, fd);
11505             tcg_temp_free_i64(fp0);
11506         }
11507         break;
11508     case OPC_MOV_D:
11509         check_cp1_registers(ctx, fs | fd);
11510         {
11511             TCGv_i64 fp0 = tcg_temp_new_i64();
11512
11513             gen_load_fpr64(ctx, fp0, fs);
11514             gen_store_fpr64(ctx, fp0, fd);
11515             tcg_temp_free_i64(fp0);
11516         }
11517         break;
11518     case OPC_NEG_D:
11519         check_cp1_registers(ctx, fs | fd);
11520         {
11521             TCGv_i64 fp0 = tcg_temp_new_i64();
11522
11523             gen_load_fpr64(ctx, fp0, fs);
11524             if (ctx->abs2008) {
11525                 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
11526             } else {
11527                 gen_helper_float_chs_d(fp0, fp0);
11528             }
11529             gen_store_fpr64(ctx, fp0, fd);
11530             tcg_temp_free_i64(fp0);
11531         }
11532         break;
11533     case OPC_ROUND_L_D:
11534         check_cp1_64bitmode(ctx);
11535         {
11536             TCGv_i64 fp0 = tcg_temp_new_i64();
11537
11538             gen_load_fpr64(ctx, fp0, fs);
11539             if (ctx->nan2008) {
11540                 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
11541             } else {
11542                 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
11543             }
11544             gen_store_fpr64(ctx, fp0, fd);
11545             tcg_temp_free_i64(fp0);
11546         }
11547         break;
11548     case OPC_TRUNC_L_D:
11549         check_cp1_64bitmode(ctx);
11550         {
11551             TCGv_i64 fp0 = tcg_temp_new_i64();
11552
11553             gen_load_fpr64(ctx, fp0, fs);
11554             if (ctx->nan2008) {
11555                 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
11556             } else {
11557                 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
11558             }
11559             gen_store_fpr64(ctx, fp0, fd);
11560             tcg_temp_free_i64(fp0);
11561         }
11562         break;
11563     case OPC_CEIL_L_D:
11564         check_cp1_64bitmode(ctx);
11565         {
11566             TCGv_i64 fp0 = tcg_temp_new_i64();
11567
11568             gen_load_fpr64(ctx, fp0, fs);
11569             if (ctx->nan2008) {
11570                 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
11571             } else {
11572                 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
11573             }
11574             gen_store_fpr64(ctx, fp0, fd);
11575             tcg_temp_free_i64(fp0);
11576         }
11577         break;
11578     case OPC_FLOOR_L_D:
11579         check_cp1_64bitmode(ctx);
11580         {
11581             TCGv_i64 fp0 = tcg_temp_new_i64();
11582
11583             gen_load_fpr64(ctx, fp0, fs);
11584             if (ctx->nan2008) {
11585                 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
11586             } else {
11587                 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
11588             }
11589             gen_store_fpr64(ctx, fp0, fd);
11590             tcg_temp_free_i64(fp0);
11591         }
11592         break;
11593     case OPC_ROUND_W_D:
11594         check_cp1_registers(ctx, fs);
11595         {
11596             TCGv_i32 fp32 = tcg_temp_new_i32();
11597             TCGv_i64 fp64 = tcg_temp_new_i64();
11598
11599             gen_load_fpr64(ctx, fp64, fs);
11600             if (ctx->nan2008) {
11601                 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
11602             } else {
11603                 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
11604             }
11605             tcg_temp_free_i64(fp64);
11606             gen_store_fpr32(ctx, fp32, fd);
11607             tcg_temp_free_i32(fp32);
11608         }
11609         break;
11610     case OPC_TRUNC_W_D:
11611         check_cp1_registers(ctx, fs);
11612         {
11613             TCGv_i32 fp32 = tcg_temp_new_i32();
11614             TCGv_i64 fp64 = tcg_temp_new_i64();
11615
11616             gen_load_fpr64(ctx, fp64, fs);
11617             if (ctx->nan2008) {
11618                 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
11619             } else {
11620                 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
11621             }
11622             tcg_temp_free_i64(fp64);
11623             gen_store_fpr32(ctx, fp32, fd);
11624             tcg_temp_free_i32(fp32);
11625         }
11626         break;
11627     case OPC_CEIL_W_D:
11628         check_cp1_registers(ctx, fs);
11629         {
11630             TCGv_i32 fp32 = tcg_temp_new_i32();
11631             TCGv_i64 fp64 = tcg_temp_new_i64();
11632
11633             gen_load_fpr64(ctx, fp64, fs);
11634             if (ctx->nan2008) {
11635                 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
11636             } else {
11637                 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
11638             }
11639             tcg_temp_free_i64(fp64);
11640             gen_store_fpr32(ctx, fp32, fd);
11641             tcg_temp_free_i32(fp32);
11642         }
11643         break;
11644     case OPC_FLOOR_W_D:
11645         check_cp1_registers(ctx, fs);
11646         {
11647             TCGv_i32 fp32 = tcg_temp_new_i32();
11648             TCGv_i64 fp64 = tcg_temp_new_i64();
11649
11650             gen_load_fpr64(ctx, fp64, fs);
11651             if (ctx->nan2008) {
11652                 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
11653             } else {
11654                 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
11655             }
11656             tcg_temp_free_i64(fp64);
11657             gen_store_fpr32(ctx, fp32, fd);
11658             tcg_temp_free_i32(fp32);
11659         }
11660         break;
11661     case OPC_SEL_D:
11662         check_insn(ctx, ISA_MIPS32R6);
11663         gen_sel_d(ctx, op1, fd, ft, fs);
11664         break;
11665     case OPC_SELEQZ_D:
11666         check_insn(ctx, ISA_MIPS32R6);
11667         gen_sel_d(ctx, op1, fd, ft, fs);
11668         break;
11669     case OPC_SELNEZ_D:
11670         check_insn(ctx, ISA_MIPS32R6);
11671         gen_sel_d(ctx, op1, fd, ft, fs);
11672         break;
11673     case OPC_MOVCF_D:
11674         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11675         gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11676         break;
11677     case OPC_MOVZ_D:
11678         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11679         {
11680             TCGLabel *l1 = gen_new_label();
11681             TCGv_i64 fp0;
11682
11683             if (ft != 0) {
11684                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11685             }
11686             fp0 = tcg_temp_new_i64();
11687             gen_load_fpr64(ctx, fp0, fs);
11688             gen_store_fpr64(ctx, fp0, fd);
11689             tcg_temp_free_i64(fp0);
11690             gen_set_label(l1);
11691         }
11692         break;
11693     case OPC_MOVN_D:
11694         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11695         {
11696             TCGLabel *l1 = gen_new_label();
11697             TCGv_i64 fp0;
11698
11699             if (ft != 0) {
11700                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11701                 fp0 = tcg_temp_new_i64();
11702                 gen_load_fpr64(ctx, fp0, fs);
11703                 gen_store_fpr64(ctx, fp0, fd);
11704                 tcg_temp_free_i64(fp0);
11705                 gen_set_label(l1);
11706             }
11707         }
11708         break;
11709     case OPC_RECIP_D:
11710         check_cp1_registers(ctx, fs | fd);
11711         {
11712             TCGv_i64 fp0 = tcg_temp_new_i64();
11713
11714             gen_load_fpr64(ctx, fp0, fs);
11715             gen_helper_float_recip_d(fp0, cpu_env, fp0);
11716             gen_store_fpr64(ctx, fp0, fd);
11717             tcg_temp_free_i64(fp0);
11718         }
11719         break;
11720     case OPC_RSQRT_D:
11721         check_cp1_registers(ctx, fs | fd);
11722         {
11723             TCGv_i64 fp0 = tcg_temp_new_i64();
11724
11725             gen_load_fpr64(ctx, fp0, fs);
11726             gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
11727             gen_store_fpr64(ctx, fp0, fd);
11728             tcg_temp_free_i64(fp0);
11729         }
11730         break;
11731     case OPC_MADDF_D:
11732         check_insn(ctx, ISA_MIPS32R6);
11733         {
11734             TCGv_i64 fp0 = tcg_temp_new_i64();
11735             TCGv_i64 fp1 = tcg_temp_new_i64();
11736             TCGv_i64 fp2 = tcg_temp_new_i64();
11737             gen_load_fpr64(ctx, fp0, fs);
11738             gen_load_fpr64(ctx, fp1, ft);
11739             gen_load_fpr64(ctx, fp2, fd);
11740             gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
11741             gen_store_fpr64(ctx, fp2, fd);
11742             tcg_temp_free_i64(fp2);
11743             tcg_temp_free_i64(fp1);
11744             tcg_temp_free_i64(fp0);
11745         }
11746         break;
11747     case OPC_MSUBF_D:
11748         check_insn(ctx, ISA_MIPS32R6);
11749         {
11750             TCGv_i64 fp0 = tcg_temp_new_i64();
11751             TCGv_i64 fp1 = tcg_temp_new_i64();
11752             TCGv_i64 fp2 = tcg_temp_new_i64();
11753             gen_load_fpr64(ctx, fp0, fs);
11754             gen_load_fpr64(ctx, fp1, ft);
11755             gen_load_fpr64(ctx, fp2, fd);
11756             gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
11757             gen_store_fpr64(ctx, fp2, fd);
11758             tcg_temp_free_i64(fp2);
11759             tcg_temp_free_i64(fp1);
11760             tcg_temp_free_i64(fp0);
11761         }
11762         break;
11763     case OPC_RINT_D:
11764         check_insn(ctx, ISA_MIPS32R6);
11765         {
11766             TCGv_i64 fp0 = tcg_temp_new_i64();
11767             gen_load_fpr64(ctx, fp0, fs);
11768             gen_helper_float_rint_d(fp0, cpu_env, fp0);
11769             gen_store_fpr64(ctx, fp0, fd);
11770             tcg_temp_free_i64(fp0);
11771         }
11772         break;
11773     case OPC_CLASS_D:
11774         check_insn(ctx, ISA_MIPS32R6);
11775         {
11776             TCGv_i64 fp0 = tcg_temp_new_i64();
11777             gen_load_fpr64(ctx, fp0, fs);
11778             gen_helper_float_class_d(fp0, cpu_env, fp0);
11779             gen_store_fpr64(ctx, fp0, fd);
11780             tcg_temp_free_i64(fp0);
11781         }
11782         break;
11783     case OPC_MIN_D: /* OPC_RECIP2_D */
11784         if (ctx->insn_flags & ISA_MIPS32R6) {
11785             /* OPC_MIN_D */
11786             TCGv_i64 fp0 = tcg_temp_new_i64();
11787             TCGv_i64 fp1 = tcg_temp_new_i64();
11788             gen_load_fpr64(ctx, fp0, fs);
11789             gen_load_fpr64(ctx, fp1, ft);
11790             gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
11791             gen_store_fpr64(ctx, fp1, fd);
11792             tcg_temp_free_i64(fp1);
11793             tcg_temp_free_i64(fp0);
11794         } else {
11795             /* OPC_RECIP2_D */
11796             check_cp1_64bitmode(ctx);
11797             {
11798                 TCGv_i64 fp0 = tcg_temp_new_i64();
11799                 TCGv_i64 fp1 = tcg_temp_new_i64();
11800
11801                 gen_load_fpr64(ctx, fp0, fs);
11802                 gen_load_fpr64(ctx, fp1, ft);
11803                 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
11804                 tcg_temp_free_i64(fp1);
11805                 gen_store_fpr64(ctx, fp0, fd);
11806                 tcg_temp_free_i64(fp0);
11807             }
11808         }
11809         break;
11810     case OPC_MINA_D: /* OPC_RECIP1_D */
11811         if (ctx->insn_flags & ISA_MIPS32R6) {
11812             /* OPC_MINA_D */
11813             TCGv_i64 fp0 = tcg_temp_new_i64();
11814             TCGv_i64 fp1 = tcg_temp_new_i64();
11815             gen_load_fpr64(ctx, fp0, fs);
11816             gen_load_fpr64(ctx, fp1, ft);
11817             gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
11818             gen_store_fpr64(ctx, fp1, fd);
11819             tcg_temp_free_i64(fp1);
11820             tcg_temp_free_i64(fp0);
11821         } else {
11822             /* OPC_RECIP1_D */
11823             check_cp1_64bitmode(ctx);
11824             {
11825                 TCGv_i64 fp0 = tcg_temp_new_i64();
11826
11827                 gen_load_fpr64(ctx, fp0, fs);
11828                 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
11829                 gen_store_fpr64(ctx, fp0, fd);
11830                 tcg_temp_free_i64(fp0);
11831             }
11832         }
11833         break;
11834     case OPC_MAX_D: /*  OPC_RSQRT1_D */
11835         if (ctx->insn_flags & ISA_MIPS32R6) {
11836             /* OPC_MAX_D */
11837             TCGv_i64 fp0 = tcg_temp_new_i64();
11838             TCGv_i64 fp1 = tcg_temp_new_i64();
11839             gen_load_fpr64(ctx, fp0, fs);
11840             gen_load_fpr64(ctx, fp1, ft);
11841             gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
11842             gen_store_fpr64(ctx, fp1, fd);
11843             tcg_temp_free_i64(fp1);
11844             tcg_temp_free_i64(fp0);
11845         } else {
11846             /* OPC_RSQRT1_D */
11847             check_cp1_64bitmode(ctx);
11848             {
11849                 TCGv_i64 fp0 = tcg_temp_new_i64();
11850
11851                 gen_load_fpr64(ctx, fp0, fs);
11852                 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
11853                 gen_store_fpr64(ctx, fp0, fd);
11854                 tcg_temp_free_i64(fp0);
11855             }
11856         }
11857         break;
11858     case OPC_MAXA_D: /* OPC_RSQRT2_D */
11859         if (ctx->insn_flags & ISA_MIPS32R6) {
11860             /* OPC_MAXA_D */
11861             TCGv_i64 fp0 = tcg_temp_new_i64();
11862             TCGv_i64 fp1 = tcg_temp_new_i64();
11863             gen_load_fpr64(ctx, fp0, fs);
11864             gen_load_fpr64(ctx, fp1, ft);
11865             gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
11866             gen_store_fpr64(ctx, fp1, fd);
11867             tcg_temp_free_i64(fp1);
11868             tcg_temp_free_i64(fp0);
11869         } else {
11870             /* OPC_RSQRT2_D */
11871             check_cp1_64bitmode(ctx);
11872             {
11873                 TCGv_i64 fp0 = tcg_temp_new_i64();
11874                 TCGv_i64 fp1 = tcg_temp_new_i64();
11875
11876                 gen_load_fpr64(ctx, fp0, fs);
11877                 gen_load_fpr64(ctx, fp1, ft);
11878                 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
11879                 tcg_temp_free_i64(fp1);
11880                 gen_store_fpr64(ctx, fp0, fd);
11881                 tcg_temp_free_i64(fp0);
11882             }
11883         }
11884         break;
11885     case OPC_CMP_F_D:
11886     case OPC_CMP_UN_D:
11887     case OPC_CMP_EQ_D:
11888     case OPC_CMP_UEQ_D:
11889     case OPC_CMP_OLT_D:
11890     case OPC_CMP_ULT_D:
11891     case OPC_CMP_OLE_D:
11892     case OPC_CMP_ULE_D:
11893     case OPC_CMP_SF_D:
11894     case OPC_CMP_NGLE_D:
11895     case OPC_CMP_SEQ_D:
11896     case OPC_CMP_NGL_D:
11897     case OPC_CMP_LT_D:
11898     case OPC_CMP_NGE_D:
11899     case OPC_CMP_LE_D:
11900     case OPC_CMP_NGT_D:
11901         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11902         if (ctx->opcode & (1 << 6)) {
11903             gen_cmpabs_d(ctx, func-48, ft, fs, cc);
11904         } else {
11905             gen_cmp_d(ctx, func-48, ft, fs, cc);
11906         }
11907         break;
11908     case OPC_CVT_S_D:
11909         check_cp1_registers(ctx, fs);
11910         {
11911             TCGv_i32 fp32 = tcg_temp_new_i32();
11912             TCGv_i64 fp64 = tcg_temp_new_i64();
11913
11914             gen_load_fpr64(ctx, fp64, fs);
11915             gen_helper_float_cvts_d(fp32, cpu_env, fp64);
11916             tcg_temp_free_i64(fp64);
11917             gen_store_fpr32(ctx, fp32, fd);
11918             tcg_temp_free_i32(fp32);
11919         }
11920         break;
11921     case OPC_CVT_W_D:
11922         check_cp1_registers(ctx, fs);
11923         {
11924             TCGv_i32 fp32 = tcg_temp_new_i32();
11925             TCGv_i64 fp64 = tcg_temp_new_i64();
11926
11927             gen_load_fpr64(ctx, fp64, fs);
11928             if (ctx->nan2008) {
11929                 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
11930             } else {
11931                 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
11932             }
11933             tcg_temp_free_i64(fp64);
11934             gen_store_fpr32(ctx, fp32, fd);
11935             tcg_temp_free_i32(fp32);
11936         }
11937         break;
11938     case OPC_CVT_L_D:
11939         check_cp1_64bitmode(ctx);
11940         {
11941             TCGv_i64 fp0 = tcg_temp_new_i64();
11942
11943             gen_load_fpr64(ctx, fp0, fs);
11944             if (ctx->nan2008) {
11945                 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
11946             } else {
11947                 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
11948             }
11949             gen_store_fpr64(ctx, fp0, fd);
11950             tcg_temp_free_i64(fp0);
11951         }
11952         break;
11953     case OPC_CVT_S_W:
11954         {
11955             TCGv_i32 fp0 = tcg_temp_new_i32();
11956
11957             gen_load_fpr32(ctx, fp0, fs);
11958             gen_helper_float_cvts_w(fp0, cpu_env, fp0);
11959             gen_store_fpr32(ctx, fp0, fd);
11960             tcg_temp_free_i32(fp0);
11961         }
11962         break;
11963     case OPC_CVT_D_W:
11964         check_cp1_registers(ctx, fd);
11965         {
11966             TCGv_i32 fp32 = tcg_temp_new_i32();
11967             TCGv_i64 fp64 = tcg_temp_new_i64();
11968
11969             gen_load_fpr32(ctx, fp32, fs);
11970             gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
11971             tcg_temp_free_i32(fp32);
11972             gen_store_fpr64(ctx, fp64, fd);
11973             tcg_temp_free_i64(fp64);
11974         }
11975         break;
11976     case OPC_CVT_S_L:
11977         check_cp1_64bitmode(ctx);
11978         {
11979             TCGv_i32 fp32 = tcg_temp_new_i32();
11980             TCGv_i64 fp64 = tcg_temp_new_i64();
11981
11982             gen_load_fpr64(ctx, fp64, fs);
11983             gen_helper_float_cvts_l(fp32, cpu_env, fp64);
11984             tcg_temp_free_i64(fp64);
11985             gen_store_fpr32(ctx, fp32, fd);
11986             tcg_temp_free_i32(fp32);
11987         }
11988         break;
11989     case OPC_CVT_D_L:
11990         check_cp1_64bitmode(ctx);
11991         {
11992             TCGv_i64 fp0 = tcg_temp_new_i64();
11993
11994             gen_load_fpr64(ctx, fp0, fs);
11995             gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
11996             gen_store_fpr64(ctx, fp0, fd);
11997             tcg_temp_free_i64(fp0);
11998         }
11999         break;
12000     case OPC_CVT_PS_PW:
12001         check_ps(ctx);
12002         {
12003             TCGv_i64 fp0 = tcg_temp_new_i64();
12004
12005             gen_load_fpr64(ctx, fp0, fs);
12006             gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
12007             gen_store_fpr64(ctx, fp0, fd);
12008             tcg_temp_free_i64(fp0);
12009         }
12010         break;
12011     case OPC_ADD_PS:
12012         check_ps(ctx);
12013         {
12014             TCGv_i64 fp0 = tcg_temp_new_i64();
12015             TCGv_i64 fp1 = tcg_temp_new_i64();
12016
12017             gen_load_fpr64(ctx, fp0, fs);
12018             gen_load_fpr64(ctx, fp1, ft);
12019             gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
12020             tcg_temp_free_i64(fp1);
12021             gen_store_fpr64(ctx, fp0, fd);
12022             tcg_temp_free_i64(fp0);
12023         }
12024         break;
12025     case OPC_SUB_PS:
12026         check_ps(ctx);
12027         {
12028             TCGv_i64 fp0 = tcg_temp_new_i64();
12029             TCGv_i64 fp1 = tcg_temp_new_i64();
12030
12031             gen_load_fpr64(ctx, fp0, fs);
12032             gen_load_fpr64(ctx, fp1, ft);
12033             gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
12034             tcg_temp_free_i64(fp1);
12035             gen_store_fpr64(ctx, fp0, fd);
12036             tcg_temp_free_i64(fp0);
12037         }
12038         break;
12039     case OPC_MUL_PS:
12040         check_ps(ctx);
12041         {
12042             TCGv_i64 fp0 = tcg_temp_new_i64();
12043             TCGv_i64 fp1 = tcg_temp_new_i64();
12044
12045             gen_load_fpr64(ctx, fp0, fs);
12046             gen_load_fpr64(ctx, fp1, ft);
12047             gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
12048             tcg_temp_free_i64(fp1);
12049             gen_store_fpr64(ctx, fp0, fd);
12050             tcg_temp_free_i64(fp0);
12051         }
12052         break;
12053     case OPC_ABS_PS:
12054         check_ps(ctx);
12055         {
12056             TCGv_i64 fp0 = tcg_temp_new_i64();
12057
12058             gen_load_fpr64(ctx, fp0, fs);
12059             gen_helper_float_abs_ps(fp0, fp0);
12060             gen_store_fpr64(ctx, fp0, fd);
12061             tcg_temp_free_i64(fp0);
12062         }
12063         break;
12064     case OPC_MOV_PS:
12065         check_ps(ctx);
12066         {
12067             TCGv_i64 fp0 = tcg_temp_new_i64();
12068
12069             gen_load_fpr64(ctx, fp0, fs);
12070             gen_store_fpr64(ctx, fp0, fd);
12071             tcg_temp_free_i64(fp0);
12072         }
12073         break;
12074     case OPC_NEG_PS:
12075         check_ps(ctx);
12076         {
12077             TCGv_i64 fp0 = tcg_temp_new_i64();
12078
12079             gen_load_fpr64(ctx, fp0, fs);
12080             gen_helper_float_chs_ps(fp0, fp0);
12081             gen_store_fpr64(ctx, fp0, fd);
12082             tcg_temp_free_i64(fp0);
12083         }
12084         break;
12085     case OPC_MOVCF_PS:
12086         check_ps(ctx);
12087         gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
12088         break;
12089     case OPC_MOVZ_PS:
12090         check_ps(ctx);
12091         {
12092             TCGLabel *l1 = gen_new_label();
12093             TCGv_i64 fp0;
12094
12095             if (ft != 0)
12096                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
12097             fp0 = tcg_temp_new_i64();
12098             gen_load_fpr64(ctx, fp0, fs);
12099             gen_store_fpr64(ctx, fp0, fd);
12100             tcg_temp_free_i64(fp0);
12101             gen_set_label(l1);
12102         }
12103         break;
12104     case OPC_MOVN_PS:
12105         check_ps(ctx);
12106         {
12107             TCGLabel *l1 = gen_new_label();
12108             TCGv_i64 fp0;
12109
12110             if (ft != 0) {
12111                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
12112                 fp0 = tcg_temp_new_i64();
12113                 gen_load_fpr64(ctx, fp0, fs);
12114                 gen_store_fpr64(ctx, fp0, fd);
12115                 tcg_temp_free_i64(fp0);
12116                 gen_set_label(l1);
12117             }
12118         }
12119         break;
12120     case OPC_ADDR_PS:
12121         check_ps(ctx);
12122         {
12123             TCGv_i64 fp0 = tcg_temp_new_i64();
12124             TCGv_i64 fp1 = tcg_temp_new_i64();
12125
12126             gen_load_fpr64(ctx, fp0, ft);
12127             gen_load_fpr64(ctx, fp1, fs);
12128             gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
12129             tcg_temp_free_i64(fp1);
12130             gen_store_fpr64(ctx, fp0, fd);
12131             tcg_temp_free_i64(fp0);
12132         }
12133         break;
12134     case OPC_MULR_PS:
12135         check_ps(ctx);
12136         {
12137             TCGv_i64 fp0 = tcg_temp_new_i64();
12138             TCGv_i64 fp1 = tcg_temp_new_i64();
12139
12140             gen_load_fpr64(ctx, fp0, ft);
12141             gen_load_fpr64(ctx, fp1, fs);
12142             gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
12143             tcg_temp_free_i64(fp1);
12144             gen_store_fpr64(ctx, fp0, fd);
12145             tcg_temp_free_i64(fp0);
12146         }
12147         break;
12148     case OPC_RECIP2_PS:
12149         check_ps(ctx);
12150         {
12151             TCGv_i64 fp0 = tcg_temp_new_i64();
12152             TCGv_i64 fp1 = tcg_temp_new_i64();
12153
12154             gen_load_fpr64(ctx, fp0, fs);
12155             gen_load_fpr64(ctx, fp1, ft);
12156             gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
12157             tcg_temp_free_i64(fp1);
12158             gen_store_fpr64(ctx, fp0, fd);
12159             tcg_temp_free_i64(fp0);
12160         }
12161         break;
12162     case OPC_RECIP1_PS:
12163         check_ps(ctx);
12164         {
12165             TCGv_i64 fp0 = tcg_temp_new_i64();
12166
12167             gen_load_fpr64(ctx, fp0, fs);
12168             gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
12169             gen_store_fpr64(ctx, fp0, fd);
12170             tcg_temp_free_i64(fp0);
12171         }
12172         break;
12173     case OPC_RSQRT1_PS:
12174         check_ps(ctx);
12175         {
12176             TCGv_i64 fp0 = tcg_temp_new_i64();
12177
12178             gen_load_fpr64(ctx, fp0, fs);
12179             gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
12180             gen_store_fpr64(ctx, fp0, fd);
12181             tcg_temp_free_i64(fp0);
12182         }
12183         break;
12184     case OPC_RSQRT2_PS:
12185         check_ps(ctx);
12186         {
12187             TCGv_i64 fp0 = tcg_temp_new_i64();
12188             TCGv_i64 fp1 = tcg_temp_new_i64();
12189
12190             gen_load_fpr64(ctx, fp0, fs);
12191             gen_load_fpr64(ctx, fp1, ft);
12192             gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
12193             tcg_temp_free_i64(fp1);
12194             gen_store_fpr64(ctx, fp0, fd);
12195             tcg_temp_free_i64(fp0);
12196         }
12197         break;
12198     case OPC_CVT_S_PU:
12199         check_cp1_64bitmode(ctx);
12200         {
12201             TCGv_i32 fp0 = tcg_temp_new_i32();
12202
12203             gen_load_fpr32h(ctx, fp0, fs);
12204             gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
12205             gen_store_fpr32(ctx, fp0, fd);
12206             tcg_temp_free_i32(fp0);
12207         }
12208         break;
12209     case OPC_CVT_PW_PS:
12210         check_ps(ctx);
12211         {
12212             TCGv_i64 fp0 = tcg_temp_new_i64();
12213
12214             gen_load_fpr64(ctx, fp0, fs);
12215             gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
12216             gen_store_fpr64(ctx, fp0, fd);
12217             tcg_temp_free_i64(fp0);
12218         }
12219         break;
12220     case OPC_CVT_S_PL:
12221         check_cp1_64bitmode(ctx);
12222         {
12223             TCGv_i32 fp0 = tcg_temp_new_i32();
12224
12225             gen_load_fpr32(ctx, fp0, fs);
12226             gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
12227             gen_store_fpr32(ctx, fp0, fd);
12228             tcg_temp_free_i32(fp0);
12229         }
12230         break;
12231     case OPC_PLL_PS:
12232         check_ps(ctx);
12233         {
12234             TCGv_i32 fp0 = tcg_temp_new_i32();
12235             TCGv_i32 fp1 = tcg_temp_new_i32();
12236
12237             gen_load_fpr32(ctx, fp0, fs);
12238             gen_load_fpr32(ctx, fp1, ft);
12239             gen_store_fpr32h(ctx, fp0, fd);
12240             gen_store_fpr32(ctx, fp1, fd);
12241             tcg_temp_free_i32(fp0);
12242             tcg_temp_free_i32(fp1);
12243         }
12244         break;
12245     case OPC_PLU_PS:
12246         check_ps(ctx);
12247         {
12248             TCGv_i32 fp0 = tcg_temp_new_i32();
12249             TCGv_i32 fp1 = tcg_temp_new_i32();
12250
12251             gen_load_fpr32(ctx, fp0, fs);
12252             gen_load_fpr32h(ctx, fp1, ft);
12253             gen_store_fpr32(ctx, fp1, fd);
12254             gen_store_fpr32h(ctx, fp0, fd);
12255             tcg_temp_free_i32(fp0);
12256             tcg_temp_free_i32(fp1);
12257         }
12258         break;
12259     case OPC_PUL_PS:
12260         check_ps(ctx);
12261         {
12262             TCGv_i32 fp0 = tcg_temp_new_i32();
12263             TCGv_i32 fp1 = tcg_temp_new_i32();
12264
12265             gen_load_fpr32h(ctx, fp0, fs);
12266             gen_load_fpr32(ctx, fp1, ft);
12267             gen_store_fpr32(ctx, fp1, fd);
12268             gen_store_fpr32h(ctx, fp0, fd);
12269             tcg_temp_free_i32(fp0);
12270             tcg_temp_free_i32(fp1);
12271         }
12272         break;
12273     case OPC_PUU_PS:
12274         check_ps(ctx);
12275         {
12276             TCGv_i32 fp0 = tcg_temp_new_i32();
12277             TCGv_i32 fp1 = tcg_temp_new_i32();
12278
12279             gen_load_fpr32h(ctx, fp0, fs);
12280             gen_load_fpr32h(ctx, fp1, ft);
12281             gen_store_fpr32(ctx, fp1, fd);
12282             gen_store_fpr32h(ctx, fp0, fd);
12283             tcg_temp_free_i32(fp0);
12284             tcg_temp_free_i32(fp1);
12285         }
12286         break;
12287     case OPC_CMP_F_PS:
12288     case OPC_CMP_UN_PS:
12289     case OPC_CMP_EQ_PS:
12290     case OPC_CMP_UEQ_PS:
12291     case OPC_CMP_OLT_PS:
12292     case OPC_CMP_ULT_PS:
12293     case OPC_CMP_OLE_PS:
12294     case OPC_CMP_ULE_PS:
12295     case OPC_CMP_SF_PS:
12296     case OPC_CMP_NGLE_PS:
12297     case OPC_CMP_SEQ_PS:
12298     case OPC_CMP_NGL_PS:
12299     case OPC_CMP_LT_PS:
12300     case OPC_CMP_NGE_PS:
12301     case OPC_CMP_LE_PS:
12302     case OPC_CMP_NGT_PS:
12303         if (ctx->opcode & (1 << 6)) {
12304             gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
12305         } else {
12306             gen_cmp_ps(ctx, func-48, ft, fs, cc);
12307         }
12308         break;
12309     default:
12310         MIPS_INVAL("farith");
12311         generate_exception_end(ctx, EXCP_RI);
12312         return;
12313     }
12314 }
12315
12316 /* Coprocessor 3 (FPU) */
12317 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
12318                            int fd, int fs, int base, int index)
12319 {
12320     TCGv t0 = tcg_temp_new();
12321
12322     if (base == 0) {
12323         gen_load_gpr(t0, index);
12324     } else if (index == 0) {
12325         gen_load_gpr(t0, base);
12326     } else {
12327         gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
12328     }
12329     /* Don't do NOP if destination is zero: we must perform the actual
12330        memory access. */
12331     switch (opc) {
12332     case OPC_LWXC1:
12333         check_cop1x(ctx);
12334         {
12335             TCGv_i32 fp0 = tcg_temp_new_i32();
12336
12337             tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
12338             tcg_gen_trunc_tl_i32(fp0, t0);
12339             gen_store_fpr32(ctx, fp0, fd);
12340             tcg_temp_free_i32(fp0);
12341         }
12342         break;
12343     case OPC_LDXC1:
12344         check_cop1x(ctx);
12345         check_cp1_registers(ctx, fd);
12346         {
12347             TCGv_i64 fp0 = tcg_temp_new_i64();
12348             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12349             gen_store_fpr64(ctx, fp0, fd);
12350             tcg_temp_free_i64(fp0);
12351         }
12352         break;
12353     case OPC_LUXC1:
12354         check_cp1_64bitmode(ctx);
12355         tcg_gen_andi_tl(t0, t0, ~0x7);
12356         {
12357             TCGv_i64 fp0 = tcg_temp_new_i64();
12358
12359             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12360             gen_store_fpr64(ctx, fp0, fd);
12361             tcg_temp_free_i64(fp0);
12362         }
12363         break;
12364     case OPC_SWXC1:
12365         check_cop1x(ctx);
12366         {
12367             TCGv_i32 fp0 = tcg_temp_new_i32();
12368             gen_load_fpr32(ctx, fp0, fs);
12369             tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
12370             tcg_temp_free_i32(fp0);
12371         }
12372         break;
12373     case OPC_SDXC1:
12374         check_cop1x(ctx);
12375         check_cp1_registers(ctx, fs);
12376         {
12377             TCGv_i64 fp0 = tcg_temp_new_i64();
12378             gen_load_fpr64(ctx, fp0, fs);
12379             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12380             tcg_temp_free_i64(fp0);
12381         }
12382         break;
12383     case OPC_SUXC1:
12384         check_cp1_64bitmode(ctx);
12385         tcg_gen_andi_tl(t0, t0, ~0x7);
12386         {
12387             TCGv_i64 fp0 = tcg_temp_new_i64();
12388             gen_load_fpr64(ctx, fp0, fs);
12389             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12390             tcg_temp_free_i64(fp0);
12391         }
12392         break;
12393     }
12394     tcg_temp_free(t0);
12395 }
12396
12397 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
12398                             int fd, int fr, int fs, int ft)
12399 {
12400     switch (opc) {
12401     case OPC_ALNV_PS:
12402         check_ps(ctx);
12403         {
12404             TCGv t0 = tcg_temp_local_new();
12405             TCGv_i32 fp = tcg_temp_new_i32();
12406             TCGv_i32 fph = tcg_temp_new_i32();
12407             TCGLabel *l1 = gen_new_label();
12408             TCGLabel *l2 = gen_new_label();
12409
12410             gen_load_gpr(t0, fr);
12411             tcg_gen_andi_tl(t0, t0, 0x7);
12412
12413             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
12414             gen_load_fpr32(ctx, fp, fs);
12415             gen_load_fpr32h(ctx, fph, fs);
12416             gen_store_fpr32(ctx, fp, fd);
12417             gen_store_fpr32h(ctx, fph, fd);
12418             tcg_gen_br(l2);
12419             gen_set_label(l1);
12420             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
12421             tcg_temp_free(t0);
12422 #ifdef TARGET_WORDS_BIGENDIAN
12423             gen_load_fpr32(ctx, fp, fs);
12424             gen_load_fpr32h(ctx, fph, ft);
12425             gen_store_fpr32h(ctx, fp, fd);
12426             gen_store_fpr32(ctx, fph, fd);
12427 #else
12428             gen_load_fpr32h(ctx, fph, fs);
12429             gen_load_fpr32(ctx, fp, ft);
12430             gen_store_fpr32(ctx, fph, fd);
12431             gen_store_fpr32h(ctx, fp, fd);
12432 #endif
12433             gen_set_label(l2);
12434             tcg_temp_free_i32(fp);
12435             tcg_temp_free_i32(fph);
12436         }
12437         break;
12438     case OPC_MADD_S:
12439         check_cop1x(ctx);
12440         {
12441             TCGv_i32 fp0 = tcg_temp_new_i32();
12442             TCGv_i32 fp1 = tcg_temp_new_i32();
12443             TCGv_i32 fp2 = tcg_temp_new_i32();
12444
12445             gen_load_fpr32(ctx, fp0, fs);
12446             gen_load_fpr32(ctx, fp1, ft);
12447             gen_load_fpr32(ctx, fp2, fr);
12448             gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
12449             tcg_temp_free_i32(fp0);
12450             tcg_temp_free_i32(fp1);
12451             gen_store_fpr32(ctx, fp2, fd);
12452             tcg_temp_free_i32(fp2);
12453         }
12454         break;
12455     case OPC_MADD_D:
12456         check_cop1x(ctx);
12457         check_cp1_registers(ctx, fd | fs | ft | fr);
12458         {
12459             TCGv_i64 fp0 = tcg_temp_new_i64();
12460             TCGv_i64 fp1 = tcg_temp_new_i64();
12461             TCGv_i64 fp2 = tcg_temp_new_i64();
12462
12463             gen_load_fpr64(ctx, fp0, fs);
12464             gen_load_fpr64(ctx, fp1, ft);
12465             gen_load_fpr64(ctx, fp2, fr);
12466             gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
12467             tcg_temp_free_i64(fp0);
12468             tcg_temp_free_i64(fp1);
12469             gen_store_fpr64(ctx, fp2, fd);
12470             tcg_temp_free_i64(fp2);
12471         }
12472         break;
12473     case OPC_MADD_PS:
12474         check_ps(ctx);
12475         {
12476             TCGv_i64 fp0 = tcg_temp_new_i64();
12477             TCGv_i64 fp1 = tcg_temp_new_i64();
12478             TCGv_i64 fp2 = tcg_temp_new_i64();
12479
12480             gen_load_fpr64(ctx, fp0, fs);
12481             gen_load_fpr64(ctx, fp1, ft);
12482             gen_load_fpr64(ctx, fp2, fr);
12483             gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
12484             tcg_temp_free_i64(fp0);
12485             tcg_temp_free_i64(fp1);
12486             gen_store_fpr64(ctx, fp2, fd);
12487             tcg_temp_free_i64(fp2);
12488         }
12489         break;
12490     case OPC_MSUB_S:
12491         check_cop1x(ctx);
12492         {
12493             TCGv_i32 fp0 = tcg_temp_new_i32();
12494             TCGv_i32 fp1 = tcg_temp_new_i32();
12495             TCGv_i32 fp2 = tcg_temp_new_i32();
12496
12497             gen_load_fpr32(ctx, fp0, fs);
12498             gen_load_fpr32(ctx, fp1, ft);
12499             gen_load_fpr32(ctx, fp2, fr);
12500             gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
12501             tcg_temp_free_i32(fp0);
12502             tcg_temp_free_i32(fp1);
12503             gen_store_fpr32(ctx, fp2, fd);
12504             tcg_temp_free_i32(fp2);
12505         }
12506         break;
12507     case OPC_MSUB_D:
12508         check_cop1x(ctx);
12509         check_cp1_registers(ctx, fd | fs | ft | fr);
12510         {
12511             TCGv_i64 fp0 = tcg_temp_new_i64();
12512             TCGv_i64 fp1 = tcg_temp_new_i64();
12513             TCGv_i64 fp2 = tcg_temp_new_i64();
12514
12515             gen_load_fpr64(ctx, fp0, fs);
12516             gen_load_fpr64(ctx, fp1, ft);
12517             gen_load_fpr64(ctx, fp2, fr);
12518             gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
12519             tcg_temp_free_i64(fp0);
12520             tcg_temp_free_i64(fp1);
12521             gen_store_fpr64(ctx, fp2, fd);
12522             tcg_temp_free_i64(fp2);
12523         }
12524         break;
12525     case OPC_MSUB_PS:
12526         check_ps(ctx);
12527         {
12528             TCGv_i64 fp0 = tcg_temp_new_i64();
12529             TCGv_i64 fp1 = tcg_temp_new_i64();
12530             TCGv_i64 fp2 = tcg_temp_new_i64();
12531
12532             gen_load_fpr64(ctx, fp0, fs);
12533             gen_load_fpr64(ctx, fp1, ft);
12534             gen_load_fpr64(ctx, fp2, fr);
12535             gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
12536             tcg_temp_free_i64(fp0);
12537             tcg_temp_free_i64(fp1);
12538             gen_store_fpr64(ctx, fp2, fd);
12539             tcg_temp_free_i64(fp2);
12540         }
12541         break;
12542     case OPC_NMADD_S:
12543         check_cop1x(ctx);
12544         {
12545             TCGv_i32 fp0 = tcg_temp_new_i32();
12546             TCGv_i32 fp1 = tcg_temp_new_i32();
12547             TCGv_i32 fp2 = tcg_temp_new_i32();
12548
12549             gen_load_fpr32(ctx, fp0, fs);
12550             gen_load_fpr32(ctx, fp1, ft);
12551             gen_load_fpr32(ctx, fp2, fr);
12552             gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
12553             tcg_temp_free_i32(fp0);
12554             tcg_temp_free_i32(fp1);
12555             gen_store_fpr32(ctx, fp2, fd);
12556             tcg_temp_free_i32(fp2);
12557         }
12558         break;
12559     case OPC_NMADD_D:
12560         check_cop1x(ctx);
12561         check_cp1_registers(ctx, fd | fs | ft | fr);
12562         {
12563             TCGv_i64 fp0 = tcg_temp_new_i64();
12564             TCGv_i64 fp1 = tcg_temp_new_i64();
12565             TCGv_i64 fp2 = tcg_temp_new_i64();
12566
12567             gen_load_fpr64(ctx, fp0, fs);
12568             gen_load_fpr64(ctx, fp1, ft);
12569             gen_load_fpr64(ctx, fp2, fr);
12570             gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
12571             tcg_temp_free_i64(fp0);
12572             tcg_temp_free_i64(fp1);
12573             gen_store_fpr64(ctx, fp2, fd);
12574             tcg_temp_free_i64(fp2);
12575         }
12576         break;
12577     case OPC_NMADD_PS:
12578         check_ps(ctx);
12579         {
12580             TCGv_i64 fp0 = tcg_temp_new_i64();
12581             TCGv_i64 fp1 = tcg_temp_new_i64();
12582             TCGv_i64 fp2 = tcg_temp_new_i64();
12583
12584             gen_load_fpr64(ctx, fp0, fs);
12585             gen_load_fpr64(ctx, fp1, ft);
12586             gen_load_fpr64(ctx, fp2, fr);
12587             gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
12588             tcg_temp_free_i64(fp0);
12589             tcg_temp_free_i64(fp1);
12590             gen_store_fpr64(ctx, fp2, fd);
12591             tcg_temp_free_i64(fp2);
12592         }
12593         break;
12594     case OPC_NMSUB_S:
12595         check_cop1x(ctx);
12596         {
12597             TCGv_i32 fp0 = tcg_temp_new_i32();
12598             TCGv_i32 fp1 = tcg_temp_new_i32();
12599             TCGv_i32 fp2 = tcg_temp_new_i32();
12600
12601             gen_load_fpr32(ctx, fp0, fs);
12602             gen_load_fpr32(ctx, fp1, ft);
12603             gen_load_fpr32(ctx, fp2, fr);
12604             gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
12605             tcg_temp_free_i32(fp0);
12606             tcg_temp_free_i32(fp1);
12607             gen_store_fpr32(ctx, fp2, fd);
12608             tcg_temp_free_i32(fp2);
12609         }
12610         break;
12611     case OPC_NMSUB_D:
12612         check_cop1x(ctx);
12613         check_cp1_registers(ctx, fd | fs | ft | fr);
12614         {
12615             TCGv_i64 fp0 = tcg_temp_new_i64();
12616             TCGv_i64 fp1 = tcg_temp_new_i64();
12617             TCGv_i64 fp2 = tcg_temp_new_i64();
12618
12619             gen_load_fpr64(ctx, fp0, fs);
12620             gen_load_fpr64(ctx, fp1, ft);
12621             gen_load_fpr64(ctx, fp2, fr);
12622             gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
12623             tcg_temp_free_i64(fp0);
12624             tcg_temp_free_i64(fp1);
12625             gen_store_fpr64(ctx, fp2, fd);
12626             tcg_temp_free_i64(fp2);
12627         }
12628         break;
12629     case OPC_NMSUB_PS:
12630         check_ps(ctx);
12631         {
12632             TCGv_i64 fp0 = tcg_temp_new_i64();
12633             TCGv_i64 fp1 = tcg_temp_new_i64();
12634             TCGv_i64 fp2 = tcg_temp_new_i64();
12635
12636             gen_load_fpr64(ctx, fp0, fs);
12637             gen_load_fpr64(ctx, fp1, ft);
12638             gen_load_fpr64(ctx, fp2, fr);
12639             gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
12640             tcg_temp_free_i64(fp0);
12641             tcg_temp_free_i64(fp1);
12642             gen_store_fpr64(ctx, fp2, fd);
12643             tcg_temp_free_i64(fp2);
12644         }
12645         break;
12646     default:
12647         MIPS_INVAL("flt3_arith");
12648         generate_exception_end(ctx, EXCP_RI);
12649         return;
12650     }
12651 }
12652
12653 static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
12654 {
12655     TCGv t0;
12656
12657 #if !defined(CONFIG_USER_ONLY)
12658     /* The Linux kernel will emulate rdhwr if it's not supported natively.
12659        Therefore only check the ISA in system mode.  */
12660     check_insn(ctx, ISA_MIPS32R2);
12661 #endif
12662     t0 = tcg_temp_new();
12663
12664     switch (rd) {
12665     case 0:
12666         gen_helper_rdhwr_cpunum(t0, cpu_env);
12667         gen_store_gpr(t0, rt);
12668         break;
12669     case 1:
12670         gen_helper_rdhwr_synci_step(t0, cpu_env);
12671         gen_store_gpr(t0, rt);
12672         break;
12673     case 2:
12674         if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
12675             gen_io_start();
12676         }
12677         gen_helper_rdhwr_cc(t0, cpu_env);
12678         if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
12679             gen_io_end();
12680         }
12681         gen_store_gpr(t0, rt);
12682         /* Break the TB to be able to take timer interrupts immediately
12683            after reading count. DISAS_STOP isn't sufficient, we need to ensure
12684            we break completely out of translated code.  */
12685         gen_save_pc(ctx->base.pc_next + 4);
12686         ctx->base.is_jmp = DISAS_EXIT;
12687         break;
12688     case 3:
12689         gen_helper_rdhwr_ccres(t0, cpu_env);
12690         gen_store_gpr(t0, rt);
12691         break;
12692     case 4:
12693         check_insn(ctx, ISA_MIPS32R6);
12694         if (sel != 0) {
12695             /* Performance counter registers are not implemented other than
12696              * control register 0.
12697              */
12698             generate_exception(ctx, EXCP_RI);
12699         }
12700         gen_helper_rdhwr_performance(t0, cpu_env);
12701         gen_store_gpr(t0, rt);
12702         break;
12703     case 5:
12704         check_insn(ctx, ISA_MIPS32R6);
12705         gen_helper_rdhwr_xnp(t0, cpu_env);
12706         gen_store_gpr(t0, rt);
12707         break;
12708     case 29:
12709 #if defined(CONFIG_USER_ONLY)
12710         tcg_gen_ld_tl(t0, cpu_env,
12711                       offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12712         gen_store_gpr(t0, rt);
12713         break;
12714 #else
12715         if ((ctx->hflags & MIPS_HFLAG_CP0) ||
12716             (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
12717             tcg_gen_ld_tl(t0, cpu_env,
12718                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12719             gen_store_gpr(t0, rt);
12720         } else {
12721             generate_exception_end(ctx, EXCP_RI);
12722         }
12723         break;
12724 #endif
12725     default:            /* Invalid */
12726         MIPS_INVAL("rdhwr");
12727         generate_exception_end(ctx, EXCP_RI);
12728         break;
12729     }
12730     tcg_temp_free(t0);
12731 }
12732
12733 static inline void clear_branch_hflags(DisasContext *ctx)
12734 {
12735     ctx->hflags &= ~MIPS_HFLAG_BMASK;
12736     if (ctx->base.is_jmp == DISAS_NEXT) {
12737         save_cpu_state(ctx, 0);
12738     } else {
12739         /* it is not safe to save ctx->hflags as hflags may be changed
12740            in execution time by the instruction in delay / forbidden slot. */
12741         tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
12742     }
12743 }
12744
12745 static void gen_branch(DisasContext *ctx, int insn_bytes)
12746 {
12747     if (ctx->hflags & MIPS_HFLAG_BMASK) {
12748         int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
12749         /* Branches completion */
12750         clear_branch_hflags(ctx);
12751         ctx->base.is_jmp = DISAS_NORETURN;
12752         /* FIXME: Need to clear can_do_io.  */
12753         switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
12754         case MIPS_HFLAG_FBNSLOT:
12755             gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
12756             break;
12757         case MIPS_HFLAG_B:
12758             /* unconditional branch */
12759             if (proc_hflags & MIPS_HFLAG_BX) {
12760                 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
12761             }
12762             gen_goto_tb(ctx, 0, ctx->btarget);
12763             break;
12764         case MIPS_HFLAG_BL:
12765             /* blikely taken case */
12766             gen_goto_tb(ctx, 0, ctx->btarget);
12767             break;
12768         case MIPS_HFLAG_BC:
12769             /* Conditional branch */
12770             {
12771                 TCGLabel *l1 = gen_new_label();
12772
12773                 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
12774                 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
12775                 gen_set_label(l1);
12776                 gen_goto_tb(ctx, 0, ctx->btarget);
12777             }
12778             break;
12779         case MIPS_HFLAG_BR:
12780             /* unconditional branch to register */
12781             if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
12782                 TCGv t0 = tcg_temp_new();
12783                 TCGv_i32 t1 = tcg_temp_new_i32();
12784
12785                 tcg_gen_andi_tl(t0, btarget, 0x1);
12786                 tcg_gen_trunc_tl_i32(t1, t0);
12787                 tcg_temp_free(t0);
12788                 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
12789                 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
12790                 tcg_gen_or_i32(hflags, hflags, t1);
12791                 tcg_temp_free_i32(t1);
12792
12793                 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
12794             } else {
12795                 tcg_gen_mov_tl(cpu_PC, btarget);
12796             }
12797             if (ctx->base.singlestep_enabled) {
12798                 save_cpu_state(ctx, 0);
12799                 gen_helper_raise_exception_debug(cpu_env);
12800             }
12801             tcg_gen_lookup_and_goto_ptr();
12802             break;
12803         default:
12804             fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
12805             abort();
12806         }
12807     }
12808 }
12809
12810 /* Compact Branches */
12811 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
12812                                        int rs, int rt, int32_t offset)
12813 {
12814     int bcond_compute = 0;
12815     TCGv t0 = tcg_temp_new();
12816     TCGv t1 = tcg_temp_new();
12817     int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
12818
12819     if (ctx->hflags & MIPS_HFLAG_BMASK) {
12820 #ifdef MIPS_DEBUG_DISAS
12821         LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
12822                   "\n", ctx->base.pc_next);
12823 #endif
12824         generate_exception_end(ctx, EXCP_RI);
12825         goto out;
12826     }
12827
12828     /* Load needed operands and calculate btarget */
12829     switch (opc) {
12830     /* compact branch */
12831     case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12832     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12833         gen_load_gpr(t0, rs);
12834         gen_load_gpr(t1, rt);
12835         bcond_compute = 1;
12836         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12837         if (rs <= rt && rs == 0) {
12838             /* OPC_BEQZALC, OPC_BNEZALC */
12839             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12840         }
12841         break;
12842     case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12843     case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12844         gen_load_gpr(t0, rs);
12845         gen_load_gpr(t1, rt);
12846         bcond_compute = 1;
12847         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12848         break;
12849     case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12850     case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12851         if (rs == 0 || rs == rt) {
12852             /* OPC_BLEZALC, OPC_BGEZALC */
12853             /* OPC_BGTZALC, OPC_BLTZALC */
12854             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12855         }
12856         gen_load_gpr(t0, rs);
12857         gen_load_gpr(t1, rt);
12858         bcond_compute = 1;
12859         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12860         break;
12861     case OPC_BC:
12862     case OPC_BALC:
12863         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12864         break;
12865     case OPC_BEQZC:
12866     case OPC_BNEZC:
12867         if (rs != 0) {
12868             /* OPC_BEQZC, OPC_BNEZC */
12869             gen_load_gpr(t0, rs);
12870             bcond_compute = 1;
12871             ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12872         } else {
12873             /* OPC_JIC, OPC_JIALC */
12874             TCGv tbase = tcg_temp_new();
12875             TCGv toffset = tcg_temp_new();
12876
12877             gen_load_gpr(tbase, rt);
12878             tcg_gen_movi_tl(toffset, offset);
12879             gen_op_addr_add(ctx, btarget, tbase, toffset);
12880             tcg_temp_free(tbase);
12881             tcg_temp_free(toffset);
12882         }
12883         break;
12884     default:
12885         MIPS_INVAL("Compact branch/jump");
12886         generate_exception_end(ctx, EXCP_RI);
12887         goto out;
12888     }
12889
12890     if (bcond_compute == 0) {
12891         /* Uncoditional compact branch */
12892         switch (opc) {
12893         case OPC_JIALC:
12894             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12895             /* Fallthrough */
12896         case OPC_JIC:
12897             ctx->hflags |= MIPS_HFLAG_BR;
12898             break;
12899         case OPC_BALC:
12900             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12901             /* Fallthrough */
12902         case OPC_BC:
12903             ctx->hflags |= MIPS_HFLAG_B;
12904             break;
12905         default:
12906             MIPS_INVAL("Compact branch/jump");
12907             generate_exception_end(ctx, EXCP_RI);
12908             goto out;
12909         }
12910
12911         /* Generating branch here as compact branches don't have delay slot */
12912         gen_branch(ctx, 4);
12913     } else {
12914         /* Conditional compact branch */
12915         TCGLabel *fs = gen_new_label();
12916         save_cpu_state(ctx, 0);
12917
12918         switch (opc) {
12919         case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12920             if (rs == 0 && rt != 0) {
12921                 /* OPC_BLEZALC */
12922                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12923             } else if (rs != 0 && rt != 0 && rs == rt) {
12924                 /* OPC_BGEZALC */
12925                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12926             } else {
12927                 /* OPC_BGEUC */
12928                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
12929             }
12930             break;
12931         case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12932             if (rs == 0 && rt != 0) {
12933                 /* OPC_BGTZALC */
12934                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12935             } else if (rs != 0 && rt != 0 && rs == rt) {
12936                 /* OPC_BLTZALC */
12937                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12938             } else {
12939                 /* OPC_BLTUC */
12940                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
12941             }
12942             break;
12943         case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12944             if (rs == 0 && rt != 0) {
12945                 /* OPC_BLEZC */
12946                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12947             } else if (rs != 0 && rt != 0 && rs == rt) {
12948                 /* OPC_BGEZC */
12949                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12950             } else {
12951                 /* OPC_BGEC */
12952                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
12953             }
12954             break;
12955         case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12956             if (rs == 0 && rt != 0) {
12957                 /* OPC_BGTZC */
12958                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12959             } else if (rs != 0 && rt != 0 && rs == rt) {
12960                 /* OPC_BLTZC */
12961                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12962             } else {
12963                 /* OPC_BLTC */
12964                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
12965             }
12966             break;
12967         case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12968         case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12969             if (rs >= rt) {
12970                 /* OPC_BOVC, OPC_BNVC */
12971                 TCGv t2 = tcg_temp_new();
12972                 TCGv t3 = tcg_temp_new();
12973                 TCGv t4 = tcg_temp_new();
12974                 TCGv input_overflow = tcg_temp_new();
12975
12976                 gen_load_gpr(t0, rs);
12977                 gen_load_gpr(t1, rt);
12978                 tcg_gen_ext32s_tl(t2, t0);
12979                 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
12980                 tcg_gen_ext32s_tl(t3, t1);
12981                 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
12982                 tcg_gen_or_tl(input_overflow, input_overflow, t4);
12983
12984                 tcg_gen_add_tl(t4, t2, t3);
12985                 tcg_gen_ext32s_tl(t4, t4);
12986                 tcg_gen_xor_tl(t2, t2, t3);
12987                 tcg_gen_xor_tl(t3, t4, t3);
12988                 tcg_gen_andc_tl(t2, t3, t2);
12989                 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
12990                 tcg_gen_or_tl(t4, t4, input_overflow);
12991                 if (opc == OPC_BOVC) {
12992                     /* OPC_BOVC */
12993                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
12994                 } else {
12995                     /* OPC_BNVC */
12996                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
12997                 }
12998                 tcg_temp_free(input_overflow);
12999                 tcg_temp_free(t4);
13000                 tcg_temp_free(t3);
13001                 tcg_temp_free(t2);
13002             } else if (rs < rt && rs == 0) {
13003                 /* OPC_BEQZALC, OPC_BNEZALC */
13004                 if (opc == OPC_BEQZALC) {
13005                     /* OPC_BEQZALC */
13006                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
13007                 } else {
13008                     /* OPC_BNEZALC */
13009                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
13010                 }
13011             } else {
13012                 /* OPC_BEQC, OPC_BNEC */
13013                 if (opc == OPC_BEQC) {
13014                     /* OPC_BEQC */
13015                     tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
13016                 } else {
13017                     /* OPC_BNEC */
13018                     tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
13019                 }
13020             }
13021             break;
13022         case OPC_BEQZC:
13023             tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
13024             break;
13025         case OPC_BNEZC:
13026             tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
13027             break;
13028         default:
13029             MIPS_INVAL("Compact conditional branch/jump");
13030             generate_exception_end(ctx, EXCP_RI);
13031             goto out;
13032         }
13033
13034         /* Generating branch here as compact branches don't have delay slot */
13035         gen_goto_tb(ctx, 1, ctx->btarget);
13036         gen_set_label(fs);
13037
13038         ctx->hflags |= MIPS_HFLAG_FBNSLOT;
13039     }
13040
13041 out:
13042     tcg_temp_free(t0);
13043     tcg_temp_free(t1);
13044 }
13045
13046 /* ISA extensions (ASEs) */
13047 /* MIPS16 extension to MIPS32 */
13048
13049 /* MIPS16 major opcodes */
13050 enum {
13051   M16_OPC_ADDIUSP = 0x00,
13052   M16_OPC_ADDIUPC = 0x01,
13053   M16_OPC_B = 0x02,
13054   M16_OPC_JAL = 0x03,
13055   M16_OPC_BEQZ = 0x04,
13056   M16_OPC_BNEQZ = 0x05,
13057   M16_OPC_SHIFT = 0x06,
13058   M16_OPC_LD = 0x07,
13059   M16_OPC_RRIA = 0x08,
13060   M16_OPC_ADDIU8 = 0x09,
13061   M16_OPC_SLTI = 0x0a,
13062   M16_OPC_SLTIU = 0x0b,
13063   M16_OPC_I8 = 0x0c,
13064   M16_OPC_LI = 0x0d,
13065   M16_OPC_CMPI = 0x0e,
13066   M16_OPC_SD = 0x0f,
13067   M16_OPC_LB = 0x10,
13068   M16_OPC_LH = 0x11,
13069   M16_OPC_LWSP = 0x12,
13070   M16_OPC_LW = 0x13,
13071   M16_OPC_LBU = 0x14,
13072   M16_OPC_LHU = 0x15,
13073   M16_OPC_LWPC = 0x16,
13074   M16_OPC_LWU = 0x17,
13075   M16_OPC_SB = 0x18,
13076   M16_OPC_SH = 0x19,
13077   M16_OPC_SWSP = 0x1a,
13078   M16_OPC_SW = 0x1b,
13079   M16_OPC_RRR = 0x1c,
13080   M16_OPC_RR = 0x1d,
13081   M16_OPC_EXTEND = 0x1e,
13082   M16_OPC_I64 = 0x1f
13083 };
13084
13085 /* I8 funct field */
13086 enum {
13087   I8_BTEQZ = 0x0,
13088   I8_BTNEZ = 0x1,
13089   I8_SWRASP = 0x2,
13090   I8_ADJSP = 0x3,
13091   I8_SVRS = 0x4,
13092   I8_MOV32R = 0x5,
13093   I8_MOVR32 = 0x7
13094 };
13095
13096 /* RRR f field */
13097 enum {
13098   RRR_DADDU = 0x0,
13099   RRR_ADDU = 0x1,
13100   RRR_DSUBU = 0x2,
13101   RRR_SUBU = 0x3
13102 };
13103
13104 /* RR funct field */
13105 enum {
13106   RR_JR = 0x00,
13107   RR_SDBBP = 0x01,
13108   RR_SLT = 0x02,
13109   RR_SLTU = 0x03,
13110   RR_SLLV = 0x04,
13111   RR_BREAK = 0x05,
13112   RR_SRLV = 0x06,
13113   RR_SRAV = 0x07,
13114   RR_DSRL = 0x08,
13115   RR_CMP = 0x0a,
13116   RR_NEG = 0x0b,
13117   RR_AND = 0x0c,
13118   RR_OR = 0x0d,
13119   RR_XOR = 0x0e,
13120   RR_NOT = 0x0f,
13121   RR_MFHI = 0x10,
13122   RR_CNVT = 0x11,
13123   RR_MFLO = 0x12,
13124   RR_DSRA = 0x13,
13125   RR_DSLLV = 0x14,
13126   RR_DSRLV = 0x16,
13127   RR_DSRAV = 0x17,
13128   RR_MULT = 0x18,
13129   RR_MULTU = 0x19,
13130   RR_DIV = 0x1a,
13131   RR_DIVU = 0x1b,
13132   RR_DMULT = 0x1c,
13133   RR_DMULTU = 0x1d,
13134   RR_DDIV = 0x1e,
13135   RR_DDIVU = 0x1f
13136 };
13137
13138 /* I64 funct field */
13139 enum {
13140   I64_LDSP = 0x0,
13141   I64_SDSP = 0x1,
13142   I64_SDRASP = 0x2,
13143   I64_DADJSP = 0x3,
13144   I64_LDPC = 0x4,
13145   I64_DADDIU5 = 0x5,
13146   I64_DADDIUPC = 0x6,
13147   I64_DADDIUSP = 0x7
13148 };
13149
13150 /* RR ry field for CNVT */
13151 enum {
13152   RR_RY_CNVT_ZEB = 0x0,
13153   RR_RY_CNVT_ZEH = 0x1,
13154   RR_RY_CNVT_ZEW = 0x2,
13155   RR_RY_CNVT_SEB = 0x4,
13156   RR_RY_CNVT_SEH = 0x5,
13157   RR_RY_CNVT_SEW = 0x6,
13158 };
13159
13160 static int xlat (int r)
13161 {
13162   static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13163
13164   return map[r];
13165 }
13166
13167 static void gen_mips16_save (DisasContext *ctx,
13168                              int xsregs, int aregs,
13169                              int do_ra, int do_s0, int do_s1,
13170                              int framesize)
13171 {
13172     TCGv t0 = tcg_temp_new();
13173     TCGv t1 = tcg_temp_new();
13174     TCGv t2 = tcg_temp_new();
13175     int args, astatic;
13176
13177     switch (aregs) {
13178     case 0:
13179     case 1:
13180     case 2:
13181     case 3:
13182     case 11:
13183         args = 0;
13184         break;
13185     case 4:
13186     case 5:
13187     case 6:
13188     case 7:
13189         args = 1;
13190         break;
13191     case 8:
13192     case 9:
13193     case 10:
13194         args = 2;
13195         break;
13196     case 12:
13197     case 13:
13198         args = 3;
13199         break;
13200     case 14:
13201         args = 4;
13202         break;
13203     default:
13204         generate_exception_end(ctx, EXCP_RI);
13205         return;
13206     }
13207
13208     switch (args) {
13209     case 4:
13210         gen_base_offset_addr(ctx, t0, 29, 12);
13211         gen_load_gpr(t1, 7);
13212         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13213         /* Fall through */
13214     case 3:
13215         gen_base_offset_addr(ctx, t0, 29, 8);
13216         gen_load_gpr(t1, 6);
13217         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13218         /* Fall through */
13219     case 2:
13220         gen_base_offset_addr(ctx, t0, 29, 4);
13221         gen_load_gpr(t1, 5);
13222         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13223         /* Fall through */
13224     case 1:
13225         gen_base_offset_addr(ctx, t0, 29, 0);
13226         gen_load_gpr(t1, 4);
13227         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13228     }
13229
13230     gen_load_gpr(t0, 29);
13231
13232 #define DECR_AND_STORE(reg) do {                                 \
13233         tcg_gen_movi_tl(t2, -4);                                 \
13234         gen_op_addr_add(ctx, t0, t0, t2);                        \
13235         gen_load_gpr(t1, reg);                                   \
13236         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
13237     } while (0)
13238
13239     if (do_ra) {
13240         DECR_AND_STORE(31);
13241     }
13242
13243     switch (xsregs) {
13244     case 7:
13245         DECR_AND_STORE(30);
13246         /* Fall through */
13247     case 6:
13248         DECR_AND_STORE(23);
13249         /* Fall through */
13250     case 5:
13251         DECR_AND_STORE(22);
13252         /* Fall through */
13253     case 4:
13254         DECR_AND_STORE(21);
13255         /* Fall through */
13256     case 3:
13257         DECR_AND_STORE(20);
13258         /* Fall through */
13259     case 2:
13260         DECR_AND_STORE(19);
13261         /* Fall through */
13262     case 1:
13263         DECR_AND_STORE(18);
13264     }
13265
13266     if (do_s1) {
13267         DECR_AND_STORE(17);
13268     }
13269     if (do_s0) {
13270         DECR_AND_STORE(16);
13271     }
13272
13273     switch (aregs) {
13274     case 0:
13275     case 4:
13276     case 8:
13277     case 12:
13278     case 14:
13279         astatic = 0;
13280         break;
13281     case 1:
13282     case 5:
13283     case 9:
13284     case 13:
13285         astatic = 1;
13286         break;
13287     case 2:
13288     case 6:
13289     case 10:
13290         astatic = 2;
13291         break;
13292     case 3:
13293     case 7:
13294         astatic = 3;
13295         break;
13296     case 11:
13297         astatic = 4;
13298         break;
13299     default:
13300         generate_exception_end(ctx, EXCP_RI);
13301         return;
13302     }
13303
13304     if (astatic > 0) {
13305         DECR_AND_STORE(7);
13306         if (astatic > 1) {
13307             DECR_AND_STORE(6);
13308             if (astatic > 2) {
13309                 DECR_AND_STORE(5);
13310                 if (astatic > 3) {
13311                     DECR_AND_STORE(4);
13312                 }
13313             }
13314         }
13315     }
13316 #undef DECR_AND_STORE
13317
13318     tcg_gen_movi_tl(t2, -framesize);
13319     gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
13320     tcg_temp_free(t0);
13321     tcg_temp_free(t1);
13322     tcg_temp_free(t2);
13323 }
13324
13325 static void gen_mips16_restore (DisasContext *ctx,
13326                                 int xsregs, int aregs,
13327                                 int do_ra, int do_s0, int do_s1,
13328                                 int framesize)
13329 {
13330     int astatic;
13331     TCGv t0 = tcg_temp_new();
13332     TCGv t1 = tcg_temp_new();
13333     TCGv t2 = tcg_temp_new();
13334
13335     tcg_gen_movi_tl(t2, framesize);
13336     gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
13337
13338 #define DECR_AND_LOAD(reg) do {                            \
13339         tcg_gen_movi_tl(t2, -4);                           \
13340         gen_op_addr_add(ctx, t0, t0, t2);                  \
13341         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
13342         gen_store_gpr(t1, reg);                            \
13343     } while (0)
13344
13345     if (do_ra) {
13346         DECR_AND_LOAD(31);
13347     }
13348
13349     switch (xsregs) {
13350     case 7:
13351         DECR_AND_LOAD(30);
13352         /* Fall through */
13353     case 6:
13354         DECR_AND_LOAD(23);
13355         /* Fall through */
13356     case 5:
13357         DECR_AND_LOAD(22);
13358         /* Fall through */
13359     case 4:
13360         DECR_AND_LOAD(21);
13361         /* Fall through */
13362     case 3:
13363         DECR_AND_LOAD(20);
13364         /* Fall through */
13365     case 2:
13366         DECR_AND_LOAD(19);
13367         /* Fall through */
13368     case 1:
13369         DECR_AND_LOAD(18);
13370     }
13371
13372     if (do_s1) {
13373         DECR_AND_LOAD(17);
13374     }
13375     if (do_s0) {
13376         DECR_AND_LOAD(16);
13377     }
13378
13379     switch (aregs) {
13380     case 0:
13381     case 4:
13382     case 8:
13383     case 12:
13384     case 14:
13385         astatic = 0;
13386         break;
13387     case 1:
13388     case 5:
13389     case 9:
13390     case 13:
13391         astatic = 1;
13392         break;
13393     case 2:
13394     case 6:
13395     case 10:
13396         astatic = 2;
13397         break;
13398     case 3:
13399     case 7:
13400         astatic = 3;
13401         break;
13402     case 11:
13403         astatic = 4;
13404         break;
13405     default:
13406         generate_exception_end(ctx, EXCP_RI);
13407         return;
13408     }
13409
13410     if (astatic > 0) {
13411         DECR_AND_LOAD(7);
13412         if (astatic > 1) {
13413             DECR_AND_LOAD(6);
13414             if (astatic > 2) {
13415                 DECR_AND_LOAD(5);
13416                 if (astatic > 3) {
13417                     DECR_AND_LOAD(4);
13418                 }
13419             }
13420         }
13421     }
13422 #undef DECR_AND_LOAD
13423
13424     tcg_gen_movi_tl(t2, framesize);
13425     gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
13426     tcg_temp_free(t0);
13427     tcg_temp_free(t1);
13428     tcg_temp_free(t2);
13429 }
13430
13431 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
13432                          int is_64_bit, int extended)
13433 {
13434     TCGv t0;
13435
13436     if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
13437         generate_exception_end(ctx, EXCP_RI);
13438         return;
13439     }
13440
13441     t0 = tcg_temp_new();
13442
13443     tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
13444     tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
13445     if (!is_64_bit) {
13446         tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13447     }
13448
13449     tcg_temp_free(t0);
13450 }
13451
13452 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
13453                                 int16_t offset)
13454 {
13455     TCGv_i32 t0 = tcg_const_i32(op);
13456     TCGv t1 = tcg_temp_new();
13457     gen_base_offset_addr(ctx, t1, base, offset);
13458     gen_helper_cache(cpu_env, t1, t0);
13459 }
13460
13461 #if defined(TARGET_MIPS64)
13462 static void decode_i64_mips16 (DisasContext *ctx,
13463                                int ry, int funct, int16_t offset,
13464                                int extended)
13465 {
13466     switch (funct) {
13467     case I64_LDSP:
13468         check_insn(ctx, ISA_MIPS3);
13469         check_mips_64(ctx);
13470         offset = extended ? offset : offset << 3;
13471         gen_ld(ctx, OPC_LD, ry, 29, offset);
13472         break;
13473     case I64_SDSP:
13474         check_insn(ctx, ISA_MIPS3);
13475         check_mips_64(ctx);
13476         offset = extended ? offset : offset << 3;
13477         gen_st(ctx, OPC_SD, ry, 29, offset);
13478         break;
13479     case I64_SDRASP:
13480         check_insn(ctx, ISA_MIPS3);
13481         check_mips_64(ctx);
13482         offset = extended ? offset : (ctx->opcode & 0xff) << 3;
13483         gen_st(ctx, OPC_SD, 31, 29, offset);
13484         break;
13485     case I64_DADJSP:
13486         check_insn(ctx, ISA_MIPS3);
13487         check_mips_64(ctx);
13488         offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
13489         gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
13490         break;
13491     case I64_LDPC:
13492         check_insn(ctx, ISA_MIPS3);
13493         check_mips_64(ctx);
13494         if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
13495             generate_exception_end(ctx, EXCP_RI);
13496         } else {
13497             offset = extended ? offset : offset << 3;
13498             gen_ld(ctx, OPC_LDPC, ry, 0, offset);
13499         }
13500         break;
13501     case I64_DADDIU5:
13502         check_insn(ctx, ISA_MIPS3);
13503         check_mips_64(ctx);
13504         offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
13505         gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
13506         break;
13507     case I64_DADDIUPC:
13508         check_insn(ctx, ISA_MIPS3);
13509         check_mips_64(ctx);
13510         offset = extended ? offset : offset << 2;
13511         gen_addiupc(ctx, ry, offset, 1, extended);
13512         break;
13513     case I64_DADDIUSP:
13514         check_insn(ctx, ISA_MIPS3);
13515         check_mips_64(ctx);
13516         offset = extended ? offset : offset << 2;
13517         gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
13518         break;
13519     }
13520 }
13521 #endif
13522
13523 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
13524 {
13525     int extend = cpu_lduw_code(env, ctx->base.pc_next + 2);
13526     int op, rx, ry, funct, sa;
13527     int16_t imm, offset;
13528
13529     ctx->opcode = (ctx->opcode << 16) | extend;
13530     op = (ctx->opcode >> 11) & 0x1f;
13531     sa = (ctx->opcode >> 22) & 0x1f;
13532     funct = (ctx->opcode >> 8) & 0x7;
13533     rx = xlat((ctx->opcode >> 8) & 0x7);
13534     ry = xlat((ctx->opcode >> 5) & 0x7);
13535     offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
13536                               | ((ctx->opcode >> 21) & 0x3f) << 5
13537                               | (ctx->opcode & 0x1f));
13538
13539     /* The extended opcodes cleverly reuse the opcodes from their 16-bit
13540        counterparts.  */
13541     switch (op) {
13542     case M16_OPC_ADDIUSP:
13543         gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
13544         break;
13545     case M16_OPC_ADDIUPC:
13546         gen_addiupc(ctx, rx, imm, 0, 1);
13547         break;
13548     case M16_OPC_B:
13549         gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
13550         /* No delay slot, so just process as a normal instruction */
13551         break;
13552     case M16_OPC_BEQZ:
13553         gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
13554         /* No delay slot, so just process as a normal instruction */
13555         break;
13556     case M16_OPC_BNEQZ:
13557         gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
13558         /* No delay slot, so just process as a normal instruction */
13559         break;
13560     case M16_OPC_SHIFT:
13561         switch (ctx->opcode & 0x3) {
13562         case 0x0:
13563             gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
13564             break;
13565         case 0x1:
13566 #if defined(TARGET_MIPS64)
13567             check_mips_64(ctx);
13568             gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
13569 #else
13570             generate_exception_end(ctx, EXCP_RI);
13571 #endif
13572             break;
13573         case 0x2:
13574             gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
13575             break;
13576         case 0x3:
13577             gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
13578             break;
13579         }
13580         break;
13581 #if defined(TARGET_MIPS64)
13582     case M16_OPC_LD:
13583         check_insn(ctx, ISA_MIPS3);
13584         check_mips_64(ctx);
13585         gen_ld(ctx, OPC_LD, ry, rx, offset);
13586         break;
13587 #endif
13588     case M16_OPC_RRIA:
13589         imm = ctx->opcode & 0xf;
13590         imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
13591         imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
13592         imm = (int16_t) (imm << 1) >> 1;
13593         if ((ctx->opcode >> 4) & 0x1) {
13594 #if defined(TARGET_MIPS64)
13595             check_mips_64(ctx);
13596             gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
13597 #else
13598             generate_exception_end(ctx, EXCP_RI);
13599 #endif
13600         } else {
13601             gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
13602         }
13603         break;
13604     case M16_OPC_ADDIU8:
13605         gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
13606         break;
13607     case M16_OPC_SLTI:
13608         gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
13609         break;
13610     case M16_OPC_SLTIU:
13611         gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
13612         break;
13613     case M16_OPC_I8:
13614         switch (funct) {
13615         case I8_BTEQZ:
13616             gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
13617             break;
13618         case I8_BTNEZ:
13619             gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
13620             break;
13621         case I8_SWRASP:
13622             gen_st(ctx, OPC_SW, 31, 29, imm);
13623             break;
13624         case I8_ADJSP:
13625             gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
13626             break;
13627         case I8_SVRS:
13628             check_insn(ctx, ISA_MIPS32);
13629             {
13630                 int xsregs = (ctx->opcode >> 24) & 0x7;
13631                 int aregs = (ctx->opcode >> 16) & 0xf;
13632                 int do_ra = (ctx->opcode >> 6) & 0x1;
13633                 int do_s0 = (ctx->opcode >> 5) & 0x1;
13634                 int do_s1 = (ctx->opcode >> 4) & 0x1;
13635                 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
13636                                  | (ctx->opcode & 0xf)) << 3;
13637
13638                 if (ctx->opcode & (1 << 7)) {
13639                     gen_mips16_save(ctx, xsregs, aregs,
13640                                     do_ra, do_s0, do_s1,
13641                                     framesize);
13642                 } else {
13643                     gen_mips16_restore(ctx, xsregs, aregs,
13644                                        do_ra, do_s0, do_s1,
13645                                        framesize);
13646                 }
13647             }
13648             break;
13649         default:
13650             generate_exception_end(ctx, EXCP_RI);
13651             break;
13652         }
13653         break;
13654     case M16_OPC_LI:
13655         tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
13656         break;
13657     case M16_OPC_CMPI:
13658         tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
13659         break;
13660 #if defined(TARGET_MIPS64)
13661     case M16_OPC_SD:
13662         check_insn(ctx, ISA_MIPS3);
13663         check_mips_64(ctx);
13664         gen_st(ctx, OPC_SD, ry, rx, offset);
13665         break;
13666 #endif
13667     case M16_OPC_LB:
13668         gen_ld(ctx, OPC_LB, ry, rx, offset);
13669         break;
13670     case M16_OPC_LH:
13671         gen_ld(ctx, OPC_LH, ry, rx, offset);
13672         break;
13673     case M16_OPC_LWSP:
13674         gen_ld(ctx, OPC_LW, rx, 29, offset);
13675         break;
13676     case M16_OPC_LW:
13677         gen_ld(ctx, OPC_LW, ry, rx, offset);
13678         break;
13679     case M16_OPC_LBU:
13680         gen_ld(ctx, OPC_LBU, ry, rx, offset);
13681         break;
13682     case M16_OPC_LHU:
13683         gen_ld(ctx, OPC_LHU, ry, rx, offset);
13684         break;
13685     case M16_OPC_LWPC:
13686         gen_ld(ctx, OPC_LWPC, rx, 0, offset);
13687         break;
13688 #if defined(TARGET_MIPS64)
13689     case M16_OPC_LWU:
13690         check_insn(ctx, ISA_MIPS3);
13691         check_mips_64(ctx);
13692         gen_ld(ctx, OPC_LWU, ry, rx, offset);
13693         break;
13694 #endif
13695     case M16_OPC_SB:
13696         gen_st(ctx, OPC_SB, ry, rx, offset);
13697         break;
13698     case M16_OPC_SH:
13699         gen_st(ctx, OPC_SH, ry, rx, offset);
13700         break;
13701     case M16_OPC_SWSP:
13702         gen_st(ctx, OPC_SW, rx, 29, offset);
13703         break;
13704     case M16_OPC_SW:
13705         gen_st(ctx, OPC_SW, ry, rx, offset);
13706         break;
13707 #if defined(TARGET_MIPS64)
13708     case M16_OPC_I64:
13709         decode_i64_mips16(ctx, ry, funct, offset, 1);
13710         break;
13711 #endif
13712     default:
13713         generate_exception_end(ctx, EXCP_RI);
13714         break;
13715     }
13716
13717     return 4;
13718 }
13719
13720 static inline bool is_uhi(int sdbbp_code)
13721 {
13722 #ifdef CONFIG_USER_ONLY
13723     return false;
13724 #else
13725     return semihosting_enabled() && sdbbp_code == 1;
13726 #endif
13727 }
13728
13729 #ifdef CONFIG_USER_ONLY
13730 /* The above should dead-code away any calls to this..*/
13731 static inline void gen_helper_do_semihosting(void *env)
13732 {
13733     g_assert_not_reached();
13734 }
13735 #endif
13736
13737 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
13738 {
13739     int rx, ry;
13740     int sa;
13741     int op, cnvt_op, op1, offset;
13742     int funct;
13743     int n_bytes;
13744
13745     op = (ctx->opcode >> 11) & 0x1f;
13746     sa = (ctx->opcode >> 2) & 0x7;
13747     sa = sa == 0 ? 8 : sa;
13748     rx = xlat((ctx->opcode >> 8) & 0x7);
13749     cnvt_op = (ctx->opcode >> 5) & 0x7;
13750     ry = xlat((ctx->opcode >> 5) & 0x7);
13751     op1 = offset = ctx->opcode & 0x1f;
13752
13753     n_bytes = 2;
13754
13755     switch (op) {
13756     case M16_OPC_ADDIUSP:
13757         {
13758             int16_t imm = ((uint8_t) ctx->opcode) << 2;
13759
13760             gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
13761         }
13762         break;
13763     case M16_OPC_ADDIUPC:
13764         gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
13765         break;
13766     case M16_OPC_B:
13767         offset = (ctx->opcode & 0x7ff) << 1;
13768         offset = (int16_t)(offset << 4) >> 4;
13769         gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
13770         /* No delay slot, so just process as a normal instruction */
13771         break;
13772     case M16_OPC_JAL:
13773         offset = cpu_lduw_code(env, ctx->base.pc_next + 2);
13774         offset = (((ctx->opcode & 0x1f) << 21)
13775                   | ((ctx->opcode >> 5) & 0x1f) << 16
13776                   | offset) << 2;
13777         op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
13778         gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
13779         n_bytes = 4;
13780         break;
13781     case M16_OPC_BEQZ:
13782         gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
13783                            ((int8_t)ctx->opcode) << 1, 0);
13784         /* No delay slot, so just process as a normal instruction */
13785         break;
13786     case M16_OPC_BNEQZ:
13787         gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
13788                            ((int8_t)ctx->opcode) << 1, 0);
13789         /* No delay slot, so just process as a normal instruction */
13790         break;
13791     case M16_OPC_SHIFT:
13792         switch (ctx->opcode & 0x3) {
13793         case 0x0:
13794             gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
13795             break;
13796         case 0x1:
13797 #if defined(TARGET_MIPS64)
13798             check_insn(ctx, ISA_MIPS3);
13799             check_mips_64(ctx);
13800             gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
13801 #else
13802             generate_exception_end(ctx, EXCP_RI);
13803 #endif
13804             break;
13805         case 0x2:
13806             gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
13807             break;
13808         case 0x3:
13809             gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
13810             break;
13811         }
13812         break;
13813 #if defined(TARGET_MIPS64)
13814     case M16_OPC_LD:
13815         check_insn(ctx, ISA_MIPS3);
13816         check_mips_64(ctx);
13817         gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
13818         break;
13819 #endif
13820     case M16_OPC_RRIA:
13821         {
13822             int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
13823
13824             if ((ctx->opcode >> 4) & 1) {
13825 #if defined(TARGET_MIPS64)
13826                 check_insn(ctx, ISA_MIPS3);
13827                 check_mips_64(ctx);
13828                 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
13829 #else
13830                 generate_exception_end(ctx, EXCP_RI);
13831 #endif
13832             } else {
13833                 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
13834             }
13835         }
13836         break;
13837     case M16_OPC_ADDIU8:
13838         {
13839             int16_t imm = (int8_t) ctx->opcode;
13840
13841             gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
13842         }
13843         break;
13844     case M16_OPC_SLTI:
13845         {
13846             int16_t imm = (uint8_t) ctx->opcode;
13847             gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
13848         }
13849         break;
13850     case M16_OPC_SLTIU:
13851         {
13852             int16_t imm = (uint8_t) ctx->opcode;
13853             gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
13854         }
13855         break;
13856     case M16_OPC_I8:
13857         {
13858             int reg32;
13859
13860             funct = (ctx->opcode >> 8) & 0x7;
13861             switch (funct) {
13862             case I8_BTEQZ:
13863                 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
13864                                    ((int8_t)ctx->opcode) << 1, 0);
13865                 break;
13866             case I8_BTNEZ:
13867                 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
13868                                    ((int8_t)ctx->opcode) << 1, 0);
13869                 break;
13870             case I8_SWRASP:
13871                 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
13872                 break;
13873             case I8_ADJSP:
13874                 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
13875                               ((int8_t)ctx->opcode) << 3);
13876                 break;
13877             case I8_SVRS:
13878                 check_insn(ctx, ISA_MIPS32);
13879                 {
13880                     int do_ra = ctx->opcode & (1 << 6);
13881                     int do_s0 = ctx->opcode & (1 << 5);
13882                     int do_s1 = ctx->opcode & (1 << 4);
13883                     int framesize = ctx->opcode & 0xf;
13884
13885                     if (framesize == 0) {
13886                         framesize = 128;
13887                     } else {
13888                         framesize = framesize << 3;
13889                     }
13890
13891                     if (ctx->opcode & (1 << 7)) {
13892                         gen_mips16_save(ctx, 0, 0,
13893                                         do_ra, do_s0, do_s1, framesize);
13894                     } else {
13895                         gen_mips16_restore(ctx, 0, 0,
13896                                            do_ra, do_s0, do_s1, framesize);
13897                     }
13898                 }
13899                 break;
13900             case I8_MOV32R:
13901                 {
13902                     int rz = xlat(ctx->opcode & 0x7);
13903
13904                     reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
13905                         ((ctx->opcode >> 5) & 0x7);
13906                     gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
13907                 }
13908                 break;
13909             case I8_MOVR32:
13910                 reg32 = ctx->opcode & 0x1f;
13911                 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
13912                 break;
13913             default:
13914                 generate_exception_end(ctx, EXCP_RI);
13915                 break;
13916             }
13917         }
13918         break;
13919     case M16_OPC_LI:
13920         {
13921             int16_t imm = (uint8_t) ctx->opcode;
13922
13923             gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
13924         }
13925         break;
13926     case M16_OPC_CMPI:
13927         {
13928             int16_t imm = (uint8_t) ctx->opcode;
13929             gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
13930         }
13931         break;
13932 #if defined(TARGET_MIPS64)
13933     case M16_OPC_SD:
13934         check_insn(ctx, ISA_MIPS3);
13935         check_mips_64(ctx);
13936         gen_st(ctx, OPC_SD, ry, rx, offset << 3);
13937         break;
13938 #endif
13939     case M16_OPC_LB:
13940         gen_ld(ctx, OPC_LB, ry, rx, offset);
13941         break;
13942     case M16_OPC_LH:
13943         gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
13944         break;
13945     case M16_OPC_LWSP:
13946         gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
13947         break;
13948     case M16_OPC_LW:
13949         gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
13950         break;
13951     case M16_OPC_LBU:
13952         gen_ld(ctx, OPC_LBU, ry, rx, offset);
13953         break;
13954     case M16_OPC_LHU:
13955         gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
13956         break;
13957     case M16_OPC_LWPC:
13958         gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
13959         break;
13960 #if defined (TARGET_MIPS64)
13961     case M16_OPC_LWU:
13962         check_insn(ctx, ISA_MIPS3);
13963         check_mips_64(ctx);
13964         gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
13965         break;
13966 #endif
13967     case M16_OPC_SB:
13968         gen_st(ctx, OPC_SB, ry, rx, offset);
13969         break;
13970     case M16_OPC_SH:
13971         gen_st(ctx, OPC_SH, ry, rx, offset << 1);
13972         break;
13973     case M16_OPC_SWSP:
13974         gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
13975         break;
13976     case M16_OPC_SW:
13977         gen_st(ctx, OPC_SW, ry, rx, offset << 2);
13978         break;
13979     case M16_OPC_RRR:
13980         {
13981             int rz = xlat((ctx->opcode >> 2) & 0x7);
13982             int mips32_op;
13983
13984             switch (ctx->opcode & 0x3) {
13985             case RRR_ADDU:
13986                 mips32_op = OPC_ADDU;
13987                 break;
13988             case RRR_SUBU:
13989                 mips32_op = OPC_SUBU;
13990                 break;
13991 #if defined(TARGET_MIPS64)
13992             case RRR_DADDU:
13993                 mips32_op = OPC_DADDU;
13994                 check_insn(ctx, ISA_MIPS3);
13995                 check_mips_64(ctx);
13996                 break;
13997             case RRR_DSUBU:
13998                 mips32_op = OPC_DSUBU;
13999                 check_insn(ctx, ISA_MIPS3);
14000                 check_mips_64(ctx);
14001                 break;
14002 #endif
14003             default:
14004                 generate_exception_end(ctx, EXCP_RI);
14005                 goto done;
14006             }
14007
14008             gen_arith(ctx, mips32_op, rz, rx, ry);
14009         done:
14010             ;
14011         }
14012         break;
14013     case M16_OPC_RR:
14014         switch (op1) {
14015         case RR_JR:
14016             {
14017                 int nd = (ctx->opcode >> 7) & 0x1;
14018                 int link = (ctx->opcode >> 6) & 0x1;
14019                 int ra = (ctx->opcode >> 5) & 0x1;
14020
14021                 if (nd) {
14022                     check_insn(ctx, ISA_MIPS32);
14023                 }
14024
14025                 if (link) {
14026                     op = OPC_JALR;
14027                 } else {
14028                     op = OPC_JR;
14029                 }
14030
14031                 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
14032                                    (nd ? 0 : 2));
14033             }
14034             break;
14035         case RR_SDBBP:
14036             if (is_uhi(extract32(ctx->opcode, 5, 6))) {
14037                 gen_helper_do_semihosting(cpu_env);
14038             } else {
14039                 /* XXX: not clear which exception should be raised
14040                  *      when in debug mode...
14041                  */
14042                 check_insn(ctx, ISA_MIPS32);
14043                 generate_exception_end(ctx, EXCP_DBp);
14044             }
14045             break;
14046         case RR_SLT:
14047             gen_slt(ctx, OPC_SLT, 24, rx, ry);
14048             break;
14049         case RR_SLTU:
14050             gen_slt(ctx, OPC_SLTU, 24, rx, ry);
14051             break;
14052         case RR_BREAK:
14053             generate_exception_end(ctx, EXCP_BREAK);
14054             break;
14055         case RR_SLLV:
14056             gen_shift(ctx, OPC_SLLV, ry, rx, ry);
14057             break;
14058         case RR_SRLV:
14059             gen_shift(ctx, OPC_SRLV, ry, rx, ry);
14060             break;
14061         case RR_SRAV:
14062             gen_shift(ctx, OPC_SRAV, ry, rx, ry);
14063             break;
14064 #if defined (TARGET_MIPS64)
14065         case RR_DSRL:
14066             check_insn(ctx, ISA_MIPS3);
14067             check_mips_64(ctx);
14068             gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
14069             break;
14070 #endif
14071         case RR_CMP:
14072             gen_logic(ctx, OPC_XOR, 24, rx, ry);
14073             break;
14074         case RR_NEG:
14075             gen_arith(ctx, OPC_SUBU, rx, 0, ry);
14076             break;
14077         case RR_AND:
14078             gen_logic(ctx, OPC_AND, rx, rx, ry);
14079             break;
14080         case RR_OR:
14081             gen_logic(ctx, OPC_OR, rx, rx, ry);
14082             break;
14083         case RR_XOR:
14084             gen_logic(ctx, OPC_XOR, rx, rx, ry);
14085             break;
14086         case RR_NOT:
14087             gen_logic(ctx, OPC_NOR, rx, ry, 0);
14088             break;
14089         case RR_MFHI:
14090             gen_HILO(ctx, OPC_MFHI, 0, rx);
14091             break;
14092         case RR_CNVT:
14093             check_insn(ctx, ISA_MIPS32);
14094             switch (cnvt_op) {
14095             case RR_RY_CNVT_ZEB:
14096                 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14097                 break;
14098             case RR_RY_CNVT_ZEH:
14099                 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14100                 break;
14101             case RR_RY_CNVT_SEB:
14102                 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14103                 break;
14104             case RR_RY_CNVT_SEH:
14105                 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14106                 break;
14107 #if defined (TARGET_MIPS64)
14108             case RR_RY_CNVT_ZEW:
14109                 check_insn(ctx, ISA_MIPS64);
14110                 check_mips_64(ctx);
14111                 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14112                 break;
14113             case RR_RY_CNVT_SEW:
14114                 check_insn(ctx, ISA_MIPS64);
14115                 check_mips_64(ctx);
14116                 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14117                 break;
14118 #endif
14119             default:
14120                 generate_exception_end(ctx, EXCP_RI);
14121                 break;
14122             }
14123             break;
14124         case RR_MFLO:
14125             gen_HILO(ctx, OPC_MFLO, 0, rx);
14126             break;
14127 #if defined (TARGET_MIPS64)
14128         case RR_DSRA:
14129             check_insn(ctx, ISA_MIPS3);
14130             check_mips_64(ctx);
14131             gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
14132             break;
14133         case RR_DSLLV:
14134             check_insn(ctx, ISA_MIPS3);
14135             check_mips_64(ctx);
14136             gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
14137             break;
14138         case RR_DSRLV:
14139             check_insn(ctx, ISA_MIPS3);
14140             check_mips_64(ctx);
14141             gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
14142             break;
14143         case RR_DSRAV:
14144             check_insn(ctx, ISA_MIPS3);
14145             check_mips_64(ctx);
14146             gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
14147             break;
14148 #endif
14149         case RR_MULT:
14150             gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
14151             break;
14152         case RR_MULTU:
14153             gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
14154             break;
14155         case RR_DIV:
14156             gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
14157             break;
14158         case RR_DIVU:
14159             gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
14160             break;
14161 #if defined (TARGET_MIPS64)
14162         case RR_DMULT:
14163             check_insn(ctx, ISA_MIPS3);
14164             check_mips_64(ctx);
14165             gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
14166             break;
14167         case RR_DMULTU:
14168             check_insn(ctx, ISA_MIPS3);
14169             check_mips_64(ctx);
14170             gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
14171             break;
14172         case RR_DDIV:
14173             check_insn(ctx, ISA_MIPS3);
14174             check_mips_64(ctx);
14175             gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
14176             break;
14177         case RR_DDIVU:
14178             check_insn(ctx, ISA_MIPS3);
14179             check_mips_64(ctx);
14180             gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
14181             break;
14182 #endif
14183         default:
14184             generate_exception_end(ctx, EXCP_RI);
14185             break;
14186         }
14187         break;
14188     case M16_OPC_EXTEND:
14189         decode_extended_mips16_opc(env, ctx);
14190         n_bytes = 4;
14191         break;
14192 #if defined(TARGET_MIPS64)
14193     case M16_OPC_I64:
14194         funct = (ctx->opcode >> 8) & 0x7;
14195         decode_i64_mips16(ctx, ry, funct, offset, 0);
14196         break;
14197 #endif
14198     default:
14199         generate_exception_end(ctx, EXCP_RI);
14200         break;
14201     }
14202
14203     return n_bytes;
14204 }
14205
14206 /* microMIPS extension to MIPS32/MIPS64 */
14207
14208 /*
14209  * microMIPS32/microMIPS64 major opcodes
14210  *
14211  * 1. MIPS Architecture for Programmers Volume II-B:
14212  *      The microMIPS32 Instruction Set (Revision 3.05)
14213  *
14214  *    Table 6.2 microMIPS32 Encoding of Major Opcode Field
14215  *
14216  * 2. MIPS Architecture For Programmers Volume II-A:
14217  *      The MIPS64 Instruction Set (Revision 3.51)
14218  */
14219
14220 enum {
14221     POOL32A = 0x00,
14222     POOL16A = 0x01,
14223     LBU16 = 0x02,
14224     MOVE16 = 0x03,
14225     ADDI32 = 0x04,
14226     R6_LUI = 0x04,
14227     AUI = 0x04,
14228     LBU32 = 0x05,
14229     SB32 = 0x06,
14230     LB32 = 0x07,
14231
14232     POOL32B = 0x08,
14233     POOL16B = 0x09,
14234     LHU16 = 0x0a,
14235     ANDI16 = 0x0b,
14236     ADDIU32 = 0x0c,
14237     LHU32 = 0x0d,
14238     SH32 = 0x0e,
14239     LH32 = 0x0f,
14240
14241     POOL32I = 0x10,
14242     POOL16C = 0x11,
14243     LWSP16 = 0x12,
14244     POOL16D = 0x13,
14245     ORI32 = 0x14,
14246     POOL32F = 0x15,
14247     POOL32S = 0x16,  /* MIPS64 */
14248     DADDIU32 = 0x17, /* MIPS64 */
14249
14250     POOL32C = 0x18,
14251     LWGP16 = 0x19,
14252     LW16 = 0x1a,
14253     POOL16E = 0x1b,
14254     XORI32 = 0x1c,
14255     JALS32 = 0x1d,
14256     BOVC = 0x1d,
14257     BEQC = 0x1d,
14258     BEQZALC = 0x1d,
14259     ADDIUPC = 0x1e,
14260     PCREL = 0x1e,
14261     BNVC = 0x1f,
14262     BNEC = 0x1f,
14263     BNEZALC = 0x1f,
14264
14265     R6_BEQZC = 0x20,
14266     JIC = 0x20,
14267     POOL16F = 0x21,
14268     SB16 = 0x22,
14269     BEQZ16 = 0x23,
14270     BEQZC16 = 0x23,
14271     SLTI32 = 0x24,
14272     BEQ32 = 0x25,
14273     BC = 0x25,
14274     SWC132 = 0x26,
14275     LWC132 = 0x27,
14276
14277     /* 0x29 is reserved */
14278     RES_29 = 0x29,
14279     R6_BNEZC = 0x28,
14280     JIALC = 0x28,
14281     SH16 = 0x2a,
14282     BNEZ16 = 0x2b,
14283     BNEZC16 = 0x2b,
14284     SLTIU32 = 0x2c,
14285     BNE32 = 0x2d,
14286     BALC = 0x2d,
14287     SDC132 = 0x2e,
14288     LDC132 = 0x2f,
14289
14290     /* 0x31 is reserved */
14291     RES_31 = 0x31,
14292     BLEZALC = 0x30,
14293     BGEZALC = 0x30,
14294     BGEUC = 0x30,
14295     SWSP16 = 0x32,
14296     B16 = 0x33,
14297     BC16 = 0x33,
14298     ANDI32 = 0x34,
14299     J32 = 0x35,
14300     BGTZC = 0x35,
14301     BLTZC = 0x35,
14302     BLTC = 0x35,
14303     SD32 = 0x36, /* MIPS64 */
14304     LD32 = 0x37, /* MIPS64 */
14305
14306     /* 0x39 is reserved */
14307     RES_39 = 0x39,
14308     BGTZALC = 0x38,
14309     BLTZALC = 0x38,
14310     BLTUC = 0x38,
14311     SW16 = 0x3a,
14312     LI16 = 0x3b,
14313     JALX32 = 0x3c,
14314     JAL32 = 0x3d,
14315     BLEZC = 0x3d,
14316     BGEZC = 0x3d,
14317     BGEC = 0x3d,
14318     SW32 = 0x3e,
14319     LW32 = 0x3f
14320 };
14321
14322 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
14323 enum {
14324     ADDIUPC_00 = 0x00,
14325     ADDIUPC_01 = 0x01,
14326     ADDIUPC_02 = 0x02,
14327     ADDIUPC_03 = 0x03,
14328     ADDIUPC_04 = 0x04,
14329     ADDIUPC_05 = 0x05,
14330     ADDIUPC_06 = 0x06,
14331     ADDIUPC_07 = 0x07,
14332     AUIPC = 0x1e,
14333     ALUIPC = 0x1f,
14334     LWPC_08 = 0x08,
14335     LWPC_09 = 0x09,
14336     LWPC_0A = 0x0A,
14337     LWPC_0B = 0x0B,
14338     LWPC_0C = 0x0C,
14339     LWPC_0D = 0x0D,
14340     LWPC_0E = 0x0E,
14341     LWPC_0F = 0x0F,
14342 };
14343
14344 /* POOL32A encoding of minor opcode field */
14345
14346 enum {
14347     /* These opcodes are distinguished only by bits 9..6; those bits are
14348      * what are recorded below. */
14349     SLL32 = 0x0,
14350     SRL32 = 0x1,
14351     SRA = 0x2,
14352     ROTR = 0x3,
14353     SELEQZ = 0x5,
14354     SELNEZ = 0x6,
14355     R6_RDHWR = 0x7,
14356
14357     SLLV = 0x0,
14358     SRLV = 0x1,
14359     SRAV = 0x2,
14360     ROTRV = 0x3,
14361     ADD = 0x4,
14362     ADDU32 = 0x5,
14363     SUB = 0x6,
14364     SUBU32 = 0x7,
14365     MUL = 0x8,
14366     AND = 0x9,
14367     OR32 = 0xa,
14368     NOR = 0xb,
14369     XOR32 = 0xc,
14370     SLT = 0xd,
14371     SLTU = 0xe,
14372
14373     MOVN = 0x0,
14374     R6_MUL  = 0x0,
14375     MOVZ = 0x1,
14376     MUH  = 0x1,
14377     MULU = 0x2,
14378     MUHU = 0x3,
14379     LWXS = 0x4,
14380     R6_DIV  = 0x4,
14381     MOD  = 0x5,
14382     R6_DIVU = 0x6,
14383     MODU = 0x7,
14384
14385     /* The following can be distinguished by their lower 6 bits. */
14386     BREAK32 = 0x07,
14387     INS = 0x0c,
14388     LSA = 0x0f,
14389     ALIGN = 0x1f,
14390     EXT = 0x2c,
14391     POOL32AXF = 0x3c,
14392     SIGRIE = 0x3f
14393 };
14394
14395 /* POOL32AXF encoding of minor opcode field extension */
14396
14397 /*
14398  * 1. MIPS Architecture for Programmers Volume II-B:
14399  *      The microMIPS32 Instruction Set (Revision 3.05)
14400  *
14401  *    Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
14402  *
14403  * 2. MIPS Architecture for Programmers VolumeIV-e:
14404  *      The MIPS DSP Application-Specific Extension
14405  *        to the microMIPS32 Architecture (Revision 2.34)
14406  *
14407  *    Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
14408  */
14409
14410 enum {
14411     /* bits 11..6 */
14412     TEQ = 0x00,
14413     TGE = 0x08,
14414     TGEU = 0x10,
14415     TLT = 0x20,
14416     TLTU = 0x28,
14417     TNE = 0x30,
14418
14419     MFC0 = 0x03,
14420     MTC0 = 0x0b,
14421
14422     /* begin of microMIPS32 DSP */
14423
14424     /* bits 13..12 for 0x01 */
14425     MFHI_ACC = 0x0,
14426     MFLO_ACC = 0x1,
14427     MTHI_ACC = 0x2,
14428     MTLO_ACC = 0x3,
14429
14430     /* bits 13..12 for 0x2a */
14431     MADD_ACC = 0x0,
14432     MADDU_ACC = 0x1,
14433     MSUB_ACC = 0x2,
14434     MSUBU_ACC = 0x3,
14435
14436     /* bits 13..12 for 0x32 */
14437     MULT_ACC = 0x0,
14438     MULTU_ACC = 0x1,
14439
14440     /* end of microMIPS32 DSP */
14441
14442     /* bits 15..12 for 0x2c */
14443     BITSWAP = 0x0,
14444     SEB = 0x2,
14445     SEH = 0x3,
14446     CLO = 0x4,
14447     CLZ = 0x5,
14448     RDHWR = 0x6,
14449     WSBH = 0x7,
14450     MULT = 0x8,
14451     MULTU = 0x9,
14452     DIV = 0xa,
14453     DIVU = 0xb,
14454     MADD = 0xc,
14455     MADDU = 0xd,
14456     MSUB = 0xe,
14457     MSUBU = 0xf,
14458
14459     /* bits 15..12 for 0x34 */
14460     MFC2 = 0x4,
14461     MTC2 = 0x5,
14462     MFHC2 = 0x8,
14463     MTHC2 = 0x9,
14464     CFC2 = 0xc,
14465     CTC2 = 0xd,
14466
14467     /* bits 15..12 for 0x3c */
14468     JALR = 0x0,
14469     JR = 0x0,                   /* alias */
14470     JALRC = 0x0,
14471     JRC = 0x0,
14472     JALR_HB = 0x1,
14473     JALRC_HB = 0x1,
14474     JALRS = 0x4,
14475     JALRS_HB = 0x5,
14476
14477     /* bits 15..12 for 0x05 */
14478     RDPGPR = 0xe,
14479     WRPGPR = 0xf,
14480
14481     /* bits 15..12 for 0x0d */
14482     TLBP = 0x0,
14483     TLBR = 0x1,
14484     TLBWI = 0x2,
14485     TLBWR = 0x3,
14486     TLBINV = 0x4,
14487     TLBINVF = 0x5,
14488     WAIT = 0x9,
14489     IRET = 0xd,
14490     DERET = 0xe,
14491     ERET = 0xf,
14492
14493     /* bits 15..12 for 0x15 */
14494     DMT = 0x0,
14495     DVPE = 0x1,
14496     EMT = 0x2,
14497     EVPE = 0x3,
14498
14499     /* bits 15..12 for 0x1d */
14500     DI = 0x4,
14501     EI = 0x5,
14502
14503     /* bits 15..12 for 0x2d */
14504     SYNC = 0x6,
14505     SYSCALL = 0x8,
14506     SDBBP = 0xd,
14507
14508     /* bits 15..12 for 0x35 */
14509     MFHI32 = 0x0,
14510     MFLO32 = 0x1,
14511     MTHI32 = 0x2,
14512     MTLO32 = 0x3,
14513 };
14514
14515 /* POOL32B encoding of minor opcode field (bits 15..12) */
14516
14517 enum {
14518     LWC2 = 0x0,
14519     LWP = 0x1,
14520     LDP = 0x4,
14521     LWM32 = 0x5,
14522     CACHE = 0x6,
14523     LDM = 0x7,
14524     SWC2 = 0x8,
14525     SWP = 0x9,
14526     SDP = 0xc,
14527     SWM32 = 0xd,
14528     SDM = 0xf
14529 };
14530
14531 /* POOL32C encoding of minor opcode field (bits 15..12) */
14532
14533 enum {
14534     LWL = 0x0,
14535     SWL = 0x8,
14536     LWR = 0x1,
14537     SWR = 0x9,
14538     PREF = 0x2,
14539     ST_EVA = 0xa,
14540     LL = 0x3,
14541     SC = 0xb,
14542     LDL = 0x4,
14543     SDL = 0xc,
14544     LDR = 0x5,
14545     SDR = 0xd,
14546     LD_EVA = 0x6,
14547     LWU = 0xe,
14548     LLD = 0x7,
14549     SCD = 0xf
14550 };
14551
14552 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
14553
14554 enum {
14555     LBUE = 0x0,
14556     LHUE = 0x1,
14557     LWLE = 0x2,
14558     LWRE = 0x3,
14559     LBE = 0x4,
14560     LHE = 0x5,
14561     LLE = 0x6,
14562     LWE = 0x7,
14563 };
14564
14565 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
14566
14567 enum {
14568     SWLE = 0x0,
14569     SWRE = 0x1,
14570     PREFE = 0x2,
14571     CACHEE = 0x3,
14572     SBE = 0x4,
14573     SHE = 0x5,
14574     SCE = 0x6,
14575     SWE = 0x7,
14576 };
14577
14578 /* POOL32F encoding of minor opcode field (bits 5..0) */
14579
14580 enum {
14581     /* These are the bit 7..6 values */
14582     ADD_FMT = 0x0,
14583
14584     SUB_FMT = 0x1,
14585
14586     MUL_FMT = 0x2,
14587
14588     DIV_FMT = 0x3,
14589
14590     /* These are the bit 8..6 values */
14591     MOVN_FMT = 0x0,
14592     RSQRT2_FMT = 0x0,
14593     MOVF_FMT = 0x0,
14594     RINT_FMT = 0x0,
14595     SELNEZ_FMT = 0x0,
14596
14597     MOVZ_FMT = 0x1,
14598     LWXC1 = 0x1,
14599     MOVT_FMT = 0x1,
14600     CLASS_FMT = 0x1,
14601     SELEQZ_FMT = 0x1,
14602
14603     PLL_PS = 0x2,
14604     SWXC1 = 0x2,
14605     SEL_FMT = 0x2,
14606
14607     PLU_PS = 0x3,
14608     LDXC1 = 0x3,
14609
14610     MOVN_FMT_04 = 0x4,
14611     PUL_PS = 0x4,
14612     SDXC1 = 0x4,
14613     RECIP2_FMT = 0x4,
14614
14615     MOVZ_FMT_05 = 0x05,
14616     PUU_PS = 0x5,
14617     LUXC1 = 0x5,
14618
14619     CVT_PS_S = 0x6,
14620     SUXC1 = 0x6,
14621     ADDR_PS = 0x6,
14622     PREFX = 0x6,
14623     MADDF_FMT = 0x6,
14624
14625     MULR_PS = 0x7,
14626     MSUBF_FMT = 0x7,
14627
14628     MADD_S = 0x01,
14629     MADD_D = 0x09,
14630     MADD_PS = 0x11,
14631     ALNV_PS = 0x19,
14632     MSUB_S = 0x21,
14633     MSUB_D = 0x29,
14634     MSUB_PS = 0x31,
14635
14636     NMADD_S = 0x02,
14637     NMADD_D = 0x0a,
14638     NMADD_PS = 0x12,
14639     NMSUB_S = 0x22,
14640     NMSUB_D = 0x2a,
14641     NMSUB_PS = 0x32,
14642
14643     MIN_FMT = 0x3,
14644     MAX_FMT = 0xb,
14645     MINA_FMT = 0x23,
14646     MAXA_FMT = 0x2b,
14647     POOL32FXF = 0x3b,
14648
14649     CABS_COND_FMT = 0x1c,              /* MIPS3D */
14650     C_COND_FMT = 0x3c,
14651
14652     CMP_CONDN_S = 0x5,
14653     CMP_CONDN_D = 0x15
14654 };
14655
14656 /* POOL32Fxf encoding of minor opcode extension field */
14657
14658 enum {
14659     CVT_L = 0x04,
14660     RSQRT_FMT = 0x08,
14661     FLOOR_L = 0x0c,
14662     CVT_PW_PS = 0x1c,
14663     CVT_W = 0x24,
14664     SQRT_FMT = 0x28,
14665     FLOOR_W = 0x2c,
14666     CVT_PS_PW = 0x3c,
14667     CFC1 = 0x40,
14668     RECIP_FMT = 0x48,
14669     CEIL_L = 0x4c,
14670     CTC1 = 0x60,
14671     CEIL_W = 0x6c,
14672     MFC1 = 0x80,
14673     CVT_S_PL = 0x84,
14674     TRUNC_L = 0x8c,
14675     MTC1 = 0xa0,
14676     CVT_S_PU = 0xa4,
14677     TRUNC_W = 0xac,
14678     MFHC1 = 0xc0,
14679     ROUND_L = 0xcc,
14680     MTHC1 = 0xe0,
14681     ROUND_W = 0xec,
14682
14683     MOV_FMT = 0x01,
14684     MOVF = 0x05,
14685     ABS_FMT = 0x0d,
14686     RSQRT1_FMT = 0x1d,
14687     MOVT = 0x25,
14688     NEG_FMT = 0x2d,
14689     CVT_D = 0x4d,
14690     RECIP1_FMT = 0x5d,
14691     CVT_S = 0x6d
14692 };
14693
14694 /* POOL32I encoding of minor opcode field (bits 25..21) */
14695
14696 enum {
14697     BLTZ = 0x00,
14698     BLTZAL = 0x01,
14699     BGEZ = 0x02,
14700     BGEZAL = 0x03,
14701     BLEZ = 0x04,
14702     BNEZC = 0x05,
14703     BGTZ = 0x06,
14704     BEQZC = 0x07,
14705     TLTI = 0x08,
14706     BC1EQZC = 0x08,
14707     TGEI = 0x09,
14708     BC1NEZC = 0x09,
14709     TLTIU = 0x0a,
14710     BC2EQZC = 0x0a,
14711     TGEIU = 0x0b,
14712     BC2NEZC = 0x0a,
14713     TNEI = 0x0c,
14714     R6_SYNCI = 0x0c,
14715     LUI = 0x0d,
14716     TEQI = 0x0e,
14717     SYNCI = 0x10,
14718     BLTZALS = 0x11,
14719     BGEZALS = 0x13,
14720     BC2F = 0x14,
14721     BC2T = 0x15,
14722     BPOSGE64 = 0x1a,
14723     BPOSGE32 = 0x1b,
14724     /* These overlap and are distinguished by bit16 of the instruction */
14725     BC1F = 0x1c,
14726     BC1T = 0x1d,
14727     BC1ANY2F = 0x1c,
14728     BC1ANY2T = 0x1d,
14729     BC1ANY4F = 0x1e,
14730     BC1ANY4T = 0x1f
14731 };
14732
14733 /* POOL16A encoding of minor opcode field */
14734
14735 enum {
14736     ADDU16 = 0x0,
14737     SUBU16 = 0x1
14738 };
14739
14740 /* POOL16B encoding of minor opcode field */
14741
14742 enum {
14743     SLL16 = 0x0,
14744     SRL16 = 0x1
14745 };
14746
14747 /* POOL16C encoding of minor opcode field */
14748
14749 enum {
14750     NOT16 = 0x00,
14751     XOR16 = 0x04,
14752     AND16 = 0x08,
14753     OR16 = 0x0c,
14754     LWM16 = 0x10,
14755     SWM16 = 0x14,
14756     JR16 = 0x18,
14757     JRC16 = 0x1a,
14758     JALR16 = 0x1c,
14759     JALR16S = 0x1e,
14760     MFHI16 = 0x20,
14761     MFLO16 = 0x24,
14762     BREAK16 = 0x28,
14763     SDBBP16 = 0x2c,
14764     JRADDIUSP = 0x30
14765 };
14766
14767 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
14768
14769 enum {
14770     R6_NOT16    = 0x00,
14771     R6_AND16    = 0x01,
14772     R6_LWM16    = 0x02,
14773     R6_JRC16    = 0x03,
14774     MOVEP       = 0x04,
14775     MOVEP_05    = 0x05,
14776     MOVEP_06    = 0x06,
14777     MOVEP_07    = 0x07,
14778     R6_XOR16    = 0x08,
14779     R6_OR16     = 0x09,
14780     R6_SWM16    = 0x0a,
14781     JALRC16     = 0x0b,
14782     MOVEP_0C    = 0x0c,
14783     MOVEP_0D    = 0x0d,
14784     MOVEP_0E    = 0x0e,
14785     MOVEP_0F    = 0x0f,
14786     JRCADDIUSP  = 0x13,
14787     R6_BREAK16  = 0x1b,
14788     R6_SDBBP16  = 0x3b
14789 };
14790
14791 /* POOL16D encoding of minor opcode field */
14792
14793 enum {
14794     ADDIUS5 = 0x0,
14795     ADDIUSP = 0x1
14796 };
14797
14798 /* POOL16E encoding of minor opcode field */
14799
14800 enum {
14801     ADDIUR2 = 0x0,
14802     ADDIUR1SP = 0x1
14803 };
14804
14805 static int mmreg (int r)
14806 {
14807     static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
14808
14809     return map[r];
14810 }
14811
14812 /* Used for 16-bit store instructions.  */
14813 static int mmreg2 (int r)
14814 {
14815     static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
14816
14817     return map[r];
14818 }
14819
14820 #define uMIPS_RD(op) ((op >> 7) & 0x7)
14821 #define uMIPS_RS(op) ((op >> 4) & 0x7)
14822 #define uMIPS_RS2(op) uMIPS_RS(op)
14823 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
14824 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
14825 #define uMIPS_RS5(op) (op & 0x1f)
14826
14827 /* Signed immediate */
14828 #define SIMM(op, start, width)                                          \
14829     ((int32_t)(((op >> start) & ((~0U) >> (32-width)))                 \
14830                << (32-width))                                           \
14831      >> (32-width))
14832 /* Zero-extended immediate */
14833 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
14834
14835 static void gen_addiur1sp(DisasContext *ctx)
14836 {
14837     int rd = mmreg(uMIPS_RD(ctx->opcode));
14838
14839     gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
14840 }
14841
14842 static void gen_addiur2(DisasContext *ctx)
14843 {
14844     static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
14845     int rd = mmreg(uMIPS_RD(ctx->opcode));
14846     int rs = mmreg(uMIPS_RS(ctx->opcode));
14847
14848     gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
14849 }
14850
14851 static void gen_addiusp(DisasContext *ctx)
14852 {
14853     int encoded = ZIMM(ctx->opcode, 1, 9);
14854     int decoded;
14855
14856     if (encoded <= 1) {
14857         decoded = 256 + encoded;
14858     } else if (encoded <= 255) {
14859         decoded = encoded;
14860     } else if (encoded <= 509) {
14861         decoded = encoded - 512;
14862     } else {
14863         decoded = encoded - 768;
14864     }
14865
14866     gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
14867 }
14868
14869 static void gen_addius5(DisasContext *ctx)
14870 {
14871     int imm = SIMM(ctx->opcode, 1, 4);
14872     int rd = (ctx->opcode >> 5) & 0x1f;
14873
14874     gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
14875 }
14876
14877 static void gen_andi16(DisasContext *ctx)
14878 {
14879     static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
14880                                  31, 32, 63, 64, 255, 32768, 65535 };
14881     int rd = mmreg(uMIPS_RD(ctx->opcode));
14882     int rs = mmreg(uMIPS_RS(ctx->opcode));
14883     int encoded = ZIMM(ctx->opcode, 0, 4);
14884
14885     gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
14886 }
14887
14888 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
14889                                int base, int16_t offset)
14890 {
14891     TCGv t0, t1;
14892     TCGv_i32 t2;
14893
14894     if (ctx->hflags & MIPS_HFLAG_BMASK) {
14895         generate_exception_end(ctx, EXCP_RI);
14896         return;
14897     }
14898
14899     t0 = tcg_temp_new();
14900
14901     gen_base_offset_addr(ctx, t0, base, offset);
14902
14903     t1 = tcg_const_tl(reglist);
14904     t2 = tcg_const_i32(ctx->mem_idx);
14905
14906     save_cpu_state(ctx, 1);
14907     switch (opc) {
14908     case LWM32:
14909         gen_helper_lwm(cpu_env, t0, t1, t2);
14910         break;
14911     case SWM32:
14912         gen_helper_swm(cpu_env, t0, t1, t2);
14913         break;
14914 #ifdef TARGET_MIPS64
14915     case LDM:
14916         gen_helper_ldm(cpu_env, t0, t1, t2);
14917         break;
14918     case SDM:
14919         gen_helper_sdm(cpu_env, t0, t1, t2);
14920         break;
14921 #endif
14922     }
14923     tcg_temp_free(t0);
14924     tcg_temp_free(t1);
14925     tcg_temp_free_i32(t2);
14926 }
14927
14928
14929 static void gen_pool16c_insn(DisasContext *ctx)
14930 {
14931     int rd = mmreg((ctx->opcode >> 3) & 0x7);
14932     int rs = mmreg(ctx->opcode & 0x7);
14933
14934     switch (((ctx->opcode) >> 4) & 0x3f) {
14935     case NOT16 + 0:
14936     case NOT16 + 1:
14937     case NOT16 + 2:
14938     case NOT16 + 3:
14939         gen_logic(ctx, OPC_NOR, rd, rs, 0);
14940         break;
14941     case XOR16 + 0:
14942     case XOR16 + 1:
14943     case XOR16 + 2:
14944     case XOR16 + 3:
14945         gen_logic(ctx, OPC_XOR, rd, rd, rs);
14946         break;
14947     case AND16 + 0:
14948     case AND16 + 1:
14949     case AND16 + 2:
14950     case AND16 + 3:
14951         gen_logic(ctx, OPC_AND, rd, rd, rs);
14952         break;
14953     case OR16 + 0:
14954     case OR16 + 1:
14955     case OR16 + 2:
14956     case OR16 + 3:
14957         gen_logic(ctx, OPC_OR, rd, rd, rs);
14958         break;
14959     case LWM16 + 0:
14960     case LWM16 + 1:
14961     case LWM16 + 2:
14962     case LWM16 + 3:
14963         {
14964             static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14965             int offset = ZIMM(ctx->opcode, 0, 4);
14966
14967             gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
14968                               29, offset << 2);
14969         }
14970         break;
14971     case SWM16 + 0:
14972     case SWM16 + 1:
14973     case SWM16 + 2:
14974     case SWM16 + 3:
14975         {
14976             static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14977             int offset = ZIMM(ctx->opcode, 0, 4);
14978
14979             gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
14980                               29, offset << 2);
14981         }
14982         break;
14983     case JR16 + 0:
14984     case JR16 + 1:
14985         {
14986             int reg = ctx->opcode & 0x1f;
14987
14988             gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
14989         }
14990         break;
14991     case JRC16 + 0:
14992     case JRC16 + 1:
14993         {
14994             int reg = ctx->opcode & 0x1f;
14995             gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
14996             /* Let normal delay slot handling in our caller take us
14997                to the branch target.  */
14998         }
14999         break;
15000     case JALR16 + 0:
15001     case JALR16 + 1:
15002         gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
15003         ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15004         break;
15005     case JALR16S + 0:
15006     case JALR16S + 1:
15007         gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
15008         ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15009         break;
15010     case MFHI16 + 0:
15011     case MFHI16 + 1:
15012         gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
15013         break;
15014     case MFLO16 + 0:
15015     case MFLO16 + 1:
15016         gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
15017         break;
15018     case BREAK16:
15019         generate_exception_end(ctx, EXCP_BREAK);
15020         break;
15021     case SDBBP16:
15022         if (is_uhi(extract32(ctx->opcode, 0, 4))) {
15023             gen_helper_do_semihosting(cpu_env);
15024         } else {
15025             /* XXX: not clear which exception should be raised
15026              *      when in debug mode...
15027              */
15028             check_insn(ctx, ISA_MIPS32);
15029             generate_exception_end(ctx, EXCP_DBp);
15030         }
15031         break;
15032     case JRADDIUSP + 0:
15033     case JRADDIUSP + 1:
15034         {
15035             int imm = ZIMM(ctx->opcode, 0, 5);
15036             gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
15037             gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
15038             /* Let normal delay slot handling in our caller take us
15039                to the branch target.  */
15040         }
15041         break;
15042     default:
15043         generate_exception_end(ctx, EXCP_RI);
15044         break;
15045     }
15046 }
15047
15048 static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
15049                              int enc_rs)
15050 {
15051     int rd, rs, re, rt;
15052     static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
15053     static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
15054     static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
15055     rd = rd_enc[enc_dest];
15056     re = re_enc[enc_dest];
15057     rs = rs_rt_enc[enc_rs];
15058     rt = rs_rt_enc[enc_rt];
15059     if (rs) {
15060         tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
15061     } else {
15062         tcg_gen_movi_tl(cpu_gpr[rd], 0);
15063     }
15064     if (rt) {
15065         tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
15066     } else {
15067         tcg_gen_movi_tl(cpu_gpr[re], 0);
15068     }
15069 }
15070
15071 static void gen_pool16c_r6_insn(DisasContext *ctx)
15072 {
15073     int rt = mmreg((ctx->opcode >> 7) & 0x7);
15074     int rs = mmreg((ctx->opcode >> 4) & 0x7);
15075
15076     switch (ctx->opcode & 0xf) {
15077     case R6_NOT16:
15078         gen_logic(ctx, OPC_NOR, rt, rs, 0);
15079         break;
15080     case R6_AND16:
15081         gen_logic(ctx, OPC_AND, rt, rt, rs);
15082         break;
15083     case R6_LWM16:
15084         {
15085             int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
15086             int offset = extract32(ctx->opcode, 4, 4);
15087             gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
15088         }
15089         break;
15090     case R6_JRC16: /* JRCADDIUSP */
15091         if ((ctx->opcode >> 4) & 1) {
15092             /* JRCADDIUSP */
15093             int imm = extract32(ctx->opcode, 5, 5);
15094             gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
15095             gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
15096         } else {
15097             /* JRC16 */
15098             rs = extract32(ctx->opcode, 5, 5);
15099             gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
15100         }
15101         break;
15102     case MOVEP:
15103     case MOVEP_05:
15104     case MOVEP_06:
15105     case MOVEP_07:
15106     case MOVEP_0C:
15107     case MOVEP_0D:
15108     case MOVEP_0E:
15109     case MOVEP_0F:
15110         {
15111             int enc_dest = uMIPS_RD(ctx->opcode);
15112             int enc_rt = uMIPS_RS2(ctx->opcode);
15113             int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
15114             gen_movep(ctx, enc_dest, enc_rt, enc_rs);
15115         }
15116         break;
15117     case R6_XOR16:
15118         gen_logic(ctx, OPC_XOR, rt, rt, rs);
15119         break;
15120     case R6_OR16:
15121         gen_logic(ctx, OPC_OR, rt, rt, rs);
15122         break;
15123     case R6_SWM16:
15124         {
15125             int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
15126             int offset = extract32(ctx->opcode, 4, 4);
15127             gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
15128         }
15129         break;
15130     case JALRC16: /* BREAK16, SDBBP16 */
15131         switch (ctx->opcode & 0x3f) {
15132         case JALRC16:
15133         case JALRC16 + 0x20:
15134             /* JALRC16 */
15135             gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
15136                                31, 0, 0);
15137             break;
15138         case R6_BREAK16:
15139             /* BREAK16 */
15140             generate_exception(ctx, EXCP_BREAK);
15141             break;
15142         case R6_SDBBP16:
15143             /* SDBBP16 */
15144             if (is_uhi(extract32(ctx->opcode, 6, 4))) {
15145                 gen_helper_do_semihosting(cpu_env);
15146             } else {
15147                 if (ctx->hflags & MIPS_HFLAG_SBRI) {
15148                     generate_exception(ctx, EXCP_RI);
15149                 } else {
15150                     generate_exception(ctx, EXCP_DBp);
15151                 }
15152             }
15153             break;
15154         }
15155         break;
15156     default:
15157         generate_exception(ctx, EXCP_RI);
15158         break;
15159     }
15160 }
15161
15162 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
15163 {
15164     TCGv t0 = tcg_temp_new();
15165     TCGv t1 = tcg_temp_new();
15166
15167     gen_load_gpr(t0, base);
15168
15169     if (index != 0) {
15170         gen_load_gpr(t1, index);
15171         tcg_gen_shli_tl(t1, t1, 2);
15172         gen_op_addr_add(ctx, t0, t1, t0);
15173     }
15174
15175     tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15176     gen_store_gpr(t1, rd);
15177
15178     tcg_temp_free(t0);
15179     tcg_temp_free(t1);
15180 }
15181
15182 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
15183                            int base, int16_t offset)
15184 {
15185     TCGv t0, t1;
15186
15187     if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
15188         generate_exception_end(ctx, EXCP_RI);
15189         return;
15190     }
15191
15192     t0 = tcg_temp_new();
15193     t1 = tcg_temp_new();
15194
15195     gen_base_offset_addr(ctx, t0, base, offset);
15196
15197     switch (opc) {
15198     case LWP:
15199         if (rd == base) {
15200             generate_exception_end(ctx, EXCP_RI);
15201             return;
15202         }
15203         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15204         gen_store_gpr(t1, rd);
15205         tcg_gen_movi_tl(t1, 4);
15206         gen_op_addr_add(ctx, t0, t0, t1);
15207         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15208         gen_store_gpr(t1, rd+1);
15209         break;
15210     case SWP:
15211         gen_load_gpr(t1, rd);
15212         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
15213         tcg_gen_movi_tl(t1, 4);
15214         gen_op_addr_add(ctx, t0, t0, t1);
15215         gen_load_gpr(t1, rd+1);
15216         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
15217         break;
15218 #ifdef TARGET_MIPS64
15219     case LDP:
15220         if (rd == base) {
15221             generate_exception_end(ctx, EXCP_RI);
15222             return;
15223         }
15224         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15225         gen_store_gpr(t1, rd);
15226         tcg_gen_movi_tl(t1, 8);
15227         gen_op_addr_add(ctx, t0, t0, t1);
15228         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15229         gen_store_gpr(t1, rd+1);
15230         break;
15231     case SDP:
15232         gen_load_gpr(t1, rd);
15233         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15234         tcg_gen_movi_tl(t1, 8);
15235         gen_op_addr_add(ctx, t0, t0, t1);
15236         gen_load_gpr(t1, rd+1);
15237         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15238         break;
15239 #endif
15240     }
15241     tcg_temp_free(t0);
15242     tcg_temp_free(t1);
15243 }
15244
15245 static void gen_sync(int stype)
15246 {
15247     TCGBar tcg_mo = TCG_BAR_SC;
15248
15249     switch (stype) {
15250     case 0x4: /* SYNC_WMB */
15251         tcg_mo |= TCG_MO_ST_ST;
15252         break;
15253     case 0x10: /* SYNC_MB */
15254         tcg_mo |= TCG_MO_ALL;
15255         break;
15256     case 0x11: /* SYNC_ACQUIRE */
15257         tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
15258         break;
15259     case 0x12: /* SYNC_RELEASE */
15260         tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
15261         break;
15262     case 0x13: /* SYNC_RMB */
15263         tcg_mo |= TCG_MO_LD_LD;
15264         break;
15265     default:
15266         tcg_mo |= TCG_MO_ALL;
15267         break;
15268     }
15269
15270     tcg_gen_mb(tcg_mo);
15271 }
15272
15273 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
15274 {
15275     int extension = (ctx->opcode >> 6) & 0x3f;
15276     int minor = (ctx->opcode >> 12) & 0xf;
15277     uint32_t mips32_op;
15278
15279     switch (extension) {
15280     case TEQ:
15281         mips32_op = OPC_TEQ;
15282         goto do_trap;
15283     case TGE:
15284         mips32_op = OPC_TGE;
15285         goto do_trap;
15286     case TGEU:
15287         mips32_op = OPC_TGEU;
15288         goto do_trap;
15289     case TLT:
15290         mips32_op = OPC_TLT;
15291         goto do_trap;
15292     case TLTU:
15293         mips32_op = OPC_TLTU;
15294         goto do_trap;
15295     case TNE:
15296         mips32_op = OPC_TNE;
15297     do_trap:
15298         gen_trap(ctx, mips32_op, rs, rt, -1);
15299         break;
15300 #ifndef CONFIG_USER_ONLY
15301     case MFC0:
15302     case MFC0 + 32:
15303         check_cp0_enabled(ctx);
15304         if (rt == 0) {
15305             /* Treat as NOP. */
15306             break;
15307         }
15308         gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
15309         break;
15310     case MTC0:
15311     case MTC0 + 32:
15312         check_cp0_enabled(ctx);
15313         {
15314             TCGv t0 = tcg_temp_new();
15315
15316             gen_load_gpr(t0, rt);
15317             gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
15318             tcg_temp_free(t0);
15319         }
15320         break;
15321 #endif
15322     case 0x2a:
15323         switch (minor & 3) {
15324         case MADD_ACC:
15325             gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
15326             break;
15327         case MADDU_ACC:
15328             gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
15329             break;
15330         case MSUB_ACC:
15331             gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
15332             break;
15333         case MSUBU_ACC:
15334             gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
15335             break;
15336         default:
15337             goto pool32axf_invalid;
15338         }
15339         break;
15340     case 0x32:
15341         switch (minor & 3) {
15342         case MULT_ACC:
15343             gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
15344             break;
15345         case MULTU_ACC:
15346             gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
15347             break;
15348         default:
15349             goto pool32axf_invalid;
15350         }
15351         break;
15352     case 0x2c:
15353         switch (minor) {
15354         case BITSWAP:
15355             check_insn(ctx, ISA_MIPS32R6);
15356             gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
15357             break;
15358         case SEB:
15359             gen_bshfl(ctx, OPC_SEB, rs, rt);
15360             break;
15361         case SEH:
15362             gen_bshfl(ctx, OPC_SEH, rs, rt);
15363             break;
15364         case CLO:
15365             mips32_op = OPC_CLO;
15366             goto do_cl;
15367         case CLZ:
15368             mips32_op = OPC_CLZ;
15369         do_cl:
15370             check_insn(ctx, ISA_MIPS32);
15371             gen_cl(ctx, mips32_op, rt, rs);
15372             break;
15373         case RDHWR:
15374             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15375             gen_rdhwr(ctx, rt, rs, 0);
15376             break;
15377         case WSBH:
15378             gen_bshfl(ctx, OPC_WSBH, rs, rt);
15379             break;
15380         case MULT:
15381             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15382             mips32_op = OPC_MULT;
15383             goto do_mul;
15384         case MULTU:
15385             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15386             mips32_op = OPC_MULTU;
15387             goto do_mul;
15388         case DIV:
15389             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15390             mips32_op = OPC_DIV;
15391             goto do_div;
15392         case DIVU:
15393             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15394             mips32_op = OPC_DIVU;
15395             goto do_div;
15396         do_div:
15397             check_insn(ctx, ISA_MIPS32);
15398             gen_muldiv(ctx, mips32_op, 0, rs, rt);
15399             break;
15400         case MADD:
15401             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15402             mips32_op = OPC_MADD;
15403             goto do_mul;
15404         case MADDU:
15405             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15406             mips32_op = OPC_MADDU;
15407             goto do_mul;
15408         case MSUB:
15409             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15410             mips32_op = OPC_MSUB;
15411             goto do_mul;
15412         case MSUBU:
15413             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15414             mips32_op = OPC_MSUBU;
15415         do_mul:
15416             check_insn(ctx, ISA_MIPS32);
15417             gen_muldiv(ctx, mips32_op, 0, rs, rt);
15418             break;
15419         default:
15420             goto pool32axf_invalid;
15421         }
15422         break;
15423     case 0x34:
15424         switch (minor) {
15425         case MFC2:
15426         case MTC2:
15427         case MFHC2:
15428         case MTHC2:
15429         case CFC2:
15430         case CTC2:
15431             generate_exception_err(ctx, EXCP_CpU, 2);
15432             break;
15433         default:
15434             goto pool32axf_invalid;
15435         }
15436         break;
15437     case 0x3c:
15438         switch (minor) {
15439         case JALR:    /* JALRC */
15440         case JALR_HB: /* JALRC_HB */
15441             if (ctx->insn_flags & ISA_MIPS32R6) {
15442                 /* JALRC, JALRC_HB */
15443                 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
15444             } else {
15445                 /* JALR, JALR_HB */
15446                 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
15447                 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15448             }
15449             break;
15450         case JALRS:
15451         case JALRS_HB:
15452             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15453             gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
15454             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15455             break;
15456         default:
15457             goto pool32axf_invalid;
15458         }
15459         break;
15460     case 0x05:
15461         switch (minor) {
15462         case RDPGPR:
15463             check_cp0_enabled(ctx);
15464             check_insn(ctx, ISA_MIPS32R2);
15465             gen_load_srsgpr(rs, rt);
15466             break;
15467         case WRPGPR:
15468             check_cp0_enabled(ctx);
15469             check_insn(ctx, ISA_MIPS32R2);
15470             gen_store_srsgpr(rs, rt);
15471             break;
15472         default:
15473             goto pool32axf_invalid;
15474         }
15475         break;
15476 #ifndef CONFIG_USER_ONLY
15477     case 0x0d:
15478         switch (minor) {
15479         case TLBP:
15480             mips32_op = OPC_TLBP;
15481             goto do_cp0;
15482         case TLBR:
15483             mips32_op = OPC_TLBR;
15484             goto do_cp0;
15485         case TLBWI:
15486             mips32_op = OPC_TLBWI;
15487             goto do_cp0;
15488         case TLBWR:
15489             mips32_op = OPC_TLBWR;
15490             goto do_cp0;
15491         case TLBINV:
15492             mips32_op = OPC_TLBINV;
15493             goto do_cp0;
15494         case TLBINVF:
15495             mips32_op = OPC_TLBINVF;
15496             goto do_cp0;
15497         case WAIT:
15498             mips32_op = OPC_WAIT;
15499             goto do_cp0;
15500         case DERET:
15501             mips32_op = OPC_DERET;
15502             goto do_cp0;
15503         case ERET:
15504             mips32_op = OPC_ERET;
15505         do_cp0:
15506             gen_cp0(env, ctx, mips32_op, rt, rs);
15507             break;
15508         default:
15509             goto pool32axf_invalid;
15510         }
15511         break;
15512     case 0x1d:
15513         switch (minor) {
15514         case DI:
15515             check_cp0_enabled(ctx);
15516             {
15517                 TCGv t0 = tcg_temp_new();
15518
15519                 save_cpu_state(ctx, 1);
15520                 gen_helper_di(t0, cpu_env);
15521                 gen_store_gpr(t0, rs);
15522                 /* Stop translation as we may have switched the execution mode */
15523                 ctx->base.is_jmp = DISAS_STOP;
15524                 tcg_temp_free(t0);
15525             }
15526             break;
15527         case EI:
15528             check_cp0_enabled(ctx);
15529             {
15530                 TCGv t0 = tcg_temp_new();
15531
15532                 save_cpu_state(ctx, 1);
15533                 gen_helper_ei(t0, cpu_env);
15534                 gen_store_gpr(t0, rs);
15535                 /* DISAS_STOP isn't sufficient, we need to ensure we break out
15536                    of translated code to check for pending interrupts.  */
15537                 gen_save_pc(ctx->base.pc_next + 4);
15538                 ctx->base.is_jmp = DISAS_EXIT;
15539                 tcg_temp_free(t0);
15540             }
15541             break;
15542         default:
15543             goto pool32axf_invalid;
15544         }
15545         break;
15546 #endif
15547     case 0x2d:
15548         switch (minor) {
15549         case SYNC:
15550             gen_sync(extract32(ctx->opcode, 16, 5));
15551             break;
15552         case SYSCALL:
15553             generate_exception_end(ctx, EXCP_SYSCALL);
15554             break;
15555         case SDBBP:
15556             if (is_uhi(extract32(ctx->opcode, 16, 10))) {
15557                 gen_helper_do_semihosting(cpu_env);
15558             } else {
15559                 check_insn(ctx, ISA_MIPS32);
15560                 if (ctx->hflags & MIPS_HFLAG_SBRI) {
15561                     generate_exception_end(ctx, EXCP_RI);
15562                 } else {
15563                     generate_exception_end(ctx, EXCP_DBp);
15564                 }
15565             }
15566             break;
15567         default:
15568             goto pool32axf_invalid;
15569         }
15570         break;
15571     case 0x01:
15572         switch (minor & 3) {
15573         case MFHI_ACC:
15574             gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
15575             break;
15576         case MFLO_ACC:
15577             gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
15578             break;
15579         case MTHI_ACC:
15580             gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
15581             break;
15582         case MTLO_ACC:
15583             gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
15584             break;
15585         default:
15586             goto pool32axf_invalid;
15587         }
15588         break;
15589     case 0x35:
15590         check_insn_opc_removed(ctx, ISA_MIPS32R6);
15591         switch (minor) {
15592         case MFHI32:
15593             gen_HILO(ctx, OPC_MFHI, 0, rs);
15594             break;
15595         case MFLO32:
15596             gen_HILO(ctx, OPC_MFLO, 0, rs);
15597             break;
15598         case MTHI32:
15599             gen_HILO(ctx, OPC_MTHI, 0, rs);
15600             break;
15601         case MTLO32:
15602             gen_HILO(ctx, OPC_MTLO, 0, rs);
15603             break;
15604         default:
15605             goto pool32axf_invalid;
15606         }
15607         break;
15608     default:
15609     pool32axf_invalid:
15610         MIPS_INVAL("pool32axf");
15611         generate_exception_end(ctx, EXCP_RI);
15612         break;
15613     }
15614 }
15615
15616 /* Values for microMIPS fmt field.  Variable-width, depending on which
15617    formats the instruction supports.  */
15618
15619 enum {
15620     FMT_SD_S = 0,
15621     FMT_SD_D = 1,
15622
15623     FMT_SDPS_S = 0,
15624     FMT_SDPS_D = 1,
15625     FMT_SDPS_PS = 2,
15626
15627     FMT_SWL_S = 0,
15628     FMT_SWL_W = 1,
15629     FMT_SWL_L = 2,
15630
15631     FMT_DWL_D = 0,
15632     FMT_DWL_W = 1,
15633     FMT_DWL_L = 2
15634 };
15635
15636 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
15637 {
15638     int extension = (ctx->opcode >> 6) & 0x3ff;
15639     uint32_t mips32_op;
15640
15641 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
15642 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
15643 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
15644
15645     switch (extension) {
15646     case FLOAT_1BIT_FMT(CFC1, 0):
15647         mips32_op = OPC_CFC1;
15648         goto do_cp1;
15649     case FLOAT_1BIT_FMT(CTC1, 0):
15650         mips32_op = OPC_CTC1;
15651         goto do_cp1;
15652     case FLOAT_1BIT_FMT(MFC1, 0):
15653         mips32_op = OPC_MFC1;
15654         goto do_cp1;
15655     case FLOAT_1BIT_FMT(MTC1, 0):
15656         mips32_op = OPC_MTC1;
15657         goto do_cp1;
15658     case FLOAT_1BIT_FMT(MFHC1, 0):
15659         mips32_op = OPC_MFHC1;
15660         goto do_cp1;
15661     case FLOAT_1BIT_FMT(MTHC1, 0):
15662         mips32_op = OPC_MTHC1;
15663     do_cp1:
15664         gen_cp1(ctx, mips32_op, rt, rs);
15665         break;
15666
15667         /* Reciprocal square root */
15668     case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
15669         mips32_op = OPC_RSQRT_S;
15670         goto do_unaryfp;
15671     case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
15672         mips32_op = OPC_RSQRT_D;
15673         goto do_unaryfp;
15674
15675         /* Square root */
15676     case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
15677         mips32_op = OPC_SQRT_S;
15678         goto do_unaryfp;
15679     case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
15680         mips32_op = OPC_SQRT_D;
15681         goto do_unaryfp;
15682
15683         /* Reciprocal */
15684     case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
15685         mips32_op = OPC_RECIP_S;
15686         goto do_unaryfp;
15687     case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
15688         mips32_op = OPC_RECIP_D;
15689         goto do_unaryfp;
15690
15691         /* Floor */
15692     case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
15693         mips32_op = OPC_FLOOR_L_S;
15694         goto do_unaryfp;
15695     case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
15696         mips32_op = OPC_FLOOR_L_D;
15697         goto do_unaryfp;
15698     case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
15699         mips32_op = OPC_FLOOR_W_S;
15700         goto do_unaryfp;
15701     case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
15702         mips32_op = OPC_FLOOR_W_D;
15703         goto do_unaryfp;
15704
15705         /* Ceiling */
15706     case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
15707         mips32_op = OPC_CEIL_L_S;
15708         goto do_unaryfp;
15709     case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
15710         mips32_op = OPC_CEIL_L_D;
15711         goto do_unaryfp;
15712     case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
15713         mips32_op = OPC_CEIL_W_S;
15714         goto do_unaryfp;
15715     case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
15716         mips32_op = OPC_CEIL_W_D;
15717         goto do_unaryfp;
15718
15719         /* Truncation */
15720     case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
15721         mips32_op = OPC_TRUNC_L_S;
15722         goto do_unaryfp;
15723     case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
15724         mips32_op = OPC_TRUNC_L_D;
15725         goto do_unaryfp;
15726     case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
15727         mips32_op = OPC_TRUNC_W_S;
15728         goto do_unaryfp;
15729     case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
15730         mips32_op = OPC_TRUNC_W_D;
15731         goto do_unaryfp;
15732
15733         /* Round */
15734     case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
15735         mips32_op = OPC_ROUND_L_S;
15736         goto do_unaryfp;
15737     case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
15738         mips32_op = OPC_ROUND_L_D;
15739         goto do_unaryfp;
15740     case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
15741         mips32_op = OPC_ROUND_W_S;
15742         goto do_unaryfp;
15743     case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
15744         mips32_op = OPC_ROUND_W_D;
15745         goto do_unaryfp;
15746
15747         /* Integer to floating-point conversion */
15748     case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
15749         mips32_op = OPC_CVT_L_S;
15750         goto do_unaryfp;
15751     case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
15752         mips32_op = OPC_CVT_L_D;
15753         goto do_unaryfp;
15754     case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
15755         mips32_op = OPC_CVT_W_S;
15756         goto do_unaryfp;
15757     case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
15758         mips32_op = OPC_CVT_W_D;
15759         goto do_unaryfp;
15760
15761         /* Paired-foo conversions */
15762     case FLOAT_1BIT_FMT(CVT_S_PL, 0):
15763         mips32_op = OPC_CVT_S_PL;
15764         goto do_unaryfp;
15765     case FLOAT_1BIT_FMT(CVT_S_PU, 0):
15766         mips32_op = OPC_CVT_S_PU;
15767         goto do_unaryfp;
15768     case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
15769         mips32_op = OPC_CVT_PW_PS;
15770         goto do_unaryfp;
15771     case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
15772         mips32_op = OPC_CVT_PS_PW;
15773         goto do_unaryfp;
15774
15775         /* Floating-point moves */
15776     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
15777         mips32_op = OPC_MOV_S;
15778         goto do_unaryfp;
15779     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
15780         mips32_op = OPC_MOV_D;
15781         goto do_unaryfp;
15782     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
15783         mips32_op = OPC_MOV_PS;
15784         goto do_unaryfp;
15785
15786         /* Absolute value */
15787     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
15788         mips32_op = OPC_ABS_S;
15789         goto do_unaryfp;
15790     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
15791         mips32_op = OPC_ABS_D;
15792         goto do_unaryfp;
15793     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
15794         mips32_op = OPC_ABS_PS;
15795         goto do_unaryfp;
15796
15797         /* Negation */
15798     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
15799         mips32_op = OPC_NEG_S;
15800         goto do_unaryfp;
15801     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
15802         mips32_op = OPC_NEG_D;
15803         goto do_unaryfp;
15804     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
15805         mips32_op = OPC_NEG_PS;
15806         goto do_unaryfp;
15807
15808         /* Reciprocal square root step */
15809     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
15810         mips32_op = OPC_RSQRT1_S;
15811         goto do_unaryfp;
15812     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
15813         mips32_op = OPC_RSQRT1_D;
15814         goto do_unaryfp;
15815     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
15816         mips32_op = OPC_RSQRT1_PS;
15817         goto do_unaryfp;
15818
15819         /* Reciprocal step */
15820     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
15821         mips32_op = OPC_RECIP1_S;
15822         goto do_unaryfp;
15823     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
15824         mips32_op = OPC_RECIP1_S;
15825         goto do_unaryfp;
15826     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
15827         mips32_op = OPC_RECIP1_PS;
15828         goto do_unaryfp;
15829
15830         /* Conversions from double */
15831     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
15832         mips32_op = OPC_CVT_D_S;
15833         goto do_unaryfp;
15834     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
15835         mips32_op = OPC_CVT_D_W;
15836         goto do_unaryfp;
15837     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
15838         mips32_op = OPC_CVT_D_L;
15839         goto do_unaryfp;
15840
15841         /* Conversions from single */
15842     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
15843         mips32_op = OPC_CVT_S_D;
15844         goto do_unaryfp;
15845     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
15846         mips32_op = OPC_CVT_S_W;
15847         goto do_unaryfp;
15848     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
15849         mips32_op = OPC_CVT_S_L;
15850     do_unaryfp:
15851         gen_farith(ctx, mips32_op, -1, rs, rt, 0);
15852         break;
15853
15854         /* Conditional moves on floating-point codes */
15855     case COND_FLOAT_MOV(MOVT, 0):
15856     case COND_FLOAT_MOV(MOVT, 1):
15857     case COND_FLOAT_MOV(MOVT, 2):
15858     case COND_FLOAT_MOV(MOVT, 3):
15859     case COND_FLOAT_MOV(MOVT, 4):
15860     case COND_FLOAT_MOV(MOVT, 5):
15861     case COND_FLOAT_MOV(MOVT, 6):
15862     case COND_FLOAT_MOV(MOVT, 7):
15863         check_insn_opc_removed(ctx, ISA_MIPS32R6);
15864         gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
15865         break;
15866     case COND_FLOAT_MOV(MOVF, 0):
15867     case COND_FLOAT_MOV(MOVF, 1):
15868     case COND_FLOAT_MOV(MOVF, 2):
15869     case COND_FLOAT_MOV(MOVF, 3):
15870     case COND_FLOAT_MOV(MOVF, 4):
15871     case COND_FLOAT_MOV(MOVF, 5):
15872     case COND_FLOAT_MOV(MOVF, 6):
15873     case COND_FLOAT_MOV(MOVF, 7):
15874         check_insn_opc_removed(ctx, ISA_MIPS32R6);
15875         gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
15876         break;
15877     default:
15878         MIPS_INVAL("pool32fxf");
15879         generate_exception_end(ctx, EXCP_RI);
15880         break;
15881     }
15882 }
15883
15884 static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
15885 {
15886     int32_t offset;
15887     uint16_t insn;
15888     int rt, rs, rd, rr;
15889     int16_t imm;
15890     uint32_t op, minor, minor2, mips32_op;
15891     uint32_t cond, fmt, cc;
15892
15893     insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
15894     ctx->opcode = (ctx->opcode << 16) | insn;
15895
15896     rt = (ctx->opcode >> 21) & 0x1f;
15897     rs = (ctx->opcode >> 16) & 0x1f;
15898     rd = (ctx->opcode >> 11) & 0x1f;
15899     rr = (ctx->opcode >> 6) & 0x1f;
15900     imm = (int16_t) ctx->opcode;
15901
15902     op = (ctx->opcode >> 26) & 0x3f;
15903     switch (op) {
15904     case POOL32A:
15905         minor = ctx->opcode & 0x3f;
15906         switch (minor) {
15907         case 0x00:
15908             minor = (ctx->opcode >> 6) & 0xf;
15909             switch (minor) {
15910             case SLL32:
15911                 mips32_op = OPC_SLL;
15912                 goto do_shifti;
15913             case SRA:
15914                 mips32_op = OPC_SRA;
15915                 goto do_shifti;
15916             case SRL32:
15917                 mips32_op = OPC_SRL;
15918                 goto do_shifti;
15919             case ROTR:
15920                 mips32_op = OPC_ROTR;
15921             do_shifti:
15922                 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
15923                 break;
15924             case SELEQZ:
15925                 check_insn(ctx, ISA_MIPS32R6);
15926                 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
15927                 break;
15928             case SELNEZ:
15929                 check_insn(ctx, ISA_MIPS32R6);
15930                 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
15931                 break;
15932             case R6_RDHWR:
15933                 check_insn(ctx, ISA_MIPS32R6);
15934                 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
15935                 break;
15936             default:
15937                 goto pool32a_invalid;
15938             }
15939             break;
15940         case 0x10:
15941             minor = (ctx->opcode >> 6) & 0xf;
15942             switch (minor) {
15943                 /* Arithmetic */
15944             case ADD:
15945                 mips32_op = OPC_ADD;
15946                 goto do_arith;
15947             case ADDU32:
15948                 mips32_op = OPC_ADDU;
15949                 goto do_arith;
15950             case SUB:
15951                 mips32_op = OPC_SUB;
15952                 goto do_arith;
15953             case SUBU32:
15954                 mips32_op = OPC_SUBU;
15955                 goto do_arith;
15956             case MUL:
15957                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15958                 mips32_op = OPC_MUL;
15959             do_arith:
15960                 gen_arith(ctx, mips32_op, rd, rs, rt);
15961                 break;
15962                 /* Shifts */
15963             case SLLV:
15964                 mips32_op = OPC_SLLV;
15965                 goto do_shift;
15966             case SRLV:
15967                 mips32_op = OPC_SRLV;
15968                 goto do_shift;
15969             case SRAV:
15970                 mips32_op = OPC_SRAV;
15971                 goto do_shift;
15972             case ROTRV:
15973                 mips32_op = OPC_ROTRV;
15974             do_shift:
15975                 gen_shift(ctx, mips32_op, rd, rs, rt);
15976                 break;
15977                 /* Logical operations */
15978             case AND:
15979                 mips32_op = OPC_AND;
15980                 goto do_logic;
15981             case OR32:
15982                 mips32_op = OPC_OR;
15983                 goto do_logic;
15984             case NOR:
15985                 mips32_op = OPC_NOR;
15986                 goto do_logic;
15987             case XOR32:
15988                 mips32_op = OPC_XOR;
15989             do_logic:
15990                 gen_logic(ctx, mips32_op, rd, rs, rt);
15991                 break;
15992                 /* Set less than */
15993             case SLT:
15994                 mips32_op = OPC_SLT;
15995                 goto do_slt;
15996             case SLTU:
15997                 mips32_op = OPC_SLTU;
15998             do_slt:
15999                 gen_slt(ctx, mips32_op, rd, rs, rt);
16000                 break;
16001             default:
16002                 goto pool32a_invalid;
16003             }
16004             break;
16005         case 0x18:
16006             minor = (ctx->opcode >> 6) & 0xf;
16007             switch (minor) {
16008                 /* Conditional moves */
16009             case MOVN: /* MUL */
16010                 if (ctx->insn_flags & ISA_MIPS32R6) {
16011                     /* MUL */
16012                     gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
16013                 } else {
16014                     /* MOVN */
16015                     gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
16016                 }
16017                 break;
16018             case MOVZ: /* MUH */
16019                 if (ctx->insn_flags & ISA_MIPS32R6) {
16020                     /* MUH */
16021                     gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
16022                 } else {
16023                     /* MOVZ */
16024                     gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
16025                 }
16026                 break;
16027             case MULU:
16028                 check_insn(ctx, ISA_MIPS32R6);
16029                 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
16030                 break;
16031             case MUHU:
16032                 check_insn(ctx, ISA_MIPS32R6);
16033                 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
16034                 break;
16035             case LWXS: /* DIV */
16036                 if (ctx->insn_flags & ISA_MIPS32R6) {
16037                     /* DIV */
16038                     gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
16039                 } else {
16040                     /* LWXS */
16041                     gen_ldxs(ctx, rs, rt, rd);
16042                 }
16043                 break;
16044             case MOD:
16045                 check_insn(ctx, ISA_MIPS32R6);
16046                 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
16047                 break;
16048             case R6_DIVU:
16049                 check_insn(ctx, ISA_MIPS32R6);
16050                 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
16051                 break;
16052             case MODU:
16053                 check_insn(ctx, ISA_MIPS32R6);
16054                 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
16055                 break;
16056             default:
16057                 goto pool32a_invalid;
16058             }
16059             break;
16060         case INS:
16061             gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
16062             return;
16063         case LSA:
16064             check_insn(ctx, ISA_MIPS32R6);
16065             gen_lsa(ctx, OPC_LSA, rd, rs, rt,
16066                     extract32(ctx->opcode, 9, 2));
16067             break;
16068         case ALIGN:
16069             check_insn(ctx, ISA_MIPS32R6);
16070             gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2));
16071             break;
16072         case EXT:
16073             gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
16074             return;
16075         case POOL32AXF:
16076             gen_pool32axf(env, ctx, rt, rs);
16077             break;
16078         case BREAK32:
16079             generate_exception_end(ctx, EXCP_BREAK);
16080             break;
16081         case SIGRIE:
16082             check_insn(ctx, ISA_MIPS32R6);
16083             generate_exception_end(ctx, EXCP_RI);
16084             break;
16085         default:
16086         pool32a_invalid:
16087                 MIPS_INVAL("pool32a");
16088                 generate_exception_end(ctx, EXCP_RI);
16089                 break;
16090         }
16091         break;
16092     case POOL32B:
16093         minor = (ctx->opcode >> 12) & 0xf;
16094         switch (minor) {
16095         case CACHE:
16096             check_cp0_enabled(ctx);
16097             if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
16098                 gen_cache_operation(ctx, rt, rs, imm);
16099             }
16100             break;
16101         case LWC2:
16102         case SWC2:
16103             /* COP2: Not implemented. */
16104             generate_exception_err(ctx, EXCP_CpU, 2);
16105             break;
16106 #ifdef TARGET_MIPS64
16107         case LDP:
16108         case SDP:
16109             check_insn(ctx, ISA_MIPS3);
16110             check_mips_64(ctx);
16111 #endif
16112             /* fall through */
16113         case LWP:
16114         case SWP:
16115             gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
16116             break;
16117 #ifdef TARGET_MIPS64
16118         case LDM:
16119         case SDM:
16120             check_insn(ctx, ISA_MIPS3);
16121             check_mips_64(ctx);
16122 #endif
16123             /* fall through */
16124         case LWM32:
16125         case SWM32:
16126             gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
16127             break;
16128         default:
16129             MIPS_INVAL("pool32b");
16130             generate_exception_end(ctx, EXCP_RI);
16131             break;
16132         }
16133         break;
16134     case POOL32F:
16135         if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
16136             minor = ctx->opcode & 0x3f;
16137             check_cp1_enabled(ctx);
16138             switch (minor) {
16139             case ALNV_PS:
16140                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16141                 mips32_op = OPC_ALNV_PS;
16142                 goto do_madd;
16143             case MADD_S:
16144                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16145                 mips32_op = OPC_MADD_S;
16146                 goto do_madd;
16147             case MADD_D:
16148                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16149                 mips32_op = OPC_MADD_D;
16150                 goto do_madd;
16151             case MADD_PS:
16152                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16153                 mips32_op = OPC_MADD_PS;
16154                 goto do_madd;
16155             case MSUB_S:
16156                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16157                 mips32_op = OPC_MSUB_S;
16158                 goto do_madd;
16159             case MSUB_D:
16160                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16161                 mips32_op = OPC_MSUB_D;
16162                 goto do_madd;
16163             case MSUB_PS:
16164                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16165                 mips32_op = OPC_MSUB_PS;
16166                 goto do_madd;
16167             case NMADD_S:
16168                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16169                 mips32_op = OPC_NMADD_S;
16170                 goto do_madd;
16171             case NMADD_D:
16172                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16173                 mips32_op = OPC_NMADD_D;
16174                 goto do_madd;
16175             case NMADD_PS:
16176                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16177                 mips32_op = OPC_NMADD_PS;
16178                 goto do_madd;
16179             case NMSUB_S:
16180                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16181                 mips32_op = OPC_NMSUB_S;
16182                 goto do_madd;
16183             case NMSUB_D:
16184                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16185                 mips32_op = OPC_NMSUB_D;
16186                 goto do_madd;
16187             case NMSUB_PS:
16188                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16189                 mips32_op = OPC_NMSUB_PS;
16190             do_madd:
16191                 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
16192                 break;
16193             case CABS_COND_FMT:
16194                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16195                 cond = (ctx->opcode >> 6) & 0xf;
16196                 cc = (ctx->opcode >> 13) & 0x7;
16197                 fmt = (ctx->opcode >> 10) & 0x3;
16198                 switch (fmt) {
16199                 case 0x0:
16200                     gen_cmpabs_s(ctx, cond, rt, rs, cc);
16201                     break;
16202                 case 0x1:
16203                     gen_cmpabs_d(ctx, cond, rt, rs, cc);
16204                     break;
16205                 case 0x2:
16206                     gen_cmpabs_ps(ctx, cond, rt, rs, cc);
16207                     break;
16208                 default:
16209                     goto pool32f_invalid;
16210                 }
16211                 break;
16212             case C_COND_FMT:
16213                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16214                 cond = (ctx->opcode >> 6) & 0xf;
16215                 cc = (ctx->opcode >> 13) & 0x7;
16216                 fmt = (ctx->opcode >> 10) & 0x3;
16217                 switch (fmt) {
16218                 case 0x0:
16219                     gen_cmp_s(ctx, cond, rt, rs, cc);
16220                     break;
16221                 case 0x1:
16222                     gen_cmp_d(ctx, cond, rt, rs, cc);
16223                     break;
16224                 case 0x2:
16225                     gen_cmp_ps(ctx, cond, rt, rs, cc);
16226                     break;
16227                 default:
16228                     goto pool32f_invalid;
16229                 }
16230                 break;
16231             case CMP_CONDN_S:
16232                 check_insn(ctx, ISA_MIPS32R6);
16233                 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
16234                 break;
16235             case CMP_CONDN_D:
16236                 check_insn(ctx, ISA_MIPS32R6);
16237                 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
16238                 break;
16239             case POOL32FXF:
16240                 gen_pool32fxf(ctx, rt, rs);
16241                 break;
16242             case 0x00:
16243                 /* PLL foo */
16244                 switch ((ctx->opcode >> 6) & 0x7) {
16245                 case PLL_PS:
16246                     mips32_op = OPC_PLL_PS;
16247                     goto do_ps;
16248                 case PLU_PS:
16249                     mips32_op = OPC_PLU_PS;
16250                     goto do_ps;
16251                 case PUL_PS:
16252                     mips32_op = OPC_PUL_PS;
16253                     goto do_ps;
16254                 case PUU_PS:
16255                     mips32_op = OPC_PUU_PS;
16256                     goto do_ps;
16257                 case CVT_PS_S:
16258                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16259                     mips32_op = OPC_CVT_PS_S;
16260                 do_ps:
16261                     gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16262                     break;
16263                 default:
16264                     goto pool32f_invalid;
16265                 }
16266                 break;
16267             case MIN_FMT:
16268                 check_insn(ctx, ISA_MIPS32R6);
16269                 switch ((ctx->opcode >> 9) & 0x3) {
16270                 case FMT_SDPS_S:
16271                     gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
16272                     break;
16273                 case FMT_SDPS_D:
16274                     gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
16275                     break;
16276                 default:
16277                     goto pool32f_invalid;
16278                 }
16279                 break;
16280             case 0x08:
16281                 /* [LS][WDU]XC1 */
16282                 switch ((ctx->opcode >> 6) & 0x7) {
16283                 case LWXC1:
16284                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16285                     mips32_op = OPC_LWXC1;
16286                     goto do_ldst_cp1;
16287                 case SWXC1:
16288                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16289                     mips32_op = OPC_SWXC1;
16290                     goto do_ldst_cp1;
16291                 case LDXC1:
16292                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16293                     mips32_op = OPC_LDXC1;
16294                     goto do_ldst_cp1;
16295                 case SDXC1:
16296                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16297                     mips32_op = OPC_SDXC1;
16298                     goto do_ldst_cp1;
16299                 case LUXC1:
16300                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16301                     mips32_op = OPC_LUXC1;
16302                     goto do_ldst_cp1;
16303                 case SUXC1:
16304                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16305                     mips32_op = OPC_SUXC1;
16306                 do_ldst_cp1:
16307                     gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
16308                     break;
16309                 default:
16310                     goto pool32f_invalid;
16311                 }
16312                 break;
16313             case MAX_FMT:
16314                 check_insn(ctx, ISA_MIPS32R6);
16315                 switch ((ctx->opcode >> 9) & 0x3) {
16316                 case FMT_SDPS_S:
16317                     gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
16318                     break;
16319                 case FMT_SDPS_D:
16320                     gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
16321                     break;
16322                 default:
16323                     goto pool32f_invalid;
16324                 }
16325                 break;
16326             case 0x18:
16327                 /* 3D insns */
16328                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16329                 fmt = (ctx->opcode >> 9) & 0x3;
16330                 switch ((ctx->opcode >> 6) & 0x7) {
16331                 case RSQRT2_FMT:
16332                     switch (fmt) {
16333                     case FMT_SDPS_S:
16334                         mips32_op = OPC_RSQRT2_S;
16335                         goto do_3d;
16336                     case FMT_SDPS_D:
16337                         mips32_op = OPC_RSQRT2_D;
16338                         goto do_3d;
16339                     case FMT_SDPS_PS:
16340                         mips32_op = OPC_RSQRT2_PS;
16341                         goto do_3d;
16342                     default:
16343                         goto pool32f_invalid;
16344                     }
16345                     break;
16346                 case RECIP2_FMT:
16347                     switch (fmt) {
16348                     case FMT_SDPS_S:
16349                         mips32_op = OPC_RECIP2_S;
16350                         goto do_3d;
16351                     case FMT_SDPS_D:
16352                         mips32_op = OPC_RECIP2_D;
16353                         goto do_3d;
16354                     case FMT_SDPS_PS:
16355                         mips32_op = OPC_RECIP2_PS;
16356                         goto do_3d;
16357                     default:
16358                         goto pool32f_invalid;
16359                     }
16360                     break;
16361                 case ADDR_PS:
16362                     mips32_op = OPC_ADDR_PS;
16363                     goto do_3d;
16364                 case MULR_PS:
16365                     mips32_op = OPC_MULR_PS;
16366                 do_3d:
16367                     gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16368                     break;
16369                 default:
16370                     goto pool32f_invalid;
16371                 }
16372                 break;
16373             case 0x20:
16374                 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
16375                 cc = (ctx->opcode >> 13) & 0x7;
16376                 fmt = (ctx->opcode >> 9) & 0x3;
16377                 switch ((ctx->opcode >> 6) & 0x7) {
16378                 case MOVF_FMT: /* RINT_FMT */
16379                     if (ctx->insn_flags & ISA_MIPS32R6) {
16380                         /* RINT_FMT */
16381                         switch (fmt) {
16382                         case FMT_SDPS_S:
16383                             gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
16384                             break;
16385                         case FMT_SDPS_D:
16386                             gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
16387                             break;
16388                         default:
16389                             goto pool32f_invalid;
16390                         }
16391                     } else {
16392                         /* MOVF_FMT */
16393                         switch (fmt) {
16394                         case FMT_SDPS_S:
16395                             gen_movcf_s(ctx, rs, rt, cc, 0);
16396                             break;
16397                         case FMT_SDPS_D:
16398                             gen_movcf_d(ctx, rs, rt, cc, 0);
16399                             break;
16400                         case FMT_SDPS_PS:
16401                             check_ps(ctx);
16402                             gen_movcf_ps(ctx, rs, rt, cc, 0);
16403                             break;
16404                         default:
16405                             goto pool32f_invalid;
16406                         }
16407                     }
16408                     break;
16409                 case MOVT_FMT: /* CLASS_FMT */
16410                     if (ctx->insn_flags & ISA_MIPS32R6) {
16411                         /* CLASS_FMT */
16412                         switch (fmt) {
16413                         case FMT_SDPS_S:
16414                             gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
16415                             break;
16416                         case FMT_SDPS_D:
16417                             gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
16418                             break;
16419                         default:
16420                             goto pool32f_invalid;
16421                         }
16422                     } else {
16423                         /* MOVT_FMT */
16424                         switch (fmt) {
16425                         case FMT_SDPS_S:
16426                             gen_movcf_s(ctx, rs, rt, cc, 1);
16427                             break;
16428                         case FMT_SDPS_D:
16429                             gen_movcf_d(ctx, rs, rt, cc, 1);
16430                             break;
16431                         case FMT_SDPS_PS:
16432                             check_ps(ctx);
16433                             gen_movcf_ps(ctx, rs, rt, cc, 1);
16434                             break;
16435                         default:
16436                             goto pool32f_invalid;
16437                         }
16438                     }
16439                     break;
16440                 case PREFX:
16441                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16442                     break;
16443                 default:
16444                     goto pool32f_invalid;
16445                 }
16446                 break;
16447 #define FINSN_3ARG_SDPS(prfx)                           \
16448                 switch ((ctx->opcode >> 8) & 0x3) {     \
16449                 case FMT_SDPS_S:                        \
16450                     mips32_op = OPC_##prfx##_S;         \
16451                     goto do_fpop;                       \
16452                 case FMT_SDPS_D:                        \
16453                     mips32_op = OPC_##prfx##_D;         \
16454                     goto do_fpop;                       \
16455                 case FMT_SDPS_PS:                       \
16456                     check_ps(ctx);                      \
16457                     mips32_op = OPC_##prfx##_PS;        \
16458                     goto do_fpop;                       \
16459                 default:                                \
16460                     goto pool32f_invalid;               \
16461                 }
16462             case MINA_FMT:
16463                 check_insn(ctx, ISA_MIPS32R6);
16464                 switch ((ctx->opcode >> 9) & 0x3) {
16465                 case FMT_SDPS_S:
16466                     gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
16467                     break;
16468                 case FMT_SDPS_D:
16469                     gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
16470                     break;
16471                 default:
16472                     goto pool32f_invalid;
16473                 }
16474                 break;
16475             case MAXA_FMT:
16476                 check_insn(ctx, ISA_MIPS32R6);
16477                 switch ((ctx->opcode >> 9) & 0x3) {
16478                 case FMT_SDPS_S:
16479                     gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
16480                     break;
16481                 case FMT_SDPS_D:
16482                     gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
16483                     break;
16484                 default:
16485                     goto pool32f_invalid;
16486                 }
16487                 break;
16488             case 0x30:
16489                 /* regular FP ops */
16490                 switch ((ctx->opcode >> 6) & 0x3) {
16491                 case ADD_FMT:
16492                     FINSN_3ARG_SDPS(ADD);
16493                     break;
16494                 case SUB_FMT:
16495                     FINSN_3ARG_SDPS(SUB);
16496                     break;
16497                 case MUL_FMT:
16498                     FINSN_3ARG_SDPS(MUL);
16499                     break;
16500                 case DIV_FMT:
16501                     fmt = (ctx->opcode >> 8) & 0x3;
16502                     if (fmt == 1) {
16503                         mips32_op = OPC_DIV_D;
16504                     } else if (fmt == 0) {
16505                         mips32_op = OPC_DIV_S;
16506                     } else {
16507                         goto pool32f_invalid;
16508                     }
16509                     goto do_fpop;
16510                 default:
16511                     goto pool32f_invalid;
16512                 }
16513                 break;
16514             case 0x38:
16515                 /* cmovs */
16516                 switch ((ctx->opcode >> 6) & 0x7) {
16517                 case MOVN_FMT: /* SELEQZ_FMT */
16518                     if (ctx->insn_flags & ISA_MIPS32R6) {
16519                         /* SELEQZ_FMT */
16520                         switch ((ctx->opcode >> 9) & 0x3) {
16521                         case FMT_SDPS_S:
16522                             gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
16523                             break;
16524                         case FMT_SDPS_D:
16525                             gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
16526                             break;
16527                         default:
16528                             goto pool32f_invalid;
16529                         }
16530                     } else {
16531                         /* MOVN_FMT */
16532                         FINSN_3ARG_SDPS(MOVN);
16533                     }
16534                     break;
16535                 case MOVN_FMT_04:
16536                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16537                     FINSN_3ARG_SDPS(MOVN);
16538                     break;
16539                 case MOVZ_FMT: /* SELNEZ_FMT */
16540                     if (ctx->insn_flags & ISA_MIPS32R6) {
16541                         /* SELNEZ_FMT */
16542                         switch ((ctx->opcode >> 9) & 0x3) {
16543                         case FMT_SDPS_S:
16544                             gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
16545                             break;
16546                         case FMT_SDPS_D:
16547                             gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
16548                             break;
16549                         default:
16550                             goto pool32f_invalid;
16551                         }
16552                     } else {
16553                         /* MOVZ_FMT */
16554                         FINSN_3ARG_SDPS(MOVZ);
16555                     }
16556                     break;
16557                 case MOVZ_FMT_05:
16558                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16559                     FINSN_3ARG_SDPS(MOVZ);
16560                     break;
16561                 case SEL_FMT:
16562                     check_insn(ctx, ISA_MIPS32R6);
16563                     switch ((ctx->opcode >> 9) & 0x3) {
16564                     case FMT_SDPS_S:
16565                         gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
16566                         break;
16567                     case FMT_SDPS_D:
16568                         gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
16569                         break;
16570                     default:
16571                         goto pool32f_invalid;
16572                     }
16573                     break;
16574                 case MADDF_FMT:
16575                     check_insn(ctx, ISA_MIPS32R6);
16576                     switch ((ctx->opcode >> 9) & 0x3) {
16577                     case FMT_SDPS_S:
16578                         mips32_op = OPC_MADDF_S;
16579                         goto do_fpop;
16580                     case FMT_SDPS_D:
16581                         mips32_op = OPC_MADDF_D;
16582                         goto do_fpop;
16583                     default:
16584                         goto pool32f_invalid;
16585                     }
16586                     break;
16587                 case MSUBF_FMT:
16588                     check_insn(ctx, ISA_MIPS32R6);
16589                     switch ((ctx->opcode >> 9) & 0x3) {
16590                     case FMT_SDPS_S:
16591                         mips32_op = OPC_MSUBF_S;
16592                         goto do_fpop;
16593                     case FMT_SDPS_D:
16594                         mips32_op = OPC_MSUBF_D;
16595                         goto do_fpop;
16596                     default:
16597                         goto pool32f_invalid;
16598                     }
16599                     break;
16600                 default:
16601                     goto pool32f_invalid;
16602                 }
16603                 break;
16604             do_fpop:
16605                 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16606                 break;
16607             default:
16608             pool32f_invalid:
16609                 MIPS_INVAL("pool32f");
16610                 generate_exception_end(ctx, EXCP_RI);
16611                 break;
16612             }
16613         } else {
16614             generate_exception_err(ctx, EXCP_CpU, 1);
16615         }
16616         break;
16617     case POOL32I:
16618         minor = (ctx->opcode >> 21) & 0x1f;
16619         switch (minor) {
16620         case BLTZ:
16621             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16622             gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
16623             break;
16624         case BLTZAL:
16625             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16626             gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
16627             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16628             break;
16629         case BLTZALS:
16630             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16631             gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
16632             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16633             break;
16634         case BGEZ:
16635             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16636             gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
16637             break;
16638         case BGEZAL:
16639             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16640             gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
16641             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16642             break;
16643         case BGEZALS:
16644             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16645             gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
16646             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16647             break;
16648         case BLEZ:
16649             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16650             gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
16651             break;
16652         case BGTZ:
16653             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16654             gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
16655             break;
16656
16657             /* Traps */
16658         case TLTI: /* BC1EQZC */
16659             if (ctx->insn_flags & ISA_MIPS32R6) {
16660                 /* BC1EQZC */
16661                 check_cp1_enabled(ctx);
16662                 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
16663             } else {
16664                 /* TLTI */
16665                 mips32_op = OPC_TLTI;
16666                 goto do_trapi;
16667             }
16668             break;
16669         case TGEI: /* BC1NEZC */
16670             if (ctx->insn_flags & ISA_MIPS32R6) {
16671                 /* BC1NEZC */
16672                 check_cp1_enabled(ctx);
16673                 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
16674             } else {
16675                 /* TGEI */
16676                 mips32_op = OPC_TGEI;
16677                 goto do_trapi;
16678             }
16679             break;
16680         case TLTIU:
16681             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16682             mips32_op = OPC_TLTIU;
16683             goto do_trapi;
16684         case TGEIU:
16685             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16686             mips32_op = OPC_TGEIU;
16687             goto do_trapi;
16688         case TNEI: /* SYNCI */
16689             if (ctx->insn_flags & ISA_MIPS32R6) {
16690                 /* SYNCI */
16691                 /* Break the TB to be able to sync copied instructions
16692                    immediately */
16693                 ctx->base.is_jmp = DISAS_STOP;
16694             } else {
16695                 /* TNEI */
16696                 mips32_op = OPC_TNEI;
16697                 goto do_trapi;
16698             }
16699             break;
16700         case TEQI:
16701             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16702             mips32_op = OPC_TEQI;
16703         do_trapi:
16704             gen_trap(ctx, mips32_op, rs, -1, imm);
16705             break;
16706
16707         case BNEZC:
16708         case BEQZC:
16709             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16710             gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
16711                                4, rs, 0, imm << 1, 0);
16712             /* Compact branches don't have a delay slot, so just let
16713                the normal delay slot handling take us to the branch
16714                target. */
16715             break;
16716         case LUI:
16717             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16718             gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
16719             break;
16720         case SYNCI:
16721             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16722             /* Break the TB to be able to sync copied instructions
16723                immediately */
16724             ctx->base.is_jmp = DISAS_STOP;
16725             break;
16726         case BC2F:
16727         case BC2T:
16728             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16729             /* COP2: Not implemented. */
16730             generate_exception_err(ctx, EXCP_CpU, 2);
16731             break;
16732         case BC1F:
16733             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16734             mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
16735             goto do_cp1branch;
16736         case BC1T:
16737             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16738             mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
16739             goto do_cp1branch;
16740         case BC1ANY4F:
16741             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16742             mips32_op = OPC_BC1FANY4;
16743             goto do_cp1mips3d;
16744         case BC1ANY4T:
16745             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16746             mips32_op = OPC_BC1TANY4;
16747         do_cp1mips3d:
16748             check_cop1x(ctx);
16749             check_insn(ctx, ASE_MIPS3D);
16750             /* Fall through */
16751         do_cp1branch:
16752             if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16753                 check_cp1_enabled(ctx);
16754                 gen_compute_branch1(ctx, mips32_op,
16755                                     (ctx->opcode >> 18) & 0x7, imm << 1);
16756             } else {
16757                 generate_exception_err(ctx, EXCP_CpU, 1);
16758             }
16759             break;
16760         case BPOSGE64:
16761         case BPOSGE32:
16762             /* MIPS DSP: not implemented */
16763             /* Fall through */
16764         default:
16765             MIPS_INVAL("pool32i");
16766             generate_exception_end(ctx, EXCP_RI);
16767             break;
16768         }
16769         break;
16770     case POOL32C:
16771         minor = (ctx->opcode >> 12) & 0xf;
16772         offset = sextract32(ctx->opcode, 0,
16773                             (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
16774         switch (minor) {
16775         case LWL:
16776             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16777             mips32_op = OPC_LWL;
16778             goto do_ld_lr;
16779         case SWL:
16780             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16781             mips32_op = OPC_SWL;
16782             goto do_st_lr;
16783         case LWR:
16784             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16785             mips32_op = OPC_LWR;
16786             goto do_ld_lr;
16787         case SWR:
16788             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16789             mips32_op = OPC_SWR;
16790             goto do_st_lr;
16791 #if defined(TARGET_MIPS64)
16792         case LDL:
16793             check_insn(ctx, ISA_MIPS3);
16794             check_mips_64(ctx);
16795             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16796             mips32_op = OPC_LDL;
16797             goto do_ld_lr;
16798         case SDL:
16799             check_insn(ctx, ISA_MIPS3);
16800             check_mips_64(ctx);
16801             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16802             mips32_op = OPC_SDL;
16803             goto do_st_lr;
16804         case LDR:
16805             check_insn(ctx, ISA_MIPS3);
16806             check_mips_64(ctx);
16807             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16808             mips32_op = OPC_LDR;
16809             goto do_ld_lr;
16810         case SDR:
16811             check_insn(ctx, ISA_MIPS3);
16812             check_mips_64(ctx);
16813             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16814             mips32_op = OPC_SDR;
16815             goto do_st_lr;
16816         case LWU:
16817             check_insn(ctx, ISA_MIPS3);
16818             check_mips_64(ctx);
16819             mips32_op = OPC_LWU;
16820             goto do_ld_lr;
16821         case LLD:
16822             check_insn(ctx, ISA_MIPS3);
16823             check_mips_64(ctx);
16824             mips32_op = OPC_LLD;
16825             goto do_ld_lr;
16826 #endif
16827         case LL:
16828             mips32_op = OPC_LL;
16829             goto do_ld_lr;
16830         do_ld_lr:
16831             gen_ld(ctx, mips32_op, rt, rs, offset);
16832             break;
16833         do_st_lr:
16834             gen_st(ctx, mips32_op, rt, rs, offset);
16835             break;
16836         case SC:
16837             gen_st_cond(ctx, rt, rs, offset, MO_TESL, false);
16838             break;
16839 #if defined(TARGET_MIPS64)
16840         case SCD:
16841             check_insn(ctx, ISA_MIPS3);
16842             check_mips_64(ctx);
16843             gen_st_cond(ctx, rt, rs, offset, MO_TEQ, false);
16844             break;
16845 #endif
16846         case LD_EVA:
16847             if (!ctx->eva) {
16848                 MIPS_INVAL("pool32c ld-eva");
16849                 generate_exception_end(ctx, EXCP_RI);
16850                 break;
16851             }
16852             check_cp0_enabled(ctx);
16853
16854             minor2 = (ctx->opcode >> 9) & 0x7;
16855             offset = sextract32(ctx->opcode, 0, 9);
16856             switch (minor2) {
16857             case LBUE:
16858                 mips32_op = OPC_LBUE;
16859                 goto do_ld_lr;
16860             case LHUE:
16861                 mips32_op = OPC_LHUE;
16862                 goto do_ld_lr;
16863             case LWLE:
16864                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16865                 mips32_op = OPC_LWLE;
16866                 goto do_ld_lr;
16867             case LWRE:
16868                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16869                 mips32_op = OPC_LWRE;
16870                 goto do_ld_lr;
16871             case LBE:
16872                 mips32_op = OPC_LBE;
16873                 goto do_ld_lr;
16874             case LHE:
16875                 mips32_op = OPC_LHE;
16876                 goto do_ld_lr;
16877             case LLE:
16878                 mips32_op = OPC_LLE;
16879                 goto do_ld_lr;
16880             case LWE:
16881                 mips32_op = OPC_LWE;
16882                 goto do_ld_lr;
16883             };
16884             break;
16885         case ST_EVA:
16886             if (!ctx->eva) {
16887                 MIPS_INVAL("pool32c st-eva");
16888                 generate_exception_end(ctx, EXCP_RI);
16889                 break;
16890             }
16891             check_cp0_enabled(ctx);
16892
16893             minor2 = (ctx->opcode >> 9) & 0x7;
16894             offset = sextract32(ctx->opcode, 0, 9);
16895             switch (minor2) {
16896             case SWLE:
16897                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16898                 mips32_op = OPC_SWLE;
16899                 goto do_st_lr;
16900             case SWRE:
16901                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16902                 mips32_op = OPC_SWRE;
16903                 goto do_st_lr;
16904             case PREFE:
16905                 /* Treat as no-op */
16906                 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16907                     /* hint codes 24-31 are reserved and signal RI */
16908                     generate_exception(ctx, EXCP_RI);
16909                 }
16910                 break;
16911             case CACHEE:
16912                 /* Treat as no-op */
16913                 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
16914                     gen_cache_operation(ctx, rt, rs, offset);
16915                 }
16916                 break;
16917             case SBE:
16918                 mips32_op = OPC_SBE;
16919                 goto do_st_lr;
16920             case SHE:
16921                 mips32_op = OPC_SHE;
16922                 goto do_st_lr;
16923             case SCE:
16924                 gen_st_cond(ctx, rt, rs, offset, MO_TESL, true);
16925                 break;
16926             case SWE:
16927                 mips32_op = OPC_SWE;
16928                 goto do_st_lr;
16929             };
16930             break;
16931         case PREF:
16932             /* Treat as no-op */
16933             if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16934                 /* hint codes 24-31 are reserved and signal RI */
16935                 generate_exception(ctx, EXCP_RI);
16936             }
16937             break;
16938         default:
16939             MIPS_INVAL("pool32c");
16940             generate_exception_end(ctx, EXCP_RI);
16941             break;
16942         }
16943         break;
16944     case ADDI32: /* AUI, LUI */
16945         if (ctx->insn_flags & ISA_MIPS32R6) {
16946             /* AUI, LUI */
16947             gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
16948         } else {
16949             /* ADDI32 */
16950             mips32_op = OPC_ADDI;
16951             goto do_addi;
16952         }
16953         break;
16954     case ADDIU32:
16955         mips32_op = OPC_ADDIU;
16956     do_addi:
16957         gen_arith_imm(ctx, mips32_op, rt, rs, imm);
16958         break;
16959
16960         /* Logical operations */
16961     case ORI32:
16962         mips32_op = OPC_ORI;
16963         goto do_logici;
16964     case XORI32:
16965         mips32_op = OPC_XORI;
16966         goto do_logici;
16967     case ANDI32:
16968         mips32_op = OPC_ANDI;
16969     do_logici:
16970         gen_logic_imm(ctx, mips32_op, rt, rs, imm);
16971         break;
16972
16973         /* Set less than immediate */
16974     case SLTI32:
16975         mips32_op = OPC_SLTI;
16976         goto do_slti;
16977     case SLTIU32:
16978         mips32_op = OPC_SLTIU;
16979     do_slti:
16980         gen_slt_imm(ctx, mips32_op, rt, rs, imm);
16981         break;
16982     case JALX32:
16983         check_insn_opc_removed(ctx, ISA_MIPS32R6);
16984         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
16985         gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
16986         ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16987         break;
16988     case JALS32: /* BOVC, BEQC, BEQZALC */
16989         if (ctx->insn_flags & ISA_MIPS32R6) {
16990             if (rs >= rt) {
16991                 /* BOVC */
16992                 mips32_op = OPC_BOVC;
16993             } else if (rs < rt && rs == 0) {
16994                 /* BEQZALC */
16995                 mips32_op = OPC_BEQZALC;
16996             } else {
16997                 /* BEQC */
16998                 mips32_op = OPC_BEQC;
16999             }
17000             gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17001         } else {
17002             /* JALS32 */
17003             offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
17004             gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
17005             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17006         }
17007         break;
17008     case BEQ32: /* BC */
17009         if (ctx->insn_flags & ISA_MIPS32R6) {
17010             /* BC */
17011             gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
17012                                        sextract32(ctx->opcode << 1, 0, 27));
17013         } else {
17014             /* BEQ32 */
17015             gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
17016         }
17017         break;
17018     case BNE32: /* BALC */
17019         if (ctx->insn_flags & ISA_MIPS32R6) {
17020             /* BALC */
17021             gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
17022                                        sextract32(ctx->opcode << 1, 0, 27));
17023         } else {
17024             /* BNE32 */
17025             gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
17026         }
17027         break;
17028     case J32: /* BGTZC, BLTZC, BLTC */
17029         if (ctx->insn_flags & ISA_MIPS32R6) {
17030             if (rs == 0 && rt != 0) {
17031                 /* BGTZC */
17032                 mips32_op = OPC_BGTZC;
17033             } else if (rs != 0 && rt != 0 && rs == rt) {
17034                 /* BLTZC */
17035                 mips32_op = OPC_BLTZC;
17036             } else {
17037                 /* BLTC */
17038                 mips32_op = OPC_BLTC;
17039             }
17040             gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17041         } else {
17042             /* J32 */
17043             gen_compute_branch(ctx, OPC_J, 4, rt, rs,
17044                                (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
17045         }
17046         break;
17047     case JAL32: /* BLEZC, BGEZC, BGEC */
17048         if (ctx->insn_flags & ISA_MIPS32R6) {
17049             if (rs == 0 && rt != 0) {
17050                 /* BLEZC */
17051                 mips32_op = OPC_BLEZC;
17052             } else if (rs != 0 && rt != 0 && rs == rt) {
17053                 /* BGEZC */
17054                 mips32_op = OPC_BGEZC;
17055             } else {
17056                 /* BGEC */
17057                 mips32_op = OPC_BGEC;
17058             }
17059             gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17060         } else {
17061             /* JAL32 */
17062             gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
17063                                (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
17064             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17065         }
17066         break;
17067         /* Floating point (COP1) */
17068     case LWC132:
17069         mips32_op = OPC_LWC1;
17070         goto do_cop1;
17071     case LDC132:
17072         mips32_op = OPC_LDC1;
17073         goto do_cop1;
17074     case SWC132:
17075         mips32_op = OPC_SWC1;
17076         goto do_cop1;
17077     case SDC132:
17078         mips32_op = OPC_SDC1;
17079     do_cop1:
17080         gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
17081         break;
17082     case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17083         if (ctx->insn_flags & ISA_MIPS32R6) {
17084             /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17085             switch ((ctx->opcode >> 16) & 0x1f) {
17086             case ADDIUPC_00:
17087             case ADDIUPC_01:
17088             case ADDIUPC_02:
17089             case ADDIUPC_03:
17090             case ADDIUPC_04:
17091             case ADDIUPC_05:
17092             case ADDIUPC_06:
17093             case ADDIUPC_07:
17094                 gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
17095                 break;
17096             case AUIPC:
17097                 gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
17098                 break;
17099             case ALUIPC:
17100                 gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
17101                 break;
17102             case LWPC_08:
17103             case LWPC_09:
17104             case LWPC_0A:
17105             case LWPC_0B:
17106             case LWPC_0C:
17107             case LWPC_0D:
17108             case LWPC_0E:
17109             case LWPC_0F:
17110                 gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
17111                 break;
17112             default:
17113                 generate_exception(ctx, EXCP_RI);
17114                 break;
17115             }
17116         } else {
17117             /* ADDIUPC */
17118             int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
17119             offset = SIMM(ctx->opcode, 0, 23) << 2;
17120
17121             gen_addiupc(ctx, reg, offset, 0, 0);
17122         }
17123         break;
17124     case BNVC: /* BNEC, BNEZALC */
17125         check_insn(ctx, ISA_MIPS32R6);
17126         if (rs >= rt) {
17127             /* BNVC */
17128             mips32_op = OPC_BNVC;
17129         } else if (rs < rt && rs == 0) {
17130             /* BNEZALC */
17131             mips32_op = OPC_BNEZALC;
17132         } else {
17133             /* BNEC */
17134             mips32_op = OPC_BNEC;
17135         }
17136         gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17137         break;
17138     case R6_BNEZC: /* JIALC */
17139         check_insn(ctx, ISA_MIPS32R6);
17140         if (rt != 0) {
17141             /* BNEZC */
17142             gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
17143                                        sextract32(ctx->opcode << 1, 0, 22));
17144         } else {
17145             /* JIALC */
17146             gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
17147         }
17148         break;
17149     case R6_BEQZC: /* JIC */
17150         check_insn(ctx, ISA_MIPS32R6);
17151         if (rt != 0) {
17152             /* BEQZC */
17153             gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
17154                                        sextract32(ctx->opcode << 1, 0, 22));
17155         } else {
17156             /* JIC */
17157             gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
17158         }
17159         break;
17160     case BLEZALC: /* BGEZALC, BGEUC */
17161         check_insn(ctx, ISA_MIPS32R6);
17162         if (rs == 0 && rt != 0) {
17163             /* BLEZALC */
17164             mips32_op = OPC_BLEZALC;
17165         } else if (rs != 0 && rt != 0 && rs == rt) {
17166             /* BGEZALC */
17167             mips32_op = OPC_BGEZALC;
17168         } else {
17169             /* BGEUC */
17170             mips32_op = OPC_BGEUC;
17171         }
17172         gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17173         break;
17174     case BGTZALC: /* BLTZALC, BLTUC */
17175         check_insn(ctx, ISA_MIPS32R6);
17176         if (rs == 0 && rt != 0) {
17177             /* BGTZALC */
17178             mips32_op = OPC_BGTZALC;
17179         } else if (rs != 0 && rt != 0 && rs == rt) {
17180             /* BLTZALC */
17181             mips32_op = OPC_BLTZALC;
17182         } else {
17183             /* BLTUC */
17184             mips32_op = OPC_BLTUC;
17185         }
17186         gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17187         break;
17188         /* Loads and stores */
17189     case LB32:
17190         mips32_op = OPC_LB;
17191         goto do_ld;
17192     case LBU32:
17193         mips32_op = OPC_LBU;
17194         goto do_ld;
17195     case LH32:
17196         mips32_op = OPC_LH;
17197         goto do_ld;
17198     case LHU32:
17199         mips32_op = OPC_LHU;
17200         goto do_ld;
17201     case LW32:
17202         mips32_op = OPC_LW;
17203         goto do_ld;
17204 #ifdef TARGET_MIPS64
17205     case LD32:
17206         check_insn(ctx, ISA_MIPS3);
17207         check_mips_64(ctx);
17208         mips32_op = OPC_LD;
17209         goto do_ld;
17210     case SD32:
17211         check_insn(ctx, ISA_MIPS3);
17212         check_mips_64(ctx);
17213         mips32_op = OPC_SD;
17214         goto do_st;
17215 #endif
17216     case SB32:
17217         mips32_op = OPC_SB;
17218         goto do_st;
17219     case SH32:
17220         mips32_op = OPC_SH;
17221         goto do_st;
17222     case SW32:
17223         mips32_op = OPC_SW;
17224         goto do_st;
17225     do_ld:
17226         gen_ld(ctx, mips32_op, rt, rs, imm);
17227         break;
17228     do_st:
17229         gen_st(ctx, mips32_op, rt, rs, imm);
17230         break;
17231     default:
17232         generate_exception_end(ctx, EXCP_RI);
17233         break;
17234     }
17235 }
17236
17237 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
17238 {
17239     uint32_t op;
17240
17241     /* make sure instructions are on a halfword boundary */
17242     if (ctx->base.pc_next & 0x1) {
17243         env->CP0_BadVAddr = ctx->base.pc_next;
17244         generate_exception_end(ctx, EXCP_AdEL);
17245         return 2;
17246     }
17247
17248     op = (ctx->opcode >> 10) & 0x3f;
17249     /* Enforce properly-sized instructions in a delay slot */
17250     if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
17251         switch (op & 0x7) { /* MSB-3..MSB-5 */
17252         case 0:
17253         /* POOL32A, POOL32B, POOL32I, POOL32C */
17254         case 4:
17255         /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
17256         case 5:
17257         /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
17258         case 6:
17259         /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
17260         case 7:
17261         /* LB32, LH32, LWC132, LDC132, LW32 */
17262             if (ctx->hflags & MIPS_HFLAG_BDS16) {
17263                 generate_exception_end(ctx, EXCP_RI);
17264                 return 2;
17265             }
17266             break;
17267         case 1:
17268         /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
17269         case 2:
17270         /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
17271         case 3:
17272         /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
17273             if (ctx->hflags & MIPS_HFLAG_BDS32) {
17274                 generate_exception_end(ctx, EXCP_RI);
17275                 return 2;
17276             }
17277             break;
17278         }
17279     }
17280
17281     switch (op) {
17282     case POOL16A:
17283         {
17284             int rd = mmreg(uMIPS_RD(ctx->opcode));
17285             int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
17286             int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
17287             uint32_t opc = 0;
17288
17289             switch (ctx->opcode & 0x1) {
17290             case ADDU16:
17291                 opc = OPC_ADDU;
17292                 break;
17293             case SUBU16:
17294                 opc = OPC_SUBU;
17295                 break;
17296             }
17297             if (ctx->insn_flags & ISA_MIPS32R6) {
17298                 /* In the Release 6 the register number location in
17299                  * the instruction encoding has changed.
17300                  */
17301                 gen_arith(ctx, opc, rs1, rd, rs2);
17302             } else {
17303                 gen_arith(ctx, opc, rd, rs1, rs2);
17304             }
17305         }
17306         break;
17307     case POOL16B:
17308         {
17309             int rd = mmreg(uMIPS_RD(ctx->opcode));
17310             int rs = mmreg(uMIPS_RS(ctx->opcode));
17311             int amount = (ctx->opcode >> 1) & 0x7;
17312             uint32_t opc = 0;
17313             amount = amount == 0 ? 8 : amount;
17314
17315             switch (ctx->opcode & 0x1) {
17316             case SLL16:
17317                 opc = OPC_SLL;
17318                 break;
17319             case SRL16:
17320                 opc = OPC_SRL;
17321                 break;
17322             }
17323
17324             gen_shift_imm(ctx, opc, rd, rs, amount);
17325         }
17326         break;
17327     case POOL16C:
17328         if (ctx->insn_flags & ISA_MIPS32R6) {
17329             gen_pool16c_r6_insn(ctx);
17330         } else {
17331             gen_pool16c_insn(ctx);
17332         }
17333         break;
17334     case LWGP16:
17335         {
17336             int rd = mmreg(uMIPS_RD(ctx->opcode));
17337             int rb = 28;            /* GP */
17338             int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
17339
17340             gen_ld(ctx, OPC_LW, rd, rb, offset);
17341         }
17342         break;
17343     case POOL16F:
17344         check_insn_opc_removed(ctx, ISA_MIPS32R6);
17345         if (ctx->opcode & 1) {
17346             generate_exception_end(ctx, EXCP_RI);
17347         } else {
17348             /* MOVEP */
17349             int enc_dest = uMIPS_RD(ctx->opcode);
17350             int enc_rt = uMIPS_RS2(ctx->opcode);
17351             int enc_rs = uMIPS_RS1(ctx->opcode);
17352             gen_movep(ctx, enc_dest, enc_rt, enc_rs);
17353         }
17354         break;
17355     case LBU16:
17356         {
17357             int rd = mmreg(uMIPS_RD(ctx->opcode));
17358             int rb = mmreg(uMIPS_RS(ctx->opcode));
17359             int16_t offset = ZIMM(ctx->opcode, 0, 4);
17360             offset = (offset == 0xf ? -1 : offset);
17361
17362             gen_ld(ctx, OPC_LBU, rd, rb, offset);
17363         }
17364         break;
17365     case LHU16:
17366         {
17367             int rd = mmreg(uMIPS_RD(ctx->opcode));
17368             int rb = mmreg(uMIPS_RS(ctx->opcode));
17369             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17370
17371             gen_ld(ctx, OPC_LHU, rd, rb, offset);
17372         }
17373         break;
17374     case LWSP16:
17375         {
17376             int rd = (ctx->opcode >> 5) & 0x1f;
17377             int rb = 29;            /* SP */
17378             int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17379
17380             gen_ld(ctx, OPC_LW, rd, rb, offset);
17381         }
17382         break;
17383     case LW16:
17384         {
17385             int rd = mmreg(uMIPS_RD(ctx->opcode));
17386             int rb = mmreg(uMIPS_RS(ctx->opcode));
17387             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17388
17389             gen_ld(ctx, OPC_LW, rd, rb, offset);
17390         }
17391         break;
17392     case SB16:
17393         {
17394             int rd = mmreg2(uMIPS_RD(ctx->opcode));
17395             int rb = mmreg(uMIPS_RS(ctx->opcode));
17396             int16_t offset = ZIMM(ctx->opcode, 0, 4);
17397
17398             gen_st(ctx, OPC_SB, rd, rb, offset);
17399         }
17400         break;
17401     case SH16:
17402         {
17403             int rd = mmreg2(uMIPS_RD(ctx->opcode));
17404             int rb = mmreg(uMIPS_RS(ctx->opcode));
17405             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17406
17407             gen_st(ctx, OPC_SH, rd, rb, offset);
17408         }
17409         break;
17410     case SWSP16:
17411         {
17412             int rd = (ctx->opcode >> 5) & 0x1f;
17413             int rb = 29;            /* SP */
17414             int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17415
17416             gen_st(ctx, OPC_SW, rd, rb, offset);
17417         }
17418         break;
17419     case SW16:
17420         {
17421             int rd = mmreg2(uMIPS_RD(ctx->opcode));
17422             int rb = mmreg(uMIPS_RS(ctx->opcode));
17423             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17424
17425             gen_st(ctx, OPC_SW, rd, rb, offset);
17426         }
17427         break;
17428     case MOVE16:
17429         {
17430             int rd = uMIPS_RD5(ctx->opcode);
17431             int rs = uMIPS_RS5(ctx->opcode);
17432
17433             gen_arith(ctx, OPC_ADDU, rd, rs, 0);
17434         }
17435         break;
17436     case ANDI16:
17437         gen_andi16(ctx);
17438         break;
17439     case POOL16D:
17440         switch (ctx->opcode & 0x1) {
17441         case ADDIUS5:
17442             gen_addius5(ctx);
17443             break;
17444         case ADDIUSP:
17445             gen_addiusp(ctx);
17446             break;
17447         }
17448         break;
17449     case POOL16E:
17450         switch (ctx->opcode & 0x1) {
17451         case ADDIUR2:
17452             gen_addiur2(ctx);
17453             break;
17454         case ADDIUR1SP:
17455             gen_addiur1sp(ctx);
17456             break;
17457         }
17458         break;
17459     case B16: /* BC16 */
17460         gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
17461                            sextract32(ctx->opcode, 0, 10) << 1,
17462                            (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17463         break;
17464     case BNEZ16: /* BNEZC16 */
17465     case BEQZ16: /* BEQZC16 */
17466         gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
17467                            mmreg(uMIPS_RD(ctx->opcode)),
17468                            0, sextract32(ctx->opcode, 0, 7) << 1,
17469                            (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17470
17471         break;
17472     case LI16:
17473         {
17474             int reg = mmreg(uMIPS_RD(ctx->opcode));
17475             int imm = ZIMM(ctx->opcode, 0, 7);
17476
17477             imm = (imm == 0x7f ? -1 : imm);
17478             tcg_gen_movi_tl(cpu_gpr[reg], imm);
17479         }
17480         break;
17481     case RES_29:
17482     case RES_31:
17483     case RES_39:
17484         generate_exception_end(ctx, EXCP_RI);
17485         break;
17486     default:
17487         decode_micromips32_opc(env, ctx);
17488         return 4;
17489     }
17490
17491     return 2;
17492 }
17493
17494 /*
17495  *
17496  * nanoMIPS opcodes
17497  *
17498  */
17499
17500 /* MAJOR, P16, and P32 pools opcodes */
17501 enum {
17502     NM_P_ADDIU      = 0x00,
17503     NM_ADDIUPC      = 0x01,
17504     NM_MOVE_BALC    = 0x02,
17505     NM_P16_MV       = 0x04,
17506     NM_LW16         = 0x05,
17507     NM_BC16         = 0x06,
17508     NM_P16_SR       = 0x07,
17509
17510     NM_POOL32A      = 0x08,
17511     NM_P_BAL        = 0x0a,
17512     NM_P16_SHIFT    = 0x0c,
17513     NM_LWSP16       = 0x0d,
17514     NM_BALC16       = 0x0e,
17515     NM_P16_4X4      = 0x0f,
17516
17517     NM_P_GP_W       = 0x10,
17518     NM_P_GP_BH      = 0x11,
17519     NM_P_J          = 0x12,
17520     NM_P16C         = 0x14,
17521     NM_LWGP16       = 0x15,
17522     NM_P16_LB       = 0x17,
17523
17524     NM_P48I         = 0x18,
17525     NM_P16_A1       = 0x1c,
17526     NM_LW4X4        = 0x1d,
17527     NM_P16_LH       = 0x1f,
17528
17529     NM_P_U12        = 0x20,
17530     NM_P_LS_U12     = 0x21,
17531     NM_P_BR1        = 0x22,
17532     NM_P16_A2       = 0x24,
17533     NM_SW16         = 0x25,
17534     NM_BEQZC16      = 0x26,
17535
17536     NM_POOL32F      = 0x28,
17537     NM_P_LS_S9      = 0x29,
17538     NM_P_BR2        = 0x2a,
17539
17540     NM_P16_ADDU     = 0x2c,
17541     NM_SWSP16       = 0x2d,
17542     NM_BNEZC16      = 0x2e,
17543     NM_MOVEP        = 0x2f,
17544
17545     NM_POOL32S      = 0x30,
17546     NM_P_BRI        = 0x32,
17547     NM_LI16         = 0x34,
17548     NM_SWGP16       = 0x35,
17549     NM_P16_BR       = 0x36,
17550
17551     NM_P_LUI        = 0x38,
17552     NM_ANDI16       = 0x3c,
17553     NM_SW4X4        = 0x3d,
17554     NM_MOVEPREV     = 0x3f,
17555 };
17556
17557 /* POOL32A instruction pool */
17558 enum {
17559     NM_POOL32A0    = 0x00,
17560     NM_SPECIAL2    = 0x01,
17561     NM_COP2_1      = 0x02,
17562     NM_UDI         = 0x03,
17563     NM_POOL32A5    = 0x05,
17564     NM_POOL32A7    = 0x07,
17565 };
17566
17567 /* P.GP.W instruction pool */
17568 enum {
17569     NM_ADDIUGP_W = 0x00,
17570     NM_LWGP      = 0x02,
17571     NM_SWGP      = 0x03,
17572 };
17573
17574 /* P48I instruction pool */
17575 enum {
17576     NM_LI48        = 0x00,
17577     NM_ADDIU48     = 0x01,
17578     NM_ADDIUGP48   = 0x02,
17579     NM_ADDIUPC48   = 0x03,
17580     NM_LWPC48      = 0x0b,
17581     NM_SWPC48      = 0x0f,
17582 };
17583
17584 /* P.U12 instruction pool */
17585 enum {
17586     NM_ORI      = 0x00,
17587     NM_XORI     = 0x01,
17588     NM_ANDI     = 0x02,
17589     NM_P_SR     = 0x03,
17590     NM_SLTI     = 0x04,
17591     NM_SLTIU    = 0x05,
17592     NM_SEQI     = 0x06,
17593     NM_ADDIUNEG = 0x08,
17594     NM_P_SHIFT  = 0x0c,
17595     NM_P_ROTX   = 0x0d,
17596     NM_P_INS    = 0x0e,
17597     NM_P_EXT    = 0x0f,
17598 };
17599
17600 /* POOL32F instruction pool */
17601 enum {
17602     NM_POOL32F_0   = 0x00,
17603     NM_POOL32F_3   = 0x03,
17604     NM_POOL32F_5   = 0x05,
17605 };
17606
17607 /* POOL32S instruction pool */
17608 enum {
17609     NM_POOL32S_0   = 0x00,
17610     NM_POOL32S_4   = 0x04,
17611 };
17612
17613 /* P.LUI instruction pool */
17614 enum {
17615     NM_LUI      = 0x00,
17616     NM_ALUIPC   = 0x01,
17617 };
17618
17619 /* P.GP.BH instruction pool */
17620 enum {
17621     NM_LBGP      = 0x00,
17622     NM_SBGP      = 0x01,
17623     NM_LBUGP     = 0x02,
17624     NM_ADDIUGP_B = 0x03,
17625     NM_P_GP_LH   = 0x04,
17626     NM_P_GP_SH   = 0x05,
17627     NM_P_GP_CP1  = 0x06,
17628 };
17629
17630 /* P.LS.U12 instruction pool */
17631 enum {
17632     NM_LB        = 0x00,
17633     NM_SB        = 0x01,
17634     NM_LBU       = 0x02,
17635     NM_P_PREFU12 = 0x03,
17636     NM_LH        = 0x04,
17637     NM_SH        = 0x05,
17638     NM_LHU       = 0x06,
17639     NM_LWU       = 0x07,
17640     NM_LW        = 0x08,
17641     NM_SW        = 0x09,
17642     NM_LWC1      = 0x0a,
17643     NM_SWC1      = 0x0b,
17644     NM_LDC1      = 0x0e,
17645     NM_SDC1      = 0x0f,
17646 };
17647
17648 /* P.LS.S9 instruction pool */
17649 enum {
17650     NM_P_LS_S0         = 0x00,
17651     NM_P_LS_S1         = 0x01,
17652     NM_P_LS_E0         = 0x02,
17653     NM_P_LS_WM         = 0x04,
17654     NM_P_LS_UAWM       = 0x05,
17655 };
17656
17657 /* P.BAL instruction pool */
17658 enum {
17659     NM_BC       = 0x00,
17660     NM_BALC     = 0x01,
17661 };
17662
17663 /* P.J instruction pool */
17664 enum {
17665     NM_JALRC    = 0x00,
17666     NM_JALRC_HB = 0x01,
17667     NM_P_BALRSC = 0x08,
17668 };
17669
17670 /* P.BR1 instruction pool */
17671 enum {
17672     NM_BEQC     = 0x00,
17673     NM_P_BR3A   = 0x01,
17674     NM_BGEC     = 0x02,
17675     NM_BGEUC    = 0x03,
17676 };
17677
17678 /* P.BR2 instruction pool */
17679 enum {
17680     NM_BNEC     = 0x00,
17681     NM_BLTC     = 0x02,
17682     NM_BLTUC    = 0x03,
17683 };
17684
17685 /* P.BRI instruction pool */
17686 enum {
17687     NM_BEQIC    = 0x00,
17688     NM_BBEQZC   = 0x01,
17689     NM_BGEIC    = 0x02,
17690     NM_BGEIUC   = 0x03,
17691     NM_BNEIC    = 0x04,
17692     NM_BBNEZC   = 0x05,
17693     NM_BLTIC    = 0x06,
17694     NM_BLTIUC   = 0x07,
17695 };
17696
17697 /* P16.SHIFT instruction pool */
17698 enum {
17699     NM_SLL16    = 0x00,
17700     NM_SRL16    = 0x01,
17701 };
17702
17703 /* POOL16C instruction pool */
17704 enum {
17705     NM_POOL16C_0  = 0x00,
17706     NM_LWXS16     = 0x01,
17707 };
17708
17709 /* P16.A1 instruction pool */
17710 enum {
17711     NM_ADDIUR1SP = 0x01,
17712 };
17713
17714 /* P16.A2 instruction pool */
17715 enum {
17716     NM_ADDIUR2  = 0x00,
17717     NM_P_ADDIURS5  = 0x01,
17718 };
17719
17720 /* P16.ADDU instruction pool */
17721 enum {
17722     NM_ADDU16     = 0x00,
17723     NM_SUBU16     = 0x01,
17724 };
17725
17726 /* P16.SR instruction pool */
17727 enum {
17728     NM_SAVE16        = 0x00,
17729     NM_RESTORE_JRC16 = 0x01,
17730 };
17731
17732 /* P16.4X4 instruction pool */
17733 enum {
17734     NM_ADDU4X4      = 0x00,
17735     NM_MUL4X4       = 0x01,
17736 };
17737
17738 /* P16.LB instruction pool */
17739 enum {
17740     NM_LB16       = 0x00,
17741     NM_SB16       = 0x01,
17742     NM_LBU16      = 0x02,
17743 };
17744
17745 /* P16.LH  instruction pool */
17746 enum {
17747     NM_LH16     = 0x00,
17748     NM_SH16     = 0x01,
17749     NM_LHU16    = 0x02,
17750 };
17751
17752 /* P.RI instruction pool */
17753 enum {
17754     NM_SIGRIE       = 0x00,
17755     NM_P_SYSCALL    = 0x01,
17756     NM_BREAK        = 0x02,
17757     NM_SDBBP        = 0x03,
17758 };
17759
17760 /* POOL32A0 instruction pool */
17761 enum {
17762     NM_P_TRAP   = 0x00,
17763     NM_SEB      = 0x01,
17764     NM_SLLV     = 0x02,
17765     NM_MUL      = 0x03,
17766     NM_MFC0     = 0x06,
17767     NM_MFHC0    = 0x07,
17768     NM_SEH      = 0x09,
17769     NM_SRLV     = 0x0a,
17770     NM_MUH      = 0x0b,
17771     NM_MTC0     = 0x0e,
17772     NM_MTHC0    = 0x0f,
17773     NM_SRAV     = 0x12,
17774     NM_MULU     = 0x13,
17775     NM_ROTRV    = 0x1a,
17776     NM_MUHU     = 0x1b,
17777     NM_ADD      = 0x22,
17778     NM_DIV      = 0x23,
17779     NM_ADDU     = 0x2a,
17780     NM_MOD      = 0x2b,
17781     NM_SUB      = 0x32,
17782     NM_DIVU     = 0x33,
17783     NM_RDHWR    = 0x38,
17784     NM_SUBU     = 0x3a,
17785     NM_MODU     = 0x3b,
17786     NM_P_CMOVE  = 0x42,
17787     NM_FORK     = 0x45,
17788     NM_MFTR     = 0x46,
17789     NM_MFHTR    = 0x47,
17790     NM_AND      = 0x4a,
17791     NM_YIELD    = 0x4d,
17792     NM_MTTR     = 0x4e,
17793     NM_MTHTR    = 0x4f,
17794     NM_OR       = 0x52,
17795     NM_D_E_MT_VPE = 0x56,
17796     NM_NOR      = 0x5a,
17797     NM_XOR      = 0x62,
17798     NM_SLT      = 0x6a,
17799     NM_P_SLTU   = 0x72,
17800     NM_SOV      = 0x7a,
17801 };
17802
17803 /* CRC32 instruction pool */
17804 enum {
17805     NM_CRC32B   = 0x00,
17806     NM_CRC32H   = 0x01,
17807     NM_CRC32W   = 0x02,
17808     NM_CRC32CB  = 0x04,
17809     NM_CRC32CH  = 0x05,
17810     NM_CRC32CW  = 0x06,
17811 };
17812
17813 /* POOL32A5 instruction pool */
17814 enum {
17815     NM_CMP_EQ_PH        = 0x00,
17816     NM_CMP_LT_PH        = 0x08,
17817     NM_CMP_LE_PH        = 0x10,
17818     NM_CMPGU_EQ_QB      = 0x18,
17819     NM_CMPGU_LT_QB      = 0x20,
17820     NM_CMPGU_LE_QB      = 0x28,
17821     NM_CMPGDU_EQ_QB     = 0x30,
17822     NM_CMPGDU_LT_QB     = 0x38,
17823     NM_CMPGDU_LE_QB     = 0x40,
17824     NM_CMPU_EQ_QB       = 0x48,
17825     NM_CMPU_LT_QB       = 0x50,
17826     NM_CMPU_LE_QB       = 0x58,
17827     NM_ADDQ_S_W         = 0x60,
17828     NM_SUBQ_S_W         = 0x68,
17829     NM_ADDSC            = 0x70,
17830     NM_ADDWC            = 0x78,
17831
17832     NM_ADDQ_S_PH   = 0x01,
17833     NM_ADDQH_R_PH  = 0x09,
17834     NM_ADDQH_R_W   = 0x11,
17835     NM_ADDU_S_QB   = 0x19,
17836     NM_ADDU_S_PH   = 0x21,
17837     NM_ADDUH_R_QB  = 0x29,
17838     NM_SHRAV_R_PH  = 0x31,
17839     NM_SHRAV_R_QB  = 0x39,
17840     NM_SUBQ_S_PH   = 0x41,
17841     NM_SUBQH_R_PH  = 0x49,
17842     NM_SUBQH_R_W   = 0x51,
17843     NM_SUBU_S_QB   = 0x59,
17844     NM_SUBU_S_PH   = 0x61,
17845     NM_SUBUH_R_QB  = 0x69,
17846     NM_SHLLV_S_PH  = 0x71,
17847     NM_PRECR_SRA_R_PH_W = 0x79,
17848
17849     NM_MULEU_S_PH_QBL   = 0x12,
17850     NM_MULEU_S_PH_QBR   = 0x1a,
17851     NM_MULQ_RS_PH       = 0x22,
17852     NM_MULQ_S_PH        = 0x2a,
17853     NM_MULQ_RS_W        = 0x32,
17854     NM_MULQ_S_W         = 0x3a,
17855     NM_APPEND           = 0x42,
17856     NM_MODSUB           = 0x52,
17857     NM_SHRAV_R_W        = 0x5a,
17858     NM_SHRLV_PH         = 0x62,
17859     NM_SHRLV_QB         = 0x6a,
17860     NM_SHLLV_QB         = 0x72,
17861     NM_SHLLV_S_W        = 0x7a,
17862
17863     NM_SHILO            = 0x03,
17864
17865     NM_MULEQ_S_W_PHL    = 0x04,
17866     NM_MULEQ_S_W_PHR    = 0x0c,
17867
17868     NM_MUL_S_PH         = 0x05,
17869     NM_PRECR_QB_PH      = 0x0d,
17870     NM_PRECRQ_QB_PH     = 0x15,
17871     NM_PRECRQ_PH_W      = 0x1d,
17872     NM_PRECRQ_RS_PH_W   = 0x25,
17873     NM_PRECRQU_S_QB_PH  = 0x2d,
17874     NM_PACKRL_PH        = 0x35,
17875     NM_PICK_QB          = 0x3d,
17876     NM_PICK_PH          = 0x45,
17877
17878     NM_SHRA_R_W         = 0x5e,
17879     NM_SHRA_R_PH        = 0x66,
17880     NM_SHLL_S_PH        = 0x76,
17881     NM_SHLL_S_W         = 0x7e,
17882
17883     NM_REPL_PH          = 0x07
17884 };
17885
17886 /* POOL32A7 instruction pool */
17887 enum {
17888     NM_P_LSX        = 0x00,
17889     NM_LSA          = 0x01,
17890     NM_EXTW         = 0x03,
17891     NM_POOL32AXF    = 0x07,
17892 };
17893
17894 /* P.SR instruction pool */
17895 enum {
17896     NM_PP_SR           = 0x00,
17897     NM_P_SR_F          = 0x01,
17898 };
17899
17900 /* P.SHIFT instruction pool */
17901 enum {
17902     NM_P_SLL        = 0x00,
17903     NM_SRL          = 0x02,
17904     NM_SRA          = 0x04,
17905     NM_ROTR         = 0x06,
17906 };
17907
17908 /* P.ROTX instruction pool */
17909 enum {
17910     NM_ROTX         = 0x00,
17911 };
17912
17913 /* P.INS instruction pool */
17914 enum {
17915     NM_INS          = 0x00,
17916 };
17917
17918 /* P.EXT instruction pool */
17919 enum {
17920     NM_EXT          = 0x00,
17921 };
17922
17923 /* POOL32F_0 (fmt) instruction pool */
17924 enum {
17925     NM_RINT_S              = 0x04,
17926     NM_RINT_D              = 0x44,
17927     NM_ADD_S               = 0x06,
17928     NM_SELEQZ_S            = 0x07,
17929     NM_SELEQZ_D            = 0x47,
17930     NM_CLASS_S             = 0x0c,
17931     NM_CLASS_D             = 0x4c,
17932     NM_SUB_S               = 0x0e,
17933     NM_SELNEZ_S            = 0x0f,
17934     NM_SELNEZ_D            = 0x4f,
17935     NM_MUL_S               = 0x16,
17936     NM_SEL_S               = 0x17,
17937     NM_SEL_D               = 0x57,
17938     NM_DIV_S               = 0x1e,
17939     NM_ADD_D               = 0x26,
17940     NM_SUB_D               = 0x2e,
17941     NM_MUL_D               = 0x36,
17942     NM_MADDF_S             = 0x37,
17943     NM_MADDF_D             = 0x77,
17944     NM_DIV_D               = 0x3e,
17945     NM_MSUBF_S             = 0x3f,
17946     NM_MSUBF_D             = 0x7f,
17947 };
17948
17949 /* POOL32F_3  instruction pool */
17950 enum {
17951     NM_MIN_FMT         = 0x00,
17952     NM_MAX_FMT         = 0x01,
17953     NM_MINA_FMT        = 0x04,
17954     NM_MAXA_FMT        = 0x05,
17955     NM_POOL32FXF       = 0x07,
17956 };
17957
17958 /* POOL32F_5  instruction pool */
17959 enum {
17960     NM_CMP_CONDN_S     = 0x00,
17961     NM_CMP_CONDN_D     = 0x02,
17962 };
17963
17964 /* P.GP.LH instruction pool */
17965 enum {
17966     NM_LHGP    = 0x00,
17967     NM_LHUGP   = 0x01,
17968 };
17969
17970 /* P.GP.SH instruction pool */
17971 enum {
17972     NM_SHGP    = 0x00,
17973 };
17974
17975 /* P.GP.CP1 instruction pool */
17976 enum {
17977     NM_LWC1GP       = 0x00,
17978     NM_SWC1GP       = 0x01,
17979     NM_LDC1GP       = 0x02,
17980     NM_SDC1GP       = 0x03,
17981 };
17982
17983 /* P.LS.S0 instruction pool */
17984 enum {
17985     NM_LBS9     = 0x00,
17986     NM_LHS9     = 0x04,
17987     NM_LWS9     = 0x08,
17988     NM_LDS9     = 0x0c,
17989
17990     NM_SBS9     = 0x01,
17991     NM_SHS9     = 0x05,
17992     NM_SWS9     = 0x09,
17993     NM_SDS9     = 0x0d,
17994
17995     NM_LBUS9    = 0x02,
17996     NM_LHUS9    = 0x06,
17997     NM_LWC1S9   = 0x0a,
17998     NM_LDC1S9   = 0x0e,
17999
18000     NM_P_PREFS9 = 0x03,
18001     NM_LWUS9    = 0x07,
18002     NM_SWC1S9   = 0x0b,
18003     NM_SDC1S9   = 0x0f,
18004 };
18005
18006 /* P.LS.S1 instruction pool */
18007 enum {
18008     NM_ASET_ACLR = 0x02,
18009     NM_UALH      = 0x04,
18010     NM_UASH      = 0x05,
18011     NM_CACHE     = 0x07,
18012     NM_P_LL      = 0x0a,
18013     NM_P_SC      = 0x0b,
18014 };
18015
18016 /* P.LS.E0 instruction pool */
18017 enum {
18018     NM_LBE      = 0x00,
18019     NM_SBE      = 0x01,
18020     NM_LBUE     = 0x02,
18021     NM_P_PREFE  = 0x03,
18022     NM_LHE      = 0x04,
18023     NM_SHE      = 0x05,
18024     NM_LHUE     = 0x06,
18025     NM_CACHEE   = 0x07,
18026     NM_LWE      = 0x08,
18027     NM_SWE      = 0x09,
18028     NM_P_LLE    = 0x0a,
18029     NM_P_SCE    = 0x0b,
18030 };
18031
18032 /* P.PREFE instruction pool */
18033 enum {
18034     NM_SYNCIE   = 0x00,
18035     NM_PREFE    = 0x01,
18036 };
18037
18038 /* P.LLE instruction pool */
18039 enum {
18040     NM_LLE      = 0x00,
18041     NM_LLWPE    = 0x01,
18042 };
18043
18044 /* P.SCE instruction pool */
18045 enum {
18046     NM_SCE      = 0x00,
18047     NM_SCWPE    = 0x01,
18048 };
18049
18050 /* P.LS.WM instruction pool */
18051 enum {
18052     NM_LWM       = 0x00,
18053     NM_SWM       = 0x01,
18054 };
18055
18056 /* P.LS.UAWM instruction pool */
18057 enum {
18058     NM_UALWM       = 0x00,
18059     NM_UASWM       = 0x01,
18060 };
18061
18062 /* P.BR3A instruction pool */
18063 enum {
18064     NM_BC1EQZC          = 0x00,
18065     NM_BC1NEZC          = 0x01,
18066     NM_BC2EQZC          = 0x02,
18067     NM_BC2NEZC          = 0x03,
18068     NM_BPOSGE32C        = 0x04,
18069 };
18070
18071 /* P16.RI instruction pool */
18072 enum {
18073     NM_P16_SYSCALL  = 0x01,
18074     NM_BREAK16      = 0x02,
18075     NM_SDBBP16      = 0x03,
18076 };
18077
18078 /* POOL16C_0 instruction pool */
18079 enum {
18080     NM_POOL16C_00      = 0x00,
18081 };
18082
18083 /* P16.JRC instruction pool */
18084 enum {
18085     NM_JRC          = 0x00,
18086     NM_JALRC16      = 0x01,
18087 };
18088
18089 /* P.SYSCALL instruction pool */
18090 enum {
18091     NM_SYSCALL      = 0x00,
18092     NM_HYPCALL      = 0x01,
18093 };
18094
18095 /* P.TRAP instruction pool */
18096 enum {
18097     NM_TEQ          = 0x00,
18098     NM_TNE          = 0x01,
18099 };
18100
18101 /* P.CMOVE instruction pool */
18102 enum {
18103     NM_MOVZ            = 0x00,
18104     NM_MOVN            = 0x01,
18105 };
18106
18107 /* POOL32Axf instruction pool */
18108 enum {
18109     NM_POOL32AXF_1 = 0x01,
18110     NM_POOL32AXF_2 = 0x02,
18111     NM_POOL32AXF_4 = 0x04,
18112     NM_POOL32AXF_5 = 0x05,
18113     NM_POOL32AXF_7 = 0x07,
18114 };
18115
18116 /* POOL32Axf_1 instruction pool */
18117 enum {
18118     NM_POOL32AXF_1_0 = 0x00,
18119     NM_POOL32AXF_1_1 = 0x01,
18120     NM_POOL32AXF_1_3 = 0x03,
18121     NM_POOL32AXF_1_4 = 0x04,
18122     NM_POOL32AXF_1_5 = 0x05,
18123     NM_POOL32AXF_1_7 = 0x07,
18124 };
18125
18126 /* POOL32Axf_2 instruction pool */
18127 enum {
18128     NM_POOL32AXF_2_0_7     = 0x00,
18129     NM_POOL32AXF_2_8_15    = 0x01,
18130     NM_POOL32AXF_2_16_23   = 0x02,
18131     NM_POOL32AXF_2_24_31   = 0x03,
18132 };
18133
18134 /* POOL32Axf_7 instruction pool */
18135 enum {
18136     NM_SHRA_R_QB    = 0x0,
18137     NM_SHRL_PH      = 0x1,
18138     NM_REPL_QB      = 0x2,
18139 };
18140
18141 /* POOL32Axf_1_0 instruction pool */
18142 enum {
18143     NM_MFHI = 0x0,
18144     NM_MFLO = 0x1,
18145     NM_MTHI = 0x2,
18146     NM_MTLO = 0x3,
18147 };
18148
18149 /* POOL32Axf_1_1 instruction pool */
18150 enum {
18151     NM_MTHLIP = 0x0,
18152     NM_SHILOV = 0x1,
18153 };
18154
18155 /* POOL32Axf_1_3 instruction pool */
18156 enum {
18157     NM_RDDSP    = 0x0,
18158     NM_WRDSP    = 0x1,
18159     NM_EXTP     = 0x2,
18160     NM_EXTPDP   = 0x3,
18161 };
18162
18163 /* POOL32Axf_1_4 instruction pool */
18164 enum {
18165     NM_SHLL_QB  = 0x0,
18166     NM_SHRL_QB  = 0x1,
18167 };
18168
18169 /* POOL32Axf_1_5 instruction pool */
18170 enum {
18171     NM_MAQ_S_W_PHR   = 0x0,
18172     NM_MAQ_S_W_PHL   = 0x1,
18173     NM_MAQ_SA_W_PHR  = 0x2,
18174     NM_MAQ_SA_W_PHL  = 0x3,
18175 };
18176
18177 /* POOL32Axf_1_7 instruction pool */
18178 enum {
18179     NM_EXTR_W       = 0x0,
18180     NM_EXTR_R_W     = 0x1,
18181     NM_EXTR_RS_W    = 0x2,
18182     NM_EXTR_S_H     = 0x3,
18183 };
18184
18185 /* POOL32Axf_2_0_7 instruction pool */
18186 enum {
18187     NM_DPA_W_PH     = 0x0,
18188     NM_DPAQ_S_W_PH  = 0x1,
18189     NM_DPS_W_PH     = 0x2,
18190     NM_DPSQ_S_W_PH  = 0x3,
18191     NM_BALIGN       = 0x4,
18192     NM_MADD         = 0x5,
18193     NM_MULT         = 0x6,
18194     NM_EXTRV_W      = 0x7,
18195 };
18196
18197 /* POOL32Axf_2_8_15 instruction pool */
18198 enum {
18199     NM_DPAX_W_PH    = 0x0,
18200     NM_DPAQ_SA_L_W  = 0x1,
18201     NM_DPSX_W_PH    = 0x2,
18202     NM_DPSQ_SA_L_W  = 0x3,
18203     NM_MADDU        = 0x5,
18204     NM_MULTU        = 0x6,
18205     NM_EXTRV_R_W    = 0x7,
18206 };
18207
18208 /* POOL32Axf_2_16_23 instruction pool */
18209 enum {
18210     NM_DPAU_H_QBL       = 0x0,
18211     NM_DPAQX_S_W_PH     = 0x1,
18212     NM_DPSU_H_QBL       = 0x2,
18213     NM_DPSQX_S_W_PH     = 0x3,
18214     NM_EXTPV            = 0x4,
18215     NM_MSUB             = 0x5,
18216     NM_MULSA_W_PH       = 0x6,
18217     NM_EXTRV_RS_W       = 0x7,
18218 };
18219
18220 /* POOL32Axf_2_24_31 instruction pool */
18221 enum {
18222     NM_DPAU_H_QBR       = 0x0,
18223     NM_DPAQX_SA_W_PH    = 0x1,
18224     NM_DPSU_H_QBR       = 0x2,
18225     NM_DPSQX_SA_W_PH    = 0x3,
18226     NM_EXTPDPV          = 0x4,
18227     NM_MSUBU            = 0x5,
18228     NM_MULSAQ_S_W_PH    = 0x6,
18229     NM_EXTRV_S_H        = 0x7,
18230 };
18231
18232 /* POOL32Axf_{4, 5} instruction pool */
18233 enum {
18234     NM_CLO      = 0x25,
18235     NM_CLZ      = 0x2d,
18236
18237     NM_TLBP     = 0x01,
18238     NM_TLBR     = 0x09,
18239     NM_TLBWI    = 0x11,
18240     NM_TLBWR    = 0x19,
18241     NM_TLBINV   = 0x03,
18242     NM_TLBINVF  = 0x0b,
18243     NM_DI       = 0x23,
18244     NM_EI       = 0x2b,
18245     NM_RDPGPR   = 0x70,
18246     NM_WRPGPR   = 0x78,
18247     NM_WAIT     = 0x61,
18248     NM_DERET    = 0x71,
18249     NM_ERETX    = 0x79,
18250
18251     /* nanoMIPS DSP instructions */
18252     NM_ABSQ_S_QB        = 0x00,
18253     NM_ABSQ_S_PH        = 0x08,
18254     NM_ABSQ_S_W         = 0x10,
18255     NM_PRECEQ_W_PHL     = 0x28,
18256     NM_PRECEQ_W_PHR     = 0x30,
18257     NM_PRECEQU_PH_QBL   = 0x38,
18258     NM_PRECEQU_PH_QBR   = 0x48,
18259     NM_PRECEU_PH_QBL    = 0x58,
18260     NM_PRECEU_PH_QBR    = 0x68,
18261     NM_PRECEQU_PH_QBLA  = 0x39,
18262     NM_PRECEQU_PH_QBRA  = 0x49,
18263     NM_PRECEU_PH_QBLA   = 0x59,
18264     NM_PRECEU_PH_QBRA   = 0x69,
18265     NM_REPLV_PH         = 0x01,
18266     NM_REPLV_QB         = 0x09,
18267     NM_BITREV           = 0x18,
18268     NM_INSV             = 0x20,
18269     NM_RADDU_W_QB       = 0x78,
18270
18271     NM_BITSWAP          = 0x05,
18272     NM_WSBH             = 0x3d,
18273 };
18274
18275 /* PP.SR instruction pool */
18276 enum {
18277     NM_SAVE         = 0x00,
18278     NM_RESTORE      = 0x02,
18279     NM_RESTORE_JRC  = 0x03,
18280 };
18281
18282 /* P.SR.F instruction pool */
18283 enum {
18284     NM_SAVEF        = 0x00,
18285     NM_RESTOREF     = 0x01,
18286 };
18287
18288 /* P16.SYSCALL  instruction pool */
18289 enum {
18290     NM_SYSCALL16     = 0x00,
18291     NM_HYPCALL16     = 0x01,
18292 };
18293
18294 /* POOL16C_00 instruction pool */
18295 enum {
18296     NM_NOT16           = 0x00,
18297     NM_XOR16           = 0x01,
18298     NM_AND16           = 0x02,
18299     NM_OR16            = 0x03,
18300 };
18301
18302 /* PP.LSX and PP.LSXS instruction pool */
18303 enum {
18304     NM_LBX      = 0x00,
18305     NM_LHX      = 0x04,
18306     NM_LWX      = 0x08,
18307     NM_LDX      = 0x0c,
18308
18309     NM_SBX      = 0x01,
18310     NM_SHX      = 0x05,
18311     NM_SWX      = 0x09,
18312     NM_SDX      = 0x0d,
18313
18314     NM_LBUX     = 0x02,
18315     NM_LHUX     = 0x06,
18316     NM_LWC1X    = 0x0a,
18317     NM_LDC1X    = 0x0e,
18318
18319     NM_LWUX     = 0x07,
18320     NM_SWC1X    = 0x0b,
18321     NM_SDC1X    = 0x0f,
18322
18323     NM_LHXS     = 0x04,
18324     NM_LWXS     = 0x08,
18325     NM_LDXS     = 0x0c,
18326
18327     NM_SHXS     = 0x05,
18328     NM_SWXS     = 0x09,
18329     NM_SDXS     = 0x0d,
18330
18331     NM_LHUXS    = 0x06,
18332     NM_LWC1XS   = 0x0a,
18333     NM_LDC1XS   = 0x0e,
18334
18335     NM_LWUXS    = 0x07,
18336     NM_SWC1XS   = 0x0b,
18337     NM_SDC1XS   = 0x0f,
18338 };
18339
18340 /* ERETx instruction pool */
18341 enum {
18342     NM_ERET     = 0x00,
18343     NM_ERETNC   = 0x01,
18344 };
18345
18346 /* POOL32FxF_{0, 1} insturction pool */
18347 enum {
18348     NM_CFC1     = 0x40,
18349     NM_CTC1     = 0x60,
18350     NM_MFC1     = 0x80,
18351     NM_MTC1     = 0xa0,
18352     NM_MFHC1    = 0xc0,
18353     NM_MTHC1    = 0xe0,
18354
18355     NM_CVT_S_PL = 0x84,
18356     NM_CVT_S_PU = 0xa4,
18357
18358     NM_CVT_L_S     = 0x004,
18359     NM_CVT_L_D     = 0x104,
18360     NM_CVT_W_S     = 0x024,
18361     NM_CVT_W_D     = 0x124,
18362
18363     NM_RSQRT_S     = 0x008,
18364     NM_RSQRT_D     = 0x108,
18365
18366     NM_SQRT_S      = 0x028,
18367     NM_SQRT_D      = 0x128,
18368
18369     NM_RECIP_S     = 0x048,
18370     NM_RECIP_D     = 0x148,
18371
18372     NM_FLOOR_L_S   = 0x00c,
18373     NM_FLOOR_L_D   = 0x10c,
18374
18375     NM_FLOOR_W_S   = 0x02c,
18376     NM_FLOOR_W_D   = 0x12c,
18377
18378     NM_CEIL_L_S    = 0x04c,
18379     NM_CEIL_L_D    = 0x14c,
18380     NM_CEIL_W_S    = 0x06c,
18381     NM_CEIL_W_D    = 0x16c,
18382     NM_TRUNC_L_S   = 0x08c,
18383     NM_TRUNC_L_D   = 0x18c,
18384     NM_TRUNC_W_S   = 0x0ac,
18385     NM_TRUNC_W_D   = 0x1ac,
18386     NM_ROUND_L_S   = 0x0cc,
18387     NM_ROUND_L_D   = 0x1cc,
18388     NM_ROUND_W_S   = 0x0ec,
18389     NM_ROUND_W_D   = 0x1ec,
18390
18391     NM_MOV_S       = 0x01,
18392     NM_MOV_D       = 0x81,
18393     NM_ABS_S       = 0x0d,
18394     NM_ABS_D       = 0x8d,
18395     NM_NEG_S       = 0x2d,
18396     NM_NEG_D       = 0xad,
18397     NM_CVT_D_S     = 0x04d,
18398     NM_CVT_D_W     = 0x0cd,
18399     NM_CVT_D_L     = 0x14d,
18400     NM_CVT_S_D     = 0x06d,
18401     NM_CVT_S_W     = 0x0ed,
18402     NM_CVT_S_L     = 0x16d,
18403 };
18404
18405 /* P.LL instruction pool */
18406 enum {
18407     NM_LL       = 0x00,
18408     NM_LLWP     = 0x01,
18409 };
18410
18411 /* P.SC instruction pool */
18412 enum {
18413     NM_SC       = 0x00,
18414     NM_SCWP     = 0x01,
18415 };
18416
18417 /* P.DVP instruction pool */
18418 enum {
18419     NM_DVP      = 0x00,
18420     NM_EVP      = 0x01,
18421 };
18422
18423
18424 /*
18425  *
18426  * nanoMIPS decoding engine
18427  *
18428  */
18429
18430
18431 /* extraction utilities */
18432
18433 #define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7)
18434 #define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7)
18435 #define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7)
18436 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18437 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18438
18439 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
18440 static inline int decode_gpr_gpr3(int r)
18441 {
18442     static const int map[] = { 16, 17, 18, 19,  4,  5,  6,  7 };
18443
18444     return map[r & 0x7];
18445 }
18446
18447 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
18448 static inline int decode_gpr_gpr3_src_store(int r)
18449 {
18450     static const int map[] = {  0, 17, 18, 19,  4,  5,  6,  7 };
18451
18452     return map[r & 0x7];
18453 }
18454
18455 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
18456 static inline int decode_gpr_gpr4(int r)
18457 {
18458     static const int map[] = {  8,  9, 10, 11,  4,  5,  6,  7,
18459                                16, 17, 18, 19, 20, 21, 22, 23 };
18460
18461     return map[r & 0xf];
18462 }
18463
18464 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
18465 static inline int decode_gpr_gpr4_zero(int r)
18466 {
18467     static const int map[] = {  8,  9, 10,  0,  4,  5,  6,  7,
18468                                16, 17, 18, 19, 20, 21, 22, 23 };
18469
18470     return map[r & 0xf];
18471 }
18472
18473
18474 static void gen_adjust_sp(DisasContext *ctx, int u)
18475 {
18476     gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u);
18477 }
18478
18479 static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count,
18480                      uint8_t gp, uint16_t u)
18481 {
18482     int counter = 0;
18483     TCGv va = tcg_temp_new();
18484     TCGv t0 = tcg_temp_new();
18485
18486     while (counter != count) {
18487         bool use_gp = gp && (counter == count - 1);
18488         int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18489         int this_offset = -((counter + 1) << 2);
18490         gen_base_offset_addr(ctx, va, 29, this_offset);
18491         gen_load_gpr(t0, this_rt);
18492         tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx,
18493                            (MO_TEUL | ctx->default_tcg_memop_mask));
18494         counter++;
18495     }
18496
18497     /* adjust stack pointer */
18498     gen_adjust_sp(ctx, -u);
18499
18500     tcg_temp_free(t0);
18501     tcg_temp_free(va);
18502 }
18503
18504 static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count,
18505                         uint8_t gp, uint16_t u)
18506 {
18507     int counter = 0;
18508     TCGv va = tcg_temp_new();
18509     TCGv t0 = tcg_temp_new();
18510
18511     while (counter != count) {
18512         bool use_gp = gp && (counter == count - 1);
18513         int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18514         int this_offset = u - ((counter + 1) << 2);
18515         gen_base_offset_addr(ctx, va, 29, this_offset);
18516         tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL |
18517                         ctx->default_tcg_memop_mask);
18518         tcg_gen_ext32s_tl(t0, t0);
18519         gen_store_gpr(t0, this_rt);
18520         counter++;
18521     }
18522
18523     /* adjust stack pointer */
18524     gen_adjust_sp(ctx, u);
18525
18526     tcg_temp_free(t0);
18527     tcg_temp_free(va);
18528 }
18529
18530 static void gen_pool16c_nanomips_insn(DisasContext *ctx)
18531 {
18532     int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode));
18533     int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
18534
18535     switch (extract32(ctx->opcode, 2, 2)) {
18536     case NM_NOT16:
18537         gen_logic(ctx, OPC_NOR, rt, rs, 0);
18538         break;
18539     case NM_AND16:
18540         gen_logic(ctx, OPC_AND, rt, rt, rs);
18541         break;
18542     case NM_XOR16:
18543         gen_logic(ctx, OPC_XOR, rt, rt, rs);
18544         break;
18545     case NM_OR16:
18546         gen_logic(ctx, OPC_OR, rt, rt, rs);
18547         break;
18548     }
18549 }
18550
18551 static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
18552 {
18553     int rt = extract32(ctx->opcode, 21, 5);
18554     int rs = extract32(ctx->opcode, 16, 5);
18555     int rd = extract32(ctx->opcode, 11, 5);
18556
18557     switch (extract32(ctx->opcode, 3, 7)) {
18558     case NM_P_TRAP:
18559         switch (extract32(ctx->opcode, 10, 1)) {
18560         case NM_TEQ:
18561             check_nms(ctx);
18562             gen_trap(ctx, OPC_TEQ, rs, rt, -1);
18563             break;
18564         case NM_TNE:
18565             check_nms(ctx);
18566             gen_trap(ctx, OPC_TNE, rs, rt, -1);
18567             break;
18568         }
18569         break;
18570     case NM_RDHWR:
18571         check_nms(ctx);
18572         gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
18573         break;
18574     case NM_SEB:
18575         check_nms(ctx);
18576         gen_bshfl(ctx, OPC_SEB, rs, rt);
18577         break;
18578     case NM_SEH:
18579         gen_bshfl(ctx, OPC_SEH, rs, rt);
18580         break;
18581     case NM_SLLV:
18582         gen_shift(ctx, OPC_SLLV, rd, rt, rs);
18583         break;
18584     case NM_SRLV:
18585         gen_shift(ctx, OPC_SRLV, rd, rt, rs);
18586         break;
18587     case NM_SRAV:
18588         gen_shift(ctx, OPC_SRAV, rd, rt, rs);
18589         break;
18590     case NM_ROTRV:
18591         gen_shift(ctx, OPC_ROTRV, rd, rt, rs);
18592         break;
18593     case NM_ADD:
18594         gen_arith(ctx, OPC_ADD, rd, rs, rt);
18595         break;
18596     case NM_ADDU:
18597         gen_arith(ctx, OPC_ADDU, rd, rs, rt);
18598         break;
18599     case NM_SUB:
18600         check_nms(ctx);
18601         gen_arith(ctx, OPC_SUB, rd, rs, rt);
18602         break;
18603     case NM_SUBU:
18604         gen_arith(ctx, OPC_SUBU, rd, rs, rt);
18605         break;
18606     case NM_P_CMOVE:
18607         switch (extract32(ctx->opcode, 10, 1)) {
18608         case NM_MOVZ:
18609             gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
18610             break;
18611         case NM_MOVN:
18612             gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
18613             break;
18614         }
18615         break;
18616     case NM_AND:
18617         gen_logic(ctx, OPC_AND, rd, rs, rt);
18618         break;
18619     case NM_OR:
18620         gen_logic(ctx, OPC_OR, rd, rs, rt);
18621         break;
18622     case NM_NOR:
18623         gen_logic(ctx, OPC_NOR, rd, rs, rt);
18624         break;
18625     case NM_XOR:
18626         gen_logic(ctx, OPC_XOR, rd, rs, rt);
18627         break;
18628     case NM_SLT:
18629         gen_slt(ctx, OPC_SLT, rd, rs, rt);
18630         break;
18631     case NM_P_SLTU:
18632         if (rd == 0) {
18633             /* P_DVP */
18634 #ifndef CONFIG_USER_ONLY
18635             TCGv t0 = tcg_temp_new();
18636             switch (extract32(ctx->opcode, 10, 1)) {
18637             case NM_DVP:
18638                 if (ctx->vp) {
18639                     check_cp0_enabled(ctx);
18640                     gen_helper_dvp(t0, cpu_env);
18641                     gen_store_gpr(t0, rt);
18642                 }
18643                 break;
18644             case NM_EVP:
18645                 if (ctx->vp) {
18646                     check_cp0_enabled(ctx);
18647                     gen_helper_evp(t0, cpu_env);
18648                     gen_store_gpr(t0, rt);
18649                 }
18650                 break;
18651             }
18652             tcg_temp_free(t0);
18653 #endif
18654         } else {
18655             gen_slt(ctx, OPC_SLTU, rd, rs, rt);
18656         }
18657         break;
18658     case NM_SOV:
18659         {
18660             TCGv t0 = tcg_temp_new();
18661             TCGv t1 = tcg_temp_new();
18662             TCGv t2 = tcg_temp_new();
18663
18664             gen_load_gpr(t1, rs);
18665             gen_load_gpr(t2, rt);
18666             tcg_gen_add_tl(t0, t1, t2);
18667             tcg_gen_ext32s_tl(t0, t0);
18668             tcg_gen_xor_tl(t1, t1, t2);
18669             tcg_gen_xor_tl(t2, t0, t2);
18670             tcg_gen_andc_tl(t1, t2, t1);
18671
18672             /* operands of same sign, result different sign */
18673             tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0);
18674             gen_store_gpr(t0, rd);
18675
18676             tcg_temp_free(t0);
18677             tcg_temp_free(t1);
18678             tcg_temp_free(t2);
18679         }
18680         break;
18681     case NM_MUL:
18682         gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
18683         break;
18684     case NM_MUH:
18685         gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
18686         break;
18687     case NM_MULU:
18688         gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
18689         break;
18690     case NM_MUHU:
18691         gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
18692         break;
18693     case NM_DIV:
18694         gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
18695         break;
18696     case NM_MOD:
18697         gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
18698         break;
18699     case NM_DIVU:
18700         gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
18701         break;
18702     case NM_MODU:
18703         gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
18704         break;
18705 #ifndef CONFIG_USER_ONLY
18706     case NM_MFC0:
18707         check_cp0_enabled(ctx);
18708         if (rt == 0) {
18709             /* Treat as NOP. */
18710             break;
18711         }
18712         gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3));
18713         break;
18714     case NM_MTC0:
18715         check_cp0_enabled(ctx);
18716         {
18717             TCGv t0 = tcg_temp_new();
18718
18719             gen_load_gpr(t0, rt);
18720             gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3));
18721             tcg_temp_free(t0);
18722         }
18723         break;
18724     case NM_D_E_MT_VPE:
18725         {
18726             uint8_t sc = extract32(ctx->opcode, 10, 1);
18727             TCGv t0 = tcg_temp_new();
18728
18729             switch (sc) {
18730             case 0:
18731                 if (rs == 1) {
18732                     /* DMT */
18733                     check_cp0_mt(ctx);
18734                     gen_helper_dmt(t0);
18735                     gen_store_gpr(t0, rt);
18736                 } else if (rs == 0) {
18737                     /* DVPE */
18738                     check_cp0_mt(ctx);
18739                     gen_helper_dvpe(t0, cpu_env);
18740                     gen_store_gpr(t0, rt);
18741                 } else {
18742                     generate_exception_end(ctx, EXCP_RI);
18743                 }
18744                 break;
18745             case 1:
18746                 if (rs == 1) {
18747                     /* EMT */
18748                     check_cp0_mt(ctx);
18749                     gen_helper_emt(t0);
18750                     gen_store_gpr(t0, rt);
18751                 } else if (rs == 0) {
18752                     /* EVPE */
18753                     check_cp0_mt(ctx);
18754                     gen_helper_evpe(t0, cpu_env);
18755                     gen_store_gpr(t0, rt);
18756                 } else {
18757                     generate_exception_end(ctx, EXCP_RI);
18758                 }
18759                 break;
18760             }
18761
18762             tcg_temp_free(t0);
18763         }
18764         break;
18765     case NM_FORK:
18766         check_mt(ctx);
18767         {
18768             TCGv t0 = tcg_temp_new();
18769             TCGv t1 = tcg_temp_new();
18770
18771             gen_load_gpr(t0, rt);
18772             gen_load_gpr(t1, rs);
18773             gen_helper_fork(t0, t1);
18774             tcg_temp_free(t0);
18775             tcg_temp_free(t1);
18776         }
18777         break;
18778     case NM_MFTR:
18779     case NM_MFHTR:
18780         check_cp0_enabled(ctx);
18781         if (rd == 0) {
18782             /* Treat as NOP. */
18783             return;
18784         }
18785         gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18786                  extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18787         break;
18788     case NM_MTTR:
18789     case NM_MTHTR:
18790         check_cp0_enabled(ctx);
18791         gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18792                  extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18793         break;
18794     case NM_YIELD:
18795         check_mt(ctx);
18796         {
18797             TCGv t0 = tcg_temp_new();
18798
18799             gen_load_gpr(t0, rs);
18800             gen_helper_yield(t0, cpu_env, t0);
18801             gen_store_gpr(t0, rt);
18802             tcg_temp_free(t0);
18803         }
18804         break;
18805 #endif
18806     default:
18807         generate_exception_end(ctx, EXCP_RI);
18808         break;
18809     }
18810 }
18811
18812 /* dsp */
18813 static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc,
18814                                             int ret, int v1, int v2)
18815 {
18816     TCGv_i32 t0;
18817     TCGv v0_t;
18818     TCGv v1_t;
18819
18820     t0 = tcg_temp_new_i32();
18821
18822     v0_t = tcg_temp_new();
18823     v1_t = tcg_temp_new();
18824
18825     tcg_gen_movi_i32(t0, v2 >> 3);
18826
18827     gen_load_gpr(v0_t, ret);
18828     gen_load_gpr(v1_t, v1);
18829
18830     switch (opc) {
18831     case NM_MAQ_S_W_PHR:
18832         check_dsp(ctx);
18833         gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env);
18834         break;
18835     case NM_MAQ_S_W_PHL:
18836         check_dsp(ctx);
18837         gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env);
18838         break;
18839     case NM_MAQ_SA_W_PHR:
18840         check_dsp(ctx);
18841         gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env);
18842         break;
18843     case NM_MAQ_SA_W_PHL:
18844         check_dsp(ctx);
18845         gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env);
18846         break;
18847     default:
18848         generate_exception_end(ctx, EXCP_RI);
18849         break;
18850     }
18851
18852     tcg_temp_free_i32(t0);
18853
18854     tcg_temp_free(v0_t);
18855     tcg_temp_free(v1_t);
18856 }
18857
18858
18859 static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc,
18860                                     int ret, int v1, int v2)
18861 {
18862     int16_t imm;
18863     TCGv t0 = tcg_temp_new();
18864     TCGv t1 = tcg_temp_new();
18865     TCGv v0_t = tcg_temp_new();
18866
18867     gen_load_gpr(v0_t, v1);
18868
18869     switch (opc) {
18870     case NM_POOL32AXF_1_0:
18871         check_dsp(ctx);
18872         switch (extract32(ctx->opcode, 12, 2)) {
18873         case NM_MFHI:
18874             gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret);
18875             break;
18876         case NM_MFLO:
18877             gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret);
18878             break;
18879         case NM_MTHI:
18880             gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1);
18881             break;
18882         case NM_MTLO:
18883             gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1);
18884             break;
18885         }
18886         break;
18887     case NM_POOL32AXF_1_1:
18888         check_dsp(ctx);
18889         switch (extract32(ctx->opcode, 12, 2)) {
18890         case NM_MTHLIP:
18891             tcg_gen_movi_tl(t0, v2);
18892             gen_helper_mthlip(t0, v0_t, cpu_env);
18893             break;
18894         case NM_SHILOV:
18895             tcg_gen_movi_tl(t0, v2 >> 3);
18896             gen_helper_shilo(t0, v0_t, cpu_env);
18897             break;
18898         default:
18899             generate_exception_end(ctx, EXCP_RI);
18900             break;
18901         }
18902         break;
18903     case NM_POOL32AXF_1_3:
18904         check_dsp(ctx);
18905         imm = extract32(ctx->opcode, 14, 7);
18906         switch (extract32(ctx->opcode, 12, 2)) {
18907         case NM_RDDSP:
18908             tcg_gen_movi_tl(t0, imm);
18909             gen_helper_rddsp(t0, t0, cpu_env);
18910             gen_store_gpr(t0, ret);
18911             break;
18912         case NM_WRDSP:
18913             gen_load_gpr(t0, ret);
18914             tcg_gen_movi_tl(t1, imm);
18915             gen_helper_wrdsp(t0, t1, cpu_env);
18916             break;
18917         case NM_EXTP:
18918             tcg_gen_movi_tl(t0, v2 >> 3);
18919             tcg_gen_movi_tl(t1, v1);
18920             gen_helper_extp(t0, t0, t1, cpu_env);
18921             gen_store_gpr(t0, ret);
18922             break;
18923         case NM_EXTPDP:
18924             tcg_gen_movi_tl(t0, v2 >> 3);
18925             tcg_gen_movi_tl(t1, v1);
18926             gen_helper_extpdp(t0, t0, t1, cpu_env);
18927             gen_store_gpr(t0, ret);
18928             break;
18929         }
18930         break;
18931     case NM_POOL32AXF_1_4:
18932         check_dsp(ctx);
18933         tcg_gen_movi_tl(t0, v2 >> 2);
18934         switch (extract32(ctx->opcode, 12, 1)) {
18935         case NM_SHLL_QB:
18936             gen_helper_shll_qb(t0, t0, v0_t, cpu_env);
18937             gen_store_gpr(t0, ret);
18938             break;
18939         case NM_SHRL_QB:
18940             gen_helper_shrl_qb(t0, t0, v0_t);
18941             gen_store_gpr(t0, ret);
18942             break;
18943         }
18944         break;
18945     case NM_POOL32AXF_1_5:
18946         opc = extract32(ctx->opcode, 12, 2);
18947         gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2);
18948         break;
18949     case NM_POOL32AXF_1_7:
18950         check_dsp(ctx);
18951         tcg_gen_movi_tl(t0, v2 >> 3);
18952         tcg_gen_movi_tl(t1, v1);
18953         switch (extract32(ctx->opcode, 12, 2)) {
18954         case NM_EXTR_W:
18955             gen_helper_extr_w(t0, t0, t1, cpu_env);
18956             gen_store_gpr(t0, ret);
18957             break;
18958         case NM_EXTR_R_W:
18959             gen_helper_extr_r_w(t0, t0, t1, cpu_env);
18960             gen_store_gpr(t0, ret);
18961             break;
18962         case NM_EXTR_RS_W:
18963             gen_helper_extr_rs_w(t0, t0, t1, cpu_env);
18964             gen_store_gpr(t0, ret);
18965             break;
18966         case NM_EXTR_S_H:
18967             gen_helper_extr_s_h(t0, t0, t1, cpu_env);
18968             gen_store_gpr(t0, ret);
18969             break;
18970         }
18971         break;
18972     default:
18973         generate_exception_end(ctx, EXCP_RI);
18974         break;
18975     }
18976
18977     tcg_temp_free(t0);
18978     tcg_temp_free(t1);
18979     tcg_temp_free(v0_t);
18980 }
18981
18982 static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc,
18983                                     TCGv v0, TCGv v1, int rd)
18984 {
18985     TCGv_i32 t0;
18986
18987     t0 = tcg_temp_new_i32();
18988
18989     tcg_gen_movi_i32(t0, rd >> 3);
18990
18991     switch (opc) {
18992     case NM_POOL32AXF_2_0_7:
18993         switch (extract32(ctx->opcode, 9, 3)) {
18994         case NM_DPA_W_PH:
18995             check_dsp_r2(ctx);
18996             gen_helper_dpa_w_ph(t0, v1, v0, cpu_env);
18997             break;
18998         case NM_DPAQ_S_W_PH:
18999             check_dsp(ctx);
19000             gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env);
19001             break;
19002         case NM_DPS_W_PH:
19003             check_dsp_r2(ctx);
19004             gen_helper_dps_w_ph(t0, v1, v0, cpu_env);
19005             break;
19006         case NM_DPSQ_S_W_PH:
19007             check_dsp(ctx);
19008             gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env);
19009             break;
19010         default:
19011             generate_exception_end(ctx, EXCP_RI);
19012             break;
19013         }
19014         break;
19015     case NM_POOL32AXF_2_8_15:
19016         switch (extract32(ctx->opcode, 9, 3)) {
19017         case NM_DPAX_W_PH:
19018             check_dsp_r2(ctx);
19019             gen_helper_dpax_w_ph(t0, v0, v1, cpu_env);
19020             break;
19021         case NM_DPAQ_SA_L_W:
19022             check_dsp(ctx);
19023             gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env);
19024             break;
19025         case NM_DPSX_W_PH:
19026             check_dsp_r2(ctx);
19027             gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env);
19028             break;
19029         case NM_DPSQ_SA_L_W:
19030             check_dsp(ctx);
19031             gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env);
19032             break;
19033         default:
19034             generate_exception_end(ctx, EXCP_RI);
19035             break;
19036         }
19037         break;
19038     case NM_POOL32AXF_2_16_23:
19039         switch (extract32(ctx->opcode, 9, 3)) {
19040         case NM_DPAU_H_QBL:
19041             check_dsp(ctx);
19042             gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env);
19043             break;
19044         case NM_DPAQX_S_W_PH:
19045             check_dsp_r2(ctx);
19046             gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env);
19047             break;
19048         case NM_DPSU_H_QBL:
19049             check_dsp(ctx);
19050             gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env);
19051             break;
19052         case NM_DPSQX_S_W_PH:
19053             check_dsp_r2(ctx);
19054             gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env);
19055             break;
19056         case NM_MULSA_W_PH:
19057             check_dsp_r2(ctx);
19058             gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env);
19059             break;
19060         default:
19061             generate_exception_end(ctx, EXCP_RI);
19062             break;
19063         }
19064         break;
19065     case NM_POOL32AXF_2_24_31:
19066         switch (extract32(ctx->opcode, 9, 3)) {
19067         case NM_DPAU_H_QBR:
19068             check_dsp(ctx);
19069             gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env);
19070             break;
19071         case NM_DPAQX_SA_W_PH:
19072             check_dsp_r2(ctx);
19073             gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env);
19074             break;
19075         case NM_DPSU_H_QBR:
19076             check_dsp(ctx);
19077             gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env);
19078             break;
19079         case NM_DPSQX_SA_W_PH:
19080             check_dsp_r2(ctx);
19081             gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env);
19082             break;
19083         case NM_MULSAQ_S_W_PH:
19084             check_dsp(ctx);
19085             gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env);
19086             break;
19087         default:
19088             generate_exception_end(ctx, EXCP_RI);
19089             break;
19090         }
19091         break;
19092     default:
19093         generate_exception_end(ctx, EXCP_RI);
19094         break;
19095     }
19096
19097     tcg_temp_free_i32(t0);
19098 }
19099
19100 static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc,
19101                                           int rt, int rs, int rd)
19102 {
19103     int ret = rt;
19104     TCGv t0 = tcg_temp_new();
19105     TCGv t1 = tcg_temp_new();
19106     TCGv v0_t = tcg_temp_new();
19107     TCGv v1_t = tcg_temp_new();
19108
19109     gen_load_gpr(v0_t, rt);
19110     gen_load_gpr(v1_t, rs);
19111
19112     switch (opc) {
19113     case NM_POOL32AXF_2_0_7:
19114         switch (extract32(ctx->opcode, 9, 3)) {
19115         case NM_DPA_W_PH:
19116         case NM_DPAQ_S_W_PH:
19117         case NM_DPS_W_PH:
19118         case NM_DPSQ_S_W_PH:
19119             gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19120             break;
19121         case NM_BALIGN:
19122             check_dsp_r2(ctx);
19123             if (rt != 0) {
19124                 gen_load_gpr(t0, rs);
19125                 rd &= 3;
19126                 if (rd != 0 && rd != 2) {
19127                     tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd);
19128                     tcg_gen_ext32u_tl(t0, t0);
19129                     tcg_gen_shri_tl(t0, t0, 8 * (4 - rd));
19130                     tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
19131                 }
19132                 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
19133             }
19134             break;
19135         case NM_MADD:
19136             check_dsp(ctx);
19137             {
19138                 int acc = extract32(ctx->opcode, 14, 2);
19139                 TCGv_i64 t2 = tcg_temp_new_i64();
19140                 TCGv_i64 t3 = tcg_temp_new_i64();
19141
19142                 gen_load_gpr(t0, rt);
19143                 gen_load_gpr(t1, rs);
19144                 tcg_gen_ext_tl_i64(t2, t0);
19145                 tcg_gen_ext_tl_i64(t3, t1);
19146                 tcg_gen_mul_i64(t2, t2, t3);
19147                 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19148                 tcg_gen_add_i64(t2, t2, t3);
19149                 tcg_temp_free_i64(t3);
19150                 gen_move_low32(cpu_LO[acc], t2);
19151                 gen_move_high32(cpu_HI[acc], t2);
19152                 tcg_temp_free_i64(t2);
19153             }
19154             break;
19155         case NM_MULT:
19156             check_dsp(ctx);
19157             {
19158                 int acc = extract32(ctx->opcode, 14, 2);
19159                 TCGv_i32 t2 = tcg_temp_new_i32();
19160                 TCGv_i32 t3 = tcg_temp_new_i32();
19161
19162                 gen_load_gpr(t0, rs);
19163                 gen_load_gpr(t1, rt);
19164                 tcg_gen_trunc_tl_i32(t2, t0);
19165                 tcg_gen_trunc_tl_i32(t3, t1);
19166                 tcg_gen_muls2_i32(t2, t3, t2, t3);
19167                 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
19168                 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
19169                 tcg_temp_free_i32(t2);
19170                 tcg_temp_free_i32(t3);
19171             }
19172             break;
19173         case NM_EXTRV_W:
19174             check_dsp(ctx);
19175             gen_load_gpr(v1_t, rs);
19176             tcg_gen_movi_tl(t0, rd >> 3);
19177             gen_helper_extr_w(t0, t0, v1_t, cpu_env);
19178             gen_store_gpr(t0, ret);
19179             break;
19180         }
19181         break;
19182     case NM_POOL32AXF_2_8_15:
19183         switch (extract32(ctx->opcode, 9, 3)) {
19184         case NM_DPAX_W_PH:
19185         case NM_DPAQ_SA_L_W:
19186         case NM_DPSX_W_PH:
19187         case NM_DPSQ_SA_L_W:
19188             gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19189             break;
19190         case NM_MADDU:
19191             check_dsp(ctx);
19192             {
19193                 int acc = extract32(ctx->opcode, 14, 2);
19194                 TCGv_i64 t2 = tcg_temp_new_i64();
19195                 TCGv_i64 t3 = tcg_temp_new_i64();
19196
19197                 gen_load_gpr(t0, rs);
19198                 gen_load_gpr(t1, rt);
19199                 tcg_gen_ext32u_tl(t0, t0);
19200                 tcg_gen_ext32u_tl(t1, t1);
19201                 tcg_gen_extu_tl_i64(t2, t0);
19202                 tcg_gen_extu_tl_i64(t3, t1);
19203                 tcg_gen_mul_i64(t2, t2, t3);
19204                 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19205                 tcg_gen_add_i64(t2, t2, t3);
19206                 tcg_temp_free_i64(t3);
19207                 gen_move_low32(cpu_LO[acc], t2);
19208                 gen_move_high32(cpu_HI[acc], t2);
19209                 tcg_temp_free_i64(t2);
19210             }
19211             break;
19212         case NM_MULTU:
19213             check_dsp(ctx);
19214             {
19215                 int acc = extract32(ctx->opcode, 14, 2);
19216                 TCGv_i32 t2 = tcg_temp_new_i32();
19217                 TCGv_i32 t3 = tcg_temp_new_i32();
19218
19219                 gen_load_gpr(t0, rs);
19220                 gen_load_gpr(t1, rt);
19221                 tcg_gen_trunc_tl_i32(t2, t0);
19222                 tcg_gen_trunc_tl_i32(t3, t1);
19223                 tcg_gen_mulu2_i32(t2, t3, t2, t3);
19224                 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
19225                 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
19226                 tcg_temp_free_i32(t2);
19227                 tcg_temp_free_i32(t3);
19228             }
19229             break;
19230         case NM_EXTRV_R_W:
19231             check_dsp(ctx);
19232             tcg_gen_movi_tl(t0, rd >> 3);
19233             gen_helper_extr_r_w(t0, t0, v1_t, cpu_env);
19234             gen_store_gpr(t0, ret);
19235             break;
19236         default:
19237             generate_exception_end(ctx, EXCP_RI);
19238             break;
19239         }
19240         break;
19241     case NM_POOL32AXF_2_16_23:
19242         switch (extract32(ctx->opcode, 9, 3)) {
19243         case NM_DPAU_H_QBL:
19244         case NM_DPAQX_S_W_PH:
19245         case NM_DPSU_H_QBL:
19246         case NM_DPSQX_S_W_PH:
19247         case NM_MULSA_W_PH:
19248             gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19249             break;
19250         case NM_EXTPV:
19251             check_dsp(ctx);
19252             tcg_gen_movi_tl(t0, rd >> 3);
19253             gen_helper_extp(t0, t0, v1_t, cpu_env);
19254             gen_store_gpr(t0, ret);
19255             break;
19256         case NM_MSUB:
19257             check_dsp(ctx);
19258             {
19259                 int acc = extract32(ctx->opcode, 14, 2);
19260                 TCGv_i64 t2 = tcg_temp_new_i64();
19261                 TCGv_i64 t3 = tcg_temp_new_i64();
19262
19263                 gen_load_gpr(t0, rs);
19264                 gen_load_gpr(t1, rt);
19265                 tcg_gen_ext_tl_i64(t2, t0);
19266                 tcg_gen_ext_tl_i64(t3, t1);
19267                 tcg_gen_mul_i64(t2, t2, t3);
19268                 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19269                 tcg_gen_sub_i64(t2, t3, t2);
19270                 tcg_temp_free_i64(t3);
19271                 gen_move_low32(cpu_LO[acc], t2);
19272                 gen_move_high32(cpu_HI[acc], t2);
19273                 tcg_temp_free_i64(t2);
19274             }
19275             break;
19276         case NM_EXTRV_RS_W:
19277             check_dsp(ctx);
19278             tcg_gen_movi_tl(t0, rd >> 3);
19279             gen_helper_extr_rs_w(t0, t0, v1_t, cpu_env);
19280             gen_store_gpr(t0, ret);
19281             break;
19282         }
19283         break;
19284     case NM_POOL32AXF_2_24_31:
19285         switch (extract32(ctx->opcode, 9, 3)) {
19286         case NM_DPAU_H_QBR:
19287         case NM_DPAQX_SA_W_PH:
19288         case NM_DPSU_H_QBR:
19289         case NM_DPSQX_SA_W_PH:
19290         case NM_MULSAQ_S_W_PH:
19291             gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19292             break;
19293         case NM_EXTPDPV:
19294             check_dsp(ctx);
19295             tcg_gen_movi_tl(t0, rd >> 3);
19296             gen_helper_extpdp(t0, t0, v1_t, cpu_env);
19297             gen_store_gpr(t0, ret);
19298             break;
19299         case NM_MSUBU:
19300             check_dsp(ctx);
19301             {
19302                 int acc = extract32(ctx->opcode, 14, 2);
19303                 TCGv_i64 t2 = tcg_temp_new_i64();
19304                 TCGv_i64 t3 = tcg_temp_new_i64();
19305
19306                 gen_load_gpr(t0, rs);
19307                 gen_load_gpr(t1, rt);
19308                 tcg_gen_ext32u_tl(t0, t0);
19309                 tcg_gen_ext32u_tl(t1, t1);
19310                 tcg_gen_extu_tl_i64(t2, t0);
19311                 tcg_gen_extu_tl_i64(t3, t1);
19312                 tcg_gen_mul_i64(t2, t2, t3);
19313                 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19314                 tcg_gen_sub_i64(t2, t3, t2);
19315                 tcg_temp_free_i64(t3);
19316                 gen_move_low32(cpu_LO[acc], t2);
19317                 gen_move_high32(cpu_HI[acc], t2);
19318                 tcg_temp_free_i64(t2);
19319             }
19320             break;
19321         case NM_EXTRV_S_H:
19322             check_dsp(ctx);
19323             tcg_gen_movi_tl(t0, rd >> 3);
19324             gen_helper_extr_s_h(t0, t0, v0_t, cpu_env);
19325             gen_store_gpr(t0, ret);
19326             break;
19327         }
19328         break;
19329     default:
19330         generate_exception_end(ctx, EXCP_RI);
19331         break;
19332     }
19333
19334     tcg_temp_free(t0);
19335     tcg_temp_free(t1);
19336
19337     tcg_temp_free(v0_t);
19338     tcg_temp_free(v1_t);
19339 }
19340
19341 static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc,
19342                                           int rt, int rs)
19343 {
19344     int ret = rt;
19345     TCGv t0 = tcg_temp_new();
19346     TCGv v0_t = tcg_temp_new();
19347
19348     gen_load_gpr(v0_t, rs);
19349
19350     switch (opc) {
19351     case NM_ABSQ_S_QB:
19352         check_dsp_r2(ctx);
19353         gen_helper_absq_s_qb(v0_t, v0_t, cpu_env);
19354         gen_store_gpr(v0_t, ret);
19355         break;
19356     case NM_ABSQ_S_PH:
19357         check_dsp(ctx);
19358         gen_helper_absq_s_ph(v0_t, v0_t, cpu_env);
19359         gen_store_gpr(v0_t, ret);
19360         break;
19361     case NM_ABSQ_S_W:
19362         check_dsp(ctx);
19363         gen_helper_absq_s_w(v0_t, v0_t, cpu_env);
19364         gen_store_gpr(v0_t, ret);
19365         break;
19366     case NM_PRECEQ_W_PHL:
19367         check_dsp(ctx);
19368         tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000);
19369         tcg_gen_ext32s_tl(v0_t, v0_t);
19370         gen_store_gpr(v0_t, ret);
19371         break;
19372     case NM_PRECEQ_W_PHR:
19373         check_dsp(ctx);
19374         tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF);
19375         tcg_gen_shli_tl(v0_t, v0_t, 16);
19376         tcg_gen_ext32s_tl(v0_t, v0_t);
19377         gen_store_gpr(v0_t, ret);
19378         break;
19379     case NM_PRECEQU_PH_QBL:
19380         check_dsp(ctx);
19381         gen_helper_precequ_ph_qbl(v0_t, v0_t);
19382         gen_store_gpr(v0_t, ret);
19383         break;
19384     case NM_PRECEQU_PH_QBR:
19385         check_dsp(ctx);
19386         gen_helper_precequ_ph_qbr(v0_t, v0_t);
19387         gen_store_gpr(v0_t, ret);
19388         break;
19389     case NM_PRECEQU_PH_QBLA:
19390         check_dsp(ctx);
19391         gen_helper_precequ_ph_qbla(v0_t, v0_t);
19392         gen_store_gpr(v0_t, ret);
19393         break;
19394     case NM_PRECEQU_PH_QBRA:
19395         check_dsp(ctx);
19396         gen_helper_precequ_ph_qbra(v0_t, v0_t);
19397         gen_store_gpr(v0_t, ret);
19398         break;
19399     case NM_PRECEU_PH_QBL:
19400         check_dsp(ctx);
19401         gen_helper_preceu_ph_qbl(v0_t, v0_t);
19402         gen_store_gpr(v0_t, ret);
19403         break;
19404     case NM_PRECEU_PH_QBR:
19405         check_dsp(ctx);
19406         gen_helper_preceu_ph_qbr(v0_t, v0_t);
19407         gen_store_gpr(v0_t, ret);
19408         break;
19409     case NM_PRECEU_PH_QBLA:
19410         check_dsp(ctx);
19411         gen_helper_preceu_ph_qbla(v0_t, v0_t);
19412         gen_store_gpr(v0_t, ret);
19413         break;
19414     case NM_PRECEU_PH_QBRA:
19415         check_dsp(ctx);
19416         gen_helper_preceu_ph_qbra(v0_t, v0_t);
19417         gen_store_gpr(v0_t, ret);
19418         break;
19419     case NM_REPLV_PH:
19420         check_dsp(ctx);
19421         tcg_gen_ext16u_tl(v0_t, v0_t);
19422         tcg_gen_shli_tl(t0, v0_t, 16);
19423         tcg_gen_or_tl(v0_t, v0_t, t0);
19424         tcg_gen_ext32s_tl(v0_t, v0_t);
19425         gen_store_gpr(v0_t, ret);
19426         break;
19427     case NM_REPLV_QB:
19428         check_dsp(ctx);
19429         tcg_gen_ext8u_tl(v0_t, v0_t);
19430         tcg_gen_shli_tl(t0, v0_t, 8);
19431         tcg_gen_or_tl(v0_t, v0_t, t0);
19432         tcg_gen_shli_tl(t0, v0_t, 16);
19433         tcg_gen_or_tl(v0_t, v0_t, t0);
19434         tcg_gen_ext32s_tl(v0_t, v0_t);
19435         gen_store_gpr(v0_t, ret);
19436         break;
19437     case NM_BITREV:
19438         check_dsp(ctx);
19439         gen_helper_bitrev(v0_t, v0_t);
19440         gen_store_gpr(v0_t, ret);
19441         break;
19442     case NM_INSV:
19443         check_dsp(ctx);
19444         {
19445             TCGv tv0 = tcg_temp_new();
19446
19447             gen_load_gpr(tv0, rt);
19448             gen_helper_insv(v0_t, cpu_env, v0_t, tv0);
19449             gen_store_gpr(v0_t, ret);
19450             tcg_temp_free(tv0);
19451         }
19452         break;
19453     case NM_RADDU_W_QB:
19454         check_dsp(ctx);
19455         gen_helper_raddu_w_qb(v0_t, v0_t);
19456         gen_store_gpr(v0_t, ret);
19457         break;
19458     case NM_BITSWAP:
19459         gen_bitswap(ctx, OPC_BITSWAP, ret, rs);
19460         break;
19461     case NM_CLO:
19462         check_nms(ctx);
19463         gen_cl(ctx, OPC_CLO, ret, rs);
19464         break;
19465     case NM_CLZ:
19466         check_nms(ctx);
19467         gen_cl(ctx, OPC_CLZ, ret, rs);
19468         break;
19469     case NM_WSBH:
19470         gen_bshfl(ctx, OPC_WSBH, ret, rs);
19471         break;
19472     default:
19473         generate_exception_end(ctx, EXCP_RI);
19474         break;
19475     }
19476
19477     tcg_temp_free(v0_t);
19478     tcg_temp_free(t0);
19479 }
19480
19481 static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc,
19482                                           int rt, int rs, int rd)
19483 {
19484     TCGv t0 = tcg_temp_new();
19485     TCGv rs_t = tcg_temp_new();
19486
19487     gen_load_gpr(rs_t, rs);
19488
19489     switch (opc) {
19490     case NM_SHRA_R_QB:
19491         check_dsp_r2(ctx);
19492         tcg_gen_movi_tl(t0, rd >> 2);
19493         switch (extract32(ctx->opcode, 12, 1)) {
19494         case 0:
19495             /* NM_SHRA_QB */
19496             gen_helper_shra_qb(t0, t0, rs_t);
19497             gen_store_gpr(t0, rt);
19498             break;
19499         case 1:
19500             /* NM_SHRA_R_QB */
19501             gen_helper_shra_r_qb(t0, t0, rs_t);
19502             gen_store_gpr(t0, rt);
19503             break;
19504         }
19505         break;
19506     case NM_SHRL_PH:
19507         check_dsp_r2(ctx);
19508         tcg_gen_movi_tl(t0, rd >> 1);
19509         gen_helper_shrl_ph(t0, t0, rs_t);
19510         gen_store_gpr(t0, rt);
19511         break;
19512     case NM_REPL_QB:
19513         check_dsp(ctx);
19514         {
19515             int16_t imm;
19516             target_long result;
19517             imm = extract32(ctx->opcode, 13, 8);
19518             result = (uint32_t)imm << 24 |
19519                      (uint32_t)imm << 16 |
19520                      (uint32_t)imm << 8  |
19521                      (uint32_t)imm;
19522             result = (int32_t)result;
19523             tcg_gen_movi_tl(t0, result);
19524             gen_store_gpr(t0, rt);
19525         }
19526         break;
19527     default:
19528         generate_exception_end(ctx, EXCP_RI);
19529         break;
19530     }
19531     tcg_temp_free(t0);
19532     tcg_temp_free(rs_t);
19533 }
19534
19535
19536 static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
19537 {
19538     int rt = extract32(ctx->opcode, 21, 5);
19539     int rs = extract32(ctx->opcode, 16, 5);
19540     int rd = extract32(ctx->opcode, 11, 5);
19541
19542     switch (extract32(ctx->opcode, 6, 3)) {
19543     case NM_POOL32AXF_1:
19544         {
19545             int32_t op1 = extract32(ctx->opcode, 9, 3);
19546             gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd);
19547         }
19548         break;
19549     case NM_POOL32AXF_2:
19550         {
19551             int32_t op1 = extract32(ctx->opcode, 12, 2);
19552             gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd);
19553         }
19554         break;
19555     case NM_POOL32AXF_4:
19556         {
19557             int32_t op1 = extract32(ctx->opcode, 9, 7);
19558             gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs);
19559         }
19560         break;
19561     case NM_POOL32AXF_5:
19562         switch (extract32(ctx->opcode, 9, 7)) {
19563 #ifndef CONFIG_USER_ONLY
19564         case NM_TLBP:
19565             gen_cp0(env, ctx, OPC_TLBP, 0, 0);
19566             break;
19567         case NM_TLBR:
19568             gen_cp0(env, ctx, OPC_TLBR, 0, 0);
19569             break;
19570         case NM_TLBWI:
19571             gen_cp0(env, ctx, OPC_TLBWI, 0, 0);
19572             break;
19573         case NM_TLBWR:
19574             gen_cp0(env, ctx, OPC_TLBWR, 0, 0);
19575             break;
19576         case NM_TLBINV:
19577             gen_cp0(env, ctx, OPC_TLBINV, 0, 0);
19578             break;
19579         case NM_TLBINVF:
19580             gen_cp0(env, ctx, OPC_TLBINVF, 0, 0);
19581             break;
19582         case NM_DI:
19583             check_cp0_enabled(ctx);
19584             {
19585                 TCGv t0 = tcg_temp_new();
19586
19587                 save_cpu_state(ctx, 1);
19588                 gen_helper_di(t0, cpu_env);
19589                 gen_store_gpr(t0, rt);
19590             /* Stop translation as we may have switched the execution mode */
19591                 ctx->base.is_jmp = DISAS_STOP;
19592                 tcg_temp_free(t0);
19593             }
19594             break;
19595         case NM_EI:
19596             check_cp0_enabled(ctx);
19597             {
19598                 TCGv t0 = tcg_temp_new();
19599
19600                 save_cpu_state(ctx, 1);
19601                 gen_helper_ei(t0, cpu_env);
19602                 gen_store_gpr(t0, rt);
19603             /* Stop translation as we may have switched the execution mode */
19604                 ctx->base.is_jmp = DISAS_STOP;
19605                 tcg_temp_free(t0);
19606             }
19607             break;
19608         case NM_RDPGPR:
19609             gen_load_srsgpr(rs, rt);
19610             break;
19611         case NM_WRPGPR:
19612             gen_store_srsgpr(rs, rt);
19613             break;
19614         case NM_WAIT:
19615             gen_cp0(env, ctx, OPC_WAIT, 0, 0);
19616             break;
19617         case NM_DERET:
19618             gen_cp0(env, ctx, OPC_DERET, 0, 0);
19619             break;
19620         case NM_ERETX:
19621             gen_cp0(env, ctx, OPC_ERET, 0, 0);
19622             break;
19623 #endif
19624         default:
19625             generate_exception_end(ctx, EXCP_RI);
19626             break;
19627         }
19628         break;
19629     case NM_POOL32AXF_7:
19630         {
19631             int32_t op1 = extract32(ctx->opcode, 9, 3);
19632             gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd);
19633         }
19634         break;
19635     default:
19636         generate_exception_end(ctx, EXCP_RI);
19637         break;
19638     }
19639 }
19640
19641 /* Immediate Value Compact Branches */
19642 static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc,
19643                                    int rt, int32_t imm, int32_t offset)
19644 {
19645     TCGCond cond;
19646     int bcond_compute = 0;
19647     TCGv t0 = tcg_temp_new();
19648     TCGv t1 = tcg_temp_new();
19649
19650     gen_load_gpr(t0, rt);
19651     tcg_gen_movi_tl(t1, imm);
19652     ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19653
19654     /* Load needed operands and calculate btarget */
19655     switch (opc) {
19656     case NM_BEQIC:
19657         if (rt == 0 && imm == 0) {
19658             /* Unconditional branch */
19659         } else if (rt == 0 && imm != 0) {
19660             /* Treat as NOP */
19661             goto out;
19662         } else {
19663             bcond_compute = 1;
19664             cond = TCG_COND_EQ;
19665         }
19666         break;
19667     case NM_BBEQZC:
19668     case NM_BBNEZC:
19669         check_nms(ctx);
19670         if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) {
19671             generate_exception_end(ctx, EXCP_RI);
19672             goto out;
19673         } else if (rt == 0 && opc == NM_BBEQZC) {
19674             /* Unconditional branch */
19675         } else if (rt == 0 && opc == NM_BBNEZC) {
19676             /* Treat as NOP */
19677             goto out;
19678         } else {
19679             tcg_gen_shri_tl(t0, t0, imm);
19680             tcg_gen_andi_tl(t0, t0, 1);
19681             tcg_gen_movi_tl(t1, 0);
19682             bcond_compute = 1;
19683             if (opc == NM_BBEQZC) {
19684                 cond = TCG_COND_EQ;
19685             } else {
19686                 cond = TCG_COND_NE;
19687             }
19688         }
19689         break;
19690     case NM_BNEIC:
19691         if (rt == 0 && imm == 0) {
19692             /* Treat as NOP */
19693             goto out;
19694         } else if (rt == 0 && imm != 0) {
19695             /* Unconditional branch */
19696         } else {
19697             bcond_compute = 1;
19698             cond = TCG_COND_NE;
19699         }
19700         break;
19701     case NM_BGEIC:
19702         if (rt == 0 && imm == 0) {
19703             /* Unconditional branch */
19704         } else  {
19705             bcond_compute = 1;
19706             cond = TCG_COND_GE;
19707         }
19708         break;
19709     case NM_BLTIC:
19710         bcond_compute = 1;
19711         cond = TCG_COND_LT;
19712         break;
19713     case NM_BGEIUC:
19714         if (rt == 0 && imm == 0) {
19715             /* Unconditional branch */
19716         } else  {
19717             bcond_compute = 1;
19718             cond = TCG_COND_GEU;
19719         }
19720         break;
19721     case NM_BLTIUC:
19722         bcond_compute = 1;
19723         cond = TCG_COND_LTU;
19724         break;
19725     default:
19726         MIPS_INVAL("Immediate Value Compact branch");
19727         generate_exception_end(ctx, EXCP_RI);
19728         goto out;
19729     }
19730
19731     /* branch completion */
19732     clear_branch_hflags(ctx);
19733     ctx->base.is_jmp = DISAS_NORETURN;
19734
19735     if (bcond_compute == 0) {
19736         /* Uncoditional compact branch */
19737         gen_goto_tb(ctx, 0, ctx->btarget);
19738     } else {
19739         /* Conditional compact branch */
19740         TCGLabel *fs = gen_new_label();
19741
19742         tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs);
19743
19744         gen_goto_tb(ctx, 1, ctx->btarget);
19745         gen_set_label(fs);
19746
19747         gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19748     }
19749
19750 out:
19751     tcg_temp_free(t0);
19752     tcg_temp_free(t1);
19753 }
19754
19755 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
19756 static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs,
19757                                                 int rt)
19758 {
19759     TCGv t0 = tcg_temp_new();
19760     TCGv t1 = tcg_temp_new();
19761
19762     /* load rs */
19763     gen_load_gpr(t0, rs);
19764
19765     /* link */
19766     if (rt != 0) {
19767         tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4);
19768     }
19769
19770     /* calculate btarget */
19771     tcg_gen_shli_tl(t0, t0, 1);
19772     tcg_gen_movi_tl(t1, ctx->base.pc_next + 4);
19773     gen_op_addr_add(ctx, btarget, t1, t0);
19774
19775     /* branch completion */
19776     clear_branch_hflags(ctx);
19777     ctx->base.is_jmp = DISAS_NORETURN;
19778
19779     /* unconditional branch to register */
19780     tcg_gen_mov_tl(cpu_PC, btarget);
19781     tcg_gen_lookup_and_goto_ptr();
19782
19783     tcg_temp_free(t0);
19784     tcg_temp_free(t1);
19785 }
19786
19787 /* nanoMIPS Branches */
19788 static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc,
19789                                        int rs, int rt, int32_t offset)
19790 {
19791     int bcond_compute = 0;
19792     TCGv t0 = tcg_temp_new();
19793     TCGv t1 = tcg_temp_new();
19794
19795     /* Load needed operands and calculate btarget */
19796     switch (opc) {
19797     /* compact branch */
19798     case OPC_BGEC:
19799     case OPC_BLTC:
19800         gen_load_gpr(t0, rs);
19801         gen_load_gpr(t1, rt);
19802         bcond_compute = 1;
19803         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19804         break;
19805     case OPC_BGEUC:
19806     case OPC_BLTUC:
19807         if (rs == 0 || rs == rt) {
19808             /* OPC_BLEZALC, OPC_BGEZALC */
19809             /* OPC_BGTZALC, OPC_BLTZALC */
19810             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4);
19811         }
19812         gen_load_gpr(t0, rs);
19813         gen_load_gpr(t1, rt);
19814         bcond_compute = 1;
19815         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19816         break;
19817     case OPC_BC:
19818         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19819         break;
19820     case OPC_BEQZC:
19821         if (rs != 0) {
19822             /* OPC_BEQZC, OPC_BNEZC */
19823             gen_load_gpr(t0, rs);
19824             bcond_compute = 1;
19825             ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19826         } else {
19827             /* OPC_JIC, OPC_JIALC */
19828             TCGv tbase = tcg_temp_new();
19829             TCGv toffset = tcg_temp_new();
19830
19831             gen_load_gpr(tbase, rt);
19832             tcg_gen_movi_tl(toffset, offset);
19833             gen_op_addr_add(ctx, btarget, tbase, toffset);
19834             tcg_temp_free(tbase);
19835             tcg_temp_free(toffset);
19836         }
19837         break;
19838     default:
19839         MIPS_INVAL("Compact branch/jump");
19840         generate_exception_end(ctx, EXCP_RI);
19841         goto out;
19842     }
19843
19844     if (bcond_compute == 0) {
19845         /* Uncoditional compact branch */
19846         switch (opc) {
19847         case OPC_BC:
19848             gen_goto_tb(ctx, 0, ctx->btarget);
19849             break;
19850         default:
19851             MIPS_INVAL("Compact branch/jump");
19852             generate_exception_end(ctx, EXCP_RI);
19853             goto out;
19854         }
19855     } else {
19856         /* Conditional compact branch */
19857         TCGLabel *fs = gen_new_label();
19858
19859         switch (opc) {
19860         case OPC_BGEUC:
19861             if (rs == 0 && rt != 0) {
19862                 /* OPC_BLEZALC */
19863                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19864             } else if (rs != 0 && rt != 0 && rs == rt) {
19865                 /* OPC_BGEZALC */
19866                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19867             } else {
19868                 /* OPC_BGEUC */
19869                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
19870             }
19871             break;
19872         case OPC_BLTUC:
19873             if (rs == 0 && rt != 0) {
19874                 /* OPC_BGTZALC */
19875                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19876             } else if (rs != 0 && rt != 0 && rs == rt) {
19877                 /* OPC_BLTZALC */
19878                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19879             } else {
19880                 /* OPC_BLTUC */
19881                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
19882             }
19883             break;
19884         case OPC_BGEC:
19885             if (rs == 0 && rt != 0) {
19886                 /* OPC_BLEZC */
19887                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19888             } else if (rs != 0 && rt != 0 && rs == rt) {
19889                 /* OPC_BGEZC */
19890                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19891             } else {
19892                 /* OPC_BGEC */
19893                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
19894             }
19895             break;
19896         case OPC_BLTC:
19897             if (rs == 0 && rt != 0) {
19898                 /* OPC_BGTZC */
19899                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19900             } else if (rs != 0 && rt != 0 && rs == rt) {
19901                 /* OPC_BLTZC */
19902                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19903             } else {
19904                 /* OPC_BLTC */
19905                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
19906             }
19907             break;
19908         case OPC_BEQZC:
19909             tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
19910             break;
19911         default:
19912             MIPS_INVAL("Compact conditional branch/jump");
19913             generate_exception_end(ctx, EXCP_RI);
19914             goto out;
19915         }
19916
19917         /* branch completion */
19918         clear_branch_hflags(ctx);
19919         ctx->base.is_jmp = DISAS_NORETURN;
19920
19921         /* Generating branch here as compact branches don't have delay slot */
19922         gen_goto_tb(ctx, 1, ctx->btarget);
19923         gen_set_label(fs);
19924
19925         gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19926     }
19927
19928 out:
19929     tcg_temp_free(t0);
19930     tcg_temp_free(t1);
19931 }
19932
19933
19934 /* nanoMIPS CP1 Branches */
19935 static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op,
19936                                    int32_t ft, int32_t offset)
19937 {
19938     target_ulong btarget;
19939     TCGv_i64 t0 = tcg_temp_new_i64();
19940
19941     gen_load_fpr64(ctx, t0, ft);
19942     tcg_gen_andi_i64(t0, t0, 1);
19943
19944     btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19945
19946     switch (op) {
19947     case NM_BC1EQZC:
19948         tcg_gen_xori_i64(t0, t0, 1);
19949         ctx->hflags |= MIPS_HFLAG_BC;
19950         break;
19951     case NM_BC1NEZC:
19952         /* t0 already set */
19953         ctx->hflags |= MIPS_HFLAG_BC;
19954         break;
19955     default:
19956         MIPS_INVAL("cp1 cond branch");
19957         generate_exception_end(ctx, EXCP_RI);
19958         goto out;
19959     }
19960
19961     tcg_gen_trunc_i64_tl(bcond, t0);
19962
19963     ctx->btarget = btarget;
19964
19965 out:
19966     tcg_temp_free_i64(t0);
19967 }
19968
19969
19970 static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt)
19971 {
19972     TCGv t0, t1;
19973     t0 = tcg_temp_new();
19974     t1 = tcg_temp_new();
19975
19976     gen_load_gpr(t0, rs);
19977     gen_load_gpr(t1, rt);
19978
19979     if ((extract32(ctx->opcode, 6, 1)) == 1) {
19980         /* PP.LSXS instructions require shifting */
19981         switch (extract32(ctx->opcode, 7, 4)) {
19982         case NM_SHXS:
19983             check_nms(ctx);
19984         case NM_LHXS:
19985         case NM_LHUXS:
19986             tcg_gen_shli_tl(t0, t0, 1);
19987             break;
19988         case NM_SWXS:
19989             check_nms(ctx);
19990         case NM_LWXS:
19991         case NM_LWC1XS:
19992         case NM_SWC1XS:
19993             tcg_gen_shli_tl(t0, t0, 2);
19994             break;
19995         case NM_LDC1XS:
19996         case NM_SDC1XS:
19997             tcg_gen_shli_tl(t0, t0, 3);
19998             break;
19999         }
20000     }
20001     gen_op_addr_add(ctx, t0, t0, t1);
20002
20003     switch (extract32(ctx->opcode, 7, 4)) {
20004     case NM_LBX:
20005         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20006                            MO_SB);
20007         gen_store_gpr(t0, rd);
20008         break;
20009     case NM_LHX:
20010     /*case NM_LHXS:*/
20011         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20012                            MO_TESW);
20013         gen_store_gpr(t0, rd);
20014         break;
20015     case NM_LWX:
20016     /*case NM_LWXS:*/
20017         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20018                            MO_TESL);
20019         gen_store_gpr(t0, rd);
20020         break;
20021     case NM_LBUX:
20022         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20023                            MO_UB);
20024         gen_store_gpr(t0, rd);
20025         break;
20026     case NM_LHUX:
20027     /*case NM_LHUXS:*/
20028         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20029                            MO_TEUW);
20030         gen_store_gpr(t0, rd);
20031         break;
20032     case NM_SBX:
20033         check_nms(ctx);
20034         gen_load_gpr(t1, rd);
20035         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20036                            MO_8);
20037         break;
20038     case NM_SHX:
20039     /*case NM_SHXS:*/
20040         check_nms(ctx);
20041         gen_load_gpr(t1, rd);
20042         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20043                            MO_TEUW);
20044         break;
20045     case NM_SWX:
20046     /*case NM_SWXS:*/
20047         check_nms(ctx);
20048         gen_load_gpr(t1, rd);
20049         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20050                            MO_TEUL);
20051         break;
20052     case NM_LWC1X:
20053     /*case NM_LWC1XS:*/
20054     case NM_LDC1X:
20055     /*case NM_LDC1XS:*/
20056     case NM_SWC1X:
20057     /*case NM_SWC1XS:*/
20058     case NM_SDC1X:
20059     /*case NM_SDC1XS:*/
20060         if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
20061             check_cp1_enabled(ctx);
20062             switch (extract32(ctx->opcode, 7, 4)) {
20063             case NM_LWC1X:
20064             /*case NM_LWC1XS:*/
20065                 gen_flt_ldst(ctx, OPC_LWC1, rd, t0);
20066                 break;
20067             case NM_LDC1X:
20068             /*case NM_LDC1XS:*/
20069                 gen_flt_ldst(ctx, OPC_LDC1, rd, t0);
20070                 break;
20071             case NM_SWC1X:
20072             /*case NM_SWC1XS:*/
20073                 gen_flt_ldst(ctx, OPC_SWC1, rd, t0);
20074                 break;
20075             case NM_SDC1X:
20076             /*case NM_SDC1XS:*/
20077                 gen_flt_ldst(ctx, OPC_SDC1, rd, t0);
20078                 break;
20079             }
20080         } else {
20081             generate_exception_err(ctx, EXCP_CpU, 1);
20082         }
20083         break;
20084     default:
20085         generate_exception_end(ctx, EXCP_RI);
20086         break;
20087     }
20088
20089     tcg_temp_free(t0);
20090     tcg_temp_free(t1);
20091 }
20092
20093 static void gen_pool32f_nanomips_insn(DisasContext *ctx)
20094 {
20095     int rt, rs, rd;
20096
20097     rt = extract32(ctx->opcode, 21, 5);
20098     rs = extract32(ctx->opcode, 16, 5);
20099     rd = extract32(ctx->opcode, 11, 5);
20100
20101     if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) {
20102         generate_exception_end(ctx, EXCP_RI);
20103         return;
20104     }
20105     check_cp1_enabled(ctx);
20106     switch (extract32(ctx->opcode, 0, 3)) {
20107     case NM_POOL32F_0:
20108         switch (extract32(ctx->opcode, 3, 7)) {
20109         case NM_RINT_S:
20110             gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
20111             break;
20112         case NM_RINT_D:
20113             gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
20114             break;
20115         case NM_CLASS_S:
20116             gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
20117             break;
20118         case NM_CLASS_D:
20119             gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
20120             break;
20121         case NM_ADD_S:
20122             gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0);
20123             break;
20124         case NM_ADD_D:
20125             gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0);
20126             break;
20127         case NM_SUB_S:
20128             gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0);
20129             break;
20130         case NM_SUB_D:
20131             gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0);
20132             break;
20133         case NM_MUL_S:
20134             gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0);
20135             break;
20136         case NM_MUL_D:
20137             gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0);
20138             break;
20139         case NM_DIV_S:
20140             gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0);
20141             break;
20142         case NM_DIV_D:
20143             gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0);
20144             break;
20145         case NM_SELEQZ_S:
20146             gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
20147             break;
20148         case NM_SELEQZ_D:
20149             gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
20150             break;
20151         case NM_SELNEZ_S:
20152             gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
20153             break;
20154         case NM_SELNEZ_D:
20155             gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
20156             break;
20157         case NM_SEL_S:
20158             gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
20159             break;
20160         case NM_SEL_D:
20161             gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
20162             break;
20163         case NM_MADDF_S:
20164             gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0);
20165             break;
20166         case NM_MADDF_D:
20167             gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0);
20168             break;
20169         case NM_MSUBF_S:
20170             gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0);
20171             break;
20172         case NM_MSUBF_D:
20173             gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0);
20174             break;
20175         default:
20176             generate_exception_end(ctx, EXCP_RI);
20177             break;
20178         }
20179         break;
20180     case NM_POOL32F_3:
20181         switch (extract32(ctx->opcode, 3, 3)) {
20182         case NM_MIN_FMT:
20183             switch (extract32(ctx->opcode, 9, 1)) {
20184             case FMT_SDPS_S:
20185                 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
20186                 break;
20187             case FMT_SDPS_D:
20188                 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
20189                 break;
20190             }
20191             break;
20192         case NM_MAX_FMT:
20193             switch (extract32(ctx->opcode, 9, 1)) {
20194             case FMT_SDPS_S:
20195                 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
20196                 break;
20197             case FMT_SDPS_D:
20198                 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
20199                 break;
20200             }
20201             break;
20202         case NM_MINA_FMT:
20203             switch (extract32(ctx->opcode, 9, 1)) {
20204             case FMT_SDPS_S:
20205                 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
20206                 break;
20207             case FMT_SDPS_D:
20208                 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
20209                 break;
20210             }
20211             break;
20212         case NM_MAXA_FMT:
20213             switch (extract32(ctx->opcode, 9, 1)) {
20214             case FMT_SDPS_S:
20215                 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
20216                 break;
20217             case FMT_SDPS_D:
20218                 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
20219                 break;
20220             }
20221             break;
20222         case NM_POOL32FXF:
20223             switch (extract32(ctx->opcode, 6, 8)) {
20224             case NM_CFC1:
20225                 gen_cp1(ctx, OPC_CFC1, rt, rs);
20226                 break;
20227             case NM_CTC1:
20228                 gen_cp1(ctx, OPC_CTC1, rt, rs);
20229                 break;
20230             case NM_MFC1:
20231                 gen_cp1(ctx, OPC_MFC1, rt, rs);
20232                 break;
20233             case NM_MTC1:
20234                 gen_cp1(ctx, OPC_MTC1, rt, rs);
20235                 break;
20236             case NM_MFHC1:
20237                 gen_cp1(ctx, OPC_MFHC1, rt, rs);
20238                 break;
20239             case NM_MTHC1:
20240                 gen_cp1(ctx, OPC_MTHC1, rt, rs);
20241                 break;
20242             case NM_CVT_S_PL:
20243                 gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0);
20244                 break;
20245             case NM_CVT_S_PU:
20246                 gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0);
20247                 break;
20248             default:
20249                 switch (extract32(ctx->opcode, 6, 9)) {
20250                 case NM_CVT_L_S:
20251                     gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0);
20252                     break;
20253                 case NM_CVT_L_D:
20254                     gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0);
20255                     break;
20256                 case NM_CVT_W_S:
20257                     gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0);
20258                     break;
20259                 case NM_CVT_W_D:
20260                     gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0);
20261                     break;
20262                 case NM_RSQRT_S:
20263                     gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0);
20264                     break;
20265                 case NM_RSQRT_D:
20266                     gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0);
20267                     break;
20268                 case NM_SQRT_S:
20269                     gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0);
20270                     break;
20271                 case NM_SQRT_D:
20272                     gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0);
20273                     break;
20274                 case NM_RECIP_S:
20275                     gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0);
20276                     break;
20277                 case NM_RECIP_D:
20278                     gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0);
20279                     break;
20280                 case NM_FLOOR_L_S:
20281                     gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0);
20282                     break;
20283                 case NM_FLOOR_L_D:
20284                     gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0);
20285                     break;
20286                 case NM_FLOOR_W_S:
20287                     gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0);
20288                     break;
20289                 case NM_FLOOR_W_D:
20290                     gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0);
20291                     break;
20292                 case NM_CEIL_L_S:
20293                     gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0);
20294                     break;
20295                 case NM_CEIL_L_D:
20296                     gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0);
20297                     break;
20298                 case NM_CEIL_W_S:
20299                     gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0);
20300                     break;
20301                 case NM_CEIL_W_D:
20302                     gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0);
20303                     break;
20304                 case NM_TRUNC_L_S:
20305                     gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0);
20306                     break;
20307                 case NM_TRUNC_L_D:
20308                     gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0);
20309                     break;
20310                 case NM_TRUNC_W_S:
20311                     gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0);
20312                     break;
20313                 case NM_TRUNC_W_D:
20314                     gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0);
20315                     break;
20316                 case NM_ROUND_L_S:
20317                     gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0);
20318                     break;
20319                 case NM_ROUND_L_D:
20320                     gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0);
20321                     break;
20322                 case NM_ROUND_W_S:
20323                     gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0);
20324                     break;
20325                 case NM_ROUND_W_D:
20326                     gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0);
20327                     break;
20328                 case NM_MOV_S:
20329                     gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0);
20330                     break;
20331                 case NM_MOV_D:
20332                     gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0);
20333                     break;
20334                 case NM_ABS_S:
20335                     gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0);
20336                     break;
20337                 case NM_ABS_D:
20338                     gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0);
20339                     break;
20340                 case NM_NEG_S:
20341                     gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0);
20342                     break;
20343                 case NM_NEG_D:
20344                     gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0);
20345                     break;
20346                 case NM_CVT_D_S:
20347                     gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0);
20348                     break;
20349                 case NM_CVT_D_W:
20350                     gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0);
20351                     break;
20352                 case NM_CVT_D_L:
20353                     gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0);
20354                     break;
20355                 case NM_CVT_S_D:
20356                     gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0);
20357                     break;
20358                 case NM_CVT_S_W:
20359                     gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0);
20360                     break;
20361                 case NM_CVT_S_L:
20362                     gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0);
20363                     break;
20364                 default:
20365                     generate_exception_end(ctx, EXCP_RI);
20366                     break;
20367                 }
20368                 break;
20369             }
20370             break;
20371         }
20372         break;
20373     case NM_POOL32F_5:
20374         switch (extract32(ctx->opcode, 3, 3)) {
20375         case NM_CMP_CONDN_S:
20376             gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20377             break;
20378         case NM_CMP_CONDN_D:
20379             gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20380             break;
20381         default:
20382             generate_exception_end(ctx, EXCP_RI);
20383             break;
20384         }
20385         break;
20386     default:
20387         generate_exception_end(ctx, EXCP_RI);
20388         break;
20389     }
20390 }
20391
20392 static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc,
20393                                        int rd, int rs, int rt)
20394 {
20395     int ret = rd;
20396     TCGv t0 = tcg_temp_new();
20397     TCGv v1_t = tcg_temp_new();
20398     TCGv v2_t = tcg_temp_new();
20399
20400     gen_load_gpr(v1_t, rs);
20401     gen_load_gpr(v2_t, rt);
20402
20403     switch (opc) {
20404     case NM_CMP_EQ_PH:
20405         check_dsp(ctx);
20406         gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
20407         break;
20408     case NM_CMP_LT_PH:
20409         check_dsp(ctx);
20410         gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
20411         break;
20412     case NM_CMP_LE_PH:
20413         check_dsp(ctx);
20414         gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
20415         break;
20416     case NM_CMPU_EQ_QB:
20417         check_dsp(ctx);
20418         gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
20419         break;
20420     case NM_CMPU_LT_QB:
20421         check_dsp(ctx);
20422         gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
20423         break;
20424     case NM_CMPU_LE_QB:
20425         check_dsp(ctx);
20426         gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
20427         break;
20428     case NM_CMPGU_EQ_QB:
20429         check_dsp(ctx);
20430         gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20431         gen_store_gpr(v1_t, ret);
20432         break;
20433     case NM_CMPGU_LT_QB:
20434         check_dsp(ctx);
20435         gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20436         gen_store_gpr(v1_t, ret);
20437         break;
20438     case NM_CMPGU_LE_QB:
20439         check_dsp(ctx);
20440         gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20441         gen_store_gpr(v1_t, ret);
20442         break;
20443     case NM_CMPGDU_EQ_QB:
20444         check_dsp_r2(ctx);
20445         gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20446         tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20447         gen_store_gpr(v1_t, ret);
20448         break;
20449     case NM_CMPGDU_LT_QB:
20450         check_dsp_r2(ctx);
20451         gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20452         tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20453         gen_store_gpr(v1_t, ret);
20454         break;
20455     case NM_CMPGDU_LE_QB:
20456         check_dsp_r2(ctx);
20457         gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20458         tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20459         gen_store_gpr(v1_t, ret);
20460         break;
20461     case NM_PACKRL_PH:
20462         check_dsp(ctx);
20463         gen_helper_packrl_ph(v1_t, v1_t, v2_t);
20464         gen_store_gpr(v1_t, ret);
20465         break;
20466     case NM_PICK_QB:
20467         check_dsp(ctx);
20468         gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env);
20469         gen_store_gpr(v1_t, ret);
20470         break;
20471     case NM_PICK_PH:
20472         check_dsp(ctx);
20473         gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env);
20474         gen_store_gpr(v1_t, ret);
20475         break;
20476     case NM_ADDQ_S_W:
20477         check_dsp(ctx);
20478         gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env);
20479         gen_store_gpr(v1_t, ret);
20480         break;
20481     case NM_SUBQ_S_W:
20482         check_dsp(ctx);
20483         gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env);
20484         gen_store_gpr(v1_t, ret);
20485         break;
20486     case NM_ADDSC:
20487         check_dsp(ctx);
20488         gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env);
20489         gen_store_gpr(v1_t, ret);
20490         break;
20491     case NM_ADDWC:
20492         check_dsp(ctx);
20493         gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env);
20494         gen_store_gpr(v1_t, ret);
20495         break;
20496     case NM_ADDQ_S_PH:
20497         check_dsp(ctx);
20498         switch (extract32(ctx->opcode, 10, 1)) {
20499         case 0:
20500             /* ADDQ_PH */
20501             gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env);
20502             gen_store_gpr(v1_t, ret);
20503             break;
20504         case 1:
20505             /* ADDQ_S_PH */
20506             gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20507             gen_store_gpr(v1_t, ret);
20508             break;
20509         }
20510         break;
20511     case NM_ADDQH_R_PH:
20512         check_dsp_r2(ctx);
20513         switch (extract32(ctx->opcode, 10, 1)) {
20514         case 0:
20515             /* ADDQH_PH */
20516             gen_helper_addqh_ph(v1_t, v1_t, v2_t);
20517             gen_store_gpr(v1_t, ret);
20518             break;
20519         case 1:
20520             /* ADDQH_R_PH */
20521             gen_helper_addqh_r_ph(v1_t, v1_t, v2_t);
20522             gen_store_gpr(v1_t, ret);
20523             break;
20524         }
20525         break;
20526     case NM_ADDQH_R_W:
20527         check_dsp_r2(ctx);
20528         switch (extract32(ctx->opcode, 10, 1)) {
20529         case 0:
20530             /* ADDQH_W */
20531             gen_helper_addqh_w(v1_t, v1_t, v2_t);
20532             gen_store_gpr(v1_t, ret);
20533             break;
20534         case 1:
20535             /* ADDQH_R_W */
20536             gen_helper_addqh_r_w(v1_t, v1_t, v2_t);
20537             gen_store_gpr(v1_t, ret);
20538             break;
20539         }
20540         break;
20541     case NM_ADDU_S_QB:
20542         check_dsp(ctx);
20543         switch (extract32(ctx->opcode, 10, 1)) {
20544         case 0:
20545             /* ADDU_QB */
20546             gen_helper_addu_qb(v1_t, v1_t, v2_t, cpu_env);
20547             gen_store_gpr(v1_t, ret);
20548             break;
20549         case 1:
20550             /* ADDU_S_QB */
20551             gen_helper_addu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20552             gen_store_gpr(v1_t, ret);
20553             break;
20554         }
20555         break;
20556     case NM_ADDU_S_PH:
20557         check_dsp_r2(ctx);
20558         switch (extract32(ctx->opcode, 10, 1)) {
20559         case 0:
20560             /* ADDU_PH */
20561             gen_helper_addu_ph(v1_t, v1_t, v2_t, cpu_env);
20562             gen_store_gpr(v1_t, ret);
20563             break;
20564         case 1:
20565             /* ADDU_S_PH */
20566             gen_helper_addu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20567             gen_store_gpr(v1_t, ret);
20568             break;
20569         }
20570         break;
20571     case NM_ADDUH_R_QB:
20572         check_dsp_r2(ctx);
20573         switch (extract32(ctx->opcode, 10, 1)) {
20574         case 0:
20575             /* ADDUH_QB */
20576             gen_helper_adduh_qb(v1_t, v1_t, v2_t);
20577             gen_store_gpr(v1_t, ret);
20578             break;
20579         case 1:
20580             /* ADDUH_R_QB */
20581             gen_helper_adduh_r_qb(v1_t, v1_t, v2_t);
20582             gen_store_gpr(v1_t, ret);
20583             break;
20584         }
20585         break;
20586     case NM_SHRAV_R_PH:
20587         check_dsp(ctx);
20588         switch (extract32(ctx->opcode, 10, 1)) {
20589         case 0:
20590             /* SHRAV_PH */
20591             gen_helper_shra_ph(v1_t, v1_t, v2_t);
20592             gen_store_gpr(v1_t, ret);
20593             break;
20594         case 1:
20595             /* SHRAV_R_PH */
20596             gen_helper_shra_r_ph(v1_t, v1_t, v2_t);
20597             gen_store_gpr(v1_t, ret);
20598             break;
20599         }
20600         break;
20601     case NM_SHRAV_R_QB:
20602         check_dsp_r2(ctx);
20603         switch (extract32(ctx->opcode, 10, 1)) {
20604         case 0:
20605             /* SHRAV_QB */
20606             gen_helper_shra_qb(v1_t, v1_t, v2_t);
20607             gen_store_gpr(v1_t, ret);
20608             break;
20609         case 1:
20610             /* SHRAV_R_QB */
20611             gen_helper_shra_r_qb(v1_t, v1_t, v2_t);
20612             gen_store_gpr(v1_t, ret);
20613             break;
20614         }
20615         break;
20616     case NM_SUBQ_S_PH:
20617         check_dsp(ctx);
20618         switch (extract32(ctx->opcode, 10, 1)) {
20619         case 0:
20620             /* SUBQ_PH */
20621             gen_helper_subq_ph(v1_t, v1_t, v2_t, cpu_env);
20622             gen_store_gpr(v1_t, ret);
20623             break;
20624         case 1:
20625             /* SUBQ_S_PH */
20626             gen_helper_subq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20627             gen_store_gpr(v1_t, ret);
20628             break;
20629         }
20630         break;
20631     case NM_SUBQH_R_PH:
20632         check_dsp_r2(ctx);
20633         switch (extract32(ctx->opcode, 10, 1)) {
20634         case 0:
20635             /* SUBQH_PH */
20636             gen_helper_subqh_ph(v1_t, v1_t, v2_t);
20637             gen_store_gpr(v1_t, ret);
20638             break;
20639         case 1:
20640             /* SUBQH_R_PH */
20641             gen_helper_subqh_r_ph(v1_t, v1_t, v2_t);
20642             gen_store_gpr(v1_t, ret);
20643             break;
20644         }
20645         break;
20646     case NM_SUBQH_R_W:
20647         check_dsp_r2(ctx);
20648         switch (extract32(ctx->opcode, 10, 1)) {
20649         case 0:
20650             /* SUBQH_W */
20651             gen_helper_subqh_w(v1_t, v1_t, v2_t);
20652             gen_store_gpr(v1_t, ret);
20653             break;
20654         case 1:
20655             /* SUBQH_R_W */
20656             gen_helper_subqh_r_w(v1_t, v1_t, v2_t);
20657             gen_store_gpr(v1_t, ret);
20658             break;
20659         }
20660         break;
20661     case NM_SUBU_S_QB:
20662         check_dsp(ctx);
20663         switch (extract32(ctx->opcode, 10, 1)) {
20664         case 0:
20665             /* SUBU_QB */
20666             gen_helper_subu_qb(v1_t, v1_t, v2_t, cpu_env);
20667             gen_store_gpr(v1_t, ret);
20668             break;
20669         case 1:
20670             /* SUBU_S_QB */
20671             gen_helper_subu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20672             gen_store_gpr(v1_t, ret);
20673             break;
20674         }
20675         break;
20676     case NM_SUBU_S_PH:
20677         check_dsp_r2(ctx);
20678         switch (extract32(ctx->opcode, 10, 1)) {
20679         case 0:
20680             /* SUBU_PH */
20681             gen_helper_subu_ph(v1_t, v1_t, v2_t, cpu_env);
20682             gen_store_gpr(v1_t, ret);
20683             break;
20684         case 1:
20685             /* SUBU_S_PH */
20686             gen_helper_subu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20687             gen_store_gpr(v1_t, ret);
20688             break;
20689         }
20690         break;
20691     case NM_SUBUH_R_QB:
20692         check_dsp_r2(ctx);
20693         switch (extract32(ctx->opcode, 10, 1)) {
20694         case 0:
20695             /* SUBUH_QB */
20696             gen_helper_subuh_qb(v1_t, v1_t, v2_t);
20697             gen_store_gpr(v1_t, ret);
20698             break;
20699         case 1:
20700             /* SUBUH_R_QB */
20701             gen_helper_subuh_r_qb(v1_t, v1_t, v2_t);
20702             gen_store_gpr(v1_t, ret);
20703             break;
20704         }
20705         break;
20706     case NM_SHLLV_S_PH:
20707         check_dsp(ctx);
20708         switch (extract32(ctx->opcode, 10, 1)) {
20709         case 0:
20710             /* SHLLV_PH */
20711             gen_helper_shll_ph(v1_t, v1_t, v2_t, cpu_env);
20712             gen_store_gpr(v1_t, ret);
20713             break;
20714         case 1:
20715             /* SHLLV_S_PH */
20716             gen_helper_shll_s_ph(v1_t, v1_t, v2_t, cpu_env);
20717             gen_store_gpr(v1_t, ret);
20718             break;
20719         }
20720         break;
20721     case NM_PRECR_SRA_R_PH_W:
20722         check_dsp_r2(ctx);
20723         switch (extract32(ctx->opcode, 10, 1)) {
20724         case 0:
20725             /* PRECR_SRA_PH_W */
20726             {
20727                 TCGv_i32 sa_t = tcg_const_i32(rd);
20728                 gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t,
20729                                           cpu_gpr[rt]);
20730                 gen_store_gpr(v1_t, rt);
20731                 tcg_temp_free_i32(sa_t);
20732             }
20733             break;
20734         case 1:
20735             /* PRECR_SRA_R_PH_W */
20736             {
20737                 TCGv_i32 sa_t = tcg_const_i32(rd);
20738                 gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t,
20739                                             cpu_gpr[rt]);
20740                 gen_store_gpr(v1_t, rt);
20741                 tcg_temp_free_i32(sa_t);
20742             }
20743             break;
20744        }
20745         break;
20746     case NM_MULEU_S_PH_QBL:
20747         check_dsp(ctx);
20748         gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, cpu_env);
20749         gen_store_gpr(v1_t, ret);
20750         break;
20751     case NM_MULEU_S_PH_QBR:
20752         check_dsp(ctx);
20753         gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, cpu_env);
20754         gen_store_gpr(v1_t, ret);
20755         break;
20756     case NM_MULQ_RS_PH:
20757         check_dsp(ctx);
20758         gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, cpu_env);
20759         gen_store_gpr(v1_t, ret);
20760         break;
20761     case NM_MULQ_S_PH:
20762         check_dsp_r2(ctx);
20763         gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20764         gen_store_gpr(v1_t, ret);
20765         break;
20766     case NM_MULQ_RS_W:
20767         check_dsp_r2(ctx);
20768         gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, cpu_env);
20769         gen_store_gpr(v1_t, ret);
20770         break;
20771     case NM_MULQ_S_W:
20772         check_dsp_r2(ctx);
20773         gen_helper_mulq_s_w(v1_t, v1_t, v2_t, cpu_env);
20774         gen_store_gpr(v1_t, ret);
20775         break;
20776     case NM_APPEND:
20777         check_dsp_r2(ctx);
20778         gen_load_gpr(t0, rs);
20779         if (rd != 0) {
20780             tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd);
20781         }
20782         tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20783         break;
20784     case NM_MODSUB:
20785         check_dsp(ctx);
20786         gen_helper_modsub(v1_t, v1_t, v2_t);
20787         gen_store_gpr(v1_t, ret);
20788         break;
20789     case NM_SHRAV_R_W:
20790         check_dsp(ctx);
20791         gen_helper_shra_r_w(v1_t, v1_t, v2_t);
20792         gen_store_gpr(v1_t, ret);
20793         break;
20794     case NM_SHRLV_PH:
20795         check_dsp_r2(ctx);
20796         gen_helper_shrl_ph(v1_t, v1_t, v2_t);
20797         gen_store_gpr(v1_t, ret);
20798         break;
20799     case NM_SHRLV_QB:
20800         check_dsp(ctx);
20801         gen_helper_shrl_qb(v1_t, v1_t, v2_t);
20802         gen_store_gpr(v1_t, ret);
20803         break;
20804     case NM_SHLLV_QB:
20805         check_dsp(ctx);
20806         gen_helper_shll_qb(v1_t, v1_t, v2_t, cpu_env);
20807         gen_store_gpr(v1_t, ret);
20808         break;
20809     case NM_SHLLV_S_W:
20810         check_dsp(ctx);
20811         gen_helper_shll_s_w(v1_t, v1_t, v2_t, cpu_env);
20812         gen_store_gpr(v1_t, ret);
20813         break;
20814     case NM_SHILO:
20815         check_dsp(ctx);
20816         {
20817             TCGv tv0 = tcg_temp_new();
20818             TCGv tv1 = tcg_temp_new();
20819             int16_t imm = extract32(ctx->opcode, 16, 7);
20820
20821             tcg_gen_movi_tl(tv0, rd >> 3);
20822             tcg_gen_movi_tl(tv1, imm);
20823             gen_helper_shilo(tv0, tv1, cpu_env);
20824         }
20825         break;
20826     case NM_MULEQ_S_W_PHL:
20827         check_dsp(ctx);
20828         gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, cpu_env);
20829         gen_store_gpr(v1_t, ret);
20830         break;
20831     case NM_MULEQ_S_W_PHR:
20832         check_dsp(ctx);
20833         gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, cpu_env);
20834         gen_store_gpr(v1_t, ret);
20835         break;
20836     case NM_MUL_S_PH:
20837         check_dsp_r2(ctx);
20838         switch (extract32(ctx->opcode, 10, 1)) {
20839         case 0:
20840             /* MUL_PH */
20841             gen_helper_mul_ph(v1_t, v1_t, v2_t, cpu_env);
20842             gen_store_gpr(v1_t, ret);
20843             break;
20844         case 1:
20845             /* MUL_S_PH */
20846             gen_helper_mul_s_ph(v1_t, v1_t, v2_t, cpu_env);
20847             gen_store_gpr(v1_t, ret);
20848             break;
20849         }
20850         break;
20851     case NM_PRECR_QB_PH:
20852         check_dsp_r2(ctx);
20853         gen_helper_precr_qb_ph(v1_t, v1_t, v2_t);
20854         gen_store_gpr(v1_t, ret);
20855         break;
20856     case NM_PRECRQ_QB_PH:
20857         check_dsp(ctx);
20858         gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t);
20859         gen_store_gpr(v1_t, ret);
20860         break;
20861     case NM_PRECRQ_PH_W:
20862         check_dsp(ctx);
20863         gen_helper_precrq_ph_w(v1_t, v1_t, v2_t);
20864         gen_store_gpr(v1_t, ret);
20865         break;
20866     case NM_PRECRQ_RS_PH_W:
20867         check_dsp(ctx);
20868         gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, cpu_env);
20869         gen_store_gpr(v1_t, ret);
20870         break;
20871     case NM_PRECRQU_S_QB_PH:
20872         check_dsp(ctx);
20873         gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, cpu_env);
20874         gen_store_gpr(v1_t, ret);
20875         break;
20876     case NM_SHRA_R_W:
20877         check_dsp(ctx);
20878         tcg_gen_movi_tl(t0, rd);
20879         gen_helper_shra_r_w(v1_t, t0, v1_t);
20880         gen_store_gpr(v1_t, rt);
20881         break;
20882     case NM_SHRA_R_PH:
20883         check_dsp(ctx);
20884         tcg_gen_movi_tl(t0, rd >> 1);
20885         switch (extract32(ctx->opcode, 10, 1)) {
20886         case 0:
20887             /* SHRA_PH */
20888             gen_helper_shra_ph(v1_t, t0, v1_t);
20889             gen_store_gpr(v1_t, rt);
20890             break;
20891         case 1:
20892             /* SHRA_R_PH */
20893             gen_helper_shra_r_ph(v1_t, t0, v1_t);
20894             gen_store_gpr(v1_t, rt);
20895             break;
20896         }
20897         break;
20898     case NM_SHLL_S_PH:
20899         check_dsp(ctx);
20900         tcg_gen_movi_tl(t0, rd >> 1);
20901         switch (extract32(ctx->opcode, 10, 2)) {
20902         case 0:
20903             /* SHLL_PH */
20904             gen_helper_shll_ph(v1_t, t0, v1_t, cpu_env);
20905             gen_store_gpr(v1_t, rt);
20906             break;
20907         case 2:
20908             /* SHLL_S_PH */
20909             gen_helper_shll_s_ph(v1_t, t0, v1_t, cpu_env);
20910             gen_store_gpr(v1_t, rt);
20911             break;
20912         default:
20913             generate_exception_end(ctx, EXCP_RI);
20914             break;
20915         }
20916         break;
20917     case NM_SHLL_S_W:
20918         check_dsp(ctx);
20919         tcg_gen_movi_tl(t0, rd);
20920         gen_helper_shll_s_w(v1_t, t0, v1_t, cpu_env);
20921         gen_store_gpr(v1_t, rt);
20922         break;
20923     case NM_REPL_PH:
20924         check_dsp(ctx);
20925         {
20926             int16_t imm;
20927             imm = sextract32(ctx->opcode, 11, 11);
20928             imm = (int16_t)(imm << 6) >> 6;
20929             if (rt != 0) {
20930                 tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm));
20931             }
20932         }
20933         break;
20934     default:
20935         generate_exception_end(ctx, EXCP_RI);
20936         break;
20937     }
20938 }
20939
20940 static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
20941 {
20942     uint16_t insn;
20943     uint32_t op;
20944     int rt, rs, rd;
20945     int offset;
20946     int imm;
20947
20948     insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
20949     ctx->opcode = (ctx->opcode << 16) | insn;
20950
20951     rt = extract32(ctx->opcode, 21, 5);
20952     rs = extract32(ctx->opcode, 16, 5);
20953     rd = extract32(ctx->opcode, 11, 5);
20954
20955     op = extract32(ctx->opcode, 26, 6);
20956     switch (op) {
20957     case NM_P_ADDIU:
20958         if (rt == 0) {
20959             /* P.RI */
20960             switch (extract32(ctx->opcode, 19, 2)) {
20961             case NM_SIGRIE:
20962             default:
20963                 generate_exception_end(ctx, EXCP_RI);
20964                 break;
20965             case NM_P_SYSCALL:
20966                 if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) {
20967                     generate_exception_end(ctx, EXCP_SYSCALL);
20968                 } else {
20969                     generate_exception_end(ctx, EXCP_RI);
20970                 }
20971                 break;
20972             case NM_BREAK:
20973                 generate_exception_end(ctx, EXCP_BREAK);
20974                 break;
20975             case NM_SDBBP:
20976                 if (is_uhi(extract32(ctx->opcode, 0, 19))) {
20977                     gen_helper_do_semihosting(cpu_env);
20978                 } else {
20979                     if (ctx->hflags & MIPS_HFLAG_SBRI) {
20980                         generate_exception_end(ctx, EXCP_RI);
20981                     } else {
20982                         generate_exception_end(ctx, EXCP_DBp);
20983                     }
20984                 }
20985                 break;
20986             }
20987         } else {
20988             /* NM_ADDIU */
20989             imm = extract32(ctx->opcode, 0, 16);
20990             if (rs != 0) {
20991                 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm);
20992             } else {
20993                 tcg_gen_movi_tl(cpu_gpr[rt], imm);
20994             }
20995             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20996         }
20997         break;
20998     case NM_ADDIUPC:
20999         if (rt != 0) {
21000             offset = sextract32(ctx->opcode, 0, 1) << 21 |
21001                      extract32(ctx->opcode, 1, 20) << 1;
21002             target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset);
21003             tcg_gen_movi_tl(cpu_gpr[rt], addr);
21004         }
21005         break;
21006     case NM_POOL32A:
21007         switch (ctx->opcode & 0x07) {
21008         case NM_POOL32A0:
21009             gen_pool32a0_nanomips_insn(env, ctx);
21010             break;
21011         case NM_POOL32A5:
21012             {
21013                 int32_t op1 = extract32(ctx->opcode, 3, 7);
21014                 gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt);
21015             }
21016             break;
21017         case NM_POOL32A7:
21018             switch (extract32(ctx->opcode, 3, 3)) {
21019             case NM_P_LSX:
21020                 gen_p_lsx(ctx, rd, rs, rt);
21021                 break;
21022             case NM_LSA:
21023                 /* In nanoMIPS, the shift field directly encodes the shift
21024                  * amount, meaning that the supported shift values are in
21025                  * the range 0 to 3 (instead of 1 to 4 in MIPSR6). */
21026                 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
21027                         extract32(ctx->opcode, 9, 2) - 1);
21028                 break;
21029             case NM_EXTW:
21030                 gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5));
21031                 break;
21032             case NM_POOL32AXF:
21033                 gen_pool32axf_nanomips_insn(env, ctx);
21034                 break;
21035             default:
21036                 generate_exception_end(ctx, EXCP_RI);
21037                 break;
21038             }
21039             break;
21040         default:
21041             generate_exception_end(ctx, EXCP_RI);
21042             break;
21043         }
21044         break;
21045     case NM_P_GP_W:
21046         switch (ctx->opcode & 0x03) {
21047         case NM_ADDIUGP_W:
21048             if (rt != 0) {
21049                 offset = extract32(ctx->opcode, 0, 21);
21050                 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset);
21051             }
21052             break;
21053         case NM_LWGP:
21054             gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
21055             break;
21056         case NM_SWGP:
21057             gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
21058             break;
21059         default:
21060             generate_exception_end(ctx, EXCP_RI);
21061             break;
21062         }
21063         break;
21064     case NM_P48I:
21065         {
21066             insn = cpu_lduw_code(env, ctx->base.pc_next + 4);
21067             target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16;
21068             switch (extract32(ctx->opcode, 16, 5)) {
21069             case NM_LI48:
21070                 check_nms(ctx);
21071                 if (rt != 0) {
21072                     tcg_gen_movi_tl(cpu_gpr[rt], addr_off);
21073                 }
21074                 break;
21075             case NM_ADDIU48:
21076                 check_nms(ctx);
21077                 if (rt != 0) {
21078                     tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off);
21079                     tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
21080                 }
21081                 break;
21082             case NM_ADDIUGP48:
21083                 check_nms(ctx);
21084                 if (rt != 0) {
21085                     gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_off);
21086                 }
21087                 break;
21088             case NM_ADDIUPC48:
21089                 check_nms(ctx);
21090                 if (rt != 0) {
21091                     target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21092                                                 addr_off);
21093
21094                     tcg_gen_movi_tl(cpu_gpr[rt], addr);
21095                 }
21096                 break;
21097             case NM_LWPC48:
21098                 check_nms(ctx);
21099                 if (rt != 0) {
21100                     TCGv t0;
21101                     t0 = tcg_temp_new();
21102
21103                     target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21104                                                 addr_off);
21105
21106                     tcg_gen_movi_tl(t0, addr);
21107                     tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_TESL);
21108                     tcg_temp_free(t0);
21109                 }
21110                 break;
21111             case NM_SWPC48:
21112                 check_nms(ctx);
21113                 {
21114                     TCGv t0, t1;
21115                     t0 = tcg_temp_new();
21116                     t1 = tcg_temp_new();
21117
21118                     target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21119                                                 addr_off);
21120
21121                     tcg_gen_movi_tl(t0, addr);
21122                     gen_load_gpr(t1, rt);
21123
21124                     tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
21125
21126                     tcg_temp_free(t0);
21127                     tcg_temp_free(t1);
21128                 }
21129                 break;
21130             default:
21131                 generate_exception_end(ctx, EXCP_RI);
21132                 break;
21133             }
21134             return 6;
21135         }
21136     case NM_P_U12:
21137         switch (extract32(ctx->opcode, 12, 4)) {
21138         case NM_ORI:
21139             gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12));
21140             break;
21141         case NM_XORI:
21142             gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12));
21143             break;
21144         case NM_ANDI:
21145             gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12));
21146             break;
21147         case NM_P_SR:
21148             switch (extract32(ctx->opcode, 20, 1)) {
21149             case NM_PP_SR:
21150                 switch (ctx->opcode & 3) {
21151                 case NM_SAVE:
21152                     gen_save(ctx, rt, extract32(ctx->opcode, 16, 4),
21153                              extract32(ctx->opcode, 2, 1),
21154                              extract32(ctx->opcode, 3, 9) << 3);
21155                     break;
21156                 case NM_RESTORE:
21157                 case NM_RESTORE_JRC:
21158                     gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4),
21159                                 extract32(ctx->opcode, 2, 1),
21160                                 extract32(ctx->opcode, 3, 9) << 3);
21161                     if ((ctx->opcode & 3) == NM_RESTORE_JRC) {
21162                         gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
21163                     }
21164                     break;
21165                 default:
21166                     generate_exception_end(ctx, EXCP_RI);
21167                     break;
21168                 }
21169                 break;
21170             case NM_P_SR_F:
21171                 generate_exception_end(ctx, EXCP_RI);
21172                 break;
21173             }
21174             break;
21175         case NM_SLTI:
21176             gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12));
21177             break;
21178         case NM_SLTIU:
21179             gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12));
21180             break;
21181         case NM_SEQI:
21182             {
21183                 TCGv t0 = tcg_temp_new();
21184
21185                 imm = extract32(ctx->opcode, 0, 12);
21186                 gen_load_gpr(t0, rs);
21187                 tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm);
21188                 gen_store_gpr(t0, rt);
21189
21190                 tcg_temp_free(t0);
21191             }
21192             break;
21193         case NM_ADDIUNEG:
21194             imm = (int16_t) extract32(ctx->opcode, 0, 12);
21195             gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm);
21196             break;
21197         case NM_P_SHIFT:
21198             {
21199                 int shift = extract32(ctx->opcode, 0, 5);
21200                 switch (extract32(ctx->opcode, 5, 4)) {
21201                 case NM_P_SLL:
21202                     if (rt == 0 && shift == 0) {
21203                         /* NOP */
21204                     } else if (rt == 0 && shift == 3) {
21205                         /* EHB - treat as NOP */
21206                     } else if (rt == 0 && shift == 5) {
21207                         /* PAUSE - treat as NOP */
21208                     } else if (rt == 0 && shift == 6) {
21209                         /* SYNC */
21210                         gen_sync(extract32(ctx->opcode, 16, 5));
21211                     } else {
21212                         /* SLL */
21213                         gen_shift_imm(ctx, OPC_SLL, rt, rs,
21214                                       extract32(ctx->opcode, 0, 5));
21215                     }
21216                     break;
21217                 case NM_SRL:
21218                     gen_shift_imm(ctx, OPC_SRL, rt, rs,
21219                                   extract32(ctx->opcode, 0, 5));
21220                     break;
21221                 case NM_SRA:
21222                     gen_shift_imm(ctx, OPC_SRA, rt, rs,
21223                                   extract32(ctx->opcode, 0, 5));
21224                     break;
21225                 case NM_ROTR:
21226                     gen_shift_imm(ctx, OPC_ROTR, rt, rs,
21227                                   extract32(ctx->opcode, 0, 5));
21228                     break;
21229                 }
21230             }
21231             break;
21232         case NM_P_ROTX:
21233             check_nms(ctx);
21234             if (rt != 0) {
21235                 TCGv t0 = tcg_temp_new();
21236                 TCGv_i32 shift = tcg_const_i32(extract32(ctx->opcode, 0, 5));
21237                 TCGv_i32 shiftx = tcg_const_i32(extract32(ctx->opcode, 7, 4)
21238                                                 << 1);
21239                 TCGv_i32 stripe = tcg_const_i32(extract32(ctx->opcode, 6, 1));
21240
21241                 gen_load_gpr(t0, rs);
21242                 gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe);
21243                 tcg_temp_free(t0);
21244
21245                 tcg_temp_free_i32(shift);
21246                 tcg_temp_free_i32(shiftx);
21247                 tcg_temp_free_i32(stripe);
21248             }
21249             break;
21250         case NM_P_INS:
21251             switch (((ctx->opcode >> 10) & 2) |
21252                     (extract32(ctx->opcode, 5, 1))) {
21253             case NM_INS:
21254                 check_nms(ctx);
21255                 gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5),
21256                            extract32(ctx->opcode, 6, 5));
21257                 break;
21258             default:
21259                 generate_exception_end(ctx, EXCP_RI);
21260                 break;
21261             }
21262             break;
21263         case NM_P_EXT:
21264             switch (((ctx->opcode >> 10) & 2) |
21265                     (extract32(ctx->opcode, 5, 1))) {
21266             case NM_EXT:
21267                 check_nms(ctx);
21268                 gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5),
21269                            extract32(ctx->opcode, 6, 5));
21270                 break;
21271             default:
21272                 generate_exception_end(ctx, EXCP_RI);
21273                 break;
21274             }
21275             break;
21276         default:
21277             generate_exception_end(ctx, EXCP_RI);
21278             break;
21279         }
21280         break;
21281     case NM_POOL32F:
21282         gen_pool32f_nanomips_insn(ctx);
21283         break;
21284     case NM_POOL32S:
21285         break;
21286     case NM_P_LUI:
21287         switch (extract32(ctx->opcode, 1, 1)) {
21288         case NM_LUI:
21289             if (rt != 0) {
21290                 tcg_gen_movi_tl(cpu_gpr[rt],
21291                                 sextract32(ctx->opcode, 0, 1) << 31 |
21292                                 extract32(ctx->opcode, 2, 10) << 21 |
21293                                 extract32(ctx->opcode, 12, 9) << 12);
21294             }
21295             break;
21296         case NM_ALUIPC:
21297             if (rt != 0) {
21298                 offset = sextract32(ctx->opcode, 0, 1) << 31 |
21299                          extract32(ctx->opcode, 2, 10) << 21 |
21300                          extract32(ctx->opcode, 12, 9) << 12;
21301                 target_long addr;
21302                 addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset);
21303                 tcg_gen_movi_tl(cpu_gpr[rt], addr);
21304             }
21305             break;
21306         }
21307         break;
21308     case NM_P_GP_BH:
21309         {
21310             uint32_t u = extract32(ctx->opcode, 0, 18);
21311
21312             switch (extract32(ctx->opcode, 18, 3)) {
21313             case NM_LBGP:
21314                 gen_ld(ctx, OPC_LB, rt, 28, u);
21315                 break;
21316             case NM_SBGP:
21317                 gen_st(ctx, OPC_SB, rt, 28, u);
21318                 break;
21319             case NM_LBUGP:
21320                 gen_ld(ctx, OPC_LBU, rt, 28, u);
21321                 break;
21322             case NM_ADDIUGP_B:
21323                 if (rt != 0) {
21324                     gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u);
21325                 }
21326                 break;
21327             case NM_P_GP_LH:
21328                 u &= ~1;
21329                 switch (ctx->opcode & 1) {
21330                 case NM_LHGP:
21331                     gen_ld(ctx, OPC_LH, rt, 28, u);
21332                     break;
21333                 case NM_LHUGP:
21334                     gen_ld(ctx, OPC_LHU, rt, 28, u);
21335                     break;
21336                 }
21337                 break;
21338             case NM_P_GP_SH:
21339                 u &= ~1;
21340                 switch (ctx->opcode & 1) {
21341                 case NM_SHGP:
21342                     gen_st(ctx, OPC_SH, rt, 28, u);
21343                     break;
21344                 default:
21345                     generate_exception_end(ctx, EXCP_RI);
21346                     break;
21347                 }
21348                 break;
21349             case NM_P_GP_CP1:
21350                 u &= ~0x3;
21351                 switch (ctx->opcode & 0x3) {
21352                 case NM_LWC1GP:
21353                     gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u);
21354                     break;
21355                 case NM_LDC1GP:
21356                     gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u);
21357                     break;
21358                 case NM_SWC1GP:
21359                     gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u);
21360                     break;
21361                 case NM_SDC1GP:
21362                     gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u);
21363                     break;
21364                 }
21365                 break;
21366             default:
21367                 generate_exception_end(ctx, EXCP_RI);
21368                 break;
21369             }
21370         }
21371         break;
21372     case NM_P_LS_U12:
21373         {
21374             uint32_t u = extract32(ctx->opcode, 0, 12);
21375
21376             switch (extract32(ctx->opcode, 12, 4)) {
21377             case NM_P_PREFU12:
21378                 if (rt == 31) {
21379                     /* SYNCI */
21380                     /* Break the TB to be able to sync copied instructions
21381                        immediately */
21382                     ctx->base.is_jmp = DISAS_STOP;
21383                 } else {
21384                     /* PREF */
21385                     /* Treat as NOP. */
21386                 }
21387                 break;
21388             case NM_LB:
21389                 gen_ld(ctx, OPC_LB, rt, rs, u);
21390                 break;
21391             case NM_LH:
21392                 gen_ld(ctx, OPC_LH, rt, rs, u);
21393                 break;
21394             case NM_LW:
21395                 gen_ld(ctx, OPC_LW, rt, rs, u);
21396                 break;
21397             case NM_LBU:
21398                 gen_ld(ctx, OPC_LBU, rt, rs, u);
21399                 break;
21400             case NM_LHU:
21401                 gen_ld(ctx, OPC_LHU, rt, rs, u);
21402                 break;
21403             case NM_SB:
21404                 gen_st(ctx, OPC_SB, rt, rs, u);
21405                 break;
21406             case NM_SH:
21407                 gen_st(ctx, OPC_SH, rt, rs, u);
21408                 break;
21409             case NM_SW:
21410                 gen_st(ctx, OPC_SW, rt, rs, u);
21411                 break;
21412             case NM_LWC1:
21413                 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u);
21414                 break;
21415             case NM_LDC1:
21416                 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u);
21417                 break;
21418             case NM_SWC1:
21419                 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u);
21420                 break;
21421             case NM_SDC1:
21422                 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u);
21423                 break;
21424             default:
21425                 generate_exception_end(ctx, EXCP_RI);
21426                 break;
21427             }
21428         }
21429         break;
21430     case NM_P_LS_S9:
21431         {
21432             int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) |
21433                         extract32(ctx->opcode, 0, 8);
21434
21435             switch (extract32(ctx->opcode, 8, 3)) {
21436             case NM_P_LS_S0:
21437                 switch (extract32(ctx->opcode, 11, 4)) {
21438                 case NM_LBS9:
21439                     gen_ld(ctx, OPC_LB, rt, rs, s);
21440                     break;
21441                 case NM_LHS9:
21442                     gen_ld(ctx, OPC_LH, rt, rs, s);
21443                     break;
21444                 case NM_LWS9:
21445                     gen_ld(ctx, OPC_LW, rt, rs, s);
21446                     break;
21447                 case NM_LBUS9:
21448                     gen_ld(ctx, OPC_LBU, rt, rs, s);
21449                     break;
21450                 case NM_LHUS9:
21451                     gen_ld(ctx, OPC_LHU, rt, rs, s);
21452                     break;
21453                 case NM_SBS9:
21454                     gen_st(ctx, OPC_SB, rt, rs, s);
21455                     break;
21456                 case NM_SHS9:
21457                     gen_st(ctx, OPC_SH, rt, rs, s);
21458                     break;
21459                 case NM_SWS9:
21460                     gen_st(ctx, OPC_SW, rt, rs, s);
21461                     break;
21462                 case NM_LWC1S9:
21463                     gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s);
21464                     break;
21465                 case NM_LDC1S9:
21466                     gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s);
21467                     break;
21468                 case NM_SWC1S9:
21469                     gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s);
21470                     break;
21471                 case NM_SDC1S9:
21472                     gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s);
21473                     break;
21474                 case NM_P_PREFS9:
21475                     if (rt == 31) {
21476                         /* SYNCI */
21477                         /* Break the TB to be able to sync copied instructions
21478                            immediately */
21479                         ctx->base.is_jmp = DISAS_STOP;
21480                     } else {
21481                         /* PREF */
21482                         /* Treat as NOP. */
21483                     }
21484                     break;
21485                 default:
21486                     generate_exception_end(ctx, EXCP_RI);
21487                     break;
21488                 }
21489                 break;
21490             case NM_P_LS_S1:
21491                 switch (extract32(ctx->opcode, 11, 4)) {
21492                 case NM_UALH:
21493                 case NM_UASH:
21494                     check_nms(ctx);
21495                     {
21496                         TCGv t0 = tcg_temp_new();
21497                         TCGv t1 = tcg_temp_new();
21498
21499                         gen_base_offset_addr(ctx, t0, rs, s);
21500
21501                         switch (extract32(ctx->opcode, 11, 4)) {
21502                         case NM_UALH:
21503                             tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
21504                                                MO_UNALN);
21505                             gen_store_gpr(t0, rt);
21506                             break;
21507                         case NM_UASH:
21508                             gen_load_gpr(t1, rt);
21509                             tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
21510                                                MO_UNALN);
21511                             break;
21512                         }
21513                         tcg_temp_free(t0);
21514                         tcg_temp_free(t1);
21515                     }
21516                     break;
21517                 case NM_P_LL:
21518                     switch (ctx->opcode & 0x03) {
21519                     case NM_LL:
21520                         gen_ld(ctx, OPC_LL, rt, rs, s);
21521                         break;
21522                     case NM_LLWP:
21523                         check_xnp(ctx);
21524                         gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21525                         break;
21526                     }
21527                     break;
21528                 case NM_P_SC:
21529                     switch (ctx->opcode & 0x03) {
21530                     case NM_SC:
21531                         gen_st_cond(ctx, rt, rs, s, MO_TESL, false);
21532                         break;
21533                     case NM_SCWP:
21534                         check_xnp(ctx);
21535                         gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5),
21536                                  false);
21537                         break;
21538                     }
21539                     break;
21540                 case NM_CACHE:
21541                     check_cp0_enabled(ctx);
21542                     if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
21543                         gen_cache_operation(ctx, rt, rs, s);
21544                     }
21545                     break;
21546                 }
21547                 break;
21548             case NM_P_LS_E0:
21549                 switch (extract32(ctx->opcode, 11, 4)) {
21550                 case NM_LBE:
21551                     check_eva(ctx);
21552                     check_cp0_enabled(ctx);
21553                     gen_ld(ctx, OPC_LBE, rt, rs, s);
21554                     break;
21555                 case NM_SBE:
21556                     check_eva(ctx);
21557                     check_cp0_enabled(ctx);
21558                     gen_st(ctx, OPC_SBE, rt, rs, s);
21559                     break;
21560                 case NM_LBUE:
21561                     check_eva(ctx);
21562                     check_cp0_enabled(ctx);
21563                     gen_ld(ctx, OPC_LBUE, rt, rs, s);
21564                     break;
21565                 case NM_P_PREFE:
21566                     if (rt == 31) {
21567                         /* case NM_SYNCIE */
21568                         check_eva(ctx);
21569                         check_cp0_enabled(ctx);
21570                         /* Break the TB to be able to sync copied instructions
21571                            immediately */
21572                         ctx->base.is_jmp = DISAS_STOP;
21573                     } else {
21574                         /* case NM_PREFE */
21575                         check_eva(ctx);
21576                         check_cp0_enabled(ctx);
21577                         /* Treat as NOP. */
21578                     }
21579                     break;
21580                 case NM_LHE:
21581                     check_eva(ctx);
21582                     check_cp0_enabled(ctx);
21583                     gen_ld(ctx, OPC_LHE, rt, rs, s);
21584                     break;
21585                 case NM_SHE:
21586                     check_eva(ctx);
21587                     check_cp0_enabled(ctx);
21588                     gen_st(ctx, OPC_SHE, rt, rs, s);
21589                     break;
21590                 case NM_LHUE:
21591                     check_eva(ctx);
21592                     check_cp0_enabled(ctx);
21593                     gen_ld(ctx, OPC_LHUE, rt, rs, s);
21594                     break;
21595                 case NM_CACHEE:
21596                     check_nms_dl_il_sl_tl_l2c(ctx);
21597                     gen_cache_operation(ctx, rt, rs, s);
21598                     break;
21599                 case NM_LWE:
21600                     check_eva(ctx);
21601                     check_cp0_enabled(ctx);
21602                     gen_ld(ctx, OPC_LWE, rt, rs, s);
21603                     break;
21604                 case NM_SWE:
21605                     check_eva(ctx);
21606                     check_cp0_enabled(ctx);
21607                     gen_st(ctx, OPC_SWE, rt, rs, s);
21608                     break;
21609                 case NM_P_LLE:
21610                     switch (extract32(ctx->opcode, 2, 2)) {
21611                     case NM_LLE:
21612                         check_xnp(ctx);
21613                         check_eva(ctx);
21614                         check_cp0_enabled(ctx);
21615                         gen_ld(ctx, OPC_LLE, rt, rs, s);
21616                         break;
21617                     case NM_LLWPE:
21618                         check_xnp(ctx);
21619                         check_eva(ctx);
21620                         check_cp0_enabled(ctx);
21621                         gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21622                         break;
21623                     default:
21624                         generate_exception_end(ctx, EXCP_RI);
21625                         break;
21626                     }
21627                     break;
21628                 case NM_P_SCE:
21629                     switch (extract32(ctx->opcode, 2, 2)) {
21630                     case NM_SCE:
21631                         check_xnp(ctx);
21632                         check_eva(ctx);
21633                         check_cp0_enabled(ctx);
21634                         gen_st_cond(ctx, rt, rs, s, MO_TESL, true);
21635                         break;
21636                     case NM_SCWPE:
21637                         check_xnp(ctx);
21638                         check_eva(ctx);
21639                         check_cp0_enabled(ctx);
21640                         gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5),
21641                                  true);
21642                         break;
21643                     default:
21644                         generate_exception_end(ctx, EXCP_RI);
21645                         break;
21646                     }
21647                     break;
21648                 }
21649                 break;
21650             case NM_P_LS_WM:
21651             case NM_P_LS_UAWM:
21652                 check_nms(ctx);
21653                 {
21654                     int count = extract32(ctx->opcode, 12, 3);
21655                     int counter = 0;
21656
21657                     offset = sextract32(ctx->opcode, 15, 1) << 8 |
21658                              extract32(ctx->opcode, 0, 8);
21659                     TCGv va = tcg_temp_new();
21660                     TCGv t1 = tcg_temp_new();
21661                     TCGMemOp memop = (extract32(ctx->opcode, 8, 3)) ==
21662                                       NM_P_LS_UAWM ? MO_UNALN : 0;
21663
21664                     count = (count == 0) ? 8 : count;
21665                     while (counter != count) {
21666                         int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10);
21667                         int this_offset = offset + (counter << 2);
21668
21669                         gen_base_offset_addr(ctx, va, rs, this_offset);
21670
21671                         switch (extract32(ctx->opcode, 11, 1)) {
21672                         case NM_LWM:
21673                             tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx,
21674                                                memop | MO_TESL);
21675                             gen_store_gpr(t1, this_rt);
21676                             if ((this_rt == rs) &&
21677                                 (counter != (count - 1))) {
21678                                 /* UNPREDICTABLE */
21679                             }
21680                             break;
21681                         case NM_SWM:
21682                             this_rt = (rt == 0) ? 0 : this_rt;
21683                             gen_load_gpr(t1, this_rt);
21684                             tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx,
21685                                                memop | MO_TEUL);
21686                             break;
21687                         }
21688                         counter++;
21689                     }
21690                     tcg_temp_free(va);
21691                     tcg_temp_free(t1);
21692                 }
21693                 break;
21694             default:
21695                 generate_exception_end(ctx, EXCP_RI);
21696                 break;
21697             }
21698         }
21699         break;
21700     case NM_MOVE_BALC:
21701         check_nms(ctx);
21702         {
21703             TCGv t0 = tcg_temp_new();
21704             int32_t s = sextract32(ctx->opcode, 0, 1) << 21 |
21705                         extract32(ctx->opcode, 1, 20) << 1;
21706             rd = (extract32(ctx->opcode, 24, 1)) == 0 ? 4 : 5;
21707             rt = decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3 |
21708                             extract32(ctx->opcode, 21, 3));
21709             gen_load_gpr(t0, rt);
21710             tcg_gen_mov_tl(cpu_gpr[rd], t0);
21711             gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21712             tcg_temp_free(t0);
21713         }
21714         break;
21715     case NM_P_BAL:
21716         {
21717             int32_t s = sextract32(ctx->opcode, 0, 1) << 25 |
21718                         extract32(ctx->opcode, 1, 24) << 1;
21719
21720             if ((extract32(ctx->opcode, 25, 1)) == 0) {
21721                 /* BC */
21722                 gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s);
21723             } else {
21724                 /* BALC */
21725                 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21726             }
21727         }
21728         break;
21729     case NM_P_J:
21730         switch (extract32(ctx->opcode, 12, 4)) {
21731         case NM_JALRC:
21732         case NM_JALRC_HB:
21733             gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0);
21734             break;
21735         case NM_P_BALRSC:
21736             gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt);
21737             break;
21738         default:
21739             generate_exception_end(ctx, EXCP_RI);
21740             break;
21741         }
21742         break;
21743     case NM_P_BR1:
21744         {
21745             int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21746                         extract32(ctx->opcode, 1, 13) << 1;
21747             switch (extract32(ctx->opcode, 14, 2)) {
21748             case NM_BEQC:
21749                 check_nms(ctx);
21750                 gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s);
21751                 break;
21752             case NM_P_BR3A:
21753                 s = sextract32(ctx->opcode, 0, 1) << 14 |
21754                     extract32(ctx->opcode, 1, 13) << 1;
21755                 check_cp1_enabled(ctx);
21756                 switch (extract32(ctx->opcode, 16, 5)) {
21757                 case NM_BC1EQZC:
21758                     gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s);
21759                     break;
21760                 case NM_BC1NEZC:
21761                     gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s);
21762                     break;
21763                 case NM_BPOSGE32C:
21764                     check_dsp_r3(ctx);
21765                     {
21766                         int32_t imm = extract32(ctx->opcode, 1, 13) |
21767                                       extract32(ctx->opcode, 0, 1) << 13;
21768
21769                         gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2,
21770                                               imm);
21771                     }
21772                     break;
21773                 default:
21774                     generate_exception_end(ctx, EXCP_RI);
21775                     break;
21776                 }
21777                 break;
21778             case NM_BGEC:
21779                 if (rs == rt) {
21780                     gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s);
21781                 } else {
21782                     gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s);
21783                 }
21784                 break;
21785             case NM_BGEUC:
21786                 if (rs == rt || rt == 0) {
21787                     gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s);
21788                 } else if (rs == 0) {
21789                     gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s);
21790                 } else {
21791                     gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, s);
21792                 }
21793                 break;
21794             }
21795         }
21796         break;
21797     case NM_P_BR2:
21798         {
21799             int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21800                         extract32(ctx->opcode, 1, 13) << 1;
21801             switch (extract32(ctx->opcode, 14, 2)) {
21802             case NM_BNEC:
21803                 check_nms(ctx);
21804                 gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s);
21805                 break;
21806             case NM_BLTC:
21807                 if (rs != 0 && rt != 0 && rs == rt) {
21808                     /* NOP */
21809                     ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21810                 } else {
21811                     gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s);
21812                 }
21813                 break;
21814             case NM_BLTUC:
21815                 if (rs == 0 || rs == rt) {
21816                     /* NOP */
21817                     ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21818                 } else {
21819                     gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, s);
21820                 }
21821                 break;
21822             default:
21823                 generate_exception_end(ctx, EXCP_RI);
21824                 break;
21825             }
21826         }
21827         break;
21828     case NM_P_BRI:
21829         {
21830             int32_t s = sextract32(ctx->opcode, 0, 1) << 11 |
21831                         extract32(ctx->opcode, 1, 10) << 1;
21832             uint32_t u = extract32(ctx->opcode, 11, 7);
21833
21834             gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3),
21835                                    rt, u, s);
21836         }
21837         break;
21838     default:
21839         generate_exception_end(ctx, EXCP_RI);
21840         break;
21841     }
21842     return 4;
21843 }
21844
21845 static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
21846 {
21847     uint32_t op;
21848     int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode));
21849     int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
21850     int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx->opcode));
21851     int offset;
21852     int imm;
21853
21854     /* make sure instructions are on a halfword boundary */
21855     if (ctx->base.pc_next & 0x1) {
21856         TCGv tmp = tcg_const_tl(ctx->base.pc_next);
21857         tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
21858         tcg_temp_free(tmp);
21859         generate_exception_end(ctx, EXCP_AdEL);
21860         return 2;
21861     }
21862
21863     op = extract32(ctx->opcode, 10, 6);
21864     switch (op) {
21865     case NM_P16_MV:
21866         rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21867         if (rt != 0) {
21868             /* MOVE */
21869             rs = NANOMIPS_EXTRACT_RS5(ctx->opcode);
21870             gen_arith(ctx, OPC_ADDU, rt, rs, 0);
21871         } else {
21872             /* P16.RI */
21873             switch (extract32(ctx->opcode, 3, 2)) {
21874             case NM_P16_SYSCALL:
21875                 if (extract32(ctx->opcode, 2, 1) == 0) {
21876                     generate_exception_end(ctx, EXCP_SYSCALL);
21877                 } else {
21878                     generate_exception_end(ctx, EXCP_RI);
21879                 }
21880                 break;
21881             case NM_BREAK16:
21882                 generate_exception_end(ctx, EXCP_BREAK);
21883                 break;
21884             case NM_SDBBP16:
21885                 if (is_uhi(extract32(ctx->opcode, 0, 3))) {
21886                     gen_helper_do_semihosting(cpu_env);
21887                 } else {
21888                     if (ctx->hflags & MIPS_HFLAG_SBRI) {
21889                         generate_exception_end(ctx, EXCP_RI);
21890                     } else {
21891                         generate_exception_end(ctx, EXCP_DBp);
21892                     }
21893                 }
21894                 break;
21895             default:
21896                 generate_exception_end(ctx, EXCP_RI);
21897                 break;
21898             }
21899         }
21900         break;
21901     case NM_P16_SHIFT:
21902         {
21903             int shift = extract32(ctx->opcode, 0, 3);
21904             uint32_t opc = 0;
21905             shift = (shift == 0) ? 8 : shift;
21906
21907             switch (extract32(ctx->opcode, 3, 1)) {
21908             case NM_SLL16:
21909                 opc = OPC_SLL;
21910                 break;
21911             case NM_SRL16:
21912                 opc = OPC_SRL;
21913                 break;
21914             }
21915             gen_shift_imm(ctx, opc, rt, rs, shift);
21916         }
21917         break;
21918     case NM_P16C:
21919         switch (ctx->opcode & 1) {
21920         case NM_POOL16C_0:
21921             gen_pool16c_nanomips_insn(ctx);
21922             break;
21923         case NM_LWXS16:
21924             gen_ldxs(ctx, rt, rs, rd);
21925             break;
21926         }
21927         break;
21928     case NM_P16_A1:
21929         switch (extract32(ctx->opcode, 6, 1)) {
21930         case NM_ADDIUR1SP:
21931             imm = extract32(ctx->opcode, 0, 6) << 2;
21932             gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm);
21933             break;
21934         default:
21935             generate_exception_end(ctx, EXCP_RI);
21936             break;
21937         }
21938         break;
21939     case NM_P16_A2:
21940         switch (extract32(ctx->opcode, 3, 1)) {
21941         case NM_ADDIUR2:
21942             imm = extract32(ctx->opcode, 0, 3) << 2;
21943             gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm);
21944             break;
21945         case NM_P_ADDIURS5:
21946             rt = extract32(ctx->opcode, 5, 5);
21947             if (rt != 0) {
21948                 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
21949                 imm = (sextract32(ctx->opcode, 4, 1) << 3) |
21950                       (extract32(ctx->opcode, 0, 3));
21951                 gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm);
21952             }
21953             break;
21954         }
21955         break;
21956     case NM_P16_ADDU:
21957         switch (ctx->opcode & 0x1) {
21958         case NM_ADDU16:
21959             gen_arith(ctx, OPC_ADDU, rd, rs, rt);
21960             break;
21961         case NM_SUBU16:
21962             gen_arith(ctx, OPC_SUBU, rd, rs, rt);
21963             break;
21964         }
21965         break;
21966     case NM_P16_4X4:
21967         rt = (extract32(ctx->opcode, 9, 1) << 3) |
21968               extract32(ctx->opcode, 5, 3);
21969         rs = (extract32(ctx->opcode, 4, 1) << 3) |
21970               extract32(ctx->opcode, 0, 3);
21971         rt = decode_gpr_gpr4(rt);
21972         rs = decode_gpr_gpr4(rs);
21973         switch ((extract32(ctx->opcode, 7, 2) & 0x2) |
21974                 (extract32(ctx->opcode, 3, 1))) {
21975         case NM_ADDU4X4:
21976             check_nms(ctx);
21977             gen_arith(ctx, OPC_ADDU, rt, rs, rt);
21978             break;
21979         case NM_MUL4X4:
21980             check_nms(ctx);
21981             gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt);
21982             break;
21983         default:
21984             generate_exception_end(ctx, EXCP_RI);
21985             break;
21986         }
21987         break;
21988     case NM_LI16:
21989         {
21990             int imm = extract32(ctx->opcode, 0, 7);
21991             imm = (imm == 0x7f ? -1 : imm);
21992             if (rt != 0) {
21993                 tcg_gen_movi_tl(cpu_gpr[rt], imm);
21994             }
21995         }
21996         break;
21997     case NM_ANDI16:
21998         {
21999             uint32_t u = extract32(ctx->opcode, 0, 4);
22000             u = (u == 12) ? 0xff :
22001                 (u == 13) ? 0xffff : u;
22002             gen_logic_imm(ctx, OPC_ANDI, rt, rs, u);
22003         }
22004         break;
22005     case NM_P16_LB:
22006         offset = extract32(ctx->opcode, 0, 2);
22007         switch (extract32(ctx->opcode, 2, 2)) {
22008         case NM_LB16:
22009             gen_ld(ctx, OPC_LB, rt, rs, offset);
22010             break;
22011         case NM_SB16:
22012             rt = decode_gpr_gpr3_src_store(
22013                      NANOMIPS_EXTRACT_RT3(ctx->opcode));
22014             gen_st(ctx, OPC_SB, rt, rs, offset);
22015             break;
22016         case NM_LBU16:
22017             gen_ld(ctx, OPC_LBU, rt, rs, offset);
22018             break;
22019         default:
22020             generate_exception_end(ctx, EXCP_RI);
22021             break;
22022         }
22023         break;
22024     case NM_P16_LH:
22025         offset = extract32(ctx->opcode, 1, 2) << 1;
22026         switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) {
22027         case NM_LH16:
22028             gen_ld(ctx, OPC_LH, rt, rs, offset);
22029             break;
22030         case NM_SH16:
22031             rt = decode_gpr_gpr3_src_store(
22032                      NANOMIPS_EXTRACT_RT3(ctx->opcode));
22033             gen_st(ctx, OPC_SH, rt, rs, offset);
22034             break;
22035         case NM_LHU16:
22036             gen_ld(ctx, OPC_LHU, rt, rs, offset);
22037             break;
22038         default:
22039             generate_exception_end(ctx, EXCP_RI);
22040             break;
22041         }
22042         break;
22043     case NM_LW16:
22044         offset = extract32(ctx->opcode, 0, 4) << 2;
22045         gen_ld(ctx, OPC_LW, rt, rs, offset);
22046         break;
22047     case NM_LWSP16:
22048         rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22049         offset = extract32(ctx->opcode, 0, 5) << 2;
22050         gen_ld(ctx, OPC_LW, rt, 29, offset);
22051         break;
22052     case NM_LW4X4:
22053         check_nms(ctx);
22054         rt = (extract32(ctx->opcode, 9, 1) << 3) |
22055              extract32(ctx->opcode, 5, 3);
22056         rs = (extract32(ctx->opcode, 4, 1) << 3) |
22057              extract32(ctx->opcode, 0, 3);
22058         offset = (extract32(ctx->opcode, 3, 1) << 3) |
22059                  (extract32(ctx->opcode, 8, 1) << 2);
22060         rt = decode_gpr_gpr4(rt);
22061         rs = decode_gpr_gpr4(rs);
22062         gen_ld(ctx, OPC_LW, rt, rs, offset);
22063         break;
22064     case NM_SW4X4:
22065         check_nms(ctx);
22066         rt = (extract32(ctx->opcode, 9, 1) << 3) |
22067              extract32(ctx->opcode, 5, 3);
22068         rs = (extract32(ctx->opcode, 4, 1) << 3) |
22069              extract32(ctx->opcode, 0, 3);
22070         offset = (extract32(ctx->opcode, 3, 1) << 3) |
22071                  (extract32(ctx->opcode, 8, 1) << 2);
22072         rt = decode_gpr_gpr4_zero(rt);
22073         rs = decode_gpr_gpr4(rs);
22074         gen_st(ctx, OPC_SW, rt, rs, offset);
22075         break;
22076     case NM_LWGP16:
22077         offset = extract32(ctx->opcode, 0, 7) << 2;
22078         gen_ld(ctx, OPC_LW, rt, 28, offset);
22079         break;
22080     case NM_SWSP16:
22081         rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22082         offset = extract32(ctx->opcode, 0, 5) << 2;
22083         gen_st(ctx, OPC_SW, rt, 29, offset);
22084         break;
22085     case NM_SW16:
22086         rt = decode_gpr_gpr3_src_store(
22087                  NANOMIPS_EXTRACT_RT3(ctx->opcode));
22088         rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
22089         offset = extract32(ctx->opcode, 0, 4) << 2;
22090         gen_st(ctx, OPC_SW, rt, rs, offset);
22091         break;
22092     case NM_SWGP16:
22093         rt = decode_gpr_gpr3_src_store(
22094                  NANOMIPS_EXTRACT_RT3(ctx->opcode));
22095         offset = extract32(ctx->opcode, 0, 7) << 2;
22096         gen_st(ctx, OPC_SW, rt, 28, offset);
22097         break;
22098     case NM_BC16:
22099         gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0,
22100                            (sextract32(ctx->opcode, 0, 1) << 10) |
22101                            (extract32(ctx->opcode, 1, 9) << 1));
22102         break;
22103     case NM_BALC16:
22104         gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0,
22105                            (sextract32(ctx->opcode, 0, 1) << 10) |
22106                            (extract32(ctx->opcode, 1, 9) << 1));
22107         break;
22108     case NM_BEQZC16:
22109         gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0,
22110                            (sextract32(ctx->opcode, 0, 1) << 7) |
22111                            (extract32(ctx->opcode, 1, 6) << 1));
22112         break;
22113     case NM_BNEZC16:
22114         gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0,
22115                            (sextract32(ctx->opcode, 0, 1) << 7) |
22116                            (extract32(ctx->opcode, 1, 6) << 1));
22117         break;
22118     case NM_P16_BR:
22119         switch (ctx->opcode & 0xf) {
22120         case 0:
22121             /* P16.JRC */
22122             switch (extract32(ctx->opcode, 4, 1)) {
22123             case NM_JRC:
22124                 gen_compute_branch_nm(ctx, OPC_JR, 2,
22125                                    extract32(ctx->opcode, 5, 5), 0, 0);
22126                 break;
22127             case NM_JALRC16:
22128                 gen_compute_branch_nm(ctx, OPC_JALR, 2,
22129                                    extract32(ctx->opcode, 5, 5), 31, 0);
22130                 break;
22131             }
22132             break;
22133         default:
22134             {
22135                 /* P16.BRI */
22136                 uint32_t opc = extract32(ctx->opcode, 4, 3) <
22137                                extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE;
22138                 gen_compute_branch_nm(ctx, opc, 2, rs, rt,
22139                                    extract32(ctx->opcode, 0, 4) << 1);
22140             }
22141             break;
22142         }
22143         break;
22144     case NM_P16_SR:
22145         {
22146             int count = extract32(ctx->opcode, 0, 4);
22147             int u = extract32(ctx->opcode, 4, 4) << 4;
22148
22149             rt = 30 + extract32(ctx->opcode, 9, 1);
22150             switch (extract32(ctx->opcode, 8, 1)) {
22151             case NM_SAVE16:
22152                 gen_save(ctx, rt, count, 0, u);
22153                 break;
22154             case NM_RESTORE_JRC16:
22155                 gen_restore(ctx, rt, count, 0, u);
22156                 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
22157                 break;
22158             }
22159         }
22160         break;
22161     case NM_MOVEP:
22162     case NM_MOVEPREV:
22163         check_nms(ctx);
22164         {
22165             static const int gpr2reg1[] = {4, 5, 6, 7};
22166             static const int gpr2reg2[] = {5, 6, 7, 8};
22167             int re;
22168             int rd2 = extract32(ctx->opcode, 3, 1) << 1 |
22169                       extract32(ctx->opcode, 8, 1);
22170             int r1 = gpr2reg1[rd2];
22171             int r2 = gpr2reg2[rd2];
22172             int r3 = extract32(ctx->opcode, 4, 1) << 3 |
22173                      extract32(ctx->opcode, 0, 3);
22174             int r4 = extract32(ctx->opcode, 9, 1) << 3 |
22175                      extract32(ctx->opcode, 5, 3);
22176             TCGv t0 = tcg_temp_new();
22177             TCGv t1 = tcg_temp_new();
22178             if (op == NM_MOVEP) {
22179                 rd = r1;
22180                 re = r2;
22181                 rs = decode_gpr_gpr4_zero(r3);
22182                 rt = decode_gpr_gpr4_zero(r4);
22183             } else {
22184                 rd = decode_gpr_gpr4(r3);
22185                 re = decode_gpr_gpr4(r4);
22186                 rs = r1;
22187                 rt = r2;
22188             }
22189             gen_load_gpr(t0, rs);
22190             gen_load_gpr(t1, rt);
22191             tcg_gen_mov_tl(cpu_gpr[rd], t0);
22192             tcg_gen_mov_tl(cpu_gpr[re], t1);
22193             tcg_temp_free(t0);
22194             tcg_temp_free(t1);
22195         }
22196         break;
22197     default:
22198         return decode_nanomips_32_48_opc(env, ctx);
22199     }
22200
22201     return 2;
22202 }
22203
22204
22205 /* SmartMIPS extension to MIPS32 */
22206
22207 #if defined(TARGET_MIPS64)
22208
22209 /* MDMX extension to MIPS64 */
22210
22211 #endif
22212
22213 /* MIPSDSP functions. */
22214 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
22215                            int rd, int base, int offset)
22216 {
22217     TCGv t0;
22218
22219     check_dsp(ctx);
22220     t0 = tcg_temp_new();
22221
22222     if (base == 0) {
22223         gen_load_gpr(t0, offset);
22224     } else if (offset == 0) {
22225         gen_load_gpr(t0, base);
22226     } else {
22227         gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
22228     }
22229
22230     switch (opc) {
22231     case OPC_LBUX:
22232         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
22233         gen_store_gpr(t0, rd);
22234         break;
22235     case OPC_LHX:
22236         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
22237         gen_store_gpr(t0, rd);
22238         break;
22239     case OPC_LWX:
22240         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
22241         gen_store_gpr(t0, rd);
22242         break;
22243 #if defined(TARGET_MIPS64)
22244     case OPC_LDX:
22245         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
22246         gen_store_gpr(t0, rd);
22247         break;
22248 #endif
22249     }
22250     tcg_temp_free(t0);
22251 }
22252
22253 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
22254                               int ret, int v1, int v2)
22255 {
22256     TCGv v1_t;
22257     TCGv v2_t;
22258
22259     if (ret == 0) {
22260         /* Treat as NOP. */
22261         return;
22262     }
22263
22264     v1_t = tcg_temp_new();
22265     v2_t = tcg_temp_new();
22266
22267     gen_load_gpr(v1_t, v1);
22268     gen_load_gpr(v2_t, v2);
22269
22270     switch (op1) {
22271     /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
22272     case OPC_MULT_G_2E:
22273         check_dsp_r2(ctx);
22274         switch (op2) {
22275         case OPC_ADDUH_QB:
22276             gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
22277             break;
22278         case OPC_ADDUH_R_QB:
22279             gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22280             break;
22281         case OPC_ADDQH_PH:
22282             gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
22283             break;
22284         case OPC_ADDQH_R_PH:
22285             gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22286             break;
22287         case OPC_ADDQH_W:
22288             gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
22289             break;
22290         case OPC_ADDQH_R_W:
22291             gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22292             break;
22293         case OPC_SUBUH_QB:
22294             gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
22295             break;
22296         case OPC_SUBUH_R_QB:
22297             gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22298             break;
22299         case OPC_SUBQH_PH:
22300             gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
22301             break;
22302         case OPC_SUBQH_R_PH:
22303             gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22304             break;
22305         case OPC_SUBQH_W:
22306             gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
22307             break;
22308         case OPC_SUBQH_R_W:
22309             gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22310             break;
22311         }
22312         break;
22313     case OPC_ABSQ_S_PH_DSP:
22314         switch (op2) {
22315         case OPC_ABSQ_S_QB:
22316             check_dsp_r2(ctx);
22317             gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
22318             break;
22319         case OPC_ABSQ_S_PH:
22320             check_dsp(ctx);
22321             gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
22322             break;
22323         case OPC_ABSQ_S_W:
22324             check_dsp(ctx);
22325             gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
22326             break;
22327         case OPC_PRECEQ_W_PHL:
22328             check_dsp(ctx);
22329             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
22330             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22331             break;
22332         case OPC_PRECEQ_W_PHR:
22333             check_dsp(ctx);
22334             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
22335             tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
22336             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22337             break;
22338         case OPC_PRECEQU_PH_QBL:
22339             check_dsp(ctx);
22340             gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
22341             break;
22342         case OPC_PRECEQU_PH_QBR:
22343             check_dsp(ctx);
22344             gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
22345             break;
22346         case OPC_PRECEQU_PH_QBLA:
22347             check_dsp(ctx);
22348             gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
22349             break;
22350         case OPC_PRECEQU_PH_QBRA:
22351             check_dsp(ctx);
22352             gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
22353             break;
22354         case OPC_PRECEU_PH_QBL:
22355             check_dsp(ctx);
22356             gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
22357             break;
22358         case OPC_PRECEU_PH_QBR:
22359             check_dsp(ctx);
22360             gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
22361             break;
22362         case OPC_PRECEU_PH_QBLA:
22363             check_dsp(ctx);
22364             gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
22365             break;
22366         case OPC_PRECEU_PH_QBRA:
22367             check_dsp(ctx);
22368             gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
22369             break;
22370         }
22371         break;
22372     case OPC_ADDU_QB_DSP:
22373         switch (op2) {
22374         case OPC_ADDQ_PH:
22375             check_dsp(ctx);
22376             gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22377             break;
22378         case OPC_ADDQ_S_PH:
22379             check_dsp(ctx);
22380             gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22381             break;
22382         case OPC_ADDQ_S_W:
22383             check_dsp(ctx);
22384             gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22385             break;
22386         case OPC_ADDU_QB:
22387             check_dsp(ctx);
22388             gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22389             break;
22390         case OPC_ADDU_S_QB:
22391             check_dsp(ctx);
22392             gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22393             break;
22394         case OPC_ADDU_PH:
22395             check_dsp_r2(ctx);
22396             gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22397             break;
22398         case OPC_ADDU_S_PH:
22399             check_dsp_r2(ctx);
22400             gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22401             break;
22402         case OPC_SUBQ_PH:
22403             check_dsp(ctx);
22404             gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22405             break;
22406         case OPC_SUBQ_S_PH:
22407             check_dsp(ctx);
22408             gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22409             break;
22410         case OPC_SUBQ_S_W:
22411             check_dsp(ctx);
22412             gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22413             break;
22414         case OPC_SUBU_QB:
22415             check_dsp(ctx);
22416             gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22417             break;
22418         case OPC_SUBU_S_QB:
22419             check_dsp(ctx);
22420             gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22421             break;
22422         case OPC_SUBU_PH:
22423             check_dsp_r2(ctx);
22424             gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22425             break;
22426         case OPC_SUBU_S_PH:
22427             check_dsp_r2(ctx);
22428             gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22429             break;
22430         case OPC_ADDSC:
22431             check_dsp(ctx);
22432             gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22433             break;
22434         case OPC_ADDWC:
22435             check_dsp(ctx);
22436             gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22437             break;
22438         case OPC_MODSUB:
22439             check_dsp(ctx);
22440             gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
22441             break;
22442         case OPC_RADDU_W_QB:
22443             check_dsp(ctx);
22444             gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
22445             break;
22446         }
22447         break;
22448     case OPC_CMPU_EQ_QB_DSP:
22449         switch (op2) {
22450         case OPC_PRECR_QB_PH:
22451             check_dsp_r2(ctx);
22452             gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22453             break;
22454         case OPC_PRECRQ_QB_PH:
22455             check_dsp(ctx);
22456             gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22457             break;
22458         case OPC_PRECR_SRA_PH_W:
22459             check_dsp_r2(ctx);
22460             {
22461                 TCGv_i32 sa_t = tcg_const_i32(v2);
22462                 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
22463                                           cpu_gpr[ret]);
22464                 tcg_temp_free_i32(sa_t);
22465                 break;
22466             }
22467         case OPC_PRECR_SRA_R_PH_W:
22468             check_dsp_r2(ctx);
22469             {
22470                 TCGv_i32 sa_t = tcg_const_i32(v2);
22471                 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
22472                                             cpu_gpr[ret]);
22473                 tcg_temp_free_i32(sa_t);
22474                 break;
22475             }
22476         case OPC_PRECRQ_PH_W:
22477             check_dsp(ctx);
22478             gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
22479             break;
22480         case OPC_PRECRQ_RS_PH_W:
22481             check_dsp(ctx);
22482             gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22483             break;
22484         case OPC_PRECRQU_S_QB_PH:
22485             check_dsp(ctx);
22486             gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22487             break;
22488         }
22489         break;
22490 #ifdef TARGET_MIPS64
22491     case OPC_ABSQ_S_QH_DSP:
22492         switch (op2) {
22493         case OPC_PRECEQ_L_PWL:
22494             check_dsp(ctx);
22495             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
22496             break;
22497         case OPC_PRECEQ_L_PWR:
22498             check_dsp(ctx);
22499             tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
22500             break;
22501         case OPC_PRECEQ_PW_QHL:
22502             check_dsp(ctx);
22503             gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
22504             break;
22505         case OPC_PRECEQ_PW_QHR:
22506             check_dsp(ctx);
22507             gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
22508             break;
22509         case OPC_PRECEQ_PW_QHLA:
22510             check_dsp(ctx);
22511             gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
22512             break;
22513         case OPC_PRECEQ_PW_QHRA:
22514             check_dsp(ctx);
22515             gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
22516             break;
22517         case OPC_PRECEQU_QH_OBL:
22518             check_dsp(ctx);
22519             gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
22520             break;
22521         case OPC_PRECEQU_QH_OBR:
22522             check_dsp(ctx);
22523             gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
22524             break;
22525         case OPC_PRECEQU_QH_OBLA:
22526             check_dsp(ctx);
22527             gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
22528             break;
22529         case OPC_PRECEQU_QH_OBRA:
22530             check_dsp(ctx);
22531             gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
22532             break;
22533         case OPC_PRECEU_QH_OBL:
22534             check_dsp(ctx);
22535             gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
22536             break;
22537         case OPC_PRECEU_QH_OBR:
22538             check_dsp(ctx);
22539             gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
22540             break;
22541         case OPC_PRECEU_QH_OBLA:
22542             check_dsp(ctx);
22543             gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
22544             break;
22545         case OPC_PRECEU_QH_OBRA:
22546             check_dsp(ctx);
22547             gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
22548             break;
22549         case OPC_ABSQ_S_OB:
22550             check_dsp_r2(ctx);
22551             gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
22552             break;
22553         case OPC_ABSQ_S_PW:
22554             check_dsp(ctx);
22555             gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
22556             break;
22557         case OPC_ABSQ_S_QH:
22558             check_dsp(ctx);
22559             gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
22560             break;
22561         }
22562         break;
22563     case OPC_ADDU_OB_DSP:
22564         switch (op2) {
22565         case OPC_RADDU_L_OB:
22566             check_dsp(ctx);
22567             gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
22568             break;
22569         case OPC_SUBQ_PW:
22570             check_dsp(ctx);
22571             gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22572             break;
22573         case OPC_SUBQ_S_PW:
22574             check_dsp(ctx);
22575             gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22576             break;
22577         case OPC_SUBQ_QH:
22578             check_dsp(ctx);
22579             gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22580             break;
22581         case OPC_SUBQ_S_QH:
22582             check_dsp(ctx);
22583             gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22584             break;
22585         case OPC_SUBU_OB:
22586             check_dsp(ctx);
22587             gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22588             break;
22589         case OPC_SUBU_S_OB:
22590             check_dsp(ctx);
22591             gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22592             break;
22593         case OPC_SUBU_QH:
22594             check_dsp_r2(ctx);
22595             gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22596             break;
22597         case OPC_SUBU_S_QH:
22598             check_dsp_r2(ctx);
22599             gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22600             break;
22601         case OPC_SUBUH_OB:
22602             check_dsp_r2(ctx);
22603             gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
22604             break;
22605         case OPC_SUBUH_R_OB:
22606             check_dsp_r2(ctx);
22607             gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22608             break;
22609         case OPC_ADDQ_PW:
22610             check_dsp(ctx);
22611             gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22612             break;
22613         case OPC_ADDQ_S_PW:
22614             check_dsp(ctx);
22615             gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22616             break;
22617         case OPC_ADDQ_QH:
22618             check_dsp(ctx);
22619             gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22620             break;
22621         case OPC_ADDQ_S_QH:
22622             check_dsp(ctx);
22623             gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22624             break;
22625         case OPC_ADDU_OB:
22626             check_dsp(ctx);
22627             gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22628             break;
22629         case OPC_ADDU_S_OB:
22630             check_dsp(ctx);
22631             gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22632             break;
22633         case OPC_ADDU_QH:
22634             check_dsp_r2(ctx);
22635             gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22636             break;
22637         case OPC_ADDU_S_QH:
22638             check_dsp_r2(ctx);
22639             gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22640             break;
22641         case OPC_ADDUH_OB:
22642             check_dsp_r2(ctx);
22643             gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
22644             break;
22645         case OPC_ADDUH_R_OB:
22646             check_dsp_r2(ctx);
22647             gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22648             break;
22649         }
22650         break;
22651     case OPC_CMPU_EQ_OB_DSP:
22652         switch (op2) {
22653         case OPC_PRECR_OB_QH:
22654             check_dsp_r2(ctx);
22655             gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22656             break;
22657         case OPC_PRECR_SRA_QH_PW:
22658             check_dsp_r2(ctx);
22659             {
22660                 TCGv_i32 ret_t = tcg_const_i32(ret);
22661                 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
22662                 tcg_temp_free_i32(ret_t);
22663                 break;
22664             }
22665         case OPC_PRECR_SRA_R_QH_PW:
22666             check_dsp_r2(ctx);
22667             {
22668                 TCGv_i32 sa_v = tcg_const_i32(ret);
22669                 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
22670                 tcg_temp_free_i32(sa_v);
22671                 break;
22672             }
22673         case OPC_PRECRQ_OB_QH:
22674             check_dsp(ctx);
22675             gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22676             break;
22677         case OPC_PRECRQ_PW_L:
22678             check_dsp(ctx);
22679             gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
22680             break;
22681         case OPC_PRECRQ_QH_PW:
22682             check_dsp(ctx);
22683             gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
22684             break;
22685         case OPC_PRECRQ_RS_QH_PW:
22686             check_dsp(ctx);
22687             gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22688             break;
22689         case OPC_PRECRQU_S_OB_QH:
22690             check_dsp(ctx);
22691             gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22692             break;
22693         }
22694         break;
22695 #endif
22696     }
22697
22698     tcg_temp_free(v1_t);
22699     tcg_temp_free(v2_t);
22700 }
22701
22702 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
22703                               int ret, int v1, int v2)
22704 {
22705     uint32_t op2;
22706     TCGv t0;
22707     TCGv v1_t;
22708     TCGv v2_t;
22709
22710     if (ret == 0) {
22711         /* Treat as NOP. */
22712         return;
22713     }
22714
22715     t0 = tcg_temp_new();
22716     v1_t = tcg_temp_new();
22717     v2_t = tcg_temp_new();
22718
22719     tcg_gen_movi_tl(t0, v1);
22720     gen_load_gpr(v1_t, v1);
22721     gen_load_gpr(v2_t, v2);
22722
22723     switch (opc) {
22724     case OPC_SHLL_QB_DSP:
22725         {
22726             op2 = MASK_SHLL_QB(ctx->opcode);
22727             switch (op2) {
22728             case OPC_SHLL_QB:
22729                 check_dsp(ctx);
22730                 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
22731                 break;
22732             case OPC_SHLLV_QB:
22733                 check_dsp(ctx);
22734                 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22735                 break;
22736             case OPC_SHLL_PH:
22737                 check_dsp(ctx);
22738                 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22739                 break;
22740             case OPC_SHLLV_PH:
22741                 check_dsp(ctx);
22742                 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22743                 break;
22744             case OPC_SHLL_S_PH:
22745                 check_dsp(ctx);
22746                 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22747                 break;
22748             case OPC_SHLLV_S_PH:
22749                 check_dsp(ctx);
22750                 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22751                 break;
22752             case OPC_SHLL_S_W:
22753                 check_dsp(ctx);
22754                 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
22755                 break;
22756             case OPC_SHLLV_S_W:
22757                 check_dsp(ctx);
22758                 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22759                 break;
22760             case OPC_SHRL_QB:
22761                 check_dsp(ctx);
22762                 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
22763                 break;
22764             case OPC_SHRLV_QB:
22765                 check_dsp(ctx);
22766                 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
22767                 break;
22768             case OPC_SHRL_PH:
22769                 check_dsp_r2(ctx);
22770                 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
22771                 break;
22772             case OPC_SHRLV_PH:
22773                 check_dsp_r2(ctx);
22774                 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
22775                 break;
22776             case OPC_SHRA_QB:
22777                 check_dsp_r2(ctx);
22778                 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
22779                 break;
22780             case OPC_SHRA_R_QB:
22781                 check_dsp_r2(ctx);
22782                 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
22783                 break;
22784             case OPC_SHRAV_QB:
22785                 check_dsp_r2(ctx);
22786                 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
22787                 break;
22788             case OPC_SHRAV_R_QB:
22789                 check_dsp_r2(ctx);
22790                 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
22791                 break;
22792             case OPC_SHRA_PH:
22793                 check_dsp(ctx);
22794                 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
22795                 break;
22796             case OPC_SHRA_R_PH:
22797                 check_dsp(ctx);
22798                 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
22799                 break;
22800             case OPC_SHRAV_PH:
22801                 check_dsp(ctx);
22802                 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
22803                 break;
22804             case OPC_SHRAV_R_PH:
22805                 check_dsp(ctx);
22806                 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
22807                 break;
22808             case OPC_SHRA_R_W:
22809                 check_dsp(ctx);
22810                 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
22811                 break;
22812             case OPC_SHRAV_R_W:
22813                 check_dsp(ctx);
22814                 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
22815                 break;
22816             default:            /* Invalid */
22817                 MIPS_INVAL("MASK SHLL.QB");
22818                 generate_exception_end(ctx, EXCP_RI);
22819                 break;
22820             }
22821             break;
22822         }
22823 #ifdef TARGET_MIPS64
22824     case OPC_SHLL_OB_DSP:
22825         op2 = MASK_SHLL_OB(ctx->opcode);
22826         switch (op2) {
22827         case OPC_SHLL_PW:
22828             check_dsp(ctx);
22829             gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22830             break;
22831         case OPC_SHLLV_PW:
22832             check_dsp(ctx);
22833             gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22834             break;
22835         case OPC_SHLL_S_PW:
22836             check_dsp(ctx);
22837             gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22838             break;
22839         case OPC_SHLLV_S_PW:
22840             check_dsp(ctx);
22841             gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22842             break;
22843         case OPC_SHLL_OB:
22844             check_dsp(ctx);
22845             gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
22846             break;
22847         case OPC_SHLLV_OB:
22848             check_dsp(ctx);
22849             gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22850             break;
22851         case OPC_SHLL_QH:
22852             check_dsp(ctx);
22853             gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
22854             break;
22855         case OPC_SHLLV_QH:
22856             check_dsp(ctx);
22857             gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22858             break;
22859         case OPC_SHLL_S_QH:
22860             check_dsp(ctx);
22861             gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
22862             break;
22863         case OPC_SHLLV_S_QH:
22864             check_dsp(ctx);
22865             gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22866             break;
22867         case OPC_SHRA_OB:
22868             check_dsp_r2(ctx);
22869             gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
22870             break;
22871         case OPC_SHRAV_OB:
22872             check_dsp_r2(ctx);
22873             gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
22874             break;
22875         case OPC_SHRA_R_OB:
22876             check_dsp_r2(ctx);
22877             gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
22878             break;
22879         case OPC_SHRAV_R_OB:
22880             check_dsp_r2(ctx);
22881             gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
22882             break;
22883         case OPC_SHRA_PW:
22884             check_dsp(ctx);
22885             gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
22886             break;
22887         case OPC_SHRAV_PW:
22888             check_dsp(ctx);
22889             gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
22890             break;
22891         case OPC_SHRA_R_PW:
22892             check_dsp(ctx);
22893             gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
22894             break;
22895         case OPC_SHRAV_R_PW:
22896             check_dsp(ctx);
22897             gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
22898             break;
22899         case OPC_SHRA_QH:
22900             check_dsp(ctx);
22901             gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
22902             break;
22903         case OPC_SHRAV_QH:
22904             check_dsp(ctx);
22905             gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
22906             break;
22907         case OPC_SHRA_R_QH:
22908             check_dsp(ctx);
22909             gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
22910             break;
22911         case OPC_SHRAV_R_QH:
22912             check_dsp(ctx);
22913             gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
22914             break;
22915         case OPC_SHRL_OB:
22916             check_dsp(ctx);
22917             gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
22918             break;
22919         case OPC_SHRLV_OB:
22920             check_dsp(ctx);
22921             gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
22922             break;
22923         case OPC_SHRL_QH:
22924             check_dsp_r2(ctx);
22925             gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
22926             break;
22927         case OPC_SHRLV_QH:
22928             check_dsp_r2(ctx);
22929             gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
22930             break;
22931         default:            /* Invalid */
22932             MIPS_INVAL("MASK SHLL.OB");
22933             generate_exception_end(ctx, EXCP_RI);
22934             break;
22935         }
22936         break;
22937 #endif
22938     }
22939
22940     tcg_temp_free(t0);
22941     tcg_temp_free(v1_t);
22942     tcg_temp_free(v2_t);
22943 }
22944
22945 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
22946                                  int ret, int v1, int v2, int check_ret)
22947 {
22948     TCGv_i32 t0;
22949     TCGv v1_t;
22950     TCGv v2_t;
22951
22952     if ((ret == 0) && (check_ret == 1)) {
22953         /* Treat as NOP. */
22954         return;
22955     }
22956
22957     t0 = tcg_temp_new_i32();
22958     v1_t = tcg_temp_new();
22959     v2_t = tcg_temp_new();
22960
22961     tcg_gen_movi_i32(t0, ret);
22962     gen_load_gpr(v1_t, v1);
22963     gen_load_gpr(v2_t, v2);
22964
22965     switch (op1) {
22966     /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
22967      * the same mask and op1. */
22968     case OPC_MULT_G_2E:
22969         check_dsp_r2(ctx);
22970         switch (op2) {
22971         case  OPC_MUL_PH:
22972             gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22973             break;
22974         case  OPC_MUL_S_PH:
22975             gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22976             break;
22977         case OPC_MULQ_S_W:
22978             gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22979             break;
22980         case OPC_MULQ_RS_W:
22981             gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22982             break;
22983         }
22984         break;
22985     case OPC_DPA_W_PH_DSP:
22986         switch (op2) {
22987         case OPC_DPAU_H_QBL:
22988             check_dsp(ctx);
22989             gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
22990             break;
22991         case OPC_DPAU_H_QBR:
22992             check_dsp(ctx);
22993             gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
22994             break;
22995         case OPC_DPSU_H_QBL:
22996             check_dsp(ctx);
22997             gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
22998             break;
22999         case OPC_DPSU_H_QBR:
23000             check_dsp(ctx);
23001             gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
23002             break;
23003         case OPC_DPA_W_PH:
23004             check_dsp_r2(ctx);
23005             gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
23006             break;
23007         case OPC_DPAX_W_PH:
23008             check_dsp_r2(ctx);
23009             gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
23010             break;
23011         case OPC_DPAQ_S_W_PH:
23012             check_dsp(ctx);
23013             gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23014             break;
23015         case OPC_DPAQX_S_W_PH:
23016             check_dsp_r2(ctx);
23017             gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
23018             break;
23019         case OPC_DPAQX_SA_W_PH:
23020             check_dsp_r2(ctx);
23021             gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
23022             break;
23023         case OPC_DPS_W_PH:
23024             check_dsp_r2(ctx);
23025             gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
23026             break;
23027         case OPC_DPSX_W_PH:
23028             check_dsp_r2(ctx);
23029             gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
23030             break;
23031         case OPC_DPSQ_S_W_PH:
23032             check_dsp(ctx);
23033             gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23034             break;
23035         case OPC_DPSQX_S_W_PH:
23036             check_dsp_r2(ctx);
23037             gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
23038             break;
23039         case OPC_DPSQX_SA_W_PH:
23040             check_dsp_r2(ctx);
23041             gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
23042             break;
23043         case OPC_MULSAQ_S_W_PH:
23044             check_dsp(ctx);
23045             gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23046             break;
23047         case OPC_DPAQ_SA_L_W:
23048             check_dsp(ctx);
23049             gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
23050             break;
23051         case OPC_DPSQ_SA_L_W:
23052             check_dsp(ctx);
23053             gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
23054             break;
23055         case OPC_MAQ_S_W_PHL:
23056             check_dsp(ctx);
23057             gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
23058             break;
23059         case OPC_MAQ_S_W_PHR:
23060             check_dsp(ctx);
23061             gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
23062             break;
23063         case OPC_MAQ_SA_W_PHL:
23064             check_dsp(ctx);
23065             gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
23066             break;
23067         case OPC_MAQ_SA_W_PHR:
23068             check_dsp(ctx);
23069             gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
23070             break;
23071         case OPC_MULSA_W_PH:
23072             check_dsp_r2(ctx);
23073             gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
23074             break;
23075         }
23076         break;
23077 #ifdef TARGET_MIPS64
23078     case OPC_DPAQ_W_QH_DSP:
23079         {
23080             int ac = ret & 0x03;
23081             tcg_gen_movi_i32(t0, ac);
23082
23083             switch (op2) {
23084             case OPC_DMADD:
23085                 check_dsp(ctx);
23086                 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
23087                 break;
23088             case OPC_DMADDU:
23089                 check_dsp(ctx);
23090                 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
23091                 break;
23092             case OPC_DMSUB:
23093                 check_dsp(ctx);
23094                 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
23095                 break;
23096             case OPC_DMSUBU:
23097                 check_dsp(ctx);
23098                 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
23099                 break;
23100             case OPC_DPA_W_QH:
23101                 check_dsp_r2(ctx);
23102                 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
23103                 break;
23104             case OPC_DPAQ_S_W_QH:
23105                 check_dsp(ctx);
23106                 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23107                 break;
23108             case OPC_DPAQ_SA_L_PW:
23109                 check_dsp(ctx);
23110                 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
23111                 break;
23112             case OPC_DPAU_H_OBL:
23113                 check_dsp(ctx);
23114                 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
23115                 break;
23116             case OPC_DPAU_H_OBR:
23117                 check_dsp(ctx);
23118                 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
23119                 break;
23120             case OPC_DPS_W_QH:
23121                 check_dsp_r2(ctx);
23122                 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
23123                 break;
23124             case OPC_DPSQ_S_W_QH:
23125                 check_dsp(ctx);
23126                 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23127                 break;
23128             case OPC_DPSQ_SA_L_PW:
23129                 check_dsp(ctx);
23130                 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
23131                 break;
23132             case OPC_DPSU_H_OBL:
23133                 check_dsp(ctx);
23134                 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
23135                 break;
23136             case OPC_DPSU_H_OBR:
23137                 check_dsp(ctx);
23138                 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
23139                 break;
23140             case OPC_MAQ_S_L_PWL:
23141                 check_dsp(ctx);
23142                 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
23143                 break;
23144             case OPC_MAQ_S_L_PWR:
23145                 check_dsp(ctx);
23146                 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
23147                 break;
23148             case OPC_MAQ_S_W_QHLL:
23149                 check_dsp(ctx);
23150                 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
23151                 break;
23152             case OPC_MAQ_SA_W_QHLL:
23153                 check_dsp(ctx);
23154                 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
23155                 break;
23156             case OPC_MAQ_S_W_QHLR:
23157                 check_dsp(ctx);
23158                 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
23159                 break;
23160             case OPC_MAQ_SA_W_QHLR:
23161                 check_dsp(ctx);
23162                 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
23163                 break;
23164             case OPC_MAQ_S_W_QHRL:
23165                 check_dsp(ctx);
23166                 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
23167                 break;
23168             case OPC_MAQ_SA_W_QHRL:
23169                 check_dsp(ctx);
23170                 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
23171                 break;
23172             case OPC_MAQ_S_W_QHRR:
23173                 check_dsp(ctx);
23174                 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
23175                 break;
23176             case OPC_MAQ_SA_W_QHRR:
23177                 check_dsp(ctx);
23178                 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
23179                 break;
23180             case OPC_MULSAQ_S_L_PW:
23181                 check_dsp(ctx);
23182                 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
23183                 break;
23184             case OPC_MULSAQ_S_W_QH:
23185                 check_dsp(ctx);
23186                 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23187                 break;
23188             }
23189         }
23190         break;
23191 #endif
23192     case OPC_ADDU_QB_DSP:
23193         switch (op2) {
23194         case OPC_MULEU_S_PH_QBL:
23195             check_dsp(ctx);
23196             gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23197             break;
23198         case OPC_MULEU_S_PH_QBR:
23199             check_dsp(ctx);
23200             gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23201             break;
23202         case OPC_MULQ_RS_PH:
23203             check_dsp(ctx);
23204             gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23205             break;
23206         case OPC_MULEQ_S_W_PHL:
23207             check_dsp(ctx);
23208             gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23209             break;
23210         case OPC_MULEQ_S_W_PHR:
23211             check_dsp(ctx);
23212             gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23213             break;
23214         case OPC_MULQ_S_PH:
23215             check_dsp_r2(ctx);
23216             gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23217             break;
23218         }
23219         break;
23220 #ifdef TARGET_MIPS64
23221     case OPC_ADDU_OB_DSP:
23222         switch (op2) {
23223         case OPC_MULEQ_S_PW_QHL:
23224             check_dsp(ctx);
23225             gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23226             break;
23227         case OPC_MULEQ_S_PW_QHR:
23228             check_dsp(ctx);
23229             gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23230             break;
23231         case OPC_MULEU_S_QH_OBL:
23232             check_dsp(ctx);
23233             gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23234             break;
23235         case OPC_MULEU_S_QH_OBR:
23236             check_dsp(ctx);
23237             gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23238             break;
23239         case OPC_MULQ_RS_QH:
23240             check_dsp(ctx);
23241             gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23242             break;
23243         }
23244         break;
23245 #endif
23246     }
23247
23248     tcg_temp_free_i32(t0);
23249     tcg_temp_free(v1_t);
23250     tcg_temp_free(v2_t);
23251 }
23252
23253 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
23254                                 int ret, int val)
23255 {
23256     int16_t imm;
23257     TCGv t0;
23258     TCGv val_t;
23259
23260     if (ret == 0) {
23261         /* Treat as NOP. */
23262         return;
23263     }
23264
23265     t0 = tcg_temp_new();
23266     val_t = tcg_temp_new();
23267     gen_load_gpr(val_t, val);
23268
23269     switch (op1) {
23270     case OPC_ABSQ_S_PH_DSP:
23271         switch (op2) {
23272         case OPC_BITREV:
23273             check_dsp(ctx);
23274             gen_helper_bitrev(cpu_gpr[ret], val_t);
23275             break;
23276         case OPC_REPL_QB:
23277             check_dsp(ctx);
23278             {
23279                 target_long result;
23280                 imm = (ctx->opcode >> 16) & 0xFF;
23281                 result = (uint32_t)imm << 24 |
23282                          (uint32_t)imm << 16 |
23283                          (uint32_t)imm << 8  |
23284                          (uint32_t)imm;
23285                 result = (int32_t)result;
23286                 tcg_gen_movi_tl(cpu_gpr[ret], result);
23287             }
23288             break;
23289         case OPC_REPLV_QB:
23290             check_dsp(ctx);
23291             tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23292             tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23293             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23294             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23295             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23296             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23297             break;
23298         case OPC_REPL_PH:
23299             check_dsp(ctx);
23300             {
23301                 imm = (ctx->opcode >> 16) & 0x03FF;
23302                 imm = (int16_t)(imm << 6) >> 6;
23303                 tcg_gen_movi_tl(cpu_gpr[ret], \
23304                                 (target_long)((int32_t)imm << 16 | \
23305                                 (uint16_t)imm));
23306             }
23307             break;
23308         case OPC_REPLV_PH:
23309             check_dsp(ctx);
23310             tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23311             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23312             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23313             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23314             break;
23315         }
23316         break;
23317 #ifdef TARGET_MIPS64
23318     case OPC_ABSQ_S_QH_DSP:
23319         switch (op2) {
23320         case OPC_REPL_OB:
23321             check_dsp(ctx);
23322             {
23323                 target_long temp;
23324
23325                 imm = (ctx->opcode >> 16) & 0xFF;
23326                 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
23327                 temp = (temp << 16) | temp;
23328                 temp = (temp << 32) | temp;
23329                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23330                 break;
23331             }
23332         case OPC_REPL_PW:
23333             check_dsp(ctx);
23334             {
23335                 target_long temp;
23336
23337                 imm = (ctx->opcode >> 16) & 0x03FF;
23338                 imm = (int16_t)(imm << 6) >> 6;
23339                 temp = ((target_long)imm << 32) \
23340                        | ((target_long)imm & 0xFFFFFFFF);
23341                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23342                 break;
23343             }
23344         case OPC_REPL_QH:
23345             check_dsp(ctx);
23346             {
23347                 target_long temp;
23348
23349                 imm = (ctx->opcode >> 16) & 0x03FF;
23350                 imm = (int16_t)(imm << 6) >> 6;
23351
23352                 temp = ((uint64_t)(uint16_t)imm << 48) |
23353                        ((uint64_t)(uint16_t)imm << 32) |
23354                        ((uint64_t)(uint16_t)imm << 16) |
23355                        (uint64_t)(uint16_t)imm;
23356                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23357                 break;
23358             }
23359         case OPC_REPLV_OB:
23360             check_dsp(ctx);
23361             tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23362             tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23363             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23364             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23365             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23366             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23367             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23368             break;
23369         case OPC_REPLV_PW:
23370             check_dsp(ctx);
23371             tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
23372             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23373             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23374             break;
23375         case OPC_REPLV_QH:
23376             check_dsp(ctx);
23377             tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23378             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23379             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23380             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23381             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23382             break;
23383         }
23384         break;
23385 #endif
23386     }
23387     tcg_temp_free(t0);
23388     tcg_temp_free(val_t);
23389 }
23390
23391 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
23392                                      uint32_t op1, uint32_t op2,
23393                                      int ret, int v1, int v2, int check_ret)
23394 {
23395     TCGv t1;
23396     TCGv v1_t;
23397     TCGv v2_t;
23398
23399     if ((ret == 0) && (check_ret == 1)) {
23400         /* Treat as NOP. */
23401         return;
23402     }
23403
23404     t1 = tcg_temp_new();
23405     v1_t = tcg_temp_new();
23406     v2_t = tcg_temp_new();
23407
23408     gen_load_gpr(v1_t, v1);
23409     gen_load_gpr(v2_t, v2);
23410
23411     switch (op1) {
23412     case OPC_CMPU_EQ_QB_DSP:
23413         switch (op2) {
23414         case OPC_CMPU_EQ_QB:
23415             check_dsp(ctx);
23416             gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
23417             break;
23418         case OPC_CMPU_LT_QB:
23419             check_dsp(ctx);
23420             gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
23421             break;
23422         case OPC_CMPU_LE_QB:
23423             check_dsp(ctx);
23424             gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
23425             break;
23426         case OPC_CMPGU_EQ_QB:
23427             check_dsp(ctx);
23428             gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
23429             break;
23430         case OPC_CMPGU_LT_QB:
23431             check_dsp(ctx);
23432             gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
23433             break;
23434         case OPC_CMPGU_LE_QB:
23435             check_dsp(ctx);
23436             gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
23437             break;
23438         case OPC_CMPGDU_EQ_QB:
23439             check_dsp_r2(ctx);
23440             gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
23441             tcg_gen_mov_tl(cpu_gpr[ret], t1);
23442             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23443             tcg_gen_shli_tl(t1, t1, 24);
23444             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23445             break;
23446         case OPC_CMPGDU_LT_QB:
23447             check_dsp_r2(ctx);
23448             gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
23449             tcg_gen_mov_tl(cpu_gpr[ret], t1);
23450             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23451             tcg_gen_shli_tl(t1, t1, 24);
23452             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23453             break;
23454         case OPC_CMPGDU_LE_QB:
23455             check_dsp_r2(ctx);
23456             gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
23457             tcg_gen_mov_tl(cpu_gpr[ret], t1);
23458             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23459             tcg_gen_shli_tl(t1, t1, 24);
23460             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23461             break;
23462         case OPC_CMP_EQ_PH:
23463             check_dsp(ctx);
23464             gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
23465             break;
23466         case OPC_CMP_LT_PH:
23467             check_dsp(ctx);
23468             gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
23469             break;
23470         case OPC_CMP_LE_PH:
23471             check_dsp(ctx);
23472             gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
23473             break;
23474         case OPC_PICK_QB:
23475             check_dsp(ctx);
23476             gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23477             break;
23478         case OPC_PICK_PH:
23479             check_dsp(ctx);
23480             gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23481             break;
23482         case OPC_PACKRL_PH:
23483             check_dsp(ctx);
23484             gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
23485             break;
23486         }
23487         break;
23488 #ifdef TARGET_MIPS64
23489     case OPC_CMPU_EQ_OB_DSP:
23490         switch (op2) {
23491         case OPC_CMP_EQ_PW:
23492             check_dsp(ctx);
23493             gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
23494             break;
23495         case OPC_CMP_LT_PW:
23496             check_dsp(ctx);
23497             gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
23498             break;
23499         case OPC_CMP_LE_PW:
23500             check_dsp(ctx);
23501             gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
23502             break;
23503         case OPC_CMP_EQ_QH:
23504             check_dsp(ctx);
23505             gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
23506             break;
23507         case OPC_CMP_LT_QH:
23508             check_dsp(ctx);
23509             gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
23510             break;
23511         case OPC_CMP_LE_QH:
23512             check_dsp(ctx);
23513             gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
23514             break;
23515         case OPC_CMPGDU_EQ_OB:
23516             check_dsp_r2(ctx);
23517             gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23518             break;
23519         case OPC_CMPGDU_LT_OB:
23520             check_dsp_r2(ctx);
23521             gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23522             break;
23523         case OPC_CMPGDU_LE_OB:
23524             check_dsp_r2(ctx);
23525             gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23526             break;
23527         case OPC_CMPGU_EQ_OB:
23528             check_dsp(ctx);
23529             gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
23530             break;
23531         case OPC_CMPGU_LT_OB:
23532             check_dsp(ctx);
23533             gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
23534             break;
23535         case OPC_CMPGU_LE_OB:
23536             check_dsp(ctx);
23537             gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
23538             break;
23539         case OPC_CMPU_EQ_OB:
23540             check_dsp(ctx);
23541             gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
23542             break;
23543         case OPC_CMPU_LT_OB:
23544             check_dsp(ctx);
23545             gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
23546             break;
23547         case OPC_CMPU_LE_OB:
23548             check_dsp(ctx);
23549             gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
23550             break;
23551         case OPC_PACKRL_PW:
23552             check_dsp(ctx);
23553             gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
23554             break;
23555         case OPC_PICK_OB:
23556             check_dsp(ctx);
23557             gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23558             break;
23559         case OPC_PICK_PW:
23560             check_dsp(ctx);
23561             gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23562             break;
23563         case OPC_PICK_QH:
23564             check_dsp(ctx);
23565             gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23566             break;
23567         }
23568         break;
23569 #endif
23570     }
23571
23572     tcg_temp_free(t1);
23573     tcg_temp_free(v1_t);
23574     tcg_temp_free(v2_t);
23575 }
23576
23577 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
23578                                uint32_t op1, int rt, int rs, int sa)
23579 {
23580     TCGv t0;
23581
23582     check_dsp_r2(ctx);
23583
23584     if (rt == 0) {
23585         /* Treat as NOP. */
23586         return;
23587     }
23588
23589     t0 = tcg_temp_new();
23590     gen_load_gpr(t0, rs);
23591
23592     switch (op1) {
23593     case OPC_APPEND_DSP:
23594         switch (MASK_APPEND(ctx->opcode)) {
23595         case OPC_APPEND:
23596             if (sa != 0) {
23597                 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
23598             }
23599             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23600             break;
23601         case OPC_PREPEND:
23602             if (sa != 0) {
23603                 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
23604                 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23605                 tcg_gen_shli_tl(t0, t0, 32 - sa);
23606                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23607             }
23608             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23609             break;
23610         case OPC_BALIGN:
23611             sa &= 3;
23612             if (sa != 0 && sa != 2) {
23613                 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23614                 tcg_gen_ext32u_tl(t0, t0);
23615                 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
23616                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23617             }
23618             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23619             break;
23620         default:            /* Invalid */
23621             MIPS_INVAL("MASK APPEND");
23622             generate_exception_end(ctx, EXCP_RI);
23623             break;
23624         }
23625         break;
23626 #ifdef TARGET_MIPS64
23627     case OPC_DAPPEND_DSP:
23628         switch (MASK_DAPPEND(ctx->opcode)) {
23629         case OPC_DAPPEND:
23630             if (sa != 0) {
23631                 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
23632             }
23633             break;
23634         case OPC_PREPENDD:
23635             tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
23636             tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
23637             tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
23638             break;
23639         case OPC_PREPENDW:
23640             if (sa != 0) {
23641                 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23642                 tcg_gen_shli_tl(t0, t0, 64 - sa);
23643                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23644             }
23645             break;
23646         case OPC_DBALIGN:
23647             sa &= 7;
23648             if (sa != 0 && sa != 2 && sa != 4) {
23649                 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23650                 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
23651                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23652             }
23653             break;
23654         default:            /* Invalid */
23655             MIPS_INVAL("MASK DAPPEND");
23656             generate_exception_end(ctx, EXCP_RI);
23657             break;
23658         }
23659         break;
23660 #endif
23661     }
23662     tcg_temp_free(t0);
23663 }
23664
23665 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
23666                                 int ret, int v1, int v2, int check_ret)
23667
23668 {
23669     TCGv t0;
23670     TCGv t1;
23671     TCGv v1_t;
23672     TCGv v2_t;
23673     int16_t imm;
23674
23675     if ((ret == 0) && (check_ret == 1)) {
23676         /* Treat as NOP. */
23677         return;
23678     }
23679
23680     t0 = tcg_temp_new();
23681     t1 = tcg_temp_new();
23682     v1_t = tcg_temp_new();
23683     v2_t = tcg_temp_new();
23684
23685     gen_load_gpr(v1_t, v1);
23686     gen_load_gpr(v2_t, v2);
23687
23688     switch (op1) {
23689     case OPC_EXTR_W_DSP:
23690         check_dsp(ctx);
23691         switch (op2) {
23692         case OPC_EXTR_W:
23693             tcg_gen_movi_tl(t0, v2);
23694             tcg_gen_movi_tl(t1, v1);
23695             gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
23696             break;
23697         case OPC_EXTR_R_W:
23698             tcg_gen_movi_tl(t0, v2);
23699             tcg_gen_movi_tl(t1, v1);
23700             gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23701             break;
23702         case OPC_EXTR_RS_W:
23703             tcg_gen_movi_tl(t0, v2);
23704             tcg_gen_movi_tl(t1, v1);
23705             gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23706             break;
23707         case OPC_EXTR_S_H:
23708             tcg_gen_movi_tl(t0, v2);
23709             tcg_gen_movi_tl(t1, v1);
23710             gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23711             break;
23712         case OPC_EXTRV_S_H:
23713             tcg_gen_movi_tl(t0, v2);
23714             gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
23715             break;
23716         case OPC_EXTRV_W:
23717             tcg_gen_movi_tl(t0, v2);
23718             gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23719             break;
23720         case OPC_EXTRV_R_W:
23721             tcg_gen_movi_tl(t0, v2);
23722             gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23723             break;
23724         case OPC_EXTRV_RS_W:
23725             tcg_gen_movi_tl(t0, v2);
23726             gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23727             break;
23728         case OPC_EXTP:
23729             tcg_gen_movi_tl(t0, v2);
23730             tcg_gen_movi_tl(t1, v1);
23731             gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
23732             break;
23733         case OPC_EXTPV:
23734             tcg_gen_movi_tl(t0, v2);
23735             gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
23736             break;
23737         case OPC_EXTPDP:
23738             tcg_gen_movi_tl(t0, v2);
23739             tcg_gen_movi_tl(t1, v1);
23740             gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
23741             break;
23742         case OPC_EXTPDPV:
23743             tcg_gen_movi_tl(t0, v2);
23744             gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23745             break;
23746         case OPC_SHILO:
23747             imm = (ctx->opcode >> 20) & 0x3F;
23748             tcg_gen_movi_tl(t0, ret);
23749             tcg_gen_movi_tl(t1, imm);
23750             gen_helper_shilo(t0, t1, cpu_env);
23751             break;
23752         case OPC_SHILOV:
23753             tcg_gen_movi_tl(t0, ret);
23754             gen_helper_shilo(t0, v1_t, cpu_env);
23755             break;
23756         case OPC_MTHLIP:
23757             tcg_gen_movi_tl(t0, ret);
23758             gen_helper_mthlip(t0, v1_t, cpu_env);
23759             break;
23760         case OPC_WRDSP:
23761             imm = (ctx->opcode >> 11) & 0x3FF;
23762             tcg_gen_movi_tl(t0, imm);
23763             gen_helper_wrdsp(v1_t, t0, cpu_env);
23764             break;
23765         case OPC_RDDSP:
23766             imm = (ctx->opcode >> 16) & 0x03FF;
23767             tcg_gen_movi_tl(t0, imm);
23768             gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
23769             break;
23770         }
23771         break;
23772 #ifdef TARGET_MIPS64
23773     case OPC_DEXTR_W_DSP:
23774         check_dsp(ctx);
23775         switch (op2) {
23776         case OPC_DMTHLIP:
23777             tcg_gen_movi_tl(t0, ret);
23778             gen_helper_dmthlip(v1_t, t0, cpu_env);
23779             break;
23780         case OPC_DSHILO:
23781             {
23782                 int shift = (ctx->opcode >> 19) & 0x7F;
23783                 int ac = (ctx->opcode >> 11) & 0x03;
23784                 tcg_gen_movi_tl(t0, shift);
23785                 tcg_gen_movi_tl(t1, ac);
23786                 gen_helper_dshilo(t0, t1, cpu_env);
23787                 break;
23788             }
23789         case OPC_DSHILOV:
23790             {
23791                 int ac = (ctx->opcode >> 11) & 0x03;
23792                 tcg_gen_movi_tl(t0, ac);
23793                 gen_helper_dshilo(v1_t, t0, cpu_env);
23794                 break;
23795             }
23796         case OPC_DEXTP:
23797             tcg_gen_movi_tl(t0, v2);
23798             tcg_gen_movi_tl(t1, v1);
23799
23800             gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
23801             break;
23802         case OPC_DEXTPV:
23803             tcg_gen_movi_tl(t0, v2);
23804             gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
23805             break;
23806         case OPC_DEXTPDP:
23807             tcg_gen_movi_tl(t0, v2);
23808             tcg_gen_movi_tl(t1, v1);
23809             gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
23810             break;
23811         case OPC_DEXTPDPV:
23812             tcg_gen_movi_tl(t0, v2);
23813             gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23814             break;
23815         case OPC_DEXTR_L:
23816             tcg_gen_movi_tl(t0, v2);
23817             tcg_gen_movi_tl(t1, v1);
23818             gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
23819             break;
23820         case OPC_DEXTR_R_L:
23821             tcg_gen_movi_tl(t0, v2);
23822             tcg_gen_movi_tl(t1, v1);
23823             gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
23824             break;
23825         case OPC_DEXTR_RS_L:
23826             tcg_gen_movi_tl(t0, v2);
23827             tcg_gen_movi_tl(t1, v1);
23828             gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
23829             break;
23830         case OPC_DEXTR_W:
23831             tcg_gen_movi_tl(t0, v2);
23832             tcg_gen_movi_tl(t1, v1);
23833             gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
23834             break;
23835         case OPC_DEXTR_R_W:
23836             tcg_gen_movi_tl(t0, v2);
23837             tcg_gen_movi_tl(t1, v1);
23838             gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23839             break;
23840         case OPC_DEXTR_RS_W:
23841             tcg_gen_movi_tl(t0, v2);
23842             tcg_gen_movi_tl(t1, v1);
23843             gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23844             break;
23845         case OPC_DEXTR_S_H:
23846             tcg_gen_movi_tl(t0, v2);
23847             tcg_gen_movi_tl(t1, v1);
23848             gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23849             break;
23850         case OPC_DEXTRV_S_H:
23851             tcg_gen_movi_tl(t0, v2);
23852             tcg_gen_movi_tl(t1, v1);
23853             gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23854             break;
23855         case OPC_DEXTRV_L:
23856             tcg_gen_movi_tl(t0, v2);
23857             gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23858             break;
23859         case OPC_DEXTRV_R_L:
23860             tcg_gen_movi_tl(t0, v2);
23861             gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23862             break;
23863         case OPC_DEXTRV_RS_L:
23864             tcg_gen_movi_tl(t0, v2);
23865             gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23866             break;
23867         case OPC_DEXTRV_W:
23868             tcg_gen_movi_tl(t0, v2);
23869             gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23870             break;
23871         case OPC_DEXTRV_R_W:
23872             tcg_gen_movi_tl(t0, v2);
23873             gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23874             break;
23875         case OPC_DEXTRV_RS_W:
23876             tcg_gen_movi_tl(t0, v2);
23877             gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23878             break;
23879         }
23880         break;
23881 #endif
23882     }
23883
23884     tcg_temp_free(t0);
23885     tcg_temp_free(t1);
23886     tcg_temp_free(v1_t);
23887     tcg_temp_free(v2_t);
23888 }
23889
23890 /* End MIPSDSP functions. */
23891
23892 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
23893 {
23894     int rs, rt, rd, sa;
23895     uint32_t op1, op2;
23896
23897     rs = (ctx->opcode >> 21) & 0x1f;
23898     rt = (ctx->opcode >> 16) & 0x1f;
23899     rd = (ctx->opcode >> 11) & 0x1f;
23900     sa = (ctx->opcode >> 6) & 0x1f;
23901
23902     op1 = MASK_SPECIAL(ctx->opcode);
23903     switch (op1) {
23904     case OPC_LSA:
23905         gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
23906         break;
23907     case OPC_MULT:
23908     case OPC_MULTU:
23909     case OPC_DIV:
23910     case OPC_DIVU:
23911         op2 = MASK_R6_MULDIV(ctx->opcode);
23912         switch (op2) {
23913         case R6_OPC_MUL:
23914         case R6_OPC_MUH:
23915         case R6_OPC_MULU:
23916         case R6_OPC_MUHU:
23917         case R6_OPC_DIV:
23918         case R6_OPC_MOD:
23919         case R6_OPC_DIVU:
23920         case R6_OPC_MODU:
23921             gen_r6_muldiv(ctx, op2, rd, rs, rt);
23922             break;
23923         default:
23924             MIPS_INVAL("special_r6 muldiv");
23925             generate_exception_end(ctx, EXCP_RI);
23926             break;
23927         }
23928         break;
23929     case OPC_SELEQZ:
23930     case OPC_SELNEZ:
23931         gen_cond_move(ctx, op1, rd, rs, rt);
23932         break;
23933     case R6_OPC_CLO:
23934     case R6_OPC_CLZ:
23935         if (rt == 0 && sa == 1) {
23936             /* Major opcode and function field is shared with preR6 MFHI/MTHI.
23937                We need additionally to check other fields */
23938             gen_cl(ctx, op1, rd, rs);
23939         } else {
23940             generate_exception_end(ctx, EXCP_RI);
23941         }
23942         break;
23943     case R6_OPC_SDBBP:
23944         if (is_uhi(extract32(ctx->opcode, 6, 20))) {
23945             gen_helper_do_semihosting(cpu_env);
23946         } else {
23947             if (ctx->hflags & MIPS_HFLAG_SBRI) {
23948                 generate_exception_end(ctx, EXCP_RI);
23949             } else {
23950                 generate_exception_end(ctx, EXCP_DBp);
23951             }
23952         }
23953         break;
23954 #if defined(TARGET_MIPS64)
23955     case OPC_DLSA:
23956         check_mips_64(ctx);
23957         gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
23958         break;
23959     case R6_OPC_DCLO:
23960     case R6_OPC_DCLZ:
23961         if (rt == 0 && sa == 1) {
23962             /* Major opcode and function field is shared with preR6 MFHI/MTHI.
23963                We need additionally to check other fields */
23964             check_mips_64(ctx);
23965             gen_cl(ctx, op1, rd, rs);
23966         } else {
23967             generate_exception_end(ctx, EXCP_RI);
23968         }
23969         break;
23970     case OPC_DMULT:
23971     case OPC_DMULTU:
23972     case OPC_DDIV:
23973     case OPC_DDIVU:
23974
23975         op2 = MASK_R6_MULDIV(ctx->opcode);
23976         switch (op2) {
23977         case R6_OPC_DMUL:
23978         case R6_OPC_DMUH:
23979         case R6_OPC_DMULU:
23980         case R6_OPC_DMUHU:
23981         case R6_OPC_DDIV:
23982         case R6_OPC_DMOD:
23983         case R6_OPC_DDIVU:
23984         case R6_OPC_DMODU:
23985             check_mips_64(ctx);
23986             gen_r6_muldiv(ctx, op2, rd, rs, rt);
23987             break;
23988         default:
23989             MIPS_INVAL("special_r6 muldiv");
23990             generate_exception_end(ctx, EXCP_RI);
23991             break;
23992         }
23993         break;
23994 #endif
23995     default:            /* Invalid */
23996         MIPS_INVAL("special_r6");
23997         generate_exception_end(ctx, EXCP_RI);
23998         break;
23999     }
24000 }
24001
24002 static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx)
24003 {
24004     int rs = extract32(ctx->opcode, 21, 5);
24005     int rt = extract32(ctx->opcode, 16, 5);
24006     int rd = extract32(ctx->opcode, 11, 5);
24007     uint32_t op1 = MASK_SPECIAL(ctx->opcode);
24008
24009     switch (op1) {
24010     case OPC_MOVN:         /* Conditional move */
24011     case OPC_MOVZ:
24012         gen_cond_move(ctx, op1, rd, rs, rt);
24013         break;
24014     case OPC_MFHI:          /* Move from HI/LO */
24015     case OPC_MFLO:
24016         gen_HILO(ctx, op1, 0, rd);
24017         break;
24018     case OPC_MTHI:
24019     case OPC_MTLO:          /* Move to HI/LO */
24020         gen_HILO(ctx, op1, 0, rs);
24021         break;
24022     case OPC_MULT:
24023     case OPC_MULTU:
24024         gen_mul_txx9(ctx, op1, rd, rs, rt);
24025         break;
24026     case OPC_DIV:
24027     case OPC_DIVU:
24028         gen_muldiv(ctx, op1, 0, rs, rt);
24029         break;
24030 #if defined(TARGET_MIPS64)
24031     case OPC_DMULT:
24032     case OPC_DMULTU:
24033     case OPC_DDIV:
24034     case OPC_DDIVU:
24035         check_insn_opc_user_only(ctx, INSN_R5900);
24036         gen_muldiv(ctx, op1, 0, rs, rt);
24037         break;
24038 #endif
24039     case OPC_JR:
24040         gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
24041         break;
24042     default:            /* Invalid */
24043         MIPS_INVAL("special_tx79");
24044         generate_exception_end(ctx, EXCP_RI);
24045         break;
24046     }
24047 }
24048
24049 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
24050 {
24051     int rs, rt, rd, sa;
24052     uint32_t op1;
24053
24054     rs = (ctx->opcode >> 21) & 0x1f;
24055     rt = (ctx->opcode >> 16) & 0x1f;
24056     rd = (ctx->opcode >> 11) & 0x1f;
24057     sa = (ctx->opcode >> 6) & 0x1f;
24058
24059     op1 = MASK_SPECIAL(ctx->opcode);
24060     switch (op1) {
24061     case OPC_MOVN:         /* Conditional move */
24062     case OPC_MOVZ:
24063         check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
24064                    INSN_LOONGSON2E | INSN_LOONGSON2F);
24065         gen_cond_move(ctx, op1, rd, rs, rt);
24066         break;
24067     case OPC_MFHI:          /* Move from HI/LO */
24068     case OPC_MFLO:
24069         gen_HILO(ctx, op1, rs & 3, rd);
24070         break;
24071     case OPC_MTHI:
24072     case OPC_MTLO:          /* Move to HI/LO */
24073         gen_HILO(ctx, op1, rd & 3, rs);
24074         break;
24075     case OPC_MOVCI:
24076         check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
24077         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
24078             check_cp1_enabled(ctx);
24079             gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
24080                       (ctx->opcode >> 16) & 1);
24081         } else {
24082             generate_exception_err(ctx, EXCP_CpU, 1);
24083         }
24084         break;
24085     case OPC_MULT:
24086     case OPC_MULTU:
24087         if (sa) {
24088             check_insn(ctx, INSN_VR54XX);
24089             op1 = MASK_MUL_VR54XX(ctx->opcode);
24090             gen_mul_vr54xx(ctx, op1, rd, rs, rt);
24091         } else {
24092             gen_muldiv(ctx, op1, rd & 3, rs, rt);
24093         }
24094         break;
24095     case OPC_DIV:
24096     case OPC_DIVU:
24097         gen_muldiv(ctx, op1, 0, rs, rt);
24098         break;
24099 #if defined(TARGET_MIPS64)
24100     case OPC_DMULT:
24101     case OPC_DMULTU:
24102     case OPC_DDIV:
24103     case OPC_DDIVU:
24104         check_insn(ctx, ISA_MIPS3);
24105         check_mips_64(ctx);
24106         gen_muldiv(ctx, op1, 0, rs, rt);
24107         break;
24108 #endif
24109     case OPC_JR:
24110         gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
24111         break;
24112     case OPC_SPIM:
24113 #ifdef MIPS_STRICT_STANDARD
24114         MIPS_INVAL("SPIM");
24115         generate_exception_end(ctx, EXCP_RI);
24116 #else
24117         /* Implemented as RI exception for now. */
24118         MIPS_INVAL("spim (unofficial)");
24119         generate_exception_end(ctx, EXCP_RI);
24120 #endif
24121         break;
24122     default:            /* Invalid */
24123         MIPS_INVAL("special_legacy");
24124         generate_exception_end(ctx, EXCP_RI);
24125         break;
24126     }
24127 }
24128
24129 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
24130 {
24131     int rs, rt, rd, sa;
24132     uint32_t op1;
24133
24134     rs = (ctx->opcode >> 21) & 0x1f;
24135     rt = (ctx->opcode >> 16) & 0x1f;
24136     rd = (ctx->opcode >> 11) & 0x1f;
24137     sa = (ctx->opcode >> 6) & 0x1f;
24138
24139     op1 = MASK_SPECIAL(ctx->opcode);
24140     switch (op1) {
24141     case OPC_SLL:          /* Shift with immediate */
24142         if (sa == 5 && rd == 0 &&
24143             rs == 0 && rt == 0) { /* PAUSE */
24144             if ((ctx->insn_flags & ISA_MIPS32R6) &&
24145                 (ctx->hflags & MIPS_HFLAG_BMASK)) {
24146                 generate_exception_end(ctx, EXCP_RI);
24147                 break;
24148             }
24149         }
24150         /* Fallthrough */
24151     case OPC_SRA:
24152         gen_shift_imm(ctx, op1, rd, rt, sa);
24153         break;
24154     case OPC_SRL:
24155         switch ((ctx->opcode >> 21) & 0x1f) {
24156         case 1:
24157             /* rotr is decoded as srl on non-R2 CPUs */
24158             if (ctx->insn_flags & ISA_MIPS32R2) {
24159                 op1 = OPC_ROTR;
24160             }
24161             /* Fallthrough */
24162         case 0:
24163             gen_shift_imm(ctx, op1, rd, rt, sa);
24164             break;
24165         default:
24166             generate_exception_end(ctx, EXCP_RI);
24167             break;
24168         }
24169         break;
24170     case OPC_ADD:
24171     case OPC_ADDU:
24172     case OPC_SUB:
24173     case OPC_SUBU:
24174         gen_arith(ctx, op1, rd, rs, rt);
24175         break;
24176     case OPC_SLLV:         /* Shifts */
24177     case OPC_SRAV:
24178         gen_shift(ctx, op1, rd, rs, rt);
24179         break;
24180     case OPC_SRLV:
24181         switch ((ctx->opcode >> 6) & 0x1f) {
24182         case 1:
24183             /* rotrv is decoded as srlv on non-R2 CPUs */
24184             if (ctx->insn_flags & ISA_MIPS32R2) {
24185                 op1 = OPC_ROTRV;
24186             }
24187             /* Fallthrough */
24188         case 0:
24189             gen_shift(ctx, op1, rd, rs, rt);
24190             break;
24191         default:
24192             generate_exception_end(ctx, EXCP_RI);
24193             break;
24194         }
24195         break;
24196     case OPC_SLT:          /* Set on less than */
24197     case OPC_SLTU:
24198         gen_slt(ctx, op1, rd, rs, rt);
24199         break;
24200     case OPC_AND:          /* Logic*/
24201     case OPC_OR:
24202     case OPC_NOR:
24203     case OPC_XOR:
24204         gen_logic(ctx, op1, rd, rs, rt);
24205         break;
24206     case OPC_JALR:
24207         gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
24208         break;
24209     case OPC_TGE: /* Traps */
24210     case OPC_TGEU:
24211     case OPC_TLT:
24212     case OPC_TLTU:
24213     case OPC_TEQ:
24214     case OPC_TNE:
24215         check_insn(ctx, ISA_MIPS2);
24216         gen_trap(ctx, op1, rs, rt, -1);
24217         break;
24218     case OPC_LSA: /* OPC_PMON */
24219         if ((ctx->insn_flags & ISA_MIPS32R6) ||
24220             (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
24221             decode_opc_special_r6(env, ctx);
24222         } else {
24223             /* Pmon entry point, also R4010 selsl */
24224 #ifdef MIPS_STRICT_STANDARD
24225             MIPS_INVAL("PMON / selsl");
24226             generate_exception_end(ctx, EXCP_RI);
24227 #else
24228             gen_helper_0e0i(pmon, sa);
24229 #endif
24230         }
24231         break;
24232     case OPC_SYSCALL:
24233         generate_exception_end(ctx, EXCP_SYSCALL);
24234         break;
24235     case OPC_BREAK:
24236         generate_exception_end(ctx, EXCP_BREAK);
24237         break;
24238     case OPC_SYNC:
24239         check_insn(ctx, ISA_MIPS2);
24240         gen_sync(extract32(ctx->opcode, 6, 5));
24241         break;
24242
24243 #if defined(TARGET_MIPS64)
24244         /* MIPS64 specific opcodes */
24245     case OPC_DSLL:
24246     case OPC_DSRA:
24247     case OPC_DSLL32:
24248     case OPC_DSRA32:
24249         check_insn(ctx, ISA_MIPS3);
24250         check_mips_64(ctx);
24251         gen_shift_imm(ctx, op1, rd, rt, sa);
24252         break;
24253     case OPC_DSRL:
24254         switch ((ctx->opcode >> 21) & 0x1f) {
24255         case 1:
24256             /* drotr is decoded as dsrl on non-R2 CPUs */
24257             if (ctx->insn_flags & ISA_MIPS32R2) {
24258                 op1 = OPC_DROTR;
24259             }
24260             /* Fallthrough */
24261         case 0:
24262             check_insn(ctx, ISA_MIPS3);
24263             check_mips_64(ctx);
24264             gen_shift_imm(ctx, op1, rd, rt, sa);
24265             break;
24266         default:
24267             generate_exception_end(ctx, EXCP_RI);
24268             break;
24269         }
24270         break;
24271     case OPC_DSRL32:
24272         switch ((ctx->opcode >> 21) & 0x1f) {
24273         case 1:
24274             /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
24275             if (ctx->insn_flags & ISA_MIPS32R2) {
24276                 op1 = OPC_DROTR32;
24277             }
24278             /* Fallthrough */
24279         case 0:
24280             check_insn(ctx, ISA_MIPS3);
24281             check_mips_64(ctx);
24282             gen_shift_imm(ctx, op1, rd, rt, sa);
24283             break;
24284         default:
24285             generate_exception_end(ctx, EXCP_RI);
24286             break;
24287         }
24288         break;
24289     case OPC_DADD:
24290     case OPC_DADDU:
24291     case OPC_DSUB:
24292     case OPC_DSUBU:
24293         check_insn(ctx, ISA_MIPS3);
24294         check_mips_64(ctx);
24295         gen_arith(ctx, op1, rd, rs, rt);
24296         break;
24297     case OPC_DSLLV:
24298     case OPC_DSRAV:
24299         check_insn(ctx, ISA_MIPS3);
24300         check_mips_64(ctx);
24301         gen_shift(ctx, op1, rd, rs, rt);
24302         break;
24303     case OPC_DSRLV:
24304         switch ((ctx->opcode >> 6) & 0x1f) {
24305         case 1:
24306             /* drotrv is decoded as dsrlv on non-R2 CPUs */
24307             if (ctx->insn_flags & ISA_MIPS32R2) {
24308                 op1 = OPC_DROTRV;
24309             }
24310             /* Fallthrough */
24311         case 0:
24312             check_insn(ctx, ISA_MIPS3);
24313             check_mips_64(ctx);
24314             gen_shift(ctx, op1, rd, rs, rt);
24315             break;
24316         default:
24317             generate_exception_end(ctx, EXCP_RI);
24318             break;
24319         }
24320         break;
24321     case OPC_DLSA:
24322         if ((ctx->insn_flags & ISA_MIPS32R6) ||
24323             (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
24324             decode_opc_special_r6(env, ctx);
24325         }
24326         break;
24327 #endif
24328     default:
24329         if (ctx->insn_flags & ISA_MIPS32R6) {
24330             decode_opc_special_r6(env, ctx);
24331         } else if (ctx->insn_flags & INSN_R5900) {
24332             decode_opc_special_tx79(env, ctx);
24333         } else {
24334             decode_opc_special_legacy(env, ctx);
24335         }
24336     }
24337 }
24338
24339
24340 #if defined(TARGET_MIPS64)
24341
24342 /*
24343  *
24344  *           MMI (MultiMedia Interface) ASE instructions
24345  *           ===========================================
24346  */
24347
24348 /*
24349  *          MMI instructions category: data communication
24350  *          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24351  *
24352  *   PCPYH    PEXCH    PEXTLB   PINTH    PPACB    PEXT5    PREVH
24353  *   PCPYLD   PEXCW    PEXTLH   PINTEH   PPACH    PPAC5    PROT3W
24354  *   PCPYUD   PEXEH    PEXTLW            PPACW
24355  *            PEXEW    PEXTUB
24356  *                     PEXTUH
24357  *                     PEXTUW
24358  */
24359
24360 /*
24361  *  PCPYH rd, rt
24362  *
24363  *    Parallel Copy Halfword
24364  *
24365  *   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
24366  *  +-----------+---------+---------+---------+---------+-----------+
24367  *  |    MMI    |0 0 0 0 0|   rt    |   rd    |  PCPYH  |    MMI3   |
24368  *  +-----------+---------+---------+---------+---------+-----------+
24369  */
24370 static void gen_mmi_pcpyh(DisasContext *ctx)
24371 {
24372     uint32_t pd, rt, rd;
24373     uint32_t opcode;
24374
24375     opcode = ctx->opcode;
24376
24377     pd = extract32(opcode, 21, 5);
24378     rt = extract32(opcode, 16, 5);
24379     rd = extract32(opcode, 11, 5);
24380
24381     if (unlikely(pd != 0)) {
24382         generate_exception_end(ctx, EXCP_RI);
24383     } else if (rd == 0) {
24384         /* nop */
24385     } else if (rt == 0) {
24386         tcg_gen_movi_i64(cpu_gpr[rd], 0);
24387         tcg_gen_movi_i64(cpu_mmr[rd], 0);
24388     } else {
24389         TCGv_i64 t0 = tcg_temp_new();
24390         TCGv_i64 t1 = tcg_temp_new();
24391         uint64_t mask = (1ULL << 16) - 1;
24392
24393         tcg_gen_andi_i64(t0, cpu_gpr[rt], mask);
24394         tcg_gen_movi_i64(t1, 0);
24395         tcg_gen_or_i64(t1, t0, t1);
24396         tcg_gen_shli_i64(t0, t0, 16);
24397         tcg_gen_or_i64(t1, t0, t1);
24398         tcg_gen_shli_i64(t0, t0, 16);
24399         tcg_gen_or_i64(t1, t0, t1);
24400         tcg_gen_shli_i64(t0, t0, 16);
24401         tcg_gen_or_i64(t1, t0, t1);
24402
24403         tcg_gen_mov_i64(cpu_gpr[rd], t1);
24404
24405         tcg_gen_andi_i64(t0, cpu_mmr[rt], mask);
24406         tcg_gen_movi_i64(t1, 0);
24407         tcg_gen_or_i64(t1, t0, t1);
24408         tcg_gen_shli_i64(t0, t0, 16);
24409         tcg_gen_or_i64(t1, t0, t1);
24410         tcg_gen_shli_i64(t0, t0, 16);
24411         tcg_gen_or_i64(t1, t0, t1);
24412         tcg_gen_shli_i64(t0, t0, 16);
24413         tcg_gen_or_i64(t1, t0, t1);
24414
24415         tcg_gen_mov_i64(cpu_mmr[rd], t1);
24416
24417         tcg_temp_free(t0);
24418         tcg_temp_free(t1);
24419     }
24420 }
24421
24422 /*
24423  *  PCPYLD rd, rs, rt
24424  *
24425  *    Parallel Copy Lower Doubleword
24426  *
24427  *   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
24428  *  +-----------+---------+---------+---------+---------+-----------+
24429  *  |    MMI    |   rs    |   rt    |   rd    | PCPYLD  |    MMI2   |
24430  *  +-----------+---------+---------+---------+---------+-----------+
24431  */
24432 static void gen_mmi_pcpyld(DisasContext *ctx)
24433 {
24434     uint32_t rs, rt, rd;
24435     uint32_t opcode;
24436
24437     opcode = ctx->opcode;
24438
24439     rs = extract32(opcode, 21, 5);
24440     rt = extract32(opcode, 16, 5);
24441     rd = extract32(opcode, 11, 5);
24442
24443     if (rd == 0) {
24444         /* nop */
24445     } else {
24446         if (rs == 0) {
24447             tcg_gen_movi_i64(cpu_mmr[rd], 0);
24448         } else {
24449             tcg_gen_mov_i64(cpu_mmr[rd], cpu_gpr[rs]);
24450         }
24451         if (rt == 0) {
24452             tcg_gen_movi_i64(cpu_gpr[rd], 0);
24453         } else {
24454             if (rd != rt) {
24455                 tcg_gen_mov_i64(cpu_gpr[rd], cpu_gpr[rt]);
24456             }
24457         }
24458     }
24459 }
24460
24461 /*
24462  *  PCPYUD rd, rs, rt
24463  *
24464  *    Parallel Copy Upper Doubleword
24465  *
24466  *   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
24467  *  +-----------+---------+---------+---------+---------+-----------+
24468  *  |    MMI    |   rs    |   rt    |   rd    | PCPYUD  |    MMI3   |
24469  *  +-----------+---------+---------+---------+---------+-----------+
24470  */
24471 static void gen_mmi_pcpyud(DisasContext *ctx)
24472 {
24473     uint32_t rs, rt, rd;
24474     uint32_t opcode;
24475
24476     opcode = ctx->opcode;
24477
24478     rs = extract32(opcode, 21, 5);
24479     rt = extract32(opcode, 16, 5);
24480     rd = extract32(opcode, 11, 5);
24481
24482     if (rd == 0) {
24483         /* nop */
24484     } else {
24485         if (rs == 0) {
24486             tcg_gen_movi_i64(cpu_gpr[rd], 0);
24487         } else {
24488             tcg_gen_mov_i64(cpu_gpr[rd], cpu_mmr[rs]);
24489         }
24490         if (rt == 0) {
24491             tcg_gen_movi_i64(cpu_mmr[rd], 0);
24492         } else {
24493             if (rd != rt) {
24494                 tcg_gen_mov_i64(cpu_mmr[rd], cpu_mmr[rt]);
24495             }
24496         }
24497     }
24498 }
24499
24500 #endif
24501
24502
24503 #if !defined(TARGET_MIPS64)
24504
24505 /* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
24506 #define MXU_APTN1_A    0
24507 #define MXU_APTN1_S    1
24508
24509 /* MXU accumulate add/subtract 2-bit pattern 'aptn2' */
24510 #define MXU_APTN2_AA    0
24511 #define MXU_APTN2_AS    1
24512 #define MXU_APTN2_SA    2
24513 #define MXU_APTN2_SS    3
24514
24515 /* MXU execute add/subtract 2-bit pattern 'eptn2' */
24516 #define MXU_EPTN2_AA    0
24517 #define MXU_EPTN2_AS    1
24518 #define MXU_EPTN2_SA    2
24519 #define MXU_EPTN2_SS    3
24520
24521 /* MXU operand getting pattern 'optn2' */
24522 #define MXU_OPTN2_PTN0  0
24523 #define MXU_OPTN2_PTN1  1
24524 #define MXU_OPTN2_PTN2  2
24525 #define MXU_OPTN2_PTN3  3
24526 /* alternative naming scheme for 'optn2' */
24527 #define MXU_OPTN2_WW    0
24528 #define MXU_OPTN2_LW    1
24529 #define MXU_OPTN2_HW    2
24530 #define MXU_OPTN2_XW    3
24531
24532 /* MXU operand getting pattern 'optn3' */
24533 #define MXU_OPTN3_PTN0  0
24534 #define MXU_OPTN3_PTN1  1
24535 #define MXU_OPTN3_PTN2  2
24536 #define MXU_OPTN3_PTN3  3
24537 #define MXU_OPTN3_PTN4  4
24538 #define MXU_OPTN3_PTN5  5
24539 #define MXU_OPTN3_PTN6  6
24540 #define MXU_OPTN3_PTN7  7
24541
24542
24543 /*
24544  * S32I2M XRa, rb - Register move from GRF to XRF
24545  */
24546 static void gen_mxu_s32i2m(DisasContext *ctx)
24547 {
24548     TCGv t0;
24549     uint32_t XRa, Rb;
24550
24551     t0 = tcg_temp_new();
24552
24553     XRa = extract32(ctx->opcode, 6, 5);
24554     Rb = extract32(ctx->opcode, 16, 5);
24555
24556     gen_load_gpr(t0, Rb);
24557     if (XRa <= 15) {
24558         gen_store_mxu_gpr(t0, XRa);
24559     } else if (XRa == 16) {
24560         gen_store_mxu_cr(t0);
24561     }
24562
24563     tcg_temp_free(t0);
24564 }
24565
24566 /*
24567  * S32M2I XRa, rb - Register move from XRF to GRF
24568  */
24569 static void gen_mxu_s32m2i(DisasContext *ctx)
24570 {
24571     TCGv t0;
24572     uint32_t XRa, Rb;
24573
24574     t0 = tcg_temp_new();
24575
24576     XRa = extract32(ctx->opcode, 6, 5);
24577     Rb = extract32(ctx->opcode, 16, 5);
24578
24579     if (XRa <= 15) {
24580         gen_load_mxu_gpr(t0, XRa);
24581     } else if (XRa == 16) {
24582         gen_load_mxu_cr(t0);
24583     }
24584
24585     gen_store_gpr(t0, Rb);
24586
24587     tcg_temp_free(t0);
24588 }
24589
24590 /*
24591  * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF
24592  */
24593 static void gen_mxu_s8ldd(DisasContext *ctx)
24594 {
24595     TCGv t0, t1;
24596     uint32_t XRa, Rb, s8, optn3;
24597
24598     t0 = tcg_temp_new();
24599     t1 = tcg_temp_new();
24600
24601     XRa = extract32(ctx->opcode, 6, 4);
24602     s8 = extract32(ctx->opcode, 10, 8);
24603     optn3 = extract32(ctx->opcode, 18, 3);
24604     Rb = extract32(ctx->opcode, 21, 5);
24605
24606     gen_load_gpr(t0, Rb);
24607     tcg_gen_addi_tl(t0, t0, (int8_t)s8);
24608
24609     switch (optn3) {
24610     /* XRa[7:0] = tmp8 */
24611     case MXU_OPTN3_PTN0:
24612         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24613         gen_load_mxu_gpr(t0, XRa);
24614         tcg_gen_deposit_tl(t0, t0, t1, 0, 8);
24615         break;
24616     /* XRa[15:8] = tmp8 */
24617     case MXU_OPTN3_PTN1:
24618         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24619         gen_load_mxu_gpr(t0, XRa);
24620         tcg_gen_deposit_tl(t0, t0, t1, 8, 8);
24621         break;
24622     /* XRa[23:16] = tmp8 */
24623     case MXU_OPTN3_PTN2:
24624         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24625         gen_load_mxu_gpr(t0, XRa);
24626         tcg_gen_deposit_tl(t0, t0, t1, 16, 8);
24627         break;
24628     /* XRa[31:24] = tmp8 */
24629     case MXU_OPTN3_PTN3:
24630         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24631         gen_load_mxu_gpr(t0, XRa);
24632         tcg_gen_deposit_tl(t0, t0, t1, 24, 8);
24633         break;
24634     /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
24635     case MXU_OPTN3_PTN4:
24636         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24637         tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24638         break;
24639     /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
24640     case MXU_OPTN3_PTN5:
24641         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24642         tcg_gen_shli_tl(t1, t1, 8);
24643         tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24644         break;
24645     /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
24646     case MXU_OPTN3_PTN6:
24647         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_SB);
24648         tcg_gen_mov_tl(t0, t1);
24649         tcg_gen_andi_tl(t0, t0, 0xFF00FFFF);
24650         tcg_gen_shli_tl(t1, t1, 16);
24651         tcg_gen_or_tl(t0, t0, t1);
24652         break;
24653     /* XRa = {tmp8, tmp8, tmp8, tmp8} */
24654     case MXU_OPTN3_PTN7:
24655         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24656         tcg_gen_deposit_tl(t1, t1, t1, 8, 8);
24657         tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24658         break;
24659     }
24660
24661     gen_store_mxu_gpr(t0, XRa);
24662
24663     tcg_temp_free(t0);
24664     tcg_temp_free(t1);
24665 }
24666
24667 /*
24668  * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication
24669  */
24670 static void gen_mxu_d16mul(DisasContext *ctx)
24671 {
24672     TCGv t0, t1, t2, t3;
24673     uint32_t XRa, XRb, XRc, XRd, optn2;
24674
24675     t0 = tcg_temp_new();
24676     t1 = tcg_temp_new();
24677     t2 = tcg_temp_new();
24678     t3 = tcg_temp_new();
24679
24680     XRa = extract32(ctx->opcode, 6, 4);
24681     XRb = extract32(ctx->opcode, 10, 4);
24682     XRc = extract32(ctx->opcode, 14, 4);
24683     XRd = extract32(ctx->opcode, 18, 4);
24684     optn2 = extract32(ctx->opcode, 22, 2);
24685
24686     gen_load_mxu_gpr(t1, XRb);
24687     tcg_gen_sextract_tl(t0, t1, 0, 16);
24688     tcg_gen_sextract_tl(t1, t1, 16, 16);
24689     gen_load_mxu_gpr(t3, XRc);
24690     tcg_gen_sextract_tl(t2, t3, 0, 16);
24691     tcg_gen_sextract_tl(t3, t3, 16, 16);
24692
24693     switch (optn2) {
24694     case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
24695         tcg_gen_mul_tl(t3, t1, t3);
24696         tcg_gen_mul_tl(t2, t0, t2);
24697         break;
24698     case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
24699         tcg_gen_mul_tl(t3, t0, t3);
24700         tcg_gen_mul_tl(t2, t0, t2);
24701         break;
24702     case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
24703         tcg_gen_mul_tl(t3, t1, t3);
24704         tcg_gen_mul_tl(t2, t1, t2);
24705         break;
24706     case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
24707         tcg_gen_mul_tl(t3, t0, t3);
24708         tcg_gen_mul_tl(t2, t1, t2);
24709         break;
24710     }
24711     gen_store_mxu_gpr(t3, XRa);
24712     gen_store_mxu_gpr(t2, XRd);
24713
24714     tcg_temp_free(t0);
24715     tcg_temp_free(t1);
24716     tcg_temp_free(t2);
24717     tcg_temp_free(t3);
24718 }
24719
24720 /*
24721  * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply
24722  *                                           and accumulate
24723  */
24724 static void gen_mxu_d16mac(DisasContext *ctx)
24725 {
24726     TCGv t0, t1, t2, t3;
24727     uint32_t XRa, XRb, XRc, XRd, optn2, aptn2;
24728
24729     t0 = tcg_temp_new();
24730     t1 = tcg_temp_new();
24731     t2 = tcg_temp_new();
24732     t3 = tcg_temp_new();
24733
24734     XRa = extract32(ctx->opcode, 6, 4);
24735     XRb = extract32(ctx->opcode, 10, 4);
24736     XRc = extract32(ctx->opcode, 14, 4);
24737     XRd = extract32(ctx->opcode, 18, 4);
24738     optn2 = extract32(ctx->opcode, 22, 2);
24739     aptn2 = extract32(ctx->opcode, 24, 2);
24740
24741     gen_load_mxu_gpr(t1, XRb);
24742     tcg_gen_sextract_tl(t0, t1, 0, 16);
24743     tcg_gen_sextract_tl(t1, t1, 16, 16);
24744
24745     gen_load_mxu_gpr(t3, XRc);
24746     tcg_gen_sextract_tl(t2, t3, 0, 16);
24747     tcg_gen_sextract_tl(t3, t3, 16, 16);
24748
24749     switch (optn2) {
24750     case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
24751         tcg_gen_mul_tl(t3, t1, t3);
24752         tcg_gen_mul_tl(t2, t0, t2);
24753         break;
24754     case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
24755         tcg_gen_mul_tl(t3, t0, t3);
24756         tcg_gen_mul_tl(t2, t0, t2);
24757         break;
24758     case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
24759         tcg_gen_mul_tl(t3, t1, t3);
24760         tcg_gen_mul_tl(t2, t1, t2);
24761         break;
24762     case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
24763         tcg_gen_mul_tl(t3, t0, t3);
24764         tcg_gen_mul_tl(t2, t1, t2);
24765         break;
24766     }
24767     gen_load_mxu_gpr(t0, XRa);
24768     gen_load_mxu_gpr(t1, XRd);
24769
24770     switch (aptn2) {
24771     case MXU_APTN2_AA:
24772         tcg_gen_add_tl(t3, t0, t3);
24773         tcg_gen_add_tl(t2, t1, t2);
24774         break;
24775     case MXU_APTN2_AS:
24776         tcg_gen_add_tl(t3, t0, t3);
24777         tcg_gen_sub_tl(t2, t1, t2);
24778         break;
24779     case MXU_APTN2_SA:
24780         tcg_gen_sub_tl(t3, t0, t3);
24781         tcg_gen_add_tl(t2, t1, t2);
24782         break;
24783     case MXU_APTN2_SS:
24784         tcg_gen_sub_tl(t3, t0, t3);
24785         tcg_gen_sub_tl(t2, t1, t2);
24786         break;
24787     }
24788     gen_store_mxu_gpr(t3, XRa);
24789     gen_store_mxu_gpr(t2, XRd);
24790
24791     tcg_temp_free(t0);
24792     tcg_temp_free(t1);
24793     tcg_temp_free(t2);
24794     tcg_temp_free(t3);
24795 }
24796
24797 /*
24798  * Q8MUL   XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply
24799  * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply
24800  */
24801 static void gen_mxu_q8mul_q8mulsu(DisasContext *ctx)
24802 {
24803     TCGv t0, t1, t2, t3, t4, t5, t6, t7;
24804     uint32_t XRa, XRb, XRc, XRd, sel;
24805
24806     t0 = tcg_temp_new();
24807     t1 = tcg_temp_new();
24808     t2 = tcg_temp_new();
24809     t3 = tcg_temp_new();
24810     t4 = tcg_temp_new();
24811     t5 = tcg_temp_new();
24812     t6 = tcg_temp_new();
24813     t7 = tcg_temp_new();
24814
24815     XRa = extract32(ctx->opcode, 6, 4);
24816     XRb = extract32(ctx->opcode, 10, 4);
24817     XRc = extract32(ctx->opcode, 14, 4);
24818     XRd = extract32(ctx->opcode, 18, 4);
24819     sel = extract32(ctx->opcode, 22, 2);
24820
24821     gen_load_mxu_gpr(t3, XRb);
24822     gen_load_mxu_gpr(t7, XRc);
24823
24824     if (sel == 0x2) {
24825         /* Q8MULSU */
24826         tcg_gen_ext8s_tl(t0, t3);
24827         tcg_gen_shri_tl(t3, t3, 8);
24828         tcg_gen_ext8s_tl(t1, t3);
24829         tcg_gen_shri_tl(t3, t3, 8);
24830         tcg_gen_ext8s_tl(t2, t3);
24831         tcg_gen_shri_tl(t3, t3, 8);
24832         tcg_gen_ext8s_tl(t3, t3);
24833     } else {
24834         /* Q8MUL */
24835         tcg_gen_ext8u_tl(t0, t3);
24836         tcg_gen_shri_tl(t3, t3, 8);
24837         tcg_gen_ext8u_tl(t1, t3);
24838         tcg_gen_shri_tl(t3, t3, 8);
24839         tcg_gen_ext8u_tl(t2, t3);
24840         tcg_gen_shri_tl(t3, t3, 8);
24841         tcg_gen_ext8u_tl(t3, t3);
24842     }
24843
24844     tcg_gen_ext8u_tl(t4, t7);
24845     tcg_gen_shri_tl(t7, t7, 8);
24846     tcg_gen_ext8u_tl(t5, t7);
24847     tcg_gen_shri_tl(t7, t7, 8);
24848     tcg_gen_ext8u_tl(t6, t7);
24849     tcg_gen_shri_tl(t7, t7, 8);
24850     tcg_gen_ext8u_tl(t7, t7);
24851
24852     tcg_gen_mul_tl(t0, t0, t4);
24853     tcg_gen_mul_tl(t1, t1, t5);
24854     tcg_gen_mul_tl(t2, t2, t6);
24855     tcg_gen_mul_tl(t3, t3, t7);
24856
24857     tcg_gen_andi_tl(t0, t0, 0xFFFF);
24858     tcg_gen_andi_tl(t1, t1, 0xFFFF);
24859     tcg_gen_andi_tl(t2, t2, 0xFFFF);
24860     tcg_gen_andi_tl(t3, t3, 0xFFFF);
24861
24862     tcg_gen_shli_tl(t1, t1, 16);
24863     tcg_gen_shli_tl(t3, t3, 16);
24864
24865     tcg_gen_or_tl(t0, t0, t1);
24866     tcg_gen_or_tl(t1, t2, t3);
24867
24868     gen_store_mxu_gpr(t0, XRd);
24869     gen_store_mxu_gpr(t1, XRa);
24870
24871     tcg_temp_free(t0);
24872     tcg_temp_free(t1);
24873     tcg_temp_free(t2);
24874     tcg_temp_free(t3);
24875     tcg_temp_free(t4);
24876     tcg_temp_free(t5);
24877     tcg_temp_free(t6);
24878     tcg_temp_free(t7);
24879 }
24880
24881 /*
24882  * S32LDD  XRa, Rb, S12 - Load a word from memory to XRF
24883  * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF, reversed byte seq.
24884  */
24885 static void gen_mxu_s32ldd_s32lddr(DisasContext *ctx)
24886 {
24887     TCGv t0, t1;
24888     uint32_t XRa, Rb, s12, sel;
24889
24890     t0 = tcg_temp_new();
24891     t1 = tcg_temp_new();
24892
24893     XRa = extract32(ctx->opcode, 6, 4);
24894     s12 = extract32(ctx->opcode, 10, 10);
24895     sel = extract32(ctx->opcode, 20, 1);
24896     Rb = extract32(ctx->opcode, 21, 5);
24897
24898     gen_load_gpr(t0, Rb);
24899
24900     tcg_gen_movi_tl(t1, s12);
24901     tcg_gen_shli_tl(t1, t1, 2);
24902     if (s12 & 0x200) {
24903         tcg_gen_ori_tl(t1, t1, 0xFFFFF000);
24904     }
24905     tcg_gen_add_tl(t1, t0, t1);
24906     tcg_gen_qemu_ld_tl(t1, t1, ctx->mem_idx, MO_SL);
24907
24908     if (sel == 1) {
24909         /* S32LDDR */
24910         tcg_gen_bswap32_tl(t1, t1);
24911     }
24912     gen_store_mxu_gpr(t1, XRa);
24913
24914     tcg_temp_free(t0);
24915     tcg_temp_free(t1);
24916 }
24917
24918
24919 /*
24920  *                 MXU instruction category: logic
24921  *                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24922  *
24923  *               S32NOR    S32AND    S32OR    S32XOR
24924  */
24925
24926 /*
24927  *  S32NOR XRa, XRb, XRc
24928  *    Update XRa with the result of logical bitwise 'nor' operation
24929  *    applied to the content of XRb and XRc.
24930  *
24931  *   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
24932  *  +-----------+---------+-----+-------+-------+-------+-----------+
24933  *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
24934  *  +-----------+---------+-----+-------+-------+-------+-----------+
24935  */
24936 static void gen_mxu_S32NOR(DisasContext *ctx)
24937 {
24938     uint32_t pad, XRc, XRb, XRa;
24939
24940     pad = extract32(ctx->opcode, 21, 5);
24941     XRc = extract32(ctx->opcode, 14, 4);
24942     XRb = extract32(ctx->opcode, 10, 4);
24943     XRa = extract32(ctx->opcode,  6, 4);
24944
24945     if (unlikely(pad != 0)) {
24946         /* opcode padding incorrect -> do nothing */
24947     } else if (unlikely(XRa == 0)) {
24948         /* destination is zero register -> do nothing */
24949     } else if (unlikely((XRb == 0) && (XRc == 0))) {
24950         /* both operands zero registers -> just set destination to all 1s */
24951         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0xFFFFFFFF);
24952     } else if (unlikely(XRb == 0)) {
24953         /* XRb zero register -> just set destination to the negation of XRc */
24954         tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
24955     } else if (unlikely(XRc == 0)) {
24956         /* XRa zero register -> just set destination to the negation of XRb */
24957         tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24958     } else if (unlikely(XRb == XRc)) {
24959         /* both operands same -> just set destination to the negation of XRb */
24960         tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24961     } else {
24962         /* the most general case */
24963         tcg_gen_nor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
24964     }
24965 }
24966
24967 /*
24968  *  S32AND XRa, XRb, XRc
24969  *    Update XRa with the result of logical bitwise 'and' operation
24970  *    applied to the content of XRb and XRc.
24971  *
24972  *   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
24973  *  +-----------+---------+-----+-------+-------+-------+-----------+
24974  *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
24975  *  +-----------+---------+-----+-------+-------+-------+-----------+
24976  */
24977 static void gen_mxu_S32AND(DisasContext *ctx)
24978 {
24979     uint32_t pad, XRc, XRb, XRa;
24980
24981     pad = extract32(ctx->opcode, 21, 5);
24982     XRc = extract32(ctx->opcode, 14, 4);
24983     XRb = extract32(ctx->opcode, 10, 4);
24984     XRa = extract32(ctx->opcode,  6, 4);
24985
24986     if (unlikely(pad != 0)) {
24987         /* opcode padding incorrect -> do nothing */
24988     } else if (unlikely(XRa == 0)) {
24989         /* destination is zero register -> do nothing */
24990     } else if (unlikely((XRb == 0) || (XRc == 0))) {
24991         /* one of operands zero register -> just set destination to all 0s */
24992         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
24993     } else if (unlikely(XRb == XRc)) {
24994         /* both operands same -> just set destination to one of them */
24995         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24996     } else {
24997         /* the most general case */
24998         tcg_gen_and_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
24999     }
25000 }
25001
25002 /*
25003  *  S32OR XRa, XRb, XRc
25004  *    Update XRa with the result of logical bitwise 'or' operation
25005  *    applied to the content of XRb and XRc.
25006  *
25007  *   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
25008  *  +-----------+---------+-----+-------+-------+-------+-----------+
25009  *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
25010  *  +-----------+---------+-----+-------+-------+-------+-----------+
25011  */
25012 static void gen_mxu_S32OR(DisasContext *ctx)
25013 {
25014     uint32_t pad, XRc, XRb, XRa;
25015
25016     pad = extract32(ctx->opcode, 21, 5);
25017     XRc = extract32(ctx->opcode, 14, 4);
25018     XRb = extract32(ctx->opcode, 10, 4);
25019     XRa = extract32(ctx->opcode,  6, 4);
25020
25021     if (unlikely(pad != 0)) {
25022         /* opcode padding incorrect -> do nothing */
25023     } else if (unlikely(XRa == 0)) {
25024         /* destination is zero register -> do nothing */
25025     } else if (unlikely((XRb == 0) && (XRc == 0))) {
25026         /* both operands zero registers -> just set destination to all 0s */
25027         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25028     } else if (unlikely(XRb == 0)) {
25029         /* XRb zero register -> just set destination to the content of XRc */
25030         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25031     } else if (unlikely(XRc == 0)) {
25032         /* XRc zero register -> just set destination to the content of XRb */
25033         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25034     } else if (unlikely(XRb == XRc)) {
25035         /* both operands same -> just set destination to one of them */
25036         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25037     } else {
25038         /* the most general case */
25039         tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
25040     }
25041 }
25042
25043 /*
25044  *  S32XOR XRa, XRb, XRc
25045  *    Update XRa with the result of logical bitwise 'xor' operation
25046  *    applied to the content of XRb and XRc.
25047  *
25048  *   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
25049  *  +-----------+---------+-----+-------+-------+-------+-----------+
25050  *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
25051  *  +-----------+---------+-----+-------+-------+-------+-----------+
25052  */
25053 static void gen_mxu_S32XOR(DisasContext *ctx)
25054 {
25055     uint32_t pad, XRc, XRb, XRa;
25056
25057     pad = extract32(ctx->opcode, 21, 5);
25058     XRc = extract32(ctx->opcode, 14, 4);
25059     XRb = extract32(ctx->opcode, 10, 4);
25060     XRa = extract32(ctx->opcode,  6, 4);
25061
25062     if (unlikely(pad != 0)) {
25063         /* opcode padding incorrect -> do nothing */
25064     } else if (unlikely(XRa == 0)) {
25065         /* destination is zero register -> do nothing */
25066     } else if (unlikely((XRb == 0) && (XRc == 0))) {
25067         /* both operands zero registers -> just set destination to all 0s */
25068         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25069     } else if (unlikely(XRb == 0)) {
25070         /* XRb zero register -> just set destination to the content of XRc */
25071         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25072     } else if (unlikely(XRc == 0)) {
25073         /* XRc zero register -> just set destination to the content of XRb */
25074         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25075     } else if (unlikely(XRb == XRc)) {
25076         /* both operands same -> just set destination to all 0s */
25077         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25078     } else {
25079         /* the most general case */
25080         tcg_gen_xor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
25081     }
25082 }
25083
25084
25085 /*
25086  *                   MXU instruction category max/min
25087  *                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25088  *
25089  *                     S32MAX     D16MAX     Q8MAX
25090  *                     S32MIN     D16MIN     Q8MIN
25091  */
25092
25093 /*
25094  *  S32MAX XRa, XRb, XRc
25095  *    Update XRa with the maximum of signed 32-bit integers contained
25096  *    in XRb and XRc.
25097  *
25098  *  S32MIN XRa, XRb, XRc
25099  *    Update XRa with the minimum of signed 32-bit integers contained
25100  *    in XRb and XRc.
25101  *
25102  *   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
25103  *  +-----------+---------+-----+-------+-------+-------+-----------+
25104  *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL00|
25105  *  +-----------+---------+-----+-------+-------+-------+-----------+
25106  */
25107 static void gen_mxu_S32MAX_S32MIN(DisasContext *ctx)
25108 {
25109     uint32_t pad, opc, XRc, XRb, XRa;
25110
25111     pad = extract32(ctx->opcode, 21, 5);
25112     opc = extract32(ctx->opcode, 18, 3);
25113     XRc = extract32(ctx->opcode, 14, 4);
25114     XRb = extract32(ctx->opcode, 10, 4);
25115     XRa = extract32(ctx->opcode,  6, 4);
25116
25117     if (unlikely(pad != 0)) {
25118         /* opcode padding incorrect -> do nothing */
25119     } else if (unlikely(XRa == 0)) {
25120         /* destination is zero register -> do nothing */
25121     } else if (unlikely((XRb == 0) && (XRc == 0))) {
25122         /* both operands zero registers -> just set destination to zero */
25123         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25124     } else if (unlikely((XRb == 0) || (XRc == 0))) {
25125         /* exactly one operand is zero register - find which one is not...*/
25126         uint32_t XRx = XRb ? XRb : XRc;
25127         /* ...and do max/min operation with one operand 0 */
25128         if (opc == OPC_MXU_S32MAX) {
25129             tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
25130         } else {
25131             tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
25132         }
25133     } else if (unlikely(XRb == XRc)) {
25134         /* both operands same -> just set destination to one of them */
25135         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25136     } else {
25137         /* the most general case */
25138         if (opc == OPC_MXU_S32MAX) {
25139             tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
25140                                                mxu_gpr[XRc - 1]);
25141         } else {
25142             tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
25143                                                mxu_gpr[XRc - 1]);
25144         }
25145     }
25146 }
25147
25148 /*
25149  *  D16MAX
25150  *    Update XRa with the 16-bit-wise maximums of signed integers
25151  *    contained in XRb and XRc.
25152  *
25153  *  D16MIN
25154  *    Update XRa with the 16-bit-wise minimums of signed integers
25155  *    contained in XRb and XRc.
25156  *
25157  *   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
25158  *  +-----------+---------+-----+-------+-------+-------+-----------+
25159  *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL00|
25160  *  +-----------+---------+-----+-------+-------+-------+-----------+
25161  */
25162 static void gen_mxu_D16MAX_D16MIN(DisasContext *ctx)
25163 {
25164     uint32_t pad, opc, XRc, XRb, XRa;
25165
25166     pad = extract32(ctx->opcode, 21, 5);
25167     opc = extract32(ctx->opcode, 18, 3);
25168     XRc = extract32(ctx->opcode, 14, 4);
25169     XRb = extract32(ctx->opcode, 10, 4);
25170     XRa = extract32(ctx->opcode,  6, 4);
25171
25172     if (unlikely(pad != 0)) {
25173         /* opcode padding incorrect -> do nothing */
25174     } else if (unlikely(XRc == 0)) {
25175         /* destination is zero register -> do nothing */
25176     } else if (unlikely((XRb == 0) && (XRa == 0))) {
25177         /* both operands zero registers -> just set destination to zero */
25178         tcg_gen_movi_i32(mxu_gpr[XRc - 1], 0);
25179     } else if (unlikely((XRb == 0) || (XRa == 0))) {
25180         /* exactly one operand is zero register - find which one is not...*/
25181         uint32_t XRx = XRb ? XRb : XRc;
25182         /* ...and do half-word-wise max/min with one operand 0 */
25183         TCGv_i32 t0 = tcg_temp_new();
25184         TCGv_i32 t1 = tcg_const_i32(0);
25185
25186         /* the left half-word first */
25187         tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFFFF0000);
25188         if (opc == OPC_MXU_D16MAX) {
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         /* the right half-word */
25195         tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0x0000FFFF);
25196         /* move half-words to the leftmost position */
25197         tcg_gen_shli_i32(t0, t0, 16);
25198         /* t0 will be max/min of t0 and t1 */
25199         if (opc == OPC_MXU_D16MAX) {
25200             tcg_gen_smax_i32(t0, t0, t1);
25201         } else {
25202             tcg_gen_smin_i32(t0, t0, t1);
25203         }
25204         /* return resulting half-words to its original position */
25205         tcg_gen_shri_i32(t0, t0, 16);
25206         /* finaly update the destination */
25207         tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25208
25209         tcg_temp_free(t1);
25210         tcg_temp_free(t0);
25211     } else if (unlikely(XRb == XRc)) {
25212         /* both operands same -> just set destination to one of them */
25213         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25214     } else {
25215         /* the most general case */
25216         TCGv_i32 t0 = tcg_temp_new();
25217         TCGv_i32 t1 = tcg_temp_new();
25218
25219         /* the left half-word first */
25220         tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFFFF0000);
25221         tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
25222         if (opc == OPC_MXU_D16MAX) {
25223             tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25224         } else {
25225             tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25226         }
25227
25228         /* the right half-word */
25229         tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
25230         tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0x0000FFFF);
25231         /* move half-words to the leftmost position */
25232         tcg_gen_shli_i32(t0, t0, 16);
25233         tcg_gen_shli_i32(t1, t1, 16);
25234         /* t0 will be max/min of t0 and t1 */
25235         if (opc == OPC_MXU_D16MAX) {
25236             tcg_gen_smax_i32(t0, t0, t1);
25237         } else {
25238             tcg_gen_smin_i32(t0, t0, t1);
25239         }
25240         /* return resulting half-words to its original position */
25241         tcg_gen_shri_i32(t0, t0, 16);
25242         /* finaly update the destination */
25243         tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25244
25245         tcg_temp_free(t1);
25246         tcg_temp_free(t0);
25247     }
25248 }
25249
25250 /*
25251  *  Q8MAX
25252  *    Update XRa with the 8-bit-wise maximums of signed integers
25253  *    contained in XRb and XRc.
25254  *
25255  *  Q8MIN
25256  *    Update XRa with the 8-bit-wise minimums of signed integers
25257  *    contained in XRb and XRc.
25258  *
25259  *   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
25260  *  +-----------+---------+-----+-------+-------+-------+-----------+
25261  *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL00|
25262  *  +-----------+---------+-----+-------+-------+-------+-----------+
25263  */
25264 static void gen_mxu_Q8MAX_Q8MIN(DisasContext *ctx)
25265 {
25266     uint32_t pad, opc, XRc, XRb, XRa;
25267
25268     pad = extract32(ctx->opcode, 21, 5);
25269     opc = extract32(ctx->opcode, 18, 3);
25270     XRc = extract32(ctx->opcode, 14, 4);
25271     XRb = extract32(ctx->opcode, 10, 4);
25272     XRa = extract32(ctx->opcode,  6, 4);
25273
25274     if (unlikely(pad != 0)) {
25275         /* opcode padding incorrect -> do nothing */
25276     } else if (unlikely(XRa == 0)) {
25277         /* destination is zero register -> do nothing */
25278     } else if (unlikely((XRb == 0) && (XRc == 0))) {
25279         /* both operands zero registers -> just set destination to zero */
25280         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25281     } else if (unlikely((XRb == 0) || (XRc == 0))) {
25282         /* exactly one operand is zero register - make it be the first...*/
25283         uint32_t XRx = XRb ? XRb : XRc;
25284         /* ...and do byte-wise max/min with one operand 0 */
25285         TCGv_i32 t0 = tcg_temp_new();
25286         TCGv_i32 t1 = tcg_const_i32(0);
25287         int32_t i;
25288
25289         /* the leftmost byte (byte 3) first */
25290         tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF000000);
25291         if (opc == OPC_MXU_Q8MAX) {
25292             tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25293         } else {
25294             tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25295         }
25296
25297         /* bytes 2, 1, 0 */
25298         for (i = 2; i >= 0; i--) {
25299             /* extract the byte */
25300             tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF << (8 * i));
25301             /* move the byte to the leftmost position */
25302             tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
25303             /* t0 will be max/min of t0 and t1 */
25304             if (opc == OPC_MXU_Q8MAX) {
25305                 tcg_gen_smax_i32(t0, t0, t1);
25306             } else {
25307                 tcg_gen_smin_i32(t0, t0, t1);
25308             }
25309             /* return resulting byte to its original position */
25310             tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
25311             /* finaly update the destination */
25312             tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25313         }
25314
25315         tcg_temp_free(t1);
25316         tcg_temp_free(t0);
25317     } else if (unlikely(XRb == XRc)) {
25318         /* both operands same -> just set destination to one of them */
25319         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25320     } else {
25321         /* the most general case */
25322         TCGv_i32 t0 = tcg_temp_new();
25323         TCGv_i32 t1 = tcg_temp_new();
25324         int32_t i;
25325
25326         /* the leftmost bytes (bytes 3) first */
25327         tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF000000);
25328         tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
25329         if (opc == OPC_MXU_Q8MAX) {
25330             tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25331         } else {
25332             tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25333         }
25334
25335         /* bytes 2, 1, 0 */
25336         for (i = 2; i >= 0; i--) {
25337             /* extract corresponding bytes */
25338             tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF << (8 * i));
25339             tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF << (8 * i));
25340             /* move the bytes to the leftmost position */
25341             tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
25342             tcg_gen_shli_i32(t1, t1, 8 * (3 - i));
25343             /* t0 will be max/min of t0 and t1 */
25344             if (opc == OPC_MXU_Q8MAX) {
25345                 tcg_gen_smax_i32(t0, t0, t1);
25346             } else {
25347                 tcg_gen_smin_i32(t0, t0, t1);
25348             }
25349             /* return resulting byte to its original position */
25350             tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
25351             /* finaly update the destination */
25352             tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25353         }
25354
25355         tcg_temp_free(t1);
25356         tcg_temp_free(t0);
25357     }
25358 }
25359
25360
25361 /*
25362  *                 MXU instruction category: align
25363  *                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25364  *
25365  *                       S32ALN     S32ALNI
25366  */
25367
25368 /*
25369  *  S32ALNI XRc, XRb, XRa, optn3
25370  *    Arrange bytes from XRb and XRc according to one of five sets of
25371  *    rules determined by optn3, and place the result in XRa.
25372  *
25373  *   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
25374  *  +-----------+-----+---+-----+-------+-------+-------+-----------+
25375  *  |  SPECIAL2 |optn3|0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
25376  *  +-----------+-----+---+-----+-------+-------+-------+-----------+
25377  *
25378  */
25379 static void gen_mxu_S32ALNI(DisasContext *ctx)
25380 {
25381     uint32_t optn3, pad, XRc, XRb, XRa;
25382
25383     optn3 = extract32(ctx->opcode,  23, 3);
25384     pad   = extract32(ctx->opcode,  21, 2);
25385     XRc   = extract32(ctx->opcode, 14, 4);
25386     XRb   = extract32(ctx->opcode, 10, 4);
25387     XRa   = extract32(ctx->opcode,  6, 4);
25388
25389     if (unlikely(pad != 0)) {
25390         /* opcode padding incorrect -> do nothing */
25391     } else if (unlikely(XRa == 0)) {
25392         /* destination is zero register -> do nothing */
25393     } else if (unlikely((XRb == 0) && (XRc == 0))) {
25394         /* both operands zero registers -> just set destination to all 0s */
25395         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25396     } else if (unlikely(XRb == 0)) {
25397         /* XRb zero register -> just appropriatelly shift XRc into XRa */
25398         switch (optn3) {
25399         case MXU_OPTN3_PTN0:
25400             tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25401             break;
25402         case MXU_OPTN3_PTN1:
25403         case MXU_OPTN3_PTN2:
25404         case MXU_OPTN3_PTN3:
25405             tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1],
25406                              8 * (4 - optn3));
25407             break;
25408         case MXU_OPTN3_PTN4:
25409             tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25410             break;
25411         }
25412     } else if (unlikely(XRc == 0)) {
25413         /* XRc zero register -> just appropriatelly shift XRb into XRa */
25414         switch (optn3) {
25415         case MXU_OPTN3_PTN0:
25416             tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25417             break;
25418         case MXU_OPTN3_PTN1:
25419         case MXU_OPTN3_PTN2:
25420         case MXU_OPTN3_PTN3:
25421             tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
25422             break;
25423         case MXU_OPTN3_PTN4:
25424             tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25425             break;
25426         }
25427     } else if (unlikely(XRb == XRc)) {
25428         /* both operands same -> just rotation or moving from any of them */
25429         switch (optn3) {
25430         case MXU_OPTN3_PTN0:
25431         case MXU_OPTN3_PTN4:
25432             tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25433             break;
25434         case MXU_OPTN3_PTN1:
25435         case MXU_OPTN3_PTN2:
25436         case MXU_OPTN3_PTN3:
25437             tcg_gen_rotli_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
25438             break;
25439         }
25440     } else {
25441         /* the most general case */
25442         switch (optn3) {
25443         case MXU_OPTN3_PTN0:
25444             {
25445                 /*                                         */
25446                 /*         XRb                XRc          */
25447                 /*  +---------------+                      */
25448                 /*  | A   B   C   D |    E   F   G   H     */
25449                 /*  +-------+-------+                      */
25450                 /*          |                              */
25451                 /*         XRa                             */
25452                 /*                                         */
25453
25454                 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25455             }
25456             break;
25457         case MXU_OPTN3_PTN1:
25458             {
25459                 /*                                         */
25460                 /*         XRb                 XRc         */
25461                 /*      +-------------------+              */
25462                 /*    A | B   C   D       E | F   G   H    */
25463                 /*      +---------+---------+              */
25464                 /*                |                        */
25465                 /*               XRa                       */
25466                 /*                                         */
25467
25468                 TCGv_i32 t0 = tcg_temp_new();
25469                 TCGv_i32 t1 = tcg_temp_new();
25470
25471                 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x00FFFFFF);
25472                 tcg_gen_shli_i32(t0, t0, 8);
25473
25474                 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
25475                 tcg_gen_shri_i32(t1, t1, 24);
25476
25477                 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25478
25479                 tcg_temp_free(t1);
25480                 tcg_temp_free(t0);
25481             }
25482             break;
25483         case MXU_OPTN3_PTN2:
25484             {
25485                 /*                                         */
25486                 /*         XRb                 XRc         */
25487                 /*          +-------------------+          */
25488                 /*    A   B | C   D       E   F | G   H    */
25489                 /*          +---------+---------+          */
25490                 /*                    |                    */
25491                 /*                   XRa                   */
25492                 /*                                         */
25493
25494                 TCGv_i32 t0 = tcg_temp_new();
25495                 TCGv_i32 t1 = tcg_temp_new();
25496
25497                 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
25498                 tcg_gen_shli_i32(t0, t0, 16);
25499
25500                 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
25501                 tcg_gen_shri_i32(t1, t1, 16);
25502
25503                 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25504
25505                 tcg_temp_free(t1);
25506                 tcg_temp_free(t0);
25507             }
25508             break;
25509         case MXU_OPTN3_PTN3:
25510             {
25511                 /*                                         */
25512                 /*         XRb                 XRc         */
25513                 /*              +-------------------+      */
25514                 /*    A   B   C | D       E   F   G | H    */
25515                 /*              +---------+---------+      */
25516                 /*                        |                */
25517                 /*                       XRa               */
25518                 /*                                         */
25519
25520                 TCGv_i32 t0 = tcg_temp_new();
25521                 TCGv_i32 t1 = tcg_temp_new();
25522
25523                 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x000000FF);
25524                 tcg_gen_shli_i32(t0, t0, 24);
25525
25526                 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFFFF00);
25527                 tcg_gen_shri_i32(t1, t1, 8);
25528
25529                 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25530
25531                 tcg_temp_free(t1);
25532                 tcg_temp_free(t0);
25533             }
25534             break;
25535         case MXU_OPTN3_PTN4:
25536             {
25537                 /*                                         */
25538                 /*         XRb                 XRc         */
25539                 /*                     +---------------+   */
25540                 /*    A   B   C   D    | E   F   G   H |   */
25541                 /*                     +-------+-------+   */
25542                 /*                             |           */
25543                 /*                            XRa          */
25544                 /*                                         */
25545
25546                 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25547             }
25548             break;
25549         }
25550     }
25551 }
25552
25553
25554 /*
25555  * Decoding engine for MXU
25556  * =======================
25557  */
25558
25559 /*
25560  *
25561  * Decode MXU pool00
25562  *
25563  *   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
25564  *  +-----------+---------+-----+-------+-------+-------+-----------+
25565  *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL00|
25566  *  +-----------+---------+-----+-------+-------+-------+-----------+
25567  *
25568  */
25569 static void decode_opc_mxu__pool00(CPUMIPSState *env, DisasContext *ctx)
25570 {
25571     uint32_t opcode = extract32(ctx->opcode, 18, 3);
25572
25573     switch (opcode) {
25574     case OPC_MXU_S32MAX:
25575     case OPC_MXU_S32MIN:
25576         gen_mxu_S32MAX_S32MIN(ctx);
25577         break;
25578     case OPC_MXU_D16MAX:
25579     case OPC_MXU_D16MIN:
25580         gen_mxu_D16MAX_D16MIN(ctx);
25581         break;
25582     case OPC_MXU_Q8MAX:
25583     case OPC_MXU_Q8MIN:
25584         gen_mxu_Q8MAX_Q8MIN(ctx);
25585         break;
25586     case OPC_MXU_Q8SLT:
25587         /* TODO: Implement emulation of Q8SLT instruction. */
25588         MIPS_INVAL("OPC_MXU_Q8SLT");
25589         generate_exception_end(ctx, EXCP_RI);
25590         break;
25591     case OPC_MXU_Q8SLTU:
25592         /* TODO: Implement emulation of Q8SLTU instruction. */
25593         MIPS_INVAL("OPC_MXU_Q8SLTU");
25594         generate_exception_end(ctx, EXCP_RI);
25595         break;
25596     default:
25597         MIPS_INVAL("decode_opc_mxu");
25598         generate_exception_end(ctx, EXCP_RI);
25599         break;
25600     }
25601 }
25602
25603 /*
25604  *
25605  * Decode MXU pool01
25606  *
25607  *  S32SLT, D16SLT, D16AVG, D16AVGR, Q8AVG, Q8AVGR:
25608  *   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
25609  *  +-----------+---------+-----+-------+-------+-------+-----------+
25610  *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL01|
25611  *  +-----------+---------+-----+-------+-------+-------+-----------+
25612  *
25613  *  Q8ADD:
25614  *   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
25615  *  +-----------+---+-----+-----+-------+-------+-------+-----------+
25616  *  |  SPECIAL2 |en2|0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL01|
25617  *  +-----------+---+-----+-----+-------+-------+-------+-----------+
25618  *
25619  */
25620 static void decode_opc_mxu__pool01(CPUMIPSState *env, DisasContext *ctx)
25621 {
25622     uint32_t opcode = extract32(ctx->opcode, 18, 3);
25623
25624     switch (opcode) {
25625     case OPC_MXU_S32SLT:
25626         /* TODO: Implement emulation of S32SLT instruction. */
25627         MIPS_INVAL("OPC_MXU_S32SLT");
25628         generate_exception_end(ctx, EXCP_RI);
25629         break;
25630     case OPC_MXU_D16SLT:
25631         /* TODO: Implement emulation of D16SLT instruction. */
25632         MIPS_INVAL("OPC_MXU_D16SLT");
25633         generate_exception_end(ctx, EXCP_RI);
25634         break;
25635     case OPC_MXU_D16AVG:
25636         /* TODO: Implement emulation of D16AVG instruction. */
25637         MIPS_INVAL("OPC_MXU_D16AVG");
25638         generate_exception_end(ctx, EXCP_RI);
25639         break;
25640     case OPC_MXU_D16AVGR:
25641         /* TODO: Implement emulation of D16AVGR instruction. */
25642         MIPS_INVAL("OPC_MXU_D16AVGR");
25643         generate_exception_end(ctx, EXCP_RI);
25644         break;
25645     case OPC_MXU_Q8AVG:
25646         /* TODO: Implement emulation of Q8AVG instruction. */
25647         MIPS_INVAL("OPC_MXU_Q8AVG");
25648         generate_exception_end(ctx, EXCP_RI);
25649         break;
25650     case OPC_MXU_Q8AVGR:
25651         /* TODO: Implement emulation of Q8AVGR instruction. */
25652         MIPS_INVAL("OPC_MXU_Q8AVGR");
25653         generate_exception_end(ctx, EXCP_RI);
25654         break;
25655     case OPC_MXU_Q8ADD:
25656         /* TODO: Implement emulation of Q8ADD instruction. */
25657         MIPS_INVAL("OPC_MXU_Q8ADD");
25658         generate_exception_end(ctx, EXCP_RI);
25659         break;
25660     default:
25661         MIPS_INVAL("decode_opc_mxu");
25662         generate_exception_end(ctx, EXCP_RI);
25663         break;
25664     }
25665 }
25666
25667 /*
25668  *
25669  * Decode MXU pool02
25670  *
25671  *   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
25672  *  +-----------+---------+-----+-------+-------+-------+-----------+
25673  *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL02|
25674  *  +-----------+---------+-----+-------+-------+-------+-----------+
25675  *
25676  */
25677 static void decode_opc_mxu__pool02(CPUMIPSState *env, DisasContext *ctx)
25678 {
25679     uint32_t opcode = extract32(ctx->opcode, 18, 3);
25680
25681     switch (opcode) {
25682     case OPC_MXU_S32CPS:
25683         /* TODO: Implement emulation of S32CPS instruction. */
25684         MIPS_INVAL("OPC_MXU_S32CPS");
25685         generate_exception_end(ctx, EXCP_RI);
25686         break;
25687     case OPC_MXU_D16CPS:
25688         /* TODO: Implement emulation of D16CPS instruction. */
25689         MIPS_INVAL("OPC_MXU_D16CPS");
25690         generate_exception_end(ctx, EXCP_RI);
25691         break;
25692     case OPC_MXU_Q8ABD:
25693         /* TODO: Implement emulation of Q8ABD instruction. */
25694         MIPS_INVAL("OPC_MXU_Q8ABD");
25695         generate_exception_end(ctx, EXCP_RI);
25696         break;
25697     case OPC_MXU_Q16SAT:
25698         /* TODO: Implement emulation of Q16SAT instruction. */
25699         MIPS_INVAL("OPC_MXU_Q16SAT");
25700         generate_exception_end(ctx, EXCP_RI);
25701         break;
25702     default:
25703         MIPS_INVAL("decode_opc_mxu");
25704         generate_exception_end(ctx, EXCP_RI);
25705         break;
25706     }
25707 }
25708
25709 /*
25710  *
25711  * Decode MXU pool03
25712  *
25713  *  D16MULF:
25714  *   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
25715  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25716  *  |  SPECIAL2 |x x|on2|0 0 0 0|  XRc  |  XRb  |  XRa  |MXU__POOL03|
25717  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25718  *
25719  *  D16MULE:
25720  *   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
25721  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25722  *  |  SPECIAL2 |x x|on2|   Xd  |  XRc  |  XRb  |  XRa  |MXU__POOL03|
25723  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25724  *
25725  */
25726 static void decode_opc_mxu__pool03(CPUMIPSState *env, DisasContext *ctx)
25727 {
25728     uint32_t opcode = extract32(ctx->opcode, 24, 2);
25729
25730     switch (opcode) {
25731     case OPC_MXU_D16MULF:
25732         /* TODO: Implement emulation of D16MULF instruction. */
25733         MIPS_INVAL("OPC_MXU_D16MULF");
25734         generate_exception_end(ctx, EXCP_RI);
25735         break;
25736     case OPC_MXU_D16MULE:
25737         /* TODO: Implement emulation of D16MULE instruction. */
25738         MIPS_INVAL("OPC_MXU_D16MULE");
25739         generate_exception_end(ctx, EXCP_RI);
25740         break;
25741     default:
25742         MIPS_INVAL("decode_opc_mxu");
25743         generate_exception_end(ctx, EXCP_RI);
25744         break;
25745     }
25746 }
25747
25748 /*
25749  *
25750  * Decode MXU pool04
25751  *
25752  *   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
25753  *  +-----------+---------+-+-------------------+-------+-----------+
25754  *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL04|
25755  *  +-----------+---------+-+-------------------+-------+-----------+
25756  *
25757  */
25758 static void decode_opc_mxu__pool04(CPUMIPSState *env, DisasContext *ctx)
25759 {
25760     uint32_t opcode = extract32(ctx->opcode, 20, 1);
25761
25762     switch (opcode) {
25763     case OPC_MXU_S32LDD:
25764     case OPC_MXU_S32LDDR:
25765         gen_mxu_s32ldd_s32lddr(ctx);
25766         break;
25767     default:
25768         MIPS_INVAL("decode_opc_mxu");
25769         generate_exception_end(ctx, EXCP_RI);
25770         break;
25771     }
25772 }
25773
25774 /*
25775  *
25776  * Decode MXU pool05
25777  *
25778  *   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
25779  *  +-----------+---------+-+-------------------+-------+-----------+
25780  *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL05|
25781  *  +-----------+---------+-+-------------------+-------+-----------+
25782  *
25783  */
25784 static void decode_opc_mxu__pool05(CPUMIPSState *env, DisasContext *ctx)
25785 {
25786     uint32_t opcode = extract32(ctx->opcode, 20, 1);
25787
25788     switch (opcode) {
25789     case OPC_MXU_S32STD:
25790         /* TODO: Implement emulation of S32STD instruction. */
25791         MIPS_INVAL("OPC_MXU_S32STD");
25792         generate_exception_end(ctx, EXCP_RI);
25793         break;
25794     case OPC_MXU_S32STDR:
25795         /* TODO: Implement emulation of S32STDR instruction. */
25796         MIPS_INVAL("OPC_MXU_S32STDR");
25797         generate_exception_end(ctx, EXCP_RI);
25798         break;
25799     default:
25800         MIPS_INVAL("decode_opc_mxu");
25801         generate_exception_end(ctx, EXCP_RI);
25802         break;
25803     }
25804 }
25805
25806 /*
25807  *
25808  * Decode MXU pool06
25809  *
25810  *   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
25811  *  +-----------+---------+---------+---+-------+-------+-----------+
25812  *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL06|
25813  *  +-----------+---------+---------+---+-------+-------+-----------+
25814  *
25815  */
25816 static void decode_opc_mxu__pool06(CPUMIPSState *env, DisasContext *ctx)
25817 {
25818     uint32_t opcode = extract32(ctx->opcode, 10, 4);
25819
25820     switch (opcode) {
25821     case OPC_MXU_S32LDDV:
25822         /* TODO: Implement emulation of S32LDDV instruction. */
25823         MIPS_INVAL("OPC_MXU_S32LDDV");
25824         generate_exception_end(ctx, EXCP_RI);
25825         break;
25826     case OPC_MXU_S32LDDVR:
25827         /* TODO: Implement emulation of S32LDDVR instruction. */
25828         MIPS_INVAL("OPC_MXU_S32LDDVR");
25829         generate_exception_end(ctx, EXCP_RI);
25830         break;
25831     default:
25832         MIPS_INVAL("decode_opc_mxu");
25833         generate_exception_end(ctx, EXCP_RI);
25834         break;
25835     }
25836 }
25837
25838 /*
25839  *
25840  * Decode MXU pool07
25841  *
25842  *   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
25843  *  +-----------+---------+---------+---+-------+-------+-----------+
25844  *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL07|
25845  *  +-----------+---------+---------+---+-------+-------+-----------+
25846  *
25847  */
25848 static void decode_opc_mxu__pool07(CPUMIPSState *env, DisasContext *ctx)
25849 {
25850     uint32_t opcode = extract32(ctx->opcode, 10, 4);
25851
25852     switch (opcode) {
25853     case OPC_MXU_S32STDV:
25854         /* TODO: Implement emulation of S32TDV instruction. */
25855         MIPS_INVAL("OPC_MXU_S32TDV");
25856         generate_exception_end(ctx, EXCP_RI);
25857         break;
25858     case OPC_MXU_S32STDVR:
25859         /* TODO: Implement emulation of S32TDVR instruction. */
25860         MIPS_INVAL("OPC_MXU_S32TDVR");
25861         generate_exception_end(ctx, EXCP_RI);
25862         break;
25863     default:
25864         MIPS_INVAL("decode_opc_mxu");
25865         generate_exception_end(ctx, EXCP_RI);
25866         break;
25867     }
25868 }
25869
25870 /*
25871  *
25872  * Decode MXU pool08
25873  *
25874  *   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
25875  *  +-----------+---------+-+-------------------+-------+-----------+
25876  *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL08|
25877  *  +-----------+---------+-+-------------------+-------+-----------+
25878  *
25879 */
25880 static void decode_opc_mxu__pool08(CPUMIPSState *env, DisasContext *ctx)
25881 {
25882     uint32_t opcode = extract32(ctx->opcode, 20, 1);
25883
25884     switch (opcode) {
25885     case OPC_MXU_S32LDI:
25886         /* TODO: Implement emulation of S32LDI instruction. */
25887         MIPS_INVAL("OPC_MXU_S32LDI");
25888         generate_exception_end(ctx, EXCP_RI);
25889         break;
25890     case OPC_MXU_S32LDIR:
25891         /* TODO: Implement emulation of S32LDIR instruction. */
25892         MIPS_INVAL("OPC_MXU_S32LDIR");
25893         generate_exception_end(ctx, EXCP_RI);
25894         break;
25895     default:
25896         MIPS_INVAL("decode_opc_mxu");
25897         generate_exception_end(ctx, EXCP_RI);
25898         break;
25899     }
25900 }
25901
25902 /*
25903  *
25904  * Decode MXU pool09
25905  *
25906  *   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
25907  *  +-----------+---------+-+-------------------+-------+-----------+
25908  *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL09|
25909  *  +-----------+---------+-+-------------------+-------+-----------+
25910  *
25911  */
25912 static void decode_opc_mxu__pool09(CPUMIPSState *env, DisasContext *ctx)
25913 {
25914     uint32_t opcode = extract32(ctx->opcode, 5, 0);
25915
25916     switch (opcode) {
25917     case OPC_MXU_S32SDI:
25918         /* TODO: Implement emulation of S32SDI instruction. */
25919         MIPS_INVAL("OPC_MXU_S32SDI");
25920         generate_exception_end(ctx, EXCP_RI);
25921         break;
25922     case OPC_MXU_S32SDIR:
25923         /* TODO: Implement emulation of S32SDIR instruction. */
25924         MIPS_INVAL("OPC_MXU_S32SDIR");
25925         generate_exception_end(ctx, EXCP_RI);
25926         break;
25927     default:
25928         MIPS_INVAL("decode_opc_mxu");
25929         generate_exception_end(ctx, EXCP_RI);
25930         break;
25931     }
25932 }
25933
25934 /*
25935  *
25936  * Decode MXU pool10
25937  *
25938  *   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
25939  *  +-----------+---------+---------+---+-------+-------+-----------+
25940  *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL10|
25941  *  +-----------+---------+---------+---+-------+-------+-----------+
25942  *
25943  */
25944 static void decode_opc_mxu__pool10(CPUMIPSState *env, DisasContext *ctx)
25945 {
25946     uint32_t opcode = extract32(ctx->opcode, 5, 0);
25947
25948     switch (opcode) {
25949     case OPC_MXU_S32LDIV:
25950         /* TODO: Implement emulation of S32LDIV instruction. */
25951         MIPS_INVAL("OPC_MXU_S32LDIV");
25952         generate_exception_end(ctx, EXCP_RI);
25953         break;
25954     case OPC_MXU_S32LDIVR:
25955         /* TODO: Implement emulation of S32LDIVR instruction. */
25956         MIPS_INVAL("OPC_MXU_S32LDIVR");
25957         generate_exception_end(ctx, EXCP_RI);
25958         break;
25959     default:
25960         MIPS_INVAL("decode_opc_mxu");
25961         generate_exception_end(ctx, EXCP_RI);
25962         break;
25963     }
25964 }
25965
25966 /*
25967  *
25968  * Decode MXU pool11
25969  *
25970  *   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
25971  *  +-----------+---------+---------+---+-------+-------+-----------+
25972  *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL11|
25973  *  +-----------+---------+---------+---+-------+-------+-----------+
25974  *
25975  */
25976 static void decode_opc_mxu__pool11(CPUMIPSState *env, DisasContext *ctx)
25977 {
25978     uint32_t opcode = extract32(ctx->opcode, 10, 4);
25979
25980     switch (opcode) {
25981     case OPC_MXU_S32SDIV:
25982         /* TODO: Implement emulation of S32SDIV instruction. */
25983         MIPS_INVAL("OPC_MXU_S32SDIV");
25984         generate_exception_end(ctx, EXCP_RI);
25985         break;
25986     case OPC_MXU_S32SDIVR:
25987         /* TODO: Implement emulation of S32SDIVR instruction. */
25988         MIPS_INVAL("OPC_MXU_S32SDIVR");
25989         generate_exception_end(ctx, EXCP_RI);
25990         break;
25991     default:
25992         MIPS_INVAL("decode_opc_mxu");
25993         generate_exception_end(ctx, EXCP_RI);
25994         break;
25995     }
25996 }
25997
25998 /*
25999  *
26000  * Decode MXU pool12
26001  *
26002  *   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
26003  *  +-----------+---+---+-------+-------+-------+-------+-----------+
26004  *  |  SPECIAL2 |an2|x x|   Xd  |  XRc  |  XRb  |  XRa  |MXU__POOL12|
26005  *  +-----------+---+---+-------+-------+-------+-------+-----------+
26006  *
26007  */
26008 static void decode_opc_mxu__pool12(CPUMIPSState *env, DisasContext *ctx)
26009 {
26010     uint32_t opcode = extract32(ctx->opcode, 22, 2);
26011
26012     switch (opcode) {
26013     case OPC_MXU_D32ACC:
26014         /* TODO: Implement emulation of D32ACC instruction. */
26015         MIPS_INVAL("OPC_MXU_D32ACC");
26016         generate_exception_end(ctx, EXCP_RI);
26017         break;
26018     case OPC_MXU_D32ACCM:
26019         /* TODO: Implement emulation of D32ACCM instruction. */
26020         MIPS_INVAL("OPC_MXU_D32ACCM");
26021         generate_exception_end(ctx, EXCP_RI);
26022         break;
26023     case OPC_MXU_D32ASUM:
26024         /* TODO: Implement emulation of D32ASUM instruction. */
26025         MIPS_INVAL("OPC_MXU_D32ASUM");
26026         generate_exception_end(ctx, EXCP_RI);
26027         break;
26028     default:
26029         MIPS_INVAL("decode_opc_mxu");
26030         generate_exception_end(ctx, EXCP_RI);
26031         break;
26032     }
26033 }
26034
26035 /*
26036  *
26037  * Decode MXU pool13
26038  *
26039  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26040  *  +-----------+---+---+-------+-------+-------+-------+-----------+
26041  *  |  SPECIAL2 |en2|x x|0 0 0 0|  XRc  |  XRb  |  XRa  |MXU__POOL13|
26042  *  +-----------+---+---+-------+-------+-------+-------+-----------+
26043  *
26044  */
26045 static void decode_opc_mxu__pool13(CPUMIPSState *env, DisasContext *ctx)
26046 {
26047     uint32_t opcode = extract32(ctx->opcode, 22, 2);
26048
26049     switch (opcode) {
26050     case OPC_MXU_Q16ACC:
26051         /* TODO: Implement emulation of Q16ACC instruction. */
26052         MIPS_INVAL("OPC_MXU_Q16ACC");
26053         generate_exception_end(ctx, EXCP_RI);
26054         break;
26055     case OPC_MXU_Q16ACCM:
26056         /* TODO: Implement emulation of Q16ACCM instruction. */
26057         MIPS_INVAL("OPC_MXU_Q16ACCM");
26058         generate_exception_end(ctx, EXCP_RI);
26059         break;
26060     case OPC_MXU_Q16ASUM:
26061         /* TODO: Implement emulation of Q16ASUM instruction. */
26062         MIPS_INVAL("OPC_MXU_Q16ASUM");
26063         generate_exception_end(ctx, EXCP_RI);
26064         break;
26065     default:
26066         MIPS_INVAL("decode_opc_mxu");
26067         generate_exception_end(ctx, EXCP_RI);
26068         break;
26069     }
26070 }
26071
26072 /*
26073  *
26074  * Decode MXU pool14
26075  *
26076  *  Q8ADDE, Q8ACCE:
26077  *   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
26078  *  +-----------+---+---+-------+-------+-------+-------+-----------+
26079  *  |  SPECIAL2 |0 0|x x|  XRd  |  XRc  |  XRb  |  XRa  |MXU__POOL14|
26080  *  +-----------+---+---+-------+-------+-------+-------+-----------+
26081  *
26082  *  D8SUM, D8SUMC:
26083  *   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
26084  *  +-----------+---+---+-------+-------+-------+-------+-----------+
26085  *  |  SPECIAL2 |en2|x x|0 0 0 0|  XRc  |  XRb  |  XRa  |MXU__POOL14|
26086  *  +-----------+---+---+-------+-------+-------+-------+-----------+
26087  *
26088  */
26089 static void decode_opc_mxu__pool14(CPUMIPSState *env, DisasContext *ctx)
26090 {
26091     uint32_t opcode = extract32(ctx->opcode, 22, 2);
26092
26093     switch (opcode) {
26094     case OPC_MXU_Q8ADDE:
26095         /* TODO: Implement emulation of Q8ADDE instruction. */
26096         MIPS_INVAL("OPC_MXU_Q8ADDE");
26097         generate_exception_end(ctx, EXCP_RI);
26098         break;
26099     case OPC_MXU_D8SUM:
26100         /* TODO: Implement emulation of D8SUM instruction. */
26101         MIPS_INVAL("OPC_MXU_D8SUM");
26102         generate_exception_end(ctx, EXCP_RI);
26103         break;
26104     case OPC_MXU_D8SUMC:
26105         /* TODO: Implement emulation of D8SUMC instruction. */
26106         MIPS_INVAL("OPC_MXU_D8SUMC");
26107         generate_exception_end(ctx, EXCP_RI);
26108         break;
26109     default:
26110         MIPS_INVAL("decode_opc_mxu");
26111         generate_exception_end(ctx, EXCP_RI);
26112         break;
26113     }
26114 }
26115
26116 /*
26117  *
26118  * Decode MXU pool15
26119  *
26120  *  S32MUL, S32MULU, S32EXTRV:
26121  *   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
26122  *  +-----------+---------+---------+---+-------+-------+-----------+
26123  *  |  SPECIAL2 |    rs   |    rt   |x x|  XRd  |  XRa  |MXU__POOL15|
26124  *  +-----------+---------+---------+---+-------+-------+-----------+
26125  *
26126  *  S32EXTR:
26127  *   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
26128  *  +-----------+---------+---------+---+-------+-------+-----------+
26129  *  |  SPECIAL2 |    rb   |   sft5  |x x|  XRd  |  XRa  |MXU__POOL15|
26130  *  +-----------+---------+---------+---+-------+-------+-----------+
26131  *
26132  */
26133 static void decode_opc_mxu__pool15(CPUMIPSState *env, DisasContext *ctx)
26134 {
26135     uint32_t opcode = extract32(ctx->opcode, 14, 2);
26136
26137     switch (opcode) {
26138     case OPC_MXU_S32MUL:
26139         /* TODO: Implement emulation of S32MUL instruction. */
26140         MIPS_INVAL("OPC_MXU_S32MUL");
26141         generate_exception_end(ctx, EXCP_RI);
26142         break;
26143     case OPC_MXU_S32MULU:
26144         /* TODO: Implement emulation of S32MULU instruction. */
26145         MIPS_INVAL("OPC_MXU_S32MULU");
26146         generate_exception_end(ctx, EXCP_RI);
26147         break;
26148     case OPC_MXU_S32EXTR:
26149         /* TODO: Implement emulation of S32EXTR instruction. */
26150         MIPS_INVAL("OPC_MXU_S32EXTR");
26151         generate_exception_end(ctx, EXCP_RI);
26152         break;
26153     case OPC_MXU_S32EXTRV:
26154         /* TODO: Implement emulation of S32EXTRV instruction. */
26155         MIPS_INVAL("OPC_MXU_S32EXTRV");
26156         generate_exception_end(ctx, EXCP_RI);
26157         break;
26158     default:
26159         MIPS_INVAL("decode_opc_mxu");
26160         generate_exception_end(ctx, EXCP_RI);
26161         break;
26162     }
26163 }
26164
26165 /*
26166  *
26167  * Decode MXU pool16
26168  *
26169  *  D32SARW:
26170  *   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
26171  *  +-----------+---------+-----+-------+-------+-------+-----------+
26172  *  |  SPECIAL2 |    rb   |x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
26173  *  +-----------+---------+-----+-------+-------+-------+-----------+
26174  *
26175  *  S32ALN:
26176  *   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
26177  *  +-----------+---------+-----+-------+-------+-------+-----------+
26178  *  |  SPECIAL2 |    rs   |x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
26179  *  +-----------+---------+-----+-------+-------+-------+-----------+
26180  *
26181  *  S32ALNI:
26182  *   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
26183  *  +-----------+-----+---+-----+-------+-------+-------+-----------+
26184  *  |  SPECIAL2 |  s3 |0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
26185  *  +-----------+-----+---+-----+-------+-------+-------+-----------+
26186  *
26187  *  S32LUI:
26188  *   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
26189  *  +-----------+-----+---+-----+-------+---------------+-----------+
26190  *  |  SPECIAL2 |optn3|0 0|x x x|  XRc  |       s8      |MXU__POOL16|
26191  *  +-----------+-----+---+-----+-------+---------------+-----------+
26192  *
26193  *  S32NOR, S32AND, S32OR, S32XOR:
26194  *   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
26195  *  +-----------+---------+-----+-------+-------+-------+-----------+
26196  *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
26197  *  +-----------+---------+-----+-------+-------+-------+-----------+
26198  *
26199  */
26200 static void decode_opc_mxu__pool16(CPUMIPSState *env, DisasContext *ctx)
26201 {
26202     uint32_t opcode = extract32(ctx->opcode, 18, 3);
26203
26204     switch (opcode) {
26205     case OPC_MXU_D32SARW:
26206         /* TODO: Implement emulation of D32SARW instruction. */
26207         MIPS_INVAL("OPC_MXU_D32SARW");
26208         generate_exception_end(ctx, EXCP_RI);
26209         break;
26210     case OPC_MXU_S32ALN:
26211         /* TODO: Implement emulation of S32ALN instruction. */
26212         MIPS_INVAL("OPC_MXU_S32ALN");
26213         generate_exception_end(ctx, EXCP_RI);
26214         break;
26215     case OPC_MXU_S32ALNI:
26216         gen_mxu_S32ALNI(ctx);
26217         break;
26218     case OPC_MXU_S32LUI:
26219         /* TODO: Implement emulation of S32LUI instruction. */
26220         MIPS_INVAL("OPC_MXU_S32LUI");
26221         generate_exception_end(ctx, EXCP_RI);
26222         break;
26223     case OPC_MXU_S32NOR:
26224         gen_mxu_S32NOR(ctx);
26225         break;
26226     case OPC_MXU_S32AND:
26227         gen_mxu_S32AND(ctx);
26228         break;
26229     case OPC_MXU_S32OR:
26230         gen_mxu_S32OR(ctx);
26231         break;
26232     case OPC_MXU_S32XOR:
26233         gen_mxu_S32XOR(ctx);
26234         break;
26235     default:
26236         MIPS_INVAL("decode_opc_mxu");
26237         generate_exception_end(ctx, EXCP_RI);
26238         break;
26239     }
26240 }
26241
26242 /*
26243  *
26244  * Decode MXU pool17
26245  *
26246  *   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
26247  *  +-----------+---------+---------+---+---------+-----+-----------+
26248  *  |  SPECIAL2 |    rs   |    rt   |0 0|    rd   |x x x|MXU__POOL15|
26249  *  +-----------+---------+---------+---+---------+-----+-----------+
26250  *
26251  */
26252 static void decode_opc_mxu__pool17(CPUMIPSState *env, DisasContext *ctx)
26253 {
26254     uint32_t opcode = extract32(ctx->opcode, 6, 2);
26255
26256     switch (opcode) {
26257     case OPC_MXU_LXW:
26258         /* TODO: Implement emulation of LXW instruction. */
26259         MIPS_INVAL("OPC_MXU_LXW");
26260         generate_exception_end(ctx, EXCP_RI);
26261         break;
26262     case OPC_MXU_LXH:
26263         /* TODO: Implement emulation of LXH instruction. */
26264         MIPS_INVAL("OPC_MXU_LXH");
26265         generate_exception_end(ctx, EXCP_RI);
26266         break;
26267     case OPC_MXU_LXHU:
26268         /* TODO: Implement emulation of LXHU instruction. */
26269         MIPS_INVAL("OPC_MXU_LXHU");
26270         generate_exception_end(ctx, EXCP_RI);
26271         break;
26272     case OPC_MXU_LXB:
26273         /* TODO: Implement emulation of LXB instruction. */
26274         MIPS_INVAL("OPC_MXU_LXB");
26275         generate_exception_end(ctx, EXCP_RI);
26276         break;
26277     case OPC_MXU_LXBU:
26278         /* TODO: Implement emulation of LXBU instruction. */
26279         MIPS_INVAL("OPC_MXU_LXBU");
26280         generate_exception_end(ctx, EXCP_RI);
26281         break;
26282     default:
26283         MIPS_INVAL("decode_opc_mxu");
26284         generate_exception_end(ctx, EXCP_RI);
26285         break;
26286     }
26287 }
26288 /*
26289  *
26290  * Decode MXU pool18
26291  *
26292  *   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
26293  *  +-----------+---------+-----+-------+-------+-------+-----------+
26294  *  |  SPECIAL2 |    rb   |x x x|  XRd  |  XRa  |0 0 0 0|MXU__POOL18|
26295  *  +-----------+---------+-----+-------+-------+-------+-----------+
26296  *
26297  */
26298 static void decode_opc_mxu__pool18(CPUMIPSState *env, DisasContext *ctx)
26299 {
26300     uint32_t opcode = extract32(ctx->opcode, 18, 3);
26301
26302     switch (opcode) {
26303     case OPC_MXU_D32SLLV:
26304         /* TODO: Implement emulation of D32SLLV instruction. */
26305         MIPS_INVAL("OPC_MXU_D32SLLV");
26306         generate_exception_end(ctx, EXCP_RI);
26307         break;
26308     case OPC_MXU_D32SLRV:
26309         /* TODO: Implement emulation of D32SLRV instruction. */
26310         MIPS_INVAL("OPC_MXU_D32SLRV");
26311         generate_exception_end(ctx, EXCP_RI);
26312         break;
26313     case OPC_MXU_D32SARV:
26314         /* TODO: Implement emulation of D32SARV instruction. */
26315         MIPS_INVAL("OPC_MXU_D32SARV");
26316         generate_exception_end(ctx, EXCP_RI);
26317         break;
26318     case OPC_MXU_Q16SLLV:
26319         /* TODO: Implement emulation of Q16SLLV instruction. */
26320         MIPS_INVAL("OPC_MXU_Q16SLLV");
26321         generate_exception_end(ctx, EXCP_RI);
26322         break;
26323     case OPC_MXU_Q16SLRV:
26324         /* TODO: Implement emulation of Q16SLRV instruction. */
26325         MIPS_INVAL("OPC_MXU_Q16SLRV");
26326         generate_exception_end(ctx, EXCP_RI);
26327         break;
26328     case OPC_MXU_Q16SARV:
26329         /* TODO: Implement emulation of Q16SARV instruction. */
26330         MIPS_INVAL("OPC_MXU_Q16SARV");
26331         generate_exception_end(ctx, EXCP_RI);
26332         break;
26333     default:
26334         MIPS_INVAL("decode_opc_mxu");
26335         generate_exception_end(ctx, EXCP_RI);
26336         break;
26337     }
26338 }
26339
26340 /*
26341  *
26342  * Decode MXU pool19
26343  *
26344  *   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
26345  *  +-----------+---+---+-------+-------+-------+-------+-----------+
26346  *  |  SPECIAL2 |0 0|x x|  XRd  |  XRc  |  XRb  |  XRa  |MXU__POOL19|
26347  *  +-----------+---+---+-------+-------+-------+-------+-----------+
26348  *
26349  */
26350 static void decode_opc_mxu__pool19(CPUMIPSState *env, DisasContext *ctx)
26351 {
26352     uint32_t opcode = extract32(ctx->opcode, 22, 2);
26353
26354     switch (opcode) {
26355     case OPC_MXU_Q8MUL:
26356     case OPC_MXU_Q8MULSU:
26357         gen_mxu_q8mul_q8mulsu(ctx);
26358         break;
26359     default:
26360         MIPS_INVAL("decode_opc_mxu");
26361         generate_exception_end(ctx, EXCP_RI);
26362         break;
26363     }
26364 }
26365
26366 /*
26367  *
26368  * Decode MXU pool20
26369  *
26370  *   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
26371  *  +-----------+---------+-----+-------+-------+-------+-----------+
26372  *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL20|
26373  *  +-----------+---------+-----+-------+-------+-------+-----------+
26374  *
26375  */
26376 static void decode_opc_mxu__pool20(CPUMIPSState *env, DisasContext *ctx)
26377 {
26378     uint32_t opcode = extract32(ctx->opcode, 18, 3);
26379
26380     switch (opcode) {
26381     case OPC_MXU_Q8MOVZ:
26382         /* TODO: Implement emulation of Q8MOVZ instruction. */
26383         MIPS_INVAL("OPC_MXU_Q8MOVZ");
26384         generate_exception_end(ctx, EXCP_RI);
26385         break;
26386     case OPC_MXU_Q8MOVN:
26387         /* TODO: Implement emulation of Q8MOVN instruction. */
26388         MIPS_INVAL("OPC_MXU_Q8MOVN");
26389         generate_exception_end(ctx, EXCP_RI);
26390         break;
26391     case OPC_MXU_D16MOVZ:
26392         /* TODO: Implement emulation of D16MOVZ instruction. */
26393         MIPS_INVAL("OPC_MXU_D16MOVZ");
26394         generate_exception_end(ctx, EXCP_RI);
26395         break;
26396     case OPC_MXU_D16MOVN:
26397         /* TODO: Implement emulation of D16MOVN instruction. */
26398         MIPS_INVAL("OPC_MXU_D16MOVN");
26399         generate_exception_end(ctx, EXCP_RI);
26400         break;
26401     case OPC_MXU_S32MOVZ:
26402         /* TODO: Implement emulation of S32MOVZ instruction. */
26403         MIPS_INVAL("OPC_MXU_S32MOVZ");
26404         generate_exception_end(ctx, EXCP_RI);
26405         break;
26406     case OPC_MXU_S32MOVN:
26407         /* TODO: Implement emulation of S32MOVN instruction. */
26408         MIPS_INVAL("OPC_MXU_S32MOVN");
26409         generate_exception_end(ctx, EXCP_RI);
26410         break;
26411     default:
26412         MIPS_INVAL("decode_opc_mxu");
26413         generate_exception_end(ctx, EXCP_RI);
26414         break;
26415     }
26416 }
26417
26418 /*
26419  *
26420  * Decode MXU pool21
26421  *
26422  *   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
26423  *  +-----------+---+---+-------+-------+-------+-------+-----------+
26424  *  |  SPECIAL2 |an2|x x|  XRd  |  XRc  |  XRb  |  XRa  |MXU__POOL21|
26425  *  +-----------+---+---+-------+-------+-------+-------+-----------+
26426  *
26427  */
26428 static void decode_opc_mxu__pool21(CPUMIPSState *env, DisasContext *ctx)
26429 {
26430     uint32_t opcode = extract32(ctx->opcode, 22, 2);
26431
26432     switch (opcode) {
26433     case OPC_MXU_Q8MAC:
26434         /* TODO: Implement emulation of Q8MAC instruction. */
26435         MIPS_INVAL("OPC_MXU_Q8MAC");
26436         generate_exception_end(ctx, EXCP_RI);
26437         break;
26438     case OPC_MXU_Q8MACSU:
26439         /* TODO: Implement emulation of Q8MACSU instruction. */
26440         MIPS_INVAL("OPC_MXU_Q8MACSU");
26441         generate_exception_end(ctx, EXCP_RI);
26442         break;
26443     default:
26444         MIPS_INVAL("decode_opc_mxu");
26445         generate_exception_end(ctx, EXCP_RI);
26446         break;
26447     }
26448 }
26449
26450
26451 /*
26452  * Main MXU decoding function
26453  *
26454  *   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
26455  *  +-----------+---------------------------------------+-----------+
26456  *  |  SPECIAL2 |                                       |x x x x x x|
26457  *  +-----------+---------------------------------------+-----------+
26458  *
26459  */
26460 static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx)
26461 {
26462     /*
26463      * TODO: Investigate necessity of including handling of
26464      * CLZ, CLO, SDBB in this function, as they belong to
26465      * SPECIAL2 opcode space for regular pre-R6 MIPS ISAs.
26466      */
26467     uint32_t opcode = extract32(ctx->opcode, 0, 6);
26468
26469     if (opcode == OPC__MXU_MUL) {
26470         uint32_t  rs, rt, rd, op1;
26471
26472         rs = extract32(ctx->opcode, 21, 5);
26473         rt = extract32(ctx->opcode, 16, 5);
26474         rd = extract32(ctx->opcode, 11, 5);
26475         op1 = MASK_SPECIAL2(ctx->opcode);
26476
26477         gen_arith(ctx, op1, rd, rs, rt);
26478
26479         return;
26480     }
26481
26482     if (opcode == OPC_MXU_S32M2I) {
26483         gen_mxu_s32m2i(ctx);
26484         return;
26485     }
26486
26487     if (opcode == OPC_MXU_S32I2M) {
26488         gen_mxu_s32i2m(ctx);
26489         return;
26490     }
26491
26492     {
26493         TCGv t_mxu_cr = tcg_temp_new();
26494         TCGLabel *l_exit = gen_new_label();
26495
26496         gen_load_mxu_cr(t_mxu_cr);
26497         tcg_gen_andi_tl(t_mxu_cr, t_mxu_cr, MXU_CR_MXU_EN);
26498         tcg_gen_brcondi_tl(TCG_COND_NE, t_mxu_cr, MXU_CR_MXU_EN, l_exit);
26499
26500         switch (opcode) {
26501         case OPC_MXU_S32MADD:
26502             /* TODO: Implement emulation of S32MADD instruction. */
26503             MIPS_INVAL("OPC_MXU_S32MADD");
26504             generate_exception_end(ctx, EXCP_RI);
26505             break;
26506         case OPC_MXU_S32MADDU:
26507             /* TODO: Implement emulation of S32MADDU instruction. */
26508             MIPS_INVAL("OPC_MXU_S32MADDU");
26509             generate_exception_end(ctx, EXCP_RI);
26510             break;
26511         case OPC_MXU__POOL00:
26512             decode_opc_mxu__pool00(env, ctx);
26513             break;
26514         case OPC_MXU_S32MSUB:
26515             /* TODO: Implement emulation of S32MSUB instruction. */
26516             MIPS_INVAL("OPC_MXU_S32MSUB");
26517             generate_exception_end(ctx, EXCP_RI);
26518             break;
26519         case OPC_MXU_S32MSUBU:
26520             /* TODO: Implement emulation of S32MSUBU instruction. */
26521             MIPS_INVAL("OPC_MXU_S32MSUBU");
26522             generate_exception_end(ctx, EXCP_RI);
26523             break;
26524         case OPC_MXU__POOL01:
26525             decode_opc_mxu__pool01(env, ctx);
26526             break;
26527         case OPC_MXU__POOL02:
26528             decode_opc_mxu__pool02(env, ctx);
26529             break;
26530         case OPC_MXU_D16MUL:
26531             gen_mxu_d16mul(ctx);
26532             break;
26533         case OPC_MXU__POOL03:
26534             decode_opc_mxu__pool03(env, ctx);
26535             break;
26536         case OPC_MXU_D16MAC:
26537             gen_mxu_d16mac(ctx);
26538             break;
26539         case OPC_MXU_D16MACF:
26540             /* TODO: Implement emulation of D16MACF instruction. */
26541             MIPS_INVAL("OPC_MXU_D16MACF");
26542             generate_exception_end(ctx, EXCP_RI);
26543             break;
26544         case OPC_MXU_D16MADL:
26545             /* TODO: Implement emulation of D16MADL instruction. */
26546             MIPS_INVAL("OPC_MXU_D16MADL");
26547             generate_exception_end(ctx, EXCP_RI);
26548             break;
26549         case OPC_MXU_S16MAD:
26550             /* TODO: Implement emulation of S16MAD instruction. */
26551             MIPS_INVAL("OPC_MXU_S16MAD");
26552             generate_exception_end(ctx, EXCP_RI);
26553             break;
26554         case OPC_MXU_Q16ADD:
26555             /* TODO: Implement emulation of Q16ADD instruction. */
26556             MIPS_INVAL("OPC_MXU_Q16ADD");
26557             generate_exception_end(ctx, EXCP_RI);
26558             break;
26559         case OPC_MXU_D16MACE:
26560             /* TODO: Implement emulation of D16MACE instruction. */
26561             MIPS_INVAL("OPC_MXU_D16MACE");
26562             generate_exception_end(ctx, EXCP_RI);
26563             break;
26564         case OPC_MXU__POOL04:
26565             decode_opc_mxu__pool04(env, ctx);
26566             break;
26567         case OPC_MXU__POOL05:
26568             decode_opc_mxu__pool05(env, ctx);
26569             break;
26570         case OPC_MXU__POOL06:
26571             decode_opc_mxu__pool06(env, ctx);
26572             break;
26573         case OPC_MXU__POOL07:
26574             decode_opc_mxu__pool07(env, ctx);
26575             break;
26576         case OPC_MXU__POOL08:
26577             decode_opc_mxu__pool08(env, ctx);
26578             break;
26579         case OPC_MXU__POOL09:
26580             decode_opc_mxu__pool09(env, ctx);
26581             break;
26582         case OPC_MXU__POOL10:
26583             decode_opc_mxu__pool10(env, ctx);
26584             break;
26585         case OPC_MXU__POOL11:
26586             decode_opc_mxu__pool11(env, ctx);
26587             break;
26588         case OPC_MXU_D32ADD:
26589             /* TODO: Implement emulation of D32ADD instruction. */
26590             MIPS_INVAL("OPC_MXU_D32ADD");
26591             generate_exception_end(ctx, EXCP_RI);
26592             break;
26593         case OPC_MXU__POOL12:
26594             decode_opc_mxu__pool12(env, ctx);
26595             break;
26596         case OPC_MXU__POOL13:
26597             decode_opc_mxu__pool13(env, ctx);
26598             break;
26599         case OPC_MXU__POOL14:
26600             decode_opc_mxu__pool14(env, ctx);
26601             break;
26602         case OPC_MXU_Q8ACCE:
26603             /* TODO: Implement emulation of Q8ACCE instruction. */
26604             MIPS_INVAL("OPC_MXU_Q8ACCE");
26605             generate_exception_end(ctx, EXCP_RI);
26606             break;
26607         case OPC_MXU_S8LDD:
26608             gen_mxu_s8ldd(ctx);
26609             break;
26610         case OPC_MXU_S8STD:
26611             /* TODO: Implement emulation of S8STD instruction. */
26612             MIPS_INVAL("OPC_MXU_S8STD");
26613             generate_exception_end(ctx, EXCP_RI);
26614             break;
26615         case OPC_MXU_S8LDI:
26616             /* TODO: Implement emulation of S8LDI instruction. */
26617             MIPS_INVAL("OPC_MXU_S8LDI");
26618             generate_exception_end(ctx, EXCP_RI);
26619             break;
26620         case OPC_MXU_S8SDI:
26621             /* TODO: Implement emulation of S8SDI instruction. */
26622             MIPS_INVAL("OPC_MXU_S8SDI");
26623             generate_exception_end(ctx, EXCP_RI);
26624             break;
26625         case OPC_MXU__POOL15:
26626             decode_opc_mxu__pool15(env, ctx);
26627             break;
26628         case OPC_MXU__POOL16:
26629             decode_opc_mxu__pool16(env, ctx);
26630             break;
26631         case OPC_MXU__POOL17:
26632             decode_opc_mxu__pool17(env, ctx);
26633             break;
26634         case OPC_MXU_S16LDD:
26635             /* TODO: Implement emulation of S16LDD instruction. */
26636             MIPS_INVAL("OPC_MXU_S16LDD");
26637             generate_exception_end(ctx, EXCP_RI);
26638             break;
26639         case OPC_MXU_S16STD:
26640             /* TODO: Implement emulation of S16STD instruction. */
26641             MIPS_INVAL("OPC_MXU_S16STD");
26642             generate_exception_end(ctx, EXCP_RI);
26643             break;
26644         case OPC_MXU_S16LDI:
26645             /* TODO: Implement emulation of S16LDI instruction. */
26646             MIPS_INVAL("OPC_MXU_S16LDI");
26647             generate_exception_end(ctx, EXCP_RI);
26648             break;
26649         case OPC_MXU_S16SDI:
26650             /* TODO: Implement emulation of S16SDI instruction. */
26651             MIPS_INVAL("OPC_MXU_S16SDI");
26652             generate_exception_end(ctx, EXCP_RI);
26653             break;
26654         case OPC_MXU_D32SLL:
26655             /* TODO: Implement emulation of D32SLL instruction. */
26656             MIPS_INVAL("OPC_MXU_D32SLL");
26657             generate_exception_end(ctx, EXCP_RI);
26658             break;
26659         case OPC_MXU_D32SLR:
26660             /* TODO: Implement emulation of D32SLR instruction. */
26661             MIPS_INVAL("OPC_MXU_D32SLR");
26662             generate_exception_end(ctx, EXCP_RI);
26663             break;
26664         case OPC_MXU_D32SARL:
26665             /* TODO: Implement emulation of D32SARL instruction. */
26666             MIPS_INVAL("OPC_MXU_D32SARL");
26667             generate_exception_end(ctx, EXCP_RI);
26668             break;
26669         case OPC_MXU_D32SAR:
26670             /* TODO: Implement emulation of D32SAR instruction. */
26671             MIPS_INVAL("OPC_MXU_D32SAR");
26672             generate_exception_end(ctx, EXCP_RI);
26673             break;
26674         case OPC_MXU_Q16SLL:
26675             /* TODO: Implement emulation of Q16SLL instruction. */
26676             MIPS_INVAL("OPC_MXU_Q16SLL");
26677             generate_exception_end(ctx, EXCP_RI);
26678             break;
26679         case OPC_MXU_Q16SLR:
26680             /* TODO: Implement emulation of Q16SLR instruction. */
26681             MIPS_INVAL("OPC_MXU_Q16SLR");
26682             generate_exception_end(ctx, EXCP_RI);
26683             break;
26684         case OPC_MXU__POOL18:
26685             decode_opc_mxu__pool18(env, ctx);
26686             break;
26687         case OPC_MXU_Q16SAR:
26688             /* TODO: Implement emulation of Q16SAR instruction. */
26689             MIPS_INVAL("OPC_MXU_Q16SAR");
26690             generate_exception_end(ctx, EXCP_RI);
26691             break;
26692         case OPC_MXU__POOL19:
26693             decode_opc_mxu__pool19(env, ctx);
26694             break;
26695         case OPC_MXU__POOL20:
26696             decode_opc_mxu__pool20(env, ctx);
26697             break;
26698         case OPC_MXU__POOL21:
26699             decode_opc_mxu__pool21(env, ctx);
26700             break;
26701         case OPC_MXU_Q16SCOP:
26702             /* TODO: Implement emulation of Q16SCOP instruction. */
26703             MIPS_INVAL("OPC_MXU_Q16SCOP");
26704             generate_exception_end(ctx, EXCP_RI);
26705             break;
26706         case OPC_MXU_Q8MADL:
26707             /* TODO: Implement emulation of Q8MADL instruction. */
26708             MIPS_INVAL("OPC_MXU_Q8MADL");
26709             generate_exception_end(ctx, EXCP_RI);
26710             break;
26711         case OPC_MXU_S32SFL:
26712             /* TODO: Implement emulation of S32SFL instruction. */
26713             MIPS_INVAL("OPC_MXU_S32SFL");
26714             generate_exception_end(ctx, EXCP_RI);
26715             break;
26716         case OPC_MXU_Q8SAD:
26717             /* TODO: Implement emulation of Q8SAD instruction. */
26718             MIPS_INVAL("OPC_MXU_Q8SAD");
26719             generate_exception_end(ctx, EXCP_RI);
26720             break;
26721         default:
26722             MIPS_INVAL("decode_opc_mxu");
26723             generate_exception_end(ctx, EXCP_RI);
26724         }
26725
26726         gen_set_label(l_exit);
26727         tcg_temp_free(t_mxu_cr);
26728     }
26729 }
26730
26731 #endif /* !defined(TARGET_MIPS64) */
26732
26733
26734 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
26735 {
26736     int rs, rt, rd;
26737     uint32_t op1;
26738
26739     check_insn_opc_removed(ctx, ISA_MIPS32R6);
26740
26741     rs = (ctx->opcode >> 21) & 0x1f;
26742     rt = (ctx->opcode >> 16) & 0x1f;
26743     rd = (ctx->opcode >> 11) & 0x1f;
26744
26745     op1 = MASK_SPECIAL2(ctx->opcode);
26746     switch (op1) {
26747     case OPC_MADD: /* Multiply and add/sub */
26748     case OPC_MADDU:
26749     case OPC_MSUB:
26750     case OPC_MSUBU:
26751         check_insn(ctx, ISA_MIPS32);
26752         gen_muldiv(ctx, op1, rd & 3, rs, rt);
26753         break;
26754     case OPC_MUL:
26755         gen_arith(ctx, op1, rd, rs, rt);
26756         break;
26757     case OPC_DIV_G_2F:
26758     case OPC_DIVU_G_2F:
26759     case OPC_MULT_G_2F:
26760     case OPC_MULTU_G_2F:
26761     case OPC_MOD_G_2F:
26762     case OPC_MODU_G_2F:
26763         check_insn(ctx, INSN_LOONGSON2F);
26764         gen_loongson_integer(ctx, op1, rd, rs, rt);
26765         break;
26766     case OPC_CLO:
26767     case OPC_CLZ:
26768         check_insn(ctx, ISA_MIPS32);
26769         gen_cl(ctx, op1, rd, rs);
26770         break;
26771     case OPC_SDBBP:
26772         if (is_uhi(extract32(ctx->opcode, 6, 20))) {
26773             gen_helper_do_semihosting(cpu_env);
26774         } else {
26775             /* XXX: not clear which exception should be raised
26776              *      when in debug mode...
26777              */
26778             check_insn(ctx, ISA_MIPS32);
26779             generate_exception_end(ctx, EXCP_DBp);
26780         }
26781         break;
26782 #if defined(TARGET_MIPS64)
26783     case OPC_DCLO:
26784     case OPC_DCLZ:
26785         check_insn(ctx, ISA_MIPS64);
26786         check_mips_64(ctx);
26787         gen_cl(ctx, op1, rd, rs);
26788         break;
26789     case OPC_DMULT_G_2F:
26790     case OPC_DMULTU_G_2F:
26791     case OPC_DDIV_G_2F:
26792     case OPC_DDIVU_G_2F:
26793     case OPC_DMOD_G_2F:
26794     case OPC_DMODU_G_2F:
26795         check_insn(ctx, INSN_LOONGSON2F);
26796         gen_loongson_integer(ctx, op1, rd, rs, rt);
26797         break;
26798 #endif
26799     default:            /* Invalid */
26800         MIPS_INVAL("special2_legacy");
26801         generate_exception_end(ctx, EXCP_RI);
26802         break;
26803     }
26804 }
26805
26806 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
26807 {
26808     int rs, rt, rd, sa;
26809     uint32_t op1, op2;
26810     int16_t imm;
26811
26812     rs = (ctx->opcode >> 21) & 0x1f;
26813     rt = (ctx->opcode >> 16) & 0x1f;
26814     rd = (ctx->opcode >> 11) & 0x1f;
26815     sa = (ctx->opcode >> 6) & 0x1f;
26816     imm = (int16_t)ctx->opcode >> 7;
26817
26818     op1 = MASK_SPECIAL3(ctx->opcode);
26819     switch (op1) {
26820     case R6_OPC_PREF:
26821         if (rt >= 24) {
26822             /* hint codes 24-31 are reserved and signal RI */
26823             generate_exception_end(ctx, EXCP_RI);
26824         }
26825         /* Treat as NOP. */
26826         break;
26827     case R6_OPC_CACHE:
26828         check_cp0_enabled(ctx);
26829         if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
26830             gen_cache_operation(ctx, rt, rs, imm);
26831         }
26832         break;
26833     case R6_OPC_SC:
26834         gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
26835         break;
26836     case R6_OPC_LL:
26837         gen_ld(ctx, op1, rt, rs, imm);
26838         break;
26839     case OPC_BSHFL:
26840         {
26841             if (rd == 0) {
26842                 /* Treat as NOP. */
26843                 break;
26844             }
26845             op2 = MASK_BSHFL(ctx->opcode);
26846             switch (op2) {
26847             case OPC_ALIGN:
26848             case OPC_ALIGN_1:
26849             case OPC_ALIGN_2:
26850             case OPC_ALIGN_3:
26851                 gen_align(ctx, 32, rd, rs, rt, sa & 3);
26852                 break;
26853             case OPC_BITSWAP:
26854                 gen_bitswap(ctx, op2, rd, rt);
26855                 break;
26856             }
26857         }
26858         break;
26859 #if defined(TARGET_MIPS64)
26860     case R6_OPC_SCD:
26861         gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false);
26862         break;
26863     case R6_OPC_LLD:
26864         gen_ld(ctx, op1, rt, rs, imm);
26865         break;
26866     case OPC_DBSHFL:
26867         check_mips_64(ctx);
26868         {
26869             if (rd == 0) {
26870                 /* Treat as NOP. */
26871                 break;
26872             }
26873             op2 = MASK_DBSHFL(ctx->opcode);
26874             switch (op2) {
26875             case OPC_DALIGN:
26876             case OPC_DALIGN_1:
26877             case OPC_DALIGN_2:
26878             case OPC_DALIGN_3:
26879             case OPC_DALIGN_4:
26880             case OPC_DALIGN_5:
26881             case OPC_DALIGN_6:
26882             case OPC_DALIGN_7:
26883                 gen_align(ctx, 64, rd, rs, rt, sa & 7);
26884                 break;
26885             case OPC_DBITSWAP:
26886                 gen_bitswap(ctx, op2, rd, rt);
26887                 break;
26888             }
26889
26890         }
26891         break;
26892 #endif
26893     default:            /* Invalid */
26894         MIPS_INVAL("special3_r6");
26895         generate_exception_end(ctx, EXCP_RI);
26896         break;
26897     }
26898 }
26899
26900 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
26901 {
26902     int rs, rt, rd;
26903     uint32_t op1, op2;
26904
26905     rs = (ctx->opcode >> 21) & 0x1f;
26906     rt = (ctx->opcode >> 16) & 0x1f;
26907     rd = (ctx->opcode >> 11) & 0x1f;
26908
26909     op1 = MASK_SPECIAL3(ctx->opcode);
26910     switch (op1) {
26911     case OPC_DIV_G_2E:
26912     case OPC_DIVU_G_2E:
26913     case OPC_MOD_G_2E:
26914     case OPC_MODU_G_2E:
26915     case OPC_MULT_G_2E:
26916     case OPC_MULTU_G_2E:
26917         /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
26918          * the same mask and op1. */
26919         if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
26920             op2 = MASK_ADDUH_QB(ctx->opcode);
26921             switch (op2) {
26922             case OPC_ADDUH_QB:
26923             case OPC_ADDUH_R_QB:
26924             case OPC_ADDQH_PH:
26925             case OPC_ADDQH_R_PH:
26926             case OPC_ADDQH_W:
26927             case OPC_ADDQH_R_W:
26928             case OPC_SUBUH_QB:
26929             case OPC_SUBUH_R_QB:
26930             case OPC_SUBQH_PH:
26931             case OPC_SUBQH_R_PH:
26932             case OPC_SUBQH_W:
26933             case OPC_SUBQH_R_W:
26934                 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26935                 break;
26936             case OPC_MUL_PH:
26937             case OPC_MUL_S_PH:
26938             case OPC_MULQ_S_W:
26939             case OPC_MULQ_RS_W:
26940                 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
26941                 break;
26942             default:
26943                 MIPS_INVAL("MASK ADDUH.QB");
26944                 generate_exception_end(ctx, EXCP_RI);
26945                 break;
26946             }
26947         } else if (ctx->insn_flags & INSN_LOONGSON2E) {
26948             gen_loongson_integer(ctx, op1, rd, rs, rt);
26949         } else {
26950             generate_exception_end(ctx, EXCP_RI);
26951         }
26952         break;
26953     case OPC_LX_DSP:
26954         op2 = MASK_LX(ctx->opcode);
26955         switch (op2) {
26956 #if defined(TARGET_MIPS64)
26957         case OPC_LDX:
26958 #endif
26959         case OPC_LBUX:
26960         case OPC_LHX:
26961         case OPC_LWX:
26962             gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
26963             break;
26964         default:            /* Invalid */
26965             MIPS_INVAL("MASK LX");
26966             generate_exception_end(ctx, EXCP_RI);
26967             break;
26968         }
26969         break;
26970     case OPC_ABSQ_S_PH_DSP:
26971         op2 = MASK_ABSQ_S_PH(ctx->opcode);
26972         switch (op2) {
26973         case OPC_ABSQ_S_QB:
26974         case OPC_ABSQ_S_PH:
26975         case OPC_ABSQ_S_W:
26976         case OPC_PRECEQ_W_PHL:
26977         case OPC_PRECEQ_W_PHR:
26978         case OPC_PRECEQU_PH_QBL:
26979         case OPC_PRECEQU_PH_QBR:
26980         case OPC_PRECEQU_PH_QBLA:
26981         case OPC_PRECEQU_PH_QBRA:
26982         case OPC_PRECEU_PH_QBL:
26983         case OPC_PRECEU_PH_QBR:
26984         case OPC_PRECEU_PH_QBLA:
26985         case OPC_PRECEU_PH_QBRA:
26986             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26987             break;
26988         case OPC_BITREV:
26989         case OPC_REPL_QB:
26990         case OPC_REPLV_QB:
26991         case OPC_REPL_PH:
26992         case OPC_REPLV_PH:
26993             gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
26994             break;
26995         default:
26996             MIPS_INVAL("MASK ABSQ_S.PH");
26997             generate_exception_end(ctx, EXCP_RI);
26998             break;
26999         }
27000         break;
27001     case OPC_ADDU_QB_DSP:
27002         op2 = MASK_ADDU_QB(ctx->opcode);
27003         switch (op2) {
27004         case OPC_ADDQ_PH:
27005         case OPC_ADDQ_S_PH:
27006         case OPC_ADDQ_S_W:
27007         case OPC_ADDU_QB:
27008         case OPC_ADDU_S_QB:
27009         case OPC_ADDU_PH:
27010         case OPC_ADDU_S_PH:
27011         case OPC_SUBQ_PH:
27012         case OPC_SUBQ_S_PH:
27013         case OPC_SUBQ_S_W:
27014         case OPC_SUBU_QB:
27015         case OPC_SUBU_S_QB:
27016         case OPC_SUBU_PH:
27017         case OPC_SUBU_S_PH:
27018         case OPC_ADDSC:
27019         case OPC_ADDWC:
27020         case OPC_MODSUB:
27021         case OPC_RADDU_W_QB:
27022             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27023             break;
27024         case OPC_MULEU_S_PH_QBL:
27025         case OPC_MULEU_S_PH_QBR:
27026         case OPC_MULQ_RS_PH:
27027         case OPC_MULEQ_S_W_PHL:
27028         case OPC_MULEQ_S_W_PHR:
27029         case OPC_MULQ_S_PH:
27030             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
27031             break;
27032         default:            /* Invalid */
27033             MIPS_INVAL("MASK ADDU.QB");
27034             generate_exception_end(ctx, EXCP_RI);
27035             break;
27036
27037         }
27038         break;
27039     case OPC_CMPU_EQ_QB_DSP:
27040         op2 = MASK_CMPU_EQ_QB(ctx->opcode);
27041         switch (op2) {
27042         case OPC_PRECR_SRA_PH_W:
27043         case OPC_PRECR_SRA_R_PH_W:
27044             gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
27045             break;
27046         case OPC_PRECR_QB_PH:
27047         case OPC_PRECRQ_QB_PH:
27048         case OPC_PRECRQ_PH_W:
27049         case OPC_PRECRQ_RS_PH_W:
27050         case OPC_PRECRQU_S_QB_PH:
27051             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27052             break;
27053         case OPC_CMPU_EQ_QB:
27054         case OPC_CMPU_LT_QB:
27055         case OPC_CMPU_LE_QB:
27056         case OPC_CMP_EQ_PH:
27057         case OPC_CMP_LT_PH:
27058         case OPC_CMP_LE_PH:
27059             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
27060             break;
27061         case OPC_CMPGU_EQ_QB:
27062         case OPC_CMPGU_LT_QB:
27063         case OPC_CMPGU_LE_QB:
27064         case OPC_CMPGDU_EQ_QB:
27065         case OPC_CMPGDU_LT_QB:
27066         case OPC_CMPGDU_LE_QB:
27067         case OPC_PICK_QB:
27068         case OPC_PICK_PH:
27069         case OPC_PACKRL_PH:
27070             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
27071             break;
27072         default:            /* Invalid */
27073             MIPS_INVAL("MASK CMPU.EQ.QB");
27074             generate_exception_end(ctx, EXCP_RI);
27075             break;
27076         }
27077         break;
27078     case OPC_SHLL_QB_DSP:
27079         gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
27080         break;
27081     case OPC_DPA_W_PH_DSP:
27082         op2 = MASK_DPA_W_PH(ctx->opcode);
27083         switch (op2) {
27084         case OPC_DPAU_H_QBL:
27085         case OPC_DPAU_H_QBR:
27086         case OPC_DPSU_H_QBL:
27087         case OPC_DPSU_H_QBR:
27088         case OPC_DPA_W_PH:
27089         case OPC_DPAX_W_PH:
27090         case OPC_DPAQ_S_W_PH:
27091         case OPC_DPAQX_S_W_PH:
27092         case OPC_DPAQX_SA_W_PH:
27093         case OPC_DPS_W_PH:
27094         case OPC_DPSX_W_PH:
27095         case OPC_DPSQ_S_W_PH:
27096         case OPC_DPSQX_S_W_PH:
27097         case OPC_DPSQX_SA_W_PH:
27098         case OPC_MULSAQ_S_W_PH:
27099         case OPC_DPAQ_SA_L_W:
27100         case OPC_DPSQ_SA_L_W:
27101         case OPC_MAQ_S_W_PHL:
27102         case OPC_MAQ_S_W_PHR:
27103         case OPC_MAQ_SA_W_PHL:
27104         case OPC_MAQ_SA_W_PHR:
27105         case OPC_MULSA_W_PH:
27106             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
27107             break;
27108         default:            /* Invalid */
27109             MIPS_INVAL("MASK DPAW.PH");
27110             generate_exception_end(ctx, EXCP_RI);
27111             break;
27112         }
27113         break;
27114     case OPC_INSV_DSP:
27115         op2 = MASK_INSV(ctx->opcode);
27116         switch (op2) {
27117         case OPC_INSV:
27118             check_dsp(ctx);
27119             {
27120                 TCGv t0, t1;
27121
27122                 if (rt == 0) {
27123                     break;
27124                 }
27125
27126                 t0 = tcg_temp_new();
27127                 t1 = tcg_temp_new();
27128
27129                 gen_load_gpr(t0, rt);
27130                 gen_load_gpr(t1, rs);
27131
27132                 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
27133
27134                 tcg_temp_free(t0);
27135                 tcg_temp_free(t1);
27136                 break;
27137             }
27138         default:            /* Invalid */
27139             MIPS_INVAL("MASK INSV");
27140             generate_exception_end(ctx, EXCP_RI);
27141             break;
27142         }
27143         break;
27144     case OPC_APPEND_DSP:
27145         gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
27146         break;
27147     case OPC_EXTR_W_DSP:
27148         op2 = MASK_EXTR_W(ctx->opcode);
27149         switch (op2) {
27150         case OPC_EXTR_W:
27151         case OPC_EXTR_R_W:
27152         case OPC_EXTR_RS_W:
27153         case OPC_EXTR_S_H:
27154         case OPC_EXTRV_S_H:
27155         case OPC_EXTRV_W:
27156         case OPC_EXTRV_R_W:
27157         case OPC_EXTRV_RS_W:
27158         case OPC_EXTP:
27159         case OPC_EXTPV:
27160         case OPC_EXTPDP:
27161         case OPC_EXTPDPV:
27162             gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
27163             break;
27164         case OPC_RDDSP:
27165             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
27166             break;
27167         case OPC_SHILO:
27168         case OPC_SHILOV:
27169         case OPC_MTHLIP:
27170         case OPC_WRDSP:
27171             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
27172             break;
27173         default:            /* Invalid */
27174             MIPS_INVAL("MASK EXTR.W");
27175             generate_exception_end(ctx, EXCP_RI);
27176             break;
27177         }
27178         break;
27179 #if defined(TARGET_MIPS64)
27180     case OPC_DDIV_G_2E:
27181     case OPC_DDIVU_G_2E:
27182     case OPC_DMULT_G_2E:
27183     case OPC_DMULTU_G_2E:
27184     case OPC_DMOD_G_2E:
27185     case OPC_DMODU_G_2E:
27186         check_insn(ctx, INSN_LOONGSON2E);
27187         gen_loongson_integer(ctx, op1, rd, rs, rt);
27188         break;
27189     case OPC_ABSQ_S_QH_DSP:
27190         op2 = MASK_ABSQ_S_QH(ctx->opcode);
27191         switch (op2) {
27192         case OPC_PRECEQ_L_PWL:
27193         case OPC_PRECEQ_L_PWR:
27194         case OPC_PRECEQ_PW_QHL:
27195         case OPC_PRECEQ_PW_QHR:
27196         case OPC_PRECEQ_PW_QHLA:
27197         case OPC_PRECEQ_PW_QHRA:
27198         case OPC_PRECEQU_QH_OBL:
27199         case OPC_PRECEQU_QH_OBR:
27200         case OPC_PRECEQU_QH_OBLA:
27201         case OPC_PRECEQU_QH_OBRA:
27202         case OPC_PRECEU_QH_OBL:
27203         case OPC_PRECEU_QH_OBR:
27204         case OPC_PRECEU_QH_OBLA:
27205         case OPC_PRECEU_QH_OBRA:
27206         case OPC_ABSQ_S_OB:
27207         case OPC_ABSQ_S_PW:
27208         case OPC_ABSQ_S_QH:
27209             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27210             break;
27211         case OPC_REPL_OB:
27212         case OPC_REPL_PW:
27213         case OPC_REPL_QH:
27214         case OPC_REPLV_OB:
27215         case OPC_REPLV_PW:
27216         case OPC_REPLV_QH:
27217             gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
27218             break;
27219         default:            /* Invalid */
27220             MIPS_INVAL("MASK ABSQ_S.QH");
27221             generate_exception_end(ctx, EXCP_RI);
27222             break;
27223         }
27224         break;
27225     case OPC_ADDU_OB_DSP:
27226         op2 = MASK_ADDU_OB(ctx->opcode);
27227         switch (op2) {
27228         case OPC_RADDU_L_OB:
27229         case OPC_SUBQ_PW:
27230         case OPC_SUBQ_S_PW:
27231         case OPC_SUBQ_QH:
27232         case OPC_SUBQ_S_QH:
27233         case OPC_SUBU_OB:
27234         case OPC_SUBU_S_OB:
27235         case OPC_SUBU_QH:
27236         case OPC_SUBU_S_QH:
27237         case OPC_SUBUH_OB:
27238         case OPC_SUBUH_R_OB:
27239         case OPC_ADDQ_PW:
27240         case OPC_ADDQ_S_PW:
27241         case OPC_ADDQ_QH:
27242         case OPC_ADDQ_S_QH:
27243         case OPC_ADDU_OB:
27244         case OPC_ADDU_S_OB:
27245         case OPC_ADDU_QH:
27246         case OPC_ADDU_S_QH:
27247         case OPC_ADDUH_OB:
27248         case OPC_ADDUH_R_OB:
27249             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27250             break;
27251         case OPC_MULEQ_S_PW_QHL:
27252         case OPC_MULEQ_S_PW_QHR:
27253         case OPC_MULEU_S_QH_OBL:
27254         case OPC_MULEU_S_QH_OBR:
27255         case OPC_MULQ_RS_QH:
27256             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
27257             break;
27258         default:            /* Invalid */
27259             MIPS_INVAL("MASK ADDU.OB");
27260             generate_exception_end(ctx, EXCP_RI);
27261             break;
27262         }
27263         break;
27264     case OPC_CMPU_EQ_OB_DSP:
27265         op2 = MASK_CMPU_EQ_OB(ctx->opcode);
27266         switch (op2) {
27267         case OPC_PRECR_SRA_QH_PW:
27268         case OPC_PRECR_SRA_R_QH_PW:
27269             /* Return value is rt. */
27270             gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
27271             break;
27272         case OPC_PRECR_OB_QH:
27273         case OPC_PRECRQ_OB_QH:
27274         case OPC_PRECRQ_PW_L:
27275         case OPC_PRECRQ_QH_PW:
27276         case OPC_PRECRQ_RS_QH_PW:
27277         case OPC_PRECRQU_S_OB_QH:
27278             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27279             break;
27280         case OPC_CMPU_EQ_OB:
27281         case OPC_CMPU_LT_OB:
27282         case OPC_CMPU_LE_OB:
27283         case OPC_CMP_EQ_QH:
27284         case OPC_CMP_LT_QH:
27285         case OPC_CMP_LE_QH:
27286         case OPC_CMP_EQ_PW:
27287         case OPC_CMP_LT_PW:
27288         case OPC_CMP_LE_PW:
27289             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
27290             break;
27291         case OPC_CMPGDU_EQ_OB:
27292         case OPC_CMPGDU_LT_OB:
27293         case OPC_CMPGDU_LE_OB:
27294         case OPC_CMPGU_EQ_OB:
27295         case OPC_CMPGU_LT_OB:
27296         case OPC_CMPGU_LE_OB:
27297         case OPC_PACKRL_PW:
27298         case OPC_PICK_OB:
27299         case OPC_PICK_PW:
27300         case OPC_PICK_QH:
27301             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
27302             break;
27303         default:            /* Invalid */
27304             MIPS_INVAL("MASK CMPU_EQ.OB");
27305             generate_exception_end(ctx, EXCP_RI);
27306             break;
27307         }
27308         break;
27309     case OPC_DAPPEND_DSP:
27310         gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
27311         break;
27312     case OPC_DEXTR_W_DSP:
27313         op2 = MASK_DEXTR_W(ctx->opcode);
27314         switch (op2) {
27315         case OPC_DEXTP:
27316         case OPC_DEXTPDP:
27317         case OPC_DEXTPDPV:
27318         case OPC_DEXTPV:
27319         case OPC_DEXTR_L:
27320         case OPC_DEXTR_R_L:
27321         case OPC_DEXTR_RS_L:
27322         case OPC_DEXTR_W:
27323         case OPC_DEXTR_R_W:
27324         case OPC_DEXTR_RS_W:
27325         case OPC_DEXTR_S_H:
27326         case OPC_DEXTRV_L:
27327         case OPC_DEXTRV_R_L:
27328         case OPC_DEXTRV_RS_L:
27329         case OPC_DEXTRV_S_H:
27330         case OPC_DEXTRV_W:
27331         case OPC_DEXTRV_R_W:
27332         case OPC_DEXTRV_RS_W:
27333             gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
27334             break;
27335         case OPC_DMTHLIP:
27336         case OPC_DSHILO:
27337         case OPC_DSHILOV:
27338             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
27339             break;
27340         default:            /* Invalid */
27341             MIPS_INVAL("MASK EXTR.W");
27342             generate_exception_end(ctx, EXCP_RI);
27343             break;
27344         }
27345         break;
27346     case OPC_DPAQ_W_QH_DSP:
27347         op2 = MASK_DPAQ_W_QH(ctx->opcode);
27348         switch (op2) {
27349         case OPC_DPAU_H_OBL:
27350         case OPC_DPAU_H_OBR:
27351         case OPC_DPSU_H_OBL:
27352         case OPC_DPSU_H_OBR:
27353         case OPC_DPA_W_QH:
27354         case OPC_DPAQ_S_W_QH:
27355         case OPC_DPS_W_QH:
27356         case OPC_DPSQ_S_W_QH:
27357         case OPC_MULSAQ_S_W_QH:
27358         case OPC_DPAQ_SA_L_PW:
27359         case OPC_DPSQ_SA_L_PW:
27360         case OPC_MULSAQ_S_L_PW:
27361             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
27362             break;
27363         case OPC_MAQ_S_W_QHLL:
27364         case OPC_MAQ_S_W_QHLR:
27365         case OPC_MAQ_S_W_QHRL:
27366         case OPC_MAQ_S_W_QHRR:
27367         case OPC_MAQ_SA_W_QHLL:
27368         case OPC_MAQ_SA_W_QHLR:
27369         case OPC_MAQ_SA_W_QHRL:
27370         case OPC_MAQ_SA_W_QHRR:
27371         case OPC_MAQ_S_L_PWL:
27372         case OPC_MAQ_S_L_PWR:
27373         case OPC_DMADD:
27374         case OPC_DMADDU:
27375         case OPC_DMSUB:
27376         case OPC_DMSUBU:
27377             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
27378             break;
27379         default:            /* Invalid */
27380             MIPS_INVAL("MASK DPAQ.W.QH");
27381             generate_exception_end(ctx, EXCP_RI);
27382             break;
27383         }
27384         break;
27385     case OPC_DINSV_DSP:
27386         op2 = MASK_INSV(ctx->opcode);
27387         switch (op2) {
27388         case OPC_DINSV:
27389         {
27390             TCGv t0, t1;
27391
27392             if (rt == 0) {
27393                 break;
27394             }
27395             check_dsp(ctx);
27396
27397             t0 = tcg_temp_new();
27398             t1 = tcg_temp_new();
27399
27400             gen_load_gpr(t0, rt);
27401             gen_load_gpr(t1, rs);
27402
27403             gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
27404
27405             tcg_temp_free(t0);
27406             tcg_temp_free(t1);
27407             break;
27408         }
27409         default:            /* Invalid */
27410             MIPS_INVAL("MASK DINSV");
27411             generate_exception_end(ctx, EXCP_RI);
27412             break;
27413         }
27414         break;
27415     case OPC_SHLL_OB_DSP:
27416         gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
27417         break;
27418 #endif
27419     default:            /* Invalid */
27420         MIPS_INVAL("special3_legacy");
27421         generate_exception_end(ctx, EXCP_RI);
27422         break;
27423     }
27424 }
27425
27426
27427 #if defined(TARGET_MIPS64)
27428
27429 static void decode_mmi0(CPUMIPSState *env, DisasContext *ctx)
27430 {
27431     uint32_t opc = MASK_MMI0(ctx->opcode);
27432
27433     switch (opc) {
27434     case MMI_OPC_0_PADDW:     /* TODO: MMI_OPC_0_PADDW */
27435     case MMI_OPC_0_PSUBW:     /* TODO: MMI_OPC_0_PSUBW */
27436     case MMI_OPC_0_PCGTW:     /* TODO: MMI_OPC_0_PCGTW */
27437     case MMI_OPC_0_PMAXW:     /* TODO: MMI_OPC_0_PMAXW */
27438     case MMI_OPC_0_PADDH:     /* TODO: MMI_OPC_0_PADDH */
27439     case MMI_OPC_0_PSUBH:     /* TODO: MMI_OPC_0_PSUBH */
27440     case MMI_OPC_0_PCGTH:     /* TODO: MMI_OPC_0_PCGTH */
27441     case MMI_OPC_0_PMAXH:     /* TODO: MMI_OPC_0_PMAXH */
27442     case MMI_OPC_0_PADDB:     /* TODO: MMI_OPC_0_PADDB */
27443     case MMI_OPC_0_PSUBB:     /* TODO: MMI_OPC_0_PSUBB */
27444     case MMI_OPC_0_PCGTB:     /* TODO: MMI_OPC_0_PCGTB */
27445     case MMI_OPC_0_PADDSW:    /* TODO: MMI_OPC_0_PADDSW */
27446     case MMI_OPC_0_PSUBSW:    /* TODO: MMI_OPC_0_PSUBSW */
27447     case MMI_OPC_0_PEXTLW:    /* TODO: MMI_OPC_0_PEXTLW */
27448     case MMI_OPC_0_PPACW:     /* TODO: MMI_OPC_0_PPACW */
27449     case MMI_OPC_0_PADDSH:    /* TODO: MMI_OPC_0_PADDSH */
27450     case MMI_OPC_0_PSUBSH:    /* TODO: MMI_OPC_0_PSUBSH */
27451     case MMI_OPC_0_PEXTLH:    /* TODO: MMI_OPC_0_PEXTLH */
27452     case MMI_OPC_0_PPACH:     /* TODO: MMI_OPC_0_PPACH */
27453     case MMI_OPC_0_PADDSB:    /* TODO: MMI_OPC_0_PADDSB */
27454     case MMI_OPC_0_PSUBSB:    /* TODO: MMI_OPC_0_PSUBSB */
27455     case MMI_OPC_0_PEXTLB:    /* TODO: MMI_OPC_0_PEXTLB */
27456     case MMI_OPC_0_PPACB:     /* TODO: MMI_OPC_0_PPACB */
27457     case MMI_OPC_0_PEXT5:     /* TODO: MMI_OPC_0_PEXT5 */
27458     case MMI_OPC_0_PPAC5:     /* TODO: MMI_OPC_0_PPAC5 */
27459         generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI0 */
27460         break;
27461     default:
27462         MIPS_INVAL("TX79 MMI class MMI0");
27463         generate_exception_end(ctx, EXCP_RI);
27464         break;
27465     }
27466 }
27467
27468 static void decode_mmi1(CPUMIPSState *env, DisasContext *ctx)
27469 {
27470     uint32_t opc = MASK_MMI1(ctx->opcode);
27471
27472     switch (opc) {
27473     case MMI_OPC_1_PABSW:     /* TODO: MMI_OPC_1_PABSW */
27474     case MMI_OPC_1_PCEQW:     /* TODO: MMI_OPC_1_PCEQW */
27475     case MMI_OPC_1_PMINW:     /* TODO: MMI_OPC_1_PMINW */
27476     case MMI_OPC_1_PADSBH:    /* TODO: MMI_OPC_1_PADSBH */
27477     case MMI_OPC_1_PABSH:     /* TODO: MMI_OPC_1_PABSH */
27478     case MMI_OPC_1_PCEQH:     /* TODO: MMI_OPC_1_PCEQH */
27479     case MMI_OPC_1_PMINH:     /* TODO: MMI_OPC_1_PMINH */
27480     case MMI_OPC_1_PCEQB:     /* TODO: MMI_OPC_1_PCEQB */
27481     case MMI_OPC_1_PADDUW:    /* TODO: MMI_OPC_1_PADDUW */
27482     case MMI_OPC_1_PSUBUW:    /* TODO: MMI_OPC_1_PSUBUW */
27483     case MMI_OPC_1_PEXTUW:    /* TODO: MMI_OPC_1_PEXTUW */
27484     case MMI_OPC_1_PADDUH:    /* TODO: MMI_OPC_1_PADDUH */
27485     case MMI_OPC_1_PSUBUH:    /* TODO: MMI_OPC_1_PSUBUH */
27486     case MMI_OPC_1_PEXTUH:    /* TODO: MMI_OPC_1_PEXTUH */
27487     case MMI_OPC_1_PADDUB:    /* TODO: MMI_OPC_1_PADDUB */
27488     case MMI_OPC_1_PSUBUB:    /* TODO: MMI_OPC_1_PSUBUB */
27489     case MMI_OPC_1_PEXTUB:    /* TODO: MMI_OPC_1_PEXTUB */
27490     case MMI_OPC_1_QFSRV:     /* TODO: MMI_OPC_1_QFSRV */
27491         generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI1 */
27492         break;
27493     default:
27494         MIPS_INVAL("TX79 MMI class MMI1");
27495         generate_exception_end(ctx, EXCP_RI);
27496         break;
27497     }
27498 }
27499
27500 static void decode_mmi2(CPUMIPSState *env, DisasContext *ctx)
27501 {
27502     uint32_t opc = MASK_MMI2(ctx->opcode);
27503
27504     switch (opc) {
27505     case MMI_OPC_2_PMADDW:    /* TODO: MMI_OPC_2_PMADDW */
27506     case MMI_OPC_2_PSLLVW:    /* TODO: MMI_OPC_2_PSLLVW */
27507     case MMI_OPC_2_PSRLVW:    /* TODO: MMI_OPC_2_PSRLVW */
27508     case MMI_OPC_2_PMSUBW:    /* TODO: MMI_OPC_2_PMSUBW */
27509     case MMI_OPC_2_PMFHI:     /* TODO: MMI_OPC_2_PMFHI */
27510     case MMI_OPC_2_PMFLO:     /* TODO: MMI_OPC_2_PMFLO */
27511     case MMI_OPC_2_PINTH:     /* TODO: MMI_OPC_2_PINTH */
27512     case MMI_OPC_2_PMULTW:    /* TODO: MMI_OPC_2_PMULTW */
27513     case MMI_OPC_2_PDIVW:     /* TODO: MMI_OPC_2_PDIVW */
27514     case MMI_OPC_2_PMADDH:    /* TODO: MMI_OPC_2_PMADDH */
27515     case MMI_OPC_2_PHMADH:    /* TODO: MMI_OPC_2_PHMADH */
27516     case MMI_OPC_2_PAND:      /* TODO: MMI_OPC_2_PAND */
27517     case MMI_OPC_2_PXOR:      /* TODO: MMI_OPC_2_PXOR */
27518     case MMI_OPC_2_PMSUBH:    /* TODO: MMI_OPC_2_PMSUBH */
27519     case MMI_OPC_2_PHMSBH:    /* TODO: MMI_OPC_2_PHMSBH */
27520     case MMI_OPC_2_PEXEH:     /* TODO: MMI_OPC_2_PEXEH */
27521     case MMI_OPC_2_PREVH:     /* TODO: MMI_OPC_2_PREVH */
27522     case MMI_OPC_2_PMULTH:    /* TODO: MMI_OPC_2_PMULTH */
27523     case MMI_OPC_2_PDIVBW:    /* TODO: MMI_OPC_2_PDIVBW */
27524     case MMI_OPC_2_PEXEW:     /* TODO: MMI_OPC_2_PEXEW */
27525     case MMI_OPC_2_PROT3W:    /* TODO: MMI_OPC_2_PROT3W */
27526         generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI2 */
27527         break;
27528     case MMI_OPC_2_PCPYLD:
27529         gen_mmi_pcpyld(ctx);
27530         break;
27531     default:
27532         MIPS_INVAL("TX79 MMI class MMI2");
27533         generate_exception_end(ctx, EXCP_RI);
27534         break;
27535     }
27536 }
27537
27538 static void decode_mmi3(CPUMIPSState *env, DisasContext *ctx)
27539 {
27540     uint32_t opc = MASK_MMI3(ctx->opcode);
27541
27542     switch (opc) {
27543     case MMI_OPC_3_PMADDUW:    /* TODO: MMI_OPC_3_PMADDUW */
27544     case MMI_OPC_3_PSRAVW:     /* TODO: MMI_OPC_3_PSRAVW */
27545     case MMI_OPC_3_PMTHI:      /* TODO: MMI_OPC_3_PMTHI */
27546     case MMI_OPC_3_PMTLO:      /* TODO: MMI_OPC_3_PMTLO */
27547     case MMI_OPC_3_PINTEH:     /* TODO: MMI_OPC_3_PINTEH */
27548     case MMI_OPC_3_PMULTUW:    /* TODO: MMI_OPC_3_PMULTUW */
27549     case MMI_OPC_3_PDIVUW:     /* TODO: MMI_OPC_3_PDIVUW */
27550     case MMI_OPC_3_POR:        /* TODO: MMI_OPC_3_POR */
27551     case MMI_OPC_3_PNOR:       /* TODO: MMI_OPC_3_PNOR */
27552     case MMI_OPC_3_PEXCH:      /* TODO: MMI_OPC_3_PEXCH */
27553     case MMI_OPC_3_PEXCW:      /* TODO: MMI_OPC_3_PEXCW */
27554         generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI3 */
27555         break;
27556     case MMI_OPC_3_PCPYH:
27557         gen_mmi_pcpyh(ctx);
27558         break;
27559     case MMI_OPC_3_PCPYUD:
27560         gen_mmi_pcpyud(ctx);
27561         break;
27562     default:
27563         MIPS_INVAL("TX79 MMI class MMI3");
27564         generate_exception_end(ctx, EXCP_RI);
27565         break;
27566     }
27567 }
27568
27569 static void decode_mmi(CPUMIPSState *env, DisasContext *ctx)
27570 {
27571     uint32_t opc = MASK_MMI(ctx->opcode);
27572     int rs = extract32(ctx->opcode, 21, 5);
27573     int rt = extract32(ctx->opcode, 16, 5);
27574     int rd = extract32(ctx->opcode, 11, 5);
27575
27576     switch (opc) {
27577     case MMI_OPC_CLASS_MMI0:
27578         decode_mmi0(env, ctx);
27579         break;
27580     case MMI_OPC_CLASS_MMI1:
27581         decode_mmi1(env, ctx);
27582         break;
27583     case MMI_OPC_CLASS_MMI2:
27584         decode_mmi2(env, ctx);
27585         break;
27586     case MMI_OPC_CLASS_MMI3:
27587         decode_mmi3(env, ctx);
27588         break;
27589     case MMI_OPC_MULT1:
27590     case MMI_OPC_MULTU1:
27591     case MMI_OPC_MADD:
27592     case MMI_OPC_MADDU:
27593     case MMI_OPC_MADD1:
27594     case MMI_OPC_MADDU1:
27595         gen_mul_txx9(ctx, opc, rd, rs, rt);
27596         break;
27597     case MMI_OPC_DIV1:
27598     case MMI_OPC_DIVU1:
27599         gen_div1_tx79(ctx, opc, rs, rt);
27600         break;
27601     case MMI_OPC_MTLO1:
27602     case MMI_OPC_MTHI1:
27603         gen_HILO1_tx79(ctx, opc, rs);
27604         break;
27605     case MMI_OPC_MFLO1:
27606     case MMI_OPC_MFHI1:
27607         gen_HILO1_tx79(ctx, opc, rd);
27608         break;
27609     case MMI_OPC_PLZCW:         /* TODO: MMI_OPC_PLZCW */
27610     case MMI_OPC_PMFHL:         /* TODO: MMI_OPC_PMFHL */
27611     case MMI_OPC_PMTHL:         /* TODO: MMI_OPC_PMTHL */
27612     case MMI_OPC_PSLLH:         /* TODO: MMI_OPC_PSLLH */
27613     case MMI_OPC_PSRLH:         /* TODO: MMI_OPC_PSRLH */
27614     case MMI_OPC_PSRAH:         /* TODO: MMI_OPC_PSRAH */
27615     case MMI_OPC_PSLLW:         /* TODO: MMI_OPC_PSLLW */
27616     case MMI_OPC_PSRLW:         /* TODO: MMI_OPC_PSRLW */
27617     case MMI_OPC_PSRAW:         /* TODO: MMI_OPC_PSRAW */
27618         generate_exception_end(ctx, EXCP_RI);    /* TODO: MMI_OPC_CLASS_MMI */
27619         break;
27620     default:
27621         MIPS_INVAL("TX79 MMI class");
27622         generate_exception_end(ctx, EXCP_RI);
27623         break;
27624     }
27625 }
27626
27627 static void gen_mmi_lq(CPUMIPSState *env, DisasContext *ctx)
27628 {
27629     generate_exception_end(ctx, EXCP_RI);    /* TODO: MMI_OPC_LQ */
27630 }
27631
27632 static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset)
27633 {
27634     generate_exception_end(ctx, EXCP_RI);    /* TODO: MMI_OPC_SQ */
27635 }
27636
27637 /*
27638  * The TX79-specific instruction Store Quadword
27639  *
27640  * +--------+-------+-------+------------------------+
27641  * | 011111 |  base |   rt  |           offset       | SQ
27642  * +--------+-------+-------+------------------------+
27643  *      6       5       5                 16
27644  *
27645  * has the same opcode as the Read Hardware Register instruction
27646  *
27647  * +--------+-------+-------+-------+-------+--------+
27648  * | 011111 | 00000 |   rt  |   rd  | 00000 | 111011 | RDHWR
27649  * +--------+-------+-------+-------+-------+--------+
27650  *      6       5       5       5       5        6
27651  *
27652  * that is required, trapped and emulated by the Linux kernel. However, all
27653  * RDHWR encodings yield address error exceptions on the TX79 since the SQ
27654  * offset is odd. Therefore all valid SQ instructions can execute normally.
27655  * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
27656  * between SQ and RDHWR, as the Linux kernel does.
27657  */
27658 static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx)
27659 {
27660     int base = extract32(ctx->opcode, 21, 5);
27661     int rt = extract32(ctx->opcode, 16, 5);
27662     int offset = extract32(ctx->opcode, 0, 16);
27663
27664 #ifdef CONFIG_USER_ONLY
27665     uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
27666     uint32_t op2 = extract32(ctx->opcode, 6, 5);
27667
27668     if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
27669         int rd = extract32(ctx->opcode, 11, 5);
27670
27671         gen_rdhwr(ctx, rt, rd, 0);
27672         return;
27673     }
27674 #endif
27675
27676     gen_mmi_sq(ctx, base, rt, offset);
27677 }
27678
27679 #endif
27680
27681 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
27682 {
27683     int rs, rt, rd, sa;
27684     uint32_t op1, op2;
27685     int16_t imm;
27686
27687     rs = (ctx->opcode >> 21) & 0x1f;
27688     rt = (ctx->opcode >> 16) & 0x1f;
27689     rd = (ctx->opcode >> 11) & 0x1f;
27690     sa = (ctx->opcode >> 6) & 0x1f;
27691     imm = sextract32(ctx->opcode, 7, 9);
27692
27693     op1 = MASK_SPECIAL3(ctx->opcode);
27694
27695     /*
27696      * EVA loads and stores overlap Loongson 2E instructions decoded by
27697      * decode_opc_special3_legacy(), so be careful to allow their decoding when
27698      * EVA is absent.
27699      */
27700     if (ctx->eva) {
27701         switch (op1) {
27702         case OPC_LWLE:
27703         case OPC_LWRE:
27704             check_insn_opc_removed(ctx, ISA_MIPS32R6);
27705             /* fall through */
27706         case OPC_LBUE:
27707         case OPC_LHUE:
27708         case OPC_LBE:
27709         case OPC_LHE:
27710         case OPC_LLE:
27711         case OPC_LWE:
27712             check_cp0_enabled(ctx);
27713             gen_ld(ctx, op1, rt, rs, imm);
27714             return;
27715         case OPC_SWLE:
27716         case OPC_SWRE:
27717             check_insn_opc_removed(ctx, ISA_MIPS32R6);
27718             /* fall through */
27719         case OPC_SBE:
27720         case OPC_SHE:
27721         case OPC_SWE:
27722             check_cp0_enabled(ctx);
27723             gen_st(ctx, op1, rt, rs, imm);
27724             return;
27725         case OPC_SCE:
27726             check_cp0_enabled(ctx);
27727             gen_st_cond(ctx, rt, rs, imm, MO_TESL, true);
27728             return;
27729         case OPC_CACHEE:
27730             check_cp0_enabled(ctx);
27731             if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
27732                 gen_cache_operation(ctx, rt, rs, imm);
27733             }
27734             /* Treat as NOP. */
27735             return;
27736         case OPC_PREFE:
27737             check_cp0_enabled(ctx);
27738             /* Treat as NOP. */
27739             return;
27740         }
27741     }
27742
27743     switch (op1) {
27744     case OPC_EXT:
27745     case OPC_INS:
27746         check_insn(ctx, ISA_MIPS32R2);
27747         gen_bitops(ctx, op1, rt, rs, sa, rd);
27748         break;
27749     case OPC_BSHFL:
27750         op2 = MASK_BSHFL(ctx->opcode);
27751         switch (op2) {
27752         case OPC_ALIGN:
27753         case OPC_ALIGN_1:
27754         case OPC_ALIGN_2:
27755         case OPC_ALIGN_3:
27756         case OPC_BITSWAP:
27757             check_insn(ctx, ISA_MIPS32R6);
27758             decode_opc_special3_r6(env, ctx);
27759             break;
27760         default:
27761             check_insn(ctx, ISA_MIPS32R2);
27762             gen_bshfl(ctx, op2, rt, rd);
27763             break;
27764         }
27765         break;
27766 #if defined(TARGET_MIPS64)
27767     case OPC_DEXTM:
27768     case OPC_DEXTU:
27769     case OPC_DEXT:
27770     case OPC_DINSM:
27771     case OPC_DINSU:
27772     case OPC_DINS:
27773         check_insn(ctx, ISA_MIPS64R2);
27774         check_mips_64(ctx);
27775         gen_bitops(ctx, op1, rt, rs, sa, rd);
27776         break;
27777     case OPC_DBSHFL:
27778         op2 = MASK_DBSHFL(ctx->opcode);
27779         switch (op2) {
27780         case OPC_DALIGN:
27781         case OPC_DALIGN_1:
27782         case OPC_DALIGN_2:
27783         case OPC_DALIGN_3:
27784         case OPC_DALIGN_4:
27785         case OPC_DALIGN_5:
27786         case OPC_DALIGN_6:
27787         case OPC_DALIGN_7:
27788         case OPC_DBITSWAP:
27789             check_insn(ctx, ISA_MIPS32R6);
27790             decode_opc_special3_r6(env, ctx);
27791             break;
27792         default:
27793             check_insn(ctx, ISA_MIPS64R2);
27794             check_mips_64(ctx);
27795             op2 = MASK_DBSHFL(ctx->opcode);
27796             gen_bshfl(ctx, op2, rt, rd);
27797             break;
27798         }
27799         break;
27800 #endif
27801     case OPC_RDHWR:
27802         gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
27803         break;
27804     case OPC_FORK:
27805         check_mt(ctx);
27806         {
27807             TCGv t0 = tcg_temp_new();
27808             TCGv t1 = tcg_temp_new();
27809
27810             gen_load_gpr(t0, rt);
27811             gen_load_gpr(t1, rs);
27812             gen_helper_fork(t0, t1);
27813             tcg_temp_free(t0);
27814             tcg_temp_free(t1);
27815         }
27816         break;
27817     case OPC_YIELD:
27818         check_mt(ctx);
27819         {
27820             TCGv t0 = tcg_temp_new();
27821
27822             gen_load_gpr(t0, rs);
27823             gen_helper_yield(t0, cpu_env, t0);
27824             gen_store_gpr(t0, rd);
27825             tcg_temp_free(t0);
27826         }
27827         break;
27828     default:
27829         if (ctx->insn_flags & ISA_MIPS32R6) {
27830             decode_opc_special3_r6(env, ctx);
27831         } else {
27832             decode_opc_special3_legacy(env, ctx);
27833         }
27834     }
27835 }
27836
27837 /* MIPS SIMD Architecture (MSA)  */
27838 static inline int check_msa_access(DisasContext *ctx)
27839 {
27840     if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
27841                  !(ctx->hflags & MIPS_HFLAG_F64))) {
27842         generate_exception_end(ctx, EXCP_RI);
27843         return 0;
27844     }
27845
27846     if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
27847         if (ctx->insn_flags & ASE_MSA) {
27848             generate_exception_end(ctx, EXCP_MSADIS);
27849             return 0;
27850         } else {
27851             generate_exception_end(ctx, EXCP_RI);
27852             return 0;
27853         }
27854     }
27855     return 1;
27856 }
27857
27858 static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
27859 {
27860     /* generates tcg ops to check if any element is 0 */
27861     /* Note this function only works with MSA_WRLEN = 128 */
27862     uint64_t eval_zero_or_big = 0;
27863     uint64_t eval_big = 0;
27864     TCGv_i64 t0 = tcg_temp_new_i64();
27865     TCGv_i64 t1 = tcg_temp_new_i64();
27866     switch (df) {
27867     case DF_BYTE:
27868         eval_zero_or_big = 0x0101010101010101ULL;
27869         eval_big = 0x8080808080808080ULL;
27870         break;
27871     case DF_HALF:
27872         eval_zero_or_big = 0x0001000100010001ULL;
27873         eval_big = 0x8000800080008000ULL;
27874         break;
27875     case DF_WORD:
27876         eval_zero_or_big = 0x0000000100000001ULL;
27877         eval_big = 0x8000000080000000ULL;
27878         break;
27879     case DF_DOUBLE:
27880         eval_zero_or_big = 0x0000000000000001ULL;
27881         eval_big = 0x8000000000000000ULL;
27882         break;
27883     }
27884     tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
27885     tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
27886     tcg_gen_andi_i64(t0, t0, eval_big);
27887     tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
27888     tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
27889     tcg_gen_andi_i64(t1, t1, eval_big);
27890     tcg_gen_or_i64(t0, t0, t1);
27891     /* if all bits are zero then all elements are not zero */
27892     /* if some bit is non-zero then some element is zero */
27893     tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
27894     tcg_gen_trunc_i64_tl(tresult, t0);
27895     tcg_temp_free_i64(t0);
27896     tcg_temp_free_i64(t1);
27897 }
27898
27899 static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
27900 {
27901     uint8_t df = (ctx->opcode >> 21) & 0x3;
27902     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
27903     int64_t s16 = (int16_t)ctx->opcode;
27904
27905     check_msa_access(ctx);
27906
27907     if (ctx->hflags & MIPS_HFLAG_BMASK) {
27908         generate_exception_end(ctx, EXCP_RI);
27909         return;
27910     }
27911     switch (op1) {
27912     case OPC_BZ_V:
27913     case OPC_BNZ_V:
27914         {
27915             TCGv_i64 t0 = tcg_temp_new_i64();
27916             tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
27917             tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
27918                     TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
27919             tcg_gen_trunc_i64_tl(bcond, t0);
27920             tcg_temp_free_i64(t0);
27921         }
27922         break;
27923     case OPC_BZ_B:
27924     case OPC_BZ_H:
27925     case OPC_BZ_W:
27926     case OPC_BZ_D:
27927         gen_check_zero_element(bcond, df, wt);
27928         break;
27929     case OPC_BNZ_B:
27930     case OPC_BNZ_H:
27931     case OPC_BNZ_W:
27932     case OPC_BNZ_D:
27933         gen_check_zero_element(bcond, df, wt);
27934         tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
27935         break;
27936     }
27937
27938     ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
27939
27940     ctx->hflags |= MIPS_HFLAG_BC;
27941     ctx->hflags |= MIPS_HFLAG_BDS32;
27942 }
27943
27944 static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
27945 {
27946 #define MASK_MSA_I8(op)    (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
27947     uint8_t i8 = (ctx->opcode >> 16) & 0xff;
27948     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27949     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27950
27951     TCGv_i32 twd = tcg_const_i32(wd);
27952     TCGv_i32 tws = tcg_const_i32(ws);
27953     TCGv_i32 ti8 = tcg_const_i32(i8);
27954
27955     switch (MASK_MSA_I8(ctx->opcode)) {
27956     case OPC_ANDI_B:
27957         gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
27958         break;
27959     case OPC_ORI_B:
27960         gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
27961         break;
27962     case OPC_NORI_B:
27963         gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
27964         break;
27965     case OPC_XORI_B:
27966         gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
27967         break;
27968     case OPC_BMNZI_B:
27969         gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
27970         break;
27971     case OPC_BMZI_B:
27972         gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
27973         break;
27974     case OPC_BSELI_B:
27975         gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
27976         break;
27977     case OPC_SHF_B:
27978     case OPC_SHF_H:
27979     case OPC_SHF_W:
27980         {
27981             uint8_t df = (ctx->opcode >> 24) & 0x3;
27982             if (df == DF_DOUBLE) {
27983                 generate_exception_end(ctx, EXCP_RI);
27984             } else {
27985                 TCGv_i32 tdf = tcg_const_i32(df);
27986                 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
27987                 tcg_temp_free_i32(tdf);
27988             }
27989         }
27990         break;
27991     default:
27992         MIPS_INVAL("MSA instruction");
27993         generate_exception_end(ctx, EXCP_RI);
27994         break;
27995     }
27996
27997     tcg_temp_free_i32(twd);
27998     tcg_temp_free_i32(tws);
27999     tcg_temp_free_i32(ti8);
28000 }
28001
28002 static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
28003 {
28004 #define MASK_MSA_I5(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28005     uint8_t df = (ctx->opcode >> 21) & 0x3;
28006     int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
28007     uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
28008     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28009     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28010
28011     TCGv_i32 tdf = tcg_const_i32(df);
28012     TCGv_i32 twd = tcg_const_i32(wd);
28013     TCGv_i32 tws = tcg_const_i32(ws);
28014     TCGv_i32 timm = tcg_temp_new_i32();
28015     tcg_gen_movi_i32(timm, u5);
28016
28017     switch (MASK_MSA_I5(ctx->opcode)) {
28018     case OPC_ADDVI_df:
28019         gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
28020         break;
28021     case OPC_SUBVI_df:
28022         gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
28023         break;
28024     case OPC_MAXI_S_df:
28025         tcg_gen_movi_i32(timm, s5);
28026         gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
28027         break;
28028     case OPC_MAXI_U_df:
28029         gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
28030         break;
28031     case OPC_MINI_S_df:
28032         tcg_gen_movi_i32(timm, s5);
28033         gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
28034         break;
28035     case OPC_MINI_U_df:
28036         gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
28037         break;
28038     case OPC_CEQI_df:
28039         tcg_gen_movi_i32(timm, s5);
28040         gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
28041         break;
28042     case OPC_CLTI_S_df:
28043         tcg_gen_movi_i32(timm, s5);
28044         gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
28045         break;
28046     case OPC_CLTI_U_df:
28047         gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
28048         break;
28049     case OPC_CLEI_S_df:
28050         tcg_gen_movi_i32(timm, s5);
28051         gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
28052         break;
28053     case OPC_CLEI_U_df:
28054         gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
28055         break;
28056     case OPC_LDI_df:
28057         {
28058             int32_t s10 = sextract32(ctx->opcode, 11, 10);
28059             tcg_gen_movi_i32(timm, s10);
28060             gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
28061         }
28062         break;
28063     default:
28064         MIPS_INVAL("MSA instruction");
28065         generate_exception_end(ctx, EXCP_RI);
28066         break;
28067     }
28068
28069     tcg_temp_free_i32(tdf);
28070     tcg_temp_free_i32(twd);
28071     tcg_temp_free_i32(tws);
28072     tcg_temp_free_i32(timm);
28073 }
28074
28075 static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
28076 {
28077 #define MASK_MSA_BIT(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28078     uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
28079     uint32_t df = 0, m = 0;
28080     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28081     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28082
28083     TCGv_i32 tdf;
28084     TCGv_i32 tm;
28085     TCGv_i32 twd;
28086     TCGv_i32 tws;
28087
28088     if ((dfm & 0x40) == 0x00) {
28089         m = dfm & 0x3f;
28090         df = DF_DOUBLE;
28091     } else if ((dfm & 0x60) == 0x40) {
28092         m = dfm & 0x1f;
28093         df = DF_WORD;
28094     } else if ((dfm & 0x70) == 0x60) {
28095         m = dfm & 0x0f;
28096         df = DF_HALF;
28097     } else if ((dfm & 0x78) == 0x70) {
28098         m = dfm & 0x7;
28099         df = DF_BYTE;
28100     } else {
28101         generate_exception_end(ctx, EXCP_RI);
28102         return;
28103     }
28104
28105     tdf = tcg_const_i32(df);
28106     tm  = tcg_const_i32(m);
28107     twd = tcg_const_i32(wd);
28108     tws = tcg_const_i32(ws);
28109
28110     switch (MASK_MSA_BIT(ctx->opcode)) {
28111     case OPC_SLLI_df:
28112         gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
28113         break;
28114     case OPC_SRAI_df:
28115         gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
28116         break;
28117     case OPC_SRLI_df:
28118         gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
28119         break;
28120     case OPC_BCLRI_df:
28121         gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
28122         break;
28123     case OPC_BSETI_df:
28124         gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
28125         break;
28126     case OPC_BNEGI_df:
28127         gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
28128         break;
28129     case OPC_BINSLI_df:
28130         gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
28131         break;
28132     case OPC_BINSRI_df:
28133         gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
28134         break;
28135     case OPC_SAT_S_df:
28136         gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
28137         break;
28138     case OPC_SAT_U_df:
28139         gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
28140         break;
28141     case OPC_SRARI_df:
28142         gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
28143         break;
28144     case OPC_SRLRI_df:
28145         gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
28146         break;
28147     default:
28148         MIPS_INVAL("MSA instruction");
28149         generate_exception_end(ctx, EXCP_RI);
28150         break;
28151     }
28152
28153     tcg_temp_free_i32(tdf);
28154     tcg_temp_free_i32(tm);
28155     tcg_temp_free_i32(twd);
28156     tcg_temp_free_i32(tws);
28157 }
28158
28159 static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
28160 {
28161 #define MASK_MSA_3R(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28162     uint8_t df = (ctx->opcode >> 21) & 0x3;
28163     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28164     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28165     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28166
28167     TCGv_i32 tdf = tcg_const_i32(df);
28168     TCGv_i32 twd = tcg_const_i32(wd);
28169     TCGv_i32 tws = tcg_const_i32(ws);
28170     TCGv_i32 twt = tcg_const_i32(wt);
28171
28172     switch (MASK_MSA_3R(ctx->opcode)) {
28173     case OPC_SLL_df:
28174         gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
28175         break;
28176     case OPC_ADDV_df:
28177         gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
28178         break;
28179     case OPC_CEQ_df:
28180         gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
28181         break;
28182     case OPC_ADD_A_df:
28183         gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
28184         break;
28185     case OPC_SUBS_S_df:
28186         gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
28187         break;
28188     case OPC_MULV_df:
28189         gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
28190         break;
28191     case OPC_SLD_df:
28192         gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
28193         break;
28194     case OPC_VSHF_df:
28195         gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
28196         break;
28197     case OPC_SRA_df:
28198         gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
28199         break;
28200     case OPC_SUBV_df:
28201         gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
28202         break;
28203     case OPC_ADDS_A_df:
28204         gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
28205         break;
28206     case OPC_SUBS_U_df:
28207         gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
28208         break;
28209     case OPC_MADDV_df:
28210         gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
28211         break;
28212     case OPC_SPLAT_df:
28213         gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
28214         break;
28215     case OPC_SRAR_df:
28216         gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
28217         break;
28218     case OPC_SRL_df:
28219         gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
28220         break;
28221     case OPC_MAX_S_df:
28222         gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
28223         break;
28224     case OPC_CLT_S_df:
28225         gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
28226         break;
28227     case OPC_ADDS_S_df:
28228         gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
28229         break;
28230     case OPC_SUBSUS_U_df:
28231         gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
28232         break;
28233     case OPC_MSUBV_df:
28234         gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
28235         break;
28236     case OPC_PCKEV_df:
28237         gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
28238         break;
28239     case OPC_SRLR_df:
28240         gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
28241         break;
28242     case OPC_BCLR_df:
28243         gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
28244         break;
28245     case OPC_MAX_U_df:
28246         gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
28247         break;
28248     case OPC_CLT_U_df:
28249         gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
28250         break;
28251     case OPC_ADDS_U_df:
28252         gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
28253         break;
28254     case OPC_SUBSUU_S_df:
28255         gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
28256         break;
28257     case OPC_PCKOD_df:
28258         gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
28259         break;
28260     case OPC_BSET_df:
28261         gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
28262         break;
28263     case OPC_MIN_S_df:
28264         gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
28265         break;
28266     case OPC_CLE_S_df:
28267         gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
28268         break;
28269     case OPC_AVE_S_df:
28270         gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
28271         break;
28272     case OPC_ASUB_S_df:
28273         gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
28274         break;
28275     case OPC_DIV_S_df:
28276         gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
28277         break;
28278     case OPC_ILVL_df:
28279         gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
28280         break;
28281     case OPC_BNEG_df:
28282         gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
28283         break;
28284     case OPC_MIN_U_df:
28285         gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
28286         break;
28287     case OPC_CLE_U_df:
28288         gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
28289         break;
28290     case OPC_AVE_U_df:
28291         gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
28292         break;
28293     case OPC_ASUB_U_df:
28294         gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
28295         break;
28296     case OPC_DIV_U_df:
28297         gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
28298         break;
28299     case OPC_ILVR_df:
28300         gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
28301         break;
28302     case OPC_BINSL_df:
28303         gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
28304         break;
28305     case OPC_MAX_A_df:
28306         gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
28307         break;
28308     case OPC_AVER_S_df:
28309         gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
28310         break;
28311     case OPC_MOD_S_df:
28312         gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
28313         break;
28314     case OPC_ILVEV_df:
28315         gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
28316         break;
28317     case OPC_BINSR_df:
28318         gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
28319         break;
28320     case OPC_MIN_A_df:
28321         gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
28322         break;
28323     case OPC_AVER_U_df:
28324         gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
28325         break;
28326     case OPC_MOD_U_df:
28327         gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
28328         break;
28329     case OPC_ILVOD_df:
28330         gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
28331         break;
28332
28333     case OPC_DOTP_S_df:
28334     case OPC_DOTP_U_df:
28335     case OPC_DPADD_S_df:
28336     case OPC_DPADD_U_df:
28337     case OPC_DPSUB_S_df:
28338     case OPC_HADD_S_df:
28339     case OPC_DPSUB_U_df:
28340     case OPC_HADD_U_df:
28341     case OPC_HSUB_S_df:
28342     case OPC_HSUB_U_df:
28343         if (df == DF_BYTE) {
28344             generate_exception_end(ctx, EXCP_RI);
28345             break;
28346         }
28347         switch (MASK_MSA_3R(ctx->opcode)) {
28348         case OPC_DOTP_S_df:
28349             gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
28350             break;
28351         case OPC_DOTP_U_df:
28352             gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
28353             break;
28354         case OPC_DPADD_S_df:
28355             gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
28356             break;
28357         case OPC_DPADD_U_df:
28358             gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
28359             break;
28360         case OPC_DPSUB_S_df:
28361             gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
28362             break;
28363         case OPC_HADD_S_df:
28364             gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
28365             break;
28366         case OPC_DPSUB_U_df:
28367             gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
28368             break;
28369         case OPC_HADD_U_df:
28370             gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
28371             break;
28372         case OPC_HSUB_S_df:
28373             gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
28374             break;
28375         case OPC_HSUB_U_df:
28376             gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
28377             break;
28378         }
28379         break;
28380     default:
28381         MIPS_INVAL("MSA instruction");
28382         generate_exception_end(ctx, EXCP_RI);
28383         break;
28384     }
28385     tcg_temp_free_i32(twd);
28386     tcg_temp_free_i32(tws);
28387     tcg_temp_free_i32(twt);
28388     tcg_temp_free_i32(tdf);
28389 }
28390
28391 static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
28392 {
28393 #define MASK_MSA_ELM_DF3E(op)   (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
28394     uint8_t source = (ctx->opcode >> 11) & 0x1f;
28395     uint8_t dest = (ctx->opcode >> 6) & 0x1f;
28396     TCGv telm = tcg_temp_new();
28397     TCGv_i32 tsr = tcg_const_i32(source);
28398     TCGv_i32 tdt = tcg_const_i32(dest);
28399
28400     switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
28401     case OPC_CTCMSA:
28402         gen_load_gpr(telm, source);
28403         gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
28404         break;
28405     case OPC_CFCMSA:
28406         gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
28407         gen_store_gpr(telm, dest);
28408         break;
28409     case OPC_MOVE_V:
28410         gen_helper_msa_move_v(cpu_env, tdt, tsr);
28411         break;
28412     default:
28413         MIPS_INVAL("MSA instruction");
28414         generate_exception_end(ctx, EXCP_RI);
28415         break;
28416     }
28417
28418     tcg_temp_free(telm);
28419     tcg_temp_free_i32(tdt);
28420     tcg_temp_free_i32(tsr);
28421 }
28422
28423 static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
28424         uint32_t n)
28425 {
28426 #define MASK_MSA_ELM(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
28427     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28428     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28429
28430     TCGv_i32 tws = tcg_const_i32(ws);
28431     TCGv_i32 twd = tcg_const_i32(wd);
28432     TCGv_i32 tn  = tcg_const_i32(n);
28433     TCGv_i32 tdf = tcg_const_i32(df);
28434
28435     switch (MASK_MSA_ELM(ctx->opcode)) {
28436     case OPC_SLDI_df:
28437         gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
28438         break;
28439     case OPC_SPLATI_df:
28440         gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
28441         break;
28442     case OPC_INSVE_df:
28443         gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
28444         break;
28445     case OPC_COPY_S_df:
28446     case OPC_COPY_U_df:
28447     case OPC_INSERT_df:
28448 #if !defined(TARGET_MIPS64)
28449         /* Double format valid only for MIPS64 */
28450         if (df == DF_DOUBLE) {
28451             generate_exception_end(ctx, EXCP_RI);
28452             break;
28453         }
28454         if ((MASK_MSA_ELM(ctx->opcode) == OPC_COPY_U_df) &&
28455               (df == DF_WORD)) {
28456             generate_exception_end(ctx, EXCP_RI);
28457             break;
28458         }
28459 #endif
28460         switch (MASK_MSA_ELM(ctx->opcode)) {
28461         case OPC_COPY_S_df:
28462             if (likely(wd != 0)) {
28463                 switch (df) {
28464                 case DF_BYTE:
28465                     gen_helper_msa_copy_s_b(cpu_env, twd, tws, tn);
28466                     break;
28467                 case DF_HALF:
28468                     gen_helper_msa_copy_s_h(cpu_env, twd, tws, tn);
28469                     break;
28470                 case DF_WORD:
28471                     gen_helper_msa_copy_s_w(cpu_env, twd, tws, tn);
28472                     break;
28473 #if defined(TARGET_MIPS64)
28474                 case DF_DOUBLE:
28475                     gen_helper_msa_copy_s_d(cpu_env, twd, tws, tn);
28476                     break;
28477 #endif
28478                 default:
28479                     assert(0);
28480                 }
28481             }
28482             break;
28483         case OPC_COPY_U_df:
28484             if (likely(wd != 0)) {
28485                 switch (df) {
28486                 case DF_BYTE:
28487                     gen_helper_msa_copy_u_b(cpu_env, twd, tws, tn);
28488                     break;
28489                 case DF_HALF:
28490                     gen_helper_msa_copy_u_h(cpu_env, twd, tws, tn);
28491                     break;
28492 #if defined(TARGET_MIPS64)
28493                 case DF_WORD:
28494                     gen_helper_msa_copy_u_w(cpu_env, twd, tws, tn);
28495                     break;
28496 #endif
28497                 default:
28498                     assert(0);
28499                 }
28500             }
28501             break;
28502         case OPC_INSERT_df:
28503             switch (df) {
28504             case DF_BYTE:
28505                 gen_helper_msa_insert_b(cpu_env, twd, tws, tn);
28506                 break;
28507             case DF_HALF:
28508                 gen_helper_msa_insert_h(cpu_env, twd, tws, tn);
28509                 break;
28510             case DF_WORD:
28511                 gen_helper_msa_insert_w(cpu_env, twd, tws, tn);
28512                 break;
28513 #if defined(TARGET_MIPS64)
28514             case DF_DOUBLE:
28515                 gen_helper_msa_insert_d(cpu_env, twd, tws, tn);
28516                 break;
28517 #endif
28518             default:
28519                 assert(0);
28520             }
28521             break;
28522         }
28523         break;
28524     default:
28525         MIPS_INVAL("MSA instruction");
28526         generate_exception_end(ctx, EXCP_RI);
28527     }
28528     tcg_temp_free_i32(twd);
28529     tcg_temp_free_i32(tws);
28530     tcg_temp_free_i32(tn);
28531     tcg_temp_free_i32(tdf);
28532 }
28533
28534 static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
28535 {
28536     uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
28537     uint32_t df = 0, n = 0;
28538
28539     if ((dfn & 0x30) == 0x00) {
28540         n = dfn & 0x0f;
28541         df = DF_BYTE;
28542     } else if ((dfn & 0x38) == 0x20) {
28543         n = dfn & 0x07;
28544         df = DF_HALF;
28545     } else if ((dfn & 0x3c) == 0x30) {
28546         n = dfn & 0x03;
28547         df = DF_WORD;
28548     } else if ((dfn & 0x3e) == 0x38) {
28549         n = dfn & 0x01;
28550         df = DF_DOUBLE;
28551     } else if (dfn == 0x3E) {
28552         /* CTCMSA, CFCMSA, MOVE.V */
28553         gen_msa_elm_3e(env, ctx);
28554         return;
28555     } else {
28556         generate_exception_end(ctx, EXCP_RI);
28557         return;
28558     }
28559
28560     gen_msa_elm_df(env, ctx, df, n);
28561 }
28562
28563 static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
28564 {
28565 #define MASK_MSA_3RF(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
28566     uint8_t df = (ctx->opcode >> 21) & 0x1;
28567     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28568     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28569     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28570
28571     TCGv_i32 twd = tcg_const_i32(wd);
28572     TCGv_i32 tws = tcg_const_i32(ws);
28573     TCGv_i32 twt = tcg_const_i32(wt);
28574     TCGv_i32 tdf = tcg_temp_new_i32();
28575
28576     /* adjust df value for floating-point instruction */
28577     tcg_gen_movi_i32(tdf, df + 2);
28578
28579     switch (MASK_MSA_3RF(ctx->opcode)) {
28580     case OPC_FCAF_df:
28581         gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
28582         break;
28583     case OPC_FADD_df:
28584         gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
28585         break;
28586     case OPC_FCUN_df:
28587         gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
28588         break;
28589     case OPC_FSUB_df:
28590         gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
28591         break;
28592     case OPC_FCOR_df:
28593         gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
28594         break;
28595     case OPC_FCEQ_df:
28596         gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
28597         break;
28598     case OPC_FMUL_df:
28599         gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
28600         break;
28601     case OPC_FCUNE_df:
28602         gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
28603         break;
28604     case OPC_FCUEQ_df:
28605         gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
28606         break;
28607     case OPC_FDIV_df:
28608         gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
28609         break;
28610     case OPC_FCNE_df:
28611         gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
28612         break;
28613     case OPC_FCLT_df:
28614         gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
28615         break;
28616     case OPC_FMADD_df:
28617         gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
28618         break;
28619     case OPC_MUL_Q_df:
28620         tcg_gen_movi_i32(tdf, df + 1);
28621         gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
28622         break;
28623     case OPC_FCULT_df:
28624         gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
28625         break;
28626     case OPC_FMSUB_df:
28627         gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
28628         break;
28629     case OPC_MADD_Q_df:
28630         tcg_gen_movi_i32(tdf, df + 1);
28631         gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
28632         break;
28633     case OPC_FCLE_df:
28634         gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
28635         break;
28636     case OPC_MSUB_Q_df:
28637         tcg_gen_movi_i32(tdf, df + 1);
28638         gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
28639         break;
28640     case OPC_FCULE_df:
28641         gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
28642         break;
28643     case OPC_FEXP2_df:
28644         gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
28645         break;
28646     case OPC_FSAF_df:
28647         gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
28648         break;
28649     case OPC_FEXDO_df:
28650         gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
28651         break;
28652     case OPC_FSUN_df:
28653         gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
28654         break;
28655     case OPC_FSOR_df:
28656         gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
28657         break;
28658     case OPC_FSEQ_df:
28659         gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
28660         break;
28661     case OPC_FTQ_df:
28662         gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
28663         break;
28664     case OPC_FSUNE_df:
28665         gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
28666         break;
28667     case OPC_FSUEQ_df:
28668         gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
28669         break;
28670     case OPC_FSNE_df:
28671         gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
28672         break;
28673     case OPC_FSLT_df:
28674         gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
28675         break;
28676     case OPC_FMIN_df:
28677         gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
28678         break;
28679     case OPC_MULR_Q_df:
28680         tcg_gen_movi_i32(tdf, df + 1);
28681         gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
28682         break;
28683     case OPC_FSULT_df:
28684         gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
28685         break;
28686     case OPC_FMIN_A_df:
28687         gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
28688         break;
28689     case OPC_MADDR_Q_df:
28690         tcg_gen_movi_i32(tdf, df + 1);
28691         gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
28692         break;
28693     case OPC_FSLE_df:
28694         gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
28695         break;
28696     case OPC_FMAX_df:
28697         gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
28698         break;
28699     case OPC_MSUBR_Q_df:
28700         tcg_gen_movi_i32(tdf, df + 1);
28701         gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
28702         break;
28703     case OPC_FSULE_df:
28704         gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
28705         break;
28706     case OPC_FMAX_A_df:
28707         gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
28708         break;
28709     default:
28710         MIPS_INVAL("MSA instruction");
28711         generate_exception_end(ctx, EXCP_RI);
28712         break;
28713     }
28714
28715     tcg_temp_free_i32(twd);
28716     tcg_temp_free_i32(tws);
28717     tcg_temp_free_i32(twt);
28718     tcg_temp_free_i32(tdf);
28719 }
28720
28721 static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
28722 {
28723 #define MASK_MSA_2R(op)     (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
28724                             (op & (0x7 << 18)))
28725     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28726     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28727     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28728     uint8_t df = (ctx->opcode >> 16) & 0x3;
28729     TCGv_i32 twd = tcg_const_i32(wd);
28730     TCGv_i32 tws = tcg_const_i32(ws);
28731     TCGv_i32 twt = tcg_const_i32(wt);
28732     TCGv_i32 tdf = tcg_const_i32(df);
28733
28734     switch (MASK_MSA_2R(ctx->opcode)) {
28735     case OPC_FILL_df:
28736 #if !defined(TARGET_MIPS64)
28737         /* Double format valid only for MIPS64 */
28738         if (df == DF_DOUBLE) {
28739             generate_exception_end(ctx, EXCP_RI);
28740             break;
28741         }
28742 #endif
28743         gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
28744         break;
28745     case OPC_PCNT_df:
28746         gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
28747         break;
28748     case OPC_NLOC_df:
28749         gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
28750         break;
28751     case OPC_NLZC_df:
28752         gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
28753         break;
28754     default:
28755         MIPS_INVAL("MSA instruction");
28756         generate_exception_end(ctx, EXCP_RI);
28757         break;
28758     }
28759
28760     tcg_temp_free_i32(twd);
28761     tcg_temp_free_i32(tws);
28762     tcg_temp_free_i32(twt);
28763     tcg_temp_free_i32(tdf);
28764 }
28765
28766 static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
28767 {
28768 #define MASK_MSA_2RF(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
28769                             (op & (0xf << 17)))
28770     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28771     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28772     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28773     uint8_t df = (ctx->opcode >> 16) & 0x1;
28774     TCGv_i32 twd = tcg_const_i32(wd);
28775     TCGv_i32 tws = tcg_const_i32(ws);
28776     TCGv_i32 twt = tcg_const_i32(wt);
28777     /* adjust df value for floating-point instruction */
28778     TCGv_i32 tdf = tcg_const_i32(df + 2);
28779
28780     switch (MASK_MSA_2RF(ctx->opcode)) {
28781     case OPC_FCLASS_df:
28782         gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
28783         break;
28784     case OPC_FTRUNC_S_df:
28785         gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
28786         break;
28787     case OPC_FTRUNC_U_df:
28788         gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
28789         break;
28790     case OPC_FSQRT_df:
28791         gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
28792         break;
28793     case OPC_FRSQRT_df:
28794         gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
28795         break;
28796     case OPC_FRCP_df:
28797         gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
28798         break;
28799     case OPC_FRINT_df:
28800         gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
28801         break;
28802     case OPC_FLOG2_df:
28803         gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
28804         break;
28805     case OPC_FEXUPL_df:
28806         gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
28807         break;
28808     case OPC_FEXUPR_df:
28809         gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
28810         break;
28811     case OPC_FFQL_df:
28812         gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
28813         break;
28814     case OPC_FFQR_df:
28815         gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
28816         break;
28817     case OPC_FTINT_S_df:
28818         gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
28819         break;
28820     case OPC_FTINT_U_df:
28821         gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
28822         break;
28823     case OPC_FFINT_S_df:
28824         gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
28825         break;
28826     case OPC_FFINT_U_df:
28827         gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
28828         break;
28829     }
28830
28831     tcg_temp_free_i32(twd);
28832     tcg_temp_free_i32(tws);
28833     tcg_temp_free_i32(twt);
28834     tcg_temp_free_i32(tdf);
28835 }
28836
28837 static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
28838 {
28839 #define MASK_MSA_VEC(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
28840     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28841     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28842     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28843     TCGv_i32 twd = tcg_const_i32(wd);
28844     TCGv_i32 tws = tcg_const_i32(ws);
28845     TCGv_i32 twt = tcg_const_i32(wt);
28846
28847     switch (MASK_MSA_VEC(ctx->opcode)) {
28848     case OPC_AND_V:
28849         gen_helper_msa_and_v(cpu_env, twd, tws, twt);
28850         break;
28851     case OPC_OR_V:
28852         gen_helper_msa_or_v(cpu_env, twd, tws, twt);
28853         break;
28854     case OPC_NOR_V:
28855         gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
28856         break;
28857     case OPC_XOR_V:
28858         gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
28859         break;
28860     case OPC_BMNZ_V:
28861         gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
28862         break;
28863     case OPC_BMZ_V:
28864         gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
28865         break;
28866     case OPC_BSEL_V:
28867         gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
28868         break;
28869     default:
28870         MIPS_INVAL("MSA instruction");
28871         generate_exception_end(ctx, EXCP_RI);
28872         break;
28873     }
28874
28875     tcg_temp_free_i32(twd);
28876     tcg_temp_free_i32(tws);
28877     tcg_temp_free_i32(twt);
28878 }
28879
28880 static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
28881 {
28882     switch (MASK_MSA_VEC(ctx->opcode)) {
28883     case OPC_AND_V:
28884     case OPC_OR_V:
28885     case OPC_NOR_V:
28886     case OPC_XOR_V:
28887     case OPC_BMNZ_V:
28888     case OPC_BMZ_V:
28889     case OPC_BSEL_V:
28890         gen_msa_vec_v(env, ctx);
28891         break;
28892     case OPC_MSA_2R:
28893         gen_msa_2r(env, ctx);
28894         break;
28895     case OPC_MSA_2RF:
28896         gen_msa_2rf(env, ctx);
28897         break;
28898     default:
28899         MIPS_INVAL("MSA instruction");
28900         generate_exception_end(ctx, EXCP_RI);
28901         break;
28902     }
28903 }
28904
28905 static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
28906 {
28907     uint32_t opcode = ctx->opcode;
28908     check_insn(ctx, ASE_MSA);
28909     check_msa_access(ctx);
28910
28911     switch (MASK_MSA_MINOR(opcode)) {
28912     case OPC_MSA_I8_00:
28913     case OPC_MSA_I8_01:
28914     case OPC_MSA_I8_02:
28915         gen_msa_i8(env, ctx);
28916         break;
28917     case OPC_MSA_I5_06:
28918     case OPC_MSA_I5_07:
28919         gen_msa_i5(env, ctx);
28920         break;
28921     case OPC_MSA_BIT_09:
28922     case OPC_MSA_BIT_0A:
28923         gen_msa_bit(env, ctx);
28924         break;
28925     case OPC_MSA_3R_0D:
28926     case OPC_MSA_3R_0E:
28927     case OPC_MSA_3R_0F:
28928     case OPC_MSA_3R_10:
28929     case OPC_MSA_3R_11:
28930     case OPC_MSA_3R_12:
28931     case OPC_MSA_3R_13:
28932     case OPC_MSA_3R_14:
28933     case OPC_MSA_3R_15:
28934         gen_msa_3r(env, ctx);
28935         break;
28936     case OPC_MSA_ELM:
28937         gen_msa_elm(env, ctx);
28938         break;
28939     case OPC_MSA_3RF_1A:
28940     case OPC_MSA_3RF_1B:
28941     case OPC_MSA_3RF_1C:
28942         gen_msa_3rf(env, ctx);
28943         break;
28944     case OPC_MSA_VEC:
28945         gen_msa_vec(env, ctx);
28946         break;
28947     case OPC_LD_B:
28948     case OPC_LD_H:
28949     case OPC_LD_W:
28950     case OPC_LD_D:
28951     case OPC_ST_B:
28952     case OPC_ST_H:
28953     case OPC_ST_W:
28954     case OPC_ST_D:
28955         {
28956             int32_t s10 = sextract32(ctx->opcode, 16, 10);
28957             uint8_t rs = (ctx->opcode >> 11) & 0x1f;
28958             uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28959             uint8_t df = (ctx->opcode >> 0) & 0x3;
28960
28961             TCGv_i32 twd = tcg_const_i32(wd);
28962             TCGv taddr = tcg_temp_new();
28963             gen_base_offset_addr(ctx, taddr, rs, s10 << df);
28964
28965             switch (MASK_MSA_MINOR(opcode)) {
28966             case OPC_LD_B:
28967                 gen_helper_msa_ld_b(cpu_env, twd, taddr);
28968                 break;
28969             case OPC_LD_H:
28970                 gen_helper_msa_ld_h(cpu_env, twd, taddr);
28971                 break;
28972             case OPC_LD_W:
28973                 gen_helper_msa_ld_w(cpu_env, twd, taddr);
28974                 break;
28975             case OPC_LD_D:
28976                 gen_helper_msa_ld_d(cpu_env, twd, taddr);
28977                 break;
28978             case OPC_ST_B:
28979                 gen_helper_msa_st_b(cpu_env, twd, taddr);
28980                 break;
28981             case OPC_ST_H:
28982                 gen_helper_msa_st_h(cpu_env, twd, taddr);
28983                 break;
28984             case OPC_ST_W:
28985                 gen_helper_msa_st_w(cpu_env, twd, taddr);
28986                 break;
28987             case OPC_ST_D:
28988                 gen_helper_msa_st_d(cpu_env, twd, taddr);
28989                 break;
28990             }
28991
28992             tcg_temp_free_i32(twd);
28993             tcg_temp_free(taddr);
28994         }
28995         break;
28996     default:
28997         MIPS_INVAL("MSA instruction");
28998         generate_exception_end(ctx, EXCP_RI);
28999         break;
29000     }
29001
29002 }
29003
29004 static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
29005 {
29006     int32_t offset;
29007     int rs, rt, rd, sa;
29008     uint32_t op, op1;
29009     int16_t imm;
29010
29011     /* make sure instructions are on a word boundary */
29012     if (ctx->base.pc_next & 0x3) {
29013         env->CP0_BadVAddr = ctx->base.pc_next;
29014         generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
29015         return;
29016     }
29017
29018     /* Handle blikely not taken case */
29019     if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
29020         TCGLabel *l1 = gen_new_label();
29021
29022         tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
29023         tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
29024         gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
29025         gen_set_label(l1);
29026     }
29027
29028     op = MASK_OP_MAJOR(ctx->opcode);
29029     rs = (ctx->opcode >> 21) & 0x1f;
29030     rt = (ctx->opcode >> 16) & 0x1f;
29031     rd = (ctx->opcode >> 11) & 0x1f;
29032     sa = (ctx->opcode >> 6) & 0x1f;
29033     imm = (int16_t)ctx->opcode;
29034     switch (op) {
29035     case OPC_SPECIAL:
29036         decode_opc_special(env, ctx);
29037         break;
29038     case OPC_SPECIAL2:
29039 #if defined(TARGET_MIPS64)
29040         if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
29041             decode_mmi(env, ctx);
29042 #else
29043         if (ctx->insn_flags & ASE_MXU) {
29044             decode_opc_mxu(env, ctx);
29045 #endif
29046         } else {
29047             decode_opc_special2_legacy(env, ctx);
29048         }
29049         break;
29050     case OPC_SPECIAL3:
29051 #if defined(TARGET_MIPS64)
29052         if (ctx->insn_flags & INSN_R5900) {
29053             decode_mmi_sq(env, ctx);    /* MMI_OPC_SQ */
29054         } else {
29055             decode_opc_special3(env, ctx);
29056         }
29057 #else
29058         decode_opc_special3(env, ctx);
29059 #endif
29060         break;
29061     case OPC_REGIMM:
29062         op1 = MASK_REGIMM(ctx->opcode);
29063         switch (op1) {
29064         case OPC_BLTZL: /* REGIMM branches */
29065         case OPC_BGEZL:
29066         case OPC_BLTZALL:
29067         case OPC_BGEZALL:
29068             check_insn(ctx, ISA_MIPS2);
29069             check_insn_opc_removed(ctx, ISA_MIPS32R6);
29070             /* Fallthrough */
29071         case OPC_BLTZ:
29072         case OPC_BGEZ:
29073             gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
29074             break;
29075         case OPC_BLTZAL:
29076         case OPC_BGEZAL:
29077             if (ctx->insn_flags & ISA_MIPS32R6) {
29078                 if (rs == 0) {
29079                     /* OPC_NAL, OPC_BAL */
29080                     gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
29081                 } else {
29082                     generate_exception_end(ctx, EXCP_RI);
29083                 }
29084             } else {
29085                 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
29086             }
29087             break;
29088         case OPC_TGEI: /* REGIMM traps */
29089         case OPC_TGEIU:
29090         case OPC_TLTI:
29091         case OPC_TLTIU:
29092         case OPC_TEQI:
29093
29094         case OPC_TNEI:
29095             check_insn(ctx, ISA_MIPS2);
29096             check_insn_opc_removed(ctx, ISA_MIPS32R6);
29097             gen_trap(ctx, op1, rs, -1, imm);
29098             break;
29099         case OPC_SIGRIE:
29100             check_insn(ctx, ISA_MIPS32R6);
29101             generate_exception_end(ctx, EXCP_RI);
29102             break;
29103         case OPC_SYNCI:
29104             check_insn(ctx, ISA_MIPS32R2);
29105             /* Break the TB to be able to sync copied instructions
29106                immediately */
29107             ctx->base.is_jmp = DISAS_STOP;
29108             break;
29109         case OPC_BPOSGE32:    /* MIPS DSP branch */
29110 #if defined(TARGET_MIPS64)
29111         case OPC_BPOSGE64:
29112 #endif
29113             check_dsp(ctx);
29114             gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
29115             break;
29116 #if defined(TARGET_MIPS64)
29117         case OPC_DAHI:
29118             check_insn(ctx, ISA_MIPS32R6);
29119             check_mips_64(ctx);
29120             if (rs != 0) {
29121                 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
29122             }
29123             break;
29124         case OPC_DATI:
29125             check_insn(ctx, ISA_MIPS32R6);
29126             check_mips_64(ctx);
29127             if (rs != 0) {
29128                 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
29129             }
29130             break;
29131 #endif
29132         default:            /* Invalid */
29133             MIPS_INVAL("regimm");
29134             generate_exception_end(ctx, EXCP_RI);
29135             break;
29136         }
29137         break;
29138     case OPC_CP0:
29139         check_cp0_enabled(ctx);
29140         op1 = MASK_CP0(ctx->opcode);
29141         switch (op1) {
29142         case OPC_MFC0:
29143         case OPC_MTC0:
29144         case OPC_MFTR:
29145         case OPC_MTTR:
29146         case OPC_MFHC0:
29147         case OPC_MTHC0:
29148 #if defined(TARGET_MIPS64)
29149         case OPC_DMFC0:
29150         case OPC_DMTC0:
29151 #endif
29152 #ifndef CONFIG_USER_ONLY
29153             gen_cp0(env, ctx, op1, rt, rd);
29154 #endif /* !CONFIG_USER_ONLY */
29155             break;
29156         case OPC_C0:
29157         case OPC_C0_1:
29158         case OPC_C0_2:
29159         case OPC_C0_3:
29160         case OPC_C0_4:
29161         case OPC_C0_5:
29162         case OPC_C0_6:
29163         case OPC_C0_7:
29164         case OPC_C0_8:
29165         case OPC_C0_9:
29166         case OPC_C0_A:
29167         case OPC_C0_B:
29168         case OPC_C0_C:
29169         case OPC_C0_D:
29170         case OPC_C0_E:
29171         case OPC_C0_F:
29172 #ifndef CONFIG_USER_ONLY
29173             gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
29174 #endif /* !CONFIG_USER_ONLY */
29175             break;
29176         case OPC_MFMC0:
29177 #ifndef CONFIG_USER_ONLY
29178             {
29179                 uint32_t op2;
29180                 TCGv t0 = tcg_temp_new();
29181
29182                 op2 = MASK_MFMC0(ctx->opcode);
29183                 switch (op2) {
29184                 case OPC_DMT:
29185                     check_cp0_mt(ctx);
29186                     gen_helper_dmt(t0);
29187                     gen_store_gpr(t0, rt);
29188                     break;
29189                 case OPC_EMT:
29190                     check_cp0_mt(ctx);
29191                     gen_helper_emt(t0);
29192                     gen_store_gpr(t0, rt);
29193                     break;
29194                 case OPC_DVPE:
29195                     check_cp0_mt(ctx);
29196                     gen_helper_dvpe(t0, cpu_env);
29197                     gen_store_gpr(t0, rt);
29198                     break;
29199                 case OPC_EVPE:
29200                     check_cp0_mt(ctx);
29201                     gen_helper_evpe(t0, cpu_env);
29202                     gen_store_gpr(t0, rt);
29203                     break;
29204                 case OPC_DVP:
29205                     check_insn(ctx, ISA_MIPS32R6);
29206                     if (ctx->vp) {
29207                         gen_helper_dvp(t0, cpu_env);
29208                         gen_store_gpr(t0, rt);
29209                     }
29210                     break;
29211                 case OPC_EVP:
29212                     check_insn(ctx, ISA_MIPS32R6);
29213                     if (ctx->vp) {
29214                         gen_helper_evp(t0, cpu_env);
29215                         gen_store_gpr(t0, rt);
29216                     }
29217                     break;
29218                 case OPC_DI:
29219                     check_insn(ctx, ISA_MIPS32R2);
29220                     save_cpu_state(ctx, 1);
29221                     gen_helper_di(t0, cpu_env);
29222                     gen_store_gpr(t0, rt);
29223                     /* Stop translation as we may have switched
29224                        the execution mode.  */
29225                     ctx->base.is_jmp = DISAS_STOP;
29226                     break;
29227                 case OPC_EI:
29228                     check_insn(ctx, ISA_MIPS32R2);
29229                     save_cpu_state(ctx, 1);
29230                     gen_helper_ei(t0, cpu_env);
29231                     gen_store_gpr(t0, rt);
29232                     /* DISAS_STOP isn't sufficient, we need to ensure we break
29233                        out of translated code to check for pending interrupts */
29234                     gen_save_pc(ctx->base.pc_next + 4);
29235                     ctx->base.is_jmp = DISAS_EXIT;
29236                     break;
29237                 default:            /* Invalid */
29238                     MIPS_INVAL("mfmc0");
29239                     generate_exception_end(ctx, EXCP_RI);
29240                     break;
29241                 }
29242                 tcg_temp_free(t0);
29243             }
29244 #endif /* !CONFIG_USER_ONLY */
29245             break;
29246         case OPC_RDPGPR:
29247             check_insn(ctx, ISA_MIPS32R2);
29248             gen_load_srsgpr(rt, rd);
29249             break;
29250         case OPC_WRPGPR:
29251             check_insn(ctx, ISA_MIPS32R2);
29252             gen_store_srsgpr(rt, rd);
29253             break;
29254         default:
29255             MIPS_INVAL("cp0");
29256             generate_exception_end(ctx, EXCP_RI);
29257             break;
29258         }
29259         break;
29260     case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
29261         if (ctx->insn_flags & ISA_MIPS32R6) {
29262             /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
29263             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29264         } else {
29265             /* OPC_ADDI */
29266             /* Arithmetic with immediate opcode */
29267             gen_arith_imm(ctx, op, rt, rs, imm);
29268         }
29269         break;
29270     case OPC_ADDIU:
29271          gen_arith_imm(ctx, op, rt, rs, imm);
29272          break;
29273     case OPC_SLTI: /* Set on less than with immediate opcode */
29274     case OPC_SLTIU:
29275          gen_slt_imm(ctx, op, rt, rs, imm);
29276          break;
29277     case OPC_ANDI: /* Arithmetic with immediate opcode */
29278     case OPC_LUI: /* OPC_AUI */
29279     case OPC_ORI:
29280     case OPC_XORI:
29281          gen_logic_imm(ctx, op, rt, rs, imm);
29282          break;
29283     case OPC_J: /* Jump */
29284     case OPC_JAL:
29285          offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
29286          gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
29287          break;
29288     /* Branch */
29289     case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
29290         if (ctx->insn_flags & ISA_MIPS32R6) {
29291             if (rt == 0) {
29292                 generate_exception_end(ctx, EXCP_RI);
29293                 break;
29294             }
29295             /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
29296             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29297         } else {
29298             /* OPC_BLEZL */
29299             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29300         }
29301         break;
29302     case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
29303         if (ctx->insn_flags & ISA_MIPS32R6) {
29304             if (rt == 0) {
29305                 generate_exception_end(ctx, EXCP_RI);
29306                 break;
29307             }
29308             /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
29309             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29310         } else {
29311             /* OPC_BGTZL */
29312             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29313         }
29314         break;
29315     case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
29316         if (rt == 0) {
29317             /* OPC_BLEZ */
29318             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29319         } else {
29320             check_insn(ctx, ISA_MIPS32R6);
29321             /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
29322             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29323         }
29324         break;
29325     case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
29326         if (rt == 0) {
29327             /* OPC_BGTZ */
29328             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29329         } else {
29330             check_insn(ctx, ISA_MIPS32R6);
29331             /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
29332             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29333         }
29334         break;
29335     case OPC_BEQL:
29336     case OPC_BNEL:
29337         check_insn(ctx, ISA_MIPS2);
29338          check_insn_opc_removed(ctx, ISA_MIPS32R6);
29339         /* Fallthrough */
29340     case OPC_BEQ:
29341     case OPC_BNE:
29342          gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29343          break;
29344     case OPC_LL: /* Load and stores */
29345         check_insn(ctx, ISA_MIPS2);
29346         if (ctx->insn_flags & INSN_R5900) {
29347             check_insn_opc_user_only(ctx, INSN_R5900);
29348         }
29349         /* Fallthrough */
29350     case OPC_LWL:
29351     case OPC_LWR:
29352         check_insn_opc_removed(ctx, ISA_MIPS32R6);
29353          /* Fallthrough */
29354     case OPC_LB:
29355     case OPC_LH:
29356     case OPC_LW:
29357     case OPC_LWPC:
29358     case OPC_LBU:
29359     case OPC_LHU:
29360          gen_ld(ctx, op, rt, rs, imm);
29361          break;
29362     case OPC_SWL:
29363     case OPC_SWR:
29364         check_insn_opc_removed(ctx, ISA_MIPS32R6);
29365         /* fall through */
29366     case OPC_SB:
29367     case OPC_SH:
29368     case OPC_SW:
29369          gen_st(ctx, op, rt, rs, imm);
29370          break;
29371     case OPC_SC:
29372         check_insn(ctx, ISA_MIPS2);
29373          check_insn_opc_removed(ctx, ISA_MIPS32R6);
29374         if (ctx->insn_flags & INSN_R5900) {
29375             check_insn_opc_user_only(ctx, INSN_R5900);
29376         }
29377         gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
29378         break;
29379     case OPC_CACHE:
29380         check_insn_opc_removed(ctx, ISA_MIPS32R6);
29381         check_cp0_enabled(ctx);
29382         check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
29383         if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
29384             gen_cache_operation(ctx, rt, rs, imm);
29385         }
29386         /* Treat as NOP. */
29387         break;
29388     case OPC_PREF:
29389         check_insn_opc_removed(ctx, ISA_MIPS32R6);
29390         if (ctx->insn_flags & INSN_R5900) {
29391             /* Treat as NOP. */
29392         } else {
29393             check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
29394             /* Treat as NOP. */
29395         }
29396         break;
29397
29398     /* Floating point (COP1). */
29399     case OPC_LWC1:
29400     case OPC_LDC1:
29401     case OPC_SWC1:
29402     case OPC_SDC1:
29403         gen_cop1_ldst(ctx, op, rt, rs, imm);
29404         break;
29405
29406     case OPC_CP1:
29407         op1 = MASK_CP1(ctx->opcode);
29408
29409         switch (op1) {
29410         case OPC_MFHC1:
29411         case OPC_MTHC1:
29412             check_cp1_enabled(ctx);
29413             check_insn(ctx, ISA_MIPS32R2);
29414             /* fall through */
29415         case OPC_MFC1:
29416         case OPC_CFC1:
29417         case OPC_MTC1:
29418         case OPC_CTC1:
29419             check_cp1_enabled(ctx);
29420             gen_cp1(ctx, op1, rt, rd);
29421             break;
29422 #if defined(TARGET_MIPS64)
29423         case OPC_DMFC1:
29424         case OPC_DMTC1:
29425             check_cp1_enabled(ctx);
29426             check_insn(ctx, ISA_MIPS3);
29427             check_mips_64(ctx);
29428             gen_cp1(ctx, op1, rt, rd);
29429             break;
29430 #endif
29431         case OPC_BC1EQZ: /* OPC_BC1ANY2 */
29432             check_cp1_enabled(ctx);
29433             if (ctx->insn_flags & ISA_MIPS32R6) {
29434                 /* OPC_BC1EQZ */
29435                 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
29436                                        rt, imm << 2, 4);
29437             } else {
29438                 /* OPC_BC1ANY2 */
29439                 check_cop1x(ctx);
29440                 check_insn(ctx, ASE_MIPS3D);
29441                 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
29442                                     (rt >> 2) & 0x7, imm << 2);
29443             }
29444             break;
29445         case OPC_BC1NEZ:
29446             check_cp1_enabled(ctx);
29447             check_insn(ctx, ISA_MIPS32R6);
29448             gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
29449                                    rt, imm << 2, 4);
29450             break;
29451         case OPC_BC1ANY4:
29452             check_cp1_enabled(ctx);
29453             check_insn_opc_removed(ctx, ISA_MIPS32R6);
29454             check_cop1x(ctx);
29455             check_insn(ctx, ASE_MIPS3D);
29456             /* fall through */
29457         case OPC_BC1:
29458             check_cp1_enabled(ctx);
29459             check_insn_opc_removed(ctx, ISA_MIPS32R6);
29460             gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
29461                                 (rt >> 2) & 0x7, imm << 2);
29462             break;
29463         case OPC_PS_FMT:
29464             check_ps(ctx);
29465             /* fall through */
29466         case OPC_S_FMT:
29467         case OPC_D_FMT:
29468             check_cp1_enabled(ctx);
29469             gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
29470                        (imm >> 8) & 0x7);
29471             break;
29472         case OPC_W_FMT:
29473         case OPC_L_FMT:
29474         {
29475             int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
29476             check_cp1_enabled(ctx);
29477             if (ctx->insn_flags & ISA_MIPS32R6) {
29478                 switch (r6_op) {
29479                 case R6_OPC_CMP_AF_S:
29480                 case R6_OPC_CMP_UN_S:
29481                 case R6_OPC_CMP_EQ_S:
29482                 case R6_OPC_CMP_UEQ_S:
29483                 case R6_OPC_CMP_LT_S:
29484                 case R6_OPC_CMP_ULT_S:
29485                 case R6_OPC_CMP_LE_S:
29486                 case R6_OPC_CMP_ULE_S:
29487                 case R6_OPC_CMP_SAF_S:
29488                 case R6_OPC_CMP_SUN_S:
29489                 case R6_OPC_CMP_SEQ_S:
29490                 case R6_OPC_CMP_SEUQ_S:
29491                 case R6_OPC_CMP_SLT_S:
29492                 case R6_OPC_CMP_SULT_S:
29493                 case R6_OPC_CMP_SLE_S:
29494                 case R6_OPC_CMP_SULE_S:
29495                 case R6_OPC_CMP_OR_S:
29496                 case R6_OPC_CMP_UNE_S:
29497                 case R6_OPC_CMP_NE_S:
29498                 case R6_OPC_CMP_SOR_S:
29499                 case R6_OPC_CMP_SUNE_S:
29500                 case R6_OPC_CMP_SNE_S:
29501                     gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
29502                     break;
29503                 case R6_OPC_CMP_AF_D:
29504                 case R6_OPC_CMP_UN_D:
29505                 case R6_OPC_CMP_EQ_D:
29506                 case R6_OPC_CMP_UEQ_D:
29507                 case R6_OPC_CMP_LT_D:
29508                 case R6_OPC_CMP_ULT_D:
29509                 case R6_OPC_CMP_LE_D:
29510                 case R6_OPC_CMP_ULE_D:
29511                 case R6_OPC_CMP_SAF_D:
29512                 case R6_OPC_CMP_SUN_D:
29513                 case R6_OPC_CMP_SEQ_D:
29514                 case R6_OPC_CMP_SEUQ_D:
29515                 case R6_OPC_CMP_SLT_D:
29516                 case R6_OPC_CMP_SULT_D:
29517                 case R6_OPC_CMP_SLE_D:
29518                 case R6_OPC_CMP_SULE_D:
29519                 case R6_OPC_CMP_OR_D:
29520                 case R6_OPC_CMP_UNE_D:
29521                 case R6_OPC_CMP_NE_D:
29522                 case R6_OPC_CMP_SOR_D:
29523                 case R6_OPC_CMP_SUNE_D:
29524                 case R6_OPC_CMP_SNE_D:
29525                     gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
29526                     break;
29527                 default:
29528                     gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
29529                                rt, rd, sa, (imm >> 8) & 0x7);
29530
29531                     break;
29532                 }
29533             } else {
29534                 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
29535                            (imm >> 8) & 0x7);
29536             }
29537             break;
29538         }
29539         case OPC_BZ_V:
29540         case OPC_BNZ_V:
29541         case OPC_BZ_B:
29542         case OPC_BZ_H:
29543         case OPC_BZ_W:
29544         case OPC_BZ_D:
29545         case OPC_BNZ_B:
29546         case OPC_BNZ_H:
29547         case OPC_BNZ_W:
29548         case OPC_BNZ_D:
29549             check_insn(ctx, ASE_MSA);
29550             gen_msa_branch(env, ctx, op1);
29551             break;
29552         default:
29553             MIPS_INVAL("cp1");
29554             generate_exception_end(ctx, EXCP_RI);
29555             break;
29556         }
29557         break;
29558
29559     /* Compact branches [R6] and COP2 [non-R6] */
29560     case OPC_BC: /* OPC_LWC2 */
29561     case OPC_BALC: /* OPC_SWC2 */
29562         if (ctx->insn_flags & ISA_MIPS32R6) {
29563             /* OPC_BC, OPC_BALC */
29564             gen_compute_compact_branch(ctx, op, 0, 0,
29565                                        sextract32(ctx->opcode << 2, 0, 28));
29566         } else {
29567             /* OPC_LWC2, OPC_SWC2 */
29568             /* COP2: Not implemented. */
29569             generate_exception_err(ctx, EXCP_CpU, 2);
29570         }
29571         break;
29572     case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
29573     case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
29574         if (ctx->insn_flags & ISA_MIPS32R6) {
29575             if (rs != 0) {
29576                 /* OPC_BEQZC, OPC_BNEZC */
29577                 gen_compute_compact_branch(ctx, op, rs, 0,
29578                                            sextract32(ctx->opcode << 2, 0, 23));
29579             } else {
29580                 /* OPC_JIC, OPC_JIALC */
29581                 gen_compute_compact_branch(ctx, op, 0, rt, imm);
29582             }
29583         } else {
29584             /* OPC_LWC2, OPC_SWC2 */
29585             /* COP2: Not implemented. */
29586             generate_exception_err(ctx, EXCP_CpU, 2);
29587         }
29588         break;
29589     case OPC_CP2:
29590         check_insn(ctx, INSN_LOONGSON2F);
29591         /* Note that these instructions use different fields.  */
29592         gen_loongson_multimedia(ctx, sa, rd, rt);
29593         break;
29594
29595     case OPC_CP3:
29596         check_insn_opc_removed(ctx, ISA_MIPS32R6);
29597         if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
29598             check_cp1_enabled(ctx);
29599             op1 = MASK_CP3(ctx->opcode);
29600             switch (op1) {
29601             case OPC_LUXC1:
29602             case OPC_SUXC1:
29603                 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
29604                 /* Fallthrough */
29605             case OPC_LWXC1:
29606             case OPC_LDXC1:
29607             case OPC_SWXC1:
29608             case OPC_SDXC1:
29609                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
29610                 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
29611                 break;
29612             case OPC_PREFX:
29613                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
29614                 /* Treat as NOP. */
29615                 break;
29616             case OPC_ALNV_PS:
29617                 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
29618                 /* Fallthrough */
29619             case OPC_MADD_S:
29620             case OPC_MADD_D:
29621             case OPC_MADD_PS:
29622             case OPC_MSUB_S:
29623             case OPC_MSUB_D:
29624             case OPC_MSUB_PS:
29625             case OPC_NMADD_S:
29626             case OPC_NMADD_D:
29627             case OPC_NMADD_PS:
29628             case OPC_NMSUB_S:
29629             case OPC_NMSUB_D:
29630             case OPC_NMSUB_PS:
29631                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
29632                 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
29633                 break;
29634             default:
29635                 MIPS_INVAL("cp3");
29636                 generate_exception_end(ctx, EXCP_RI);
29637                 break;
29638             }
29639         } else {
29640             generate_exception_err(ctx, EXCP_CpU, 1);
29641         }
29642         break;
29643
29644 #if defined(TARGET_MIPS64)
29645     /* MIPS64 opcodes */
29646     case OPC_LLD:
29647         if (ctx->insn_flags & INSN_R5900) {
29648             check_insn_opc_user_only(ctx, INSN_R5900);
29649         }
29650         /* fall through */
29651     case OPC_LDL:
29652     case OPC_LDR:
29653         check_insn_opc_removed(ctx, ISA_MIPS32R6);
29654         /* fall through */
29655     case OPC_LWU:
29656     case OPC_LD:
29657         check_insn(ctx, ISA_MIPS3);
29658         check_mips_64(ctx);
29659         gen_ld(ctx, op, rt, rs, imm);
29660         break;
29661     case OPC_SDL:
29662     case OPC_SDR:
29663         check_insn_opc_removed(ctx, ISA_MIPS32R6);
29664         /* fall through */
29665     case OPC_SD:
29666         check_insn(ctx, ISA_MIPS3);
29667         check_mips_64(ctx);
29668         gen_st(ctx, op, rt, rs, imm);
29669         break;
29670     case OPC_SCD:
29671         check_insn_opc_removed(ctx, ISA_MIPS32R6);
29672         check_insn(ctx, ISA_MIPS3);
29673         if (ctx->insn_flags & INSN_R5900) {
29674             check_insn_opc_user_only(ctx, INSN_R5900);
29675         }
29676         check_mips_64(ctx);
29677         gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false);
29678         break;
29679     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
29680         if (ctx->insn_flags & ISA_MIPS32R6) {
29681             /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
29682             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29683         } else {
29684             /* OPC_DADDI */
29685             check_insn(ctx, ISA_MIPS3);
29686             check_mips_64(ctx);
29687             gen_arith_imm(ctx, op, rt, rs, imm);
29688         }
29689         break;
29690     case OPC_DADDIU:
29691         check_insn(ctx, ISA_MIPS3);
29692         check_mips_64(ctx);
29693         gen_arith_imm(ctx, op, rt, rs, imm);
29694         break;
29695 #else
29696     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
29697         if (ctx->insn_flags & ISA_MIPS32R6) {
29698             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29699         } else {
29700             MIPS_INVAL("major opcode");
29701             generate_exception_end(ctx, EXCP_RI);
29702         }
29703         break;
29704 #endif
29705     case OPC_DAUI: /* OPC_JALX */
29706         if (ctx->insn_flags & ISA_MIPS32R6) {
29707 #if defined(TARGET_MIPS64)
29708             /* OPC_DAUI */
29709             check_mips_64(ctx);
29710             if (rs == 0) {
29711                 generate_exception(ctx, EXCP_RI);
29712             } else if (rt != 0) {
29713                 TCGv t0 = tcg_temp_new();
29714                 gen_load_gpr(t0, rs);
29715                 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
29716                 tcg_temp_free(t0);
29717             }
29718 #else
29719             generate_exception_end(ctx, EXCP_RI);
29720             MIPS_INVAL("major opcode");
29721 #endif
29722         } else {
29723             /* OPC_JALX */
29724             check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
29725             offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
29726             gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
29727         }
29728         break;
29729     case OPC_MSA: /* OPC_MDMX */
29730         if (ctx->insn_flags & INSN_R5900) {
29731 #if defined(TARGET_MIPS64)
29732             gen_mmi_lq(env, ctx);    /* MMI_OPC_LQ */
29733 #endif
29734         } else {
29735             /* MDMX: Not implemented. */
29736             gen_msa(env, ctx);
29737         }
29738         break;
29739     case OPC_PCREL:
29740         check_insn(ctx, ISA_MIPS32R6);
29741         gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
29742         break;
29743     default:            /* Invalid */
29744         MIPS_INVAL("major opcode");
29745         generate_exception_end(ctx, EXCP_RI);
29746         break;
29747     }
29748 }
29749
29750 static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
29751 {
29752     DisasContext *ctx = container_of(dcbase, DisasContext, base);
29753     CPUMIPSState *env = cs->env_ptr;
29754
29755     ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
29756     ctx->saved_pc = -1;
29757     ctx->insn_flags = env->insn_flags;
29758     ctx->CP0_Config1 = env->CP0_Config1;
29759     ctx->CP0_Config2 = env->CP0_Config2;
29760     ctx->CP0_Config3 = env->CP0_Config3;
29761     ctx->CP0_Config5 = env->CP0_Config5;
29762     ctx->btarget = 0;
29763     ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
29764     ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
29765     ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
29766     ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
29767     ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
29768     ctx->PAMask = env->PAMask;
29769     ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
29770     ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
29771     ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
29772     ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
29773     ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
29774     /* Restore delay slot state from the tb context.  */
29775     ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
29776     ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
29777     ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
29778              (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
29779     ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
29780     ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
29781     ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
29782     ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
29783     restore_cpu_state(env, ctx);
29784 #ifdef CONFIG_USER_ONLY
29785         ctx->mem_idx = MIPS_HFLAG_UM;
29786 #else
29787         ctx->mem_idx = hflags_mmu_index(ctx->hflags);
29788 #endif
29789     ctx->default_tcg_memop_mask = (ctx->insn_flags & ISA_MIPS32R6) ?
29790                                   MO_UNALN : MO_ALIGN;
29791
29792     LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
29793               ctx->hflags);
29794 }
29795
29796 static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
29797 {
29798 }
29799
29800 static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
29801 {
29802     DisasContext *ctx = container_of(dcbase, DisasContext, base);
29803
29804     tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
29805                        ctx->btarget);
29806 }
29807
29808 static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
29809                                      const CPUBreakpoint *bp)
29810 {
29811     DisasContext *ctx = container_of(dcbase, DisasContext, base);
29812
29813     save_cpu_state(ctx, 1);
29814     ctx->base.is_jmp = DISAS_NORETURN;
29815     gen_helper_raise_exception_debug(cpu_env);
29816     /* The address covered by the breakpoint must be included in
29817        [tb->pc, tb->pc + tb->size) in order to for it to be
29818        properly cleared -- thus we increment the PC here so that
29819        the logic setting tb->size below does the right thing.  */
29820     ctx->base.pc_next += 4;
29821     return true;
29822 }
29823
29824 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
29825 {
29826     CPUMIPSState *env = cs->env_ptr;
29827     DisasContext *ctx = container_of(dcbase, DisasContext, base);
29828     int insn_bytes;
29829     int is_slot;
29830
29831     is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
29832     if (ctx->insn_flags & ISA_NANOMIPS32) {
29833         ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
29834         insn_bytes = decode_nanomips_opc(env, ctx);
29835     } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
29836         ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
29837         insn_bytes = 4;
29838         decode_opc(env, ctx);
29839     } else if (ctx->insn_flags & ASE_MICROMIPS) {
29840         ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
29841         insn_bytes = decode_micromips_opc(env, ctx);
29842     } else if (ctx->insn_flags & ASE_MIPS16) {
29843         ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
29844         insn_bytes = decode_mips16_opc(env, ctx);
29845     } else {
29846         generate_exception_end(ctx, EXCP_RI);
29847         g_assert(ctx->base.is_jmp == DISAS_NORETURN);
29848         return;
29849     }
29850
29851     if (ctx->hflags & MIPS_HFLAG_BMASK) {
29852         if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
29853                              MIPS_HFLAG_FBNSLOT))) {
29854             /* force to generate branch as there is neither delay nor
29855                forbidden slot */
29856             is_slot = 1;
29857         }
29858         if ((ctx->hflags & MIPS_HFLAG_M16) &&
29859             (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
29860             /* Force to generate branch as microMIPS R6 doesn't restrict
29861                branches in the forbidden slot. */
29862             is_slot = 1;
29863         }
29864     }
29865     if (is_slot) {
29866         gen_branch(ctx, insn_bytes);
29867     }
29868     ctx->base.pc_next += insn_bytes;
29869
29870     if (ctx->base.is_jmp != DISAS_NEXT) {
29871         return;
29872     }
29873     /* Execute a branch and its delay slot as a single instruction.
29874        This is what GDB expects and is consistent with what the
29875        hardware does (e.g. if a delay slot instruction faults, the
29876        reported PC is the PC of the branch).  */
29877     if (ctx->base.singlestep_enabled &&
29878         (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
29879         ctx->base.is_jmp = DISAS_TOO_MANY;
29880     }
29881     if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
29882         ctx->base.is_jmp = DISAS_TOO_MANY;
29883     }
29884 }
29885
29886 static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
29887 {
29888     DisasContext *ctx = container_of(dcbase, DisasContext, base);
29889
29890     if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
29891         save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
29892         gen_helper_raise_exception_debug(cpu_env);
29893     } else {
29894         switch (ctx->base.is_jmp) {
29895         case DISAS_STOP:
29896             gen_save_pc(ctx->base.pc_next);
29897             tcg_gen_lookup_and_goto_ptr();
29898             break;
29899         case DISAS_NEXT:
29900         case DISAS_TOO_MANY:
29901             save_cpu_state(ctx, 0);
29902             gen_goto_tb(ctx, 0, ctx->base.pc_next);
29903             break;
29904         case DISAS_EXIT:
29905             tcg_gen_exit_tb(NULL, 0);
29906             break;
29907         case DISAS_NORETURN:
29908             break;
29909         default:
29910             g_assert_not_reached();
29911         }
29912     }
29913 }
29914
29915 static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
29916 {
29917     qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
29918     log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
29919 }
29920
29921 static const TranslatorOps mips_tr_ops = {
29922     .init_disas_context = mips_tr_init_disas_context,
29923     .tb_start           = mips_tr_tb_start,
29924     .insn_start         = mips_tr_insn_start,
29925     .breakpoint_check   = mips_tr_breakpoint_check,
29926     .translate_insn     = mips_tr_translate_insn,
29927     .tb_stop            = mips_tr_tb_stop,
29928     .disas_log          = mips_tr_disas_log,
29929 };
29930
29931 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
29932 {
29933     DisasContext ctx;
29934
29935     translator_loop(&mips_tr_ops, &ctx.base, cs, tb, max_insns);
29936 }
29937
29938 static void fpu_dump_state(CPUMIPSState *env, FILE *f, int flags)
29939 {
29940     int i;
29941     int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
29942
29943 #define printfpr(fp)                                                    \
29944     do {                                                                \
29945         if (is_fpu64)                                                   \
29946             qemu_fprintf(f, "w:%08x d:%016" PRIx64                      \
29947                          " fd:%13g fs:%13g psu: %13g\n",                \
29948                          (fp)->w[FP_ENDIAN_IDX], (fp)->d,               \
29949                          (double)(fp)->fd,                              \
29950                          (double)(fp)->fs[FP_ENDIAN_IDX],               \
29951                          (double)(fp)->fs[!FP_ENDIAN_IDX]);             \
29952         else {                                                          \
29953             fpr_t tmp;                                                  \
29954             tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];              \
29955             tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];       \
29956             qemu_fprintf(f, "w:%08x d:%016" PRIx64                      \
29957                          " fd:%13g fs:%13g psu:%13g\n",                 \
29958                          tmp.w[FP_ENDIAN_IDX], tmp.d,                   \
29959                          (double)tmp.fd,                                \
29960                          (double)tmp.fs[FP_ENDIAN_IDX],                 \
29961                          (double)tmp.fs[!FP_ENDIAN_IDX]);               \
29962         }                                                               \
29963     } while(0)
29964
29965
29966     qemu_fprintf(f,
29967                  "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%02x\n",
29968                  env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
29969                  get_float_exception_flags(&env->active_fpu.fp_status));
29970     for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
29971         qemu_fprintf(f, "%3s: ", fregnames[i]);
29972         printfpr(&env->active_fpu.fpr[i]);
29973     }
29974
29975 #undef printfpr
29976 }
29977
29978 void mips_cpu_dump_state(CPUState *cs, FILE *f, int flags)
29979 {
29980     MIPSCPU *cpu = MIPS_CPU(cs);
29981     CPUMIPSState *env = &cpu->env;
29982     int i;
29983
29984     qemu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
29985                  " LO=0x" TARGET_FMT_lx " ds %04x "
29986                  TARGET_FMT_lx " " TARGET_FMT_ld "\n",
29987                  env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
29988                  env->hflags, env->btarget, env->bcond);
29989     for (i = 0; i < 32; i++) {
29990         if ((i & 3) == 0)
29991             qemu_fprintf(f, "GPR%02d:", i);
29992         qemu_fprintf(f, " %s " TARGET_FMT_lx,
29993                      regnames[i], env->active_tc.gpr[i]);
29994         if ((i & 3) == 3)
29995             qemu_fprintf(f, "\n");
29996     }
29997
29998     qemu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
29999                  env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
30000     qemu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
30001                  PRIx64 "\n",
30002                  env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
30003     qemu_fprintf(f, "    Config2 0x%08x Config3 0x%08x\n",
30004                  env->CP0_Config2, env->CP0_Config3);
30005     qemu_fprintf(f, "    Config4 0x%08x Config5 0x%08x\n",
30006                  env->CP0_Config4, env->CP0_Config5);
30007     if ((flags & CPU_DUMP_FPU) && (env->hflags & MIPS_HFLAG_FPU)) {
30008         fpu_dump_state(env, f, flags);
30009     }
30010 }
30011
30012 void mips_tcg_init(void)
30013 {
30014     int i;
30015
30016     cpu_gpr[0] = NULL;
30017     for (i = 1; i < 32; i++)
30018         cpu_gpr[i] = tcg_global_mem_new(cpu_env,
30019                                         offsetof(CPUMIPSState, active_tc.gpr[i]),
30020                                         regnames[i]);
30021
30022     for (i = 0; i < 32; i++) {
30023         int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
30024         msa_wr_d[i * 2] =
30025                 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
30026         /* The scalar floating-point unit (FPU) registers are mapped on
30027          * the MSA vector registers. */
30028         fpu_f64[i] = msa_wr_d[i * 2];
30029         off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
30030         msa_wr_d[i * 2 + 1] =
30031                 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
30032     }
30033
30034     cpu_PC = tcg_global_mem_new(cpu_env,
30035                                 offsetof(CPUMIPSState, active_tc.PC), "PC");
30036     for (i = 0; i < MIPS_DSP_ACC; i++) {
30037         cpu_HI[i] = tcg_global_mem_new(cpu_env,
30038                                        offsetof(CPUMIPSState, active_tc.HI[i]),
30039                                        regnames_HI[i]);
30040         cpu_LO[i] = tcg_global_mem_new(cpu_env,
30041                                        offsetof(CPUMIPSState, active_tc.LO[i]),
30042                                        regnames_LO[i]);
30043     }
30044     cpu_dspctrl = tcg_global_mem_new(cpu_env,
30045                                      offsetof(CPUMIPSState, active_tc.DSPControl),
30046                                      "DSPControl");
30047     bcond = tcg_global_mem_new(cpu_env,
30048                                offsetof(CPUMIPSState, bcond), "bcond");
30049     btarget = tcg_global_mem_new(cpu_env,
30050                                  offsetof(CPUMIPSState, btarget), "btarget");
30051     hflags = tcg_global_mem_new_i32(cpu_env,
30052                                     offsetof(CPUMIPSState, hflags), "hflags");
30053
30054     fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
30055                                       offsetof(CPUMIPSState, active_fpu.fcr0),
30056                                       "fcr0");
30057     fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
30058                                        offsetof(CPUMIPSState, active_fpu.fcr31),
30059                                        "fcr31");
30060     cpu_lladdr = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, lladdr),
30061                                     "lladdr");
30062     cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, llval),
30063                                    "llval");
30064
30065 #if defined(TARGET_MIPS64)
30066     cpu_mmr[0] = NULL;
30067     for (i = 1; i < 32; i++) {
30068         cpu_mmr[i] = tcg_global_mem_new_i64(cpu_env,
30069                                             offsetof(CPUMIPSState,
30070                                                      active_tc.mmr[i]),
30071                                             regnames[i]);
30072     }
30073 #endif
30074
30075 #if !defined(TARGET_MIPS64)
30076     for (i = 0; i < NUMBER_OF_MXU_REGISTERS - 1; i++) {
30077         mxu_gpr[i] = tcg_global_mem_new(cpu_env,
30078                                         offsetof(CPUMIPSState,
30079                                                  active_tc.mxu_gpr[i]),
30080                                         mxuregnames[i]);
30081     }
30082
30083     mxu_CR = tcg_global_mem_new(cpu_env,
30084                                 offsetof(CPUMIPSState, active_tc.mxu_cr),
30085                                 mxuregnames[NUMBER_OF_MXU_REGISTERS - 1]);
30086 #endif
30087 }
30088
30089 #include "translate_init.inc.c"
30090
30091 void cpu_mips_realize_env(CPUMIPSState *env)
30092 {
30093     env->exception_base = (int32_t)0xBFC00000;
30094
30095 #ifndef CONFIG_USER_ONLY
30096     mmu_init(env, env->cpu_model);
30097 #endif
30098     fpu_init(env, env->cpu_model);
30099     mvp_init(env, env->cpu_model);
30100 }
30101
30102 bool cpu_supports_cps_smp(const char *cpu_type)
30103 {
30104     const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
30105     return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
30106 }
30107
30108 bool cpu_supports_isa(const char *cpu_type, uint64_t isa)
30109 {
30110     const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
30111     return (mcc->cpu_def->insn_flags & isa) != 0;
30112 }
30113
30114 void cpu_set_exception_base(int vp_index, target_ulong address)
30115 {
30116     MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
30117     vp->env.exception_base = address;
30118 }
30119
30120 void cpu_state_reset(CPUMIPSState *env)
30121 {
30122     CPUState *cs = env_cpu(env);
30123
30124     /* Reset registers to their default values */
30125     env->CP0_PRid = env->cpu_model->CP0_PRid;
30126     env->CP0_Config0 = env->cpu_model->CP0_Config0;
30127 #ifdef TARGET_WORDS_BIGENDIAN
30128     env->CP0_Config0 |= (1 << CP0C0_BE);
30129 #endif
30130     env->CP0_Config1 = env->cpu_model->CP0_Config1;
30131     env->CP0_Config2 = env->cpu_model->CP0_Config2;
30132     env->CP0_Config3 = env->cpu_model->CP0_Config3;
30133     env->CP0_Config4 = env->cpu_model->CP0_Config4;
30134     env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
30135     env->CP0_Config5 = env->cpu_model->CP0_Config5;
30136     env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
30137     env->CP0_Config6 = env->cpu_model->CP0_Config6;
30138     env->CP0_Config7 = env->cpu_model->CP0_Config7;
30139     env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
30140                                  << env->cpu_model->CP0_LLAddr_shift;
30141     env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
30142     env->SYNCI_Step = env->cpu_model->SYNCI_Step;
30143     env->CCRes = env->cpu_model->CCRes;
30144     env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
30145     env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
30146     env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
30147     env->current_tc = 0;
30148     env->SEGBITS = env->cpu_model->SEGBITS;
30149     env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
30150 #if defined(TARGET_MIPS64)
30151     if (env->cpu_model->insn_flags & ISA_MIPS3) {
30152         env->SEGMask |= 3ULL << 62;
30153     }
30154 #endif
30155     env->PABITS = env->cpu_model->PABITS;
30156     env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
30157     env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
30158     env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
30159     env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
30160     env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
30161     env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
30162     env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
30163     env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
30164     env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
30165     env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
30166     env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
30167     env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
30168     env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
30169     env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
30170     env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
30171     env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
30172     env->msair = env->cpu_model->MSAIR;
30173     env->insn_flags = env->cpu_model->insn_flags;
30174
30175 #if defined(CONFIG_USER_ONLY)
30176     env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
30177 # ifdef TARGET_MIPS64
30178     /* Enable 64-bit register mode.  */
30179     env->CP0_Status |= (1 << CP0St_PX);
30180 # endif
30181 # ifdef TARGET_ABI_MIPSN64
30182     /* Enable 64-bit address mode.  */
30183     env->CP0_Status |= (1 << CP0St_UX);
30184 # endif
30185     /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
30186        hardware registers.  */
30187     env->CP0_HWREna |= 0x0000000F;
30188     if (env->CP0_Config1 & (1 << CP0C1_FP)) {
30189         env->CP0_Status |= (1 << CP0St_CU1);
30190     }
30191     if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
30192         env->CP0_Status |= (1 << CP0St_MX);
30193     }
30194 # if defined(TARGET_MIPS64)
30195     /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
30196     if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
30197         (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
30198         env->CP0_Status |= (1 << CP0St_FR);
30199     }
30200 # endif
30201 #else
30202     if (env->hflags & MIPS_HFLAG_BMASK) {
30203         /* If the exception was raised from a delay slot,
30204            come back to the jump.  */
30205         env->CP0_ErrorEPC = (env->active_tc.PC
30206                              - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
30207     } else {
30208         env->CP0_ErrorEPC = env->active_tc.PC;
30209     }
30210     env->active_tc.PC = env->exception_base;
30211     env->CP0_Random = env->tlb->nb_tlb - 1;
30212     env->tlb->tlb_in_use = env->tlb->nb_tlb;
30213     env->CP0_Wired = 0;
30214     env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
30215     env->CP0_EBase = (cs->cpu_index & 0x3FF);
30216     if (mips_um_ksegs_enabled()) {
30217         env->CP0_EBase |= 0x40000000;
30218     } else {
30219         env->CP0_EBase |= (int32_t)0x80000000;
30220     }
30221     if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
30222         env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
30223     }
30224     env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
30225                                  0x3ff : 0xff;
30226     env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
30227     /* vectored interrupts not implemented, timer on int 7,
30228        no performance counters. */
30229     env->CP0_IntCtl = 0xe0000000;
30230     {
30231         int i;
30232
30233         for (i = 0; i < 7; i++) {
30234             env->CP0_WatchLo[i] = 0;
30235             env->CP0_WatchHi[i] = 0x80000000;
30236         }
30237         env->CP0_WatchLo[7] = 0;
30238         env->CP0_WatchHi[7] = 0;
30239     }
30240     /* Count register increments in debug mode, EJTAG version 1 */
30241     env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
30242
30243     cpu_mips_store_count(env, 1);
30244
30245     if (env->CP0_Config3 & (1 << CP0C3_MT)) {
30246         int i;
30247
30248         /* Only TC0 on VPE 0 starts as active.  */
30249         for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
30250             env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
30251             env->tcs[i].CP0_TCHalt = 1;
30252         }
30253         env->active_tc.CP0_TCHalt = 1;
30254         cs->halted = 1;
30255
30256         if (cs->cpu_index == 0) {
30257             /* VPE0 starts up enabled.  */
30258             env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
30259             env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
30260
30261             /* TC0 starts up unhalted.  */
30262             cs->halted = 0;
30263             env->active_tc.CP0_TCHalt = 0;
30264             env->tcs[0].CP0_TCHalt = 0;
30265             /* With thread 0 active.  */
30266             env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
30267             env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
30268         }
30269     }
30270
30271     /*
30272      * Configure default legacy segmentation control. We use this regardless of
30273      * whether segmentation control is presented to the guest.
30274      */
30275     /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
30276     env->CP0_SegCtl0 =   (CP0SC_AM_MK << CP0SC_AM);
30277     /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
30278     env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
30279     /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
30280     env->CP0_SegCtl1 =   (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
30281                          (2 << CP0SC_C);
30282     /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
30283     env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
30284                          (3 << CP0SC_C)) << 16;
30285     /* USeg (seg4 0x40000000..0x7FFFFFFF) */
30286     env->CP0_SegCtl2 =   (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
30287                          (1 << CP0SC_EU) | (2 << CP0SC_C);
30288     /* USeg (seg5 0x00000000..0x3FFFFFFF) */
30289     env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
30290                          (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
30291     /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
30292     env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
30293 #endif
30294     if ((env->insn_flags & ISA_MIPS32R6) &&
30295         (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
30296         /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
30297         env->CP0_Status |= (1 << CP0St_FR);
30298     }
30299
30300     if (env->insn_flags & ISA_MIPS32R6) {
30301         /* PTW  =  1 */
30302         env->CP0_PWSize = 0x40;
30303         /* GDI  = 12 */
30304         /* UDI  = 12 */
30305         /* MDI  = 12 */
30306         /* PRI  = 12 */
30307         /* PTEI =  2 */
30308         env->CP0_PWField = 0x0C30C302;
30309     } else {
30310         /* GDI  =  0 */
30311         /* UDI  =  0 */
30312         /* MDI  =  0 */
30313         /* PRI  =  0 */
30314         /* PTEI =  2 */
30315         env->CP0_PWField = 0x02;
30316     }
30317
30318     if (env->CP0_Config3 & (1 << CP0C3_ISA) & (1 << (CP0C3_ISA + 1))) {
30319         /*  microMIPS on reset when Config3.ISA is 3 */
30320         env->hflags |= MIPS_HFLAG_M16;
30321     }
30322
30323     /* MSA */
30324     if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
30325         msa_reset(env);
30326     }
30327
30328     compute_hflags(env);
30329     restore_fp_status(env);
30330     restore_pamask(env);
30331     cs->exception_index = EXCP_NONE;
30332
30333     if (semihosting_get_argc()) {
30334         /* UHI interface can be used to obtain argc and argv */
30335         env->active_tc.gpr[4] = -1;
30336     }
30337 }
30338
30339 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
30340                           target_ulong *data)
30341 {
30342     env->active_tc.PC = data[0];
30343     env->hflags &= ~MIPS_HFLAG_BMASK;
30344     env->hflags |= data[1];
30345     switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
30346     case MIPS_HFLAG_BR:
30347         break;
30348     case MIPS_HFLAG_BC:
30349     case MIPS_HFLAG_BL:
30350     case MIPS_HFLAG_B:
30351         env->btarget = data[2];
30352         break;
30353     }
30354 }
This page took 1.70189 seconds and 4 git commands to generate.