]> Git Repo - qemu.git/blob - target/mips/translate.c
target/mips: Add emulation of MXU instructions S32I2M and S32M2I
[qemu.git] / target / mips / translate.c
1 /*
2  *  MIPS emulation for QEMU - main translation routines
3  *
4  *  Copyright (c) 2004-2005 Jocelyn Mayer
5  *  Copyright (c) 2006 Marius Groeger (FPU operations)
6  *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7  *  Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
8  *  Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
22  */
23
24 #include "qemu/osdep.h"
25 #include "cpu.h"
26 #include "internal.h"
27 #include "disas/disas.h"
28 #include "exec/exec-all.h"
29 #include "tcg-op.h"
30 #include "exec/cpu_ldst.h"
31 #include "hw/mips/cpudevs.h"
32
33 #include "exec/helper-proto.h"
34 #include "exec/helper-gen.h"
35 #include "exec/semihost.h"
36
37 #include "target/mips/trace.h"
38 #include "trace-tcg.h"
39 #include "exec/translator.h"
40 #include "exec/log.h"
41
42 #define MIPS_DEBUG_DISAS 0
43
44 /* MIPS major opcodes */
45 #define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
46
47 enum {
48     /* indirect opcode tables */
49     OPC_SPECIAL  = (0x00 << 26),
50     OPC_REGIMM   = (0x01 << 26),
51     OPC_CP0      = (0x10 << 26),
52     OPC_CP1      = (0x11 << 26),
53     OPC_CP2      = (0x12 << 26),
54     OPC_CP3      = (0x13 << 26),
55     OPC_SPECIAL2 = (0x1C << 26),
56     OPC_SPECIAL3 = (0x1F << 26),
57     /* arithmetic with immediate */
58     OPC_ADDI     = (0x08 << 26),
59     OPC_ADDIU    = (0x09 << 26),
60     OPC_SLTI     = (0x0A << 26),
61     OPC_SLTIU    = (0x0B << 26),
62     /* logic with immediate */
63     OPC_ANDI     = (0x0C << 26),
64     OPC_ORI      = (0x0D << 26),
65     OPC_XORI     = (0x0E << 26),
66     OPC_LUI      = (0x0F << 26),
67     /* arithmetic with immediate */
68     OPC_DADDI    = (0x18 << 26),
69     OPC_DADDIU   = (0x19 << 26),
70     /* Jump and branches */
71     OPC_J        = (0x02 << 26),
72     OPC_JAL      = (0x03 << 26),
73     OPC_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
74     OPC_BEQL     = (0x14 << 26),
75     OPC_BNE      = (0x05 << 26),
76     OPC_BNEL     = (0x15 << 26),
77     OPC_BLEZ     = (0x06 << 26),
78     OPC_BLEZL    = (0x16 << 26),
79     OPC_BGTZ     = (0x07 << 26),
80     OPC_BGTZL    = (0x17 << 26),
81     OPC_JALX     = (0x1D << 26),
82     OPC_DAUI     = (0x1D << 26),
83     /* Load and stores */
84     OPC_LDL      = (0x1A << 26),
85     OPC_LDR      = (0x1B << 26),
86     OPC_LB       = (0x20 << 26),
87     OPC_LH       = (0x21 << 26),
88     OPC_LWL      = (0x22 << 26),
89     OPC_LW       = (0x23 << 26),
90     OPC_LWPC     = OPC_LW | 0x5,
91     OPC_LBU      = (0x24 << 26),
92     OPC_LHU      = (0x25 << 26),
93     OPC_LWR      = (0x26 << 26),
94     OPC_LWU      = (0x27 << 26),
95     OPC_SB       = (0x28 << 26),
96     OPC_SH       = (0x29 << 26),
97     OPC_SWL      = (0x2A << 26),
98     OPC_SW       = (0x2B << 26),
99     OPC_SDL      = (0x2C << 26),
100     OPC_SDR      = (0x2D << 26),
101     OPC_SWR      = (0x2E << 26),
102     OPC_LL       = (0x30 << 26),
103     OPC_LLD      = (0x34 << 26),
104     OPC_LD       = (0x37 << 26),
105     OPC_LDPC     = OPC_LD | 0x5,
106     OPC_SC       = (0x38 << 26),
107     OPC_SCD      = (0x3C << 26),
108     OPC_SD       = (0x3F << 26),
109     /* Floating point load/store */
110     OPC_LWC1     = (0x31 << 26),
111     OPC_LWC2     = (0x32 << 26),
112     OPC_LDC1     = (0x35 << 26),
113     OPC_LDC2     = (0x36 << 26),
114     OPC_SWC1     = (0x39 << 26),
115     OPC_SWC2     = (0x3A << 26),
116     OPC_SDC1     = (0x3D << 26),
117     OPC_SDC2     = (0x3E << 26),
118     /* Compact Branches */
119     OPC_BLEZALC  = (0x06 << 26),
120     OPC_BGEZALC  = (0x06 << 26),
121     OPC_BGEUC    = (0x06 << 26),
122     OPC_BGTZALC  = (0x07 << 26),
123     OPC_BLTZALC  = (0x07 << 26),
124     OPC_BLTUC    = (0x07 << 26),
125     OPC_BOVC     = (0x08 << 26),
126     OPC_BEQZALC  = (0x08 << 26),
127     OPC_BEQC     = (0x08 << 26),
128     OPC_BLEZC    = (0x16 << 26),
129     OPC_BGEZC    = (0x16 << 26),
130     OPC_BGEC     = (0x16 << 26),
131     OPC_BGTZC    = (0x17 << 26),
132     OPC_BLTZC    = (0x17 << 26),
133     OPC_BLTC     = (0x17 << 26),
134     OPC_BNVC     = (0x18 << 26),
135     OPC_BNEZALC  = (0x18 << 26),
136     OPC_BNEC     = (0x18 << 26),
137     OPC_BC       = (0x32 << 26),
138     OPC_BEQZC    = (0x36 << 26),
139     OPC_JIC      = (0x36 << 26),
140     OPC_BALC     = (0x3A << 26),
141     OPC_BNEZC    = (0x3E << 26),
142     OPC_JIALC    = (0x3E << 26),
143     /* MDMX ASE specific */
144     OPC_MDMX     = (0x1E << 26),
145     /* MSA ASE, same as MDMX */
146     OPC_MSA      = OPC_MDMX,
147     /* Cache and prefetch */
148     OPC_CACHE    = (0x2F << 26),
149     OPC_PREF     = (0x33 << 26),
150     /* PC-relative address computation / loads */
151     OPC_PCREL    = (0x3B << 26),
152 };
153
154 /* PC-relative address computation / loads  */
155 #define MASK_OPC_PCREL_TOP2BITS(op)  (MASK_OP_MAJOR(op) | (op & (3 << 19)))
156 #define MASK_OPC_PCREL_TOP5BITS(op)  (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
157 enum {
158     /* Instructions determined by bits 19 and 20 */
159     OPC_ADDIUPC = OPC_PCREL | (0 << 19),
160     R6_OPC_LWPC = OPC_PCREL | (1 << 19),
161     OPC_LWUPC   = OPC_PCREL | (2 << 19),
162
163     /* Instructions determined by bits 16 ... 20 */
164     OPC_AUIPC   = OPC_PCREL | (0x1e << 16),
165     OPC_ALUIPC  = OPC_PCREL | (0x1f << 16),
166
167     /* Other */
168     R6_OPC_LDPC = OPC_PCREL | (6 << 18),
169 };
170
171 /* MIPS special opcodes */
172 #define MASK_SPECIAL(op)   MASK_OP_MAJOR(op) | (op & 0x3F)
173
174 enum {
175     /* Shifts */
176     OPC_SLL      = 0x00 | OPC_SPECIAL,
177     /* NOP is SLL r0, r0, 0   */
178     /* SSNOP is SLL r0, r0, 1 */
179     /* EHB is SLL r0, r0, 3 */
180     OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
181     OPC_ROTR     = OPC_SRL | (1 << 21),
182     OPC_SRA      = 0x03 | OPC_SPECIAL,
183     OPC_SLLV     = 0x04 | OPC_SPECIAL,
184     OPC_SRLV     = 0x06 | OPC_SPECIAL, /* also ROTRV */
185     OPC_ROTRV    = OPC_SRLV | (1 << 6),
186     OPC_SRAV     = 0x07 | OPC_SPECIAL,
187     OPC_DSLLV    = 0x14 | OPC_SPECIAL,
188     OPC_DSRLV    = 0x16 | OPC_SPECIAL, /* also DROTRV */
189     OPC_DROTRV   = OPC_DSRLV | (1 << 6),
190     OPC_DSRAV    = 0x17 | OPC_SPECIAL,
191     OPC_DSLL     = 0x38 | OPC_SPECIAL,
192     OPC_DSRL     = 0x3A | OPC_SPECIAL, /* also DROTR */
193     OPC_DROTR    = OPC_DSRL | (1 << 21),
194     OPC_DSRA     = 0x3B | OPC_SPECIAL,
195     OPC_DSLL32   = 0x3C | OPC_SPECIAL,
196     OPC_DSRL32   = 0x3E | OPC_SPECIAL, /* also DROTR32 */
197     OPC_DROTR32  = OPC_DSRL32 | (1 << 21),
198     OPC_DSRA32   = 0x3F | OPC_SPECIAL,
199     /* Multiplication / division */
200     OPC_MULT     = 0x18 | OPC_SPECIAL,
201     OPC_MULTU    = 0x19 | OPC_SPECIAL,
202     OPC_DIV      = 0x1A | OPC_SPECIAL,
203     OPC_DIVU     = 0x1B | OPC_SPECIAL,
204     OPC_DMULT    = 0x1C | OPC_SPECIAL,
205     OPC_DMULTU   = 0x1D | OPC_SPECIAL,
206     OPC_DDIV     = 0x1E | OPC_SPECIAL,
207     OPC_DDIVU    = 0x1F | OPC_SPECIAL,
208
209     /* 2 registers arithmetic / logic */
210     OPC_ADD      = 0x20 | OPC_SPECIAL,
211     OPC_ADDU     = 0x21 | OPC_SPECIAL,
212     OPC_SUB      = 0x22 | OPC_SPECIAL,
213     OPC_SUBU     = 0x23 | OPC_SPECIAL,
214     OPC_AND      = 0x24 | OPC_SPECIAL,
215     OPC_OR       = 0x25 | OPC_SPECIAL,
216     OPC_XOR      = 0x26 | OPC_SPECIAL,
217     OPC_NOR      = 0x27 | OPC_SPECIAL,
218     OPC_SLT      = 0x2A | OPC_SPECIAL,
219     OPC_SLTU     = 0x2B | OPC_SPECIAL,
220     OPC_DADD     = 0x2C | OPC_SPECIAL,
221     OPC_DADDU    = 0x2D | OPC_SPECIAL,
222     OPC_DSUB     = 0x2E | OPC_SPECIAL,
223     OPC_DSUBU    = 0x2F | OPC_SPECIAL,
224     /* Jumps */
225     OPC_JR       = 0x08 | OPC_SPECIAL, /* Also JR.HB */
226     OPC_JALR     = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
227     /* Traps */
228     OPC_TGE      = 0x30 | OPC_SPECIAL,
229     OPC_TGEU     = 0x31 | OPC_SPECIAL,
230     OPC_TLT      = 0x32 | OPC_SPECIAL,
231     OPC_TLTU     = 0x33 | OPC_SPECIAL,
232     OPC_TEQ      = 0x34 | OPC_SPECIAL,
233     OPC_TNE      = 0x36 | OPC_SPECIAL,
234     /* HI / LO registers load & stores */
235     OPC_MFHI     = 0x10 | OPC_SPECIAL,
236     OPC_MTHI     = 0x11 | OPC_SPECIAL,
237     OPC_MFLO     = 0x12 | OPC_SPECIAL,
238     OPC_MTLO     = 0x13 | OPC_SPECIAL,
239     /* Conditional moves */
240     OPC_MOVZ     = 0x0A | OPC_SPECIAL,
241     OPC_MOVN     = 0x0B | OPC_SPECIAL,
242
243     OPC_SELEQZ   = 0x35 | OPC_SPECIAL,
244     OPC_SELNEZ   = 0x37 | OPC_SPECIAL,
245
246     OPC_MOVCI    = 0x01 | OPC_SPECIAL,
247
248     /* Special */
249     OPC_PMON     = 0x05 | OPC_SPECIAL, /* unofficial */
250     OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
251     OPC_BREAK    = 0x0D | OPC_SPECIAL,
252     OPC_SPIM     = 0x0E | OPC_SPECIAL, /* unofficial */
253     OPC_SYNC     = 0x0F | OPC_SPECIAL,
254
255     OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
256     OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
257     OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
258     OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
259 };
260
261 /* R6 Multiply and Divide instructions have the same Opcode
262    and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
263 #define MASK_R6_MULDIV(op)   (MASK_SPECIAL(op) | (op & (0x7ff)))
264
265 enum {
266     R6_OPC_MUL   = OPC_MULT  | (2 << 6),
267     R6_OPC_MUH   = OPC_MULT  | (3 << 6),
268     R6_OPC_MULU  = OPC_MULTU | (2 << 6),
269     R6_OPC_MUHU  = OPC_MULTU | (3 << 6),
270     R6_OPC_DIV   = OPC_DIV   | (2 << 6),
271     R6_OPC_MOD   = OPC_DIV   | (3 << 6),
272     R6_OPC_DIVU  = OPC_DIVU  | (2 << 6),
273     R6_OPC_MODU  = OPC_DIVU  | (3 << 6),
274
275     R6_OPC_DMUL   = OPC_DMULT  | (2 << 6),
276     R6_OPC_DMUH   = OPC_DMULT  | (3 << 6),
277     R6_OPC_DMULU  = OPC_DMULTU | (2 << 6),
278     R6_OPC_DMUHU  = OPC_DMULTU | (3 << 6),
279     R6_OPC_DDIV   = OPC_DDIV   | (2 << 6),
280     R6_OPC_DMOD   = OPC_DDIV   | (3 << 6),
281     R6_OPC_DDIVU  = OPC_DDIVU  | (2 << 6),
282     R6_OPC_DMODU  = OPC_DDIVU  | (3 << 6),
283
284     R6_OPC_CLZ      = 0x10 | OPC_SPECIAL,
285     R6_OPC_CLO      = 0x11 | OPC_SPECIAL,
286     R6_OPC_DCLZ     = 0x12 | OPC_SPECIAL,
287     R6_OPC_DCLO     = 0x13 | OPC_SPECIAL,
288     R6_OPC_SDBBP    = 0x0e | OPC_SPECIAL,
289
290     OPC_LSA  = 0x05 | OPC_SPECIAL,
291     OPC_DLSA = 0x15 | OPC_SPECIAL,
292 };
293
294 /* Multiplication variants of the vr54xx. */
295 #define MASK_MUL_VR54XX(op)   MASK_SPECIAL(op) | (op & (0x1F << 6))
296
297 enum {
298     OPC_VR54XX_MULS    = (0x03 << 6) | OPC_MULT,
299     OPC_VR54XX_MULSU   = (0x03 << 6) | OPC_MULTU,
300     OPC_VR54XX_MACC    = (0x05 << 6) | OPC_MULT,
301     OPC_VR54XX_MACCU   = (0x05 << 6) | OPC_MULTU,
302     OPC_VR54XX_MSAC    = (0x07 << 6) | OPC_MULT,
303     OPC_VR54XX_MSACU   = (0x07 << 6) | OPC_MULTU,
304     OPC_VR54XX_MULHI   = (0x09 << 6) | OPC_MULT,
305     OPC_VR54XX_MULHIU  = (0x09 << 6) | OPC_MULTU,
306     OPC_VR54XX_MULSHI  = (0x0B << 6) | OPC_MULT,
307     OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
308     OPC_VR54XX_MACCHI  = (0x0D << 6) | OPC_MULT,
309     OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
310     OPC_VR54XX_MSACHI  = (0x0F << 6) | OPC_MULT,
311     OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
312 };
313
314 /* REGIMM (rt field) opcodes */
315 #define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
316
317 enum {
318     OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
319     OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
320     OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
321     OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
322     OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
323     OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
324     OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
325     OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
326     OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
327     OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
328     OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
329     OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
330     OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
331     OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
332     OPC_SIGRIE   = (0x17 << 16) | OPC_REGIMM,
333     OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
334
335     OPC_DAHI     = (0x06 << 16) | OPC_REGIMM,
336     OPC_DATI     = (0x1e << 16) | OPC_REGIMM,
337 };
338
339 /* Special2 opcodes */
340 #define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
341
342 enum {
343     /* Multiply & xxx operations */
344     OPC_MADD     = 0x00 | OPC_SPECIAL2,
345     OPC_MADDU    = 0x01 | OPC_SPECIAL2,
346     OPC_MUL      = 0x02 | OPC_SPECIAL2,
347     OPC_MSUB     = 0x04 | OPC_SPECIAL2,
348     OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
349     /* Loongson 2F */
350     OPC_MULT_G_2F   = 0x10 | OPC_SPECIAL2,
351     OPC_DMULT_G_2F  = 0x11 | OPC_SPECIAL2,
352     OPC_MULTU_G_2F  = 0x12 | OPC_SPECIAL2,
353     OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
354     OPC_DIV_G_2F    = 0x14 | OPC_SPECIAL2,
355     OPC_DDIV_G_2F   = 0x15 | OPC_SPECIAL2,
356     OPC_DIVU_G_2F   = 0x16 | OPC_SPECIAL2,
357     OPC_DDIVU_G_2F  = 0x17 | OPC_SPECIAL2,
358     OPC_MOD_G_2F    = 0x1c | OPC_SPECIAL2,
359     OPC_DMOD_G_2F   = 0x1d | OPC_SPECIAL2,
360     OPC_MODU_G_2F   = 0x1e | OPC_SPECIAL2,
361     OPC_DMODU_G_2F  = 0x1f | OPC_SPECIAL2,
362     /* Misc */
363     OPC_CLZ      = 0x20 | OPC_SPECIAL2,
364     OPC_CLO      = 0x21 | OPC_SPECIAL2,
365     OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
366     OPC_DCLO     = 0x25 | OPC_SPECIAL2,
367     /* Special */
368     OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
369 };
370
371 /* Special3 opcodes */
372 #define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
373
374 enum {
375     OPC_EXT      = 0x00 | OPC_SPECIAL3,
376     OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
377     OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
378     OPC_DEXT     = 0x03 | OPC_SPECIAL3,
379     OPC_INS      = 0x04 | OPC_SPECIAL3,
380     OPC_DINSM    = 0x05 | OPC_SPECIAL3,
381     OPC_DINSU    = 0x06 | OPC_SPECIAL3,
382     OPC_DINS     = 0x07 | OPC_SPECIAL3,
383     OPC_FORK     = 0x08 | OPC_SPECIAL3,
384     OPC_YIELD    = 0x09 | OPC_SPECIAL3,
385     OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
386     OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
387     OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
388
389     /* Loongson 2E */
390     OPC_MULT_G_2E   = 0x18 | OPC_SPECIAL3,
391     OPC_MULTU_G_2E  = 0x19 | OPC_SPECIAL3,
392     OPC_DIV_G_2E    = 0x1A | OPC_SPECIAL3,
393     OPC_DIVU_G_2E   = 0x1B | OPC_SPECIAL3,
394     OPC_DMULT_G_2E  = 0x1C | OPC_SPECIAL3,
395     OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
396     OPC_DDIV_G_2E   = 0x1E | OPC_SPECIAL3,
397     OPC_DDIVU_G_2E  = 0x1F | OPC_SPECIAL3,
398     OPC_MOD_G_2E    = 0x22 | OPC_SPECIAL3,
399     OPC_MODU_G_2E   = 0x23 | OPC_SPECIAL3,
400     OPC_DMOD_G_2E   = 0x26 | OPC_SPECIAL3,
401     OPC_DMODU_G_2E  = 0x27 | OPC_SPECIAL3,
402
403     /* MIPS DSP Load */
404     OPC_LX_DSP         = 0x0A | OPC_SPECIAL3,
405     /* MIPS DSP Arithmetic */
406     OPC_ADDU_QB_DSP    = 0x10 | OPC_SPECIAL3,
407     OPC_ADDU_OB_DSP    = 0x14 | OPC_SPECIAL3,
408     OPC_ABSQ_S_PH_DSP  = 0x12 | OPC_SPECIAL3,
409     OPC_ABSQ_S_QH_DSP  = 0x16 | OPC_SPECIAL3,
410     /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E.  */
411     /* OPC_ADDUH_QB_DSP   = 0x18 | OPC_SPECIAL3,  */
412     OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
413     OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
414     /* MIPS DSP GPR-Based Shift Sub-class */
415     OPC_SHLL_QB_DSP    = 0x13 | OPC_SPECIAL3,
416     OPC_SHLL_OB_DSP    = 0x17 | OPC_SPECIAL3,
417     /* MIPS DSP Multiply Sub-class insns */
418     /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP.  */
419     /* OPC_MUL_PH_DSP     = 0x18 | OPC_SPECIAL3,  */
420     OPC_DPA_W_PH_DSP   = 0x30 | OPC_SPECIAL3,
421     OPC_DPAQ_W_QH_DSP  = 0x34 | OPC_SPECIAL3,
422     /* DSP Bit/Manipulation Sub-class */
423     OPC_INSV_DSP       = 0x0C | OPC_SPECIAL3,
424     OPC_DINSV_DSP      = 0x0D | OPC_SPECIAL3,
425     /* MIPS DSP Append Sub-class */
426     OPC_APPEND_DSP     = 0x31 | OPC_SPECIAL3,
427     OPC_DAPPEND_DSP    = 0x35 | OPC_SPECIAL3,
428     /* MIPS DSP Accumulator and DSPControl Access Sub-class */
429     OPC_EXTR_W_DSP     = 0x38 | OPC_SPECIAL3,
430     OPC_DEXTR_W_DSP    = 0x3C | OPC_SPECIAL3,
431
432     /* EVA */
433     OPC_LWLE           = 0x19 | OPC_SPECIAL3,
434     OPC_LWRE           = 0x1A | OPC_SPECIAL3,
435     OPC_CACHEE         = 0x1B | OPC_SPECIAL3,
436     OPC_SBE            = 0x1C | OPC_SPECIAL3,
437     OPC_SHE            = 0x1D | OPC_SPECIAL3,
438     OPC_SCE            = 0x1E | OPC_SPECIAL3,
439     OPC_SWE            = 0x1F | OPC_SPECIAL3,
440     OPC_SWLE           = 0x21 | OPC_SPECIAL3,
441     OPC_SWRE           = 0x22 | OPC_SPECIAL3,
442     OPC_PREFE          = 0x23 | OPC_SPECIAL3,
443     OPC_LBUE           = 0x28 | OPC_SPECIAL3,
444     OPC_LHUE           = 0x29 | OPC_SPECIAL3,
445     OPC_LBE            = 0x2C | OPC_SPECIAL3,
446     OPC_LHE            = 0x2D | OPC_SPECIAL3,
447     OPC_LLE            = 0x2E | OPC_SPECIAL3,
448     OPC_LWE            = 0x2F | OPC_SPECIAL3,
449
450     /* R6 */
451     R6_OPC_PREF        = 0x35 | OPC_SPECIAL3,
452     R6_OPC_CACHE       = 0x25 | OPC_SPECIAL3,
453     R6_OPC_LL          = 0x36 | OPC_SPECIAL3,
454     R6_OPC_SC          = 0x26 | OPC_SPECIAL3,
455     R6_OPC_LLD         = 0x37 | OPC_SPECIAL3,
456     R6_OPC_SCD         = 0x27 | OPC_SPECIAL3,
457 };
458
459 /* BSHFL opcodes */
460 #define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
461
462 enum {
463     OPC_WSBH      = (0x02 << 6) | OPC_BSHFL,
464     OPC_SEB       = (0x10 << 6) | OPC_BSHFL,
465     OPC_SEH       = (0x18 << 6) | OPC_BSHFL,
466     OPC_ALIGN     = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */
467     OPC_ALIGN_1   = (0x09 << 6) | OPC_BSHFL,
468     OPC_ALIGN_2   = (0x0A << 6) | OPC_BSHFL,
469     OPC_ALIGN_3   = (0x0B << 6) | OPC_BSHFL,
470     OPC_BITSWAP   = (0x00 << 6) | OPC_BSHFL  /* 00000 */
471 };
472
473 /* DBSHFL opcodes */
474 #define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
475
476 enum {
477     OPC_DSBH       = (0x02 << 6) | OPC_DBSHFL,
478     OPC_DSHD       = (0x05 << 6) | OPC_DBSHFL,
479     OPC_DALIGN     = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */
480     OPC_DALIGN_1   = (0x09 << 6) | OPC_DBSHFL,
481     OPC_DALIGN_2   = (0x0A << 6) | OPC_DBSHFL,
482     OPC_DALIGN_3   = (0x0B << 6) | OPC_DBSHFL,
483     OPC_DALIGN_4   = (0x0C << 6) | OPC_DBSHFL,
484     OPC_DALIGN_5   = (0x0D << 6) | OPC_DBSHFL,
485     OPC_DALIGN_6   = (0x0E << 6) | OPC_DBSHFL,
486     OPC_DALIGN_7   = (0x0F << 6) | OPC_DBSHFL,
487     OPC_DBITSWAP   = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
488 };
489
490 /* MIPS DSP REGIMM opcodes */
491 enum {
492     OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
493     OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
494 };
495
496 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
497 /* MIPS DSP Load */
498 enum {
499     OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
500     OPC_LHX  = (0x04 << 6) | OPC_LX_DSP,
501     OPC_LWX  = (0x00 << 6) | OPC_LX_DSP,
502     OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
503 };
504
505 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
506 enum {
507     /* MIPS DSP Arithmetic Sub-class */
508     OPC_ADDQ_PH        = (0x0A << 6) | OPC_ADDU_QB_DSP,
509     OPC_ADDQ_S_PH      = (0x0E << 6) | OPC_ADDU_QB_DSP,
510     OPC_ADDQ_S_W       = (0x16 << 6) | OPC_ADDU_QB_DSP,
511     OPC_ADDU_QB        = (0x00 << 6) | OPC_ADDU_QB_DSP,
512     OPC_ADDU_S_QB      = (0x04 << 6) | OPC_ADDU_QB_DSP,
513     OPC_ADDU_PH        = (0x08 << 6) | OPC_ADDU_QB_DSP,
514     OPC_ADDU_S_PH      = (0x0C << 6) | OPC_ADDU_QB_DSP,
515     OPC_SUBQ_PH        = (0x0B << 6) | OPC_ADDU_QB_DSP,
516     OPC_SUBQ_S_PH      = (0x0F << 6) | OPC_ADDU_QB_DSP,
517     OPC_SUBQ_S_W       = (0x17 << 6) | OPC_ADDU_QB_DSP,
518     OPC_SUBU_QB        = (0x01 << 6) | OPC_ADDU_QB_DSP,
519     OPC_SUBU_S_QB      = (0x05 << 6) | OPC_ADDU_QB_DSP,
520     OPC_SUBU_PH        = (0x09 << 6) | OPC_ADDU_QB_DSP,
521     OPC_SUBU_S_PH      = (0x0D << 6) | OPC_ADDU_QB_DSP,
522     OPC_ADDSC          = (0x10 << 6) | OPC_ADDU_QB_DSP,
523     OPC_ADDWC          = (0x11 << 6) | OPC_ADDU_QB_DSP,
524     OPC_MODSUB         = (0x12 << 6) | OPC_ADDU_QB_DSP,
525     OPC_RADDU_W_QB     = (0x14 << 6) | OPC_ADDU_QB_DSP,
526     /* MIPS DSP Multiply Sub-class insns */
527     OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
528     OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
529     OPC_MULQ_RS_PH     = (0x1F << 6) | OPC_ADDU_QB_DSP,
530     OPC_MULEQ_S_W_PHL  = (0x1C << 6) | OPC_ADDU_QB_DSP,
531     OPC_MULEQ_S_W_PHR  = (0x1D << 6) | OPC_ADDU_QB_DSP,
532     OPC_MULQ_S_PH      = (0x1E << 6) | OPC_ADDU_QB_DSP,
533 };
534
535 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
536 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
537 enum {
538     /* MIPS DSP Arithmetic Sub-class */
539     OPC_ADDUH_QB   = (0x00 << 6) | OPC_ADDUH_QB_DSP,
540     OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
541     OPC_ADDQH_PH   = (0x08 << 6) | OPC_ADDUH_QB_DSP,
542     OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
543     OPC_ADDQH_W    = (0x10 << 6) | OPC_ADDUH_QB_DSP,
544     OPC_ADDQH_R_W  = (0x12 << 6) | OPC_ADDUH_QB_DSP,
545     OPC_SUBUH_QB   = (0x01 << 6) | OPC_ADDUH_QB_DSP,
546     OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
547     OPC_SUBQH_PH   = (0x09 << 6) | OPC_ADDUH_QB_DSP,
548     OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
549     OPC_SUBQH_W    = (0x11 << 6) | OPC_ADDUH_QB_DSP,
550     OPC_SUBQH_R_W  = (0x13 << 6) | OPC_ADDUH_QB_DSP,
551     /* MIPS DSP Multiply Sub-class insns */
552     OPC_MUL_PH     = (0x0C << 6) | OPC_ADDUH_QB_DSP,
553     OPC_MUL_S_PH   = (0x0E << 6) | OPC_ADDUH_QB_DSP,
554     OPC_MULQ_S_W   = (0x16 << 6) | OPC_ADDUH_QB_DSP,
555     OPC_MULQ_RS_W  = (0x17 << 6) | OPC_ADDUH_QB_DSP,
556 };
557
558 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
559 enum {
560     /* MIPS DSP Arithmetic Sub-class */
561     OPC_ABSQ_S_QB       = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
562     OPC_ABSQ_S_PH       = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
563     OPC_ABSQ_S_W        = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
564     OPC_PRECEQ_W_PHL    = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
565     OPC_PRECEQ_W_PHR    = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
566     OPC_PRECEQU_PH_QBL  = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
567     OPC_PRECEQU_PH_QBR  = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
568     OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
569     OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
570     OPC_PRECEU_PH_QBL   = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
571     OPC_PRECEU_PH_QBR   = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
572     OPC_PRECEU_PH_QBLA  = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
573     OPC_PRECEU_PH_QBRA  = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
574     /* DSP Bit/Manipulation Sub-class */
575     OPC_BITREV          = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
576     OPC_REPL_QB         = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
577     OPC_REPLV_QB        = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
578     OPC_REPL_PH         = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
579     OPC_REPLV_PH        = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
580 };
581
582 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
583 enum {
584     /* MIPS DSP Arithmetic Sub-class */
585     OPC_PRECR_QB_PH      = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
586     OPC_PRECRQ_QB_PH     = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
587     OPC_PRECR_SRA_PH_W   = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
588     OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
589     OPC_PRECRQ_PH_W      = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
590     OPC_PRECRQ_RS_PH_W   = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
591     OPC_PRECRQU_S_QB_PH  = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
592     /* DSP Compare-Pick Sub-class */
593     OPC_CMPU_EQ_QB       = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
594     OPC_CMPU_LT_QB       = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
595     OPC_CMPU_LE_QB       = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
596     OPC_CMPGU_EQ_QB      = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
597     OPC_CMPGU_LT_QB      = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
598     OPC_CMPGU_LE_QB      = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
599     OPC_CMPGDU_EQ_QB     = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
600     OPC_CMPGDU_LT_QB     = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
601     OPC_CMPGDU_LE_QB     = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
602     OPC_CMP_EQ_PH        = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
603     OPC_CMP_LT_PH        = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
604     OPC_CMP_LE_PH        = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
605     OPC_PICK_QB          = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
606     OPC_PICK_PH          = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
607     OPC_PACKRL_PH        = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
608 };
609
610 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
611 enum {
612     /* MIPS DSP GPR-Based Shift Sub-class */
613     OPC_SHLL_QB    = (0x00 << 6) | OPC_SHLL_QB_DSP,
614     OPC_SHLLV_QB   = (0x02 << 6) | OPC_SHLL_QB_DSP,
615     OPC_SHLL_PH    = (0x08 << 6) | OPC_SHLL_QB_DSP,
616     OPC_SHLLV_PH   = (0x0A << 6) | OPC_SHLL_QB_DSP,
617     OPC_SHLL_S_PH  = (0x0C << 6) | OPC_SHLL_QB_DSP,
618     OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
619     OPC_SHLL_S_W   = (0x14 << 6) | OPC_SHLL_QB_DSP,
620     OPC_SHLLV_S_W  = (0x16 << 6) | OPC_SHLL_QB_DSP,
621     OPC_SHRL_QB    = (0x01 << 6) | OPC_SHLL_QB_DSP,
622     OPC_SHRLV_QB   = (0x03 << 6) | OPC_SHLL_QB_DSP,
623     OPC_SHRL_PH    = (0x19 << 6) | OPC_SHLL_QB_DSP,
624     OPC_SHRLV_PH   = (0x1B << 6) | OPC_SHLL_QB_DSP,
625     OPC_SHRA_QB    = (0x04 << 6) | OPC_SHLL_QB_DSP,
626     OPC_SHRA_R_QB  = (0x05 << 6) | OPC_SHLL_QB_DSP,
627     OPC_SHRAV_QB   = (0x06 << 6) | OPC_SHLL_QB_DSP,
628     OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
629     OPC_SHRA_PH    = (0x09 << 6) | OPC_SHLL_QB_DSP,
630     OPC_SHRAV_PH   = (0x0B << 6) | OPC_SHLL_QB_DSP,
631     OPC_SHRA_R_PH  = (0x0D << 6) | OPC_SHLL_QB_DSP,
632     OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
633     OPC_SHRA_R_W   = (0x15 << 6) | OPC_SHLL_QB_DSP,
634     OPC_SHRAV_R_W  = (0x17 << 6) | OPC_SHLL_QB_DSP,
635 };
636
637 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
638 enum {
639     /* MIPS DSP Multiply Sub-class insns */
640     OPC_DPAU_H_QBL    = (0x03 << 6) | OPC_DPA_W_PH_DSP,
641     OPC_DPAU_H_QBR    = (0x07 << 6) | OPC_DPA_W_PH_DSP,
642     OPC_DPSU_H_QBL    = (0x0B << 6) | OPC_DPA_W_PH_DSP,
643     OPC_DPSU_H_QBR    = (0x0F << 6) | OPC_DPA_W_PH_DSP,
644     OPC_DPA_W_PH      = (0x00 << 6) | OPC_DPA_W_PH_DSP,
645     OPC_DPAX_W_PH     = (0x08 << 6) | OPC_DPA_W_PH_DSP,
646     OPC_DPAQ_S_W_PH   = (0x04 << 6) | OPC_DPA_W_PH_DSP,
647     OPC_DPAQX_S_W_PH  = (0x18 << 6) | OPC_DPA_W_PH_DSP,
648     OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
649     OPC_DPS_W_PH      = (0x01 << 6) | OPC_DPA_W_PH_DSP,
650     OPC_DPSX_W_PH     = (0x09 << 6) | OPC_DPA_W_PH_DSP,
651     OPC_DPSQ_S_W_PH   = (0x05 << 6) | OPC_DPA_W_PH_DSP,
652     OPC_DPSQX_S_W_PH  = (0x19 << 6) | OPC_DPA_W_PH_DSP,
653     OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
654     OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
655     OPC_DPAQ_SA_L_W   = (0x0C << 6) | OPC_DPA_W_PH_DSP,
656     OPC_DPSQ_SA_L_W   = (0x0D << 6) | OPC_DPA_W_PH_DSP,
657     OPC_MAQ_S_W_PHL   = (0x14 << 6) | OPC_DPA_W_PH_DSP,
658     OPC_MAQ_S_W_PHR   = (0x16 << 6) | OPC_DPA_W_PH_DSP,
659     OPC_MAQ_SA_W_PHL  = (0x10 << 6) | OPC_DPA_W_PH_DSP,
660     OPC_MAQ_SA_W_PHR  = (0x12 << 6) | OPC_DPA_W_PH_DSP,
661     OPC_MULSA_W_PH    = (0x02 << 6) | OPC_DPA_W_PH_DSP,
662 };
663
664 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
665 enum {
666     /* DSP Bit/Manipulation Sub-class */
667     OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
668 };
669
670 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
671 enum {
672     /* MIPS DSP Append Sub-class */
673     OPC_APPEND  = (0x00 << 6) | OPC_APPEND_DSP,
674     OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
675     OPC_BALIGN  = (0x10 << 6) | OPC_APPEND_DSP,
676 };
677
678 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
679 enum {
680     /* MIPS DSP Accumulator and DSPControl Access Sub-class */
681     OPC_EXTR_W     = (0x00 << 6) | OPC_EXTR_W_DSP,
682     OPC_EXTR_R_W   = (0x04 << 6) | OPC_EXTR_W_DSP,
683     OPC_EXTR_RS_W  = (0x06 << 6) | OPC_EXTR_W_DSP,
684     OPC_EXTR_S_H   = (0x0E << 6) | OPC_EXTR_W_DSP,
685     OPC_EXTRV_S_H  = (0x0F << 6) | OPC_EXTR_W_DSP,
686     OPC_EXTRV_W    = (0x01 << 6) | OPC_EXTR_W_DSP,
687     OPC_EXTRV_R_W  = (0x05 << 6) | OPC_EXTR_W_DSP,
688     OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
689     OPC_EXTP       = (0x02 << 6) | OPC_EXTR_W_DSP,
690     OPC_EXTPV      = (0x03 << 6) | OPC_EXTR_W_DSP,
691     OPC_EXTPDP     = (0x0A << 6) | OPC_EXTR_W_DSP,
692     OPC_EXTPDPV    = (0x0B << 6) | OPC_EXTR_W_DSP,
693     OPC_SHILO      = (0x1A << 6) | OPC_EXTR_W_DSP,
694     OPC_SHILOV     = (0x1B << 6) | OPC_EXTR_W_DSP,
695     OPC_MTHLIP     = (0x1F << 6) | OPC_EXTR_W_DSP,
696     OPC_WRDSP      = (0x13 << 6) | OPC_EXTR_W_DSP,
697     OPC_RDDSP      = (0x12 << 6) | OPC_EXTR_W_DSP,
698 };
699
700 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
701 enum {
702     /* MIPS DSP Arithmetic Sub-class */
703     OPC_PRECEQ_L_PWL    = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
704     OPC_PRECEQ_L_PWR    = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
705     OPC_PRECEQ_PW_QHL   = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
706     OPC_PRECEQ_PW_QHR   = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
707     OPC_PRECEQ_PW_QHLA  = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
708     OPC_PRECEQ_PW_QHRA  = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
709     OPC_PRECEQU_QH_OBL  = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
710     OPC_PRECEQU_QH_OBR  = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
711     OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
712     OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
713     OPC_PRECEU_QH_OBL   = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
714     OPC_PRECEU_QH_OBR   = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
715     OPC_PRECEU_QH_OBLA  = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
716     OPC_PRECEU_QH_OBRA  = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
717     OPC_ABSQ_S_OB       = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
718     OPC_ABSQ_S_PW       = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
719     OPC_ABSQ_S_QH       = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
720     /* DSP Bit/Manipulation Sub-class */
721     OPC_REPL_OB         = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
722     OPC_REPL_PW         = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
723     OPC_REPL_QH         = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
724     OPC_REPLV_OB        = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
725     OPC_REPLV_PW        = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
726     OPC_REPLV_QH        = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
727 };
728
729 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
730 enum {
731     /* MIPS DSP Multiply Sub-class insns */
732     OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
733     OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
734     OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
735     OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
736     OPC_MULQ_RS_QH     = (0x1F << 6) | OPC_ADDU_OB_DSP,
737     /* MIPS DSP Arithmetic Sub-class */
738     OPC_RADDU_L_OB     = (0x14 << 6) | OPC_ADDU_OB_DSP,
739     OPC_SUBQ_PW        = (0x13 << 6) | OPC_ADDU_OB_DSP,
740     OPC_SUBQ_S_PW      = (0x17 << 6) | OPC_ADDU_OB_DSP,
741     OPC_SUBQ_QH        = (0x0B << 6) | OPC_ADDU_OB_DSP,
742     OPC_SUBQ_S_QH      = (0x0F << 6) | OPC_ADDU_OB_DSP,
743     OPC_SUBU_OB        = (0x01 << 6) | OPC_ADDU_OB_DSP,
744     OPC_SUBU_S_OB      = (0x05 << 6) | OPC_ADDU_OB_DSP,
745     OPC_SUBU_QH        = (0x09 << 6) | OPC_ADDU_OB_DSP,
746     OPC_SUBU_S_QH      = (0x0D << 6) | OPC_ADDU_OB_DSP,
747     OPC_SUBUH_OB       = (0x19 << 6) | OPC_ADDU_OB_DSP,
748     OPC_SUBUH_R_OB     = (0x1B << 6) | OPC_ADDU_OB_DSP,
749     OPC_ADDQ_PW        = (0x12 << 6) | OPC_ADDU_OB_DSP,
750     OPC_ADDQ_S_PW      = (0x16 << 6) | OPC_ADDU_OB_DSP,
751     OPC_ADDQ_QH        = (0x0A << 6) | OPC_ADDU_OB_DSP,
752     OPC_ADDQ_S_QH      = (0x0E << 6) | OPC_ADDU_OB_DSP,
753     OPC_ADDU_OB        = (0x00 << 6) | OPC_ADDU_OB_DSP,
754     OPC_ADDU_S_OB      = (0x04 << 6) | OPC_ADDU_OB_DSP,
755     OPC_ADDU_QH        = (0x08 << 6) | OPC_ADDU_OB_DSP,
756     OPC_ADDU_S_QH      = (0x0C << 6) | OPC_ADDU_OB_DSP,
757     OPC_ADDUH_OB       = (0x18 << 6) | OPC_ADDU_OB_DSP,
758     OPC_ADDUH_R_OB     = (0x1A << 6) | OPC_ADDU_OB_DSP,
759 };
760
761 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
762 enum {
763     /* DSP Compare-Pick Sub-class */
764     OPC_CMP_EQ_PW         = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
765     OPC_CMP_LT_PW         = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
766     OPC_CMP_LE_PW         = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
767     OPC_CMP_EQ_QH         = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
768     OPC_CMP_LT_QH         = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
769     OPC_CMP_LE_QH         = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
770     OPC_CMPGDU_EQ_OB      = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
771     OPC_CMPGDU_LT_OB      = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
772     OPC_CMPGDU_LE_OB      = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
773     OPC_CMPGU_EQ_OB       = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
774     OPC_CMPGU_LT_OB       = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
775     OPC_CMPGU_LE_OB       = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
776     OPC_CMPU_EQ_OB        = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
777     OPC_CMPU_LT_OB        = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
778     OPC_CMPU_LE_OB        = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
779     OPC_PACKRL_PW         = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
780     OPC_PICK_OB           = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
781     OPC_PICK_PW           = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
782     OPC_PICK_QH           = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
783     /* MIPS DSP Arithmetic Sub-class */
784     OPC_PRECR_OB_QH       = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
785     OPC_PRECR_SRA_QH_PW   = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
786     OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
787     OPC_PRECRQ_OB_QH      = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
788     OPC_PRECRQ_PW_L       = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
789     OPC_PRECRQ_QH_PW      = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
790     OPC_PRECRQ_RS_QH_PW   = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
791     OPC_PRECRQU_S_OB_QH   = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
792 };
793
794 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
795 enum {
796     /* DSP Append Sub-class */
797     OPC_DAPPEND  = (0x00 << 6) | OPC_DAPPEND_DSP,
798     OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
799     OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
800     OPC_DBALIGN  = (0x10 << 6) | OPC_DAPPEND_DSP,
801 };
802
803 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
804 enum {
805     /* MIPS DSP Accumulator and DSPControl Access Sub-class */
806     OPC_DMTHLIP     = (0x1F << 6) | OPC_DEXTR_W_DSP,
807     OPC_DSHILO      = (0x1A << 6) | OPC_DEXTR_W_DSP,
808     OPC_DEXTP       = (0x02 << 6) | OPC_DEXTR_W_DSP,
809     OPC_DEXTPDP     = (0x0A << 6) | OPC_DEXTR_W_DSP,
810     OPC_DEXTPDPV    = (0x0B << 6) | OPC_DEXTR_W_DSP,
811     OPC_DEXTPV      = (0x03 << 6) | OPC_DEXTR_W_DSP,
812     OPC_DEXTR_L     = (0x10 << 6) | OPC_DEXTR_W_DSP,
813     OPC_DEXTR_R_L   = (0x14 << 6) | OPC_DEXTR_W_DSP,
814     OPC_DEXTR_RS_L  = (0x16 << 6) | OPC_DEXTR_W_DSP,
815     OPC_DEXTR_W     = (0x00 << 6) | OPC_DEXTR_W_DSP,
816     OPC_DEXTR_R_W   = (0x04 << 6) | OPC_DEXTR_W_DSP,
817     OPC_DEXTR_RS_W  = (0x06 << 6) | OPC_DEXTR_W_DSP,
818     OPC_DEXTR_S_H   = (0x0E << 6) | OPC_DEXTR_W_DSP,
819     OPC_DEXTRV_L    = (0x11 << 6) | OPC_DEXTR_W_DSP,
820     OPC_DEXTRV_R_L  = (0x15 << 6) | OPC_DEXTR_W_DSP,
821     OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
822     OPC_DEXTRV_S_H  = (0x0F << 6) | OPC_DEXTR_W_DSP,
823     OPC_DEXTRV_W    = (0x01 << 6) | OPC_DEXTR_W_DSP,
824     OPC_DEXTRV_R_W  = (0x05 << 6) | OPC_DEXTR_W_DSP,
825     OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
826     OPC_DSHILOV     = (0x1B << 6) | OPC_DEXTR_W_DSP,
827 };
828
829 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
830 enum {
831     /* DSP Bit/Manipulation Sub-class */
832     OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
833 };
834
835 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
836 enum {
837     /* MIPS DSP Multiply Sub-class insns */
838     OPC_DMADD         = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
839     OPC_DMADDU        = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
840     OPC_DMSUB         = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
841     OPC_DMSUBU        = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
842     OPC_DPA_W_QH      = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
843     OPC_DPAQ_S_W_QH   = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
844     OPC_DPAQ_SA_L_PW  = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
845     OPC_DPAU_H_OBL    = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
846     OPC_DPAU_H_OBR    = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
847     OPC_DPS_W_QH      = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
848     OPC_DPSQ_S_W_QH   = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
849     OPC_DPSQ_SA_L_PW  = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
850     OPC_DPSU_H_OBL    = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
851     OPC_DPSU_H_OBR    = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
852     OPC_MAQ_S_L_PWL   = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
853     OPC_MAQ_S_L_PWR   = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
854     OPC_MAQ_S_W_QHLL  = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
855     OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
856     OPC_MAQ_S_W_QHLR  = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
857     OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
858     OPC_MAQ_S_W_QHRL  = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
859     OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
860     OPC_MAQ_S_W_QHRR  = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
861     OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
862     OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
863     OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
864 };
865
866 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
867 enum {
868     /* MIPS DSP GPR-Based Shift Sub-class */
869     OPC_SHLL_PW    = (0x10 << 6) | OPC_SHLL_OB_DSP,
870     OPC_SHLL_S_PW  = (0x14 << 6) | OPC_SHLL_OB_DSP,
871     OPC_SHLLV_OB   = (0x02 << 6) | OPC_SHLL_OB_DSP,
872     OPC_SHLLV_PW   = (0x12 << 6) | OPC_SHLL_OB_DSP,
873     OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
874     OPC_SHLLV_QH   = (0x0A << 6) | OPC_SHLL_OB_DSP,
875     OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
876     OPC_SHRA_PW    = (0x11 << 6) | OPC_SHLL_OB_DSP,
877     OPC_SHRA_R_PW  = (0x15 << 6) | OPC_SHLL_OB_DSP,
878     OPC_SHRAV_OB   = (0x06 << 6) | OPC_SHLL_OB_DSP,
879     OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
880     OPC_SHRAV_PW   = (0x13 << 6) | OPC_SHLL_OB_DSP,
881     OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
882     OPC_SHRAV_QH   = (0x0B << 6) | OPC_SHLL_OB_DSP,
883     OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
884     OPC_SHRLV_OB   = (0x03 << 6) | OPC_SHLL_OB_DSP,
885     OPC_SHRLV_QH   = (0x1B << 6) | OPC_SHLL_OB_DSP,
886     OPC_SHLL_OB    = (0x00 << 6) | OPC_SHLL_OB_DSP,
887     OPC_SHLL_QH    = (0x08 << 6) | OPC_SHLL_OB_DSP,
888     OPC_SHLL_S_QH  = (0x0C << 6) | OPC_SHLL_OB_DSP,
889     OPC_SHRA_OB    = (0x04 << 6) | OPC_SHLL_OB_DSP,
890     OPC_SHRA_R_OB  = (0x05 << 6) | OPC_SHLL_OB_DSP,
891     OPC_SHRA_QH    = (0x09 << 6) | OPC_SHLL_OB_DSP,
892     OPC_SHRA_R_QH  = (0x0D << 6) | OPC_SHLL_OB_DSP,
893     OPC_SHRL_OB    = (0x01 << 6) | OPC_SHLL_OB_DSP,
894     OPC_SHRL_QH    = (0x19 << 6) | OPC_SHLL_OB_DSP,
895 };
896
897 /* Coprocessor 0 (rs field) */
898 #define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
899
900 enum {
901     OPC_MFC0     = (0x00 << 21) | OPC_CP0,
902     OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
903     OPC_MFHC0    = (0x02 << 21) | OPC_CP0,
904     OPC_MTC0     = (0x04 << 21) | OPC_CP0,
905     OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
906     OPC_MTHC0    = (0x06 << 21) | OPC_CP0,
907     OPC_MFTR     = (0x08 << 21) | OPC_CP0,
908     OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
909     OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
910     OPC_MTTR     = (0x0C << 21) | OPC_CP0,
911     OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
912     OPC_C0       = (0x10 << 21) | OPC_CP0,
913     OPC_C0_1     = (0x11 << 21) | OPC_CP0,
914     OPC_C0_2     = (0x12 << 21) | OPC_CP0,
915     OPC_C0_3     = (0x13 << 21) | OPC_CP0,
916     OPC_C0_4     = (0x14 << 21) | OPC_CP0,
917     OPC_C0_5     = (0x15 << 21) | OPC_CP0,
918     OPC_C0_6     = (0x16 << 21) | OPC_CP0,
919     OPC_C0_7     = (0x17 << 21) | OPC_CP0,
920     OPC_C0_8     = (0x18 << 21) | OPC_CP0,
921     OPC_C0_9     = (0x19 << 21) | OPC_CP0,
922     OPC_C0_A     = (0x1A << 21) | OPC_CP0,
923     OPC_C0_B     = (0x1B << 21) | OPC_CP0,
924     OPC_C0_C     = (0x1C << 21) | OPC_CP0,
925     OPC_C0_D     = (0x1D << 21) | OPC_CP0,
926     OPC_C0_E     = (0x1E << 21) | OPC_CP0,
927     OPC_C0_F     = (0x1F << 21) | OPC_CP0,
928 };
929
930 /* MFMC0 opcodes */
931 #define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
932
933 enum {
934     OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
935     OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
936     OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
937     OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
938     OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
939     OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
940     OPC_DVP      = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
941     OPC_EVP      = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
942 };
943
944 /* Coprocessor 0 (with rs == C0) */
945 #define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
946
947 enum {
948     OPC_TLBR     = 0x01 | OPC_C0,
949     OPC_TLBWI    = 0x02 | OPC_C0,
950     OPC_TLBINV   = 0x03 | OPC_C0,
951     OPC_TLBINVF  = 0x04 | OPC_C0,
952     OPC_TLBWR    = 0x06 | OPC_C0,
953     OPC_TLBP     = 0x08 | OPC_C0,
954     OPC_RFE      = 0x10 | OPC_C0,
955     OPC_ERET     = 0x18 | OPC_C0,
956     OPC_DERET    = 0x1F | OPC_C0,
957     OPC_WAIT     = 0x20 | OPC_C0,
958 };
959
960 /* Coprocessor 1 (rs field) */
961 #define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
962
963 /* Values for the fmt field in FP instructions */
964 enum {
965     /* 0 - 15 are reserved */
966     FMT_S = 16,          /* single fp */
967     FMT_D = 17,          /* double fp */
968     FMT_E = 18,          /* extended fp */
969     FMT_Q = 19,          /* quad fp */
970     FMT_W = 20,          /* 32-bit fixed */
971     FMT_L = 21,          /* 64-bit fixed */
972     FMT_PS = 22,         /* paired single fp */
973     /* 23 - 31 are reserved */
974 };
975
976 enum {
977     OPC_MFC1     = (0x00 << 21) | OPC_CP1,
978     OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
979     OPC_CFC1     = (0x02 << 21) | OPC_CP1,
980     OPC_MFHC1    = (0x03 << 21) | OPC_CP1,
981     OPC_MTC1     = (0x04 << 21) | OPC_CP1,
982     OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
983     OPC_CTC1     = (0x06 << 21) | OPC_CP1,
984     OPC_MTHC1    = (0x07 << 21) | OPC_CP1,
985     OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
986     OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
987     OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
988     OPC_BZ_V     = (0x0B << 21) | OPC_CP1,
989     OPC_BNZ_V    = (0x0F << 21) | OPC_CP1,
990     OPC_S_FMT    = (FMT_S << 21) | OPC_CP1,
991     OPC_D_FMT    = (FMT_D << 21) | OPC_CP1,
992     OPC_E_FMT    = (FMT_E << 21) | OPC_CP1,
993     OPC_Q_FMT    = (FMT_Q << 21) | OPC_CP1,
994     OPC_W_FMT    = (FMT_W << 21) | OPC_CP1,
995     OPC_L_FMT    = (FMT_L << 21) | OPC_CP1,
996     OPC_PS_FMT   = (FMT_PS << 21) | OPC_CP1,
997     OPC_BC1EQZ   = (0x09 << 21) | OPC_CP1,
998     OPC_BC1NEZ   = (0x0D << 21) | OPC_CP1,
999     OPC_BZ_B     = (0x18 << 21) | OPC_CP1,
1000     OPC_BZ_H     = (0x19 << 21) | OPC_CP1,
1001     OPC_BZ_W     = (0x1A << 21) | OPC_CP1,
1002     OPC_BZ_D     = (0x1B << 21) | OPC_CP1,
1003     OPC_BNZ_B    = (0x1C << 21) | OPC_CP1,
1004     OPC_BNZ_H    = (0x1D << 21) | OPC_CP1,
1005     OPC_BNZ_W    = (0x1E << 21) | OPC_CP1,
1006     OPC_BNZ_D    = (0x1F << 21) | OPC_CP1,
1007 };
1008
1009 #define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
1010 #define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
1011
1012 enum {
1013     OPC_BC1F     = (0x00 << 16) | OPC_BC1,
1014     OPC_BC1T     = (0x01 << 16) | OPC_BC1,
1015     OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
1016     OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
1017 };
1018
1019 enum {
1020     OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
1021     OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
1022 };
1023
1024 enum {
1025     OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
1026     OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
1027 };
1028
1029 #define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
1030
1031 enum {
1032     OPC_MFC2    = (0x00 << 21) | OPC_CP2,
1033     OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
1034     OPC_CFC2    = (0x02 << 21) | OPC_CP2,
1035     OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
1036     OPC_MTC2    = (0x04 << 21) | OPC_CP2,
1037     OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
1038     OPC_CTC2    = (0x06 << 21) | OPC_CP2,
1039     OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
1040     OPC_BC2     = (0x08 << 21) | OPC_CP2,
1041     OPC_BC2EQZ  = (0x09 << 21) | OPC_CP2,
1042     OPC_BC2NEZ  = (0x0D << 21) | OPC_CP2,
1043 };
1044
1045 #define MASK_LMI(op)  (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1046
1047 enum {
1048     OPC_PADDSH  = (24 << 21) | (0x00) | OPC_CP2,
1049     OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1050     OPC_PADDH   = (26 << 21) | (0x00) | OPC_CP2,
1051     OPC_PADDW   = (27 << 21) | (0x00) | OPC_CP2,
1052     OPC_PADDSB  = (28 << 21) | (0x00) | OPC_CP2,
1053     OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1054     OPC_PADDB   = (30 << 21) | (0x00) | OPC_CP2,
1055     OPC_PADDD   = (31 << 21) | (0x00) | OPC_CP2,
1056
1057     OPC_PSUBSH  = (24 << 21) | (0x01) | OPC_CP2,
1058     OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1059     OPC_PSUBH   = (26 << 21) | (0x01) | OPC_CP2,
1060     OPC_PSUBW   = (27 << 21) | (0x01) | OPC_CP2,
1061     OPC_PSUBSB  = (28 << 21) | (0x01) | OPC_CP2,
1062     OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1063     OPC_PSUBB   = (30 << 21) | (0x01) | OPC_CP2,
1064     OPC_PSUBD   = (31 << 21) | (0x01) | OPC_CP2,
1065
1066     OPC_PSHUFH   = (24 << 21) | (0x02) | OPC_CP2,
1067     OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1068     OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1069     OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1070     OPC_XOR_CP2  = (28 << 21) | (0x02) | OPC_CP2,
1071     OPC_NOR_CP2  = (29 << 21) | (0x02) | OPC_CP2,
1072     OPC_AND_CP2  = (30 << 21) | (0x02) | OPC_CP2,
1073     OPC_PANDN    = (31 << 21) | (0x02) | OPC_CP2,
1074
1075     OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1076     OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1077     OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1078     OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1079     OPC_PINSRH_0  = (28 << 21) | (0x03) | OPC_CP2,
1080     OPC_PINSRH_1  = (29 << 21) | (0x03) | OPC_CP2,
1081     OPC_PINSRH_2  = (30 << 21) | (0x03) | OPC_CP2,
1082     OPC_PINSRH_3  = (31 << 21) | (0x03) | OPC_CP2,
1083
1084     OPC_PAVGH   = (24 << 21) | (0x08) | OPC_CP2,
1085     OPC_PAVGB   = (25 << 21) | (0x08) | OPC_CP2,
1086     OPC_PMAXSH  = (26 << 21) | (0x08) | OPC_CP2,
1087     OPC_PMINSH  = (27 << 21) | (0x08) | OPC_CP2,
1088     OPC_PMAXUB  = (28 << 21) | (0x08) | OPC_CP2,
1089     OPC_PMINUB  = (29 << 21) | (0x08) | OPC_CP2,
1090
1091     OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1092     OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1093     OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1094     OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1095     OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1096     OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1097
1098     OPC_PSLLW   = (24 << 21) | (0x0A) | OPC_CP2,
1099     OPC_PSLLH   = (25 << 21) | (0x0A) | OPC_CP2,
1100     OPC_PMULLH  = (26 << 21) | (0x0A) | OPC_CP2,
1101     OPC_PMULHH  = (27 << 21) | (0x0A) | OPC_CP2,
1102     OPC_PMULUW  = (28 << 21) | (0x0A) | OPC_CP2,
1103     OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1104
1105     OPC_PSRLW     = (24 << 21) | (0x0B) | OPC_CP2,
1106     OPC_PSRLH     = (25 << 21) | (0x0B) | OPC_CP2,
1107     OPC_PSRAW     = (26 << 21) | (0x0B) | OPC_CP2,
1108     OPC_PSRAH     = (27 << 21) | (0x0B) | OPC_CP2,
1109     OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1110     OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1111
1112     OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1113     OPC_OR_CP2   = (25 << 21) | (0x0C) | OPC_CP2,
1114     OPC_ADD_CP2  = (26 << 21) | (0x0C) | OPC_CP2,
1115     OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1116     OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1117     OPC_SEQ_CP2  = (29 << 21) | (0x0C) | OPC_CP2,
1118
1119     OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1120     OPC_PASUBUB  = (25 << 21) | (0x0D) | OPC_CP2,
1121     OPC_SUB_CP2  = (26 << 21) | (0x0D) | OPC_CP2,
1122     OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1123     OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1124     OPC_SLT_CP2  = (29 << 21) | (0x0D) | OPC_CP2,
1125
1126     OPC_SLL_CP2  = (24 << 21) | (0x0E) | OPC_CP2,
1127     OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1128     OPC_PEXTRH   = (26 << 21) | (0x0E) | OPC_CP2,
1129     OPC_PMADDHW  = (27 << 21) | (0x0E) | OPC_CP2,
1130     OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1131     OPC_SLE_CP2  = (29 << 21) | (0x0E) | OPC_CP2,
1132
1133     OPC_SRL_CP2  = (24 << 21) | (0x0F) | OPC_CP2,
1134     OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1135     OPC_SRA_CP2  = (26 << 21) | (0x0F) | OPC_CP2,
1136     OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1137     OPC_BIADD    = (28 << 21) | (0x0F) | OPC_CP2,
1138     OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1139 };
1140
1141
1142 #define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
1143
1144 enum {
1145     OPC_LWXC1   = 0x00 | OPC_CP3,
1146     OPC_LDXC1   = 0x01 | OPC_CP3,
1147     OPC_LUXC1   = 0x05 | OPC_CP3,
1148     OPC_SWXC1   = 0x08 | OPC_CP3,
1149     OPC_SDXC1   = 0x09 | OPC_CP3,
1150     OPC_SUXC1   = 0x0D | OPC_CP3,
1151     OPC_PREFX   = 0x0F | OPC_CP3,
1152     OPC_ALNV_PS = 0x1E | OPC_CP3,
1153     OPC_MADD_S  = 0x20 | OPC_CP3,
1154     OPC_MADD_D  = 0x21 | OPC_CP3,
1155     OPC_MADD_PS = 0x26 | OPC_CP3,
1156     OPC_MSUB_S  = 0x28 | OPC_CP3,
1157     OPC_MSUB_D  = 0x29 | OPC_CP3,
1158     OPC_MSUB_PS = 0x2E | OPC_CP3,
1159     OPC_NMADD_S = 0x30 | OPC_CP3,
1160     OPC_NMADD_D = 0x31 | OPC_CP3,
1161     OPC_NMADD_PS= 0x36 | OPC_CP3,
1162     OPC_NMSUB_S = 0x38 | OPC_CP3,
1163     OPC_NMSUB_D = 0x39 | OPC_CP3,
1164     OPC_NMSUB_PS= 0x3E | OPC_CP3,
1165 };
1166
1167 /* MSA Opcodes */
1168 #define MASK_MSA_MINOR(op)    (MASK_OP_MAJOR(op) | (op & 0x3F))
1169 enum {
1170     OPC_MSA_I8_00   = 0x00 | OPC_MSA,
1171     OPC_MSA_I8_01   = 0x01 | OPC_MSA,
1172     OPC_MSA_I8_02   = 0x02 | OPC_MSA,
1173     OPC_MSA_I5_06   = 0x06 | OPC_MSA,
1174     OPC_MSA_I5_07   = 0x07 | OPC_MSA,
1175     OPC_MSA_BIT_09  = 0x09 | OPC_MSA,
1176     OPC_MSA_BIT_0A  = 0x0A | OPC_MSA,
1177     OPC_MSA_3R_0D   = 0x0D | OPC_MSA,
1178     OPC_MSA_3R_0E   = 0x0E | OPC_MSA,
1179     OPC_MSA_3R_0F   = 0x0F | OPC_MSA,
1180     OPC_MSA_3R_10   = 0x10 | OPC_MSA,
1181     OPC_MSA_3R_11   = 0x11 | OPC_MSA,
1182     OPC_MSA_3R_12   = 0x12 | OPC_MSA,
1183     OPC_MSA_3R_13   = 0x13 | OPC_MSA,
1184     OPC_MSA_3R_14   = 0x14 | OPC_MSA,
1185     OPC_MSA_3R_15   = 0x15 | OPC_MSA,
1186     OPC_MSA_ELM     = 0x19 | OPC_MSA,
1187     OPC_MSA_3RF_1A  = 0x1A | OPC_MSA,
1188     OPC_MSA_3RF_1B  = 0x1B | OPC_MSA,
1189     OPC_MSA_3RF_1C  = 0x1C | OPC_MSA,
1190     OPC_MSA_VEC     = 0x1E | OPC_MSA,
1191
1192     /* MI10 instruction */
1193     OPC_LD_B    = (0x20) | OPC_MSA,
1194     OPC_LD_H    = (0x21) | OPC_MSA,
1195     OPC_LD_W    = (0x22) | OPC_MSA,
1196     OPC_LD_D    = (0x23) | OPC_MSA,
1197     OPC_ST_B    = (0x24) | OPC_MSA,
1198     OPC_ST_H    = (0x25) | OPC_MSA,
1199     OPC_ST_W    = (0x26) | OPC_MSA,
1200     OPC_ST_D    = (0x27) | OPC_MSA,
1201 };
1202
1203 enum {
1204     /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1205     OPC_ADDVI_df    = (0x0 << 23) | OPC_MSA_I5_06,
1206     OPC_CEQI_df     = (0x0 << 23) | OPC_MSA_I5_07,
1207     OPC_SUBVI_df    = (0x1 << 23) | OPC_MSA_I5_06,
1208     OPC_MAXI_S_df   = (0x2 << 23) | OPC_MSA_I5_06,
1209     OPC_CLTI_S_df   = (0x2 << 23) | OPC_MSA_I5_07,
1210     OPC_MAXI_U_df   = (0x3 << 23) | OPC_MSA_I5_06,
1211     OPC_CLTI_U_df   = (0x3 << 23) | OPC_MSA_I5_07,
1212     OPC_MINI_S_df   = (0x4 << 23) | OPC_MSA_I5_06,
1213     OPC_CLEI_S_df   = (0x4 << 23) | OPC_MSA_I5_07,
1214     OPC_MINI_U_df   = (0x5 << 23) | OPC_MSA_I5_06,
1215     OPC_CLEI_U_df   = (0x5 << 23) | OPC_MSA_I5_07,
1216     OPC_LDI_df      = (0x6 << 23) | OPC_MSA_I5_07,
1217
1218     /* I8 instruction */
1219     OPC_ANDI_B  = (0x0 << 24) | OPC_MSA_I8_00,
1220     OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1221     OPC_SHF_B   = (0x0 << 24) | OPC_MSA_I8_02,
1222     OPC_ORI_B   = (0x1 << 24) | OPC_MSA_I8_00,
1223     OPC_BMZI_B  = (0x1 << 24) | OPC_MSA_I8_01,
1224     OPC_SHF_H   = (0x1 << 24) | OPC_MSA_I8_02,
1225     OPC_NORI_B  = (0x2 << 24) | OPC_MSA_I8_00,
1226     OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1227     OPC_SHF_W   = (0x2 << 24) | OPC_MSA_I8_02,
1228     OPC_XORI_B  = (0x3 << 24) | OPC_MSA_I8_00,
1229
1230     /* VEC/2R/2RF instruction */
1231     OPC_AND_V   = (0x00 << 21) | OPC_MSA_VEC,
1232     OPC_OR_V    = (0x01 << 21) | OPC_MSA_VEC,
1233     OPC_NOR_V   = (0x02 << 21) | OPC_MSA_VEC,
1234     OPC_XOR_V   = (0x03 << 21) | OPC_MSA_VEC,
1235     OPC_BMNZ_V  = (0x04 << 21) | OPC_MSA_VEC,
1236     OPC_BMZ_V   = (0x05 << 21) | OPC_MSA_VEC,
1237     OPC_BSEL_V  = (0x06 << 21) | OPC_MSA_VEC,
1238
1239     OPC_MSA_2R      = (0x18 << 21) | OPC_MSA_VEC,
1240     OPC_MSA_2RF     = (0x19 << 21) | OPC_MSA_VEC,
1241
1242     /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1243     OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1244     OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1245     OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1246     OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1247
1248     /* 2RF instruction df(bit 16) = _w, _d */
1249     OPC_FCLASS_df   = (0x00 << 17) | OPC_MSA_2RF,
1250     OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1251     OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1252     OPC_FSQRT_df    = (0x03 << 17) | OPC_MSA_2RF,
1253     OPC_FRSQRT_df   = (0x04 << 17) | OPC_MSA_2RF,
1254     OPC_FRCP_df     = (0x05 << 17) | OPC_MSA_2RF,
1255     OPC_FRINT_df    = (0x06 << 17) | OPC_MSA_2RF,
1256     OPC_FLOG2_df    = (0x07 << 17) | OPC_MSA_2RF,
1257     OPC_FEXUPL_df   = (0x08 << 17) | OPC_MSA_2RF,
1258     OPC_FEXUPR_df   = (0x09 << 17) | OPC_MSA_2RF,
1259     OPC_FFQL_df     = (0x0A << 17) | OPC_MSA_2RF,
1260     OPC_FFQR_df     = (0x0B << 17) | OPC_MSA_2RF,
1261     OPC_FTINT_S_df  = (0x0C << 17) | OPC_MSA_2RF,
1262     OPC_FTINT_U_df  = (0x0D << 17) | OPC_MSA_2RF,
1263     OPC_FFINT_S_df  = (0x0E << 17) | OPC_MSA_2RF,
1264     OPC_FFINT_U_df  = (0x0F << 17) | OPC_MSA_2RF,
1265
1266     /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1267     OPC_SLL_df      = (0x0 << 23) | OPC_MSA_3R_0D,
1268     OPC_ADDV_df     = (0x0 << 23) | OPC_MSA_3R_0E,
1269     OPC_CEQ_df      = (0x0 << 23) | OPC_MSA_3R_0F,
1270     OPC_ADD_A_df    = (0x0 << 23) | OPC_MSA_3R_10,
1271     OPC_SUBS_S_df   = (0x0 << 23) | OPC_MSA_3R_11,
1272     OPC_MULV_df     = (0x0 << 23) | OPC_MSA_3R_12,
1273     OPC_DOTP_S_df   = (0x0 << 23) | OPC_MSA_3R_13,
1274     OPC_SLD_df      = (0x0 << 23) | OPC_MSA_3R_14,
1275     OPC_VSHF_df     = (0x0 << 23) | OPC_MSA_3R_15,
1276     OPC_SRA_df      = (0x1 << 23) | OPC_MSA_3R_0D,
1277     OPC_SUBV_df     = (0x1 << 23) | OPC_MSA_3R_0E,
1278     OPC_ADDS_A_df   = (0x1 << 23) | OPC_MSA_3R_10,
1279     OPC_SUBS_U_df   = (0x1 << 23) | OPC_MSA_3R_11,
1280     OPC_MADDV_df    = (0x1 << 23) | OPC_MSA_3R_12,
1281     OPC_DOTP_U_df   = (0x1 << 23) | OPC_MSA_3R_13,
1282     OPC_SPLAT_df    = (0x1 << 23) | OPC_MSA_3R_14,
1283     OPC_SRAR_df     = (0x1 << 23) | OPC_MSA_3R_15,
1284     OPC_SRL_df      = (0x2 << 23) | OPC_MSA_3R_0D,
1285     OPC_MAX_S_df    = (0x2 << 23) | OPC_MSA_3R_0E,
1286     OPC_CLT_S_df    = (0x2 << 23) | OPC_MSA_3R_0F,
1287     OPC_ADDS_S_df   = (0x2 << 23) | OPC_MSA_3R_10,
1288     OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1289     OPC_MSUBV_df    = (0x2 << 23) | OPC_MSA_3R_12,
1290     OPC_DPADD_S_df  = (0x2 << 23) | OPC_MSA_3R_13,
1291     OPC_PCKEV_df    = (0x2 << 23) | OPC_MSA_3R_14,
1292     OPC_SRLR_df     = (0x2 << 23) | OPC_MSA_3R_15,
1293     OPC_BCLR_df     = (0x3 << 23) | OPC_MSA_3R_0D,
1294     OPC_MAX_U_df    = (0x3 << 23) | OPC_MSA_3R_0E,
1295     OPC_CLT_U_df    = (0x3 << 23) | OPC_MSA_3R_0F,
1296     OPC_ADDS_U_df   = (0x3 << 23) | OPC_MSA_3R_10,
1297     OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1298     OPC_DPADD_U_df  = (0x3 << 23) | OPC_MSA_3R_13,
1299     OPC_PCKOD_df    = (0x3 << 23) | OPC_MSA_3R_14,
1300     OPC_BSET_df     = (0x4 << 23) | OPC_MSA_3R_0D,
1301     OPC_MIN_S_df    = (0x4 << 23) | OPC_MSA_3R_0E,
1302     OPC_CLE_S_df    = (0x4 << 23) | OPC_MSA_3R_0F,
1303     OPC_AVE_S_df    = (0x4 << 23) | OPC_MSA_3R_10,
1304     OPC_ASUB_S_df   = (0x4 << 23) | OPC_MSA_3R_11,
1305     OPC_DIV_S_df    = (0x4 << 23) | OPC_MSA_3R_12,
1306     OPC_DPSUB_S_df  = (0x4 << 23) | OPC_MSA_3R_13,
1307     OPC_ILVL_df     = (0x4 << 23) | OPC_MSA_3R_14,
1308     OPC_HADD_S_df   = (0x4 << 23) | OPC_MSA_3R_15,
1309     OPC_BNEG_df     = (0x5 << 23) | OPC_MSA_3R_0D,
1310     OPC_MIN_U_df    = (0x5 << 23) | OPC_MSA_3R_0E,
1311     OPC_CLE_U_df    = (0x5 << 23) | OPC_MSA_3R_0F,
1312     OPC_AVE_U_df    = (0x5 << 23) | OPC_MSA_3R_10,
1313     OPC_ASUB_U_df   = (0x5 << 23) | OPC_MSA_3R_11,
1314     OPC_DIV_U_df    = (0x5 << 23) | OPC_MSA_3R_12,
1315     OPC_DPSUB_U_df  = (0x5 << 23) | OPC_MSA_3R_13,
1316     OPC_ILVR_df     = (0x5 << 23) | OPC_MSA_3R_14,
1317     OPC_HADD_U_df   = (0x5 << 23) | OPC_MSA_3R_15,
1318     OPC_BINSL_df    = (0x6 << 23) | OPC_MSA_3R_0D,
1319     OPC_MAX_A_df    = (0x6 << 23) | OPC_MSA_3R_0E,
1320     OPC_AVER_S_df   = (0x6 << 23) | OPC_MSA_3R_10,
1321     OPC_MOD_S_df    = (0x6 << 23) | OPC_MSA_3R_12,
1322     OPC_ILVEV_df    = (0x6 << 23) | OPC_MSA_3R_14,
1323     OPC_HSUB_S_df   = (0x6 << 23) | OPC_MSA_3R_15,
1324     OPC_BINSR_df    = (0x7 << 23) | OPC_MSA_3R_0D,
1325     OPC_MIN_A_df    = (0x7 << 23) | OPC_MSA_3R_0E,
1326     OPC_AVER_U_df   = (0x7 << 23) | OPC_MSA_3R_10,
1327     OPC_MOD_U_df    = (0x7 << 23) | OPC_MSA_3R_12,
1328     OPC_ILVOD_df    = (0x7 << 23) | OPC_MSA_3R_14,
1329     OPC_HSUB_U_df   = (0x7 << 23) | OPC_MSA_3R_15,
1330
1331     /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1332     OPC_SLDI_df     = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1333     OPC_CTCMSA      = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1334     OPC_SPLATI_df   = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1335     OPC_CFCMSA      = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1336     OPC_COPY_S_df   = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1337     OPC_MOVE_V      = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1338     OPC_COPY_U_df   = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1339     OPC_INSERT_df   = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1340     OPC_INSVE_df    = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1341
1342     /* 3RF instruction _df(bit 21) = _w, _d */
1343     OPC_FCAF_df     = (0x0 << 22) | OPC_MSA_3RF_1A,
1344     OPC_FADD_df     = (0x0 << 22) | OPC_MSA_3RF_1B,
1345     OPC_FCUN_df     = (0x1 << 22) | OPC_MSA_3RF_1A,
1346     OPC_FSUB_df     = (0x1 << 22) | OPC_MSA_3RF_1B,
1347     OPC_FCOR_df     = (0x1 << 22) | OPC_MSA_3RF_1C,
1348     OPC_FCEQ_df     = (0x2 << 22) | OPC_MSA_3RF_1A,
1349     OPC_FMUL_df     = (0x2 << 22) | OPC_MSA_3RF_1B,
1350     OPC_FCUNE_df    = (0x2 << 22) | OPC_MSA_3RF_1C,
1351     OPC_FCUEQ_df    = (0x3 << 22) | OPC_MSA_3RF_1A,
1352     OPC_FDIV_df     = (0x3 << 22) | OPC_MSA_3RF_1B,
1353     OPC_FCNE_df     = (0x3 << 22) | OPC_MSA_3RF_1C,
1354     OPC_FCLT_df     = (0x4 << 22) | OPC_MSA_3RF_1A,
1355     OPC_FMADD_df    = (0x4 << 22) | OPC_MSA_3RF_1B,
1356     OPC_MUL_Q_df    = (0x4 << 22) | OPC_MSA_3RF_1C,
1357     OPC_FCULT_df    = (0x5 << 22) | OPC_MSA_3RF_1A,
1358     OPC_FMSUB_df    = (0x5 << 22) | OPC_MSA_3RF_1B,
1359     OPC_MADD_Q_df   = (0x5 << 22) | OPC_MSA_3RF_1C,
1360     OPC_FCLE_df     = (0x6 << 22) | OPC_MSA_3RF_1A,
1361     OPC_MSUB_Q_df   = (0x6 << 22) | OPC_MSA_3RF_1C,
1362     OPC_FCULE_df    = (0x7 << 22) | OPC_MSA_3RF_1A,
1363     OPC_FEXP2_df    = (0x7 << 22) | OPC_MSA_3RF_1B,
1364     OPC_FSAF_df     = (0x8 << 22) | OPC_MSA_3RF_1A,
1365     OPC_FEXDO_df    = (0x8 << 22) | OPC_MSA_3RF_1B,
1366     OPC_FSUN_df     = (0x9 << 22) | OPC_MSA_3RF_1A,
1367     OPC_FSOR_df     = (0x9 << 22) | OPC_MSA_3RF_1C,
1368     OPC_FSEQ_df     = (0xA << 22) | OPC_MSA_3RF_1A,
1369     OPC_FTQ_df      = (0xA << 22) | OPC_MSA_3RF_1B,
1370     OPC_FSUNE_df    = (0xA << 22) | OPC_MSA_3RF_1C,
1371     OPC_FSUEQ_df    = (0xB << 22) | OPC_MSA_3RF_1A,
1372     OPC_FSNE_df     = (0xB << 22) | OPC_MSA_3RF_1C,
1373     OPC_FSLT_df     = (0xC << 22) | OPC_MSA_3RF_1A,
1374     OPC_FMIN_df     = (0xC << 22) | OPC_MSA_3RF_1B,
1375     OPC_MULR_Q_df   = (0xC << 22) | OPC_MSA_3RF_1C,
1376     OPC_FSULT_df    = (0xD << 22) | OPC_MSA_3RF_1A,
1377     OPC_FMIN_A_df   = (0xD << 22) | OPC_MSA_3RF_1B,
1378     OPC_MADDR_Q_df  = (0xD << 22) | OPC_MSA_3RF_1C,
1379     OPC_FSLE_df     = (0xE << 22) | OPC_MSA_3RF_1A,
1380     OPC_FMAX_df     = (0xE << 22) | OPC_MSA_3RF_1B,
1381     OPC_MSUBR_Q_df  = (0xE << 22) | OPC_MSA_3RF_1C,
1382     OPC_FSULE_df    = (0xF << 22) | OPC_MSA_3RF_1A,
1383     OPC_FMAX_A_df   = (0xF << 22) | OPC_MSA_3RF_1B,
1384
1385     /* BIT instruction df(bits 22..16) = _B _H _W _D */
1386     OPC_SLLI_df     = (0x0 << 23) | OPC_MSA_BIT_09,
1387     OPC_SAT_S_df    = (0x0 << 23) | OPC_MSA_BIT_0A,
1388     OPC_SRAI_df     = (0x1 << 23) | OPC_MSA_BIT_09,
1389     OPC_SAT_U_df    = (0x1 << 23) | OPC_MSA_BIT_0A,
1390     OPC_SRLI_df     = (0x2 << 23) | OPC_MSA_BIT_09,
1391     OPC_SRARI_df    = (0x2 << 23) | OPC_MSA_BIT_0A,
1392     OPC_BCLRI_df    = (0x3 << 23) | OPC_MSA_BIT_09,
1393     OPC_SRLRI_df    = (0x3 << 23) | OPC_MSA_BIT_0A,
1394     OPC_BSETI_df    = (0x4 << 23) | OPC_MSA_BIT_09,
1395     OPC_BNEGI_df    = (0x5 << 23) | OPC_MSA_BIT_09,
1396     OPC_BINSLI_df   = (0x6 << 23) | OPC_MSA_BIT_09,
1397     OPC_BINSRI_df   = (0x7 << 23) | OPC_MSA_BIT_09,
1398 };
1399
1400
1401 /*
1402  *    AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
1403  *    ============================================
1404  *
1405  * MXU (full name: MIPS eXtension/enhanced Unit) is an SIMD extension of MIPS32
1406  * instructions set. It is designed to fit the needs of signal, graphical and
1407  * video processing applications. MXU instruction set is used in Xburst family
1408  * of microprocessors by Ingenic.
1409  *
1410  * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X16 is
1411  * the control register.
1412  *
1413  * The notation used in MXU assembler mnemonics:
1414  *
1415  *   XRa, XRb, XRc, XRd - MXU registers
1416  *   Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
1417  *   s12                - a subfield of an instruction code
1418  *   strd2              - a subfield of an instruction code
1419  *   eptn2              - a subfield of an instruction code
1420  *   eptn3              - a subfield of an instruction code
1421  *   optn2              - a subfield of an instruction code
1422  *   optn3              - a subfield of an instruction code
1423  *   sft4               - a subfield of an instruction code
1424  *
1425  * Load/Store instructions           Multiplication instructions
1426  * -----------------------           ---------------------------
1427  *
1428  *  S32LDD XRa, Rb, s12               S32MADD XRa, XRd, Rs, Rt
1429  *  S32STD XRa, Rb, s12               S32MADDU XRa, XRd, Rs, Rt
1430  *  S32LDDV XRa, Rb, rc, strd2        S32SUB XRa, XRd, Rs, Rt
1431  *  S32STDV XRa, Rb, rc, strd2        S32SUBU XRa, XRd, Rs, Rt
1432  *  S32LDI XRa, Rb, s12               S32MUL XRa, XRd, Rs, Rt
1433  *  S32SDI XRa, Rb, s12               S32MULU XRa, XRd, Rs, Rt
1434  *  S32LDIV XRa, Rb, rc, strd2        D16MUL XRa, XRb, XRc, XRd, optn2
1435  *  S32SDIV XRa, Rb, rc, strd2        D16MULE XRa, XRb, XRc, optn2
1436  *  S32LDDR XRa, Rb, s12              D16MULF XRa, XRb, XRc, optn2
1437  *  S32STDR XRa, Rb, s12              D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
1438  *  S32LDDVR XRa, Rb, rc, strd2       D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
1439  *  S32STDVR XRa, Rb, rc, strd2       D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
1440  *  S32LDIR XRa, Rb, s12              D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
1441  *  S32SDIR XRa, Rb, s12              S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
1442  *  S32LDIVR XRa, Rb, rc, strd2       Q8MUL XRa, XRb, XRc, XRd
1443  *  S32SDIVR XRa, Rb, rc, strd2       Q8MULSU XRa, XRb, XRc, XRd
1444  *  S16LDD XRa, Rb, s10, eptn2        Q8MAC XRa, XRb, XRc, XRd, aptn2
1445  *  S16STD XRa, Rb, s10, eptn2        Q8MACSU XRa, XRb, XRc, XRd, aptn2
1446  *  S16LDI XRa, Rb, s10, eptn2        Q8MADL XRa, XRb, XRc, XRd, aptn2
1447  *  S16SDI XRa, Rb, s10, eptn2
1448  *  S8LDD XRa, Rb, s8, eptn3
1449  *  S8STD XRa, Rb, s8, eptn3         Addition and subtraction instructions
1450  *  S8LDI XRa, Rb, s8, eptn3         -------------------------------------
1451  *  S8SDI XRa, Rb, s8, eptn3
1452  *  LXW Rd, Rs, Rt, strd2             D32ADD XRa, XRb, XRc, XRd, eptn2
1453  *  LXH Rd, Rs, Rt, strd2             D32ADDC XRa, XRb, XRc, XRd
1454  *  LXHU Rd, Rs, Rt, strd2            D32ACC XRa, XRb, XRc, XRd, eptn2
1455  *  LXB Rd, Rs, Rt, strd2             D32ACCM XRa, XRb, XRc, XRd, eptn2
1456  *  LXBU Rd, Rs, Rt, strd2            D32ASUM XRa, XRb, XRc, XRd, eptn2
1457  *                                    S32CPS XRa, XRb, XRc
1458  *                                    Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
1459  * Comparison instructions            Q16ACC XRa, XRb, XRc, XRd, eptn2
1460  * -----------------------            Q16ACCM XRa, XRb, XRc, XRd, eptn2
1461  *                                    D16ASUM XRa, XRb, XRc, XRd, eptn2
1462  *  S32MAX XRa, XRb, XRc              D16CPS XRa, XRb,
1463  *  S32MIN XRa, XRb, XRc              D16AVG XRa, XRb, XRc
1464  *  S32SLT XRa, XRb, XRc              D16AVGR XRa, XRb, XRc
1465  *  S32MOVZ XRa, XRb, XRc             Q8ADD XRa, XRb, XRc, eptn2
1466  *  S32MOVN XRa, XRb, XRc             Q8ADDE XRa, XRb, XRc, XRd, eptn2
1467  *  D16MAX XRa, XRb, XRc              Q8ACCE XRa, XRb, XRc, XRd, eptn2
1468  *  D16MIN XRa, XRb, XRc              Q8ABD XRa, XRb, XRc
1469  *  D16SLT XRa, XRb, XRc              Q8SAD XRa, XRb, XRc, XRd
1470  *  D16MOVZ XRa, XRb, XRc             Q8AVG XRa, XRb, XRc
1471  *  D16MOVN XRa, XRb, XRc             Q8AVGR XRa, XRb, XRc
1472  *  Q8MAX XRa, XRb, XRc               D8SUM XRa, XRb, XRc, XRd
1473  *  Q8MIN XRa, XRb, XRc               D8SUMC XRa, XRb, XRc, XRd
1474  *  Q8SLT XRa, XRb, XRc
1475  *  Q8SLTU XRa, XRb, XRc
1476  *  Q8MOVZ XRa, XRb, XRc             Shift instructions
1477  *  Q8MOVN XRa, XRb, XRc             ------------------
1478  *
1479  *                                    D32SLL XRa, XRb, XRc, XRd, sft4
1480  * Bitwise instructions               D32SLR XRa, XRb, XRc, XRd, sft4
1481  * --------------------               D32SAR XRa, XRb, XRc, XRd, sft4
1482  *                                    D32SARL XRa, XRb, XRc, sft4
1483  *  S32NOR XRa, XRb, XRc              D32SLLV XRa, XRb, Rb
1484  *  S32AND XRa, XRb, XRc              D32SLRV XRa, XRb, Rb
1485  *  S32XOR XRa, XRb, XRc              D32SARV XRa, XRb, Rb
1486  *  S32OR XRa, XRb, XRc               D32SARW XRa, XRb, XRc, Rb
1487  *                                    Q16SLL XRa, XRb, XRc, XRd, sft4
1488  *                                    Q16SLR XRa, XRb, XRc, XRd, sft4
1489  * Miscellaneous instructions         Q16SAR XRa, XRb, XRc, XRd, sft4
1490  * -------------------------          Q16SLLV XRa, XRb, Rb
1491  *                                    Q16SLRV XRa, XRb, Rb
1492  *  S32SFL XRa, XRb, XRc, XRd, optn2  Q16SARV XRa, XRb, Rb
1493  *  S32ALN XRa, XRb, XRc, Rb
1494  *  S32ALNI XRa, XRb, XRc, s3
1495  *  S32LUI XRa, s8, optn3            Move instructions
1496  *  S32EXTR XRa, XRb, Rb, bits5      -----------------
1497  *  S32EXTRV XRa, XRb, Rs, Rt
1498  *  Q16SCOP XRa, XRb, XRc, XRd        S32M2I XRa, Rb
1499  *  Q16SAT XRa, XRb, XRc              S32I2M XRa, Rb
1500  *
1501  *
1502  *              bits
1503  *             05..00
1504  *
1505  *          â”Œâ”€ 000000 â”€ OPC_MXU_S32MADD
1506  *          â”œâ”€ 000001 â”€ OPC_MXU_S32MADDU
1507  *          â”œâ”€ 000010 â”€ <not assigned>   (non-MXU OPC_MUL)
1508  *          â”‚
1509  *          â”‚                               20..18
1510  *          â”œâ”€ 000011 â”€ OPC_MXU__POOL00 â”€â”¬â”€ 000 â”€ OPC_MXU_S32MAX
1511  *          â”‚                            â”œâ”€ 001 â”€ OPC_MXU_S32MIN
1512  *          â”‚                            â”œâ”€ 010 â”€ OPC_MXU_D16MAX
1513  *          â”‚                            â”œâ”€ 011 â”€ OPC_MXU_D16MIN
1514  *          â”‚                            â”œâ”€ 100 â”€ OPC_MXU_Q8MAX
1515  *          â”‚                            â”œâ”€ 101 â”€ OPC_MXU_Q8MIN
1516  *          â”‚                            â”œâ”€ 110 â”€ OPC_MXU_Q8SLT
1517  *          â”‚                            â””─ 111 â”€ OPC_MXU_Q8SLTU
1518  *          â”œâ”€ 000100 â”€ OPC_MXU_S32MSUB
1519  *          â”œâ”€ 000101 â”€ OPC_MXU_S32MSUBU    20..18
1520  *          â”œâ”€ 000110 â”€ OPC_MXU__POOL01 â”€â”¬â”€ 000 â”€ OPC_MXU_S32SLT
1521  *          â”‚                            â”œâ”€ 001 â”€ OPC_MXU_D16SLT
1522  *          â”‚                            â”œâ”€ 010 â”€ OPC_MXU_D16AVG
1523  *          â”‚                            â”œâ”€ 011 â”€ OPC_MXU_D16AVGR
1524  *          â”‚                            â”œâ”€ 100 â”€ OPC_MXU_Q8AVG
1525  *          â”‚                            â”œâ”€ 101 â”€ OPC_MXU_Q8AVGR
1526  *          â”‚                            â””─ 111 â”€ OPC_MXU_Q8ADD
1527  *          â”‚
1528  *          â”‚                               20..18
1529  *          â”œâ”€ 000111 â”€ OPC_MXU__POOL02 â”€â”¬â”€ 000 â”€ OPC_MXU_S32CPS
1530  *          â”‚                            â”œâ”€ 010 â”€ OPC_MXU_D16CPS
1531  *          â”‚                            â”œâ”€ 100 â”€ OPC_MXU_Q8ABD
1532  *          â”‚                            â””─ 110 â”€ OPC_MXU_Q16SAT
1533  *          â”œâ”€ 001000 â”€ OPC_MXU_D16MUL
1534  *          â”‚                               25..24
1535  *          â”œâ”€ 001001 â”€ OPC_MXU__POOL03 â”€â”¬â”€ 00 â”€ OPC_MXU_D16MULF
1536  *          â”‚                            â””─ 01 â”€ OPC_MXU_D16MULE
1537  *          â”œâ”€ 001010 â”€ OPC_MXU_D16MAC
1538  *          â”œâ”€ 001011 â”€ OPC_MXU_D16MACF
1539  *          â”œâ”€ 001100 â”€ OPC_MXU_D16MADL
1540  *          â”œâ”€ 001101 â”€ OPC_MXU_S16MAD
1541  *          â”œâ”€ 001110 â”€ OPC_MXU_Q16ADD
1542  *          â”œâ”€ 001111 â”€ OPC_MXU_D16MACE     23
1543  *          â”‚                            â”Œâ”€ 0 â”€ OPC_MXU_S32LDD
1544  *          â”œâ”€ 010000 â”€ OPC_MXU__POOL04 â”€â”´â”€ 1 â”€ OPC_MXU_S32LDDR
1545  *          â”‚
1546  *          â”‚                               23
1547  *          â”œâ”€ 010001 â”€ OPC_MXU__POOL05 â”€â”¬â”€ 0 â”€ OPC_MXU_S32STD
1548  *          â”‚                            â””─ 1 â”€ OPC_MXU_S32STDR
1549  *          â”‚
1550  *          â”‚                               13..10
1551  *          â”œâ”€ 010010 â”€ OPC_MXU__POOL06 â”€â”¬â”€ 0000 â”€ OPC_MXU_S32LDDV
1552  *          â”‚                            â””─ 0001 â”€ OPC_MXU_S32LDDVR
1553  *          â”‚
1554  *          â”‚                               13..10
1555  *          â”œâ”€ 010011 â”€ OPC_MXU__POOL07 â”€â”¬â”€ 0000 â”€ OPC_MXU_S32STDV
1556  *          â”‚                            â””─ 0001 â”€ OPC_MXU_S32STDVR
1557  *          â”‚
1558  *          â”‚                               23
1559  *          â”œâ”€ 010100 â”€ OPC_MXU__POOL08 â”€â”¬â”€ 0 â”€ OPC_MXU_S32LDI
1560  *          â”‚                            â””─ 1 â”€ OPC_MXU_S32LDIR
1561  *          â”‚
1562  *          â”‚                               23
1563  *          â”œâ”€ 010101 â”€ OPC_MXU__POOL09 â”€â”¬â”€ 0 â”€ OPC_MXU_S32SDI
1564  *          â”‚                            â””─ 1 â”€ OPC_MXU_S32SDIR
1565  *          â”‚
1566  *          â”‚                               13..10
1567  *          â”œâ”€ 010110 â”€ OPC_MXU__POOL10 â”€â”¬â”€ 0000 â”€ OPC_MXU_S32LDIV
1568  *          â”‚                            â””─ 0001 â”€ OPC_MXU_S32LDIVR
1569  *          â”‚
1570  *          â”‚                               13..10
1571  *          â”œâ”€ 010111 â”€ OPC_MXU__POOL11 â”€â”¬â”€ 0000 â”€ OPC_MXU_S32SDIV
1572  *          â”‚                            â””─ 0001 â”€ OPC_MXU_S32SDIVR
1573  *          â”œâ”€ 011000 â”€ OPC_MXU_D32ADD
1574  *          â”‚                               23..22
1575  *   MXU    â”œâ”€ 011001 â”€ OPC_MXU__POOL12 â”€â”¬â”€ 00 â”€ OPC_MXU_D32ACC
1576  * opcodes â”€â”¤                            â”œâ”€ 01 â”€ OPC_MXU_D32ACCM
1577  *          â”‚                            â””─ 10 â”€ OPC_MXU_D32ASUM
1578  *          â”œâ”€ 011010 â”€ <not assigned>
1579  *          â”‚                               23..22
1580  *          â”œâ”€ 011011 â”€ OPC_MXU__POOL13 â”€â”¬â”€ 00 â”€ OPC_MXU_Q16ACC
1581  *          â”‚                            â”œâ”€ 01 â”€ OPC_MXU_Q16ACCM
1582  *          â”‚                            â””─ 10 â”€ OPC_MXU_Q16ASUM
1583  *          â”‚
1584  *          â”‚                               23..22
1585  *          â”œâ”€ 011100 â”€ OPC_MXU__POOL14 â”€â”¬â”€ 00 â”€ OPC_MXU_Q8ADDE
1586  *          â”‚                            â”œâ”€ 01 â”€ OPC_MXU_D8SUM
1587  *          â”œâ”€ 011101 â”€ OPC_MXU_Q8ACCE   â””─ 10 â”€ OPC_MXU_D8SUMC
1588  *          â”œâ”€ 011110 â”€ <not assigned>
1589  *          â”œâ”€ 011111 â”€ <not assigned>
1590  *          â”œâ”€ 100000 â”€ <not assigned>   (overlaps with CLZ)
1591  *          â”œâ”€ 100001 â”€ <not assigned>   (overlaps with CLO)
1592  *          â”œâ”€ 100010 â”€ OPC_MXU_S8LDD
1593  *          â”œâ”€ 100011 â”€ OPC_MXU_S8STD       15..14
1594  *          â”œâ”€ 100100 â”€ OPC_MXU_S8LDI    â”Œâ”€ 00 â”€ OPC_MXU_S32MUL
1595  *          â”œâ”€ 100101 â”€ OPC_MXU_S8SDI    â”œâ”€ 00 â”€ OPC_MXU_S32MULU
1596  *          â”‚                            â”œâ”€ 00 â”€ OPC_MXU_S32EXTR
1597  *          â”œâ”€ 100110 â”€ OPC_MXU__POOL15 â”€â”´â”€ 00 â”€ OPC_MXU_S32EXTRV
1598  *          â”‚
1599  *          â”‚                               20..18
1600  *          â”œâ”€ 100111 â”€ OPC_MXU__POOL16 â”€â”¬â”€ 000 â”€ OPC_MXU_D32SARW
1601  *          â”‚                            â”œâ”€ 001 â”€ OPC_MXU_S32ALN
1602  *          â”œâ”€ 101000 â”€ OPC_MXU_LXB      â”œâ”€ 010 â”€ OPC_MXU_S32ALNI
1603  *          â”œâ”€ 101001 â”€ <not assigned>   â”œâ”€ 011 â”€ OPC_MXU_S32NOR
1604  *          â”œâ”€ 101010 â”€ OPC_MXU_S16LDD   â”œâ”€ 100 â”€ OPC_MXU_S32AND
1605  *          â”œâ”€ 101011 â”€ OPC_MXU_S16STD   â”œâ”€ 101 â”€ OPC_MXU_S32OR
1606  *          â”œâ”€ 101100 â”€ OPC_MXU_S16LDI   â”œâ”€ 110 â”€ OPC_MXU_S32XOR
1607  *          â”œâ”€ 101101 â”€ OPC_MXU_S16SDI   â””─ 111 â”€ OPC_MXU_S32LUI
1608  *          â”œâ”€ 101110 â”€ OPC_MXU_S32M2I
1609  *          â”œâ”€ 101111 â”€ OPC_MXU_S32I2M
1610  *          â”œâ”€ 110000 â”€ OPC_MXU_D32SLL
1611  *          â”œâ”€ 110001 â”€ OPC_MXU_D32SLR      20..18
1612  *          â”œâ”€ 110010 â”€ OPC_MXU_D32SARL  â”Œâ”€ 000 â”€ OPC_MXU_D32SLLV
1613  *          â”œâ”€ 110011 â”€ OPC_MXU_D32SAR   â”œâ”€ 001 â”€ OPC_MXU_D32SLRV
1614  *          â”œâ”€ 110100 â”€ OPC_MXU_Q16SLL   â”œâ”€ 010 â”€ OPC_MXU_D32SARV
1615  *          â”œâ”€ 110101 â”€ OPC_MXU_Q16SLR   â”œâ”€ 011 â”€ OPC_MXU_Q16SLLV
1616  *          â”‚                            â”œâ”€ 100 â”€ OPC_MXU_Q16SLRV
1617  *          â”œâ”€ 110110 â”€ OPC_MXU__POOL17 â”€â”´â”€ 101 â”€ OPC_MXU_Q16SARV
1618  *          â”‚
1619  *          â”œâ”€ 110111 â”€ OPC_MXU_Q16SAR
1620  *          â”‚                               23..22
1621  *          â”œâ”€ 111000 â”€ OPC_MXU__POOL18 â”€â”¬â”€ 00 â”€ OPC_MXU_Q8MUL
1622  *          â”‚                            â””─ 01 â”€ OPC_MXU_Q8MULSU
1623  *          â”‚
1624  *          â”‚                               20..18
1625  *          â”œâ”€ 111001 â”€ OPC_MXU__POOL19 â”€â”¬â”€ 000 â”€ OPC_MXU_Q8MOVZ
1626  *          â”‚                            â”œâ”€ 001 â”€ OPC_MXU_Q8MOVN
1627  *          â”‚                            â”œâ”€ 010 â”€ OPC_MXU_D16MOVZ
1628  *          â”‚                            â”œâ”€ 011 â”€ OPC_MXU_D16MOVN
1629  *          â”‚                            â”œâ”€ 100 â”€ OPC_MXU_S32MOVZ
1630  *          â”‚                            â””─ 101 â”€ OPC_MXU_S32MOV
1631  *          â”‚
1632  *          â”‚                               23..22
1633  *          â”œâ”€ 111010 â”€ OPC_MXU__POOL20 â”€â”¬â”€ 00 â”€ OPC_MXU_Q8MAC
1634  *          â”‚                            â””─ 10 â”€ OPC_MXU_Q8MACSU
1635  *          â”œâ”€ 111011 â”€ OPC_MXU_Q16SCOP
1636  *          â”œâ”€ 111100 â”€ OPC_MXU_Q8MADL
1637  *          â”œâ”€ 111101 â”€ OPC_MXU_S32SFL
1638  *          â”œâ”€ 111110 â”€ OPC_MXU_Q8SAD
1639  *          â””─ 111111 â”€ <not assigned>   (overlaps with SDBBP)
1640  *
1641  *
1642  *   Compiled after:
1643  *
1644  *   "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
1645  *   Programming Manual", Ingenic Semiconductor Co, Ltd., 2017
1646  */
1647
1648 enum {
1649     OPC_MXU_S32MADD  = 0x00,
1650     OPC_MXU_S32MADDU = 0x01,
1651     OPC__MXU_MUL     = 0x02,
1652     OPC_MXU__POOL00  = 0x03,
1653     OPC_MXU_S32MSUB  = 0x04,
1654     OPC_MXU_S32MSUBU = 0x05,
1655     OPC_MXU__POOL01  = 0x06,
1656     OPC_MXU__POOL02  = 0x07,
1657     OPC_MXU_D16MUL   = 0x08,
1658     OPC_MXU__POOL03  = 0x09,
1659     OPC_MXU_D16MAC   = 0x0A,
1660     OPC_MXU_D16MACF  = 0x0B,
1661     OPC_MXU_D16MADL  = 0x0C,
1662     OPC_MXU_S16MAD   = 0x0D,
1663     OPC_MXU_Q16ADD   = 0x0E,
1664     OPC_MXU_D16MACE  = 0x0F,
1665     OPC_MXU__POOL04  = 0x10,
1666     OPC_MXU__POOL05  = 0x11,
1667     OPC_MXU__POOL06  = 0x12,
1668     OPC_MXU__POOL07  = 0x13,
1669     OPC_MXU__POOL08  = 0x14,
1670     OPC_MXU__POOL09  = 0x15,
1671     OPC_MXU__POOL10  = 0x16,
1672     OPC_MXU__POOL11  = 0x17,
1673     OPC_MXU_D32ADD   = 0x18,
1674     OPC_MXU__POOL12  = 0x19,
1675     /* not assigned 0x1A */
1676     OPC_MXU__POOL13  = 0x1B,
1677     OPC_MXU__POOL14  = 0x1C,
1678     OPC_MXU_Q8ACCE   = 0x1D,
1679     /* not assigned 0x1E */
1680     /* not assigned 0x1F */
1681     /* not assigned 0x20 */
1682     /* not assigned 0x21 */
1683     OPC_MXU_S8LDD    = 0x22,
1684     OPC_MXU_S8STD    = 0x23,
1685     OPC_MXU_S8LDI    = 0x24,
1686     OPC_MXU_S8SDI    = 0x25,
1687     OPC_MXU__POOL15  = 0x26,
1688     OPC_MXU__POOL16  = 0x27,
1689     OPC_MXU_LXB      = 0x28,
1690     /* not assigned 0x29 */
1691     OPC_MXU_S16LDD   = 0x2A,
1692     OPC_MXU_S16STD   = 0x2B,
1693     OPC_MXU_S16LDI   = 0x2C,
1694     OPC_MXU_S16SDI   = 0x2D,
1695     OPC_MXU_S32M2I   = 0x2E,
1696     OPC_MXU_S32I2M   = 0x2F,
1697     OPC_MXU_D32SLL   = 0x30,
1698     OPC_MXU_D32SLR   = 0x31,
1699     OPC_MXU_D32SARL  = 0x32,
1700     OPC_MXU_D32SAR   = 0x33,
1701     OPC_MXU_Q16SLL   = 0x34,
1702     OPC_MXU_Q16SLR   = 0x35,
1703     OPC_MXU__POOL17  = 0x36,
1704     OPC_MXU_Q16SAR   = 0x37,
1705     OPC_MXU__POOL18  = 0x38,
1706     OPC_MXU__POOL19  = 0x39,
1707     OPC_MXU__POOL20  = 0x3A,
1708     OPC_MXU_Q16SCOP  = 0x3B,
1709     OPC_MXU_Q8MADL   = 0x3C,
1710     OPC_MXU_S32SFL   = 0x3D,
1711     OPC_MXU_Q8SAD    = 0x3E,
1712     /* not assigned 0x3F */
1713 };
1714
1715
1716 /*
1717  * MXU pool 00
1718  */
1719 enum {
1720     OPC_MXU_S32MAX   = 0x00,
1721     OPC_MXU_S32MIN   = 0x01,
1722     OPC_MXU_D16MAX   = 0x02,
1723     OPC_MXU_D16MIN   = 0x03,
1724     OPC_MXU_Q8MAX    = 0x04,
1725     OPC_MXU_Q8MIN    = 0x05,
1726     OPC_MXU_Q8SLT    = 0x06,
1727     OPC_MXU_Q8SLTU   = 0x07,
1728 };
1729
1730 /*
1731  * MXU pool 01
1732  */
1733 enum {
1734     OPC_MXU_S32SLT   = 0x00,
1735     OPC_MXU_D16SLT   = 0x01,
1736     OPC_MXU_D16AVG   = 0x02,
1737     OPC_MXU_D16AVGR  = 0x03,
1738     OPC_MXU_Q8AVG    = 0x04,
1739     OPC_MXU_Q8AVGR   = 0x05,
1740     OPC_MXU_Q8ADD    = 0x07,
1741 };
1742
1743 /*
1744  * MXU pool 02
1745  */
1746 enum {
1747     OPC_MXU_S32CPS   = 0x00,
1748     OPC_MXU_D16CPS   = 0x02,
1749     OPC_MXU_Q8ABD    = 0x04,
1750     OPC_MXU_Q16SAT   = 0x06,
1751 };
1752
1753 /*
1754  * MXU pool 03
1755  */
1756 enum {
1757     OPC_MXU_D16MULF  = 0x00,
1758     OPC_MXU_D16MULE  = 0x01,
1759 };
1760
1761 /*
1762  * MXU pool 04
1763  */
1764 enum {
1765     OPC_MXU_S32LDD   = 0x00,
1766     OPC_MXU_S32LDDR  = 0x01,
1767 };
1768
1769 /*
1770  * MXU pool 05
1771  */
1772 enum {
1773     OPC_MXU_S32STD   = 0x00,
1774     OPC_MXU_S32STDR  = 0x01,
1775 };
1776
1777 /*
1778  * MXU pool 06
1779  */
1780 enum {
1781     OPC_MXU_S32LDDV  = 0x00,
1782     OPC_MXU_S32LDDVR = 0x01,
1783 };
1784
1785 /*
1786  * MXU pool 07
1787  */
1788 enum {
1789     OPC_MXU_S32STDV  = 0x00,
1790     OPC_MXU_S32STDVR = 0x01,
1791 };
1792
1793 /*
1794  * MXU pool 08
1795  */
1796 enum {
1797     OPC_MXU_S32LDI   = 0x00,
1798     OPC_MXU_S32LDIR  = 0x01,
1799 };
1800
1801 /*
1802  * MXU pool 09
1803  */
1804 enum {
1805     OPC_MXU_S32SDI   = 0x00,
1806     OPC_MXU_S32SDIR  = 0x01,
1807 };
1808
1809 /*
1810  * MXU pool 10
1811  */
1812 enum {
1813     OPC_MXU_S32LDIV  = 0x00,
1814     OPC_MXU_S32LDIVR = 0x01,
1815 };
1816
1817 /*
1818  * MXU pool 11
1819  */
1820 enum {
1821     OPC_MXU_S32SDIV  = 0x00,
1822     OPC_MXU_S32SDIVR = 0x01,
1823 };
1824
1825 /*
1826  * MXU pool 12
1827  */
1828 enum {
1829     OPC_MXU_D32ACC   = 0x00,
1830     OPC_MXU_D32ACCM  = 0x01,
1831     OPC_MXU_D32ASUM  = 0x02,
1832 };
1833
1834 /*
1835  * MXU pool 13
1836  */
1837 enum {
1838     OPC_MXU_Q16ACC   = 0x00,
1839     OPC_MXU_Q16ACCM  = 0x01,
1840     OPC_MXU_Q16ASUM  = 0x02,
1841 };
1842
1843 /*
1844  * MXU pool 14
1845  */
1846 enum {
1847     OPC_MXU_Q8ADDE   = 0x00,
1848     OPC_MXU_D8SUM    = 0x01,
1849     OPC_MXU_D8SUMC   = 0x02,
1850 };
1851
1852 /*
1853  * MXU pool 15
1854  */
1855 enum {
1856     OPC_MXU_S32MUL   = 0x00,
1857     OPC_MXU_S32MULU  = 0x01,
1858     OPC_MXU_S32EXTR  = 0x02,
1859     OPC_MXU_S32EXTRV = 0x03,
1860 };
1861
1862 /*
1863  * MXU pool 16
1864  */
1865 enum {
1866     OPC_MXU_D32SARW  = 0x00,
1867     OPC_MXU_S32ALN   = 0x01,
1868     OPC_MXU_S32ALNI  = 0x02,
1869     OPC_MXU_S32NOR   = 0x03,
1870     OPC_MXU_S32AND   = 0x04,
1871     OPC_MXU_S32OR    = 0x05,
1872     OPC_MXU_S32XOR   = 0x06,
1873     OPC_MXU_S32LUI   = 0x07,
1874 };
1875
1876 /*
1877  * MXU pool 17
1878  */
1879 enum {
1880     OPC_MXU_D32SLLV  = 0x00,
1881     OPC_MXU_D32SLRV  = 0x01,
1882     OPC_MXU_D32SARV  = 0x03,
1883     OPC_MXU_Q16SLLV  = 0x04,
1884     OPC_MXU_Q16SLRV  = 0x05,
1885     OPC_MXU_Q16SARV  = 0x07,
1886 };
1887
1888 /*
1889  * MXU pool 18
1890  */
1891 enum {
1892     OPC_MXU_Q8MUL    = 0x00,
1893     OPC_MXU_Q8MULSU  = 0x01,
1894 };
1895
1896 /*
1897  * MXU pool 19
1898  */
1899 enum {
1900     OPC_MXU_Q8MOVZ   = 0x00,
1901     OPC_MXU_Q8MOVN   = 0x01,
1902     OPC_MXU_D16MOVZ  = 0x02,
1903     OPC_MXU_D16MOVN  = 0x03,
1904     OPC_MXU_S32MOVZ  = 0x04,
1905     OPC_MXU_S32MOVN  = 0x05,
1906 };
1907
1908 /*
1909  * MXU pool 20
1910  */
1911 enum {
1912     OPC_MXU_Q8MAC    = 0x00,
1913     OPC_MXU_Q8MACSU  = 0x01,
1914 };
1915
1916 /*
1917  *     Overview of the TX79-specific instruction set
1918  *     =============================================
1919  *
1920  * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits
1921  * are only used by the specific quadword (128-bit) LQ/SQ load/store
1922  * instructions and certain multimedia instructions (MMIs). These MMIs
1923  * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
1924  * or sixteen 8-bit paths.
1925  *
1926  * Reference:
1927  *
1928  * The Toshiba TX System RISC TX79 Core Architecture manual,
1929  * https://wiki.qemu.org/File:C790.pdf
1930  *
1931  *     Three-Operand Multiply and Multiply-Add (4 instructions)
1932  *     --------------------------------------------------------
1933  * MADD    [rd,] rs, rt      Multiply/Add
1934  * MADDU   [rd,] rs, rt      Multiply/Add Unsigned
1935  * MULT    [rd,] rs, rt      Multiply (3-operand)
1936  * MULTU   [rd,] rs, rt      Multiply Unsigned (3-operand)
1937  *
1938  *     Multiply Instructions for Pipeline 1 (10 instructions)
1939  *     ------------------------------------------------------
1940  * MULT1   [rd,] rs, rt      Multiply Pipeline 1
1941  * MULTU1  [rd,] rs, rt      Multiply Unsigned Pipeline 1
1942  * DIV1    rs, rt            Divide Pipeline 1
1943  * DIVU1   rs, rt            Divide Unsigned Pipeline 1
1944  * MADD1   [rd,] rs, rt      Multiply-Add Pipeline 1
1945  * MADDU1  [rd,] rs, rt      Multiply-Add Unsigned Pipeline 1
1946  * MFHI1   rd                Move From HI1 Register
1947  * MFLO1   rd                Move From LO1 Register
1948  * MTHI1   rs                Move To HI1 Register
1949  * MTLO1   rs                Move To LO1 Register
1950  *
1951  *     Arithmetic (19 instructions)
1952  *     ----------------------------
1953  * PADDB   rd, rs, rt        Parallel Add Byte
1954  * PSUBB   rd, rs, rt        Parallel Subtract Byte
1955  * PADDH   rd, rs, rt        Parallel Add Halfword
1956  * PSUBH   rd, rs, rt        Parallel Subtract Halfword
1957  * PADDW   rd, rs, rt        Parallel Add Word
1958  * PSUBW   rd, rs, rt        Parallel Subtract Word
1959  * PADSBH  rd, rs, rt        Parallel Add/Subtract Halfword
1960  * PADDSB  rd, rs, rt        Parallel Add with Signed Saturation Byte
1961  * PSUBSB  rd, rs, rt        Parallel Subtract with Signed Saturation Byte
1962  * PADDSH  rd, rs, rt        Parallel Add with Signed Saturation Halfword
1963  * PSUBSH  rd, rs, rt        Parallel Subtract with Signed Saturation Halfword
1964  * PADDSW  rd, rs, rt        Parallel Add with Signed Saturation Word
1965  * PSUBSW  rd, rs, rt        Parallel Subtract with Signed Saturation Word
1966  * PADDUB  rd, rs, rt        Parallel Add with Unsigned saturation Byte
1967  * PSUBUB  rd, rs, rt        Parallel Subtract with Unsigned saturation Byte
1968  * PADDUH  rd, rs, rt        Parallel Add with Unsigned saturation Halfword
1969  * PSUBUH  rd, rs, rt        Parallel Subtract with Unsigned saturation Halfword
1970  * PADDUW  rd, rs, rt        Parallel Add with Unsigned saturation Word
1971  * PSUBUW  rd, rs, rt        Parallel Subtract with Unsigned saturation Word
1972  *
1973  *     Min/Max (4 instructions)
1974  *     ------------------------
1975  * PMAXH   rd, rs, rt        Parallel Maximum Halfword
1976  * PMINH   rd, rs, rt        Parallel Minimum Halfword
1977  * PMAXW   rd, rs, rt        Parallel Maximum Word
1978  * PMINW   rd, rs, rt        Parallel Minimum Word
1979  *
1980  *     Absolute (2 instructions)
1981  *     -------------------------
1982  * PABSH   rd, rt            Parallel Absolute Halfword
1983  * PABSW   rd, rt            Parallel Absolute Word
1984  *
1985  *     Logical (4 instructions)
1986  *     ------------------------
1987  * PAND    rd, rs, rt        Parallel AND
1988  * POR     rd, rs, rt        Parallel OR
1989  * PXOR    rd, rs, rt        Parallel XOR
1990  * PNOR    rd, rs, rt        Parallel NOR
1991  *
1992  *     Shift (9 instructions)
1993  *     ----------------------
1994  * PSLLH   rd, rt, sa        Parallel Shift Left Logical Halfword
1995  * PSRLH   rd, rt, sa        Parallel Shift Right Logical Halfword
1996  * PSRAH   rd, rt, sa        Parallel Shift Right Arithmetic Halfword
1997  * PSLLW   rd, rt, sa        Parallel Shift Left Logical Word
1998  * PSRLW   rd, rt, sa        Parallel Shift Right Logical Word
1999  * PSRAW   rd, rt, sa        Parallel Shift Right Arithmetic Word
2000  * PSLLVW  rd, rt, rs        Parallel Shift Left Logical Variable Word
2001  * PSRLVW  rd, rt, rs        Parallel Shift Right Logical Variable Word
2002  * PSRAVW  rd, rt, rs        Parallel Shift Right Arithmetic Variable Word
2003  *
2004  *     Compare (6 instructions)
2005  *     ------------------------
2006  * PCGTB   rd, rs, rt        Parallel Compare for Greater Than Byte
2007  * PCEQB   rd, rs, rt        Parallel Compare for Equal Byte
2008  * PCGTH   rd, rs, rt        Parallel Compare for Greater Than Halfword
2009  * PCEQH   rd, rs, rt        Parallel Compare for Equal Halfword
2010  * PCGTW   rd, rs, rt        Parallel Compare for Greater Than Word
2011  * PCEQW   rd, rs, rt        Parallel Compare for Equal Word
2012  *
2013  *     LZC (1 instruction)
2014  *     -------------------
2015  * PLZCW   rd, rs            Parallel Leading Zero or One Count Word
2016  *
2017  *     Quadword Load and Store (2 instructions)
2018  *     ----------------------------------------
2019  * LQ      rt, offset(base)  Load Quadword
2020  * SQ      rt, offset(base)  Store Quadword
2021  *
2022  *     Multiply and Divide (19 instructions)
2023  *     -------------------------------------
2024  * PMULTW  rd, rs, rt        Parallel Multiply Word
2025  * PMULTUW rd, rs, rt        Parallel Multiply Unsigned Word
2026  * PDIVW   rs, rt            Parallel Divide Word
2027  * PDIVUW  rs, rt            Parallel Divide Unsigned Word
2028  * PMADDW  rd, rs, rt        Parallel Multiply-Add Word
2029  * PMADDUW rd, rs, rt        Parallel Multiply-Add Unsigned Word
2030  * PMSUBW  rd, rs, rt        Parallel Multiply-Subtract Word
2031  * PMULTH  rd, rs, rt        Parallel Multiply Halfword
2032  * PMADDH  rd, rs, rt        Parallel Multiply-Add Halfword
2033  * PMSUBH  rd, rs, rt        Parallel Multiply-Subtract Halfword
2034  * PHMADH  rd, rs, rt        Parallel Horizontal Multiply-Add Halfword
2035  * PHMSBH  rd, rs, rt        Parallel Horizontal Multiply-Subtract Halfword
2036  * PDIVBW  rs, rt            Parallel Divide Broadcast Word
2037  * PMFHI   rd                Parallel Move From HI Register
2038  * PMFLO   rd                Parallel Move From LO Register
2039  * PMTHI   rs                Parallel Move To HI Register
2040  * PMTLO   rs                Parallel Move To LO Register
2041  * PMFHL   rd                Parallel Move From HI/LO Register
2042  * PMTHL   rs                Parallel Move To HI/LO Register
2043  *
2044  *     Pack/Extend (11 instructions)
2045  *     -----------------------------
2046  * PPAC5   rd, rt            Parallel Pack to 5 bits
2047  * PPACB   rd, rs, rt        Parallel Pack to Byte
2048  * PPACH   rd, rs, rt        Parallel Pack to Halfword
2049  * PPACW   rd, rs, rt        Parallel Pack to Word
2050  * PEXT5   rd, rt            Parallel Extend Upper from 5 bits
2051  * PEXTUB  rd, rs, rt        Parallel Extend Upper from Byte
2052  * PEXTLB  rd, rs, rt        Parallel Extend Lower from Byte
2053  * PEXTUH  rd, rs, rt        Parallel Extend Upper from Halfword
2054  * PEXTLH  rd, rs, rt        Parallel Extend Lower from Halfword
2055  * PEXTUW  rd, rs, rt        Parallel Extend Upper from Word
2056  * PEXTLW  rd, rs, rt        Parallel Extend Lower from Word
2057  *
2058  *     Others (16 instructions)
2059  *     ------------------------
2060  * PCPYH   rd, rt            Parallel Copy Halfword
2061  * PCPYLD  rd, rs, rt        Parallel Copy Lower Doubleword
2062  * PCPYUD  rd, rs, rt        Parallel Copy Upper Doubleword
2063  * PREVH   rd, rt            Parallel Reverse Halfword
2064  * PINTH   rd, rs, rt        Parallel Interleave Halfword
2065  * PINTEH  rd, rs, rt        Parallel Interleave Even Halfword
2066  * PEXEH   rd, rt            Parallel Exchange Even Halfword
2067  * PEXCH   rd, rt            Parallel Exchange Center Halfword
2068  * PEXEW   rd, rt            Parallel Exchange Even Word
2069  * PEXCW   rd, rt            Parallel Exchange Center Word
2070  * QFSRV   rd, rs, rt        Quadword Funnel Shift Right Variable
2071  * MFSA    rd                Move from Shift Amount Register
2072  * MTSA    rs                Move to Shift Amount Register
2073  * MTSAB   rs, immediate     Move Byte Count to Shift Amount Register
2074  * MTSAH   rs, immediate     Move Halfword Count to Shift Amount Register
2075  * PROT3W  rd, rt            Parallel Rotate 3 Words
2076  *
2077  *     The TX79-specific Multimedia Instruction encodings
2078  *     ==================================================
2079  *
2080  * TX79 Multimedia Instruction encoding table keys:
2081  *
2082  *     *   This code is reserved for future use. An attempt to execute it
2083  *         causes a Reserved Instruction exception.
2084  *     %   This code indicates an instruction class. The instruction word
2085  *         must be further decoded by examining additional tables that show
2086  *         the values for other instruction fields.
2087  *     #   This code is reserved for the unsupported instructions DMULT,
2088  *         DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
2089  *         to execute it causes a Reserved Instruction exception.
2090  *
2091  * TX79 Multimedia Instructions encoded by opcode field (MMI, LQ, SQ):
2092  *
2093  *  31    26                                        0
2094  * +--------+----------------------------------------+
2095  * | opcode |                                        |
2096  * +--------+----------------------------------------+
2097  *
2098  *   opcode  bits 28..26
2099  *     bits |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7
2100  *   31..29 |  000  |  001  |  010  |  011  |  100  |  101  |  110  |  111
2101  *   -------+-------+-------+-------+-------+-------+-------+-------+-------
2102  *    0 000 |SPECIAL| REGIMM|   J   |  JAL  |  BEQ  |  BNE  |  BLEZ |  BGTZ
2103  *    1 001 |  ADDI | ADDIU |  SLTI | SLTIU |  ANDI |  ORI  |  XORI |  LUI
2104  *    2 010 |  COP0 |  COP1 |   *   |   *   |  BEQL |  BNEL | BLEZL | BGTZL
2105  *    3 011 | DADDI | DADDIU|  LDL  |  LDR  |  MMI% |   *   |   LQ  |   SQ
2106  *    4 100 |   LB  |   LH  |  LWL  |   LW  |  LBU  |  LHU  |  LWR  |  LWU
2107  *    5 101 |   SB  |   SH  |  SWL  |   SW  |  SDL  |  SDR  |  SWR  | CACHE
2108  *    6 110 |   #   |  LWC1 |   #   |  PREF |   #   |  LDC1 |   #   |   LD
2109  *    7 111 |   #   |  SWC1 |   #   |   *   |   #   |  SDC1 |   #   |   SD
2110  */
2111
2112 enum {
2113     TX79_CLASS_MMI = 0x1C << 26,    /* Same as OPC_SPECIAL2 */
2114     TX79_LQ        = 0x1E << 26,    /* Same as OPC_MSA */
2115     TX79_SQ        = 0x1F << 26,    /* Same as OPC_SPECIAL3 */
2116 };
2117
2118 /*
2119  * TX79 Multimedia Instructions with opcode field = MMI:
2120  *
2121  *  31    26                                 5      0
2122  * +--------+-------------------------------+--------+
2123  * |   MMI  |                               |function|
2124  * +--------+-------------------------------+--------+
2125  *
2126  * function  bits 2..0
2127  *     bits |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7
2128  *     5..3 |  000  |  001  |  010  |  011  |  100  |  101  |  110  |  111
2129  *   -------+-------+-------+-------+-------+-------+-------+-------+-------
2130  *    0 000 |  MADD | MADDU |   *   |   *   | PLZCW |   *   |   *   |   *
2131  *    1 001 | MMI0% | MMI2% |   *   |   *   |   *   |   *   |   *   |   *
2132  *    2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 |   *   |   *   |   *   |   *
2133  *    3 011 | MULT1 | MULTU1|  DIV1 | DIVU1 |   *   |   *   |   *   |   *
2134  *    4 100 | MADD1 | MADDU1|   *   |   *   |   *   |   *   |   *   |   *
2135  *    5 101 | MMI1% | MMI3% |   *   |   *   |   *   |   *   |   *   |   *
2136  *    6 110 | PMFHL | PMTHL |   *   |   *   | PSLLH |   *   | PSRLH | PSRAH
2137  *    7 111 |   *   |   *   |   *   |   *   | PSLLW |   *   | PSRLW | PSRAW
2138  */
2139
2140 #define MASK_TX79_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
2141 enum {
2142     TX79_MMI_MADD       = 0x00 | TX79_CLASS_MMI, /* Same as OPC_MADD */
2143     TX79_MMI_MADDU      = 0x01 | TX79_CLASS_MMI, /* Same as OPC_MADDU */
2144     TX79_MMI_PLZCW      = 0x04 | TX79_CLASS_MMI,
2145     TX79_MMI_CLASS_MMI0 = 0x08 | TX79_CLASS_MMI,
2146     TX79_MMI_CLASS_MMI2 = 0x09 | TX79_CLASS_MMI,
2147     TX79_MMI_MFHI1      = 0x10 | TX79_CLASS_MMI, /* Same minor as OPC_MFHI */
2148     TX79_MMI_MTHI1      = 0x11 | TX79_CLASS_MMI, /* Same minor as OPC_MTHI */
2149     TX79_MMI_MFLO1      = 0x12 | TX79_CLASS_MMI, /* Same minor as OPC_MFLO */
2150     TX79_MMI_MTLO1      = 0x13 | TX79_CLASS_MMI, /* Same minor as OPC_MTLO */
2151     TX79_MMI_MULT1      = 0x18 | TX79_CLASS_MMI, /* Same minor as OPC_MULT */
2152     TX79_MMI_MULTU1     = 0x19 | TX79_CLASS_MMI, /* Same minor as OPC_MULTU */
2153     TX79_MMI_DIV1       = 0x1A | TX79_CLASS_MMI, /* Same minor as OPC_DIV */
2154     TX79_MMI_DIVU1      = 0x1B | TX79_CLASS_MMI, /* Same minor as OPC_DIVU */
2155     TX79_MMI_MADD1      = 0x20 | TX79_CLASS_MMI,
2156     TX79_MMI_MADDU1     = 0x21 | TX79_CLASS_MMI,
2157     TX79_MMI_CLASS_MMI1 = 0x28 | TX79_CLASS_MMI,
2158     TX79_MMI_CLASS_MMI3 = 0x29 | TX79_CLASS_MMI,
2159     TX79_MMI_PMFHL      = 0x30 | TX79_CLASS_MMI,
2160     TX79_MMI_PMTHL      = 0x31 | TX79_CLASS_MMI,
2161     TX79_MMI_PSLLH      = 0x34 | TX79_CLASS_MMI,
2162     TX79_MMI_PSRLH      = 0x36 | TX79_CLASS_MMI,
2163     TX79_MMI_PSRAH      = 0x37 | TX79_CLASS_MMI,
2164     TX79_MMI_PSLLW      = 0x3C | TX79_CLASS_MMI,
2165     TX79_MMI_PSRLW      = 0x3E | TX79_CLASS_MMI,
2166     TX79_MMI_PSRAW      = 0x3F | TX79_CLASS_MMI,
2167 };
2168
2169 /*
2170  * TX79 Multimedia Instructions with opcode field = MMI and bits 5..0 = MMI0:
2171  *
2172  *  31    26                        10     6 5      0
2173  * +--------+----------------------+--------+--------+
2174  * |   MMI  |                      |function|  MMI0  |
2175  * +--------+----------------------+--------+--------+
2176  *
2177  * function  bits 7..6
2178  *     bits |   0   |   1   |   2   |   3
2179  *    10..8 |   00  |   01  |   10  |   11
2180  *   -------+-------+-------+-------+-------
2181  *    0 000 | PADDW | PSUBW | PCGTW | PMAXW
2182  *    1 001 | PADDH | PSUBH | PCGTH | PMAXH
2183  *    2 010 | PADDB | PSUBB | PCGTB |   *
2184  *    3 011 |   *   |   *   |   *   |   *
2185  *    4 100 | PADDSW| PSUBSW| PEXTLW| PPACW
2186  *    5 101 | PADDSH| PSUBSH| PEXTLH| PPACH
2187  *    6 110 | PADDSB| PSUBSB| PEXTLB| PPACB
2188  *    7 111 |   *   |   *   | PEXT5 | PPAC5
2189  */
2190
2191 #define MASK_TX79_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2192 enum {
2193     TX79_MMI0_PADDW  = (0x00 << 6) | TX79_MMI_CLASS_MMI0,
2194     TX79_MMI0_PSUBW  = (0x01 << 6) | TX79_MMI_CLASS_MMI0,
2195     TX79_MMI0_PCGTW  = (0x02 << 6) | TX79_MMI_CLASS_MMI0,
2196     TX79_MMI0_PMAXW  = (0x03 << 6) | TX79_MMI_CLASS_MMI0,
2197     TX79_MMI0_PADDH  = (0x04 << 6) | TX79_MMI_CLASS_MMI0,
2198     TX79_MMI0_PSUBH  = (0x05 << 6) | TX79_MMI_CLASS_MMI0,
2199     TX79_MMI0_PCGTH  = (0x06 << 6) | TX79_MMI_CLASS_MMI0,
2200     TX79_MMI0_PMAXH  = (0x07 << 6) | TX79_MMI_CLASS_MMI0,
2201     TX79_MMI0_PADDB  = (0x08 << 6) | TX79_MMI_CLASS_MMI0,
2202     TX79_MMI0_PSUBB  = (0x09 << 6) | TX79_MMI_CLASS_MMI0,
2203     TX79_MMI0_PCGTB  = (0x0A << 6) | TX79_MMI_CLASS_MMI0,
2204     TX79_MMI0_PADDSW = (0x10 << 6) | TX79_MMI_CLASS_MMI0,
2205     TX79_MMI0_PSUBSW = (0x11 << 6) | TX79_MMI_CLASS_MMI0,
2206     TX79_MMI0_PEXTLW = (0x12 << 6) | TX79_MMI_CLASS_MMI0,
2207     TX79_MMI0_PPACW  = (0x13 << 6) | TX79_MMI_CLASS_MMI0,
2208     TX79_MMI0_PADDSH = (0x14 << 6) | TX79_MMI_CLASS_MMI0,
2209     TX79_MMI0_PSUBSH = (0x15 << 6) | TX79_MMI_CLASS_MMI0,
2210     TX79_MMI0_PEXTLH = (0x16 << 6) | TX79_MMI_CLASS_MMI0,
2211     TX79_MMI0_PPACH  = (0x17 << 6) | TX79_MMI_CLASS_MMI0,
2212     TX79_MMI0_PADDSB = (0x18 << 6) | TX79_MMI_CLASS_MMI0,
2213     TX79_MMI0_PSUBSB = (0x19 << 6) | TX79_MMI_CLASS_MMI0,
2214     TX79_MMI0_PEXTLB = (0x1A << 6) | TX79_MMI_CLASS_MMI0,
2215     TX79_MMI0_PPACB  = (0x1B << 6) | TX79_MMI_CLASS_MMI0,
2216     TX79_MMI0_PEXT5  = (0x1E << 6) | TX79_MMI_CLASS_MMI0,
2217     TX79_MMI0_PPAC5  = (0x1F << 6) | TX79_MMI_CLASS_MMI0,
2218 };
2219
2220 /*
2221  * TX79 Multimedia Instructions with opcode field = MMI and bits 5..0 = MMI1:
2222  *
2223  *  31    26                        10     6 5      0
2224  * +--------+----------------------+--------+--------+
2225  * |   MMI  |                      |function|  MMI1  |
2226  * +--------+----------------------+--------+--------+
2227  *
2228  * function  bits 7..6
2229  *     bits |   0   |   1   |   2   |   3
2230  *    10..8 |   00  |   01  |   10  |   11
2231  *   -------+-------+-------+-------+-------
2232  *    0 000 |   *   | PABSW | PCEQW | PMINW
2233  *    1 001 | PADSBH| PABSH | PCEQH | PMINH
2234  *    2 010 |   *   |   *   | PCEQB |   *
2235  *    3 011 |   *   |   *   |   *   |   *
2236  *    4 100 | PADDUW| PSUBUW| PEXTUW|   *
2237  *    5 101 | PADDUH| PSUBUH| PEXTUH|   *
2238  *    6 110 | PADDUB| PSUBUB| PEXTUB| QFSRV
2239  *    7 111 |   *   |   *   |   *   |   *
2240  */
2241
2242 #define MASK_TX79_MMI1(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2243 enum {
2244     TX79_MMI1_PABSW  = (0x01 << 6) | TX79_MMI_CLASS_MMI1,
2245     TX79_MMI1_PCEQW  = (0x02 << 6) | TX79_MMI_CLASS_MMI1,
2246     TX79_MMI1_PMINW  = (0x03 << 6) | TX79_MMI_CLASS_MMI1,
2247     TX79_MMI1_PADSBH = (0x04 << 6) | TX79_MMI_CLASS_MMI1,
2248     TX79_MMI1_PABSH  = (0x05 << 6) | TX79_MMI_CLASS_MMI1,
2249     TX79_MMI1_PCEQH  = (0x06 << 6) | TX79_MMI_CLASS_MMI1,
2250     TX79_MMI1_PMINH  = (0x07 << 6) | TX79_MMI_CLASS_MMI1,
2251     TX79_MMI1_PCEQB  = (0x0A << 6) | TX79_MMI_CLASS_MMI1,
2252     TX79_MMI1_PADDUW = (0x10 << 6) | TX79_MMI_CLASS_MMI1,
2253     TX79_MMI1_PSUBUW = (0x11 << 6) | TX79_MMI_CLASS_MMI1,
2254     TX79_MMI1_PEXTUW = (0x12 << 6) | TX79_MMI_CLASS_MMI1,
2255     TX79_MMI1_PADDUH = (0x14 << 6) | TX79_MMI_CLASS_MMI1,
2256     TX79_MMI1_PSUBUH = (0x15 << 6) | TX79_MMI_CLASS_MMI1,
2257     TX79_MMI1_PEXTUH = (0x16 << 6) | TX79_MMI_CLASS_MMI1,
2258     TX79_MMI1_PADDUB = (0x18 << 6) | TX79_MMI_CLASS_MMI1,
2259     TX79_MMI1_PSUBUB = (0x19 << 6) | TX79_MMI_CLASS_MMI1,
2260     TX79_MMI1_PEXTUB = (0x1A << 6) | TX79_MMI_CLASS_MMI1,
2261     TX79_MMI1_QFSRV  = (0x1B << 6) | TX79_MMI_CLASS_MMI1,
2262 };
2263
2264 /*
2265  * TX79 Multimedia Instructions with opcode field = MMI and bits 5..0 = MMI2:
2266  *
2267  *  31    26                        10     6 5      0
2268  * +--------+----------------------+--------+--------+
2269  * |   MMI  |                      |function|  MMI2  |
2270  * +--------+----------------------+--------+--------+
2271  *
2272  * function  bits 7..6
2273  *     bits |   0   |   1   |   2   |   3
2274  *    10..8 |   00  |   01  |   10  |   11
2275  *   -------+-------+-------+-------+-------
2276  *    0 000 | PMADDW|   *   | PSLLVW| PSRLVW
2277  *    1 001 | PMSUBW|   *   |   *   |   *
2278  *    2 010 | PMFHI | PMFLO | PINTH |   *
2279  *    3 011 | PMULTW| PDIVW | PCPYLD|   *
2280  *    4 100 | PMADDH| PHMADH|  PAND |  PXOR
2281  *    5 101 | PMSUBH| PHMSBH|   *   |   *
2282  *    6 110 |   *   |   *   | PEXEH | PREVH
2283  *    7 111 | PMULTH| PDIVBW| PEXEW | PROT3W
2284  */
2285
2286 #define MASK_TX79_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2287 enum {
2288     TX79_MMI2_PMADDW = (0x00 << 6) | TX79_MMI_CLASS_MMI2,
2289     TX79_MMI2_PSLLVW = (0x02 << 6) | TX79_MMI_CLASS_MMI2,
2290     TX79_MMI2_PSRLVW = (0x03 << 6) | TX79_MMI_CLASS_MMI2,
2291     TX79_MMI2_PMSUBW = (0x04 << 6) | TX79_MMI_CLASS_MMI2,
2292     TX79_MMI2_PMFHI  = (0x08 << 6) | TX79_MMI_CLASS_MMI2,
2293     TX79_MMI2_PMFLO  = (0x09 << 6) | TX79_MMI_CLASS_MMI2,
2294     TX79_MMI2_PINTH  = (0x0A << 6) | TX79_MMI_CLASS_MMI2,
2295     TX79_MMI2_PMULTW = (0x0C << 6) | TX79_MMI_CLASS_MMI2,
2296     TX79_MMI2_PDIVW  = (0x0D << 6) | TX79_MMI_CLASS_MMI2,
2297     TX79_MMI2_PCPYLD = (0x0E << 6) | TX79_MMI_CLASS_MMI2,
2298     TX79_MMI2_PMADDH = (0x10 << 6) | TX79_MMI_CLASS_MMI2,
2299     TX79_MMI2_PHMADH = (0x11 << 6) | TX79_MMI_CLASS_MMI2,
2300     TX79_MMI2_PAND   = (0x12 << 6) | TX79_MMI_CLASS_MMI2,
2301     TX79_MMI2_PXOR   = (0x13 << 6) | TX79_MMI_CLASS_MMI2,
2302     TX79_MMI2_PMSUBH = (0x14 << 6) | TX79_MMI_CLASS_MMI2,
2303     TX79_MMI2_PHMSBH = (0x15 << 6) | TX79_MMI_CLASS_MMI2,
2304     TX79_MMI2_PEXEH  = (0x1A << 6) | TX79_MMI_CLASS_MMI2,
2305     TX79_MMI2_PREVH  = (0x1B << 6) | TX79_MMI_CLASS_MMI2,
2306     TX79_MMI2_PMULTH = (0x1C << 6) | TX79_MMI_CLASS_MMI2,
2307     TX79_MMI2_PDIVBW = (0x1D << 6) | TX79_MMI_CLASS_MMI2,
2308     TX79_MMI2_PEXEW  = (0x1E << 6) | TX79_MMI_CLASS_MMI2,
2309     TX79_MMI2_PROT3W = (0x1F << 6) | TX79_MMI_CLASS_MMI2,
2310 };
2311
2312 /*
2313  * TX79 Multimedia Instructions with opcode field = MMI and bits 5..0 = MMI3:
2314  *
2315  *  31    26                        10     6 5      0
2316  * +--------+----------------------+--------+--------+
2317  * |   MMI  |                      |function|  MMI3  |
2318  * +--------+----------------------+--------+--------+
2319  *
2320  * function  bits 7..6
2321  *     bits |   0   |   1   |   2   |   3
2322  *    10..8 |   00  |   01  |   10  |   11
2323  *   -------+-------+-------+-------+-------
2324  *    0 000 |PMADDUW|   *   |   *   | PSRAVW
2325  *    1 001 |   *   |   *   |   *   |   *
2326  *    2 010 | PMTHI | PMTLO | PINTEH|   *
2327  *    3 011 |PMULTUW| PDIVUW| PCPYUD|   *
2328  *    4 100 |   *   |   *   |  POR  |  PNOR
2329  *    5 101 |   *   |   *   |   *   |   *
2330  *    6 110 |   *   |   *   | PEXCH | PCPYH
2331  *    7 111 |   *   |   *   | PEXCW |   *
2332  */
2333
2334 #define MASK_TX79_MMI3(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2335 enum {
2336     TX79_MMI3_PMADDUW = (0x00 << 6) | TX79_MMI_CLASS_MMI3,
2337     TX79_MMI3_PSRAVW  = (0x03 << 6) | TX79_MMI_CLASS_MMI3,
2338     TX79_MMI3_PMTHI   = (0x08 << 6) | TX79_MMI_CLASS_MMI3,
2339     TX79_MMI3_PMTLO   = (0x09 << 6) | TX79_MMI_CLASS_MMI3,
2340     TX79_MMI3_PINTEH  = (0x0A << 6) | TX79_MMI_CLASS_MMI3,
2341     TX79_MMI3_PMULTUW = (0x0C << 6) | TX79_MMI_CLASS_MMI3,
2342     TX79_MMI3_PDIVUW  = (0x0D << 6) | TX79_MMI_CLASS_MMI3,
2343     TX79_MMI3_PCPYUD  = (0x0E << 6) | TX79_MMI_CLASS_MMI3,
2344     TX79_MMI3_POR     = (0x12 << 6) | TX79_MMI_CLASS_MMI3,
2345     TX79_MMI3_PNOR    = (0x13 << 6) | TX79_MMI_CLASS_MMI3,
2346     TX79_MMI3_PEXCH   = (0x1A << 6) | TX79_MMI_CLASS_MMI3,
2347     TX79_MMI3_PCPYH   = (0x1B << 6) | TX79_MMI_CLASS_MMI3,
2348     TX79_MMI3_PEXCW   = (0x1E << 6) | TX79_MMI_CLASS_MMI3,
2349 };
2350
2351 /* global register indices */
2352 static TCGv cpu_gpr[32], cpu_PC;
2353 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
2354 static TCGv cpu_dspctrl, btarget, bcond;
2355 static TCGv_i32 hflags;
2356 static TCGv_i32 fpu_fcr0, fpu_fcr31;
2357 static TCGv_i64 fpu_f64[32];
2358 static TCGv_i64 msa_wr_d[64];
2359
2360 /* MXU registers */
2361 static TCGv mxu_gpr[NUMBER_OF_MXU_REGISTERS - 1];
2362 static TCGv mxu_CR;
2363
2364 #include "exec/gen-icount.h"
2365
2366 #define gen_helper_0e0i(name, arg) do {                           \
2367     TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
2368     gen_helper_##name(cpu_env, helper_tmp);                       \
2369     tcg_temp_free_i32(helper_tmp);                                \
2370     } while(0)
2371
2372 #define gen_helper_0e1i(name, arg1, arg2) do {                    \
2373     TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
2374     gen_helper_##name(cpu_env, arg1, helper_tmp);                 \
2375     tcg_temp_free_i32(helper_tmp);                                \
2376     } while(0)
2377
2378 #define gen_helper_1e0i(name, ret, arg1) do {                     \
2379     TCGv_i32 helper_tmp = tcg_const_i32(arg1);                    \
2380     gen_helper_##name(ret, cpu_env, helper_tmp);                  \
2381     tcg_temp_free_i32(helper_tmp);                                \
2382     } while(0)
2383
2384 #define gen_helper_1e1i(name, ret, arg1, arg2) do {               \
2385     TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
2386     gen_helper_##name(ret, cpu_env, arg1, helper_tmp);            \
2387     tcg_temp_free_i32(helper_tmp);                                \
2388     } while(0)
2389
2390 #define gen_helper_0e2i(name, arg1, arg2, arg3) do {              \
2391     TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
2392     gen_helper_##name(cpu_env, arg1, arg2, helper_tmp);           \
2393     tcg_temp_free_i32(helper_tmp);                                \
2394     } while(0)
2395
2396 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do {         \
2397     TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
2398     gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp);      \
2399     tcg_temp_free_i32(helper_tmp);                                \
2400     } while(0)
2401
2402 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do {        \
2403     TCGv_i32 helper_tmp = tcg_const_i32(arg4);                    \
2404     gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp);     \
2405     tcg_temp_free_i32(helper_tmp);                                \
2406     } while(0)
2407
2408 typedef struct DisasContext {
2409     DisasContextBase base;
2410     target_ulong saved_pc;
2411     target_ulong page_start;
2412     uint32_t opcode;
2413     uint64_t insn_flags;
2414     int32_t CP0_Config1;
2415     int32_t CP0_Config2;
2416     int32_t CP0_Config3;
2417     int32_t CP0_Config5;
2418     /* Routine used to access memory */
2419     int mem_idx;
2420     TCGMemOp default_tcg_memop_mask;
2421     uint32_t hflags, saved_hflags;
2422     target_ulong btarget;
2423     bool ulri;
2424     int kscrexist;
2425     bool rxi;
2426     int ie;
2427     bool bi;
2428     bool bp;
2429     uint64_t PAMask;
2430     bool mvh;
2431     bool eva;
2432     bool sc;
2433     int CP0_LLAddr_shift;
2434     bool ps;
2435     bool vp;
2436     bool cmgcr;
2437     bool mrp;
2438     bool nan2008;
2439     bool abs2008;
2440 } DisasContext;
2441
2442 #define DISAS_STOP       DISAS_TARGET_0
2443 #define DISAS_EXIT       DISAS_TARGET_1
2444
2445 static const char * const regnames[] = {
2446     "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2447     "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2448     "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2449     "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2450 };
2451
2452 static const char * const regnames_HI[] = {
2453     "HI0", "HI1", "HI2", "HI3",
2454 };
2455
2456 static const char * const regnames_LO[] = {
2457     "LO0", "LO1", "LO2", "LO3",
2458 };
2459
2460 static const char * const fregnames[] = {
2461     "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
2462     "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
2463     "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2464     "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2465 };
2466
2467 static const char * const msaregnames[] = {
2468     "w0.d0",  "w0.d1",  "w1.d0",  "w1.d1",
2469     "w2.d0",  "w2.d1",  "w3.d0",  "w3.d1",
2470     "w4.d0",  "w4.d1",  "w5.d0",  "w5.d1",
2471     "w6.d0",  "w6.d1",  "w7.d0",  "w7.d1",
2472     "w8.d0",  "w8.d1",  "w9.d0",  "w9.d1",
2473     "w10.d0", "w10.d1", "w11.d0", "w11.d1",
2474     "w12.d0", "w12.d1", "w13.d0", "w13.d1",
2475     "w14.d0", "w14.d1", "w15.d0", "w15.d1",
2476     "w16.d0", "w16.d1", "w17.d0", "w17.d1",
2477     "w18.d0", "w18.d1", "w19.d0", "w19.d1",
2478     "w20.d0", "w20.d1", "w21.d0", "w21.d1",
2479     "w22.d0", "w22.d1", "w23.d0", "w23.d1",
2480     "w24.d0", "w24.d1", "w25.d0", "w25.d1",
2481     "w26.d0", "w26.d1", "w27.d0", "w27.d1",
2482     "w28.d0", "w28.d1", "w29.d0", "w29.d1",
2483     "w30.d0", "w30.d1", "w31.d0", "w31.d1",
2484 };
2485
2486 static const char * const mxuregnames[] = {
2487     "XR1",  "XR2",  "XR3",  "XR4",  "XR5",  "XR6",  "XR7",  "XR8",
2488     "XR9",  "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
2489 };
2490
2491 #define LOG_DISAS(...)                                                        \
2492     do {                                                                      \
2493         if (MIPS_DEBUG_DISAS) {                                               \
2494             qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__);                 \
2495         }                                                                     \
2496     } while (0)
2497
2498 #define MIPS_INVAL(op)                                                        \
2499     do {                                                                      \
2500         if (MIPS_DEBUG_DISAS) {                                               \
2501             qemu_log_mask(CPU_LOG_TB_IN_ASM,                                  \
2502                           TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
2503                           ctx->base.pc_next, ctx->opcode, op,                 \
2504                           ctx->opcode >> 26, ctx->opcode & 0x3F,              \
2505                           ((ctx->opcode >> 16) & 0x1F));                      \
2506         }                                                                     \
2507     } while (0)
2508
2509 /* General purpose registers moves. */
2510 static inline void gen_load_gpr (TCGv t, int reg)
2511 {
2512     if (reg == 0)
2513         tcg_gen_movi_tl(t, 0);
2514     else
2515         tcg_gen_mov_tl(t, cpu_gpr[reg]);
2516 }
2517
2518 static inline void gen_store_gpr (TCGv t, int reg)
2519 {
2520     if (reg != 0)
2521         tcg_gen_mov_tl(cpu_gpr[reg], t);
2522 }
2523
2524 /* Moves to/from shadow registers. */
2525 static inline void gen_load_srsgpr (int from, int to)
2526 {
2527     TCGv t0 = tcg_temp_new();
2528
2529     if (from == 0)
2530         tcg_gen_movi_tl(t0, 0);
2531     else {
2532         TCGv_i32 t2 = tcg_temp_new_i32();
2533         TCGv_ptr addr = tcg_temp_new_ptr();
2534
2535         tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2536         tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2537         tcg_gen_andi_i32(t2, t2, 0xf);
2538         tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2539         tcg_gen_ext_i32_ptr(addr, t2);
2540         tcg_gen_add_ptr(addr, cpu_env, addr);
2541
2542         tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
2543         tcg_temp_free_ptr(addr);
2544         tcg_temp_free_i32(t2);
2545     }
2546     gen_store_gpr(t0, to);
2547     tcg_temp_free(t0);
2548 }
2549
2550 static inline void gen_store_srsgpr (int from, int to)
2551 {
2552     if (to != 0) {
2553         TCGv t0 = tcg_temp_new();
2554         TCGv_i32 t2 = tcg_temp_new_i32();
2555         TCGv_ptr addr = tcg_temp_new_ptr();
2556
2557         gen_load_gpr(t0, from);
2558         tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2559         tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2560         tcg_gen_andi_i32(t2, t2, 0xf);
2561         tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2562         tcg_gen_ext_i32_ptr(addr, t2);
2563         tcg_gen_add_ptr(addr, cpu_env, addr);
2564
2565         tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
2566         tcg_temp_free_ptr(addr);
2567         tcg_temp_free_i32(t2);
2568         tcg_temp_free(t0);
2569     }
2570 }
2571
2572 /* MXU General purpose registers moves. */
2573 static inline void gen_load_mxu_gpr(TCGv t, unsigned int reg)
2574 {
2575     if (reg == 0) {
2576         tcg_gen_movi_tl(t, 0);
2577     } else if (reg <= 15) {
2578         tcg_gen_mov_tl(t, mxu_gpr[reg - 1]);
2579     }
2580 }
2581
2582 static inline void gen_store_mxu_gpr(TCGv t, unsigned int reg)
2583 {
2584     if (reg > 0 && reg <= 15) {
2585         tcg_gen_mov_tl(mxu_gpr[reg - 1], t);
2586     }
2587 }
2588
2589 /* MXU control register moves. */
2590 static inline void gen_load_mxu_cr(TCGv t)
2591 {
2592     tcg_gen_mov_tl(t, mxu_CR);
2593 }
2594
2595 static inline void gen_store_mxu_cr(TCGv t)
2596 {
2597     /* TODO: Add handling of RW rules for MXU_CR. */
2598     tcg_gen_mov_tl(mxu_CR, t);
2599 }
2600
2601
2602 /* Tests */
2603 static inline void gen_save_pc(target_ulong pc)
2604 {
2605     tcg_gen_movi_tl(cpu_PC, pc);
2606 }
2607
2608 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
2609 {
2610     LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
2611     if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
2612         gen_save_pc(ctx->base.pc_next);
2613         ctx->saved_pc = ctx->base.pc_next;
2614     }
2615     if (ctx->hflags != ctx->saved_hflags) {
2616         tcg_gen_movi_i32(hflags, ctx->hflags);
2617         ctx->saved_hflags = ctx->hflags;
2618         switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2619         case MIPS_HFLAG_BR:
2620             break;
2621         case MIPS_HFLAG_BC:
2622         case MIPS_HFLAG_BL:
2623         case MIPS_HFLAG_B:
2624             tcg_gen_movi_tl(btarget, ctx->btarget);
2625             break;
2626         }
2627     }
2628 }
2629
2630 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
2631 {
2632     ctx->saved_hflags = ctx->hflags;
2633     switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2634     case MIPS_HFLAG_BR:
2635         break;
2636     case MIPS_HFLAG_BC:
2637     case MIPS_HFLAG_BL:
2638     case MIPS_HFLAG_B:
2639         ctx->btarget = env->btarget;
2640         break;
2641     }
2642 }
2643
2644 static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
2645 {
2646     TCGv_i32 texcp = tcg_const_i32(excp);
2647     TCGv_i32 terr = tcg_const_i32(err);
2648     save_cpu_state(ctx, 1);
2649     gen_helper_raise_exception_err(cpu_env, texcp, terr);
2650     tcg_temp_free_i32(terr);
2651     tcg_temp_free_i32(texcp);
2652     ctx->base.is_jmp = DISAS_NORETURN;
2653 }
2654
2655 static inline void generate_exception(DisasContext *ctx, int excp)
2656 {
2657     gen_helper_0e0i(raise_exception, excp);
2658 }
2659
2660 static inline void generate_exception_end(DisasContext *ctx, int excp)
2661 {
2662     generate_exception_err(ctx, excp, 0);
2663 }
2664
2665 /* Floating point register moves. */
2666 static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2667 {
2668     if (ctx->hflags & MIPS_HFLAG_FRE) {
2669         generate_exception(ctx, EXCP_RI);
2670     }
2671     tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
2672 }
2673
2674 static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2675 {
2676     TCGv_i64 t64;
2677     if (ctx->hflags & MIPS_HFLAG_FRE) {
2678         generate_exception(ctx, EXCP_RI);
2679     }
2680     t64 = tcg_temp_new_i64();
2681     tcg_gen_extu_i32_i64(t64, t);
2682     tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
2683     tcg_temp_free_i64(t64);
2684 }
2685
2686 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2687 {
2688     if (ctx->hflags & MIPS_HFLAG_F64) {
2689         tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
2690     } else {
2691         gen_load_fpr32(ctx, t, reg | 1);
2692     }
2693 }
2694
2695 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2696 {
2697     if (ctx->hflags & MIPS_HFLAG_F64) {
2698         TCGv_i64 t64 = tcg_temp_new_i64();
2699         tcg_gen_extu_i32_i64(t64, t);
2700         tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
2701         tcg_temp_free_i64(t64);
2702     } else {
2703         gen_store_fpr32(ctx, t, reg | 1);
2704     }
2705 }
2706
2707 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2708 {
2709     if (ctx->hflags & MIPS_HFLAG_F64) {
2710         tcg_gen_mov_i64(t, fpu_f64[reg]);
2711     } else {
2712         tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
2713     }
2714 }
2715
2716 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2717 {
2718     if (ctx->hflags & MIPS_HFLAG_F64) {
2719         tcg_gen_mov_i64(fpu_f64[reg], t);
2720     } else {
2721         TCGv_i64 t0;
2722         tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
2723         t0 = tcg_temp_new_i64();
2724         tcg_gen_shri_i64(t0, t, 32);
2725         tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
2726         tcg_temp_free_i64(t0);
2727     }
2728 }
2729
2730 static inline int get_fp_bit (int cc)
2731 {
2732     if (cc)
2733         return 24 + cc;
2734     else
2735         return 23;
2736 }
2737
2738 /* Addresses computation */
2739 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
2740 {
2741     tcg_gen_add_tl(ret, arg0, arg1);
2742
2743 #if defined(TARGET_MIPS64)
2744     if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2745         tcg_gen_ext32s_i64(ret, ret);
2746     }
2747 #endif
2748 }
2749
2750 static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
2751                                     target_long ofs)
2752 {
2753     tcg_gen_addi_tl(ret, base, ofs);
2754
2755 #if defined(TARGET_MIPS64)
2756     if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2757         tcg_gen_ext32s_i64(ret, ret);
2758     }
2759 #endif
2760 }
2761
2762 /* Addresses computation (translation time) */
2763 static target_long addr_add(DisasContext *ctx, target_long base,
2764                             target_long offset)
2765 {
2766     target_long sum = base + offset;
2767
2768 #if defined(TARGET_MIPS64)
2769     if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2770         sum = (int32_t)sum;
2771     }
2772 #endif
2773     return sum;
2774 }
2775
2776 /* Sign-extract the low 32-bits to a target_long.  */
2777 static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
2778 {
2779 #if defined(TARGET_MIPS64)
2780     tcg_gen_ext32s_i64(ret, arg);
2781 #else
2782     tcg_gen_extrl_i64_i32(ret, arg);
2783 #endif
2784 }
2785
2786 /* Sign-extract the high 32-bits to a target_long.  */
2787 static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
2788 {
2789 #if defined(TARGET_MIPS64)
2790     tcg_gen_sari_i64(ret, arg, 32);
2791 #else
2792     tcg_gen_extrh_i64_i32(ret, arg);
2793 #endif
2794 }
2795
2796 static inline void check_cp0_enabled(DisasContext *ctx)
2797 {
2798     if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
2799         generate_exception_err(ctx, EXCP_CpU, 0);
2800 }
2801
2802 static inline void check_cp1_enabled(DisasContext *ctx)
2803 {
2804     if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
2805         generate_exception_err(ctx, EXCP_CpU, 1);
2806 }
2807
2808 /* Verify that the processor is running with COP1X instructions enabled.
2809    This is associated with the nabla symbol in the MIPS32 and MIPS64
2810    opcode tables.  */
2811
2812 static inline void check_cop1x(DisasContext *ctx)
2813 {
2814     if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
2815         generate_exception_end(ctx, EXCP_RI);
2816 }
2817
2818 /* Verify that the processor is running with 64-bit floating-point
2819    operations enabled.  */
2820
2821 static inline void check_cp1_64bitmode(DisasContext *ctx)
2822 {
2823     if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
2824         generate_exception_end(ctx, EXCP_RI);
2825 }
2826
2827 /*
2828  * Verify if floating point register is valid; an operation is not defined
2829  * if bit 0 of any register specification is set and the FR bit in the
2830  * Status register equals zero, since the register numbers specify an
2831  * even-odd pair of adjacent coprocessor general registers. When the FR bit
2832  * in the Status register equals one, both even and odd register numbers
2833  * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
2834  *
2835  * Multiple 64 bit wide registers can be checked by calling
2836  * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
2837  */
2838 static inline void check_cp1_registers(DisasContext *ctx, int regs)
2839 {
2840     if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
2841         generate_exception_end(ctx, EXCP_RI);
2842 }
2843
2844 /* Verify that the processor is running with DSP instructions enabled.
2845    This is enabled by CP0 Status register MX(24) bit.
2846  */
2847
2848 static inline void check_dsp(DisasContext *ctx)
2849 {
2850     if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
2851         if (ctx->insn_flags & ASE_DSP) {
2852             generate_exception_end(ctx, EXCP_DSPDIS);
2853         } else {
2854             generate_exception_end(ctx, EXCP_RI);
2855         }
2856     }
2857 }
2858
2859 static inline void check_dsp_r2(DisasContext *ctx)
2860 {
2861     if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
2862         if (ctx->insn_flags & ASE_DSP) {
2863             generate_exception_end(ctx, EXCP_DSPDIS);
2864         } else {
2865             generate_exception_end(ctx, EXCP_RI);
2866         }
2867     }
2868 }
2869
2870 static inline void check_dsp_r3(DisasContext *ctx)
2871 {
2872     if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
2873         if (ctx->insn_flags & ASE_DSP) {
2874             generate_exception_end(ctx, EXCP_DSPDIS);
2875         } else {
2876             generate_exception_end(ctx, EXCP_RI);
2877         }
2878     }
2879 }
2880
2881 /* This code generates a "reserved instruction" exception if the
2882    CPU does not support the instruction set corresponding to flags. */
2883 static inline void check_insn(DisasContext *ctx, uint64_t flags)
2884 {
2885     if (unlikely(!(ctx->insn_flags & flags))) {
2886         generate_exception_end(ctx, EXCP_RI);
2887     }
2888 }
2889
2890 /* This code generates a "reserved instruction" exception if the
2891    CPU has corresponding flag set which indicates that the instruction
2892    has been removed. */
2893 static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
2894 {
2895     if (unlikely(ctx->insn_flags & flags)) {
2896         generate_exception_end(ctx, EXCP_RI);
2897     }
2898 }
2899
2900 /*
2901  * The Linux kernel traps certain reserved instruction exceptions to
2902  * emulate the corresponding instructions. QEMU is the kernel in user
2903  * mode, so those traps are emulated by accepting the instructions.
2904  *
2905  * A reserved instruction exception is generated for flagged CPUs if
2906  * QEMU runs in system mode.
2907  */
2908 static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
2909 {
2910 #ifndef CONFIG_USER_ONLY
2911     check_insn_opc_removed(ctx, flags);
2912 #endif
2913 }
2914
2915 /* This code generates a "reserved instruction" exception if the
2916    CPU does not support 64-bit paired-single (PS) floating point data type */
2917 static inline void check_ps(DisasContext *ctx)
2918 {
2919     if (unlikely(!ctx->ps)) {
2920         generate_exception(ctx, EXCP_RI);
2921     }
2922     check_cp1_64bitmode(ctx);
2923 }
2924
2925 #ifdef TARGET_MIPS64
2926 /* This code generates a "reserved instruction" exception if 64-bit
2927    instructions are not enabled. */
2928 static inline void check_mips_64(DisasContext *ctx)
2929 {
2930     if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
2931         generate_exception_end(ctx, EXCP_RI);
2932 }
2933 #endif
2934
2935 #ifndef CONFIG_USER_ONLY
2936 static inline void check_mvh(DisasContext *ctx)
2937 {
2938     if (unlikely(!ctx->mvh)) {
2939         generate_exception(ctx, EXCP_RI);
2940     }
2941 }
2942 #endif
2943
2944 /*
2945  * This code generates a "reserved instruction" exception if the
2946  * Config5 XNP bit is set.
2947  */
2948 static inline void check_xnp(DisasContext *ctx)
2949 {
2950     if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
2951         generate_exception_end(ctx, EXCP_RI);
2952     }
2953 }
2954
2955 #ifndef CONFIG_USER_ONLY
2956 /*
2957  * This code generates a "reserved instruction" exception if the
2958  * Config3 PW bit is NOT set.
2959  */
2960 static inline void check_pw(DisasContext *ctx)
2961 {
2962     if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
2963         generate_exception_end(ctx, EXCP_RI);
2964     }
2965 }
2966 #endif
2967
2968 /*
2969  * This code generates a "reserved instruction" exception if the
2970  * Config3 MT bit is NOT set.
2971  */
2972 static inline void check_mt(DisasContext *ctx)
2973 {
2974     if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
2975         generate_exception_end(ctx, EXCP_RI);
2976     }
2977 }
2978
2979 #ifndef CONFIG_USER_ONLY
2980 /*
2981  * This code generates a "coprocessor unusable" exception if CP0 is not
2982  * available, and, if that is not the case, generates a "reserved instruction"
2983  * exception if the Config5 MT bit is NOT set. This is needed for availability
2984  * control of some of MT ASE instructions.
2985  */
2986 static inline void check_cp0_mt(DisasContext *ctx)
2987 {
2988     if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
2989         generate_exception_err(ctx, EXCP_CpU, 0);
2990     } else {
2991         if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
2992             generate_exception_err(ctx, EXCP_RI, 0);
2993         }
2994     }
2995 }
2996 #endif
2997
2998 /*
2999  * This code generates a "reserved instruction" exception if the
3000  * Config5 NMS bit is set.
3001  */
3002 static inline void check_nms(DisasContext *ctx)
3003 {
3004     if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
3005         generate_exception_end(ctx, EXCP_RI);
3006     }
3007 }
3008
3009 /*
3010  * This code generates a "reserved instruction" exception if the
3011  * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
3012  * Config2 TL, and Config5 L2C are unset.
3013  */
3014 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
3015 {
3016     if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
3017         !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
3018         !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
3019         !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
3020         !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
3021         !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))
3022     {
3023         generate_exception_end(ctx, EXCP_RI);
3024     }
3025 }
3026
3027 /*
3028  * This code generates a "reserved instruction" exception if the
3029  * Config5 EVA bit is NOT set.
3030  */
3031 static inline void check_eva(DisasContext *ctx)
3032 {
3033     if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
3034         generate_exception_end(ctx, EXCP_RI);
3035     }
3036 }
3037
3038
3039 /* Define small wrappers for gen_load_fpr* so that we have a uniform
3040    calling interface for 32 and 64-bit FPRs.  No sense in changing
3041    all callers for gen_load_fpr32 when we need the CTX parameter for
3042    this one use.  */
3043 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
3044 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
3045 #define FOP_CONDS(type, abs, fmt, ifmt, bits)                                 \
3046 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
3047                                                int ft, int fs, int cc)        \
3048 {                                                                             \
3049     TCGv_i##bits fp0 = tcg_temp_new_i##bits ();                               \
3050     TCGv_i##bits fp1 = tcg_temp_new_i##bits ();                               \
3051     switch (ifmt) {                                                           \
3052     case FMT_PS:                                                              \
3053         check_ps(ctx);                                                        \
3054         break;                                                                \
3055     case FMT_D:                                                               \
3056         if (abs) {                                                            \
3057             check_cop1x(ctx);                                                 \
3058         }                                                                     \
3059         check_cp1_registers(ctx, fs | ft);                                    \
3060         break;                                                                \
3061     case FMT_S:                                                               \
3062         if (abs) {                                                            \
3063             check_cop1x(ctx);                                                 \
3064         }                                                                     \
3065         break;                                                                \
3066     }                                                                         \
3067     gen_ldcmp_fpr##bits (ctx, fp0, fs);                                       \
3068     gen_ldcmp_fpr##bits (ctx, fp1, ft);                                       \
3069     switch (n) {                                                              \
3070     case  0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc);    break;\
3071     case  1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc);   break;\
3072     case  2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc);   break;\
3073     case  3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc);  break;\
3074     case  4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc);  break;\
3075     case  5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc);  break;\
3076     case  6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc);  break;\
3077     case  7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc);  break;\
3078     case  8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc);   break;\
3079     case  9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
3080     case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc);  break;\
3081     case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc);  break;\
3082     case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc);   break;\
3083     case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc);  break;\
3084     case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc);   break;\
3085     case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc);  break;\
3086     default: abort();                                                         \
3087     }                                                                         \
3088     tcg_temp_free_i##bits (fp0);                                              \
3089     tcg_temp_free_i##bits (fp1);                                              \
3090 }
3091
3092 FOP_CONDS(, 0, d, FMT_D, 64)
3093 FOP_CONDS(abs, 1, d, FMT_D, 64)
3094 FOP_CONDS(, 0, s, FMT_S, 32)
3095 FOP_CONDS(abs, 1, s, FMT_S, 32)
3096 FOP_CONDS(, 0, ps, FMT_PS, 64)
3097 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
3098 #undef FOP_CONDS
3099
3100 #define FOP_CONDNS(fmt, ifmt, bits, STORE)                              \
3101 static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n,        \
3102                                       int ft, int fs, int fd)           \
3103 {                                                                       \
3104     TCGv_i ## bits fp0 = tcg_temp_new_i ## bits();                      \
3105     TCGv_i ## bits fp1 = tcg_temp_new_i ## bits();                      \
3106     if (ifmt == FMT_D) {                                                \
3107         check_cp1_registers(ctx, fs | ft | fd);                         \
3108     }                                                                   \
3109     gen_ldcmp_fpr ## bits(ctx, fp0, fs);                                \
3110     gen_ldcmp_fpr ## bits(ctx, fp1, ft);                                \
3111     switch (n) {                                                        \
3112     case  0:                                                            \
3113         gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1);       \
3114         break;                                                          \
3115     case  1:                                                            \
3116         gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1);       \
3117         break;                                                          \
3118     case  2:                                                            \
3119         gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1);       \
3120         break;                                                          \
3121     case  3:                                                            \
3122         gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1);      \
3123         break;                                                          \
3124     case  4:                                                            \
3125         gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1);       \
3126         break;                                                          \
3127     case  5:                                                            \
3128         gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1);      \
3129         break;                                                          \
3130     case  6:                                                            \
3131         gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1);       \
3132         break;                                                          \
3133     case  7:                                                            \
3134         gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1);      \
3135         break;                                                          \
3136     case  8:                                                            \
3137         gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1);      \
3138         break;                                                          \
3139     case  9:                                                            \
3140         gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1);      \
3141         break;                                                          \
3142     case 10:                                                            \
3143         gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1);      \
3144         break;                                                          \
3145     case 11:                                                            \
3146         gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1);     \
3147         break;                                                          \
3148     case 12:                                                            \
3149         gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1);      \
3150         break;                                                          \
3151     case 13:                                                            \
3152         gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1);     \
3153         break;                                                          \
3154     case 14:                                                            \
3155         gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1);      \
3156         break;                                                          \
3157     case 15:                                                            \
3158         gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1);     \
3159         break;                                                          \
3160     case 17:                                                            \
3161         gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1);       \
3162         break;                                                          \
3163     case 18:                                                            \
3164         gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1);      \
3165         break;                                                          \
3166     case 19:                                                            \
3167         gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1);       \
3168         break;                                                          \
3169     case 25:                                                            \
3170         gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1);      \
3171         break;                                                          \
3172     case 26:                                                            \
3173         gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1);     \
3174         break;                                                          \
3175     case 27:                                                            \
3176         gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1);      \
3177         break;                                                          \
3178     default:                                                            \
3179         abort();                                                        \
3180     }                                                                   \
3181     STORE;                                                              \
3182     tcg_temp_free_i ## bits (fp0);                                      \
3183     tcg_temp_free_i ## bits (fp1);                                      \
3184 }
3185
3186 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
3187 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3188 #undef FOP_CONDNS
3189 #undef gen_ldcmp_fpr32
3190 #undef gen_ldcmp_fpr64
3191
3192 /* load/store instructions. */
3193 #ifdef CONFIG_USER_ONLY
3194 #define OP_LD_ATOMIC(insn,fname)                                           \
3195 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
3196                                 DisasContext *ctx)                         \
3197 {                                                                          \
3198     TCGv t0 = tcg_temp_new();                                              \
3199     tcg_gen_mov_tl(t0, arg1);                                              \
3200     tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
3201     tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));                \
3202     tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval));                \
3203     tcg_temp_free(t0);                                                     \
3204 }
3205 #else
3206 #define OP_LD_ATOMIC(insn,fname)                                           \
3207 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
3208                                 DisasContext *ctx)                         \
3209 {                                                                          \
3210     gen_helper_1e1i(insn, ret, arg1, mem_idx);                             \
3211 }
3212 #endif
3213 OP_LD_ATOMIC(ll,ld32s);
3214 #if defined(TARGET_MIPS64)
3215 OP_LD_ATOMIC(lld,ld64);
3216 #endif
3217 #undef OP_LD_ATOMIC
3218
3219 #ifdef CONFIG_USER_ONLY
3220 #define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
3221 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx,   \
3222                                 DisasContext *ctx)                           \
3223 {                                                                            \
3224     TCGv t0 = tcg_temp_new();                                                \
3225     TCGLabel *l1 = gen_new_label();                                          \
3226     TCGLabel *l2 = gen_new_label();                                          \
3227                                                                              \
3228     tcg_gen_andi_tl(t0, arg2, almask);                                       \
3229     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);                              \
3230     tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));          \
3231     generate_exception(ctx, EXCP_AdES);                                      \
3232     gen_set_label(l1);                                                       \
3233     tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));                  \
3234     tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2);                            \
3235     tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20));                        \
3236     tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg));                   \
3237     tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval));              \
3238     generate_exception_end(ctx, EXCP_SC);                                    \
3239     gen_set_label(l2);                                                       \
3240     tcg_gen_movi_tl(t0, 0);                                                  \
3241     gen_store_gpr(t0, rt);                                                   \
3242     tcg_temp_free(t0);                                                       \
3243 }
3244 #else
3245 #define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
3246 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx,   \
3247                                 DisasContext *ctx)                           \
3248 {                                                                            \
3249     TCGv t0 = tcg_temp_new();                                                \
3250     gen_helper_1e2i(insn, t0, arg1, arg2, mem_idx);                          \
3251     gen_store_gpr(t0, rt);                                                   \
3252     tcg_temp_free(t0);                                                       \
3253 }
3254 #endif
3255 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
3256 #if defined(TARGET_MIPS64)
3257 OP_ST_ATOMIC(scd,st64,ld64,0x7);
3258 #endif
3259 #undef OP_ST_ATOMIC
3260
3261 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
3262                                   int base, int offset)
3263 {
3264     if (base == 0) {
3265         tcg_gen_movi_tl(addr, offset);
3266     } else if (offset == 0) {
3267         gen_load_gpr(addr, base);
3268     } else {
3269         tcg_gen_movi_tl(addr, offset);
3270         gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
3271     }
3272 }
3273
3274 static target_ulong pc_relative_pc (DisasContext *ctx)
3275 {
3276     target_ulong pc = ctx->base.pc_next;
3277
3278     if (ctx->hflags & MIPS_HFLAG_BMASK) {
3279         int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
3280
3281         pc -= branch_bytes;
3282     }
3283
3284     pc &= ~(target_ulong)3;
3285     return pc;
3286 }
3287
3288 /* Load */
3289 static void gen_ld(DisasContext *ctx, uint32_t opc,
3290                    int rt, int base, int offset)
3291 {
3292     TCGv t0, t1, t2;
3293     int mem_idx = ctx->mem_idx;
3294
3295     if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
3296         /* Loongson CPU uses a load to zero register for prefetch.
3297            We emulate it as a NOP. On other CPU we must perform the
3298            actual memory access. */
3299         return;
3300     }
3301
3302     t0 = tcg_temp_new();
3303     gen_base_offset_addr(ctx, t0, base, offset);
3304
3305     switch (opc) {
3306 #if defined(TARGET_MIPS64)
3307     case OPC_LWU:
3308         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
3309                            ctx->default_tcg_memop_mask);
3310         gen_store_gpr(t0, rt);
3311         break;
3312     case OPC_LD:
3313         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
3314                            ctx->default_tcg_memop_mask);
3315         gen_store_gpr(t0, rt);
3316         break;
3317     case OPC_LLD:
3318     case R6_OPC_LLD:
3319         op_ld_lld(t0, t0, mem_idx, ctx);
3320         gen_store_gpr(t0, rt);
3321         break;
3322     case OPC_LDL:
3323         t1 = tcg_temp_new();
3324         /* Do a byte access to possibly trigger a page
3325            fault with the unaligned address.  */
3326         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3327         tcg_gen_andi_tl(t1, t0, 7);
3328 #ifndef TARGET_WORDS_BIGENDIAN
3329         tcg_gen_xori_tl(t1, t1, 7);
3330 #endif
3331         tcg_gen_shli_tl(t1, t1, 3);
3332         tcg_gen_andi_tl(t0, t0, ~7);
3333         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3334         tcg_gen_shl_tl(t0, t0, t1);
3335         t2 = tcg_const_tl(-1);
3336         tcg_gen_shl_tl(t2, t2, t1);
3337         gen_load_gpr(t1, rt);
3338         tcg_gen_andc_tl(t1, t1, t2);
3339         tcg_temp_free(t2);
3340         tcg_gen_or_tl(t0, t0, t1);
3341         tcg_temp_free(t1);
3342         gen_store_gpr(t0, rt);
3343         break;
3344     case OPC_LDR:
3345         t1 = tcg_temp_new();
3346         /* Do a byte access to possibly trigger a page
3347            fault with the unaligned address.  */
3348         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3349         tcg_gen_andi_tl(t1, t0, 7);
3350 #ifdef TARGET_WORDS_BIGENDIAN
3351         tcg_gen_xori_tl(t1, t1, 7);
3352 #endif
3353         tcg_gen_shli_tl(t1, t1, 3);
3354         tcg_gen_andi_tl(t0, t0, ~7);
3355         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3356         tcg_gen_shr_tl(t0, t0, t1);
3357         tcg_gen_xori_tl(t1, t1, 63);
3358         t2 = tcg_const_tl(0xfffffffffffffffeull);
3359         tcg_gen_shl_tl(t2, t2, t1);
3360         gen_load_gpr(t1, rt);
3361         tcg_gen_and_tl(t1, t1, t2);
3362         tcg_temp_free(t2);
3363         tcg_gen_or_tl(t0, t0, t1);
3364         tcg_temp_free(t1);
3365         gen_store_gpr(t0, rt);
3366         break;
3367     case OPC_LDPC:
3368         t1 = tcg_const_tl(pc_relative_pc(ctx));
3369         gen_op_addr_add(ctx, t0, t0, t1);
3370         tcg_temp_free(t1);
3371         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3372         gen_store_gpr(t0, rt);
3373         break;
3374 #endif
3375     case OPC_LWPC:
3376         t1 = tcg_const_tl(pc_relative_pc(ctx));
3377         gen_op_addr_add(ctx, t0, t0, t1);
3378         tcg_temp_free(t1);
3379         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
3380         gen_store_gpr(t0, rt);
3381         break;
3382     case OPC_LWE:
3383         mem_idx = MIPS_HFLAG_UM;
3384         /* fall through */
3385     case OPC_LW:
3386         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
3387                            ctx->default_tcg_memop_mask);
3388         gen_store_gpr(t0, rt);
3389         break;
3390     case OPC_LHE:
3391         mem_idx = MIPS_HFLAG_UM;
3392         /* fall through */
3393     case OPC_LH:
3394         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
3395                            ctx->default_tcg_memop_mask);
3396         gen_store_gpr(t0, rt);
3397         break;
3398     case OPC_LHUE:
3399         mem_idx = MIPS_HFLAG_UM;
3400         /* fall through */
3401     case OPC_LHU:
3402         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
3403                            ctx->default_tcg_memop_mask);
3404         gen_store_gpr(t0, rt);
3405         break;
3406     case OPC_LBE:
3407         mem_idx = MIPS_HFLAG_UM;
3408         /* fall through */
3409     case OPC_LB:
3410         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
3411         gen_store_gpr(t0, rt);
3412         break;
3413     case OPC_LBUE:
3414         mem_idx = MIPS_HFLAG_UM;
3415         /* fall through */
3416     case OPC_LBU:
3417         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
3418         gen_store_gpr(t0, rt);
3419         break;
3420     case OPC_LWLE:
3421         mem_idx = MIPS_HFLAG_UM;
3422         /* fall through */
3423     case OPC_LWL:
3424         t1 = tcg_temp_new();
3425         /* Do a byte access to possibly trigger a page
3426            fault with the unaligned address.  */
3427         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3428         tcg_gen_andi_tl(t1, t0, 3);
3429 #ifndef TARGET_WORDS_BIGENDIAN
3430         tcg_gen_xori_tl(t1, t1, 3);
3431 #endif
3432         tcg_gen_shli_tl(t1, t1, 3);
3433         tcg_gen_andi_tl(t0, t0, ~3);
3434         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3435         tcg_gen_shl_tl(t0, t0, t1);
3436         t2 = tcg_const_tl(-1);
3437         tcg_gen_shl_tl(t2, t2, t1);
3438         gen_load_gpr(t1, rt);
3439         tcg_gen_andc_tl(t1, t1, t2);
3440         tcg_temp_free(t2);
3441         tcg_gen_or_tl(t0, t0, t1);
3442         tcg_temp_free(t1);
3443         tcg_gen_ext32s_tl(t0, t0);
3444         gen_store_gpr(t0, rt);
3445         break;
3446     case OPC_LWRE:
3447         mem_idx = MIPS_HFLAG_UM;
3448         /* fall through */
3449     case OPC_LWR:
3450         t1 = tcg_temp_new();
3451         /* Do a byte access to possibly trigger a page
3452            fault with the unaligned address.  */
3453         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3454         tcg_gen_andi_tl(t1, t0, 3);
3455 #ifdef TARGET_WORDS_BIGENDIAN
3456         tcg_gen_xori_tl(t1, t1, 3);
3457 #endif
3458         tcg_gen_shli_tl(t1, t1, 3);
3459         tcg_gen_andi_tl(t0, t0, ~3);
3460         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3461         tcg_gen_shr_tl(t0, t0, t1);
3462         tcg_gen_xori_tl(t1, t1, 31);
3463         t2 = tcg_const_tl(0xfffffffeull);
3464         tcg_gen_shl_tl(t2, t2, t1);
3465         gen_load_gpr(t1, rt);
3466         tcg_gen_and_tl(t1, t1, t2);
3467         tcg_temp_free(t2);
3468         tcg_gen_or_tl(t0, t0, t1);
3469         tcg_temp_free(t1);
3470         tcg_gen_ext32s_tl(t0, t0);
3471         gen_store_gpr(t0, rt);
3472         break;
3473     case OPC_LLE:
3474         mem_idx = MIPS_HFLAG_UM;
3475         /* fall through */
3476     case OPC_LL:
3477     case R6_OPC_LL:
3478         op_ld_ll(t0, t0, mem_idx, ctx);
3479         gen_store_gpr(t0, rt);
3480         break;
3481     }
3482     tcg_temp_free(t0);
3483 }
3484
3485 static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
3486                     uint32_t reg1, uint32_t reg2)
3487 {
3488     TCGv taddr = tcg_temp_new();
3489     TCGv_i64 tval = tcg_temp_new_i64();
3490     TCGv tmp1 = tcg_temp_new();
3491     TCGv tmp2 = tcg_temp_new();
3492
3493     gen_base_offset_addr(ctx, taddr, base, offset);
3494     tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx);
3495 #ifdef TARGET_WORDS_BIGENDIAN
3496     tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
3497 #else
3498     tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
3499 #endif
3500     gen_store_gpr(tmp1, reg1);
3501     tcg_temp_free(tmp1);
3502     gen_store_gpr(tmp2, reg2);
3503     tcg_temp_free(tmp2);
3504     tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3505     tcg_temp_free_i64(tval);
3506     tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr));
3507     tcg_temp_free(taddr);
3508 }
3509
3510 /* Store */
3511 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
3512                     int base, int offset)
3513 {
3514     TCGv t0 = tcg_temp_new();
3515     TCGv t1 = tcg_temp_new();
3516     int mem_idx = ctx->mem_idx;
3517
3518     gen_base_offset_addr(ctx, t0, base, offset);
3519     gen_load_gpr(t1, rt);
3520     switch (opc) {
3521 #if defined(TARGET_MIPS64)
3522     case OPC_SD:
3523         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
3524                            ctx->default_tcg_memop_mask);
3525         break;
3526     case OPC_SDL:
3527         gen_helper_0e2i(sdl, t1, t0, mem_idx);
3528         break;
3529     case OPC_SDR:
3530         gen_helper_0e2i(sdr, t1, t0, mem_idx);
3531         break;
3532 #endif
3533     case OPC_SWE:
3534         mem_idx = MIPS_HFLAG_UM;
3535         /* fall through */
3536     case OPC_SW:
3537         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
3538                            ctx->default_tcg_memop_mask);
3539         break;
3540     case OPC_SHE:
3541         mem_idx = MIPS_HFLAG_UM;
3542         /* fall through */
3543     case OPC_SH:
3544         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
3545                            ctx->default_tcg_memop_mask);
3546         break;
3547     case OPC_SBE:
3548         mem_idx = MIPS_HFLAG_UM;
3549         /* fall through */
3550     case OPC_SB:
3551         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
3552         break;
3553     case OPC_SWLE:
3554         mem_idx = MIPS_HFLAG_UM;
3555         /* fall through */
3556     case OPC_SWL:
3557         gen_helper_0e2i(swl, t1, t0, mem_idx);
3558         break;
3559     case OPC_SWRE:
3560         mem_idx = MIPS_HFLAG_UM;
3561         /* fall through */
3562     case OPC_SWR:
3563         gen_helper_0e2i(swr, t1, t0, mem_idx);
3564         break;
3565     }
3566     tcg_temp_free(t0);
3567     tcg_temp_free(t1);
3568 }
3569
3570
3571 /* Store conditional */
3572 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
3573                          int base, int16_t offset)
3574 {
3575     TCGv t0, t1;
3576     int mem_idx = ctx->mem_idx;
3577
3578 #ifdef CONFIG_USER_ONLY
3579     t0 = tcg_temp_local_new();
3580     t1 = tcg_temp_local_new();
3581 #else
3582     t0 = tcg_temp_new();
3583     t1 = tcg_temp_new();
3584 #endif
3585     gen_base_offset_addr(ctx, t0, base, offset);
3586     gen_load_gpr(t1, rt);
3587     switch (opc) {
3588 #if defined(TARGET_MIPS64)
3589     case OPC_SCD:
3590     case R6_OPC_SCD:
3591         op_st_scd(t1, t0, rt, mem_idx, ctx);
3592         break;
3593 #endif
3594     case OPC_SCE:
3595         mem_idx = MIPS_HFLAG_UM;
3596         /* fall through */
3597     case OPC_SC:
3598     case R6_OPC_SC:
3599         op_st_sc(t1, t0, rt, mem_idx, ctx);
3600         break;
3601     }
3602     tcg_temp_free(t1);
3603     tcg_temp_free(t0);
3604 }
3605
3606 static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
3607                     uint32_t reg1, uint32_t reg2)
3608 {
3609     TCGv taddr = tcg_temp_local_new();
3610     TCGv lladdr = tcg_temp_local_new();
3611     TCGv_i64 tval = tcg_temp_new_i64();
3612     TCGv_i64 llval = tcg_temp_new_i64();
3613     TCGv_i64 val = tcg_temp_new_i64();
3614     TCGv tmp1 = tcg_temp_new();
3615     TCGv tmp2 = tcg_temp_new();
3616     TCGLabel *lab_fail = gen_new_label();
3617     TCGLabel *lab_done = gen_new_label();
3618
3619     gen_base_offset_addr(ctx, taddr, base, offset);
3620
3621     tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3622     tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail);
3623
3624     gen_load_gpr(tmp1, reg1);
3625     gen_load_gpr(tmp2, reg2);
3626
3627 #ifdef TARGET_WORDS_BIGENDIAN
3628     tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
3629 #else
3630     tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
3631 #endif
3632
3633     tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3634     tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
3635                                ctx->mem_idx, MO_64);
3636     if (reg1 != 0) {
3637         tcg_gen_movi_tl(cpu_gpr[reg1], 1);
3638     }
3639     tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done);
3640
3641     gen_set_label(lab_fail);
3642
3643     if (reg1 != 0) {
3644         tcg_gen_movi_tl(cpu_gpr[reg1], 0);
3645     }
3646     gen_set_label(lab_done);
3647     tcg_gen_movi_tl(lladdr, -1);
3648     tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3649 }
3650
3651 /* Load and store */
3652 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
3653                           TCGv t0)
3654 {
3655     /* Don't do NOP if destination is zero: we must perform the actual
3656        memory access. */
3657     switch (opc) {
3658     case OPC_LWC1:
3659         {
3660             TCGv_i32 fp0 = tcg_temp_new_i32();
3661             tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
3662                                 ctx->default_tcg_memop_mask);
3663             gen_store_fpr32(ctx, fp0, ft);
3664             tcg_temp_free_i32(fp0);
3665         }
3666         break;
3667     case OPC_SWC1:
3668         {
3669             TCGv_i32 fp0 = tcg_temp_new_i32();
3670             gen_load_fpr32(ctx, fp0, ft);
3671             tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
3672                                 ctx->default_tcg_memop_mask);
3673             tcg_temp_free_i32(fp0);
3674         }
3675         break;
3676     case OPC_LDC1:
3677         {
3678             TCGv_i64 fp0 = tcg_temp_new_i64();
3679             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3680                                 ctx->default_tcg_memop_mask);
3681             gen_store_fpr64(ctx, fp0, ft);
3682             tcg_temp_free_i64(fp0);
3683         }
3684         break;
3685     case OPC_SDC1:
3686         {
3687             TCGv_i64 fp0 = tcg_temp_new_i64();
3688             gen_load_fpr64(ctx, fp0, ft);
3689             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3690                                 ctx->default_tcg_memop_mask);
3691             tcg_temp_free_i64(fp0);
3692         }
3693         break;
3694     default:
3695         MIPS_INVAL("flt_ldst");
3696         generate_exception_end(ctx, EXCP_RI);
3697         break;
3698     }
3699 }
3700
3701 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
3702                           int rs, int16_t imm)
3703 {
3704     TCGv t0 = tcg_temp_new();
3705
3706     if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3707         check_cp1_enabled(ctx);
3708         switch (op) {
3709         case OPC_LDC1:
3710         case OPC_SDC1:
3711             check_insn(ctx, ISA_MIPS2);
3712             /* Fallthrough */
3713         default:
3714             gen_base_offset_addr(ctx, t0, rs, imm);
3715             gen_flt_ldst(ctx, op, rt, t0);
3716         }
3717     } else {
3718         generate_exception_err(ctx, EXCP_CpU, 1);
3719     }
3720     tcg_temp_free(t0);
3721 }
3722
3723 /* Arithmetic with immediate operand */
3724 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
3725                           int rt, int rs, int imm)
3726 {
3727     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3728
3729     if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
3730         /* If no destination, treat it as a NOP.
3731            For addi, we must generate the overflow exception when needed. */
3732         return;
3733     }
3734     switch (opc) {
3735     case OPC_ADDI:
3736         {
3737             TCGv t0 = tcg_temp_local_new();
3738             TCGv t1 = tcg_temp_new();
3739             TCGv t2 = tcg_temp_new();
3740             TCGLabel *l1 = gen_new_label();
3741
3742             gen_load_gpr(t1, rs);
3743             tcg_gen_addi_tl(t0, t1, uimm);
3744             tcg_gen_ext32s_tl(t0, t0);
3745
3746             tcg_gen_xori_tl(t1, t1, ~uimm);
3747             tcg_gen_xori_tl(t2, t0, uimm);
3748             tcg_gen_and_tl(t1, t1, t2);
3749             tcg_temp_free(t2);
3750             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3751             tcg_temp_free(t1);
3752             /* operands of same sign, result different sign */
3753             generate_exception(ctx, EXCP_OVERFLOW);
3754             gen_set_label(l1);
3755             tcg_gen_ext32s_tl(t0, t0);
3756             gen_store_gpr(t0, rt);
3757             tcg_temp_free(t0);
3758         }
3759         break;
3760     case OPC_ADDIU:
3761         if (rs != 0) {
3762             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3763             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3764         } else {
3765             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3766         }
3767         break;
3768 #if defined(TARGET_MIPS64)
3769     case OPC_DADDI:
3770         {
3771             TCGv t0 = tcg_temp_local_new();
3772             TCGv t1 = tcg_temp_new();
3773             TCGv t2 = tcg_temp_new();
3774             TCGLabel *l1 = gen_new_label();
3775
3776             gen_load_gpr(t1, rs);
3777             tcg_gen_addi_tl(t0, t1, uimm);
3778
3779             tcg_gen_xori_tl(t1, t1, ~uimm);
3780             tcg_gen_xori_tl(t2, t0, uimm);
3781             tcg_gen_and_tl(t1, t1, t2);
3782             tcg_temp_free(t2);
3783             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3784             tcg_temp_free(t1);
3785             /* operands of same sign, result different sign */
3786             generate_exception(ctx, EXCP_OVERFLOW);
3787             gen_set_label(l1);
3788             gen_store_gpr(t0, rt);
3789             tcg_temp_free(t0);
3790         }
3791         break;
3792     case OPC_DADDIU:
3793         if (rs != 0) {
3794             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3795         } else {
3796             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3797         }
3798         break;
3799 #endif
3800     }
3801 }
3802
3803 /* Logic with immediate operand */
3804 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
3805                           int rt, int rs, int16_t imm)
3806 {
3807     target_ulong uimm;
3808
3809     if (rt == 0) {
3810         /* If no destination, treat it as a NOP. */
3811         return;
3812     }
3813     uimm = (uint16_t)imm;
3814     switch (opc) {
3815     case OPC_ANDI:
3816         if (likely(rs != 0))
3817             tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3818         else
3819             tcg_gen_movi_tl(cpu_gpr[rt], 0);
3820         break;
3821     case OPC_ORI:
3822         if (rs != 0)
3823             tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3824         else
3825             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3826         break;
3827     case OPC_XORI:
3828         if (likely(rs != 0))
3829             tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3830         else
3831             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3832         break;
3833     case OPC_LUI:
3834         if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
3835             /* OPC_AUI */
3836             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
3837             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3838         } else {
3839             tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
3840         }
3841         break;
3842
3843     default:
3844         break;
3845     }
3846 }
3847
3848 /* Set on less than with immediate operand */
3849 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
3850                         int rt, int rs, int16_t imm)
3851 {
3852     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3853     TCGv t0;
3854
3855     if (rt == 0) {
3856         /* If no destination, treat it as a NOP. */
3857         return;
3858     }
3859     t0 = tcg_temp_new();
3860     gen_load_gpr(t0, rs);
3861     switch (opc) {
3862     case OPC_SLTI:
3863         tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
3864         break;
3865     case OPC_SLTIU:
3866         tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
3867         break;
3868     }
3869     tcg_temp_free(t0);
3870 }
3871
3872 /* Shifts with immediate operand */
3873 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
3874                           int rt, int rs, int16_t imm)
3875 {
3876     target_ulong uimm = ((uint16_t)imm) & 0x1f;
3877     TCGv t0;
3878
3879     if (rt == 0) {
3880         /* If no destination, treat it as a NOP. */
3881         return;
3882     }
3883
3884     t0 = tcg_temp_new();
3885     gen_load_gpr(t0, rs);
3886     switch (opc) {
3887     case OPC_SLL:
3888         tcg_gen_shli_tl(t0, t0, uimm);
3889         tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3890         break;
3891     case OPC_SRA:
3892         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
3893         break;
3894     case OPC_SRL:
3895         if (uimm != 0) {
3896             tcg_gen_ext32u_tl(t0, t0);
3897             tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3898         } else {
3899             tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3900         }
3901         break;
3902     case OPC_ROTR:
3903         if (uimm != 0) {
3904             TCGv_i32 t1 = tcg_temp_new_i32();
3905
3906             tcg_gen_trunc_tl_i32(t1, t0);
3907             tcg_gen_rotri_i32(t1, t1, uimm);
3908             tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
3909             tcg_temp_free_i32(t1);
3910         } else {
3911             tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3912         }
3913         break;
3914 #if defined(TARGET_MIPS64)
3915     case OPC_DSLL:
3916         tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
3917         break;
3918     case OPC_DSRA:
3919         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
3920         break;
3921     case OPC_DSRL:
3922         tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3923         break;
3924     case OPC_DROTR:
3925         if (uimm != 0) {
3926             tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3927         } else {
3928             tcg_gen_mov_tl(cpu_gpr[rt], t0);
3929         }
3930         break;
3931     case OPC_DSLL32:
3932         tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
3933         break;
3934     case OPC_DSRA32:
3935         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
3936         break;
3937     case OPC_DSRL32:
3938         tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
3939         break;
3940     case OPC_DROTR32:
3941         tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
3942         break;
3943 #endif
3944     }
3945     tcg_temp_free(t0);
3946 }
3947
3948 /* Arithmetic */
3949 static void gen_arith(DisasContext *ctx, uint32_t opc,
3950                       int rd, int rs, int rt)
3951 {
3952     if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
3953        && opc != OPC_DADD && opc != OPC_DSUB) {
3954         /* If no destination, treat it as a NOP.
3955            For add & sub, we must generate the overflow exception when needed. */
3956         return;
3957     }
3958
3959     switch (opc) {
3960     case OPC_ADD:
3961         {
3962             TCGv t0 = tcg_temp_local_new();
3963             TCGv t1 = tcg_temp_new();
3964             TCGv t2 = tcg_temp_new();
3965             TCGLabel *l1 = gen_new_label();
3966
3967             gen_load_gpr(t1, rs);
3968             gen_load_gpr(t2, rt);
3969             tcg_gen_add_tl(t0, t1, t2);
3970             tcg_gen_ext32s_tl(t0, t0);
3971             tcg_gen_xor_tl(t1, t1, t2);
3972             tcg_gen_xor_tl(t2, t0, t2);
3973             tcg_gen_andc_tl(t1, t2, t1);
3974             tcg_temp_free(t2);
3975             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3976             tcg_temp_free(t1);
3977             /* operands of same sign, result different sign */
3978             generate_exception(ctx, EXCP_OVERFLOW);
3979             gen_set_label(l1);
3980             gen_store_gpr(t0, rd);
3981             tcg_temp_free(t0);
3982         }
3983         break;
3984     case OPC_ADDU:
3985         if (rs != 0 && rt != 0) {
3986             tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3987             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3988         } else if (rs == 0 && rt != 0) {
3989             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3990         } else if (rs != 0 && rt == 0) {
3991             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3992         } else {
3993             tcg_gen_movi_tl(cpu_gpr[rd], 0);
3994         }
3995         break;
3996     case OPC_SUB:
3997         {
3998             TCGv t0 = tcg_temp_local_new();
3999             TCGv t1 = tcg_temp_new();
4000             TCGv t2 = tcg_temp_new();
4001             TCGLabel *l1 = gen_new_label();
4002
4003             gen_load_gpr(t1, rs);
4004             gen_load_gpr(t2, rt);
4005             tcg_gen_sub_tl(t0, t1, t2);
4006             tcg_gen_ext32s_tl(t0, t0);
4007             tcg_gen_xor_tl(t2, t1, t2);
4008             tcg_gen_xor_tl(t1, t0, t1);
4009             tcg_gen_and_tl(t1, t1, t2);
4010             tcg_temp_free(t2);
4011             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4012             tcg_temp_free(t1);
4013             /* operands of different sign, first operand and result different sign */
4014             generate_exception(ctx, EXCP_OVERFLOW);
4015             gen_set_label(l1);
4016             gen_store_gpr(t0, rd);
4017             tcg_temp_free(t0);
4018         }
4019         break;
4020     case OPC_SUBU:
4021         if (rs != 0 && rt != 0) {
4022             tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4023             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4024         } else if (rs == 0 && rt != 0) {
4025             tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4026             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4027         } else if (rs != 0 && rt == 0) {
4028             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4029         } else {
4030             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4031         }
4032         break;
4033 #if defined(TARGET_MIPS64)
4034     case OPC_DADD:
4035         {
4036             TCGv t0 = tcg_temp_local_new();
4037             TCGv t1 = tcg_temp_new();
4038             TCGv t2 = tcg_temp_new();
4039             TCGLabel *l1 = gen_new_label();
4040
4041             gen_load_gpr(t1, rs);
4042             gen_load_gpr(t2, rt);
4043             tcg_gen_add_tl(t0, t1, t2);
4044             tcg_gen_xor_tl(t1, t1, t2);
4045             tcg_gen_xor_tl(t2, t0, t2);
4046             tcg_gen_andc_tl(t1, t2, t1);
4047             tcg_temp_free(t2);
4048             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4049             tcg_temp_free(t1);
4050             /* operands of same sign, result different sign */
4051             generate_exception(ctx, EXCP_OVERFLOW);
4052             gen_set_label(l1);
4053             gen_store_gpr(t0, rd);
4054             tcg_temp_free(t0);
4055         }
4056         break;
4057     case OPC_DADDU:
4058         if (rs != 0 && rt != 0) {
4059             tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4060         } else if (rs == 0 && rt != 0) {
4061             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4062         } else if (rs != 0 && rt == 0) {
4063             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4064         } else {
4065             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4066         }
4067         break;
4068     case OPC_DSUB:
4069         {
4070             TCGv t0 = tcg_temp_local_new();
4071             TCGv t1 = tcg_temp_new();
4072             TCGv t2 = tcg_temp_new();
4073             TCGLabel *l1 = gen_new_label();
4074
4075             gen_load_gpr(t1, rs);
4076             gen_load_gpr(t2, rt);
4077             tcg_gen_sub_tl(t0, t1, t2);
4078             tcg_gen_xor_tl(t2, t1, t2);
4079             tcg_gen_xor_tl(t1, t0, t1);
4080             tcg_gen_and_tl(t1, t1, t2);
4081             tcg_temp_free(t2);
4082             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4083             tcg_temp_free(t1);
4084             /* operands of different sign, first operand and result different sign */
4085             generate_exception(ctx, EXCP_OVERFLOW);
4086             gen_set_label(l1);
4087             gen_store_gpr(t0, rd);
4088             tcg_temp_free(t0);
4089         }
4090         break;
4091     case OPC_DSUBU:
4092         if (rs != 0 && rt != 0) {
4093             tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4094         } else if (rs == 0 && rt != 0) {
4095             tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4096         } else if (rs != 0 && rt == 0) {
4097             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4098         } else {
4099             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4100         }
4101         break;
4102 #endif
4103     case OPC_MUL:
4104         if (likely(rs != 0 && rt != 0)) {
4105             tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4106             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4107         } else {
4108             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4109         }
4110         break;
4111     }
4112 }
4113
4114 /* Conditional move */
4115 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
4116                           int rd, int rs, int rt)
4117 {
4118     TCGv t0, t1, t2;
4119
4120     if (rd == 0) {
4121         /* If no destination, treat it as a NOP. */
4122         return;
4123     }
4124
4125     t0 = tcg_temp_new();
4126     gen_load_gpr(t0, rt);
4127     t1 = tcg_const_tl(0);
4128     t2 = tcg_temp_new();
4129     gen_load_gpr(t2, rs);
4130     switch (opc) {
4131     case OPC_MOVN:
4132         tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4133         break;
4134     case OPC_MOVZ:
4135         tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4136         break;
4137     case OPC_SELNEZ:
4138         tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
4139         break;
4140     case OPC_SELEQZ:
4141         tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
4142         break;
4143     }
4144     tcg_temp_free(t2);
4145     tcg_temp_free(t1);
4146     tcg_temp_free(t0);
4147 }
4148
4149 /* Logic */
4150 static void gen_logic(DisasContext *ctx, uint32_t opc,
4151                       int rd, int rs, int rt)
4152 {
4153     if (rd == 0) {
4154         /* If no destination, treat it as a NOP. */
4155         return;
4156     }
4157
4158     switch (opc) {
4159     case OPC_AND:
4160         if (likely(rs != 0 && rt != 0)) {
4161             tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4162         } else {
4163             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4164         }
4165         break;
4166     case OPC_NOR:
4167         if (rs != 0 && rt != 0) {
4168             tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4169         } else if (rs == 0 && rt != 0) {
4170             tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
4171         } else if (rs != 0 && rt == 0) {
4172             tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
4173         } else {
4174             tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
4175         }
4176         break;
4177     case OPC_OR:
4178         if (likely(rs != 0 && rt != 0)) {
4179             tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4180         } else if (rs == 0 && rt != 0) {
4181             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4182         } else if (rs != 0 && rt == 0) {
4183             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4184         } else {
4185             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4186         }
4187         break;
4188     case OPC_XOR:
4189         if (likely(rs != 0 && rt != 0)) {
4190             tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4191         } else if (rs == 0 && rt != 0) {
4192             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4193         } else if (rs != 0 && rt == 0) {
4194             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4195         } else {
4196             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4197         }
4198         break;
4199     }
4200 }
4201
4202 /* Set on lower than */
4203 static void gen_slt(DisasContext *ctx, uint32_t opc,
4204                     int rd, int rs, int rt)
4205 {
4206     TCGv t0, t1;
4207
4208     if (rd == 0) {
4209         /* If no destination, treat it as a NOP. */
4210         return;
4211     }
4212
4213     t0 = tcg_temp_new();
4214     t1 = tcg_temp_new();
4215     gen_load_gpr(t0, rs);
4216     gen_load_gpr(t1, rt);
4217     switch (opc) {
4218     case OPC_SLT:
4219         tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
4220         break;
4221     case OPC_SLTU:
4222         tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
4223         break;
4224     }
4225     tcg_temp_free(t0);
4226     tcg_temp_free(t1);
4227 }
4228
4229 /* Shifts */
4230 static void gen_shift(DisasContext *ctx, uint32_t opc,
4231                       int rd, int rs, int rt)
4232 {
4233     TCGv t0, t1;
4234
4235     if (rd == 0) {
4236         /* If no destination, treat it as a NOP.
4237            For add & sub, we must generate the overflow exception when needed. */
4238         return;
4239     }
4240
4241     t0 = tcg_temp_new();
4242     t1 = tcg_temp_new();
4243     gen_load_gpr(t0, rs);
4244     gen_load_gpr(t1, rt);
4245     switch (opc) {
4246     case OPC_SLLV:
4247         tcg_gen_andi_tl(t0, t0, 0x1f);
4248         tcg_gen_shl_tl(t0, t1, t0);
4249         tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4250         break;
4251     case OPC_SRAV:
4252         tcg_gen_andi_tl(t0, t0, 0x1f);
4253         tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4254         break;
4255     case OPC_SRLV:
4256         tcg_gen_ext32u_tl(t1, t1);
4257         tcg_gen_andi_tl(t0, t0, 0x1f);
4258         tcg_gen_shr_tl(t0, t1, t0);
4259         tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4260         break;
4261     case OPC_ROTRV:
4262         {
4263             TCGv_i32 t2 = tcg_temp_new_i32();
4264             TCGv_i32 t3 = tcg_temp_new_i32();
4265
4266             tcg_gen_trunc_tl_i32(t2, t0);
4267             tcg_gen_trunc_tl_i32(t3, t1);
4268             tcg_gen_andi_i32(t2, t2, 0x1f);
4269             tcg_gen_rotr_i32(t2, t3, t2);
4270             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4271             tcg_temp_free_i32(t2);
4272             tcg_temp_free_i32(t3);
4273         }
4274         break;
4275 #if defined(TARGET_MIPS64)
4276     case OPC_DSLLV:
4277         tcg_gen_andi_tl(t0, t0, 0x3f);
4278         tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
4279         break;
4280     case OPC_DSRAV:
4281         tcg_gen_andi_tl(t0, t0, 0x3f);
4282         tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4283         break;
4284     case OPC_DSRLV:
4285         tcg_gen_andi_tl(t0, t0, 0x3f);
4286         tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
4287         break;
4288     case OPC_DROTRV:
4289         tcg_gen_andi_tl(t0, t0, 0x3f);
4290         tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
4291         break;
4292 #endif
4293     }
4294     tcg_temp_free(t0);
4295     tcg_temp_free(t1);
4296 }
4297
4298 /* Arithmetic on HI/LO registers */
4299 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
4300 {
4301     if (reg == 0 && (opc == OPC_MFHI || opc == TX79_MMI_MFHI1 ||
4302                      opc == OPC_MFLO || opc == TX79_MMI_MFLO1)) {
4303         /* Treat as NOP. */
4304         return;
4305     }
4306
4307     if (acc != 0) {
4308         if (!(ctx->insn_flags & INSN_R5900)) {
4309             check_dsp(ctx);
4310         }
4311     }
4312
4313     switch (opc) {
4314     case OPC_MFHI:
4315     case TX79_MMI_MFHI1:
4316 #if defined(TARGET_MIPS64)
4317         if (acc != 0) {
4318             tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
4319         } else
4320 #endif
4321         {
4322             tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
4323         }
4324         break;
4325     case OPC_MFLO:
4326     case TX79_MMI_MFLO1:
4327 #if defined(TARGET_MIPS64)
4328         if (acc != 0) {
4329             tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
4330         } else
4331 #endif
4332         {
4333             tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
4334         }
4335         break;
4336     case OPC_MTHI:
4337     case TX79_MMI_MTHI1:
4338         if (reg != 0) {
4339 #if defined(TARGET_MIPS64)
4340             if (acc != 0) {
4341                 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
4342             } else
4343 #endif
4344             {
4345                 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
4346             }
4347         } else {
4348             tcg_gen_movi_tl(cpu_HI[acc], 0);
4349         }
4350         break;
4351     case OPC_MTLO:
4352     case TX79_MMI_MTLO1:
4353         if (reg != 0) {
4354 #if defined(TARGET_MIPS64)
4355             if (acc != 0) {
4356                 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
4357             } else
4358 #endif
4359             {
4360                 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
4361             }
4362         } else {
4363             tcg_gen_movi_tl(cpu_LO[acc], 0);
4364         }
4365         break;
4366     }
4367 }
4368
4369 static inline void gen_r6_ld(target_long addr, int reg, int memidx,
4370                              TCGMemOp memop)
4371 {
4372     TCGv t0 = tcg_const_tl(addr);
4373     tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
4374     gen_store_gpr(t0, reg);
4375     tcg_temp_free(t0);
4376 }
4377
4378 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
4379                              int rs)
4380 {
4381     target_long offset;
4382     target_long addr;
4383
4384     switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
4385     case OPC_ADDIUPC:
4386         if (rs != 0) {
4387             offset = sextract32(ctx->opcode << 2, 0, 21);
4388             addr = addr_add(ctx, pc, offset);
4389             tcg_gen_movi_tl(cpu_gpr[rs], addr);
4390         }
4391         break;
4392     case R6_OPC_LWPC:
4393         offset = sextract32(ctx->opcode << 2, 0, 21);
4394         addr = addr_add(ctx, pc, offset);
4395         gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
4396         break;
4397 #if defined(TARGET_MIPS64)
4398     case OPC_LWUPC:
4399         check_mips_64(ctx);
4400         offset = sextract32(ctx->opcode << 2, 0, 21);
4401         addr = addr_add(ctx, pc, offset);
4402         gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
4403         break;
4404 #endif
4405     default:
4406         switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
4407         case OPC_AUIPC:
4408             if (rs != 0) {
4409                 offset = sextract32(ctx->opcode, 0, 16) << 16;
4410                 addr = addr_add(ctx, pc, offset);
4411                 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4412             }
4413             break;
4414         case OPC_ALUIPC:
4415             if (rs != 0) {
4416                 offset = sextract32(ctx->opcode, 0, 16) << 16;
4417                 addr = ~0xFFFF & addr_add(ctx, pc, offset);
4418                 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4419             }
4420             break;
4421 #if defined(TARGET_MIPS64)
4422         case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
4423         case R6_OPC_LDPC + (1 << 16):
4424         case R6_OPC_LDPC + (2 << 16):
4425         case R6_OPC_LDPC + (3 << 16):
4426             check_mips_64(ctx);
4427             offset = sextract32(ctx->opcode << 3, 0, 21);
4428             addr = addr_add(ctx, (pc & ~0x7), offset);
4429             gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
4430             break;
4431 #endif
4432         default:
4433             MIPS_INVAL("OPC_PCREL");
4434             generate_exception_end(ctx, EXCP_RI);
4435             break;
4436         }
4437         break;
4438     }
4439 }
4440
4441 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
4442 {
4443     TCGv t0, t1;
4444
4445     if (rd == 0) {
4446         /* Treat as NOP. */
4447         return;
4448     }
4449
4450     t0 = tcg_temp_new();
4451     t1 = tcg_temp_new();
4452
4453     gen_load_gpr(t0, rs);
4454     gen_load_gpr(t1, rt);
4455
4456     switch (opc) {
4457     case R6_OPC_DIV:
4458         {
4459             TCGv t2 = tcg_temp_new();
4460             TCGv t3 = tcg_temp_new();
4461             tcg_gen_ext32s_tl(t0, t0);
4462             tcg_gen_ext32s_tl(t1, t1);
4463             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4464             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4465             tcg_gen_and_tl(t2, t2, t3);
4466             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4467             tcg_gen_or_tl(t2, t2, t3);
4468             tcg_gen_movi_tl(t3, 0);
4469             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4470             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4471             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4472             tcg_temp_free(t3);
4473             tcg_temp_free(t2);
4474         }
4475         break;
4476     case R6_OPC_MOD:
4477         {
4478             TCGv t2 = tcg_temp_new();
4479             TCGv t3 = tcg_temp_new();
4480             tcg_gen_ext32s_tl(t0, t0);
4481             tcg_gen_ext32s_tl(t1, t1);
4482             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4483             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4484             tcg_gen_and_tl(t2, t2, t3);
4485             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4486             tcg_gen_or_tl(t2, t2, t3);
4487             tcg_gen_movi_tl(t3, 0);
4488             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4489             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4490             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4491             tcg_temp_free(t3);
4492             tcg_temp_free(t2);
4493         }
4494         break;
4495     case R6_OPC_DIVU:
4496         {
4497             TCGv t2 = tcg_const_tl(0);
4498             TCGv t3 = tcg_const_tl(1);
4499             tcg_gen_ext32u_tl(t0, t0);
4500             tcg_gen_ext32u_tl(t1, t1);
4501             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4502             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4503             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4504             tcg_temp_free(t3);
4505             tcg_temp_free(t2);
4506         }
4507         break;
4508     case R6_OPC_MODU:
4509         {
4510             TCGv t2 = tcg_const_tl(0);
4511             TCGv t3 = tcg_const_tl(1);
4512             tcg_gen_ext32u_tl(t0, t0);
4513             tcg_gen_ext32u_tl(t1, t1);
4514             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4515             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4516             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4517             tcg_temp_free(t3);
4518             tcg_temp_free(t2);
4519         }
4520         break;
4521     case R6_OPC_MUL:
4522         {
4523             TCGv_i32 t2 = tcg_temp_new_i32();
4524             TCGv_i32 t3 = tcg_temp_new_i32();
4525             tcg_gen_trunc_tl_i32(t2, t0);
4526             tcg_gen_trunc_tl_i32(t3, t1);
4527             tcg_gen_mul_i32(t2, t2, t3);
4528             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4529             tcg_temp_free_i32(t2);
4530             tcg_temp_free_i32(t3);
4531         }
4532         break;
4533     case R6_OPC_MUH:
4534         {
4535             TCGv_i32 t2 = tcg_temp_new_i32();
4536             TCGv_i32 t3 = tcg_temp_new_i32();
4537             tcg_gen_trunc_tl_i32(t2, t0);
4538             tcg_gen_trunc_tl_i32(t3, t1);
4539             tcg_gen_muls2_i32(t2, t3, t2, t3);
4540             tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4541             tcg_temp_free_i32(t2);
4542             tcg_temp_free_i32(t3);
4543         }
4544         break;
4545     case R6_OPC_MULU:
4546         {
4547             TCGv_i32 t2 = tcg_temp_new_i32();
4548             TCGv_i32 t3 = tcg_temp_new_i32();
4549             tcg_gen_trunc_tl_i32(t2, t0);
4550             tcg_gen_trunc_tl_i32(t3, t1);
4551             tcg_gen_mul_i32(t2, t2, t3);
4552             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4553             tcg_temp_free_i32(t2);
4554             tcg_temp_free_i32(t3);
4555         }
4556         break;
4557     case R6_OPC_MUHU:
4558         {
4559             TCGv_i32 t2 = tcg_temp_new_i32();
4560             TCGv_i32 t3 = tcg_temp_new_i32();
4561             tcg_gen_trunc_tl_i32(t2, t0);
4562             tcg_gen_trunc_tl_i32(t3, t1);
4563             tcg_gen_mulu2_i32(t2, t3, t2, t3);
4564             tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4565             tcg_temp_free_i32(t2);
4566             tcg_temp_free_i32(t3);
4567         }
4568         break;
4569 #if defined(TARGET_MIPS64)
4570     case R6_OPC_DDIV:
4571         {
4572             TCGv t2 = tcg_temp_new();
4573             TCGv t3 = tcg_temp_new();
4574             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4575             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4576             tcg_gen_and_tl(t2, t2, t3);
4577             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4578             tcg_gen_or_tl(t2, t2, t3);
4579             tcg_gen_movi_tl(t3, 0);
4580             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4581             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4582             tcg_temp_free(t3);
4583             tcg_temp_free(t2);
4584         }
4585         break;
4586     case R6_OPC_DMOD:
4587         {
4588             TCGv t2 = tcg_temp_new();
4589             TCGv t3 = tcg_temp_new();
4590             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4591             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4592             tcg_gen_and_tl(t2, t2, t3);
4593             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4594             tcg_gen_or_tl(t2, t2, t3);
4595             tcg_gen_movi_tl(t3, 0);
4596             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4597             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4598             tcg_temp_free(t3);
4599             tcg_temp_free(t2);
4600         }
4601         break;
4602     case R6_OPC_DDIVU:
4603         {
4604             TCGv t2 = tcg_const_tl(0);
4605             TCGv t3 = tcg_const_tl(1);
4606             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4607             tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
4608             tcg_temp_free(t3);
4609             tcg_temp_free(t2);
4610         }
4611         break;
4612     case R6_OPC_DMODU:
4613         {
4614             TCGv t2 = tcg_const_tl(0);
4615             TCGv t3 = tcg_const_tl(1);
4616             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4617             tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
4618             tcg_temp_free(t3);
4619             tcg_temp_free(t2);
4620         }
4621         break;
4622     case R6_OPC_DMUL:
4623         tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4624         break;
4625     case R6_OPC_DMUH:
4626         {
4627             TCGv t2 = tcg_temp_new();
4628             tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
4629             tcg_temp_free(t2);
4630         }
4631         break;
4632     case R6_OPC_DMULU:
4633         tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4634         break;
4635     case R6_OPC_DMUHU:
4636         {
4637             TCGv t2 = tcg_temp_new();
4638             tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
4639             tcg_temp_free(t2);
4640         }
4641         break;
4642 #endif
4643     default:
4644         MIPS_INVAL("r6 mul/div");
4645         generate_exception_end(ctx, EXCP_RI);
4646         goto out;
4647     }
4648  out:
4649     tcg_temp_free(t0);
4650     tcg_temp_free(t1);
4651 }
4652
4653 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
4654                        int acc, int rs, int rt)
4655 {
4656     TCGv t0, t1;
4657
4658     t0 = tcg_temp_new();
4659     t1 = tcg_temp_new();
4660
4661     gen_load_gpr(t0, rs);
4662     gen_load_gpr(t1, rt);
4663
4664     if (acc != 0) {
4665         if (!(ctx->insn_flags & INSN_R5900)) {
4666             check_dsp(ctx);
4667         }
4668     }
4669
4670     switch (opc) {
4671     case OPC_DIV:
4672     case TX79_MMI_DIV1:
4673         {
4674             TCGv t2 = tcg_temp_new();
4675             TCGv t3 = tcg_temp_new();
4676             tcg_gen_ext32s_tl(t0, t0);
4677             tcg_gen_ext32s_tl(t1, t1);
4678             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4679             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4680             tcg_gen_and_tl(t2, t2, t3);
4681             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4682             tcg_gen_or_tl(t2, t2, t3);
4683             tcg_gen_movi_tl(t3, 0);
4684             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4685             tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4686             tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4687             tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4688             tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4689             tcg_temp_free(t3);
4690             tcg_temp_free(t2);
4691         }
4692         break;
4693     case OPC_DIVU:
4694     case TX79_MMI_DIVU1:
4695         {
4696             TCGv t2 = tcg_const_tl(0);
4697             TCGv t3 = tcg_const_tl(1);
4698             tcg_gen_ext32u_tl(t0, t0);
4699             tcg_gen_ext32u_tl(t1, t1);
4700             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4701             tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
4702             tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
4703             tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4704             tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4705             tcg_temp_free(t3);
4706             tcg_temp_free(t2);
4707         }
4708         break;
4709     case OPC_MULT:
4710         {
4711             TCGv_i32 t2 = tcg_temp_new_i32();
4712             TCGv_i32 t3 = tcg_temp_new_i32();
4713             tcg_gen_trunc_tl_i32(t2, t0);
4714             tcg_gen_trunc_tl_i32(t3, t1);
4715             tcg_gen_muls2_i32(t2, t3, t2, t3);
4716             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4717             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4718             tcg_temp_free_i32(t2);
4719             tcg_temp_free_i32(t3);
4720         }
4721         break;
4722     case OPC_MULTU:
4723         {
4724             TCGv_i32 t2 = tcg_temp_new_i32();
4725             TCGv_i32 t3 = tcg_temp_new_i32();
4726             tcg_gen_trunc_tl_i32(t2, t0);
4727             tcg_gen_trunc_tl_i32(t3, t1);
4728             tcg_gen_mulu2_i32(t2, t3, t2, t3);
4729             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4730             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4731             tcg_temp_free_i32(t2);
4732             tcg_temp_free_i32(t3);
4733         }
4734         break;
4735 #if defined(TARGET_MIPS64)
4736     case OPC_DDIV:
4737         {
4738             TCGv t2 = tcg_temp_new();
4739             TCGv t3 = tcg_temp_new();
4740             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4741             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4742             tcg_gen_and_tl(t2, t2, t3);
4743             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4744             tcg_gen_or_tl(t2, t2, t3);
4745             tcg_gen_movi_tl(t3, 0);
4746             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4747             tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4748             tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4749             tcg_temp_free(t3);
4750             tcg_temp_free(t2);
4751         }
4752         break;
4753     case OPC_DDIVU:
4754         {
4755             TCGv t2 = tcg_const_tl(0);
4756             TCGv t3 = tcg_const_tl(1);
4757             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4758             tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
4759             tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
4760             tcg_temp_free(t3);
4761             tcg_temp_free(t2);
4762         }
4763         break;
4764     case OPC_DMULT:
4765         tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
4766         break;
4767     case OPC_DMULTU:
4768         tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
4769         break;
4770 #endif
4771     case OPC_MADD:
4772         {
4773             TCGv_i64 t2 = tcg_temp_new_i64();
4774             TCGv_i64 t3 = tcg_temp_new_i64();
4775
4776             tcg_gen_ext_tl_i64(t2, t0);
4777             tcg_gen_ext_tl_i64(t3, t1);
4778             tcg_gen_mul_i64(t2, t2, t3);
4779             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4780             tcg_gen_add_i64(t2, t2, t3);
4781             tcg_temp_free_i64(t3);
4782             gen_move_low32(cpu_LO[acc], t2);
4783             gen_move_high32(cpu_HI[acc], t2);
4784             tcg_temp_free_i64(t2);
4785         }
4786         break;
4787     case OPC_MADDU:
4788         {
4789             TCGv_i64 t2 = tcg_temp_new_i64();
4790             TCGv_i64 t3 = tcg_temp_new_i64();
4791
4792             tcg_gen_ext32u_tl(t0, t0);
4793             tcg_gen_ext32u_tl(t1, t1);
4794             tcg_gen_extu_tl_i64(t2, t0);
4795             tcg_gen_extu_tl_i64(t3, t1);
4796             tcg_gen_mul_i64(t2, t2, t3);
4797             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4798             tcg_gen_add_i64(t2, t2, t3);
4799             tcg_temp_free_i64(t3);
4800             gen_move_low32(cpu_LO[acc], t2);
4801             gen_move_high32(cpu_HI[acc], t2);
4802             tcg_temp_free_i64(t2);
4803         }
4804         break;
4805     case OPC_MSUB:
4806         {
4807             TCGv_i64 t2 = tcg_temp_new_i64();
4808             TCGv_i64 t3 = tcg_temp_new_i64();
4809
4810             tcg_gen_ext_tl_i64(t2, t0);
4811             tcg_gen_ext_tl_i64(t3, t1);
4812             tcg_gen_mul_i64(t2, t2, t3);
4813             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4814             tcg_gen_sub_i64(t2, t3, t2);
4815             tcg_temp_free_i64(t3);
4816             gen_move_low32(cpu_LO[acc], t2);
4817             gen_move_high32(cpu_HI[acc], t2);
4818             tcg_temp_free_i64(t2);
4819         }
4820         break;
4821     case OPC_MSUBU:
4822         {
4823             TCGv_i64 t2 = tcg_temp_new_i64();
4824             TCGv_i64 t3 = tcg_temp_new_i64();
4825
4826             tcg_gen_ext32u_tl(t0, t0);
4827             tcg_gen_ext32u_tl(t1, t1);
4828             tcg_gen_extu_tl_i64(t2, t0);
4829             tcg_gen_extu_tl_i64(t3, t1);
4830             tcg_gen_mul_i64(t2, t2, t3);
4831             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4832             tcg_gen_sub_i64(t2, t3, t2);
4833             tcg_temp_free_i64(t3);
4834             gen_move_low32(cpu_LO[acc], t2);
4835             gen_move_high32(cpu_HI[acc], t2);
4836             tcg_temp_free_i64(t2);
4837         }
4838         break;
4839     default:
4840         MIPS_INVAL("mul/div");
4841         generate_exception_end(ctx, EXCP_RI);
4842         goto out;
4843     }
4844  out:
4845     tcg_temp_free(t0);
4846     tcg_temp_free(t1);
4847 }
4848
4849 /*
4850  * These MULT and MULTU instructions implemented in for example the
4851  * Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
4852  * architectures are special three-operand variants with the syntax
4853  *
4854  *     MULT[U][1] rd, rs, rt
4855  *
4856  * such that
4857  *
4858  *     (rd, LO, HI) <- rs * rt
4859  *
4860  * where the low-order 32-bits of the result is placed into both the
4861  * GPR rd and the special register LO. The high-order 32-bits of the
4862  * result is placed into the special register HI.
4863  *
4864  * If the GPR rd is omitted in assembly language, it is taken to be 0,
4865  * which is the zero register that always reads as 0.
4866  */
4867 static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
4868                          int rd, int rs, int rt)
4869 {
4870     TCGv t0 = tcg_temp_new();
4871     TCGv t1 = tcg_temp_new();
4872     int acc = 0;
4873
4874     gen_load_gpr(t0, rs);
4875     gen_load_gpr(t1, rt);
4876
4877     switch (opc) {
4878     case TX79_MMI_MULT1:
4879         acc = 1;
4880         /* Fall through */
4881     case OPC_MULT:
4882         {
4883             TCGv_i32 t2 = tcg_temp_new_i32();
4884             TCGv_i32 t3 = tcg_temp_new_i32();
4885             tcg_gen_trunc_tl_i32(t2, t0);
4886             tcg_gen_trunc_tl_i32(t3, t1);
4887             tcg_gen_muls2_i32(t2, t3, t2, t3);
4888             if (rd) {
4889                 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4890             }
4891             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4892             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4893             tcg_temp_free_i32(t2);
4894             tcg_temp_free_i32(t3);
4895         }
4896         break;
4897     case TX79_MMI_MULTU1:
4898         acc = 1;
4899         /* Fall through */
4900     case OPC_MULTU:
4901         {
4902             TCGv_i32 t2 = tcg_temp_new_i32();
4903             TCGv_i32 t3 = tcg_temp_new_i32();
4904             tcg_gen_trunc_tl_i32(t2, t0);
4905             tcg_gen_trunc_tl_i32(t3, t1);
4906             tcg_gen_mulu2_i32(t2, t3, t2, t3);
4907             if (rd) {
4908                 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4909             }
4910             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4911             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4912             tcg_temp_free_i32(t2);
4913             tcg_temp_free_i32(t3);
4914         }
4915         break;
4916     default:
4917         MIPS_INVAL("mul TXx9");
4918         generate_exception_end(ctx, EXCP_RI);
4919         goto out;
4920     }
4921
4922  out:
4923     tcg_temp_free(t0);
4924     tcg_temp_free(t1);
4925 }
4926
4927 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
4928                             int rd, int rs, int rt)
4929 {
4930     TCGv t0 = tcg_temp_new();
4931     TCGv t1 = tcg_temp_new();
4932
4933     gen_load_gpr(t0, rs);
4934     gen_load_gpr(t1, rt);
4935
4936     switch (opc) {
4937     case OPC_VR54XX_MULS:
4938         gen_helper_muls(t0, cpu_env, t0, t1);
4939         break;
4940     case OPC_VR54XX_MULSU:
4941         gen_helper_mulsu(t0, cpu_env, t0, t1);
4942         break;
4943     case OPC_VR54XX_MACC:
4944         gen_helper_macc(t0, cpu_env, t0, t1);
4945         break;
4946     case OPC_VR54XX_MACCU:
4947         gen_helper_maccu(t0, cpu_env, t0, t1);
4948         break;
4949     case OPC_VR54XX_MSAC:
4950         gen_helper_msac(t0, cpu_env, t0, t1);
4951         break;
4952     case OPC_VR54XX_MSACU:
4953         gen_helper_msacu(t0, cpu_env, t0, t1);
4954         break;
4955     case OPC_VR54XX_MULHI:
4956         gen_helper_mulhi(t0, cpu_env, t0, t1);
4957         break;
4958     case OPC_VR54XX_MULHIU:
4959         gen_helper_mulhiu(t0, cpu_env, t0, t1);
4960         break;
4961     case OPC_VR54XX_MULSHI:
4962         gen_helper_mulshi(t0, cpu_env, t0, t1);
4963         break;
4964     case OPC_VR54XX_MULSHIU:
4965         gen_helper_mulshiu(t0, cpu_env, t0, t1);
4966         break;
4967     case OPC_VR54XX_MACCHI:
4968         gen_helper_macchi(t0, cpu_env, t0, t1);
4969         break;
4970     case OPC_VR54XX_MACCHIU:
4971         gen_helper_macchiu(t0, cpu_env, t0, t1);
4972         break;
4973     case OPC_VR54XX_MSACHI:
4974         gen_helper_msachi(t0, cpu_env, t0, t1);
4975         break;
4976     case OPC_VR54XX_MSACHIU:
4977         gen_helper_msachiu(t0, cpu_env, t0, t1);
4978         break;
4979     default:
4980         MIPS_INVAL("mul vr54xx");
4981         generate_exception_end(ctx, EXCP_RI);
4982         goto out;
4983     }
4984     gen_store_gpr(t0, rd);
4985
4986  out:
4987     tcg_temp_free(t0);
4988     tcg_temp_free(t1);
4989 }
4990
4991 static void gen_cl (DisasContext *ctx, uint32_t opc,
4992                     int rd, int rs)
4993 {
4994     TCGv t0;
4995
4996     if (rd == 0) {
4997         /* Treat as NOP. */
4998         return;
4999     }
5000     t0 = cpu_gpr[rd];
5001     gen_load_gpr(t0, rs);
5002
5003     switch (opc) {
5004     case OPC_CLO:
5005     case R6_OPC_CLO:
5006 #if defined(TARGET_MIPS64)
5007     case OPC_DCLO:
5008     case R6_OPC_DCLO:
5009 #endif
5010         tcg_gen_not_tl(t0, t0);
5011         break;
5012     }
5013
5014     switch (opc) {
5015     case OPC_CLO:
5016     case R6_OPC_CLO:
5017     case OPC_CLZ:
5018     case R6_OPC_CLZ:
5019         tcg_gen_ext32u_tl(t0, t0);
5020         tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
5021         tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
5022         break;
5023 #if defined(TARGET_MIPS64)
5024     case OPC_DCLO:
5025     case R6_OPC_DCLO:
5026     case OPC_DCLZ:
5027     case R6_OPC_DCLZ:
5028         tcg_gen_clzi_i64(t0, t0, 64);
5029         break;
5030 #endif
5031     }
5032 }
5033
5034 /* Godson integer instructions */
5035 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
5036                                  int rd, int rs, int rt)
5037 {
5038     TCGv t0, t1;
5039
5040     if (rd == 0) {
5041         /* Treat as NOP. */
5042         return;
5043     }
5044
5045     switch (opc) {
5046     case OPC_MULT_G_2E:
5047     case OPC_MULT_G_2F:
5048     case OPC_MULTU_G_2E:
5049     case OPC_MULTU_G_2F:
5050 #if defined(TARGET_MIPS64)
5051     case OPC_DMULT_G_2E:
5052     case OPC_DMULT_G_2F:
5053     case OPC_DMULTU_G_2E:
5054     case OPC_DMULTU_G_2F:
5055 #endif
5056         t0 = tcg_temp_new();
5057         t1 = tcg_temp_new();
5058         break;
5059     default:
5060         t0 = tcg_temp_local_new();
5061         t1 = tcg_temp_local_new();
5062         break;
5063     }
5064
5065     gen_load_gpr(t0, rs);
5066     gen_load_gpr(t1, rt);
5067
5068     switch (opc) {
5069     case OPC_MULT_G_2E:
5070     case OPC_MULT_G_2F:
5071         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5072         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5073         break;
5074     case OPC_MULTU_G_2E:
5075     case OPC_MULTU_G_2F:
5076         tcg_gen_ext32u_tl(t0, t0);
5077         tcg_gen_ext32u_tl(t1, t1);
5078         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5079         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5080         break;
5081     case OPC_DIV_G_2E:
5082     case OPC_DIV_G_2F:
5083         {
5084             TCGLabel *l1 = gen_new_label();
5085             TCGLabel *l2 = gen_new_label();
5086             TCGLabel *l3 = gen_new_label();
5087             tcg_gen_ext32s_tl(t0, t0);
5088             tcg_gen_ext32s_tl(t1, t1);
5089             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5090             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5091             tcg_gen_br(l3);
5092             gen_set_label(l1);
5093             tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5094             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5095             tcg_gen_mov_tl(cpu_gpr[rd], t0);
5096             tcg_gen_br(l3);
5097             gen_set_label(l2);
5098             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5099             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5100             gen_set_label(l3);
5101         }
5102         break;
5103     case OPC_DIVU_G_2E:
5104     case OPC_DIVU_G_2F:
5105         {
5106             TCGLabel *l1 = gen_new_label();
5107             TCGLabel *l2 = gen_new_label();
5108             tcg_gen_ext32u_tl(t0, t0);
5109             tcg_gen_ext32u_tl(t1, t1);
5110             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5111             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5112             tcg_gen_br(l2);
5113             gen_set_label(l1);
5114             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5115             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5116             gen_set_label(l2);
5117         }
5118         break;
5119     case OPC_MOD_G_2E:
5120     case OPC_MOD_G_2F:
5121         {
5122             TCGLabel *l1 = gen_new_label();
5123             TCGLabel *l2 = gen_new_label();
5124             TCGLabel *l3 = gen_new_label();
5125             tcg_gen_ext32u_tl(t0, t0);
5126             tcg_gen_ext32u_tl(t1, t1);
5127             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5128             tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5129             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5130             gen_set_label(l1);
5131             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5132             tcg_gen_br(l3);
5133             gen_set_label(l2);
5134             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5135             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5136             gen_set_label(l3);
5137         }
5138         break;
5139     case OPC_MODU_G_2E:
5140     case OPC_MODU_G_2F:
5141         {
5142             TCGLabel *l1 = gen_new_label();
5143             TCGLabel *l2 = gen_new_label();
5144             tcg_gen_ext32u_tl(t0, t0);
5145             tcg_gen_ext32u_tl(t1, t1);
5146             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5147             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5148             tcg_gen_br(l2);
5149             gen_set_label(l1);
5150             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5151             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5152             gen_set_label(l2);
5153         }
5154         break;
5155 #if defined(TARGET_MIPS64)
5156     case OPC_DMULT_G_2E:
5157     case OPC_DMULT_G_2F:
5158         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5159         break;
5160     case OPC_DMULTU_G_2E:
5161     case OPC_DMULTU_G_2F:
5162         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5163         break;
5164     case OPC_DDIV_G_2E:
5165     case OPC_DDIV_G_2F:
5166         {
5167             TCGLabel *l1 = gen_new_label();
5168             TCGLabel *l2 = gen_new_label();
5169             TCGLabel *l3 = gen_new_label();
5170             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5171             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5172             tcg_gen_br(l3);
5173             gen_set_label(l1);
5174             tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5175             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5176             tcg_gen_mov_tl(cpu_gpr[rd], t0);
5177             tcg_gen_br(l3);
5178             gen_set_label(l2);
5179             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5180             gen_set_label(l3);
5181         }
5182         break;
5183     case OPC_DDIVU_G_2E:
5184     case OPC_DDIVU_G_2F:
5185         {
5186             TCGLabel *l1 = gen_new_label();
5187             TCGLabel *l2 = gen_new_label();
5188             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5189             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5190             tcg_gen_br(l2);
5191             gen_set_label(l1);
5192             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5193             gen_set_label(l2);
5194         }
5195         break;
5196     case OPC_DMOD_G_2E:
5197     case OPC_DMOD_G_2F:
5198         {
5199             TCGLabel *l1 = gen_new_label();
5200             TCGLabel *l2 = gen_new_label();
5201             TCGLabel *l3 = gen_new_label();
5202             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5203             tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5204             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5205             gen_set_label(l1);
5206             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5207             tcg_gen_br(l3);
5208             gen_set_label(l2);
5209             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5210             gen_set_label(l3);
5211         }
5212         break;
5213     case OPC_DMODU_G_2E:
5214     case OPC_DMODU_G_2F:
5215         {
5216             TCGLabel *l1 = gen_new_label();
5217             TCGLabel *l2 = gen_new_label();
5218             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5219             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5220             tcg_gen_br(l2);
5221             gen_set_label(l1);
5222             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5223             gen_set_label(l2);
5224         }
5225         break;
5226 #endif
5227     }
5228
5229     tcg_temp_free(t0);
5230     tcg_temp_free(t1);
5231 }
5232
5233 /* Loongson multimedia instructions */
5234 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
5235 {
5236     uint32_t opc, shift_max;
5237     TCGv_i64 t0, t1;
5238
5239     opc = MASK_LMI(ctx->opcode);
5240     switch (opc) {
5241     case OPC_ADD_CP2:
5242     case OPC_SUB_CP2:
5243     case OPC_DADD_CP2:
5244     case OPC_DSUB_CP2:
5245         t0 = tcg_temp_local_new_i64();
5246         t1 = tcg_temp_local_new_i64();
5247         break;
5248     default:
5249         t0 = tcg_temp_new_i64();
5250         t1 = tcg_temp_new_i64();
5251         break;
5252     }
5253
5254     check_cp1_enabled(ctx);
5255     gen_load_fpr64(ctx, t0, rs);
5256     gen_load_fpr64(ctx, t1, rt);
5257
5258 #define LMI_HELPER(UP, LO) \
5259     case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
5260 #define LMI_HELPER_1(UP, LO) \
5261     case OPC_##UP: gen_helper_##LO(t0, t0); break
5262 #define LMI_DIRECT(UP, LO, OP) \
5263     case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
5264
5265     switch (opc) {
5266     LMI_HELPER(PADDSH, paddsh);
5267     LMI_HELPER(PADDUSH, paddush);
5268     LMI_HELPER(PADDH, paddh);
5269     LMI_HELPER(PADDW, paddw);
5270     LMI_HELPER(PADDSB, paddsb);
5271     LMI_HELPER(PADDUSB, paddusb);
5272     LMI_HELPER(PADDB, paddb);
5273
5274     LMI_HELPER(PSUBSH, psubsh);
5275     LMI_HELPER(PSUBUSH, psubush);
5276     LMI_HELPER(PSUBH, psubh);
5277     LMI_HELPER(PSUBW, psubw);
5278     LMI_HELPER(PSUBSB, psubsb);
5279     LMI_HELPER(PSUBUSB, psubusb);
5280     LMI_HELPER(PSUBB, psubb);
5281
5282     LMI_HELPER(PSHUFH, pshufh);
5283     LMI_HELPER(PACKSSWH, packsswh);
5284     LMI_HELPER(PACKSSHB, packsshb);
5285     LMI_HELPER(PACKUSHB, packushb);
5286
5287     LMI_HELPER(PUNPCKLHW, punpcklhw);
5288     LMI_HELPER(PUNPCKHHW, punpckhhw);
5289     LMI_HELPER(PUNPCKLBH, punpcklbh);
5290     LMI_HELPER(PUNPCKHBH, punpckhbh);
5291     LMI_HELPER(PUNPCKLWD, punpcklwd);
5292     LMI_HELPER(PUNPCKHWD, punpckhwd);
5293
5294     LMI_HELPER(PAVGH, pavgh);
5295     LMI_HELPER(PAVGB, pavgb);
5296     LMI_HELPER(PMAXSH, pmaxsh);
5297     LMI_HELPER(PMINSH, pminsh);
5298     LMI_HELPER(PMAXUB, pmaxub);
5299     LMI_HELPER(PMINUB, pminub);
5300
5301     LMI_HELPER(PCMPEQW, pcmpeqw);
5302     LMI_HELPER(PCMPGTW, pcmpgtw);
5303     LMI_HELPER(PCMPEQH, pcmpeqh);
5304     LMI_HELPER(PCMPGTH, pcmpgth);
5305     LMI_HELPER(PCMPEQB, pcmpeqb);
5306     LMI_HELPER(PCMPGTB, pcmpgtb);
5307
5308     LMI_HELPER(PSLLW, psllw);
5309     LMI_HELPER(PSLLH, psllh);
5310     LMI_HELPER(PSRLW, psrlw);
5311     LMI_HELPER(PSRLH, psrlh);
5312     LMI_HELPER(PSRAW, psraw);
5313     LMI_HELPER(PSRAH, psrah);
5314
5315     LMI_HELPER(PMULLH, pmullh);
5316     LMI_HELPER(PMULHH, pmulhh);
5317     LMI_HELPER(PMULHUH, pmulhuh);
5318     LMI_HELPER(PMADDHW, pmaddhw);
5319
5320     LMI_HELPER(PASUBUB, pasubub);
5321     LMI_HELPER_1(BIADD, biadd);
5322     LMI_HELPER_1(PMOVMSKB, pmovmskb);
5323
5324     LMI_DIRECT(PADDD, paddd, add);
5325     LMI_DIRECT(PSUBD, psubd, sub);
5326     LMI_DIRECT(XOR_CP2, xor, xor);
5327     LMI_DIRECT(NOR_CP2, nor, nor);
5328     LMI_DIRECT(AND_CP2, and, and);
5329     LMI_DIRECT(OR_CP2, or, or);
5330
5331     case OPC_PANDN:
5332         tcg_gen_andc_i64(t0, t1, t0);
5333         break;
5334
5335     case OPC_PINSRH_0:
5336         tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
5337         break;
5338     case OPC_PINSRH_1:
5339         tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
5340         break;
5341     case OPC_PINSRH_2:
5342         tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
5343         break;
5344     case OPC_PINSRH_3:
5345         tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
5346         break;
5347
5348     case OPC_PEXTRH:
5349         tcg_gen_andi_i64(t1, t1, 3);
5350         tcg_gen_shli_i64(t1, t1, 4);
5351         tcg_gen_shr_i64(t0, t0, t1);
5352         tcg_gen_ext16u_i64(t0, t0);
5353         break;
5354
5355     case OPC_ADDU_CP2:
5356         tcg_gen_add_i64(t0, t0, t1);
5357         tcg_gen_ext32s_i64(t0, t0);
5358         break;
5359     case OPC_SUBU_CP2:
5360         tcg_gen_sub_i64(t0, t0, t1);
5361         tcg_gen_ext32s_i64(t0, t0);
5362         break;
5363
5364     case OPC_SLL_CP2:
5365         shift_max = 32;
5366         goto do_shift;
5367     case OPC_SRL_CP2:
5368         shift_max = 32;
5369         goto do_shift;
5370     case OPC_SRA_CP2:
5371         shift_max = 32;
5372         goto do_shift;
5373     case OPC_DSLL_CP2:
5374         shift_max = 64;
5375         goto do_shift;
5376     case OPC_DSRL_CP2:
5377         shift_max = 64;
5378         goto do_shift;
5379     case OPC_DSRA_CP2:
5380         shift_max = 64;
5381         goto do_shift;
5382     do_shift:
5383         /* Make sure shift count isn't TCG undefined behaviour.  */
5384         tcg_gen_andi_i64(t1, t1, shift_max - 1);
5385
5386         switch (opc) {
5387         case OPC_SLL_CP2:
5388         case OPC_DSLL_CP2:
5389             tcg_gen_shl_i64(t0, t0, t1);
5390             break;
5391         case OPC_SRA_CP2:
5392         case OPC_DSRA_CP2:
5393             /* Since SRA is UndefinedResult without sign-extended inputs,
5394                we can treat SRA and DSRA the same.  */
5395             tcg_gen_sar_i64(t0, t0, t1);
5396             break;
5397         case OPC_SRL_CP2:
5398             /* We want to shift in zeros for SRL; zero-extend first.  */
5399             tcg_gen_ext32u_i64(t0, t0);
5400             /* FALLTHRU */
5401         case OPC_DSRL_CP2:
5402             tcg_gen_shr_i64(t0, t0, t1);
5403             break;
5404         }
5405
5406         if (shift_max == 32) {
5407             tcg_gen_ext32s_i64(t0, t0);
5408         }
5409
5410         /* Shifts larger than MAX produce zero.  */
5411         tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
5412         tcg_gen_neg_i64(t1, t1);
5413         tcg_gen_and_i64(t0, t0, t1);
5414         break;
5415
5416     case OPC_ADD_CP2:
5417     case OPC_DADD_CP2:
5418         {
5419             TCGv_i64 t2 = tcg_temp_new_i64();
5420             TCGLabel *lab = gen_new_label();
5421
5422             tcg_gen_mov_i64(t2, t0);
5423             tcg_gen_add_i64(t0, t1, t2);
5424             if (opc == OPC_ADD_CP2) {
5425                 tcg_gen_ext32s_i64(t0, t0);
5426             }
5427             tcg_gen_xor_i64(t1, t1, t2);
5428             tcg_gen_xor_i64(t2, t2, t0);
5429             tcg_gen_andc_i64(t1, t2, t1);
5430             tcg_temp_free_i64(t2);
5431             tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5432             generate_exception(ctx, EXCP_OVERFLOW);
5433             gen_set_label(lab);
5434             break;
5435         }
5436
5437     case OPC_SUB_CP2:
5438     case OPC_DSUB_CP2:
5439         {
5440             TCGv_i64 t2 = tcg_temp_new_i64();
5441             TCGLabel *lab = gen_new_label();
5442
5443             tcg_gen_mov_i64(t2, t0);
5444             tcg_gen_sub_i64(t0, t1, t2);
5445             if (opc == OPC_SUB_CP2) {
5446                 tcg_gen_ext32s_i64(t0, t0);
5447             }
5448             tcg_gen_xor_i64(t1, t1, t2);
5449             tcg_gen_xor_i64(t2, t2, t0);
5450             tcg_gen_and_i64(t1, t1, t2);
5451             tcg_temp_free_i64(t2);
5452             tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5453             generate_exception(ctx, EXCP_OVERFLOW);
5454             gen_set_label(lab);
5455             break;
5456         }
5457
5458     case OPC_PMULUW:
5459         tcg_gen_ext32u_i64(t0, t0);
5460         tcg_gen_ext32u_i64(t1, t1);
5461         tcg_gen_mul_i64(t0, t0, t1);
5462         break;
5463
5464     case OPC_SEQU_CP2:
5465     case OPC_SEQ_CP2:
5466     case OPC_SLTU_CP2:
5467     case OPC_SLT_CP2:
5468     case OPC_SLEU_CP2:
5469     case OPC_SLE_CP2:
5470         /* ??? Document is unclear: Set FCC[CC].  Does that mean the
5471            FD field is the CC field?  */
5472     default:
5473         MIPS_INVAL("loongson_cp2");
5474         generate_exception_end(ctx, EXCP_RI);
5475         return;
5476     }
5477
5478 #undef LMI_HELPER
5479 #undef LMI_DIRECT
5480
5481     gen_store_fpr64(ctx, t0, rd);
5482
5483     tcg_temp_free_i64(t0);
5484     tcg_temp_free_i64(t1);
5485 }
5486
5487 /* Traps */
5488 static void gen_trap (DisasContext *ctx, uint32_t opc,
5489                       int rs, int rt, int16_t imm)
5490 {
5491     int cond;
5492     TCGv t0 = tcg_temp_new();
5493     TCGv t1 = tcg_temp_new();
5494
5495     cond = 0;
5496     /* Load needed operands */
5497     switch (opc) {
5498     case OPC_TEQ:
5499     case OPC_TGE:
5500     case OPC_TGEU:
5501     case OPC_TLT:
5502     case OPC_TLTU:
5503     case OPC_TNE:
5504         /* Compare two registers */
5505         if (rs != rt) {
5506             gen_load_gpr(t0, rs);
5507             gen_load_gpr(t1, rt);
5508             cond = 1;
5509         }
5510         break;
5511     case OPC_TEQI:
5512     case OPC_TGEI:
5513     case OPC_TGEIU:
5514     case OPC_TLTI:
5515     case OPC_TLTIU:
5516     case OPC_TNEI:
5517         /* Compare register to immediate */
5518         if (rs != 0 || imm != 0) {
5519             gen_load_gpr(t0, rs);
5520             tcg_gen_movi_tl(t1, (int32_t)imm);
5521             cond = 1;
5522         }
5523         break;
5524     }
5525     if (cond == 0) {
5526         switch (opc) {
5527         case OPC_TEQ:   /* rs == rs */
5528         case OPC_TEQI:  /* r0 == 0  */
5529         case OPC_TGE:   /* rs >= rs */
5530         case OPC_TGEI:  /* r0 >= 0  */
5531         case OPC_TGEU:  /* rs >= rs unsigned */
5532         case OPC_TGEIU: /* r0 >= 0  unsigned */
5533             /* Always trap */
5534             generate_exception_end(ctx, EXCP_TRAP);
5535             break;
5536         case OPC_TLT:   /* rs < rs           */
5537         case OPC_TLTI:  /* r0 < 0            */
5538         case OPC_TLTU:  /* rs < rs unsigned  */
5539         case OPC_TLTIU: /* r0 < 0  unsigned  */
5540         case OPC_TNE:   /* rs != rs          */
5541         case OPC_TNEI:  /* r0 != 0           */
5542             /* Never trap: treat as NOP. */
5543             break;
5544         }
5545     } else {
5546         TCGLabel *l1 = gen_new_label();
5547
5548         switch (opc) {
5549         case OPC_TEQ:
5550         case OPC_TEQI:
5551             tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
5552             break;
5553         case OPC_TGE:
5554         case OPC_TGEI:
5555             tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
5556             break;
5557         case OPC_TGEU:
5558         case OPC_TGEIU:
5559             tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
5560             break;
5561         case OPC_TLT:
5562         case OPC_TLTI:
5563             tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
5564             break;
5565         case OPC_TLTU:
5566         case OPC_TLTIU:
5567             tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
5568             break;
5569         case OPC_TNE:
5570         case OPC_TNEI:
5571             tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
5572             break;
5573         }
5574         generate_exception(ctx, EXCP_TRAP);
5575         gen_set_label(l1);
5576     }
5577     tcg_temp_free(t0);
5578     tcg_temp_free(t1);
5579 }
5580
5581 static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
5582 {
5583     if (unlikely(ctx->base.singlestep_enabled)) {
5584         return false;
5585     }
5586
5587 #ifndef CONFIG_USER_ONLY
5588     return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
5589 #else
5590     return true;
5591 #endif
5592 }
5593
5594 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
5595 {
5596     if (use_goto_tb(ctx, dest)) {
5597         tcg_gen_goto_tb(n);
5598         gen_save_pc(dest);
5599         tcg_gen_exit_tb(ctx->base.tb, n);
5600     } else {
5601         gen_save_pc(dest);
5602         if (ctx->base.singlestep_enabled) {
5603             save_cpu_state(ctx, 0);
5604             gen_helper_raise_exception_debug(cpu_env);
5605         }
5606         tcg_gen_lookup_and_goto_ptr();
5607     }
5608 }
5609
5610 /* Branches (before delay slot) */
5611 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
5612                                 int insn_bytes,
5613                                 int rs, int rt, int32_t offset,
5614                                 int delayslot_size)
5615 {
5616     target_ulong btgt = -1;
5617     int blink = 0;
5618     int bcond_compute = 0;
5619     TCGv t0 = tcg_temp_new();
5620     TCGv t1 = tcg_temp_new();
5621
5622     if (ctx->hflags & MIPS_HFLAG_BMASK) {
5623 #ifdef MIPS_DEBUG_DISAS
5624         LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
5625                   TARGET_FMT_lx "\n", ctx->base.pc_next);
5626 #endif
5627         generate_exception_end(ctx, EXCP_RI);
5628         goto out;
5629     }
5630
5631     /* Load needed operands */
5632     switch (opc) {
5633     case OPC_BEQ:
5634     case OPC_BEQL:
5635     case OPC_BNE:
5636     case OPC_BNEL:
5637         /* Compare two registers */
5638         if (rs != rt) {
5639             gen_load_gpr(t0, rs);
5640             gen_load_gpr(t1, rt);
5641             bcond_compute = 1;
5642         }
5643         btgt = ctx->base.pc_next + insn_bytes + offset;
5644         break;
5645     case OPC_BGEZ:
5646     case OPC_BGEZAL:
5647     case OPC_BGEZALL:
5648     case OPC_BGEZL:
5649     case OPC_BGTZ:
5650     case OPC_BGTZL:
5651     case OPC_BLEZ:
5652     case OPC_BLEZL:
5653     case OPC_BLTZ:
5654     case OPC_BLTZAL:
5655     case OPC_BLTZALL:
5656     case OPC_BLTZL:
5657         /* Compare to zero */
5658         if (rs != 0) {
5659             gen_load_gpr(t0, rs);
5660             bcond_compute = 1;
5661         }
5662         btgt = ctx->base.pc_next + insn_bytes + offset;
5663         break;
5664     case OPC_BPOSGE32:
5665 #if defined(TARGET_MIPS64)
5666     case OPC_BPOSGE64:
5667         tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
5668 #else
5669         tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5670 #endif
5671         bcond_compute = 1;
5672         btgt = ctx->base.pc_next + insn_bytes + offset;
5673         break;
5674     case OPC_J:
5675     case OPC_JAL:
5676     case OPC_JALX:
5677         /* Jump to immediate */
5678         btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
5679             (uint32_t)offset;
5680         break;
5681     case OPC_JR:
5682     case OPC_JALR:
5683         /* Jump to register */
5684         if (offset != 0 && offset != 16) {
5685             /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5686                others are reserved. */
5687             MIPS_INVAL("jump hint");
5688             generate_exception_end(ctx, EXCP_RI);
5689             goto out;
5690         }
5691         gen_load_gpr(btarget, rs);
5692         break;
5693     default:
5694         MIPS_INVAL("branch/jump");
5695         generate_exception_end(ctx, EXCP_RI);
5696         goto out;
5697     }
5698     if (bcond_compute == 0) {
5699         /* No condition to be computed */
5700         switch (opc) {
5701         case OPC_BEQ:     /* rx == rx        */
5702         case OPC_BEQL:    /* rx == rx likely */
5703         case OPC_BGEZ:    /* 0 >= 0          */
5704         case OPC_BGEZL:   /* 0 >= 0 likely   */
5705         case OPC_BLEZ:    /* 0 <= 0          */
5706         case OPC_BLEZL:   /* 0 <= 0 likely   */
5707             /* Always take */
5708             ctx->hflags |= MIPS_HFLAG_B;
5709             break;
5710         case OPC_BGEZAL:  /* 0 >= 0          */
5711         case OPC_BGEZALL: /* 0 >= 0 likely   */
5712             /* Always take and link */
5713             blink = 31;
5714             ctx->hflags |= MIPS_HFLAG_B;
5715             break;
5716         case OPC_BNE:     /* rx != rx        */
5717         case OPC_BGTZ:    /* 0 > 0           */
5718         case OPC_BLTZ:    /* 0 < 0           */
5719             /* Treat as NOP. */
5720             goto out;
5721         case OPC_BLTZAL:  /* 0 < 0           */
5722             /* Handle as an unconditional branch to get correct delay
5723                slot checking.  */
5724             blink = 31;
5725             btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
5726             ctx->hflags |= MIPS_HFLAG_B;
5727             break;
5728         case OPC_BLTZALL: /* 0 < 0 likely */
5729             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
5730             /* Skip the instruction in the delay slot */
5731             ctx->base.pc_next += 4;
5732             goto out;
5733         case OPC_BNEL:    /* rx != rx likely */
5734         case OPC_BGTZL:   /* 0 > 0 likely */
5735         case OPC_BLTZL:   /* 0 < 0 likely */
5736             /* Skip the instruction in the delay slot */
5737             ctx->base.pc_next += 4;
5738             goto out;
5739         case OPC_J:
5740             ctx->hflags |= MIPS_HFLAG_B;
5741             break;
5742         case OPC_JALX:
5743             ctx->hflags |= MIPS_HFLAG_BX;
5744             /* Fallthrough */
5745         case OPC_JAL:
5746             blink = 31;
5747             ctx->hflags |= MIPS_HFLAG_B;
5748             break;
5749         case OPC_JR:
5750             ctx->hflags |= MIPS_HFLAG_BR;
5751             break;
5752         case OPC_JALR:
5753             blink = rt;
5754             ctx->hflags |= MIPS_HFLAG_BR;
5755             break;
5756         default:
5757             MIPS_INVAL("branch/jump");
5758             generate_exception_end(ctx, EXCP_RI);
5759             goto out;
5760         }
5761     } else {
5762         switch (opc) {
5763         case OPC_BEQ:
5764             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5765             goto not_likely;
5766         case OPC_BEQL:
5767             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5768             goto likely;
5769         case OPC_BNE:
5770             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5771             goto not_likely;
5772         case OPC_BNEL:
5773             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5774             goto likely;
5775         case OPC_BGEZ:
5776             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5777             goto not_likely;
5778         case OPC_BGEZL:
5779             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5780             goto likely;
5781         case OPC_BGEZAL:
5782             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5783             blink = 31;
5784             goto not_likely;
5785         case OPC_BGEZALL:
5786             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5787             blink = 31;
5788             goto likely;
5789         case OPC_BGTZ:
5790             tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5791             goto not_likely;
5792         case OPC_BGTZL:
5793             tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5794             goto likely;
5795         case OPC_BLEZ:
5796             tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
5797             goto not_likely;
5798         case OPC_BLEZL:
5799             tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
5800             goto likely;
5801         case OPC_BLTZ:
5802             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5803             goto not_likely;
5804         case OPC_BLTZL:
5805             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5806             goto likely;
5807         case OPC_BPOSGE32:
5808             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
5809             goto not_likely;
5810 #if defined(TARGET_MIPS64)
5811         case OPC_BPOSGE64:
5812             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
5813             goto not_likely;
5814 #endif
5815         case OPC_BLTZAL:
5816             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5817             blink = 31;
5818         not_likely:
5819             ctx->hflags |= MIPS_HFLAG_BC;
5820             break;
5821         case OPC_BLTZALL:
5822             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5823             blink = 31;
5824         likely:
5825             ctx->hflags |= MIPS_HFLAG_BL;
5826             break;
5827         default:
5828             MIPS_INVAL("conditional branch/jump");
5829             generate_exception_end(ctx, EXCP_RI);
5830             goto out;
5831         }
5832     }
5833
5834     ctx->btarget = btgt;
5835
5836     switch (delayslot_size) {
5837     case 2:
5838         ctx->hflags |= MIPS_HFLAG_BDS16;
5839         break;
5840     case 4:
5841         ctx->hflags |= MIPS_HFLAG_BDS32;
5842         break;
5843     }
5844
5845     if (blink > 0) {
5846         int post_delay = insn_bytes + delayslot_size;
5847         int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
5848
5849         tcg_gen_movi_tl(cpu_gpr[blink],
5850                         ctx->base.pc_next + post_delay + lowbit);
5851     }
5852
5853  out:
5854     if (insn_bytes == 2)
5855         ctx->hflags |= MIPS_HFLAG_B16;
5856     tcg_temp_free(t0);
5857     tcg_temp_free(t1);
5858 }
5859
5860
5861 /* nanoMIPS Branches */
5862 static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc,
5863                                 int insn_bytes,
5864                                 int rs, int rt, int32_t offset)
5865 {
5866     target_ulong btgt = -1;
5867     int bcond_compute = 0;
5868     TCGv t0 = tcg_temp_new();
5869     TCGv t1 = tcg_temp_new();
5870
5871     /* Load needed operands */
5872     switch (opc) {
5873     case OPC_BEQ:
5874     case OPC_BNE:
5875         /* Compare two registers */
5876         if (rs != rt) {
5877             gen_load_gpr(t0, rs);
5878             gen_load_gpr(t1, rt);
5879             bcond_compute = 1;
5880         }
5881         btgt = ctx->base.pc_next + insn_bytes + offset;
5882         break;
5883     case OPC_BGEZAL:
5884         /* Compare to zero */
5885         if (rs != 0) {
5886             gen_load_gpr(t0, rs);
5887             bcond_compute = 1;
5888         }
5889         btgt = ctx->base.pc_next + insn_bytes + offset;
5890         break;
5891     case OPC_BPOSGE32:
5892         tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5893         bcond_compute = 1;
5894         btgt = ctx->base.pc_next + insn_bytes + offset;
5895         break;
5896     case OPC_JR:
5897     case OPC_JALR:
5898         /* Jump to register */
5899         if (offset != 0 && offset != 16) {
5900             /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5901                others are reserved. */
5902             MIPS_INVAL("jump hint");
5903             generate_exception_end(ctx, EXCP_RI);
5904             goto out;
5905         }
5906         gen_load_gpr(btarget, rs);
5907         break;
5908     default:
5909         MIPS_INVAL("branch/jump");
5910         generate_exception_end(ctx, EXCP_RI);
5911         goto out;
5912     }
5913     if (bcond_compute == 0) {
5914         /* No condition to be computed */
5915         switch (opc) {
5916         case OPC_BEQ:     /* rx == rx        */
5917             /* Always take */
5918             ctx->hflags |= MIPS_HFLAG_B;
5919             break;
5920         case OPC_BGEZAL:  /* 0 >= 0          */
5921             /* Always take and link */
5922             tcg_gen_movi_tl(cpu_gpr[31],
5923                             ctx->base.pc_next + insn_bytes);
5924             ctx->hflags |= MIPS_HFLAG_B;
5925             break;
5926         case OPC_BNE:     /* rx != rx        */
5927             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
5928             /* Skip the instruction in the delay slot */
5929             ctx->base.pc_next += 4;
5930             goto out;
5931         case OPC_JR:
5932             ctx->hflags |= MIPS_HFLAG_BR;
5933             break;
5934         case OPC_JALR:
5935             if (rt > 0) {
5936                 tcg_gen_movi_tl(cpu_gpr[rt],
5937                                 ctx->base.pc_next + insn_bytes);
5938             }
5939             ctx->hflags |= MIPS_HFLAG_BR;
5940             break;
5941         default:
5942             MIPS_INVAL("branch/jump");
5943             generate_exception_end(ctx, EXCP_RI);
5944             goto out;
5945         }
5946     } else {
5947         switch (opc) {
5948         case OPC_BEQ:
5949             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5950             goto not_likely;
5951         case OPC_BNE:
5952             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5953             goto not_likely;
5954         case OPC_BGEZAL:
5955             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5956             tcg_gen_movi_tl(cpu_gpr[31],
5957                             ctx->base.pc_next + insn_bytes);
5958             goto not_likely;
5959         case OPC_BPOSGE32:
5960             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
5961         not_likely:
5962             ctx->hflags |= MIPS_HFLAG_BC;
5963             break;
5964         default:
5965             MIPS_INVAL("conditional branch/jump");
5966             generate_exception_end(ctx, EXCP_RI);
5967             goto out;
5968         }
5969     }
5970
5971     ctx->btarget = btgt;
5972
5973  out:
5974     if (insn_bytes == 2) {
5975         ctx->hflags |= MIPS_HFLAG_B16;
5976     }
5977     tcg_temp_free(t0);
5978     tcg_temp_free(t1);
5979 }
5980
5981
5982 /* special3 bitfield operations */
5983 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
5984                         int rs, int lsb, int msb)
5985 {
5986     TCGv t0 = tcg_temp_new();
5987     TCGv t1 = tcg_temp_new();
5988
5989     gen_load_gpr(t1, rs);
5990     switch (opc) {
5991     case OPC_EXT:
5992         if (lsb + msb > 31) {
5993             goto fail;
5994         }
5995         if (msb != 31) {
5996             tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
5997         } else {
5998             /* The two checks together imply that lsb == 0,
5999                so this is a simple sign-extension.  */
6000             tcg_gen_ext32s_tl(t0, t1);
6001         }
6002         break;
6003 #if defined(TARGET_MIPS64)
6004     case OPC_DEXTU:
6005         lsb += 32;
6006         goto do_dext;
6007     case OPC_DEXTM:
6008         msb += 32;
6009         goto do_dext;
6010     case OPC_DEXT:
6011     do_dext:
6012         if (lsb + msb > 63) {
6013             goto fail;
6014         }
6015         tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
6016         break;
6017 #endif
6018     case OPC_INS:
6019         if (lsb > msb) {
6020             goto fail;
6021         }
6022         gen_load_gpr(t0, rt);
6023         tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
6024         tcg_gen_ext32s_tl(t0, t0);
6025         break;
6026 #if defined(TARGET_MIPS64)
6027     case OPC_DINSU:
6028         lsb += 32;
6029         /* FALLTHRU */
6030     case OPC_DINSM:
6031         msb += 32;
6032         /* FALLTHRU */
6033     case OPC_DINS:
6034         if (lsb > msb) {
6035             goto fail;
6036         }
6037         gen_load_gpr(t0, rt);
6038         tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
6039         break;
6040 #endif
6041     default:
6042 fail:
6043         MIPS_INVAL("bitops");
6044         generate_exception_end(ctx, EXCP_RI);
6045         tcg_temp_free(t0);
6046         tcg_temp_free(t1);
6047         return;
6048     }
6049     gen_store_gpr(t0, rt);
6050     tcg_temp_free(t0);
6051     tcg_temp_free(t1);
6052 }
6053
6054 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
6055 {
6056     TCGv t0;
6057
6058     if (rd == 0) {
6059         /* If no destination, treat it as a NOP. */
6060         return;
6061     }
6062
6063     t0 = tcg_temp_new();
6064     gen_load_gpr(t0, rt);
6065     switch (op2) {
6066     case OPC_WSBH:
6067         {
6068             TCGv t1 = tcg_temp_new();
6069             TCGv t2 = tcg_const_tl(0x00FF00FF);
6070
6071             tcg_gen_shri_tl(t1, t0, 8);
6072             tcg_gen_and_tl(t1, t1, t2);
6073             tcg_gen_and_tl(t0, t0, t2);
6074             tcg_gen_shli_tl(t0, t0, 8);
6075             tcg_gen_or_tl(t0, t0, t1);
6076             tcg_temp_free(t2);
6077             tcg_temp_free(t1);
6078             tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6079         }
6080         break;
6081     case OPC_SEB:
6082         tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
6083         break;
6084     case OPC_SEH:
6085         tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
6086         break;
6087 #if defined(TARGET_MIPS64)
6088     case OPC_DSBH:
6089         {
6090             TCGv t1 = tcg_temp_new();
6091             TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
6092
6093             tcg_gen_shri_tl(t1, t0, 8);
6094             tcg_gen_and_tl(t1, t1, t2);
6095             tcg_gen_and_tl(t0, t0, t2);
6096             tcg_gen_shli_tl(t0, t0, 8);
6097             tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
6098             tcg_temp_free(t2);
6099             tcg_temp_free(t1);
6100         }
6101         break;
6102     case OPC_DSHD:
6103         {
6104             TCGv t1 = tcg_temp_new();
6105             TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
6106
6107             tcg_gen_shri_tl(t1, t0, 16);
6108             tcg_gen_and_tl(t1, t1, t2);
6109             tcg_gen_and_tl(t0, t0, t2);
6110             tcg_gen_shli_tl(t0, t0, 16);
6111             tcg_gen_or_tl(t0, t0, t1);
6112             tcg_gen_shri_tl(t1, t0, 32);
6113             tcg_gen_shli_tl(t0, t0, 32);
6114             tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
6115             tcg_temp_free(t2);
6116             tcg_temp_free(t1);
6117         }
6118         break;
6119 #endif
6120     default:
6121         MIPS_INVAL("bsfhl");
6122         generate_exception_end(ctx, EXCP_RI);
6123         tcg_temp_free(t0);
6124         return;
6125     }
6126     tcg_temp_free(t0);
6127 }
6128
6129 static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
6130                     int imm2)
6131 {
6132     TCGv t0;
6133     TCGv t1;
6134     if (rd == 0) {
6135         /* Treat as NOP. */
6136         return;
6137     }
6138     t0 = tcg_temp_new();
6139     t1 = tcg_temp_new();
6140     gen_load_gpr(t0, rs);
6141     gen_load_gpr(t1, rt);
6142     tcg_gen_shli_tl(t0, t0, imm2 + 1);
6143     tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
6144     if (opc == OPC_LSA) {
6145         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
6146     }
6147
6148     tcg_temp_free(t1);
6149     tcg_temp_free(t0);
6150
6151     return;
6152 }
6153
6154 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
6155                            int rt, int bits)
6156 {
6157     TCGv t0;
6158     if (rd == 0) {
6159         /* Treat as NOP. */
6160         return;
6161     }
6162     t0 = tcg_temp_new();
6163     if (bits == 0 || bits == wordsz) {
6164         if (bits == 0) {
6165             gen_load_gpr(t0, rt);
6166         } else {
6167             gen_load_gpr(t0, rs);
6168         }
6169         switch (wordsz) {
6170         case 32:
6171             tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6172             break;
6173 #if defined(TARGET_MIPS64)
6174         case 64:
6175             tcg_gen_mov_tl(cpu_gpr[rd], t0);
6176             break;
6177 #endif
6178         }
6179     } else {
6180         TCGv t1 = tcg_temp_new();
6181         gen_load_gpr(t0, rt);
6182         gen_load_gpr(t1, rs);
6183         switch (wordsz) {
6184         case 32:
6185             {
6186                 TCGv_i64 t2 = tcg_temp_new_i64();
6187                 tcg_gen_concat_tl_i64(t2, t1, t0);
6188                 tcg_gen_shri_i64(t2, t2, 32 - bits);
6189                 gen_move_low32(cpu_gpr[rd], t2);
6190                 tcg_temp_free_i64(t2);
6191             }
6192             break;
6193 #if defined(TARGET_MIPS64)
6194         case 64:
6195             tcg_gen_shli_tl(t0, t0, bits);
6196             tcg_gen_shri_tl(t1, t1, 64 - bits);
6197             tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
6198             break;
6199 #endif
6200         }
6201         tcg_temp_free(t1);
6202     }
6203
6204     tcg_temp_free(t0);
6205 }
6206
6207 static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6208                       int bp)
6209 {
6210     gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
6211 }
6212
6213 static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6214                     int shift)
6215 {
6216     gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift);
6217 }
6218
6219 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
6220 {
6221     TCGv t0;
6222     if (rd == 0) {
6223         /* Treat as NOP. */
6224         return;
6225     }
6226     t0 = tcg_temp_new();
6227     gen_load_gpr(t0, rt);
6228     switch (opc) {
6229     case OPC_BITSWAP:
6230         gen_helper_bitswap(cpu_gpr[rd], t0);
6231         break;
6232 #if defined(TARGET_MIPS64)
6233     case OPC_DBITSWAP:
6234         gen_helper_dbitswap(cpu_gpr[rd], t0);
6235         break;
6236 #endif
6237     }
6238     tcg_temp_free(t0);
6239 }
6240
6241 #ifndef CONFIG_USER_ONLY
6242 /* CP0 (MMU and control) */
6243 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
6244 {
6245     TCGv_i64 t0 = tcg_temp_new_i64();
6246     TCGv_i64 t1 = tcg_temp_new_i64();
6247
6248     tcg_gen_ext_tl_i64(t0, arg);
6249     tcg_gen_ld_i64(t1, cpu_env, off);
6250 #if defined(TARGET_MIPS64)
6251     tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
6252 #else
6253     tcg_gen_concat32_i64(t1, t1, t0);
6254 #endif
6255     tcg_gen_st_i64(t1, cpu_env, off);
6256     tcg_temp_free_i64(t1);
6257     tcg_temp_free_i64(t0);
6258 }
6259
6260 static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
6261 {
6262     TCGv_i64 t0 = tcg_temp_new_i64();
6263     TCGv_i64 t1 = tcg_temp_new_i64();
6264
6265     tcg_gen_ext_tl_i64(t0, arg);
6266     tcg_gen_ld_i64(t1, cpu_env, off);
6267     tcg_gen_concat32_i64(t1, t1, t0);
6268     tcg_gen_st_i64(t1, cpu_env, off);
6269     tcg_temp_free_i64(t1);
6270     tcg_temp_free_i64(t0);
6271 }
6272
6273 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
6274 {
6275     TCGv_i64 t0 = tcg_temp_new_i64();
6276
6277     tcg_gen_ld_i64(t0, cpu_env, off);
6278 #if defined(TARGET_MIPS64)
6279     tcg_gen_shri_i64(t0, t0, 30);
6280 #else
6281     tcg_gen_shri_i64(t0, t0, 32);
6282 #endif
6283     gen_move_low32(arg, t0);
6284     tcg_temp_free_i64(t0);
6285 }
6286
6287 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
6288 {
6289     TCGv_i64 t0 = tcg_temp_new_i64();
6290
6291     tcg_gen_ld_i64(t0, cpu_env, off);
6292     tcg_gen_shri_i64(t0, t0, 32 + shift);
6293     gen_move_low32(arg, t0);
6294     tcg_temp_free_i64(t0);
6295 }
6296
6297 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
6298 {
6299     TCGv_i32 t0 = tcg_temp_new_i32();
6300
6301     tcg_gen_ld_i32(t0, cpu_env, off);
6302     tcg_gen_ext_i32_tl(arg, t0);
6303     tcg_temp_free_i32(t0);
6304 }
6305
6306 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
6307 {
6308     tcg_gen_ld_tl(arg, cpu_env, off);
6309     tcg_gen_ext32s_tl(arg, arg);
6310 }
6311
6312 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
6313 {
6314     TCGv_i32 t0 = tcg_temp_new_i32();
6315
6316     tcg_gen_trunc_tl_i32(t0, arg);
6317     tcg_gen_st_i32(t0, cpu_env, off);
6318     tcg_temp_free_i32(t0);
6319 }
6320
6321 #define CP0_CHECK(c)                            \
6322     do {                                        \
6323         if (!(c)) {                             \
6324             goto cp0_unimplemented;             \
6325         }                                       \
6326     } while (0)
6327
6328 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6329 {
6330     const char *rn = "invalid";
6331
6332     switch (reg) {
6333     case 2:
6334         switch (sel) {
6335         case 0:
6336             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6337             gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6338             rn = "EntryLo0";
6339             break;
6340         default:
6341             goto cp0_unimplemented;
6342         }
6343         break;
6344     case 3:
6345         switch (sel) {
6346         case 0:
6347             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6348             gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6349             rn = "EntryLo1";
6350             break;
6351         default:
6352             goto cp0_unimplemented;
6353         }
6354         break;
6355     case 17:
6356         switch (sel) {
6357         case 0:
6358             gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
6359                              ctx->CP0_LLAddr_shift);
6360             rn = "LLAddr";
6361             break;
6362         case 1:
6363             CP0_CHECK(ctx->mrp);
6364             gen_helper_mfhc0_maar(arg, cpu_env);
6365             rn = "MAAR";
6366             break;
6367         default:
6368             goto cp0_unimplemented;
6369         }
6370         break;
6371     case 28:
6372         switch (sel) {
6373         case 0:
6374         case 2:
6375         case 4:
6376         case 6:
6377             gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
6378             rn = "TagLo";
6379             break;
6380         default:
6381             goto cp0_unimplemented;
6382         }
6383         break;
6384     default:
6385         goto cp0_unimplemented;
6386     }
6387     trace_mips_translate_c0("mfhc0", rn, reg, sel);
6388     return;
6389
6390 cp0_unimplemented:
6391     qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
6392     tcg_gen_movi_tl(arg, 0);
6393 }
6394
6395 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6396 {
6397     const char *rn = "invalid";
6398     uint64_t mask = ctx->PAMask >> 36;
6399
6400     switch (reg) {
6401     case 2:
6402         switch (sel) {
6403         case 0:
6404             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6405             tcg_gen_andi_tl(arg, arg, mask);
6406             gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6407             rn = "EntryLo0";
6408             break;
6409         default:
6410             goto cp0_unimplemented;
6411         }
6412         break;
6413     case 3:
6414         switch (sel) {
6415         case 0:
6416             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6417             tcg_gen_andi_tl(arg, arg, mask);
6418             gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6419             rn = "EntryLo1";
6420             break;
6421         default:
6422             goto cp0_unimplemented;
6423         }
6424         break;
6425     case 17:
6426         switch (sel) {
6427         case 0:
6428             /* LLAddr is read-only (the only exception is bit 0 if LLB is
6429                supported); the CP0_LLAddr_rw_bitmask does not seem to be
6430                relevant for modern MIPS cores supporting MTHC0, therefore
6431                treating MTHC0 to LLAddr as NOP. */
6432             rn = "LLAddr";
6433             break;
6434         case 1:
6435             CP0_CHECK(ctx->mrp);
6436             gen_helper_mthc0_maar(cpu_env, arg);
6437             rn = "MAAR";
6438             break;
6439         default:
6440             goto cp0_unimplemented;
6441         }
6442         break;
6443     case 28:
6444         switch (sel) {
6445         case 0:
6446         case 2:
6447         case 4:
6448         case 6:
6449             tcg_gen_andi_tl(arg, arg, mask);
6450             gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
6451             rn = "TagLo";
6452             break;
6453         default:
6454             goto cp0_unimplemented;
6455         }
6456         break;
6457     default:
6458         goto cp0_unimplemented;
6459     }
6460     trace_mips_translate_c0("mthc0", rn, reg, sel);
6461
6462 cp0_unimplemented:
6463     qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
6464 }
6465
6466 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
6467 {
6468     if (ctx->insn_flags & ISA_MIPS32R6) {
6469         tcg_gen_movi_tl(arg, 0);
6470     } else {
6471         tcg_gen_movi_tl(arg, ~0);
6472     }
6473 }
6474
6475 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6476 {
6477     const char *rn = "invalid";
6478
6479     if (sel != 0)
6480         check_insn(ctx, ISA_MIPS32);
6481
6482     switch (reg) {
6483     case 0:
6484         switch (sel) {
6485         case 0:
6486             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
6487             rn = "Index";
6488             break;
6489         case 1:
6490             CP0_CHECK(ctx->insn_flags & ASE_MT);
6491             gen_helper_mfc0_mvpcontrol(arg, cpu_env);
6492             rn = "MVPControl";
6493             break;
6494         case 2:
6495             CP0_CHECK(ctx->insn_flags & ASE_MT);
6496             gen_helper_mfc0_mvpconf0(arg, cpu_env);
6497             rn = "MVPConf0";
6498             break;
6499         case 3:
6500             CP0_CHECK(ctx->insn_flags & ASE_MT);
6501             gen_helper_mfc0_mvpconf1(arg, cpu_env);
6502             rn = "MVPConf1";
6503             break;
6504         case 4:
6505             CP0_CHECK(ctx->vp);
6506             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6507             rn = "VPControl";
6508             break;
6509         default:
6510             goto cp0_unimplemented;
6511         }
6512         break;
6513     case 1:
6514         switch (sel) {
6515         case 0:
6516             CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6517             gen_helper_mfc0_random(arg, cpu_env);
6518             rn = "Random";
6519             break;
6520         case 1:
6521             CP0_CHECK(ctx->insn_flags & ASE_MT);
6522             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
6523             rn = "VPEControl";
6524             break;
6525         case 2:
6526             CP0_CHECK(ctx->insn_flags & ASE_MT);
6527             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
6528             rn = "VPEConf0";
6529             break;
6530         case 3:
6531             CP0_CHECK(ctx->insn_flags & ASE_MT);
6532             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
6533             rn = "VPEConf1";
6534             break;
6535         case 4:
6536             CP0_CHECK(ctx->insn_flags & ASE_MT);
6537             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
6538             rn = "YQMask";
6539             break;
6540         case 5:
6541             CP0_CHECK(ctx->insn_flags & ASE_MT);
6542             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
6543             rn = "VPESchedule";
6544             break;
6545         case 6:
6546             CP0_CHECK(ctx->insn_flags & ASE_MT);
6547             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6548             rn = "VPEScheFBack";
6549             break;
6550         case 7:
6551             CP0_CHECK(ctx->insn_flags & ASE_MT);
6552             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
6553             rn = "VPEOpt";
6554             break;
6555         default:
6556             goto cp0_unimplemented;
6557         }
6558         break;
6559     case 2:
6560         switch (sel) {
6561         case 0:
6562             {
6563                 TCGv_i64 tmp = tcg_temp_new_i64();
6564                 tcg_gen_ld_i64(tmp, cpu_env,
6565                                offsetof(CPUMIPSState, CP0_EntryLo0));
6566 #if defined(TARGET_MIPS64)
6567                 if (ctx->rxi) {
6568                     /* Move RI/XI fields to bits 31:30 */
6569                     tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6570                     tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6571                 }
6572 #endif
6573                 gen_move_low32(arg, tmp);
6574                 tcg_temp_free_i64(tmp);
6575             }
6576             rn = "EntryLo0";
6577             break;
6578         case 1:
6579             CP0_CHECK(ctx->insn_flags & ASE_MT);
6580             gen_helper_mfc0_tcstatus(arg, cpu_env);
6581             rn = "TCStatus";
6582             break;
6583         case 2:
6584             CP0_CHECK(ctx->insn_flags & ASE_MT);
6585             gen_helper_mfc0_tcbind(arg, cpu_env);
6586             rn = "TCBind";
6587             break;
6588         case 3:
6589             CP0_CHECK(ctx->insn_flags & ASE_MT);
6590             gen_helper_mfc0_tcrestart(arg, cpu_env);
6591             rn = "TCRestart";
6592             break;
6593         case 4:
6594             CP0_CHECK(ctx->insn_flags & ASE_MT);
6595             gen_helper_mfc0_tchalt(arg, cpu_env);
6596             rn = "TCHalt";
6597             break;
6598         case 5:
6599             CP0_CHECK(ctx->insn_flags & ASE_MT);
6600             gen_helper_mfc0_tccontext(arg, cpu_env);
6601             rn = "TCContext";
6602             break;
6603         case 6:
6604             CP0_CHECK(ctx->insn_flags & ASE_MT);
6605             gen_helper_mfc0_tcschedule(arg, cpu_env);
6606             rn = "TCSchedule";
6607             break;
6608         case 7:
6609             CP0_CHECK(ctx->insn_flags & ASE_MT);
6610             gen_helper_mfc0_tcschefback(arg, cpu_env);
6611             rn = "TCScheFBack";
6612             break;
6613         default:
6614             goto cp0_unimplemented;
6615         }
6616         break;
6617     case 3:
6618         switch (sel) {
6619         case 0:
6620             {
6621                 TCGv_i64 tmp = tcg_temp_new_i64();
6622                 tcg_gen_ld_i64(tmp, cpu_env,
6623                                offsetof(CPUMIPSState, CP0_EntryLo1));
6624 #if defined(TARGET_MIPS64)
6625                 if (ctx->rxi) {
6626                     /* Move RI/XI fields to bits 31:30 */
6627                     tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6628                     tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6629                 }
6630 #endif
6631                 gen_move_low32(arg, tmp);
6632                 tcg_temp_free_i64(tmp);
6633             }
6634             rn = "EntryLo1";
6635             break;
6636         case 1:
6637             CP0_CHECK(ctx->vp);
6638             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6639             rn = "GlobalNumber";
6640             break;
6641         default:
6642             goto cp0_unimplemented;
6643         }
6644         break;
6645     case 4:
6646         switch (sel) {
6647         case 0:
6648             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
6649             tcg_gen_ext32s_tl(arg, arg);
6650             rn = "Context";
6651             break;
6652         case 1:
6653 //            gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
6654             rn = "ContextConfig";
6655             goto cp0_unimplemented;
6656         case 2:
6657             CP0_CHECK(ctx->ulri);
6658             tcg_gen_ld_tl(arg, cpu_env,
6659                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6660             tcg_gen_ext32s_tl(arg, arg);
6661             rn = "UserLocal";
6662             break;
6663         default:
6664             goto cp0_unimplemented;
6665         }
6666         break;
6667     case 5:
6668         switch (sel) {
6669         case 0:
6670             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
6671             rn = "PageMask";
6672             break;
6673         case 1:
6674             check_insn(ctx, ISA_MIPS32R2);
6675             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
6676             rn = "PageGrain";
6677             break;
6678         case 2:
6679             CP0_CHECK(ctx->sc);
6680             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
6681             tcg_gen_ext32s_tl(arg, arg);
6682             rn = "SegCtl0";
6683             break;
6684         case 3:
6685             CP0_CHECK(ctx->sc);
6686             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
6687             tcg_gen_ext32s_tl(arg, arg);
6688             rn = "SegCtl1";
6689             break;
6690         case 4:
6691             CP0_CHECK(ctx->sc);
6692             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
6693             tcg_gen_ext32s_tl(arg, arg);
6694             rn = "SegCtl2";
6695             break;
6696         case 5:
6697             check_pw(ctx);
6698             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6699             rn = "PWBase";
6700             break;
6701         case 6:
6702             check_pw(ctx);
6703             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
6704             rn = "PWField";
6705             break;
6706         case 7:
6707             check_pw(ctx);
6708             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
6709             rn = "PWSize";
6710             break;
6711         default:
6712             goto cp0_unimplemented;
6713         }
6714         break;
6715     case 6:
6716         switch (sel) {
6717         case 0:
6718             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
6719             rn = "Wired";
6720             break;
6721         case 1:
6722             check_insn(ctx, ISA_MIPS32R2);
6723             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
6724             rn = "SRSConf0";
6725             break;
6726         case 2:
6727             check_insn(ctx, ISA_MIPS32R2);
6728             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
6729             rn = "SRSConf1";
6730             break;
6731         case 3:
6732             check_insn(ctx, ISA_MIPS32R2);
6733             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
6734             rn = "SRSConf2";
6735             break;
6736         case 4:
6737             check_insn(ctx, ISA_MIPS32R2);
6738             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
6739             rn = "SRSConf3";
6740             break;
6741         case 5:
6742             check_insn(ctx, ISA_MIPS32R2);
6743             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
6744             rn = "SRSConf4";
6745             break;
6746         case 6:
6747             check_pw(ctx);
6748             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
6749             rn = "PWCtl";
6750             break;
6751         default:
6752             goto cp0_unimplemented;
6753         }
6754         break;
6755     case 7:
6756         switch (sel) {
6757         case 0:
6758             check_insn(ctx, ISA_MIPS32R2);
6759             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
6760             rn = "HWREna";
6761             break;
6762         default:
6763             goto cp0_unimplemented;
6764         }
6765         break;
6766     case 8:
6767         switch (sel) {
6768         case 0:
6769             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
6770             tcg_gen_ext32s_tl(arg, arg);
6771             rn = "BadVAddr";
6772             break;
6773         case 1:
6774             CP0_CHECK(ctx->bi);
6775             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6776             rn = "BadInstr";
6777             break;
6778         case 2:
6779             CP0_CHECK(ctx->bp);
6780             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6781             rn = "BadInstrP";
6782             break;
6783         case 3:
6784             CP0_CHECK(ctx->bi);
6785             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
6786             tcg_gen_andi_tl(arg, arg, ~0xffff);
6787             rn = "BadInstrX";
6788             break;
6789        default:
6790             goto cp0_unimplemented;
6791         }
6792         break;
6793     case 9:
6794         switch (sel) {
6795         case 0:
6796             /* Mark as an IO operation because we read the time.  */
6797             if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
6798                 gen_io_start();
6799             }
6800             gen_helper_mfc0_count(arg, cpu_env);
6801             if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
6802                 gen_io_end();
6803             }
6804             /* Break the TB to be able to take timer interrupts immediately
6805                after reading count. DISAS_STOP isn't sufficient, we need to
6806                ensure we break completely out of translated code.  */
6807             gen_save_pc(ctx->base.pc_next + 4);
6808             ctx->base.is_jmp = DISAS_EXIT;
6809             rn = "Count";
6810             break;
6811         /* 6,7 are implementation dependent */
6812         default:
6813             goto cp0_unimplemented;
6814         }
6815         break;
6816     case 10:
6817         switch (sel) {
6818         case 0:
6819             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
6820             tcg_gen_ext32s_tl(arg, arg);
6821             rn = "EntryHi";
6822             break;
6823         default:
6824             goto cp0_unimplemented;
6825         }
6826         break;
6827     case 11:
6828         switch (sel) {
6829         case 0:
6830             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
6831             rn = "Compare";
6832             break;
6833         /* 6,7 are implementation dependent */
6834         default:
6835             goto cp0_unimplemented;
6836         }
6837         break;
6838     case 12:
6839         switch (sel) {
6840         case 0:
6841             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
6842             rn = "Status";
6843             break;
6844         case 1:
6845             check_insn(ctx, ISA_MIPS32R2);
6846             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
6847             rn = "IntCtl";
6848             break;
6849         case 2:
6850             check_insn(ctx, ISA_MIPS32R2);
6851             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
6852             rn = "SRSCtl";
6853             break;
6854         case 3:
6855             check_insn(ctx, ISA_MIPS32R2);
6856             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6857             rn = "SRSMap";
6858             break;
6859         default:
6860             goto cp0_unimplemented;
6861        }
6862         break;
6863     case 13:
6864         switch (sel) {
6865         case 0:
6866             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
6867             rn = "Cause";
6868             break;
6869         default:
6870             goto cp0_unimplemented;
6871        }
6872         break;
6873     case 14:
6874         switch (sel) {
6875         case 0:
6876             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6877             tcg_gen_ext32s_tl(arg, arg);
6878             rn = "EPC";
6879             break;
6880         default:
6881             goto cp0_unimplemented;
6882         }
6883         break;
6884     case 15:
6885         switch (sel) {
6886         case 0:
6887             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
6888             rn = "PRid";
6889             break;
6890         case 1:
6891             check_insn(ctx, ISA_MIPS32R2);
6892             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
6893             tcg_gen_ext32s_tl(arg, arg);
6894             rn = "EBase";
6895             break;
6896         case 3:
6897             check_insn(ctx, ISA_MIPS32R2);
6898             CP0_CHECK(ctx->cmgcr);
6899             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6900             tcg_gen_ext32s_tl(arg, arg);
6901             rn = "CMGCRBase";
6902             break;
6903         default:
6904             goto cp0_unimplemented;
6905        }
6906         break;
6907     case 16:
6908         switch (sel) {
6909         case 0:
6910             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
6911             rn = "Config";
6912             break;
6913         case 1:
6914             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
6915             rn = "Config1";
6916             break;
6917         case 2:
6918             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
6919             rn = "Config2";
6920             break;
6921         case 3:
6922             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
6923             rn = "Config3";
6924             break;
6925         case 4:
6926             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6927             rn = "Config4";
6928             break;
6929         case 5:
6930             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6931             rn = "Config5";
6932             break;
6933         /* 6,7 are implementation dependent */
6934         case 6:
6935             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
6936             rn = "Config6";
6937             break;
6938         case 7:
6939             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
6940             rn = "Config7";
6941             break;
6942         default:
6943             goto cp0_unimplemented;
6944         }
6945         break;
6946     case 17:
6947         switch (sel) {
6948         case 0:
6949             gen_helper_mfc0_lladdr(arg, cpu_env);
6950             rn = "LLAddr";
6951             break;
6952         case 1:
6953             CP0_CHECK(ctx->mrp);
6954             gen_helper_mfc0_maar(arg, cpu_env);
6955             rn = "MAAR";
6956             break;
6957         case 2:
6958             CP0_CHECK(ctx->mrp);
6959             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
6960             rn = "MAARI";
6961             break;
6962         default:
6963             goto cp0_unimplemented;
6964         }
6965         break;
6966     case 18:
6967         switch (sel) {
6968         case 0:
6969         case 1:
6970         case 2:
6971         case 3:
6972         case 4:
6973         case 5:
6974         case 6:
6975         case 7:
6976             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6977             gen_helper_1e0i(mfc0_watchlo, arg, sel);
6978             rn = "WatchLo";
6979             break;
6980         default:
6981             goto cp0_unimplemented;
6982         }
6983         break;
6984     case 19:
6985         switch (sel) {
6986         case 0:
6987         case 1:
6988         case 2:
6989         case 3:
6990         case 4:
6991         case 5:
6992         case 6:
6993         case 7:
6994             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6995             gen_helper_1e0i(mfc0_watchhi, arg, sel);
6996             rn = "WatchHi";
6997             break;
6998         default:
6999             goto cp0_unimplemented;
7000         }
7001         break;
7002     case 20:
7003         switch (sel) {
7004         case 0:
7005 #if defined(TARGET_MIPS64)
7006             check_insn(ctx, ISA_MIPS3);
7007             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
7008             tcg_gen_ext32s_tl(arg, arg);
7009             rn = "XContext";
7010             break;
7011 #endif
7012         default:
7013             goto cp0_unimplemented;
7014         }
7015         break;
7016     case 21:
7017        /* Officially reserved, but sel 0 is used for R1x000 framemask */
7018         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7019         switch (sel) {
7020         case 0:
7021             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
7022             rn = "Framemask";
7023             break;
7024         default:
7025             goto cp0_unimplemented;
7026         }
7027         break;
7028     case 22:
7029         tcg_gen_movi_tl(arg, 0); /* unimplemented */
7030         rn = "'Diagnostic"; /* implementation dependent */
7031         break;
7032     case 23:
7033         switch (sel) {
7034         case 0:
7035             gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
7036             rn = "Debug";
7037             break;
7038         case 1:
7039 //            gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
7040             rn = "TraceControl";
7041             goto cp0_unimplemented;
7042         case 2:
7043 //            gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
7044             rn = "TraceControl2";
7045             goto cp0_unimplemented;
7046         case 3:
7047 //            gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
7048             rn = "UserTraceData";
7049             goto cp0_unimplemented;
7050         case 4:
7051 //            gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
7052             rn = "TraceBPC";
7053             goto cp0_unimplemented;
7054         default:
7055             goto cp0_unimplemented;
7056         }
7057         break;
7058     case 24:
7059         switch (sel) {
7060         case 0:
7061             /* EJTAG support */
7062             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7063             tcg_gen_ext32s_tl(arg, arg);
7064             rn = "DEPC";
7065             break;
7066         default:
7067             goto cp0_unimplemented;
7068         }
7069         break;
7070     case 25:
7071         switch (sel) {
7072         case 0:
7073             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
7074             rn = "Performance0";
7075             break;
7076         case 1:
7077 //            gen_helper_mfc0_performance1(arg);
7078             rn = "Performance1";
7079             goto cp0_unimplemented;
7080         case 2:
7081 //            gen_helper_mfc0_performance2(arg);
7082             rn = "Performance2";
7083             goto cp0_unimplemented;
7084         case 3:
7085 //            gen_helper_mfc0_performance3(arg);
7086             rn = "Performance3";
7087             goto cp0_unimplemented;
7088         case 4:
7089 //            gen_helper_mfc0_performance4(arg);
7090             rn = "Performance4";
7091             goto cp0_unimplemented;
7092         case 5:
7093 //            gen_helper_mfc0_performance5(arg);
7094             rn = "Performance5";
7095             goto cp0_unimplemented;
7096         case 6:
7097 //            gen_helper_mfc0_performance6(arg);
7098             rn = "Performance6";
7099             goto cp0_unimplemented;
7100         case 7:
7101 //            gen_helper_mfc0_performance7(arg);
7102             rn = "Performance7";
7103             goto cp0_unimplemented;
7104         default:
7105             goto cp0_unimplemented;
7106         }
7107         break;
7108     case 26:
7109         switch (sel) {
7110         case 0:
7111             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7112             rn = "ErrCtl";
7113             break;
7114         default:
7115             goto cp0_unimplemented;
7116         }
7117         break;
7118     case 27:
7119         switch (sel) {
7120         case 0:
7121         case 1:
7122         case 2:
7123         case 3:
7124             tcg_gen_movi_tl(arg, 0); /* unimplemented */
7125             rn = "CacheErr";
7126             break;
7127         default:
7128             goto cp0_unimplemented;
7129         }
7130         break;
7131     case 28:
7132         switch (sel) {
7133         case 0:
7134         case 2:
7135         case 4:
7136         case 6:
7137             {
7138                 TCGv_i64 tmp = tcg_temp_new_i64();
7139                 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
7140                 gen_move_low32(arg, tmp);
7141                 tcg_temp_free_i64(tmp);
7142             }
7143             rn = "TagLo";
7144             break;
7145         case 1:
7146         case 3:
7147         case 5:
7148         case 7:
7149             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
7150             rn = "DataLo";
7151             break;
7152         default:
7153             goto cp0_unimplemented;
7154         }
7155         break;
7156     case 29:
7157         switch (sel) {
7158         case 0:
7159         case 2:
7160         case 4:
7161         case 6:
7162             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7163             rn = "TagHi";
7164             break;
7165         case 1:
7166         case 3:
7167         case 5:
7168         case 7:
7169             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7170             rn = "DataHi";
7171             break;
7172         default:
7173             goto cp0_unimplemented;
7174         }
7175         break;
7176     case 30:
7177         switch (sel) {
7178         case 0:
7179             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7180             tcg_gen_ext32s_tl(arg, arg);
7181             rn = "ErrorEPC";
7182             break;
7183         default:
7184             goto cp0_unimplemented;
7185         }
7186         break;
7187     case 31:
7188         switch (sel) {
7189         case 0:
7190             /* EJTAG support */
7191             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7192             rn = "DESAVE";
7193             break;
7194         case 2:
7195         case 3:
7196         case 4:
7197         case 5:
7198         case 6:
7199         case 7:
7200             CP0_CHECK(ctx->kscrexist & (1 << sel));
7201             tcg_gen_ld_tl(arg, cpu_env,
7202                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7203             tcg_gen_ext32s_tl(arg, arg);
7204             rn = "KScratch";
7205             break;
7206         default:
7207             goto cp0_unimplemented;
7208         }
7209         break;
7210     default:
7211        goto cp0_unimplemented;
7212     }
7213     trace_mips_translate_c0("mfc0", rn, reg, sel);
7214     return;
7215
7216 cp0_unimplemented:
7217     qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
7218     gen_mfc0_unimplemented(ctx, arg);
7219 }
7220
7221 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7222 {
7223     const char *rn = "invalid";
7224
7225     if (sel != 0)
7226         check_insn(ctx, ISA_MIPS32);
7227
7228     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7229         gen_io_start();
7230     }
7231
7232     switch (reg) {
7233     case 0:
7234         switch (sel) {
7235         case 0:
7236             gen_helper_mtc0_index(cpu_env, arg);
7237             rn = "Index";
7238             break;
7239         case 1:
7240             CP0_CHECK(ctx->insn_flags & ASE_MT);
7241             gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7242             rn = "MVPControl";
7243             break;
7244         case 2:
7245             CP0_CHECK(ctx->insn_flags & ASE_MT);
7246             /* ignored */
7247             rn = "MVPConf0";
7248             break;
7249         case 3:
7250             CP0_CHECK(ctx->insn_flags & ASE_MT);
7251             /* ignored */
7252             rn = "MVPConf1";
7253             break;
7254         case 4:
7255             CP0_CHECK(ctx->vp);
7256             /* ignored */
7257             rn = "VPControl";
7258             break;
7259         default:
7260             goto cp0_unimplemented;
7261         }
7262         break;
7263     case 1:
7264         switch (sel) {
7265         case 0:
7266             /* ignored */
7267             rn = "Random";
7268             break;
7269         case 1:
7270             CP0_CHECK(ctx->insn_flags & ASE_MT);
7271             gen_helper_mtc0_vpecontrol(cpu_env, arg);
7272             rn = "VPEControl";
7273             break;
7274         case 2:
7275             CP0_CHECK(ctx->insn_flags & ASE_MT);
7276             gen_helper_mtc0_vpeconf0(cpu_env, arg);
7277             rn = "VPEConf0";
7278             break;
7279         case 3:
7280             CP0_CHECK(ctx->insn_flags & ASE_MT);
7281             gen_helper_mtc0_vpeconf1(cpu_env, arg);
7282             rn = "VPEConf1";
7283             break;
7284         case 4:
7285             CP0_CHECK(ctx->insn_flags & ASE_MT);
7286             gen_helper_mtc0_yqmask(cpu_env, arg);
7287             rn = "YQMask";
7288             break;
7289         case 5:
7290             CP0_CHECK(ctx->insn_flags & ASE_MT);
7291             tcg_gen_st_tl(arg, cpu_env,
7292                           offsetof(CPUMIPSState, CP0_VPESchedule));
7293             rn = "VPESchedule";
7294             break;
7295         case 6:
7296             CP0_CHECK(ctx->insn_flags & ASE_MT);
7297             tcg_gen_st_tl(arg, cpu_env,
7298                           offsetof(CPUMIPSState, CP0_VPEScheFBack));
7299             rn = "VPEScheFBack";
7300             break;
7301         case 7:
7302             CP0_CHECK(ctx->insn_flags & ASE_MT);
7303             gen_helper_mtc0_vpeopt(cpu_env, arg);
7304             rn = "VPEOpt";
7305             break;
7306         default:
7307             goto cp0_unimplemented;
7308         }
7309         break;
7310     case 2:
7311         switch (sel) {
7312         case 0:
7313             gen_helper_mtc0_entrylo0(cpu_env, arg);
7314             rn = "EntryLo0";
7315             break;
7316         case 1:
7317             CP0_CHECK(ctx->insn_flags & ASE_MT);
7318             gen_helper_mtc0_tcstatus(cpu_env, arg);
7319             rn = "TCStatus";
7320             break;
7321         case 2:
7322             CP0_CHECK(ctx->insn_flags & ASE_MT);
7323             gen_helper_mtc0_tcbind(cpu_env, arg);
7324             rn = "TCBind";
7325             break;
7326         case 3:
7327             CP0_CHECK(ctx->insn_flags & ASE_MT);
7328             gen_helper_mtc0_tcrestart(cpu_env, arg);
7329             rn = "TCRestart";
7330             break;
7331         case 4:
7332             CP0_CHECK(ctx->insn_flags & ASE_MT);
7333             gen_helper_mtc0_tchalt(cpu_env, arg);
7334             rn = "TCHalt";
7335             break;
7336         case 5:
7337             CP0_CHECK(ctx->insn_flags & ASE_MT);
7338             gen_helper_mtc0_tccontext(cpu_env, arg);
7339             rn = "TCContext";
7340             break;
7341         case 6:
7342             CP0_CHECK(ctx->insn_flags & ASE_MT);
7343             gen_helper_mtc0_tcschedule(cpu_env, arg);
7344             rn = "TCSchedule";
7345             break;
7346         case 7:
7347             CP0_CHECK(ctx->insn_flags & ASE_MT);
7348             gen_helper_mtc0_tcschefback(cpu_env, arg);
7349             rn = "TCScheFBack";
7350             break;
7351         default:
7352             goto cp0_unimplemented;
7353         }
7354         break;
7355     case 3:
7356         switch (sel) {
7357         case 0:
7358             gen_helper_mtc0_entrylo1(cpu_env, arg);
7359             rn = "EntryLo1";
7360             break;
7361         case 1:
7362             CP0_CHECK(ctx->vp);
7363             /* ignored */
7364             rn = "GlobalNumber";
7365             break;
7366         default:
7367             goto cp0_unimplemented;
7368         }
7369         break;
7370     case 4:
7371         switch (sel) {
7372         case 0:
7373             gen_helper_mtc0_context(cpu_env, arg);
7374             rn = "Context";
7375             break;
7376         case 1:
7377 //            gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
7378             rn = "ContextConfig";
7379             goto cp0_unimplemented;
7380         case 2:
7381             CP0_CHECK(ctx->ulri);
7382             tcg_gen_st_tl(arg, cpu_env,
7383                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7384             rn = "UserLocal";
7385             break;
7386         default:
7387             goto cp0_unimplemented;
7388         }
7389         break;
7390     case 5:
7391         switch (sel) {
7392         case 0:
7393             gen_helper_mtc0_pagemask(cpu_env, arg);
7394             rn = "PageMask";
7395             break;
7396         case 1:
7397             check_insn(ctx, ISA_MIPS32R2);
7398             gen_helper_mtc0_pagegrain(cpu_env, arg);
7399             rn = "PageGrain";
7400             ctx->base.is_jmp = DISAS_STOP;
7401             break;
7402         case 2:
7403             CP0_CHECK(ctx->sc);
7404             gen_helper_mtc0_segctl0(cpu_env, arg);
7405             rn = "SegCtl0";
7406             break;
7407         case 3:
7408             CP0_CHECK(ctx->sc);
7409             gen_helper_mtc0_segctl1(cpu_env, arg);
7410             rn = "SegCtl1";
7411             break;
7412         case 4:
7413             CP0_CHECK(ctx->sc);
7414             gen_helper_mtc0_segctl2(cpu_env, arg);
7415             rn = "SegCtl2";
7416             break;
7417         case 5:
7418             check_pw(ctx);
7419             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
7420             rn = "PWBase";
7421             break;
7422         case 6:
7423             check_pw(ctx);
7424             gen_helper_mtc0_pwfield(cpu_env, arg);
7425             rn = "PWField";
7426             break;
7427         case 7:
7428             check_pw(ctx);
7429             gen_helper_mtc0_pwsize(cpu_env, arg);
7430             rn = "PWSize";
7431             break;
7432         default:
7433             goto cp0_unimplemented;
7434         }
7435         break;
7436     case 6:
7437         switch (sel) {
7438         case 0:
7439             gen_helper_mtc0_wired(cpu_env, arg);
7440             rn = "Wired";
7441             break;
7442         case 1:
7443             check_insn(ctx, ISA_MIPS32R2);
7444             gen_helper_mtc0_srsconf0(cpu_env, arg);
7445             rn = "SRSConf0";
7446             break;
7447         case 2:
7448             check_insn(ctx, ISA_MIPS32R2);
7449             gen_helper_mtc0_srsconf1(cpu_env, arg);
7450             rn = "SRSConf1";
7451             break;
7452         case 3:
7453             check_insn(ctx, ISA_MIPS32R2);
7454             gen_helper_mtc0_srsconf2(cpu_env, arg);
7455             rn = "SRSConf2";
7456             break;
7457         case 4:
7458             check_insn(ctx, ISA_MIPS32R2);
7459             gen_helper_mtc0_srsconf3(cpu_env, arg);
7460             rn = "SRSConf3";
7461             break;
7462         case 5:
7463             check_insn(ctx, ISA_MIPS32R2);
7464             gen_helper_mtc0_srsconf4(cpu_env, arg);
7465             rn = "SRSConf4";
7466             break;
7467         case 6:
7468             check_pw(ctx);
7469             gen_helper_mtc0_pwctl(cpu_env, arg);
7470             rn = "PWCtl";
7471             break;
7472         default:
7473             goto cp0_unimplemented;
7474         }
7475         break;
7476     case 7:
7477         switch (sel) {
7478         case 0:
7479             check_insn(ctx, ISA_MIPS32R2);
7480             gen_helper_mtc0_hwrena(cpu_env, arg);
7481             ctx->base.is_jmp = DISAS_STOP;
7482             rn = "HWREna";
7483             break;
7484         default:
7485             goto cp0_unimplemented;
7486         }
7487         break;
7488     case 8:
7489         switch (sel) {
7490         case 0:
7491             /* ignored */
7492             rn = "BadVAddr";
7493             break;
7494         case 1:
7495             /* ignored */
7496             rn = "BadInstr";
7497             break;
7498         case 2:
7499             /* ignored */
7500             rn = "BadInstrP";
7501             break;
7502         case 3:
7503             /* ignored */
7504             rn = "BadInstrX";
7505             break;
7506         default:
7507             goto cp0_unimplemented;
7508         }
7509         break;
7510     case 9:
7511         switch (sel) {
7512         case 0:
7513             gen_helper_mtc0_count(cpu_env, arg);
7514             rn = "Count";
7515             break;
7516         /* 6,7 are implementation dependent */
7517         default:
7518             goto cp0_unimplemented;
7519         }
7520         break;
7521     case 10:
7522         switch (sel) {
7523         case 0:
7524             gen_helper_mtc0_entryhi(cpu_env, arg);
7525             rn = "EntryHi";
7526             break;
7527         default:
7528             goto cp0_unimplemented;
7529         }
7530         break;
7531     case 11:
7532         switch (sel) {
7533         case 0:
7534             gen_helper_mtc0_compare(cpu_env, arg);
7535             rn = "Compare";
7536             break;
7537         /* 6,7 are implementation dependent */
7538         default:
7539             goto cp0_unimplemented;
7540         }
7541         break;
7542     case 12:
7543         switch (sel) {
7544         case 0:
7545             save_cpu_state(ctx, 1);
7546             gen_helper_mtc0_status(cpu_env, arg);
7547             /* DISAS_STOP isn't good enough here, hflags may have changed. */
7548             gen_save_pc(ctx->base.pc_next + 4);
7549             ctx->base.is_jmp = DISAS_EXIT;
7550             rn = "Status";
7551             break;
7552         case 1:
7553             check_insn(ctx, ISA_MIPS32R2);
7554             gen_helper_mtc0_intctl(cpu_env, arg);
7555             /* Stop translation as we may have switched the execution mode */
7556             ctx->base.is_jmp = DISAS_STOP;
7557             rn = "IntCtl";
7558             break;
7559         case 2:
7560             check_insn(ctx, ISA_MIPS32R2);
7561             gen_helper_mtc0_srsctl(cpu_env, arg);
7562             /* Stop translation as we may have switched the execution mode */
7563             ctx->base.is_jmp = DISAS_STOP;
7564             rn = "SRSCtl";
7565             break;
7566         case 3:
7567             check_insn(ctx, ISA_MIPS32R2);
7568             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7569             /* Stop translation as we may have switched the execution mode */
7570             ctx->base.is_jmp = DISAS_STOP;
7571             rn = "SRSMap";
7572             break;
7573         default:
7574             goto cp0_unimplemented;
7575         }
7576         break;
7577     case 13:
7578         switch (sel) {
7579         case 0:
7580             save_cpu_state(ctx, 1);
7581             gen_helper_mtc0_cause(cpu_env, arg);
7582             /* Stop translation as we may have triggered an interrupt.
7583              * DISAS_STOP isn't sufficient, we need to ensure we break out of
7584              * translated code to check for pending interrupts.  */
7585             gen_save_pc(ctx->base.pc_next + 4);
7586             ctx->base.is_jmp = DISAS_EXIT;
7587             rn = "Cause";
7588             break;
7589         default:
7590             goto cp0_unimplemented;
7591         }
7592         break;
7593     case 14:
7594         switch (sel) {
7595         case 0:
7596             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7597             rn = "EPC";
7598             break;
7599         default:
7600             goto cp0_unimplemented;
7601         }
7602         break;
7603     case 15:
7604         switch (sel) {
7605         case 0:
7606             /* ignored */
7607             rn = "PRid";
7608             break;
7609         case 1:
7610             check_insn(ctx, ISA_MIPS32R2);
7611             gen_helper_mtc0_ebase(cpu_env, arg);
7612             rn = "EBase";
7613             break;
7614         default:
7615             goto cp0_unimplemented;
7616         }
7617         break;
7618     case 16:
7619         switch (sel) {
7620         case 0:
7621             gen_helper_mtc0_config0(cpu_env, arg);
7622             rn = "Config";
7623             /* Stop translation as we may have switched the execution mode */
7624             ctx->base.is_jmp = DISAS_STOP;
7625             break;
7626         case 1:
7627             /* ignored, read only */
7628             rn = "Config1";
7629             break;
7630         case 2:
7631             gen_helper_mtc0_config2(cpu_env, arg);
7632             rn = "Config2";
7633             /* Stop translation as we may have switched the execution mode */
7634             ctx->base.is_jmp = DISAS_STOP;
7635             break;
7636         case 3:
7637             gen_helper_mtc0_config3(cpu_env, arg);
7638             rn = "Config3";
7639             /* Stop translation as we may have switched the execution mode */
7640             ctx->base.is_jmp = DISAS_STOP;
7641             break;
7642         case 4:
7643             gen_helper_mtc0_config4(cpu_env, arg);
7644             rn = "Config4";
7645             ctx->base.is_jmp = DISAS_STOP;
7646             break;
7647         case 5:
7648             gen_helper_mtc0_config5(cpu_env, arg);
7649             rn = "Config5";
7650             /* Stop translation as we may have switched the execution mode */
7651             ctx->base.is_jmp = DISAS_STOP;
7652             break;
7653         /* 6,7 are implementation dependent */
7654         case 6:
7655             /* ignored */
7656             rn = "Config6";
7657             break;
7658         case 7:
7659             /* ignored */
7660             rn = "Config7";
7661             break;
7662         default:
7663             rn = "Invalid config selector";
7664             goto cp0_unimplemented;
7665         }
7666         break;
7667     case 17:
7668         switch (sel) {
7669         case 0:
7670             gen_helper_mtc0_lladdr(cpu_env, arg);
7671             rn = "LLAddr";
7672             break;
7673         case 1:
7674             CP0_CHECK(ctx->mrp);
7675             gen_helper_mtc0_maar(cpu_env, arg);
7676             rn = "MAAR";
7677             break;
7678         case 2:
7679             CP0_CHECK(ctx->mrp);
7680             gen_helper_mtc0_maari(cpu_env, arg);
7681             rn = "MAARI";
7682             break;
7683         default:
7684             goto cp0_unimplemented;
7685         }
7686         break;
7687     case 18:
7688         switch (sel) {
7689         case 0:
7690         case 1:
7691         case 2:
7692         case 3:
7693         case 4:
7694         case 5:
7695         case 6:
7696         case 7:
7697             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7698             gen_helper_0e1i(mtc0_watchlo, arg, sel);
7699             rn = "WatchLo";
7700             break;
7701         default:
7702             goto cp0_unimplemented;
7703         }
7704         break;
7705     case 19:
7706         switch (sel) {
7707         case 0:
7708         case 1:
7709         case 2:
7710         case 3:
7711         case 4:
7712         case 5:
7713         case 6:
7714         case 7:
7715             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7716             gen_helper_0e1i(mtc0_watchhi, arg, sel);
7717             rn = "WatchHi";
7718             break;
7719         default:
7720             goto cp0_unimplemented;
7721         }
7722         break;
7723     case 20:
7724         switch (sel) {
7725         case 0:
7726 #if defined(TARGET_MIPS64)
7727             check_insn(ctx, ISA_MIPS3);
7728             gen_helper_mtc0_xcontext(cpu_env, arg);
7729             rn = "XContext";
7730             break;
7731 #endif
7732         default:
7733             goto cp0_unimplemented;
7734         }
7735         break;
7736     case 21:
7737        /* Officially reserved, but sel 0 is used for R1x000 framemask */
7738         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7739         switch (sel) {
7740         case 0:
7741             gen_helper_mtc0_framemask(cpu_env, arg);
7742             rn = "Framemask";
7743             break;
7744         default:
7745             goto cp0_unimplemented;
7746         }
7747         break;
7748     case 22:
7749         /* ignored */
7750         rn = "Diagnostic"; /* implementation dependent */
7751         break;
7752     case 23:
7753         switch (sel) {
7754         case 0:
7755             gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
7756             /* DISAS_STOP isn't good enough here, hflags may have changed. */
7757             gen_save_pc(ctx->base.pc_next + 4);
7758             ctx->base.is_jmp = DISAS_EXIT;
7759             rn = "Debug";
7760             break;
7761         case 1:
7762 //            gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
7763             rn = "TraceControl";
7764             /* Stop translation as we may have switched the execution mode */
7765             ctx->base.is_jmp = DISAS_STOP;
7766             goto cp0_unimplemented;
7767         case 2:
7768 //            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
7769             rn = "TraceControl2";
7770             /* Stop translation as we may have switched the execution mode */
7771             ctx->base.is_jmp = DISAS_STOP;
7772             goto cp0_unimplemented;
7773         case 3:
7774             /* Stop translation as we may have switched the execution mode */
7775             ctx->base.is_jmp = DISAS_STOP;
7776 //            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
7777             rn = "UserTraceData";
7778             /* Stop translation as we may have switched the execution mode */
7779             ctx->base.is_jmp = DISAS_STOP;
7780             goto cp0_unimplemented;
7781         case 4:
7782 //            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
7783             /* Stop translation as we may have switched the execution mode */
7784             ctx->base.is_jmp = DISAS_STOP;
7785             rn = "TraceBPC";
7786             goto cp0_unimplemented;
7787         default:
7788             goto cp0_unimplemented;
7789         }
7790         break;
7791     case 24:
7792         switch (sel) {
7793         case 0:
7794             /* EJTAG support */
7795             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7796             rn = "DEPC";
7797             break;
7798         default:
7799             goto cp0_unimplemented;
7800         }
7801         break;
7802     case 25:
7803         switch (sel) {
7804         case 0:
7805             gen_helper_mtc0_performance0(cpu_env, arg);
7806             rn = "Performance0";
7807             break;
7808         case 1:
7809 //            gen_helper_mtc0_performance1(arg);
7810             rn = "Performance1";
7811             goto cp0_unimplemented;
7812         case 2:
7813 //            gen_helper_mtc0_performance2(arg);
7814             rn = "Performance2";
7815             goto cp0_unimplemented;
7816         case 3:
7817 //            gen_helper_mtc0_performance3(arg);
7818             rn = "Performance3";
7819             goto cp0_unimplemented;
7820         case 4:
7821 //            gen_helper_mtc0_performance4(arg);
7822             rn = "Performance4";
7823             goto cp0_unimplemented;
7824         case 5:
7825 //            gen_helper_mtc0_performance5(arg);
7826             rn = "Performance5";
7827             goto cp0_unimplemented;
7828         case 6:
7829 //            gen_helper_mtc0_performance6(arg);
7830             rn = "Performance6";
7831             goto cp0_unimplemented;
7832         case 7:
7833 //            gen_helper_mtc0_performance7(arg);
7834             rn = "Performance7";
7835             goto cp0_unimplemented;
7836         default:
7837             goto cp0_unimplemented;
7838         }
7839        break;
7840     case 26:
7841         switch (sel) {
7842         case 0:
7843             gen_helper_mtc0_errctl(cpu_env, arg);
7844             ctx->base.is_jmp = DISAS_STOP;
7845             rn = "ErrCtl";
7846             break;
7847         default:
7848             goto cp0_unimplemented;
7849         }
7850         break;
7851     case 27:
7852         switch (sel) {
7853         case 0:
7854         case 1:
7855         case 2:
7856         case 3:
7857             /* ignored */
7858             rn = "CacheErr";
7859             break;
7860         default:
7861             goto cp0_unimplemented;
7862         }
7863        break;
7864     case 28:
7865         switch (sel) {
7866         case 0:
7867         case 2:
7868         case 4:
7869         case 6:
7870             gen_helper_mtc0_taglo(cpu_env, arg);
7871             rn = "TagLo";
7872             break;
7873         case 1:
7874         case 3:
7875         case 5:
7876         case 7:
7877             gen_helper_mtc0_datalo(cpu_env, arg);
7878             rn = "DataLo";
7879             break;
7880         default:
7881             goto cp0_unimplemented;
7882         }
7883         break;
7884     case 29:
7885         switch (sel) {
7886         case 0:
7887         case 2:
7888         case 4:
7889         case 6:
7890             gen_helper_mtc0_taghi(cpu_env, arg);
7891             rn = "TagHi";
7892             break;
7893         case 1:
7894         case 3:
7895         case 5:
7896         case 7:
7897             gen_helper_mtc0_datahi(cpu_env, arg);
7898             rn = "DataHi";
7899             break;
7900         default:
7901             rn = "invalid sel";
7902             goto cp0_unimplemented;
7903         }
7904        break;
7905     case 30:
7906         switch (sel) {
7907         case 0:
7908             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7909             rn = "ErrorEPC";
7910             break;
7911         default:
7912             goto cp0_unimplemented;
7913         }
7914         break;
7915     case 31:
7916         switch (sel) {
7917         case 0:
7918             /* EJTAG support */
7919             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7920             rn = "DESAVE";
7921             break;
7922         case 2:
7923         case 3:
7924         case 4:
7925         case 5:
7926         case 6:
7927         case 7:
7928             CP0_CHECK(ctx->kscrexist & (1 << sel));
7929             tcg_gen_st_tl(arg, cpu_env,
7930                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7931             rn = "KScratch";
7932             break;
7933         default:
7934             goto cp0_unimplemented;
7935         }
7936         break;
7937     default:
7938        goto cp0_unimplemented;
7939     }
7940     trace_mips_translate_c0("mtc0", rn, reg, sel);
7941
7942     /* For simplicity assume that all writes can cause interrupts.  */
7943     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7944         gen_io_end();
7945         /* DISAS_STOP isn't sufficient, we need to ensure we break out of
7946          * translated code to check for pending interrupts.  */
7947         gen_save_pc(ctx->base.pc_next + 4);
7948         ctx->base.is_jmp = DISAS_EXIT;
7949     }
7950     return;
7951
7952 cp0_unimplemented:
7953     qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
7954 }
7955
7956 #if defined(TARGET_MIPS64)
7957 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7958 {
7959     const char *rn = "invalid";
7960
7961     if (sel != 0)
7962         check_insn(ctx, ISA_MIPS64);
7963
7964     switch (reg) {
7965     case 0:
7966         switch (sel) {
7967         case 0:
7968             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7969             rn = "Index";
7970             break;
7971         case 1:
7972             CP0_CHECK(ctx->insn_flags & ASE_MT);
7973             gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7974             rn = "MVPControl";
7975             break;
7976         case 2:
7977             CP0_CHECK(ctx->insn_flags & ASE_MT);
7978             gen_helper_mfc0_mvpconf0(arg, cpu_env);
7979             rn = "MVPConf0";
7980             break;
7981         case 3:
7982             CP0_CHECK(ctx->insn_flags & ASE_MT);
7983             gen_helper_mfc0_mvpconf1(arg, cpu_env);
7984             rn = "MVPConf1";
7985             break;
7986         case 4:
7987             CP0_CHECK(ctx->vp);
7988             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
7989             rn = "VPControl";
7990             break;
7991         default:
7992             goto cp0_unimplemented;
7993         }
7994         break;
7995     case 1:
7996         switch (sel) {
7997         case 0:
7998             CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7999             gen_helper_mfc0_random(arg, cpu_env);
8000             rn = "Random";
8001             break;
8002         case 1:
8003             CP0_CHECK(ctx->insn_flags & ASE_MT);
8004             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
8005             rn = "VPEControl";
8006             break;
8007         case 2:
8008             CP0_CHECK(ctx->insn_flags & ASE_MT);
8009             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
8010             rn = "VPEConf0";
8011             break;
8012         case 3:
8013             CP0_CHECK(ctx->insn_flags & ASE_MT);
8014             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
8015             rn = "VPEConf1";
8016             break;
8017         case 4:
8018             CP0_CHECK(ctx->insn_flags & ASE_MT);
8019             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
8020             rn = "YQMask";
8021             break;
8022         case 5:
8023             CP0_CHECK(ctx->insn_flags & ASE_MT);
8024             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
8025             rn = "VPESchedule";
8026             break;
8027         case 6:
8028             CP0_CHECK(ctx->insn_flags & ASE_MT);
8029             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
8030             rn = "VPEScheFBack";
8031             break;
8032         case 7:
8033             CP0_CHECK(ctx->insn_flags & ASE_MT);
8034             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
8035             rn = "VPEOpt";
8036             break;
8037         default:
8038             goto cp0_unimplemented;
8039         }
8040         break;
8041     case 2:
8042         switch (sel) {
8043         case 0:
8044             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
8045             rn = "EntryLo0";
8046             break;
8047         case 1:
8048             CP0_CHECK(ctx->insn_flags & ASE_MT);
8049             gen_helper_mfc0_tcstatus(arg, cpu_env);
8050             rn = "TCStatus";
8051             break;
8052         case 2:
8053             CP0_CHECK(ctx->insn_flags & ASE_MT);
8054             gen_helper_mfc0_tcbind(arg, cpu_env);
8055             rn = "TCBind";
8056             break;
8057         case 3:
8058             CP0_CHECK(ctx->insn_flags & ASE_MT);
8059             gen_helper_dmfc0_tcrestart(arg, cpu_env);
8060             rn = "TCRestart";
8061             break;
8062         case 4:
8063             CP0_CHECK(ctx->insn_flags & ASE_MT);
8064             gen_helper_dmfc0_tchalt(arg, cpu_env);
8065             rn = "TCHalt";
8066             break;
8067         case 5:
8068             CP0_CHECK(ctx->insn_flags & ASE_MT);
8069             gen_helper_dmfc0_tccontext(arg, cpu_env);
8070             rn = "TCContext";
8071             break;
8072         case 6:
8073             CP0_CHECK(ctx->insn_flags & ASE_MT);
8074             gen_helper_dmfc0_tcschedule(arg, cpu_env);
8075             rn = "TCSchedule";
8076             break;
8077         case 7:
8078             CP0_CHECK(ctx->insn_flags & ASE_MT);
8079             gen_helper_dmfc0_tcschefback(arg, cpu_env);
8080             rn = "TCScheFBack";
8081             break;
8082         default:
8083             goto cp0_unimplemented;
8084         }
8085         break;
8086     case 3:
8087         switch (sel) {
8088         case 0:
8089             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
8090             rn = "EntryLo1";
8091             break;
8092         case 1:
8093             CP0_CHECK(ctx->vp);
8094             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
8095             rn = "GlobalNumber";
8096             break;
8097         default:
8098             goto cp0_unimplemented;
8099         }
8100         break;
8101     case 4:
8102         switch (sel) {
8103         case 0:
8104             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
8105             rn = "Context";
8106             break;
8107         case 1:
8108 //            gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
8109             rn = "ContextConfig";
8110             goto cp0_unimplemented;
8111         case 2:
8112             CP0_CHECK(ctx->ulri);
8113             tcg_gen_ld_tl(arg, cpu_env,
8114                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8115             rn = "UserLocal";
8116             break;
8117         default:
8118             goto cp0_unimplemented;
8119         }
8120         break;
8121     case 5:
8122         switch (sel) {
8123         case 0:
8124             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
8125             rn = "PageMask";
8126             break;
8127         case 1:
8128             check_insn(ctx, ISA_MIPS32R2);
8129             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
8130             rn = "PageGrain";
8131             break;
8132         case 2:
8133             CP0_CHECK(ctx->sc);
8134             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
8135             rn = "SegCtl0";
8136             break;
8137         case 3:
8138             CP0_CHECK(ctx->sc);
8139             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
8140             rn = "SegCtl1";
8141             break;
8142         case 4:
8143             CP0_CHECK(ctx->sc);
8144             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
8145             rn = "SegCtl2";
8146             break;
8147         case 5:
8148             check_pw(ctx);
8149             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8150             rn = "PWBase";
8151             break;
8152         case 6:
8153             check_pw(ctx);
8154             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
8155             rn = "PWField";
8156             break;
8157         case 7:
8158             check_pw(ctx);
8159             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
8160             rn = "PWSize";
8161             break;
8162         default:
8163             goto cp0_unimplemented;
8164         }
8165         break;
8166     case 6:
8167         switch (sel) {
8168         case 0:
8169             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
8170             rn = "Wired";
8171             break;
8172         case 1:
8173             check_insn(ctx, ISA_MIPS32R2);
8174             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
8175             rn = "SRSConf0";
8176             break;
8177         case 2:
8178             check_insn(ctx, ISA_MIPS32R2);
8179             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
8180             rn = "SRSConf1";
8181             break;
8182         case 3:
8183             check_insn(ctx, ISA_MIPS32R2);
8184             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
8185             rn = "SRSConf2";
8186             break;
8187         case 4:
8188             check_insn(ctx, ISA_MIPS32R2);
8189             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
8190             rn = "SRSConf3";
8191             break;
8192         case 5:
8193             check_insn(ctx, ISA_MIPS32R2);
8194             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
8195             rn = "SRSConf4";
8196             break;
8197         case 6:
8198             check_pw(ctx);
8199             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
8200             rn = "PWCtl";
8201             break;
8202         default:
8203             goto cp0_unimplemented;
8204         }
8205         break;
8206     case 7:
8207         switch (sel) {
8208         case 0:
8209             check_insn(ctx, ISA_MIPS32R2);
8210             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
8211             rn = "HWREna";
8212             break;
8213         default:
8214             goto cp0_unimplemented;
8215         }
8216         break;
8217     case 8:
8218         switch (sel) {
8219         case 0:
8220             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
8221             rn = "BadVAddr";
8222             break;
8223         case 1:
8224             CP0_CHECK(ctx->bi);
8225             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
8226             rn = "BadInstr";
8227             break;
8228         case 2:
8229             CP0_CHECK(ctx->bp);
8230             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
8231             rn = "BadInstrP";
8232             break;
8233         case 3:
8234             CP0_CHECK(ctx->bi);
8235             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
8236             tcg_gen_andi_tl(arg, arg, ~0xffff);
8237             rn = "BadInstrX";
8238             break;
8239         default:
8240             goto cp0_unimplemented;
8241         }
8242         break;
8243     case 9:
8244         switch (sel) {
8245         case 0:
8246             /* Mark as an IO operation because we read the time.  */
8247             if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8248                 gen_io_start();
8249             }
8250             gen_helper_mfc0_count(arg, cpu_env);
8251             if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8252                 gen_io_end();
8253             }
8254             /* Break the TB to be able to take timer interrupts immediately
8255                after reading count. DISAS_STOP isn't sufficient, we need to
8256                ensure we break completely out of translated code.  */
8257             gen_save_pc(ctx->base.pc_next + 4);
8258             ctx->base.is_jmp = DISAS_EXIT;
8259             rn = "Count";
8260             break;
8261         /* 6,7 are implementation dependent */
8262         default:
8263             goto cp0_unimplemented;
8264         }
8265         break;
8266     case 10:
8267         switch (sel) {
8268         case 0:
8269             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
8270             rn = "EntryHi";
8271             break;
8272         default:
8273             goto cp0_unimplemented;
8274         }
8275         break;
8276     case 11:
8277         switch (sel) {
8278         case 0:
8279             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
8280             rn = "Compare";
8281             break;
8282         /* 6,7 are implementation dependent */
8283         default:
8284             goto cp0_unimplemented;
8285         }
8286         break;
8287     case 12:
8288         switch (sel) {
8289         case 0:
8290             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
8291             rn = "Status";
8292             break;
8293         case 1:
8294             check_insn(ctx, ISA_MIPS32R2);
8295             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
8296             rn = "IntCtl";
8297             break;
8298         case 2:
8299             check_insn(ctx, ISA_MIPS32R2);
8300             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
8301             rn = "SRSCtl";
8302             break;
8303         case 3:
8304             check_insn(ctx, ISA_MIPS32R2);
8305             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8306             rn = "SRSMap";
8307             break;
8308         default:
8309             goto cp0_unimplemented;
8310         }
8311         break;
8312     case 13:
8313         switch (sel) {
8314         case 0:
8315             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
8316             rn = "Cause";
8317             break;
8318         default:
8319             goto cp0_unimplemented;
8320         }
8321         break;
8322     case 14:
8323         switch (sel) {
8324         case 0:
8325             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
8326             rn = "EPC";
8327             break;
8328         default:
8329             goto cp0_unimplemented;
8330         }
8331         break;
8332     case 15:
8333         switch (sel) {
8334         case 0:
8335             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
8336             rn = "PRid";
8337             break;
8338         case 1:
8339             check_insn(ctx, ISA_MIPS32R2);
8340             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
8341             rn = "EBase";
8342             break;
8343         case 3:
8344             check_insn(ctx, ISA_MIPS32R2);
8345             CP0_CHECK(ctx->cmgcr);
8346             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
8347             rn = "CMGCRBase";
8348             break;
8349         default:
8350             goto cp0_unimplemented;
8351         }
8352         break;
8353     case 16:
8354         switch (sel) {
8355         case 0:
8356             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
8357             rn = "Config";
8358             break;
8359         case 1:
8360             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
8361             rn = "Config1";
8362             break;
8363         case 2:
8364             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
8365             rn = "Config2";
8366             break;
8367         case 3:
8368             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
8369             rn = "Config3";
8370             break;
8371         case 4:
8372             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
8373             rn = "Config4";
8374             break;
8375         case 5:
8376             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
8377             rn = "Config5";
8378             break;
8379        /* 6,7 are implementation dependent */
8380         case 6:
8381             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
8382             rn = "Config6";
8383             break;
8384         case 7:
8385             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
8386             rn = "Config7";
8387             break;
8388         default:
8389             goto cp0_unimplemented;
8390         }
8391         break;
8392     case 17:
8393         switch (sel) {
8394         case 0:
8395             gen_helper_dmfc0_lladdr(arg, cpu_env);
8396             rn = "LLAddr";
8397             break;
8398         case 1:
8399             CP0_CHECK(ctx->mrp);
8400             gen_helper_dmfc0_maar(arg, cpu_env);
8401             rn = "MAAR";
8402             break;
8403         case 2:
8404             CP0_CHECK(ctx->mrp);
8405             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
8406             rn = "MAARI";
8407             break;
8408         default:
8409             goto cp0_unimplemented;
8410         }
8411         break;
8412     case 18:
8413         switch (sel) {
8414         case 0:
8415         case 1:
8416         case 2:
8417         case 3:
8418         case 4:
8419         case 5:
8420         case 6:
8421         case 7:
8422             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8423             gen_helper_1e0i(dmfc0_watchlo, arg, sel);
8424             rn = "WatchLo";
8425             break;
8426         default:
8427             goto cp0_unimplemented;
8428         }
8429         break;
8430     case 19:
8431         switch (sel) {
8432         case 0:
8433         case 1:
8434         case 2:
8435         case 3:
8436         case 4:
8437         case 5:
8438         case 6:
8439         case 7:
8440             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8441             gen_helper_1e0i(mfc0_watchhi, arg, sel);
8442             rn = "WatchHi";
8443             break;
8444         default:
8445             goto cp0_unimplemented;
8446         }
8447         break;
8448     case 20:
8449         switch (sel) {
8450         case 0:
8451             check_insn(ctx, ISA_MIPS3);
8452             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
8453             rn = "XContext";
8454             break;
8455         default:
8456             goto cp0_unimplemented;
8457         }
8458         break;
8459     case 21:
8460        /* Officially reserved, but sel 0 is used for R1x000 framemask */
8461         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8462         switch (sel) {
8463         case 0:
8464             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
8465             rn = "Framemask";
8466             break;
8467         default:
8468             goto cp0_unimplemented;
8469         }
8470         break;
8471     case 22:
8472         tcg_gen_movi_tl(arg, 0); /* unimplemented */
8473         rn = "'Diagnostic"; /* implementation dependent */
8474         break;
8475     case 23:
8476         switch (sel) {
8477         case 0:
8478             gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
8479             rn = "Debug";
8480             break;
8481         case 1:
8482 //            gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
8483             rn = "TraceControl";
8484             goto cp0_unimplemented;
8485         case 2:
8486 //            gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
8487             rn = "TraceControl2";
8488             goto cp0_unimplemented;
8489         case 3:
8490 //            gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
8491             rn = "UserTraceData";
8492             goto cp0_unimplemented;
8493         case 4:
8494 //            gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
8495             rn = "TraceBPC";
8496             goto cp0_unimplemented;
8497         default:
8498             goto cp0_unimplemented;
8499         }
8500         break;
8501     case 24:
8502         switch (sel) {
8503         case 0:
8504             /* EJTAG support */
8505             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8506             rn = "DEPC";
8507             break;
8508         default:
8509             goto cp0_unimplemented;
8510         }
8511         break;
8512     case 25:
8513         switch (sel) {
8514         case 0:
8515             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
8516             rn = "Performance0";
8517             break;
8518         case 1:
8519 //            gen_helper_dmfc0_performance1(arg);
8520             rn = "Performance1";
8521             goto cp0_unimplemented;
8522         case 2:
8523 //            gen_helper_dmfc0_performance2(arg);
8524             rn = "Performance2";
8525             goto cp0_unimplemented;
8526         case 3:
8527 //            gen_helper_dmfc0_performance3(arg);
8528             rn = "Performance3";
8529             goto cp0_unimplemented;
8530         case 4:
8531 //            gen_helper_dmfc0_performance4(arg);
8532             rn = "Performance4";
8533             goto cp0_unimplemented;
8534         case 5:
8535 //            gen_helper_dmfc0_performance5(arg);
8536             rn = "Performance5";
8537             goto cp0_unimplemented;
8538         case 6:
8539 //            gen_helper_dmfc0_performance6(arg);
8540             rn = "Performance6";
8541             goto cp0_unimplemented;
8542         case 7:
8543 //            gen_helper_dmfc0_performance7(arg);
8544             rn = "Performance7";
8545             goto cp0_unimplemented;
8546         default:
8547             goto cp0_unimplemented;
8548         }
8549         break;
8550     case 26:
8551         switch (sel) {
8552         case 0:
8553             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
8554             rn = "ErrCtl";
8555             break;
8556         default:
8557             goto cp0_unimplemented;
8558         }
8559         break;
8560     case 27:
8561         switch (sel) {
8562         /* ignored */
8563         case 0:
8564         case 1:
8565         case 2:
8566         case 3:
8567             tcg_gen_movi_tl(arg, 0); /* unimplemented */
8568             rn = "CacheErr";
8569             break;
8570         default:
8571             goto cp0_unimplemented;
8572         }
8573         break;
8574     case 28:
8575         switch (sel) {
8576         case 0:
8577         case 2:
8578         case 4:
8579         case 6:
8580             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
8581             rn = "TagLo";
8582             break;
8583         case 1:
8584         case 3:
8585         case 5:
8586         case 7:
8587             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
8588             rn = "DataLo";
8589             break;
8590         default:
8591             goto cp0_unimplemented;
8592         }
8593         break;
8594     case 29:
8595         switch (sel) {
8596         case 0:
8597         case 2:
8598         case 4:
8599         case 6:
8600             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
8601             rn = "TagHi";
8602             break;
8603         case 1:
8604         case 3:
8605         case 5:
8606         case 7:
8607             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
8608             rn = "DataHi";
8609             break;
8610         default:
8611             goto cp0_unimplemented;
8612         }
8613         break;
8614     case 30:
8615         switch (sel) {
8616         case 0:
8617             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8618             rn = "ErrorEPC";
8619             break;
8620         default:
8621             goto cp0_unimplemented;
8622         }
8623         break;
8624     case 31:
8625         switch (sel) {
8626         case 0:
8627             /* EJTAG support */
8628             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8629             rn = "DESAVE";
8630             break;
8631         case 2:
8632         case 3:
8633         case 4:
8634         case 5:
8635         case 6:
8636         case 7:
8637             CP0_CHECK(ctx->kscrexist & (1 << sel));
8638             tcg_gen_ld_tl(arg, cpu_env,
8639                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8640             rn = "KScratch";
8641             break;
8642         default:
8643             goto cp0_unimplemented;
8644         }
8645         break;
8646     default:
8647         goto cp0_unimplemented;
8648     }
8649     trace_mips_translate_c0("dmfc0", rn, reg, sel);
8650     return;
8651
8652 cp0_unimplemented:
8653     qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
8654     gen_mfc0_unimplemented(ctx, arg);
8655 }
8656
8657 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8658 {
8659     const char *rn = "invalid";
8660
8661     if (sel != 0)
8662         check_insn(ctx, ISA_MIPS64);
8663
8664     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8665         gen_io_start();
8666     }
8667
8668     switch (reg) {
8669     case 0:
8670         switch (sel) {
8671         case 0:
8672             gen_helper_mtc0_index(cpu_env, arg);
8673             rn = "Index";
8674             break;
8675         case 1:
8676             CP0_CHECK(ctx->insn_flags & ASE_MT);
8677             gen_helper_mtc0_mvpcontrol(cpu_env, arg);
8678             rn = "MVPControl";
8679             break;
8680         case 2:
8681             CP0_CHECK(ctx->insn_flags & ASE_MT);
8682             /* ignored */
8683             rn = "MVPConf0";
8684             break;
8685         case 3:
8686             CP0_CHECK(ctx->insn_flags & ASE_MT);
8687             /* ignored */
8688             rn = "MVPConf1";
8689             break;
8690         case 4:
8691             CP0_CHECK(ctx->vp);
8692             /* ignored */
8693             rn = "VPControl";
8694             break;
8695         default:
8696             goto cp0_unimplemented;
8697         }
8698         break;
8699     case 1:
8700         switch (sel) {
8701         case 0:
8702             /* ignored */
8703             rn = "Random";
8704             break;
8705         case 1:
8706             CP0_CHECK(ctx->insn_flags & ASE_MT);
8707             gen_helper_mtc0_vpecontrol(cpu_env, arg);
8708             rn = "VPEControl";
8709             break;
8710         case 2:
8711             CP0_CHECK(ctx->insn_flags & ASE_MT);
8712             gen_helper_mtc0_vpeconf0(cpu_env, arg);
8713             rn = "VPEConf0";
8714             break;
8715         case 3:
8716             CP0_CHECK(ctx->insn_flags & ASE_MT);
8717             gen_helper_mtc0_vpeconf1(cpu_env, arg);
8718             rn = "VPEConf1";
8719             break;
8720         case 4:
8721             CP0_CHECK(ctx->insn_flags & ASE_MT);
8722             gen_helper_mtc0_yqmask(cpu_env, arg);
8723             rn = "YQMask";
8724             break;
8725         case 5:
8726             CP0_CHECK(ctx->insn_flags & ASE_MT);
8727             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
8728             rn = "VPESchedule";
8729             break;
8730         case 6:
8731             CP0_CHECK(ctx->insn_flags & ASE_MT);
8732             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
8733             rn = "VPEScheFBack";
8734             break;
8735         case 7:
8736             CP0_CHECK(ctx->insn_flags & ASE_MT);
8737             gen_helper_mtc0_vpeopt(cpu_env, arg);
8738             rn = "VPEOpt";
8739             break;
8740         default:
8741             goto cp0_unimplemented;
8742         }
8743         break;
8744     case 2:
8745         switch (sel) {
8746         case 0:
8747             gen_helper_dmtc0_entrylo0(cpu_env, arg);
8748             rn = "EntryLo0";
8749             break;
8750         case 1:
8751             CP0_CHECK(ctx->insn_flags & ASE_MT);
8752             gen_helper_mtc0_tcstatus(cpu_env, arg);
8753             rn = "TCStatus";
8754             break;
8755         case 2:
8756             CP0_CHECK(ctx->insn_flags & ASE_MT);
8757             gen_helper_mtc0_tcbind(cpu_env, arg);
8758             rn = "TCBind";
8759             break;
8760         case 3:
8761             CP0_CHECK(ctx->insn_flags & ASE_MT);
8762             gen_helper_mtc0_tcrestart(cpu_env, arg);
8763             rn = "TCRestart";
8764             break;
8765         case 4:
8766             CP0_CHECK(ctx->insn_flags & ASE_MT);
8767             gen_helper_mtc0_tchalt(cpu_env, arg);
8768             rn = "TCHalt";
8769             break;
8770         case 5:
8771             CP0_CHECK(ctx->insn_flags & ASE_MT);
8772             gen_helper_mtc0_tccontext(cpu_env, arg);
8773             rn = "TCContext";
8774             break;
8775         case 6:
8776             CP0_CHECK(ctx->insn_flags & ASE_MT);
8777             gen_helper_mtc0_tcschedule(cpu_env, arg);
8778             rn = "TCSchedule";
8779             break;
8780         case 7:
8781             CP0_CHECK(ctx->insn_flags & ASE_MT);
8782             gen_helper_mtc0_tcschefback(cpu_env, arg);
8783             rn = "TCScheFBack";
8784             break;
8785         default:
8786             goto cp0_unimplemented;
8787         }
8788         break;
8789     case 3:
8790         switch (sel) {
8791         case 0:
8792             gen_helper_dmtc0_entrylo1(cpu_env, arg);
8793             rn = "EntryLo1";
8794             break;
8795         case 1:
8796             CP0_CHECK(ctx->vp);
8797             /* ignored */
8798             rn = "GlobalNumber";
8799             break;
8800         default:
8801             goto cp0_unimplemented;
8802         }
8803         break;
8804     case 4:
8805         switch (sel) {
8806         case 0:
8807             gen_helper_mtc0_context(cpu_env, arg);
8808             rn = "Context";
8809             break;
8810         case 1:
8811 //           gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
8812             rn = "ContextConfig";
8813             goto cp0_unimplemented;
8814         case 2:
8815             CP0_CHECK(ctx->ulri);
8816             tcg_gen_st_tl(arg, cpu_env,
8817                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8818             rn = "UserLocal";
8819             break;
8820         default:
8821             goto cp0_unimplemented;
8822         }
8823         break;
8824     case 5:
8825         switch (sel) {
8826         case 0:
8827             gen_helper_mtc0_pagemask(cpu_env, arg);
8828             rn = "PageMask";
8829             break;
8830         case 1:
8831             check_insn(ctx, ISA_MIPS32R2);
8832             gen_helper_mtc0_pagegrain(cpu_env, arg);
8833             rn = "PageGrain";
8834             break;
8835         case 2:
8836             CP0_CHECK(ctx->sc);
8837             gen_helper_mtc0_segctl0(cpu_env, arg);
8838             rn = "SegCtl0";
8839             break;
8840         case 3:
8841             CP0_CHECK(ctx->sc);
8842             gen_helper_mtc0_segctl1(cpu_env, arg);
8843             rn = "SegCtl1";
8844             break;
8845         case 4:
8846             CP0_CHECK(ctx->sc);
8847             gen_helper_mtc0_segctl2(cpu_env, arg);
8848             rn = "SegCtl2";
8849             break;
8850         case 5:
8851             check_pw(ctx);
8852             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8853             rn = "PWBase";
8854             break;
8855         case 6:
8856             check_pw(ctx);
8857             gen_helper_mtc0_pwfield(cpu_env, arg);
8858             rn = "PWField";
8859             break;
8860         case 7:
8861             check_pw(ctx);
8862             gen_helper_mtc0_pwsize(cpu_env, arg);
8863             rn = "PWSize";
8864             break;
8865         default:
8866             goto cp0_unimplemented;
8867         }
8868         break;
8869     case 6:
8870         switch (sel) {
8871         case 0:
8872             gen_helper_mtc0_wired(cpu_env, arg);
8873             rn = "Wired";
8874             break;
8875         case 1:
8876             check_insn(ctx, ISA_MIPS32R2);
8877             gen_helper_mtc0_srsconf0(cpu_env, arg);
8878             rn = "SRSConf0";
8879             break;
8880         case 2:
8881             check_insn(ctx, ISA_MIPS32R2);
8882             gen_helper_mtc0_srsconf1(cpu_env, arg);
8883             rn = "SRSConf1";
8884             break;
8885         case 3:
8886             check_insn(ctx, ISA_MIPS32R2);
8887             gen_helper_mtc0_srsconf2(cpu_env, arg);
8888             rn = "SRSConf2";
8889             break;
8890         case 4:
8891             check_insn(ctx, ISA_MIPS32R2);
8892             gen_helper_mtc0_srsconf3(cpu_env, arg);
8893             rn = "SRSConf3";
8894             break;
8895         case 5:
8896             check_insn(ctx, ISA_MIPS32R2);
8897             gen_helper_mtc0_srsconf4(cpu_env, arg);
8898             rn = "SRSConf4";
8899             break;
8900         case 6:
8901             check_pw(ctx);
8902             gen_helper_mtc0_pwctl(cpu_env, arg);
8903             rn = "PWCtl";
8904             break;
8905         default:
8906             goto cp0_unimplemented;
8907         }
8908         break;
8909     case 7:
8910         switch (sel) {
8911         case 0:
8912             check_insn(ctx, ISA_MIPS32R2);
8913             gen_helper_mtc0_hwrena(cpu_env, arg);
8914             ctx->base.is_jmp = DISAS_STOP;
8915             rn = "HWREna";
8916             break;
8917         default:
8918             goto cp0_unimplemented;
8919         }
8920         break;
8921     case 8:
8922         switch (sel) {
8923         case 0:
8924             /* ignored */
8925             rn = "BadVAddr";
8926             break;
8927         case 1:
8928             /* ignored */
8929             rn = "BadInstr";
8930             break;
8931         case 2:
8932             /* ignored */
8933             rn = "BadInstrP";
8934             break;
8935         case 3:
8936             /* ignored */
8937             rn = "BadInstrX";
8938             break;
8939         default:
8940             goto cp0_unimplemented;
8941         }
8942         break;
8943     case 9:
8944         switch (sel) {
8945         case 0:
8946             gen_helper_mtc0_count(cpu_env, arg);
8947             rn = "Count";
8948             break;
8949         /* 6,7 are implementation dependent */
8950         default:
8951             goto cp0_unimplemented;
8952         }
8953         /* Stop translation as we may have switched the execution mode */
8954         ctx->base.is_jmp = DISAS_STOP;
8955         break;
8956     case 10:
8957         switch (sel) {
8958         case 0:
8959             gen_helper_mtc0_entryhi(cpu_env, arg);
8960             rn = "EntryHi";
8961             break;
8962         default:
8963             goto cp0_unimplemented;
8964         }
8965         break;
8966     case 11:
8967         switch (sel) {
8968         case 0:
8969             gen_helper_mtc0_compare(cpu_env, arg);
8970             rn = "Compare";
8971             break;
8972         /* 6,7 are implementation dependent */
8973         default:
8974             goto cp0_unimplemented;
8975         }
8976         /* Stop translation as we may have switched the execution mode */
8977         ctx->base.is_jmp = DISAS_STOP;
8978         break;
8979     case 12:
8980         switch (sel) {
8981         case 0:
8982             save_cpu_state(ctx, 1);
8983             gen_helper_mtc0_status(cpu_env, arg);
8984             /* DISAS_STOP isn't good enough here, hflags may have changed. */
8985             gen_save_pc(ctx->base.pc_next + 4);
8986             ctx->base.is_jmp = DISAS_EXIT;
8987             rn = "Status";
8988             break;
8989         case 1:
8990             check_insn(ctx, ISA_MIPS32R2);
8991             gen_helper_mtc0_intctl(cpu_env, arg);
8992             /* Stop translation as we may have switched the execution mode */
8993             ctx->base.is_jmp = DISAS_STOP;
8994             rn = "IntCtl";
8995             break;
8996         case 2:
8997             check_insn(ctx, ISA_MIPS32R2);
8998             gen_helper_mtc0_srsctl(cpu_env, arg);
8999             /* Stop translation as we may have switched the execution mode */
9000             ctx->base.is_jmp = DISAS_STOP;
9001             rn = "SRSCtl";
9002             break;
9003         case 3:
9004             check_insn(ctx, ISA_MIPS32R2);
9005             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
9006             /* Stop translation as we may have switched the execution mode */
9007             ctx->base.is_jmp = DISAS_STOP;
9008             rn = "SRSMap";
9009             break;
9010         default:
9011             goto cp0_unimplemented;
9012         }
9013         break;
9014     case 13:
9015         switch (sel) {
9016         case 0:
9017             save_cpu_state(ctx, 1);
9018             gen_helper_mtc0_cause(cpu_env, arg);
9019             /* Stop translation as we may have triggered an interrupt.
9020              * DISAS_STOP isn't sufficient, we need to ensure we break out of
9021              * translated code to check for pending interrupts.  */
9022             gen_save_pc(ctx->base.pc_next + 4);
9023             ctx->base.is_jmp = DISAS_EXIT;
9024             rn = "Cause";
9025             break;
9026         default:
9027             goto cp0_unimplemented;
9028         }
9029         break;
9030     case 14:
9031         switch (sel) {
9032         case 0:
9033             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
9034             rn = "EPC";
9035             break;
9036         default:
9037             goto cp0_unimplemented;
9038         }
9039         break;
9040     case 15:
9041         switch (sel) {
9042         case 0:
9043             /* ignored */
9044             rn = "PRid";
9045             break;
9046         case 1:
9047             check_insn(ctx, ISA_MIPS32R2);
9048             gen_helper_mtc0_ebase(cpu_env, arg);
9049             rn = "EBase";
9050             break;
9051         default:
9052             goto cp0_unimplemented;
9053         }
9054         break;
9055     case 16:
9056         switch (sel) {
9057         case 0:
9058             gen_helper_mtc0_config0(cpu_env, arg);
9059             rn = "Config";
9060             /* Stop translation as we may have switched the execution mode */
9061             ctx->base.is_jmp = DISAS_STOP;
9062             break;
9063         case 1:
9064             /* ignored, read only */
9065             rn = "Config1";
9066             break;
9067         case 2:
9068             gen_helper_mtc0_config2(cpu_env, arg);
9069             rn = "Config2";
9070             /* Stop translation as we may have switched the execution mode */
9071             ctx->base.is_jmp = DISAS_STOP;
9072             break;
9073         case 3:
9074             gen_helper_mtc0_config3(cpu_env, arg);
9075             rn = "Config3";
9076             /* Stop translation as we may have switched the execution mode */
9077             ctx->base.is_jmp = DISAS_STOP;
9078             break;
9079         case 4:
9080             /* currently ignored */
9081             rn = "Config4";
9082             break;
9083         case 5:
9084             gen_helper_mtc0_config5(cpu_env, arg);
9085             rn = "Config5";
9086             /* Stop translation as we may have switched the execution mode */
9087             ctx->base.is_jmp = DISAS_STOP;
9088             break;
9089         /* 6,7 are implementation dependent */
9090         default:
9091             rn = "Invalid config selector";
9092             goto cp0_unimplemented;
9093         }
9094         break;
9095     case 17:
9096         switch (sel) {
9097         case 0:
9098             gen_helper_mtc0_lladdr(cpu_env, arg);
9099             rn = "LLAddr";
9100             break;
9101         case 1:
9102             CP0_CHECK(ctx->mrp);
9103             gen_helper_mtc0_maar(cpu_env, arg);
9104             rn = "MAAR";
9105             break;
9106         case 2:
9107             CP0_CHECK(ctx->mrp);
9108             gen_helper_mtc0_maari(cpu_env, arg);
9109             rn = "MAARI";
9110             break;
9111         default:
9112             goto cp0_unimplemented;
9113         }
9114         break;
9115     case 18:
9116         switch (sel) {
9117         case 0:
9118         case 1:
9119         case 2:
9120         case 3:
9121         case 4:
9122         case 5:
9123         case 6:
9124         case 7:
9125             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9126             gen_helper_0e1i(mtc0_watchlo, arg, sel);
9127             rn = "WatchLo";
9128             break;
9129         default:
9130             goto cp0_unimplemented;
9131         }
9132         break;
9133     case 19:
9134         switch (sel) {
9135         case 0:
9136         case 1:
9137         case 2:
9138         case 3:
9139         case 4:
9140         case 5:
9141         case 6:
9142         case 7:
9143             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9144             gen_helper_0e1i(mtc0_watchhi, arg, sel);
9145             rn = "WatchHi";
9146             break;
9147         default:
9148             goto cp0_unimplemented;
9149         }
9150         break;
9151     case 20:
9152         switch (sel) {
9153         case 0:
9154             check_insn(ctx, ISA_MIPS3);
9155             gen_helper_mtc0_xcontext(cpu_env, arg);
9156             rn = "XContext";
9157             break;
9158         default:
9159             goto cp0_unimplemented;
9160         }
9161         break;
9162     case 21:
9163        /* Officially reserved, but sel 0 is used for R1x000 framemask */
9164         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9165         switch (sel) {
9166         case 0:
9167             gen_helper_mtc0_framemask(cpu_env, arg);
9168             rn = "Framemask";
9169             break;
9170         default:
9171             goto cp0_unimplemented;
9172         }
9173         break;
9174     case 22:
9175         /* ignored */
9176         rn = "Diagnostic"; /* implementation dependent */
9177         break;
9178     case 23:
9179         switch (sel) {
9180         case 0:
9181             gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
9182             /* DISAS_STOP isn't good enough here, hflags may have changed. */
9183             gen_save_pc(ctx->base.pc_next + 4);
9184             ctx->base.is_jmp = DISAS_EXIT;
9185             rn = "Debug";
9186             break;
9187         case 1:
9188 //            gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
9189             /* Stop translation as we may have switched the execution mode */
9190             ctx->base.is_jmp = DISAS_STOP;
9191             rn = "TraceControl";
9192             goto cp0_unimplemented;
9193         case 2:
9194 //            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
9195             /* Stop translation as we may have switched the execution mode */
9196             ctx->base.is_jmp = DISAS_STOP;
9197             rn = "TraceControl2";
9198             goto cp0_unimplemented;
9199         case 3:
9200 //            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
9201             /* Stop translation as we may have switched the execution mode */
9202             ctx->base.is_jmp = DISAS_STOP;
9203             rn = "UserTraceData";
9204             goto cp0_unimplemented;
9205         case 4:
9206 //            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
9207             /* Stop translation as we may have switched the execution mode */
9208             ctx->base.is_jmp = DISAS_STOP;
9209             rn = "TraceBPC";
9210             goto cp0_unimplemented;
9211         default:
9212             goto cp0_unimplemented;
9213         }
9214         break;
9215     case 24:
9216         switch (sel) {
9217         case 0:
9218             /* EJTAG support */
9219             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
9220             rn = "DEPC";
9221             break;
9222         default:
9223             goto cp0_unimplemented;
9224         }
9225         break;
9226     case 25:
9227         switch (sel) {
9228         case 0:
9229             gen_helper_mtc0_performance0(cpu_env, arg);
9230             rn = "Performance0";
9231             break;
9232         case 1:
9233 //            gen_helper_mtc0_performance1(cpu_env, arg);
9234             rn = "Performance1";
9235             goto cp0_unimplemented;
9236         case 2:
9237 //            gen_helper_mtc0_performance2(cpu_env, arg);
9238             rn = "Performance2";
9239             goto cp0_unimplemented;
9240         case 3:
9241 //            gen_helper_mtc0_performance3(cpu_env, arg);
9242             rn = "Performance3";
9243             goto cp0_unimplemented;
9244         case 4:
9245 //            gen_helper_mtc0_performance4(cpu_env, arg);
9246             rn = "Performance4";
9247             goto cp0_unimplemented;
9248         case 5:
9249 //            gen_helper_mtc0_performance5(cpu_env, arg);
9250             rn = "Performance5";
9251             goto cp0_unimplemented;
9252         case 6:
9253 //            gen_helper_mtc0_performance6(cpu_env, arg);
9254             rn = "Performance6";
9255             goto cp0_unimplemented;
9256         case 7:
9257 //            gen_helper_mtc0_performance7(cpu_env, arg);
9258             rn = "Performance7";
9259             goto cp0_unimplemented;
9260         default:
9261             goto cp0_unimplemented;
9262         }
9263         break;
9264     case 26:
9265         switch (sel) {
9266         case 0:
9267             gen_helper_mtc0_errctl(cpu_env, arg);
9268             ctx->base.is_jmp = DISAS_STOP;
9269             rn = "ErrCtl";
9270             break;
9271         default:
9272             goto cp0_unimplemented;
9273         }
9274         break;
9275     case 27:
9276         switch (sel) {
9277         case 0:
9278         case 1:
9279         case 2:
9280         case 3:
9281             /* ignored */
9282             rn = "CacheErr";
9283             break;
9284         default:
9285             goto cp0_unimplemented;
9286         }
9287         break;
9288     case 28:
9289         switch (sel) {
9290         case 0:
9291         case 2:
9292         case 4:
9293         case 6:
9294             gen_helper_mtc0_taglo(cpu_env, arg);
9295             rn = "TagLo";
9296             break;
9297         case 1:
9298         case 3:
9299         case 5:
9300         case 7:
9301             gen_helper_mtc0_datalo(cpu_env, arg);
9302             rn = "DataLo";
9303             break;
9304         default:
9305             goto cp0_unimplemented;
9306         }
9307         break;
9308     case 29:
9309         switch (sel) {
9310         case 0:
9311         case 2:
9312         case 4:
9313         case 6:
9314             gen_helper_mtc0_taghi(cpu_env, arg);
9315             rn = "TagHi";
9316             break;
9317         case 1:
9318         case 3:
9319         case 5:
9320         case 7:
9321             gen_helper_mtc0_datahi(cpu_env, arg);
9322             rn = "DataHi";
9323             break;
9324         default:
9325             rn = "invalid sel";
9326             goto cp0_unimplemented;
9327         }
9328         break;
9329     case 30:
9330         switch (sel) {
9331         case 0:
9332             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
9333             rn = "ErrorEPC";
9334             break;
9335         default:
9336             goto cp0_unimplemented;
9337         }
9338         break;
9339     case 31:
9340         switch (sel) {
9341         case 0:
9342             /* EJTAG support */
9343             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
9344             rn = "DESAVE";
9345             break;
9346         case 2:
9347         case 3:
9348         case 4:
9349         case 5:
9350         case 6:
9351         case 7:
9352             CP0_CHECK(ctx->kscrexist & (1 << sel));
9353             tcg_gen_st_tl(arg, cpu_env,
9354                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
9355             rn = "KScratch";
9356             break;
9357         default:
9358             goto cp0_unimplemented;
9359         }
9360         break;
9361     default:
9362         goto cp0_unimplemented;
9363     }
9364     trace_mips_translate_c0("dmtc0", rn, reg, sel);
9365
9366     /* For simplicity assume that all writes can cause interrupts.  */
9367     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
9368         gen_io_end();
9369         /* DISAS_STOP isn't sufficient, we need to ensure we break out of
9370          * translated code to check for pending interrupts.  */
9371         gen_save_pc(ctx->base.pc_next + 4);
9372         ctx->base.is_jmp = DISAS_EXIT;
9373     }
9374     return;
9375
9376 cp0_unimplemented:
9377     qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9378 }
9379 #endif /* TARGET_MIPS64 */
9380
9381 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
9382                      int u, int sel, int h)
9383 {
9384     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9385     TCGv t0 = tcg_temp_local_new();
9386
9387     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9388         ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9389          (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
9390         tcg_gen_movi_tl(t0, -1);
9391     else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9392              (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
9393         tcg_gen_movi_tl(t0, -1);
9394     else if (u == 0) {
9395         switch (rt) {
9396         case 1:
9397             switch (sel) {
9398             case 1:
9399                 gen_helper_mftc0_vpecontrol(t0, cpu_env);
9400                 break;
9401             case 2:
9402                 gen_helper_mftc0_vpeconf0(t0, cpu_env);
9403                 break;
9404             default:
9405                 goto die;
9406                 break;
9407             }
9408             break;
9409         case 2:
9410             switch (sel) {
9411             case 1:
9412                 gen_helper_mftc0_tcstatus(t0, cpu_env);
9413                 break;
9414             case 2:
9415                 gen_helper_mftc0_tcbind(t0, cpu_env);
9416                 break;
9417             case 3:
9418                 gen_helper_mftc0_tcrestart(t0, cpu_env);
9419                 break;
9420             case 4:
9421                 gen_helper_mftc0_tchalt(t0, cpu_env);
9422                 break;
9423             case 5:
9424                 gen_helper_mftc0_tccontext(t0, cpu_env);
9425                 break;
9426             case 6:
9427                 gen_helper_mftc0_tcschedule(t0, cpu_env);
9428                 break;
9429             case 7:
9430                 gen_helper_mftc0_tcschefback(t0, cpu_env);
9431                 break;
9432             default:
9433                 gen_mfc0(ctx, t0, rt, sel);
9434                 break;
9435             }
9436             break;
9437         case 10:
9438             switch (sel) {
9439             case 0:
9440                 gen_helper_mftc0_entryhi(t0, cpu_env);
9441                 break;
9442             default:
9443                 gen_mfc0(ctx, t0, rt, sel);
9444                 break;
9445             }
9446         case 12:
9447             switch (sel) {
9448             case 0:
9449                 gen_helper_mftc0_status(t0, cpu_env);
9450                 break;
9451             default:
9452                 gen_mfc0(ctx, t0, rt, sel);
9453                 break;
9454             }
9455         case 13:
9456             switch (sel) {
9457             case 0:
9458                 gen_helper_mftc0_cause(t0, cpu_env);
9459                 break;
9460             default:
9461                 goto die;
9462                 break;
9463             }
9464             break;
9465         case 14:
9466             switch (sel) {
9467             case 0:
9468                 gen_helper_mftc0_epc(t0, cpu_env);
9469                 break;
9470             default:
9471                 goto die;
9472                 break;
9473             }
9474             break;
9475         case 15:
9476             switch (sel) {
9477             case 1:
9478                 gen_helper_mftc0_ebase(t0, cpu_env);
9479                 break;
9480             default:
9481                 goto die;
9482                 break;
9483             }
9484             break;
9485         case 16:
9486             switch (sel) {
9487             case 0:
9488             case 1:
9489             case 2:
9490             case 3:
9491             case 4:
9492             case 5:
9493             case 6:
9494             case 7:
9495                 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
9496                 break;
9497             default:
9498                 goto die;
9499                 break;
9500             }
9501             break;
9502         case 23:
9503             switch (sel) {
9504             case 0:
9505                 gen_helper_mftc0_debug(t0, cpu_env);
9506                 break;
9507             default:
9508                 gen_mfc0(ctx, t0, rt, sel);
9509                 break;
9510             }
9511             break;
9512         default:
9513             gen_mfc0(ctx, t0, rt, sel);
9514         }
9515     } else switch (sel) {
9516     /* GPR registers. */
9517     case 0:
9518         gen_helper_1e0i(mftgpr, t0, rt);
9519         break;
9520     /* Auxiliary CPU registers */
9521     case 1:
9522         switch (rt) {
9523         case 0:
9524             gen_helper_1e0i(mftlo, t0, 0);
9525             break;
9526         case 1:
9527             gen_helper_1e0i(mfthi, t0, 0);
9528             break;
9529         case 2:
9530             gen_helper_1e0i(mftacx, t0, 0);
9531             break;
9532         case 4:
9533             gen_helper_1e0i(mftlo, t0, 1);
9534             break;
9535         case 5:
9536             gen_helper_1e0i(mfthi, t0, 1);
9537             break;
9538         case 6:
9539             gen_helper_1e0i(mftacx, t0, 1);
9540             break;
9541         case 8:
9542             gen_helper_1e0i(mftlo, t0, 2);
9543             break;
9544         case 9:
9545             gen_helper_1e0i(mfthi, t0, 2);
9546             break;
9547         case 10:
9548             gen_helper_1e0i(mftacx, t0, 2);
9549             break;
9550         case 12:
9551             gen_helper_1e0i(mftlo, t0, 3);
9552             break;
9553         case 13:
9554             gen_helper_1e0i(mfthi, t0, 3);
9555             break;
9556         case 14:
9557             gen_helper_1e0i(mftacx, t0, 3);
9558             break;
9559         case 16:
9560             gen_helper_mftdsp(t0, cpu_env);
9561             break;
9562         default:
9563             goto die;
9564         }
9565         break;
9566     /* Floating point (COP1). */
9567     case 2:
9568         /* XXX: For now we support only a single FPU context. */
9569         if (h == 0) {
9570             TCGv_i32 fp0 = tcg_temp_new_i32();
9571
9572             gen_load_fpr32(ctx, fp0, rt);
9573             tcg_gen_ext_i32_tl(t0, fp0);
9574             tcg_temp_free_i32(fp0);
9575         } else {
9576             TCGv_i32 fp0 = tcg_temp_new_i32();
9577
9578             gen_load_fpr32h(ctx, fp0, rt);
9579             tcg_gen_ext_i32_tl(t0, fp0);
9580             tcg_temp_free_i32(fp0);
9581         }
9582         break;
9583     case 3:
9584         /* XXX: For now we support only a single FPU context. */
9585         gen_helper_1e0i(cfc1, t0, rt);
9586         break;
9587     /* COP2: Not implemented. */
9588     case 4:
9589     case 5:
9590         /* fall through */
9591     default:
9592         goto die;
9593     }
9594     trace_mips_translate_tr("mftr", rt, u, sel, h);
9595     gen_store_gpr(t0, rd);
9596     tcg_temp_free(t0);
9597     return;
9598
9599 die:
9600     tcg_temp_free(t0);
9601     LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
9602     generate_exception_end(ctx, EXCP_RI);
9603 }
9604
9605 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
9606                      int u, int sel, int h)
9607 {
9608     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9609     TCGv t0 = tcg_temp_local_new();
9610
9611     gen_load_gpr(t0, rt);
9612     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9613         ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9614          (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
9615         /* NOP */ ;
9616     else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9617              (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
9618         /* NOP */ ;
9619     else if (u == 0) {
9620         switch (rd) {
9621         case 1:
9622             switch (sel) {
9623             case 1:
9624                 gen_helper_mttc0_vpecontrol(cpu_env, t0);
9625                 break;
9626             case 2:
9627                 gen_helper_mttc0_vpeconf0(cpu_env, t0);
9628                 break;
9629             default:
9630                 goto die;
9631                 break;
9632             }
9633             break;
9634         case 2:
9635             switch (sel) {
9636             case 1:
9637                 gen_helper_mttc0_tcstatus(cpu_env, t0);
9638                 break;
9639             case 2:
9640                 gen_helper_mttc0_tcbind(cpu_env, t0);
9641                 break;
9642             case 3:
9643                 gen_helper_mttc0_tcrestart(cpu_env, t0);
9644                 break;
9645             case 4:
9646                 gen_helper_mttc0_tchalt(cpu_env, t0);
9647                 break;
9648             case 5:
9649                 gen_helper_mttc0_tccontext(cpu_env, t0);
9650                 break;
9651             case 6:
9652                 gen_helper_mttc0_tcschedule(cpu_env, t0);
9653                 break;
9654             case 7:
9655                 gen_helper_mttc0_tcschefback(cpu_env, t0);
9656                 break;
9657             default:
9658                 gen_mtc0(ctx, t0, rd, sel);
9659                 break;
9660             }
9661             break;
9662         case 10:
9663             switch (sel) {
9664             case 0:
9665                 gen_helper_mttc0_entryhi(cpu_env, t0);
9666                 break;
9667             default:
9668                 gen_mtc0(ctx, t0, rd, sel);
9669                 break;
9670             }
9671         case 12:
9672             switch (sel) {
9673             case 0:
9674                 gen_helper_mttc0_status(cpu_env, t0);
9675                 break;
9676             default:
9677                 gen_mtc0(ctx, t0, rd, sel);
9678                 break;
9679             }
9680         case 13:
9681             switch (sel) {
9682             case 0:
9683                 gen_helper_mttc0_cause(cpu_env, t0);
9684                 break;
9685             default:
9686                 goto die;
9687                 break;
9688             }
9689             break;
9690         case 15:
9691             switch (sel) {
9692             case 1:
9693                 gen_helper_mttc0_ebase(cpu_env, t0);
9694                 break;
9695             default:
9696                 goto die;
9697                 break;
9698             }
9699             break;
9700         case 23:
9701             switch (sel) {
9702             case 0:
9703                 gen_helper_mttc0_debug(cpu_env, t0);
9704                 break;
9705             default:
9706                 gen_mtc0(ctx, t0, rd, sel);
9707                 break;
9708             }
9709             break;
9710         default:
9711             gen_mtc0(ctx, t0, rd, sel);
9712         }
9713     } else switch (sel) {
9714     /* GPR registers. */
9715     case 0:
9716         gen_helper_0e1i(mttgpr, t0, rd);
9717         break;
9718     /* Auxiliary CPU registers */
9719     case 1:
9720         switch (rd) {
9721         case 0:
9722             gen_helper_0e1i(mttlo, t0, 0);
9723             break;
9724         case 1:
9725             gen_helper_0e1i(mtthi, t0, 0);
9726             break;
9727         case 2:
9728             gen_helper_0e1i(mttacx, t0, 0);
9729             break;
9730         case 4:
9731             gen_helper_0e1i(mttlo, t0, 1);
9732             break;
9733         case 5:
9734             gen_helper_0e1i(mtthi, t0, 1);
9735             break;
9736         case 6:
9737             gen_helper_0e1i(mttacx, t0, 1);
9738             break;
9739         case 8:
9740             gen_helper_0e1i(mttlo, t0, 2);
9741             break;
9742         case 9:
9743             gen_helper_0e1i(mtthi, t0, 2);
9744             break;
9745         case 10:
9746             gen_helper_0e1i(mttacx, t0, 2);
9747             break;
9748         case 12:
9749             gen_helper_0e1i(mttlo, t0, 3);
9750             break;
9751         case 13:
9752             gen_helper_0e1i(mtthi, t0, 3);
9753             break;
9754         case 14:
9755             gen_helper_0e1i(mttacx, t0, 3);
9756             break;
9757         case 16:
9758             gen_helper_mttdsp(cpu_env, t0);
9759             break;
9760         default:
9761             goto die;
9762         }
9763         break;
9764     /* Floating point (COP1). */
9765     case 2:
9766         /* XXX: For now we support only a single FPU context. */
9767         if (h == 0) {
9768             TCGv_i32 fp0 = tcg_temp_new_i32();
9769
9770             tcg_gen_trunc_tl_i32(fp0, t0);
9771             gen_store_fpr32(ctx, fp0, rd);
9772             tcg_temp_free_i32(fp0);
9773         } else {
9774             TCGv_i32 fp0 = tcg_temp_new_i32();
9775
9776             tcg_gen_trunc_tl_i32(fp0, t0);
9777             gen_store_fpr32h(ctx, fp0, rd);
9778             tcg_temp_free_i32(fp0);
9779         }
9780         break;
9781     case 3:
9782         /* XXX: For now we support only a single FPU context. */
9783         {
9784             TCGv_i32 fs_tmp = tcg_const_i32(rd);
9785
9786             gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
9787             tcg_temp_free_i32(fs_tmp);
9788         }
9789         /* Stop translation as we may have changed hflags */
9790         ctx->base.is_jmp = DISAS_STOP;
9791         break;
9792     /* COP2: Not implemented. */
9793     case 4:
9794     case 5:
9795         /* fall through */
9796     default:
9797         goto die;
9798     }
9799     trace_mips_translate_tr("mttr", rd, u, sel, h);
9800     tcg_temp_free(t0);
9801     return;
9802
9803 die:
9804     tcg_temp_free(t0);
9805     LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
9806     generate_exception_end(ctx, EXCP_RI);
9807 }
9808
9809 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
9810 {
9811     const char *opn = "ldst";
9812
9813     check_cp0_enabled(ctx);
9814     switch (opc) {
9815     case OPC_MFC0:
9816         if (rt == 0) {
9817             /* Treat as NOP. */
9818             return;
9819         }
9820         gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9821         opn = "mfc0";
9822         break;
9823     case OPC_MTC0:
9824         {
9825             TCGv t0 = tcg_temp_new();
9826
9827             gen_load_gpr(t0, rt);
9828             gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
9829             tcg_temp_free(t0);
9830         }
9831         opn = "mtc0";
9832         break;
9833 #if defined(TARGET_MIPS64)
9834     case OPC_DMFC0:
9835         check_insn(ctx, ISA_MIPS3);
9836         if (rt == 0) {
9837             /* Treat as NOP. */
9838             return;
9839         }
9840         gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9841         opn = "dmfc0";
9842         break;
9843     case OPC_DMTC0:
9844         check_insn(ctx, ISA_MIPS3);
9845         {
9846             TCGv t0 = tcg_temp_new();
9847
9848             gen_load_gpr(t0, rt);
9849             gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
9850             tcg_temp_free(t0);
9851         }
9852         opn = "dmtc0";
9853         break;
9854 #endif
9855     case OPC_MFHC0:
9856         check_mvh(ctx);
9857         if (rt == 0) {
9858             /* Treat as NOP. */
9859             return;
9860         }
9861         gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9862         opn = "mfhc0";
9863         break;
9864     case OPC_MTHC0:
9865         check_mvh(ctx);
9866         {
9867             TCGv t0 = tcg_temp_new();
9868             gen_load_gpr(t0, rt);
9869             gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
9870             tcg_temp_free(t0);
9871         }
9872         opn = "mthc0";
9873         break;
9874     case OPC_MFTR:
9875         check_cp0_enabled(ctx);
9876         if (rd == 0) {
9877             /* Treat as NOP. */
9878             return;
9879         }
9880         gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
9881                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9882         opn = "mftr";
9883         break;
9884     case OPC_MTTR:
9885         check_cp0_enabled(ctx);
9886         gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
9887                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9888         opn = "mttr";
9889         break;
9890     case OPC_TLBWI:
9891         opn = "tlbwi";
9892         if (!env->tlb->helper_tlbwi)
9893             goto die;
9894         gen_helper_tlbwi(cpu_env);
9895         break;
9896     case OPC_TLBINV:
9897         opn = "tlbinv";
9898         if (ctx->ie >= 2) {
9899             if (!env->tlb->helper_tlbinv) {
9900                 goto die;
9901             }
9902             gen_helper_tlbinv(cpu_env);
9903         } /* treat as nop if TLBINV not supported */
9904         break;
9905     case OPC_TLBINVF:
9906         opn = "tlbinvf";
9907         if (ctx->ie >= 2) {
9908             if (!env->tlb->helper_tlbinvf) {
9909                 goto die;
9910             }
9911             gen_helper_tlbinvf(cpu_env);
9912         } /* treat as nop if TLBINV not supported */
9913         break;
9914     case OPC_TLBWR:
9915         opn = "tlbwr";
9916         if (!env->tlb->helper_tlbwr)
9917             goto die;
9918         gen_helper_tlbwr(cpu_env);
9919         break;
9920     case OPC_TLBP:
9921         opn = "tlbp";
9922         if (!env->tlb->helper_tlbp)
9923             goto die;
9924         gen_helper_tlbp(cpu_env);
9925         break;
9926     case OPC_TLBR:
9927         opn = "tlbr";
9928         if (!env->tlb->helper_tlbr)
9929             goto die;
9930         gen_helper_tlbr(cpu_env);
9931         break;
9932     case OPC_ERET: /* OPC_ERETNC */
9933         if ((ctx->insn_flags & ISA_MIPS32R6) &&
9934             (ctx->hflags & MIPS_HFLAG_BMASK)) {
9935             goto die;
9936         } else {
9937             int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
9938             if (ctx->opcode & (1 << bit_shift)) {
9939                 /* OPC_ERETNC */
9940                 opn = "eretnc";
9941                 check_insn(ctx, ISA_MIPS32R5);
9942                 gen_helper_eretnc(cpu_env);
9943             } else {
9944                 /* OPC_ERET */
9945                 opn = "eret";
9946                 check_insn(ctx, ISA_MIPS2);
9947                 gen_helper_eret(cpu_env);
9948             }
9949             ctx->base.is_jmp = DISAS_EXIT;
9950         }
9951         break;
9952     case OPC_DERET:
9953         opn = "deret";
9954         check_insn(ctx, ISA_MIPS32);
9955         if ((ctx->insn_flags & ISA_MIPS32R6) &&
9956             (ctx->hflags & MIPS_HFLAG_BMASK)) {
9957             goto die;
9958         }
9959         if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9960             MIPS_INVAL(opn);
9961             generate_exception_end(ctx, EXCP_RI);
9962         } else {
9963             gen_helper_deret(cpu_env);
9964             ctx->base.is_jmp = DISAS_EXIT;
9965         }
9966         break;
9967     case OPC_WAIT:
9968         opn = "wait";
9969         check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
9970         if ((ctx->insn_flags & ISA_MIPS32R6) &&
9971             (ctx->hflags & MIPS_HFLAG_BMASK)) {
9972             goto die;
9973         }
9974         /* If we get an exception, we want to restart at next instruction */
9975         ctx->base.pc_next += 4;
9976         save_cpu_state(ctx, 1);
9977         ctx->base.pc_next -= 4;
9978         gen_helper_wait(cpu_env);
9979         ctx->base.is_jmp = DISAS_NORETURN;
9980         break;
9981     default:
9982  die:
9983         MIPS_INVAL(opn);
9984         generate_exception_end(ctx, EXCP_RI);
9985         return;
9986     }
9987     (void)opn; /* avoid a compiler warning */
9988 }
9989 #endif /* !CONFIG_USER_ONLY */
9990
9991 /* CP1 Branches (before delay slot) */
9992 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
9993                                 int32_t cc, int32_t offset)
9994 {
9995     target_ulong btarget;
9996     TCGv_i32 t0 = tcg_temp_new_i32();
9997
9998     if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9999         generate_exception_end(ctx, EXCP_RI);
10000         goto out;
10001     }
10002
10003     if (cc != 0)
10004         check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
10005
10006     btarget = ctx->base.pc_next + 4 + offset;
10007
10008     switch (op) {
10009     case OPC_BC1F:
10010         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10011         tcg_gen_not_i32(t0, t0);
10012         tcg_gen_andi_i32(t0, t0, 1);
10013         tcg_gen_extu_i32_tl(bcond, t0);
10014         goto not_likely;
10015     case OPC_BC1FL:
10016         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10017         tcg_gen_not_i32(t0, t0);
10018         tcg_gen_andi_i32(t0, t0, 1);
10019         tcg_gen_extu_i32_tl(bcond, t0);
10020         goto likely;
10021     case OPC_BC1T:
10022         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10023         tcg_gen_andi_i32(t0, t0, 1);
10024         tcg_gen_extu_i32_tl(bcond, t0);
10025         goto not_likely;
10026     case OPC_BC1TL:
10027         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10028         tcg_gen_andi_i32(t0, t0, 1);
10029         tcg_gen_extu_i32_tl(bcond, t0);
10030     likely:
10031         ctx->hflags |= MIPS_HFLAG_BL;
10032         break;
10033     case OPC_BC1FANY2:
10034         {
10035             TCGv_i32 t1 = tcg_temp_new_i32();
10036             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10037             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10038             tcg_gen_nand_i32(t0, t0, t1);
10039             tcg_temp_free_i32(t1);
10040             tcg_gen_andi_i32(t0, t0, 1);
10041             tcg_gen_extu_i32_tl(bcond, t0);
10042         }
10043         goto not_likely;
10044     case OPC_BC1TANY2:
10045         {
10046             TCGv_i32 t1 = tcg_temp_new_i32();
10047             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10048             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10049             tcg_gen_or_i32(t0, t0, t1);
10050             tcg_temp_free_i32(t1);
10051             tcg_gen_andi_i32(t0, t0, 1);
10052             tcg_gen_extu_i32_tl(bcond, t0);
10053         }
10054         goto not_likely;
10055     case OPC_BC1FANY4:
10056         {
10057             TCGv_i32 t1 = tcg_temp_new_i32();
10058             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10059             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10060             tcg_gen_and_i32(t0, t0, t1);
10061             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
10062             tcg_gen_and_i32(t0, t0, t1);
10063             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
10064             tcg_gen_nand_i32(t0, t0, t1);
10065             tcg_temp_free_i32(t1);
10066             tcg_gen_andi_i32(t0, t0, 1);
10067             tcg_gen_extu_i32_tl(bcond, t0);
10068         }
10069         goto not_likely;
10070     case OPC_BC1TANY4:
10071         {
10072             TCGv_i32 t1 = tcg_temp_new_i32();
10073             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10074             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10075             tcg_gen_or_i32(t0, t0, t1);
10076             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
10077             tcg_gen_or_i32(t0, t0, t1);
10078             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
10079             tcg_gen_or_i32(t0, t0, t1);
10080             tcg_temp_free_i32(t1);
10081             tcg_gen_andi_i32(t0, t0, 1);
10082             tcg_gen_extu_i32_tl(bcond, t0);
10083         }
10084     not_likely:
10085         ctx->hflags |= MIPS_HFLAG_BC;
10086         break;
10087     default:
10088         MIPS_INVAL("cp1 cond branch");
10089         generate_exception_end(ctx, EXCP_RI);
10090         goto out;
10091     }
10092     ctx->btarget = btarget;
10093     ctx->hflags |= MIPS_HFLAG_BDS32;
10094  out:
10095     tcg_temp_free_i32(t0);
10096 }
10097
10098 /* R6 CP1 Branches */
10099 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
10100                                    int32_t ft, int32_t offset,
10101                                    int delayslot_size)
10102 {
10103     target_ulong btarget;
10104     TCGv_i64 t0 = tcg_temp_new_i64();
10105
10106     if (ctx->hflags & MIPS_HFLAG_BMASK) {
10107 #ifdef MIPS_DEBUG_DISAS
10108         LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10109                   "\n", ctx->base.pc_next);
10110 #endif
10111         generate_exception_end(ctx, EXCP_RI);
10112         goto out;
10113     }
10114
10115     gen_load_fpr64(ctx, t0, ft);
10116     tcg_gen_andi_i64(t0, t0, 1);
10117
10118     btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
10119
10120     switch (op) {
10121     case OPC_BC1EQZ:
10122         tcg_gen_xori_i64(t0, t0, 1);
10123         ctx->hflags |= MIPS_HFLAG_BC;
10124         break;
10125     case OPC_BC1NEZ:
10126         /* t0 already set */
10127         ctx->hflags |= MIPS_HFLAG_BC;
10128         break;
10129     default:
10130         MIPS_INVAL("cp1 cond branch");
10131         generate_exception_end(ctx, EXCP_RI);
10132         goto out;
10133     }
10134
10135     tcg_gen_trunc_i64_tl(bcond, t0);
10136
10137     ctx->btarget = btarget;
10138
10139     switch (delayslot_size) {
10140     case 2:
10141         ctx->hflags |= MIPS_HFLAG_BDS16;
10142         break;
10143     case 4:
10144         ctx->hflags |= MIPS_HFLAG_BDS32;
10145         break;
10146     }
10147
10148 out:
10149     tcg_temp_free_i64(t0);
10150 }
10151
10152 /* Coprocessor 1 (FPU) */
10153
10154 #define FOP(func, fmt) (((fmt) << 21) | (func))
10155
10156 enum fopcode {
10157     OPC_ADD_S = FOP(0, FMT_S),
10158     OPC_SUB_S = FOP(1, FMT_S),
10159     OPC_MUL_S = FOP(2, FMT_S),
10160     OPC_DIV_S = FOP(3, FMT_S),
10161     OPC_SQRT_S = FOP(4, FMT_S),
10162     OPC_ABS_S = FOP(5, FMT_S),
10163     OPC_MOV_S = FOP(6, FMT_S),
10164     OPC_NEG_S = FOP(7, FMT_S),
10165     OPC_ROUND_L_S = FOP(8, FMT_S),
10166     OPC_TRUNC_L_S = FOP(9, FMT_S),
10167     OPC_CEIL_L_S = FOP(10, FMT_S),
10168     OPC_FLOOR_L_S = FOP(11, FMT_S),
10169     OPC_ROUND_W_S = FOP(12, FMT_S),
10170     OPC_TRUNC_W_S = FOP(13, FMT_S),
10171     OPC_CEIL_W_S = FOP(14, FMT_S),
10172     OPC_FLOOR_W_S = FOP(15, FMT_S),
10173     OPC_SEL_S = FOP(16, FMT_S),
10174     OPC_MOVCF_S = FOP(17, FMT_S),
10175     OPC_MOVZ_S = FOP(18, FMT_S),
10176     OPC_MOVN_S = FOP(19, FMT_S),
10177     OPC_SELEQZ_S = FOP(20, FMT_S),
10178     OPC_RECIP_S = FOP(21, FMT_S),
10179     OPC_RSQRT_S = FOP(22, FMT_S),
10180     OPC_SELNEZ_S = FOP(23, FMT_S),
10181     OPC_MADDF_S = FOP(24, FMT_S),
10182     OPC_MSUBF_S = FOP(25, FMT_S),
10183     OPC_RINT_S = FOP(26, FMT_S),
10184     OPC_CLASS_S = FOP(27, FMT_S),
10185     OPC_MIN_S = FOP(28, FMT_S),
10186     OPC_RECIP2_S = FOP(28, FMT_S),
10187     OPC_MINA_S = FOP(29, FMT_S),
10188     OPC_RECIP1_S = FOP(29, FMT_S),
10189     OPC_MAX_S = FOP(30, FMT_S),
10190     OPC_RSQRT1_S = FOP(30, FMT_S),
10191     OPC_MAXA_S = FOP(31, FMT_S),
10192     OPC_RSQRT2_S = FOP(31, FMT_S),
10193     OPC_CVT_D_S = FOP(33, FMT_S),
10194     OPC_CVT_W_S = FOP(36, FMT_S),
10195     OPC_CVT_L_S = FOP(37, FMT_S),
10196     OPC_CVT_PS_S = FOP(38, FMT_S),
10197     OPC_CMP_F_S = FOP (48, FMT_S),
10198     OPC_CMP_UN_S = FOP (49, FMT_S),
10199     OPC_CMP_EQ_S = FOP (50, FMT_S),
10200     OPC_CMP_UEQ_S = FOP (51, FMT_S),
10201     OPC_CMP_OLT_S = FOP (52, FMT_S),
10202     OPC_CMP_ULT_S = FOP (53, FMT_S),
10203     OPC_CMP_OLE_S = FOP (54, FMT_S),
10204     OPC_CMP_ULE_S = FOP (55, FMT_S),
10205     OPC_CMP_SF_S = FOP (56, FMT_S),
10206     OPC_CMP_NGLE_S = FOP (57, FMT_S),
10207     OPC_CMP_SEQ_S = FOP (58, FMT_S),
10208     OPC_CMP_NGL_S = FOP (59, FMT_S),
10209     OPC_CMP_LT_S = FOP (60, FMT_S),
10210     OPC_CMP_NGE_S = FOP (61, FMT_S),
10211     OPC_CMP_LE_S = FOP (62, FMT_S),
10212     OPC_CMP_NGT_S = FOP (63, FMT_S),
10213
10214     OPC_ADD_D = FOP(0, FMT_D),
10215     OPC_SUB_D = FOP(1, FMT_D),
10216     OPC_MUL_D = FOP(2, FMT_D),
10217     OPC_DIV_D = FOP(3, FMT_D),
10218     OPC_SQRT_D = FOP(4, FMT_D),
10219     OPC_ABS_D = FOP(5, FMT_D),
10220     OPC_MOV_D = FOP(6, FMT_D),
10221     OPC_NEG_D = FOP(7, FMT_D),
10222     OPC_ROUND_L_D = FOP(8, FMT_D),
10223     OPC_TRUNC_L_D = FOP(9, FMT_D),
10224     OPC_CEIL_L_D = FOP(10, FMT_D),
10225     OPC_FLOOR_L_D = FOP(11, FMT_D),
10226     OPC_ROUND_W_D = FOP(12, FMT_D),
10227     OPC_TRUNC_W_D = FOP(13, FMT_D),
10228     OPC_CEIL_W_D = FOP(14, FMT_D),
10229     OPC_FLOOR_W_D = FOP(15, FMT_D),
10230     OPC_SEL_D = FOP(16, FMT_D),
10231     OPC_MOVCF_D = FOP(17, FMT_D),
10232     OPC_MOVZ_D = FOP(18, FMT_D),
10233     OPC_MOVN_D = FOP(19, FMT_D),
10234     OPC_SELEQZ_D = FOP(20, FMT_D),
10235     OPC_RECIP_D = FOP(21, FMT_D),
10236     OPC_RSQRT_D = FOP(22, FMT_D),
10237     OPC_SELNEZ_D = FOP(23, FMT_D),
10238     OPC_MADDF_D = FOP(24, FMT_D),
10239     OPC_MSUBF_D = FOP(25, FMT_D),
10240     OPC_RINT_D = FOP(26, FMT_D),
10241     OPC_CLASS_D = FOP(27, FMT_D),
10242     OPC_MIN_D = FOP(28, FMT_D),
10243     OPC_RECIP2_D = FOP(28, FMT_D),
10244     OPC_MINA_D = FOP(29, FMT_D),
10245     OPC_RECIP1_D = FOP(29, FMT_D),
10246     OPC_MAX_D = FOP(30, FMT_D),
10247     OPC_RSQRT1_D = FOP(30, FMT_D),
10248     OPC_MAXA_D = FOP(31, FMT_D),
10249     OPC_RSQRT2_D = FOP(31, FMT_D),
10250     OPC_CVT_S_D = FOP(32, FMT_D),
10251     OPC_CVT_W_D = FOP(36, FMT_D),
10252     OPC_CVT_L_D = FOP(37, FMT_D),
10253     OPC_CMP_F_D = FOP (48, FMT_D),
10254     OPC_CMP_UN_D = FOP (49, FMT_D),
10255     OPC_CMP_EQ_D = FOP (50, FMT_D),
10256     OPC_CMP_UEQ_D = FOP (51, FMT_D),
10257     OPC_CMP_OLT_D = FOP (52, FMT_D),
10258     OPC_CMP_ULT_D = FOP (53, FMT_D),
10259     OPC_CMP_OLE_D = FOP (54, FMT_D),
10260     OPC_CMP_ULE_D = FOP (55, FMT_D),
10261     OPC_CMP_SF_D = FOP (56, FMT_D),
10262     OPC_CMP_NGLE_D = FOP (57, FMT_D),
10263     OPC_CMP_SEQ_D = FOP (58, FMT_D),
10264     OPC_CMP_NGL_D = FOP (59, FMT_D),
10265     OPC_CMP_LT_D = FOP (60, FMT_D),
10266     OPC_CMP_NGE_D = FOP (61, FMT_D),
10267     OPC_CMP_LE_D = FOP (62, FMT_D),
10268     OPC_CMP_NGT_D = FOP (63, FMT_D),
10269
10270     OPC_CVT_S_W = FOP(32, FMT_W),
10271     OPC_CVT_D_W = FOP(33, FMT_W),
10272     OPC_CVT_S_L = FOP(32, FMT_L),
10273     OPC_CVT_D_L = FOP(33, FMT_L),
10274     OPC_CVT_PS_PW = FOP(38, FMT_W),
10275
10276     OPC_ADD_PS = FOP(0, FMT_PS),
10277     OPC_SUB_PS = FOP(1, FMT_PS),
10278     OPC_MUL_PS = FOP(2, FMT_PS),
10279     OPC_DIV_PS = FOP(3, FMT_PS),
10280     OPC_ABS_PS = FOP(5, FMT_PS),
10281     OPC_MOV_PS = FOP(6, FMT_PS),
10282     OPC_NEG_PS = FOP(7, FMT_PS),
10283     OPC_MOVCF_PS = FOP(17, FMT_PS),
10284     OPC_MOVZ_PS = FOP(18, FMT_PS),
10285     OPC_MOVN_PS = FOP(19, FMT_PS),
10286     OPC_ADDR_PS = FOP(24, FMT_PS),
10287     OPC_MULR_PS = FOP(26, FMT_PS),
10288     OPC_RECIP2_PS = FOP(28, FMT_PS),
10289     OPC_RECIP1_PS = FOP(29, FMT_PS),
10290     OPC_RSQRT1_PS = FOP(30, FMT_PS),
10291     OPC_RSQRT2_PS = FOP(31, FMT_PS),
10292
10293     OPC_CVT_S_PU = FOP(32, FMT_PS),
10294     OPC_CVT_PW_PS = FOP(36, FMT_PS),
10295     OPC_CVT_S_PL = FOP(40, FMT_PS),
10296     OPC_PLL_PS = FOP(44, FMT_PS),
10297     OPC_PLU_PS = FOP(45, FMT_PS),
10298     OPC_PUL_PS = FOP(46, FMT_PS),
10299     OPC_PUU_PS = FOP(47, FMT_PS),
10300     OPC_CMP_F_PS = FOP (48, FMT_PS),
10301     OPC_CMP_UN_PS = FOP (49, FMT_PS),
10302     OPC_CMP_EQ_PS = FOP (50, FMT_PS),
10303     OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
10304     OPC_CMP_OLT_PS = FOP (52, FMT_PS),
10305     OPC_CMP_ULT_PS = FOP (53, FMT_PS),
10306     OPC_CMP_OLE_PS = FOP (54, FMT_PS),
10307     OPC_CMP_ULE_PS = FOP (55, FMT_PS),
10308     OPC_CMP_SF_PS = FOP (56, FMT_PS),
10309     OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
10310     OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
10311     OPC_CMP_NGL_PS = FOP (59, FMT_PS),
10312     OPC_CMP_LT_PS = FOP (60, FMT_PS),
10313     OPC_CMP_NGE_PS = FOP (61, FMT_PS),
10314     OPC_CMP_LE_PS = FOP (62, FMT_PS),
10315     OPC_CMP_NGT_PS = FOP (63, FMT_PS),
10316 };
10317
10318 enum r6_f_cmp_op {
10319     R6_OPC_CMP_AF_S   = FOP(0, FMT_W),
10320     R6_OPC_CMP_UN_S   = FOP(1, FMT_W),
10321     R6_OPC_CMP_EQ_S   = FOP(2, FMT_W),
10322     R6_OPC_CMP_UEQ_S  = FOP(3, FMT_W),
10323     R6_OPC_CMP_LT_S   = FOP(4, FMT_W),
10324     R6_OPC_CMP_ULT_S  = FOP(5, FMT_W),
10325     R6_OPC_CMP_LE_S   = FOP(6, FMT_W),
10326     R6_OPC_CMP_ULE_S  = FOP(7, FMT_W),
10327     R6_OPC_CMP_SAF_S  = FOP(8, FMT_W),
10328     R6_OPC_CMP_SUN_S  = FOP(9, FMT_W),
10329     R6_OPC_CMP_SEQ_S  = FOP(10, FMT_W),
10330     R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
10331     R6_OPC_CMP_SLT_S  = FOP(12, FMT_W),
10332     R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
10333     R6_OPC_CMP_SLE_S  = FOP(14, FMT_W),
10334     R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
10335     R6_OPC_CMP_OR_S   = FOP(17, FMT_W),
10336     R6_OPC_CMP_UNE_S  = FOP(18, FMT_W),
10337     R6_OPC_CMP_NE_S   = FOP(19, FMT_W),
10338     R6_OPC_CMP_SOR_S  = FOP(25, FMT_W),
10339     R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
10340     R6_OPC_CMP_SNE_S  = FOP(27, FMT_W),
10341
10342     R6_OPC_CMP_AF_D   = FOP(0, FMT_L),
10343     R6_OPC_CMP_UN_D   = FOP(1, FMT_L),
10344     R6_OPC_CMP_EQ_D   = FOP(2, FMT_L),
10345     R6_OPC_CMP_UEQ_D  = FOP(3, FMT_L),
10346     R6_OPC_CMP_LT_D   = FOP(4, FMT_L),
10347     R6_OPC_CMP_ULT_D  = FOP(5, FMT_L),
10348     R6_OPC_CMP_LE_D   = FOP(6, FMT_L),
10349     R6_OPC_CMP_ULE_D  = FOP(7, FMT_L),
10350     R6_OPC_CMP_SAF_D  = FOP(8, FMT_L),
10351     R6_OPC_CMP_SUN_D  = FOP(9, FMT_L),
10352     R6_OPC_CMP_SEQ_D  = FOP(10, FMT_L),
10353     R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
10354     R6_OPC_CMP_SLT_D  = FOP(12, FMT_L),
10355     R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
10356     R6_OPC_CMP_SLE_D  = FOP(14, FMT_L),
10357     R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
10358     R6_OPC_CMP_OR_D   = FOP(17, FMT_L),
10359     R6_OPC_CMP_UNE_D  = FOP(18, FMT_L),
10360     R6_OPC_CMP_NE_D   = FOP(19, FMT_L),
10361     R6_OPC_CMP_SOR_D  = FOP(25, FMT_L),
10362     R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
10363     R6_OPC_CMP_SNE_D  = FOP(27, FMT_L),
10364 };
10365 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
10366 {
10367     TCGv t0 = tcg_temp_new();
10368
10369     switch (opc) {
10370     case OPC_MFC1:
10371         {
10372             TCGv_i32 fp0 = tcg_temp_new_i32();
10373
10374             gen_load_fpr32(ctx, fp0, fs);
10375             tcg_gen_ext_i32_tl(t0, fp0);
10376             tcg_temp_free_i32(fp0);
10377         }
10378         gen_store_gpr(t0, rt);
10379         break;
10380     case OPC_MTC1:
10381         gen_load_gpr(t0, rt);
10382         {
10383             TCGv_i32 fp0 = tcg_temp_new_i32();
10384
10385             tcg_gen_trunc_tl_i32(fp0, t0);
10386             gen_store_fpr32(ctx, fp0, fs);
10387             tcg_temp_free_i32(fp0);
10388         }
10389         break;
10390     case OPC_CFC1:
10391         gen_helper_1e0i(cfc1, t0, fs);
10392         gen_store_gpr(t0, rt);
10393         break;
10394     case OPC_CTC1:
10395         gen_load_gpr(t0, rt);
10396         save_cpu_state(ctx, 0);
10397         {
10398             TCGv_i32 fs_tmp = tcg_const_i32(fs);
10399
10400             gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10401             tcg_temp_free_i32(fs_tmp);
10402         }
10403         /* Stop translation as we may have changed hflags */
10404         ctx->base.is_jmp = DISAS_STOP;
10405         break;
10406 #if defined(TARGET_MIPS64)
10407     case OPC_DMFC1:
10408         gen_load_fpr64(ctx, t0, fs);
10409         gen_store_gpr(t0, rt);
10410         break;
10411     case OPC_DMTC1:
10412         gen_load_gpr(t0, rt);
10413         gen_store_fpr64(ctx, t0, fs);
10414         break;
10415 #endif
10416     case OPC_MFHC1:
10417         {
10418             TCGv_i32 fp0 = tcg_temp_new_i32();
10419
10420             gen_load_fpr32h(ctx, fp0, fs);
10421             tcg_gen_ext_i32_tl(t0, fp0);
10422             tcg_temp_free_i32(fp0);
10423         }
10424         gen_store_gpr(t0, rt);
10425         break;
10426     case OPC_MTHC1:
10427         gen_load_gpr(t0, rt);
10428         {
10429             TCGv_i32 fp0 = tcg_temp_new_i32();
10430
10431             tcg_gen_trunc_tl_i32(fp0, t0);
10432             gen_store_fpr32h(ctx, fp0, fs);
10433             tcg_temp_free_i32(fp0);
10434         }
10435         break;
10436     default:
10437         MIPS_INVAL("cp1 move");
10438         generate_exception_end(ctx, EXCP_RI);
10439         goto out;
10440     }
10441
10442  out:
10443     tcg_temp_free(t0);
10444 }
10445
10446 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
10447 {
10448     TCGLabel *l1;
10449     TCGCond cond;
10450     TCGv_i32 t0;
10451
10452     if (rd == 0) {
10453         /* Treat as NOP. */
10454         return;
10455     }
10456
10457     if (tf)
10458         cond = TCG_COND_EQ;
10459     else
10460         cond = TCG_COND_NE;
10461
10462     l1 = gen_new_label();
10463     t0 = tcg_temp_new_i32();
10464     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10465     tcg_gen_brcondi_i32(cond, t0, 0, l1);
10466     tcg_temp_free_i32(t0);
10467     if (rs == 0) {
10468         tcg_gen_movi_tl(cpu_gpr[rd], 0);
10469     } else {
10470         tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
10471     }
10472     gen_set_label(l1);
10473 }
10474
10475 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
10476                                int tf)
10477 {
10478     int cond;
10479     TCGv_i32 t0 = tcg_temp_new_i32();
10480     TCGLabel *l1 = gen_new_label();
10481
10482     if (tf)
10483         cond = TCG_COND_EQ;
10484     else
10485         cond = TCG_COND_NE;
10486
10487     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10488     tcg_gen_brcondi_i32(cond, t0, 0, l1);
10489     gen_load_fpr32(ctx, t0, fs);
10490     gen_store_fpr32(ctx, t0, fd);
10491     gen_set_label(l1);
10492     tcg_temp_free_i32(t0);
10493 }
10494
10495 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
10496 {
10497     int cond;
10498     TCGv_i32 t0 = tcg_temp_new_i32();
10499     TCGv_i64 fp0;
10500     TCGLabel *l1 = gen_new_label();
10501
10502     if (tf)
10503         cond = TCG_COND_EQ;
10504     else
10505         cond = TCG_COND_NE;
10506
10507     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10508     tcg_gen_brcondi_i32(cond, t0, 0, l1);
10509     tcg_temp_free_i32(t0);
10510     fp0 = tcg_temp_new_i64();
10511     gen_load_fpr64(ctx, fp0, fs);
10512     gen_store_fpr64(ctx, fp0, fd);
10513     tcg_temp_free_i64(fp0);
10514     gen_set_label(l1);
10515 }
10516
10517 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
10518                                 int cc, int tf)
10519 {
10520     int cond;
10521     TCGv_i32 t0 = tcg_temp_new_i32();
10522     TCGLabel *l1 = gen_new_label();
10523     TCGLabel *l2 = gen_new_label();
10524
10525     if (tf)
10526         cond = TCG_COND_EQ;
10527     else
10528         cond = TCG_COND_NE;
10529
10530     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10531     tcg_gen_brcondi_i32(cond, t0, 0, l1);
10532     gen_load_fpr32(ctx, t0, fs);
10533     gen_store_fpr32(ctx, t0, fd);
10534     gen_set_label(l1);
10535
10536     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
10537     tcg_gen_brcondi_i32(cond, t0, 0, l2);
10538     gen_load_fpr32h(ctx, t0, fs);
10539     gen_store_fpr32h(ctx, t0, fd);
10540     tcg_temp_free_i32(t0);
10541     gen_set_label(l2);
10542 }
10543
10544 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10545                       int fs)
10546 {
10547     TCGv_i32 t1 = tcg_const_i32(0);
10548     TCGv_i32 fp0 = tcg_temp_new_i32();
10549     TCGv_i32 fp1 = tcg_temp_new_i32();
10550     TCGv_i32 fp2 = tcg_temp_new_i32();
10551     gen_load_fpr32(ctx, fp0, fd);
10552     gen_load_fpr32(ctx, fp1, ft);
10553     gen_load_fpr32(ctx, fp2, fs);
10554
10555     switch (op1) {
10556     case OPC_SEL_S:
10557         tcg_gen_andi_i32(fp0, fp0, 1);
10558         tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10559         break;
10560     case OPC_SELEQZ_S:
10561         tcg_gen_andi_i32(fp1, fp1, 1);
10562         tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10563         break;
10564     case OPC_SELNEZ_S:
10565         tcg_gen_andi_i32(fp1, fp1, 1);
10566         tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10567         break;
10568     default:
10569         MIPS_INVAL("gen_sel_s");
10570         generate_exception_end(ctx, EXCP_RI);
10571         break;
10572     }
10573
10574     gen_store_fpr32(ctx, fp0, fd);
10575     tcg_temp_free_i32(fp2);
10576     tcg_temp_free_i32(fp1);
10577     tcg_temp_free_i32(fp0);
10578     tcg_temp_free_i32(t1);
10579 }
10580
10581 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10582                       int fs)
10583 {
10584     TCGv_i64 t1 = tcg_const_i64(0);
10585     TCGv_i64 fp0 = tcg_temp_new_i64();
10586     TCGv_i64 fp1 = tcg_temp_new_i64();
10587     TCGv_i64 fp2 = tcg_temp_new_i64();
10588     gen_load_fpr64(ctx, fp0, fd);
10589     gen_load_fpr64(ctx, fp1, ft);
10590     gen_load_fpr64(ctx, fp2, fs);
10591
10592     switch (op1) {
10593     case OPC_SEL_D:
10594         tcg_gen_andi_i64(fp0, fp0, 1);
10595         tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10596         break;
10597     case OPC_SELEQZ_D:
10598         tcg_gen_andi_i64(fp1, fp1, 1);
10599         tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10600         break;
10601     case OPC_SELNEZ_D:
10602         tcg_gen_andi_i64(fp1, fp1, 1);
10603         tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10604         break;
10605     default:
10606         MIPS_INVAL("gen_sel_d");
10607         generate_exception_end(ctx, EXCP_RI);
10608         break;
10609     }
10610
10611     gen_store_fpr64(ctx, fp0, fd);
10612     tcg_temp_free_i64(fp2);
10613     tcg_temp_free_i64(fp1);
10614     tcg_temp_free_i64(fp0);
10615     tcg_temp_free_i64(t1);
10616 }
10617
10618 static void gen_farith (DisasContext *ctx, enum fopcode op1,
10619                         int ft, int fs, int fd, int cc)
10620 {
10621     uint32_t func = ctx->opcode & 0x3f;
10622     switch (op1) {
10623     case OPC_ADD_S:
10624         {
10625             TCGv_i32 fp0 = tcg_temp_new_i32();
10626             TCGv_i32 fp1 = tcg_temp_new_i32();
10627
10628             gen_load_fpr32(ctx, fp0, fs);
10629             gen_load_fpr32(ctx, fp1, ft);
10630             gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
10631             tcg_temp_free_i32(fp1);
10632             gen_store_fpr32(ctx, fp0, fd);
10633             tcg_temp_free_i32(fp0);
10634         }
10635         break;
10636     case OPC_SUB_S:
10637         {
10638             TCGv_i32 fp0 = tcg_temp_new_i32();
10639             TCGv_i32 fp1 = tcg_temp_new_i32();
10640
10641             gen_load_fpr32(ctx, fp0, fs);
10642             gen_load_fpr32(ctx, fp1, ft);
10643             gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
10644             tcg_temp_free_i32(fp1);
10645             gen_store_fpr32(ctx, fp0, fd);
10646             tcg_temp_free_i32(fp0);
10647         }
10648         break;
10649     case OPC_MUL_S:
10650         {
10651             TCGv_i32 fp0 = tcg_temp_new_i32();
10652             TCGv_i32 fp1 = tcg_temp_new_i32();
10653
10654             gen_load_fpr32(ctx, fp0, fs);
10655             gen_load_fpr32(ctx, fp1, ft);
10656             gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
10657             tcg_temp_free_i32(fp1);
10658             gen_store_fpr32(ctx, fp0, fd);
10659             tcg_temp_free_i32(fp0);
10660         }
10661         break;
10662     case OPC_DIV_S:
10663         {
10664             TCGv_i32 fp0 = tcg_temp_new_i32();
10665             TCGv_i32 fp1 = tcg_temp_new_i32();
10666
10667             gen_load_fpr32(ctx, fp0, fs);
10668             gen_load_fpr32(ctx, fp1, ft);
10669             gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
10670             tcg_temp_free_i32(fp1);
10671             gen_store_fpr32(ctx, fp0, fd);
10672             tcg_temp_free_i32(fp0);
10673         }
10674         break;
10675     case OPC_SQRT_S:
10676         {
10677             TCGv_i32 fp0 = tcg_temp_new_i32();
10678
10679             gen_load_fpr32(ctx, fp0, fs);
10680             gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
10681             gen_store_fpr32(ctx, fp0, fd);
10682             tcg_temp_free_i32(fp0);
10683         }
10684         break;
10685     case OPC_ABS_S:
10686         {
10687             TCGv_i32 fp0 = tcg_temp_new_i32();
10688
10689             gen_load_fpr32(ctx, fp0, fs);
10690             if (ctx->abs2008) {
10691                 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
10692             } else {
10693                 gen_helper_float_abs_s(fp0, fp0);
10694             }
10695             gen_store_fpr32(ctx, fp0, fd);
10696             tcg_temp_free_i32(fp0);
10697         }
10698         break;
10699     case OPC_MOV_S:
10700         {
10701             TCGv_i32 fp0 = tcg_temp_new_i32();
10702
10703             gen_load_fpr32(ctx, fp0, fs);
10704             gen_store_fpr32(ctx, fp0, fd);
10705             tcg_temp_free_i32(fp0);
10706         }
10707         break;
10708     case OPC_NEG_S:
10709         {
10710             TCGv_i32 fp0 = tcg_temp_new_i32();
10711
10712             gen_load_fpr32(ctx, fp0, fs);
10713             if (ctx->abs2008) {
10714                 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
10715             } else {
10716                 gen_helper_float_chs_s(fp0, fp0);
10717             }
10718             gen_store_fpr32(ctx, fp0, fd);
10719             tcg_temp_free_i32(fp0);
10720         }
10721         break;
10722     case OPC_ROUND_L_S:
10723         check_cp1_64bitmode(ctx);
10724         {
10725             TCGv_i32 fp32 = tcg_temp_new_i32();
10726             TCGv_i64 fp64 = tcg_temp_new_i64();
10727
10728             gen_load_fpr32(ctx, fp32, fs);
10729             if (ctx->nan2008) {
10730                 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
10731             } else {
10732                 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
10733             }
10734             tcg_temp_free_i32(fp32);
10735             gen_store_fpr64(ctx, fp64, fd);
10736             tcg_temp_free_i64(fp64);
10737         }
10738         break;
10739     case OPC_TRUNC_L_S:
10740         check_cp1_64bitmode(ctx);
10741         {
10742             TCGv_i32 fp32 = tcg_temp_new_i32();
10743             TCGv_i64 fp64 = tcg_temp_new_i64();
10744
10745             gen_load_fpr32(ctx, fp32, fs);
10746             if (ctx->nan2008) {
10747                 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
10748             } else {
10749                 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
10750             }
10751             tcg_temp_free_i32(fp32);
10752             gen_store_fpr64(ctx, fp64, fd);
10753             tcg_temp_free_i64(fp64);
10754         }
10755         break;
10756     case OPC_CEIL_L_S:
10757         check_cp1_64bitmode(ctx);
10758         {
10759             TCGv_i32 fp32 = tcg_temp_new_i32();
10760             TCGv_i64 fp64 = tcg_temp_new_i64();
10761
10762             gen_load_fpr32(ctx, fp32, fs);
10763             if (ctx->nan2008) {
10764                 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
10765             } else {
10766                 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
10767             }
10768             tcg_temp_free_i32(fp32);
10769             gen_store_fpr64(ctx, fp64, fd);
10770             tcg_temp_free_i64(fp64);
10771         }
10772         break;
10773     case OPC_FLOOR_L_S:
10774         check_cp1_64bitmode(ctx);
10775         {
10776             TCGv_i32 fp32 = tcg_temp_new_i32();
10777             TCGv_i64 fp64 = tcg_temp_new_i64();
10778
10779             gen_load_fpr32(ctx, fp32, fs);
10780             if (ctx->nan2008) {
10781                 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
10782             } else {
10783                 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
10784             }
10785             tcg_temp_free_i32(fp32);
10786             gen_store_fpr64(ctx, fp64, fd);
10787             tcg_temp_free_i64(fp64);
10788         }
10789         break;
10790     case OPC_ROUND_W_S:
10791         {
10792             TCGv_i32 fp0 = tcg_temp_new_i32();
10793
10794             gen_load_fpr32(ctx, fp0, fs);
10795             if (ctx->nan2008) {
10796                 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
10797             } else {
10798                 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
10799             }
10800             gen_store_fpr32(ctx, fp0, fd);
10801             tcg_temp_free_i32(fp0);
10802         }
10803         break;
10804     case OPC_TRUNC_W_S:
10805         {
10806             TCGv_i32 fp0 = tcg_temp_new_i32();
10807
10808             gen_load_fpr32(ctx, fp0, fs);
10809             if (ctx->nan2008) {
10810                 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
10811             } else {
10812                 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
10813             }
10814             gen_store_fpr32(ctx, fp0, fd);
10815             tcg_temp_free_i32(fp0);
10816         }
10817         break;
10818     case OPC_CEIL_W_S:
10819         {
10820             TCGv_i32 fp0 = tcg_temp_new_i32();
10821
10822             gen_load_fpr32(ctx, fp0, fs);
10823             if (ctx->nan2008) {
10824                 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
10825             } else {
10826                 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
10827             }
10828             gen_store_fpr32(ctx, fp0, fd);
10829             tcg_temp_free_i32(fp0);
10830         }
10831         break;
10832     case OPC_FLOOR_W_S:
10833         {
10834             TCGv_i32 fp0 = tcg_temp_new_i32();
10835
10836             gen_load_fpr32(ctx, fp0, fs);
10837             if (ctx->nan2008) {
10838                 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
10839             } else {
10840                 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
10841             }
10842             gen_store_fpr32(ctx, fp0, fd);
10843             tcg_temp_free_i32(fp0);
10844         }
10845         break;
10846     case OPC_SEL_S:
10847         check_insn(ctx, ISA_MIPS32R6);
10848         gen_sel_s(ctx, op1, fd, ft, fs);
10849         break;
10850     case OPC_SELEQZ_S:
10851         check_insn(ctx, ISA_MIPS32R6);
10852         gen_sel_s(ctx, op1, fd, ft, fs);
10853         break;
10854     case OPC_SELNEZ_S:
10855         check_insn(ctx, ISA_MIPS32R6);
10856         gen_sel_s(ctx, op1, fd, ft, fs);
10857         break;
10858     case OPC_MOVCF_S:
10859         check_insn_opc_removed(ctx, ISA_MIPS32R6);
10860         gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10861         break;
10862     case OPC_MOVZ_S:
10863         check_insn_opc_removed(ctx, ISA_MIPS32R6);
10864         {
10865             TCGLabel *l1 = gen_new_label();
10866             TCGv_i32 fp0;
10867
10868             if (ft != 0) {
10869                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10870             }
10871             fp0 = tcg_temp_new_i32();
10872             gen_load_fpr32(ctx, fp0, fs);
10873             gen_store_fpr32(ctx, fp0, fd);
10874             tcg_temp_free_i32(fp0);
10875             gen_set_label(l1);
10876         }
10877         break;
10878     case OPC_MOVN_S:
10879         check_insn_opc_removed(ctx, ISA_MIPS32R6);
10880         {
10881             TCGLabel *l1 = gen_new_label();
10882             TCGv_i32 fp0;
10883
10884             if (ft != 0) {
10885                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10886                 fp0 = tcg_temp_new_i32();
10887                 gen_load_fpr32(ctx, fp0, fs);
10888                 gen_store_fpr32(ctx, fp0, fd);
10889                 tcg_temp_free_i32(fp0);
10890                 gen_set_label(l1);
10891             }
10892         }
10893         break;
10894     case OPC_RECIP_S:
10895         {
10896             TCGv_i32 fp0 = tcg_temp_new_i32();
10897
10898             gen_load_fpr32(ctx, fp0, fs);
10899             gen_helper_float_recip_s(fp0, cpu_env, fp0);
10900             gen_store_fpr32(ctx, fp0, fd);
10901             tcg_temp_free_i32(fp0);
10902         }
10903         break;
10904     case OPC_RSQRT_S:
10905         {
10906             TCGv_i32 fp0 = tcg_temp_new_i32();
10907
10908             gen_load_fpr32(ctx, fp0, fs);
10909             gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
10910             gen_store_fpr32(ctx, fp0, fd);
10911             tcg_temp_free_i32(fp0);
10912         }
10913         break;
10914     case OPC_MADDF_S:
10915         check_insn(ctx, ISA_MIPS32R6);
10916         {
10917             TCGv_i32 fp0 = tcg_temp_new_i32();
10918             TCGv_i32 fp1 = tcg_temp_new_i32();
10919             TCGv_i32 fp2 = tcg_temp_new_i32();
10920             gen_load_fpr32(ctx, fp0, fs);
10921             gen_load_fpr32(ctx, fp1, ft);
10922             gen_load_fpr32(ctx, fp2, fd);
10923             gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
10924             gen_store_fpr32(ctx, fp2, fd);
10925             tcg_temp_free_i32(fp2);
10926             tcg_temp_free_i32(fp1);
10927             tcg_temp_free_i32(fp0);
10928         }
10929         break;
10930     case OPC_MSUBF_S:
10931         check_insn(ctx, ISA_MIPS32R6);
10932         {
10933             TCGv_i32 fp0 = tcg_temp_new_i32();
10934             TCGv_i32 fp1 = tcg_temp_new_i32();
10935             TCGv_i32 fp2 = tcg_temp_new_i32();
10936             gen_load_fpr32(ctx, fp0, fs);
10937             gen_load_fpr32(ctx, fp1, ft);
10938             gen_load_fpr32(ctx, fp2, fd);
10939             gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
10940             gen_store_fpr32(ctx, fp2, fd);
10941             tcg_temp_free_i32(fp2);
10942             tcg_temp_free_i32(fp1);
10943             tcg_temp_free_i32(fp0);
10944         }
10945         break;
10946     case OPC_RINT_S:
10947         check_insn(ctx, ISA_MIPS32R6);
10948         {
10949             TCGv_i32 fp0 = tcg_temp_new_i32();
10950             gen_load_fpr32(ctx, fp0, fs);
10951             gen_helper_float_rint_s(fp0, cpu_env, fp0);
10952             gen_store_fpr32(ctx, fp0, fd);
10953             tcg_temp_free_i32(fp0);
10954         }
10955         break;
10956     case OPC_CLASS_S:
10957         check_insn(ctx, ISA_MIPS32R6);
10958         {
10959             TCGv_i32 fp0 = tcg_temp_new_i32();
10960             gen_load_fpr32(ctx, fp0, fs);
10961             gen_helper_float_class_s(fp0, cpu_env, fp0);
10962             gen_store_fpr32(ctx, fp0, fd);
10963             tcg_temp_free_i32(fp0);
10964         }
10965         break;
10966     case OPC_MIN_S: /* OPC_RECIP2_S */
10967         if (ctx->insn_flags & ISA_MIPS32R6) {
10968             /* OPC_MIN_S */
10969             TCGv_i32 fp0 = tcg_temp_new_i32();
10970             TCGv_i32 fp1 = tcg_temp_new_i32();
10971             TCGv_i32 fp2 = tcg_temp_new_i32();
10972             gen_load_fpr32(ctx, fp0, fs);
10973             gen_load_fpr32(ctx, fp1, ft);
10974             gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
10975             gen_store_fpr32(ctx, fp2, fd);
10976             tcg_temp_free_i32(fp2);
10977             tcg_temp_free_i32(fp1);
10978             tcg_temp_free_i32(fp0);
10979         } else {
10980             /* OPC_RECIP2_S */
10981             check_cp1_64bitmode(ctx);
10982             {
10983                 TCGv_i32 fp0 = tcg_temp_new_i32();
10984                 TCGv_i32 fp1 = tcg_temp_new_i32();
10985
10986                 gen_load_fpr32(ctx, fp0, fs);
10987                 gen_load_fpr32(ctx, fp1, ft);
10988                 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
10989                 tcg_temp_free_i32(fp1);
10990                 gen_store_fpr32(ctx, fp0, fd);
10991                 tcg_temp_free_i32(fp0);
10992             }
10993         }
10994         break;
10995     case OPC_MINA_S: /* OPC_RECIP1_S */
10996         if (ctx->insn_flags & ISA_MIPS32R6) {
10997             /* OPC_MINA_S */
10998             TCGv_i32 fp0 = tcg_temp_new_i32();
10999             TCGv_i32 fp1 = tcg_temp_new_i32();
11000             TCGv_i32 fp2 = tcg_temp_new_i32();
11001             gen_load_fpr32(ctx, fp0, fs);
11002             gen_load_fpr32(ctx, fp1, ft);
11003             gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
11004             gen_store_fpr32(ctx, fp2, fd);
11005             tcg_temp_free_i32(fp2);
11006             tcg_temp_free_i32(fp1);
11007             tcg_temp_free_i32(fp0);
11008         } else {
11009             /* OPC_RECIP1_S */
11010             check_cp1_64bitmode(ctx);
11011             {
11012                 TCGv_i32 fp0 = tcg_temp_new_i32();
11013
11014                 gen_load_fpr32(ctx, fp0, fs);
11015                 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
11016                 gen_store_fpr32(ctx, fp0, fd);
11017                 tcg_temp_free_i32(fp0);
11018             }
11019         }
11020         break;
11021     case OPC_MAX_S: /* OPC_RSQRT1_S */
11022         if (ctx->insn_flags & ISA_MIPS32R6) {
11023             /* OPC_MAX_S */
11024             TCGv_i32 fp0 = tcg_temp_new_i32();
11025             TCGv_i32 fp1 = tcg_temp_new_i32();
11026             gen_load_fpr32(ctx, fp0, fs);
11027             gen_load_fpr32(ctx, fp1, ft);
11028             gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
11029             gen_store_fpr32(ctx, fp1, fd);
11030             tcg_temp_free_i32(fp1);
11031             tcg_temp_free_i32(fp0);
11032         } else {
11033             /* OPC_RSQRT1_S */
11034             check_cp1_64bitmode(ctx);
11035             {
11036                 TCGv_i32 fp0 = tcg_temp_new_i32();
11037
11038                 gen_load_fpr32(ctx, fp0, fs);
11039                 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
11040                 gen_store_fpr32(ctx, fp0, fd);
11041                 tcg_temp_free_i32(fp0);
11042             }
11043         }
11044         break;
11045     case OPC_MAXA_S: /* OPC_RSQRT2_S */
11046         if (ctx->insn_flags & ISA_MIPS32R6) {
11047             /* OPC_MAXA_S */
11048             TCGv_i32 fp0 = tcg_temp_new_i32();
11049             TCGv_i32 fp1 = tcg_temp_new_i32();
11050             gen_load_fpr32(ctx, fp0, fs);
11051             gen_load_fpr32(ctx, fp1, ft);
11052             gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
11053             gen_store_fpr32(ctx, fp1, fd);
11054             tcg_temp_free_i32(fp1);
11055             tcg_temp_free_i32(fp0);
11056         } else {
11057             /* OPC_RSQRT2_S */
11058             check_cp1_64bitmode(ctx);
11059             {
11060                 TCGv_i32 fp0 = tcg_temp_new_i32();
11061                 TCGv_i32 fp1 = tcg_temp_new_i32();
11062
11063                 gen_load_fpr32(ctx, fp0, fs);
11064                 gen_load_fpr32(ctx, fp1, ft);
11065                 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
11066                 tcg_temp_free_i32(fp1);
11067                 gen_store_fpr32(ctx, fp0, fd);
11068                 tcg_temp_free_i32(fp0);
11069             }
11070         }
11071         break;
11072     case OPC_CVT_D_S:
11073         check_cp1_registers(ctx, fd);
11074         {
11075             TCGv_i32 fp32 = tcg_temp_new_i32();
11076             TCGv_i64 fp64 = tcg_temp_new_i64();
11077
11078             gen_load_fpr32(ctx, fp32, fs);
11079             gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
11080             tcg_temp_free_i32(fp32);
11081             gen_store_fpr64(ctx, fp64, fd);
11082             tcg_temp_free_i64(fp64);
11083         }
11084         break;
11085     case OPC_CVT_W_S:
11086         {
11087             TCGv_i32 fp0 = tcg_temp_new_i32();
11088
11089             gen_load_fpr32(ctx, fp0, fs);
11090             if (ctx->nan2008) {
11091                 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
11092             } else {
11093                 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
11094             }
11095             gen_store_fpr32(ctx, fp0, fd);
11096             tcg_temp_free_i32(fp0);
11097         }
11098         break;
11099     case OPC_CVT_L_S:
11100         check_cp1_64bitmode(ctx);
11101         {
11102             TCGv_i32 fp32 = tcg_temp_new_i32();
11103             TCGv_i64 fp64 = tcg_temp_new_i64();
11104
11105             gen_load_fpr32(ctx, fp32, fs);
11106             if (ctx->nan2008) {
11107                 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
11108             } else {
11109                 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
11110             }
11111             tcg_temp_free_i32(fp32);
11112             gen_store_fpr64(ctx, fp64, fd);
11113             tcg_temp_free_i64(fp64);
11114         }
11115         break;
11116     case OPC_CVT_PS_S:
11117         check_ps(ctx);
11118         {
11119             TCGv_i64 fp64 = tcg_temp_new_i64();
11120             TCGv_i32 fp32_0 = tcg_temp_new_i32();
11121             TCGv_i32 fp32_1 = tcg_temp_new_i32();
11122
11123             gen_load_fpr32(ctx, fp32_0, fs);
11124             gen_load_fpr32(ctx, fp32_1, ft);
11125             tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
11126             tcg_temp_free_i32(fp32_1);
11127             tcg_temp_free_i32(fp32_0);
11128             gen_store_fpr64(ctx, fp64, fd);
11129             tcg_temp_free_i64(fp64);
11130         }
11131         break;
11132     case OPC_CMP_F_S:
11133     case OPC_CMP_UN_S:
11134     case OPC_CMP_EQ_S:
11135     case OPC_CMP_UEQ_S:
11136     case OPC_CMP_OLT_S:
11137     case OPC_CMP_ULT_S:
11138     case OPC_CMP_OLE_S:
11139     case OPC_CMP_ULE_S:
11140     case OPC_CMP_SF_S:
11141     case OPC_CMP_NGLE_S:
11142     case OPC_CMP_SEQ_S:
11143     case OPC_CMP_NGL_S:
11144     case OPC_CMP_LT_S:
11145     case OPC_CMP_NGE_S:
11146     case OPC_CMP_LE_S:
11147     case OPC_CMP_NGT_S:
11148         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11149         if (ctx->opcode & (1 << 6)) {
11150             gen_cmpabs_s(ctx, func-48, ft, fs, cc);
11151         } else {
11152             gen_cmp_s(ctx, func-48, ft, fs, cc);
11153         }
11154         break;
11155     case OPC_ADD_D:
11156         check_cp1_registers(ctx, fs | ft | fd);
11157         {
11158             TCGv_i64 fp0 = tcg_temp_new_i64();
11159             TCGv_i64 fp1 = tcg_temp_new_i64();
11160
11161             gen_load_fpr64(ctx, fp0, fs);
11162             gen_load_fpr64(ctx, fp1, ft);
11163             gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
11164             tcg_temp_free_i64(fp1);
11165             gen_store_fpr64(ctx, fp0, fd);
11166             tcg_temp_free_i64(fp0);
11167         }
11168         break;
11169     case OPC_SUB_D:
11170         check_cp1_registers(ctx, fs | ft | fd);
11171         {
11172             TCGv_i64 fp0 = tcg_temp_new_i64();
11173             TCGv_i64 fp1 = tcg_temp_new_i64();
11174
11175             gen_load_fpr64(ctx, fp0, fs);
11176             gen_load_fpr64(ctx, fp1, ft);
11177             gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
11178             tcg_temp_free_i64(fp1);
11179             gen_store_fpr64(ctx, fp0, fd);
11180             tcg_temp_free_i64(fp0);
11181         }
11182         break;
11183     case OPC_MUL_D:
11184         check_cp1_registers(ctx, fs | ft | fd);
11185         {
11186             TCGv_i64 fp0 = tcg_temp_new_i64();
11187             TCGv_i64 fp1 = tcg_temp_new_i64();
11188
11189             gen_load_fpr64(ctx, fp0, fs);
11190             gen_load_fpr64(ctx, fp1, ft);
11191             gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
11192             tcg_temp_free_i64(fp1);
11193             gen_store_fpr64(ctx, fp0, fd);
11194             tcg_temp_free_i64(fp0);
11195         }
11196         break;
11197     case OPC_DIV_D:
11198         check_cp1_registers(ctx, fs | ft | fd);
11199         {
11200             TCGv_i64 fp0 = tcg_temp_new_i64();
11201             TCGv_i64 fp1 = tcg_temp_new_i64();
11202
11203             gen_load_fpr64(ctx, fp0, fs);
11204             gen_load_fpr64(ctx, fp1, ft);
11205             gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
11206             tcg_temp_free_i64(fp1);
11207             gen_store_fpr64(ctx, fp0, fd);
11208             tcg_temp_free_i64(fp0);
11209         }
11210         break;
11211     case OPC_SQRT_D:
11212         check_cp1_registers(ctx, fs | fd);
11213         {
11214             TCGv_i64 fp0 = tcg_temp_new_i64();
11215
11216             gen_load_fpr64(ctx, fp0, fs);
11217             gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
11218             gen_store_fpr64(ctx, fp0, fd);
11219             tcg_temp_free_i64(fp0);
11220         }
11221         break;
11222     case OPC_ABS_D:
11223         check_cp1_registers(ctx, fs | fd);
11224         {
11225             TCGv_i64 fp0 = tcg_temp_new_i64();
11226
11227             gen_load_fpr64(ctx, fp0, fs);
11228             if (ctx->abs2008) {
11229                 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
11230             } else {
11231                 gen_helper_float_abs_d(fp0, fp0);
11232             }
11233             gen_store_fpr64(ctx, fp0, fd);
11234             tcg_temp_free_i64(fp0);
11235         }
11236         break;
11237     case OPC_MOV_D:
11238         check_cp1_registers(ctx, fs | fd);
11239         {
11240             TCGv_i64 fp0 = tcg_temp_new_i64();
11241
11242             gen_load_fpr64(ctx, fp0, fs);
11243             gen_store_fpr64(ctx, fp0, fd);
11244             tcg_temp_free_i64(fp0);
11245         }
11246         break;
11247     case OPC_NEG_D:
11248         check_cp1_registers(ctx, fs | fd);
11249         {
11250             TCGv_i64 fp0 = tcg_temp_new_i64();
11251
11252             gen_load_fpr64(ctx, fp0, fs);
11253             if (ctx->abs2008) {
11254                 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
11255             } else {
11256                 gen_helper_float_chs_d(fp0, fp0);
11257             }
11258             gen_store_fpr64(ctx, fp0, fd);
11259             tcg_temp_free_i64(fp0);
11260         }
11261         break;
11262     case OPC_ROUND_L_D:
11263         check_cp1_64bitmode(ctx);
11264         {
11265             TCGv_i64 fp0 = tcg_temp_new_i64();
11266
11267             gen_load_fpr64(ctx, fp0, fs);
11268             if (ctx->nan2008) {
11269                 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
11270             } else {
11271                 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
11272             }
11273             gen_store_fpr64(ctx, fp0, fd);
11274             tcg_temp_free_i64(fp0);
11275         }
11276         break;
11277     case OPC_TRUNC_L_D:
11278         check_cp1_64bitmode(ctx);
11279         {
11280             TCGv_i64 fp0 = tcg_temp_new_i64();
11281
11282             gen_load_fpr64(ctx, fp0, fs);
11283             if (ctx->nan2008) {
11284                 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
11285             } else {
11286                 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
11287             }
11288             gen_store_fpr64(ctx, fp0, fd);
11289             tcg_temp_free_i64(fp0);
11290         }
11291         break;
11292     case OPC_CEIL_L_D:
11293         check_cp1_64bitmode(ctx);
11294         {
11295             TCGv_i64 fp0 = tcg_temp_new_i64();
11296
11297             gen_load_fpr64(ctx, fp0, fs);
11298             if (ctx->nan2008) {
11299                 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
11300             } else {
11301                 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
11302             }
11303             gen_store_fpr64(ctx, fp0, fd);
11304             tcg_temp_free_i64(fp0);
11305         }
11306         break;
11307     case OPC_FLOOR_L_D:
11308         check_cp1_64bitmode(ctx);
11309         {
11310             TCGv_i64 fp0 = tcg_temp_new_i64();
11311
11312             gen_load_fpr64(ctx, fp0, fs);
11313             if (ctx->nan2008) {
11314                 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
11315             } else {
11316                 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
11317             }
11318             gen_store_fpr64(ctx, fp0, fd);
11319             tcg_temp_free_i64(fp0);
11320         }
11321         break;
11322     case OPC_ROUND_W_D:
11323         check_cp1_registers(ctx, fs);
11324         {
11325             TCGv_i32 fp32 = tcg_temp_new_i32();
11326             TCGv_i64 fp64 = tcg_temp_new_i64();
11327
11328             gen_load_fpr64(ctx, fp64, fs);
11329             if (ctx->nan2008) {
11330                 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
11331             } else {
11332                 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
11333             }
11334             tcg_temp_free_i64(fp64);
11335             gen_store_fpr32(ctx, fp32, fd);
11336             tcg_temp_free_i32(fp32);
11337         }
11338         break;
11339     case OPC_TRUNC_W_D:
11340         check_cp1_registers(ctx, fs);
11341         {
11342             TCGv_i32 fp32 = tcg_temp_new_i32();
11343             TCGv_i64 fp64 = tcg_temp_new_i64();
11344
11345             gen_load_fpr64(ctx, fp64, fs);
11346             if (ctx->nan2008) {
11347                 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
11348             } else {
11349                 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
11350             }
11351             tcg_temp_free_i64(fp64);
11352             gen_store_fpr32(ctx, fp32, fd);
11353             tcg_temp_free_i32(fp32);
11354         }
11355         break;
11356     case OPC_CEIL_W_D:
11357         check_cp1_registers(ctx, fs);
11358         {
11359             TCGv_i32 fp32 = tcg_temp_new_i32();
11360             TCGv_i64 fp64 = tcg_temp_new_i64();
11361
11362             gen_load_fpr64(ctx, fp64, fs);
11363             if (ctx->nan2008) {
11364                 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
11365             } else {
11366                 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
11367             }
11368             tcg_temp_free_i64(fp64);
11369             gen_store_fpr32(ctx, fp32, fd);
11370             tcg_temp_free_i32(fp32);
11371         }
11372         break;
11373     case OPC_FLOOR_W_D:
11374         check_cp1_registers(ctx, fs);
11375         {
11376             TCGv_i32 fp32 = tcg_temp_new_i32();
11377             TCGv_i64 fp64 = tcg_temp_new_i64();
11378
11379             gen_load_fpr64(ctx, fp64, fs);
11380             if (ctx->nan2008) {
11381                 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
11382             } else {
11383                 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
11384             }
11385             tcg_temp_free_i64(fp64);
11386             gen_store_fpr32(ctx, fp32, fd);
11387             tcg_temp_free_i32(fp32);
11388         }
11389         break;
11390     case OPC_SEL_D:
11391         check_insn(ctx, ISA_MIPS32R6);
11392         gen_sel_d(ctx, op1, fd, ft, fs);
11393         break;
11394     case OPC_SELEQZ_D:
11395         check_insn(ctx, ISA_MIPS32R6);
11396         gen_sel_d(ctx, op1, fd, ft, fs);
11397         break;
11398     case OPC_SELNEZ_D:
11399         check_insn(ctx, ISA_MIPS32R6);
11400         gen_sel_d(ctx, op1, fd, ft, fs);
11401         break;
11402     case OPC_MOVCF_D:
11403         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11404         gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11405         break;
11406     case OPC_MOVZ_D:
11407         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11408         {
11409             TCGLabel *l1 = gen_new_label();
11410             TCGv_i64 fp0;
11411
11412             if (ft != 0) {
11413                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11414             }
11415             fp0 = tcg_temp_new_i64();
11416             gen_load_fpr64(ctx, fp0, fs);
11417             gen_store_fpr64(ctx, fp0, fd);
11418             tcg_temp_free_i64(fp0);
11419             gen_set_label(l1);
11420         }
11421         break;
11422     case OPC_MOVN_D:
11423         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11424         {
11425             TCGLabel *l1 = gen_new_label();
11426             TCGv_i64 fp0;
11427
11428             if (ft != 0) {
11429                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11430                 fp0 = tcg_temp_new_i64();
11431                 gen_load_fpr64(ctx, fp0, fs);
11432                 gen_store_fpr64(ctx, fp0, fd);
11433                 tcg_temp_free_i64(fp0);
11434                 gen_set_label(l1);
11435             }
11436         }
11437         break;
11438     case OPC_RECIP_D:
11439         check_cp1_registers(ctx, fs | fd);
11440         {
11441             TCGv_i64 fp0 = tcg_temp_new_i64();
11442
11443             gen_load_fpr64(ctx, fp0, fs);
11444             gen_helper_float_recip_d(fp0, cpu_env, fp0);
11445             gen_store_fpr64(ctx, fp0, fd);
11446             tcg_temp_free_i64(fp0);
11447         }
11448         break;
11449     case OPC_RSQRT_D:
11450         check_cp1_registers(ctx, fs | fd);
11451         {
11452             TCGv_i64 fp0 = tcg_temp_new_i64();
11453
11454             gen_load_fpr64(ctx, fp0, fs);
11455             gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
11456             gen_store_fpr64(ctx, fp0, fd);
11457             tcg_temp_free_i64(fp0);
11458         }
11459         break;
11460     case OPC_MADDF_D:
11461         check_insn(ctx, ISA_MIPS32R6);
11462         {
11463             TCGv_i64 fp0 = tcg_temp_new_i64();
11464             TCGv_i64 fp1 = tcg_temp_new_i64();
11465             TCGv_i64 fp2 = tcg_temp_new_i64();
11466             gen_load_fpr64(ctx, fp0, fs);
11467             gen_load_fpr64(ctx, fp1, ft);
11468             gen_load_fpr64(ctx, fp2, fd);
11469             gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
11470             gen_store_fpr64(ctx, fp2, fd);
11471             tcg_temp_free_i64(fp2);
11472             tcg_temp_free_i64(fp1);
11473             tcg_temp_free_i64(fp0);
11474         }
11475         break;
11476     case OPC_MSUBF_D:
11477         check_insn(ctx, ISA_MIPS32R6);
11478         {
11479             TCGv_i64 fp0 = tcg_temp_new_i64();
11480             TCGv_i64 fp1 = tcg_temp_new_i64();
11481             TCGv_i64 fp2 = tcg_temp_new_i64();
11482             gen_load_fpr64(ctx, fp0, fs);
11483             gen_load_fpr64(ctx, fp1, ft);
11484             gen_load_fpr64(ctx, fp2, fd);
11485             gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
11486             gen_store_fpr64(ctx, fp2, fd);
11487             tcg_temp_free_i64(fp2);
11488             tcg_temp_free_i64(fp1);
11489             tcg_temp_free_i64(fp0);
11490         }
11491         break;
11492     case OPC_RINT_D:
11493         check_insn(ctx, ISA_MIPS32R6);
11494         {
11495             TCGv_i64 fp0 = tcg_temp_new_i64();
11496             gen_load_fpr64(ctx, fp0, fs);
11497             gen_helper_float_rint_d(fp0, cpu_env, fp0);
11498             gen_store_fpr64(ctx, fp0, fd);
11499             tcg_temp_free_i64(fp0);
11500         }
11501         break;
11502     case OPC_CLASS_D:
11503         check_insn(ctx, ISA_MIPS32R6);
11504         {
11505             TCGv_i64 fp0 = tcg_temp_new_i64();
11506             gen_load_fpr64(ctx, fp0, fs);
11507             gen_helper_float_class_d(fp0, cpu_env, fp0);
11508             gen_store_fpr64(ctx, fp0, fd);
11509             tcg_temp_free_i64(fp0);
11510         }
11511         break;
11512     case OPC_MIN_D: /* OPC_RECIP2_D */
11513         if (ctx->insn_flags & ISA_MIPS32R6) {
11514             /* OPC_MIN_D */
11515             TCGv_i64 fp0 = tcg_temp_new_i64();
11516             TCGv_i64 fp1 = tcg_temp_new_i64();
11517             gen_load_fpr64(ctx, fp0, fs);
11518             gen_load_fpr64(ctx, fp1, ft);
11519             gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
11520             gen_store_fpr64(ctx, fp1, fd);
11521             tcg_temp_free_i64(fp1);
11522             tcg_temp_free_i64(fp0);
11523         } else {
11524             /* OPC_RECIP2_D */
11525             check_cp1_64bitmode(ctx);
11526             {
11527                 TCGv_i64 fp0 = tcg_temp_new_i64();
11528                 TCGv_i64 fp1 = tcg_temp_new_i64();
11529
11530                 gen_load_fpr64(ctx, fp0, fs);
11531                 gen_load_fpr64(ctx, fp1, ft);
11532                 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
11533                 tcg_temp_free_i64(fp1);
11534                 gen_store_fpr64(ctx, fp0, fd);
11535                 tcg_temp_free_i64(fp0);
11536             }
11537         }
11538         break;
11539     case OPC_MINA_D: /* OPC_RECIP1_D */
11540         if (ctx->insn_flags & ISA_MIPS32R6) {
11541             /* OPC_MINA_D */
11542             TCGv_i64 fp0 = tcg_temp_new_i64();
11543             TCGv_i64 fp1 = tcg_temp_new_i64();
11544             gen_load_fpr64(ctx, fp0, fs);
11545             gen_load_fpr64(ctx, fp1, ft);
11546             gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
11547             gen_store_fpr64(ctx, fp1, fd);
11548             tcg_temp_free_i64(fp1);
11549             tcg_temp_free_i64(fp0);
11550         } else {
11551             /* OPC_RECIP1_D */
11552             check_cp1_64bitmode(ctx);
11553             {
11554                 TCGv_i64 fp0 = tcg_temp_new_i64();
11555
11556                 gen_load_fpr64(ctx, fp0, fs);
11557                 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
11558                 gen_store_fpr64(ctx, fp0, fd);
11559                 tcg_temp_free_i64(fp0);
11560             }
11561         }
11562         break;
11563     case OPC_MAX_D: /*  OPC_RSQRT1_D */
11564         if (ctx->insn_flags & ISA_MIPS32R6) {
11565             /* OPC_MAX_D */
11566             TCGv_i64 fp0 = tcg_temp_new_i64();
11567             TCGv_i64 fp1 = tcg_temp_new_i64();
11568             gen_load_fpr64(ctx, fp0, fs);
11569             gen_load_fpr64(ctx, fp1, ft);
11570             gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
11571             gen_store_fpr64(ctx, fp1, fd);
11572             tcg_temp_free_i64(fp1);
11573             tcg_temp_free_i64(fp0);
11574         } else {
11575             /* OPC_RSQRT1_D */
11576             check_cp1_64bitmode(ctx);
11577             {
11578                 TCGv_i64 fp0 = tcg_temp_new_i64();
11579
11580                 gen_load_fpr64(ctx, fp0, fs);
11581                 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
11582                 gen_store_fpr64(ctx, fp0, fd);
11583                 tcg_temp_free_i64(fp0);
11584             }
11585         }
11586         break;
11587     case OPC_MAXA_D: /* OPC_RSQRT2_D */
11588         if (ctx->insn_flags & ISA_MIPS32R6) {
11589             /* OPC_MAXA_D */
11590             TCGv_i64 fp0 = tcg_temp_new_i64();
11591             TCGv_i64 fp1 = tcg_temp_new_i64();
11592             gen_load_fpr64(ctx, fp0, fs);
11593             gen_load_fpr64(ctx, fp1, ft);
11594             gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
11595             gen_store_fpr64(ctx, fp1, fd);
11596             tcg_temp_free_i64(fp1);
11597             tcg_temp_free_i64(fp0);
11598         } else {
11599             /* OPC_RSQRT2_D */
11600             check_cp1_64bitmode(ctx);
11601             {
11602                 TCGv_i64 fp0 = tcg_temp_new_i64();
11603                 TCGv_i64 fp1 = tcg_temp_new_i64();
11604
11605                 gen_load_fpr64(ctx, fp0, fs);
11606                 gen_load_fpr64(ctx, fp1, ft);
11607                 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
11608                 tcg_temp_free_i64(fp1);
11609                 gen_store_fpr64(ctx, fp0, fd);
11610                 tcg_temp_free_i64(fp0);
11611             }
11612         }
11613         break;
11614     case OPC_CMP_F_D:
11615     case OPC_CMP_UN_D:
11616     case OPC_CMP_EQ_D:
11617     case OPC_CMP_UEQ_D:
11618     case OPC_CMP_OLT_D:
11619     case OPC_CMP_ULT_D:
11620     case OPC_CMP_OLE_D:
11621     case OPC_CMP_ULE_D:
11622     case OPC_CMP_SF_D:
11623     case OPC_CMP_NGLE_D:
11624     case OPC_CMP_SEQ_D:
11625     case OPC_CMP_NGL_D:
11626     case OPC_CMP_LT_D:
11627     case OPC_CMP_NGE_D:
11628     case OPC_CMP_LE_D:
11629     case OPC_CMP_NGT_D:
11630         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11631         if (ctx->opcode & (1 << 6)) {
11632             gen_cmpabs_d(ctx, func-48, ft, fs, cc);
11633         } else {
11634             gen_cmp_d(ctx, func-48, ft, fs, cc);
11635         }
11636         break;
11637     case OPC_CVT_S_D:
11638         check_cp1_registers(ctx, fs);
11639         {
11640             TCGv_i32 fp32 = tcg_temp_new_i32();
11641             TCGv_i64 fp64 = tcg_temp_new_i64();
11642
11643             gen_load_fpr64(ctx, fp64, fs);
11644             gen_helper_float_cvts_d(fp32, cpu_env, fp64);
11645             tcg_temp_free_i64(fp64);
11646             gen_store_fpr32(ctx, fp32, fd);
11647             tcg_temp_free_i32(fp32);
11648         }
11649         break;
11650     case OPC_CVT_W_D:
11651         check_cp1_registers(ctx, fs);
11652         {
11653             TCGv_i32 fp32 = tcg_temp_new_i32();
11654             TCGv_i64 fp64 = tcg_temp_new_i64();
11655
11656             gen_load_fpr64(ctx, fp64, fs);
11657             if (ctx->nan2008) {
11658                 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
11659             } else {
11660                 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
11661             }
11662             tcg_temp_free_i64(fp64);
11663             gen_store_fpr32(ctx, fp32, fd);
11664             tcg_temp_free_i32(fp32);
11665         }
11666         break;
11667     case OPC_CVT_L_D:
11668         check_cp1_64bitmode(ctx);
11669         {
11670             TCGv_i64 fp0 = tcg_temp_new_i64();
11671
11672             gen_load_fpr64(ctx, fp0, fs);
11673             if (ctx->nan2008) {
11674                 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
11675             } else {
11676                 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
11677             }
11678             gen_store_fpr64(ctx, fp0, fd);
11679             tcg_temp_free_i64(fp0);
11680         }
11681         break;
11682     case OPC_CVT_S_W:
11683         {
11684             TCGv_i32 fp0 = tcg_temp_new_i32();
11685
11686             gen_load_fpr32(ctx, fp0, fs);
11687             gen_helper_float_cvts_w(fp0, cpu_env, fp0);
11688             gen_store_fpr32(ctx, fp0, fd);
11689             tcg_temp_free_i32(fp0);
11690         }
11691         break;
11692     case OPC_CVT_D_W:
11693         check_cp1_registers(ctx, fd);
11694         {
11695             TCGv_i32 fp32 = tcg_temp_new_i32();
11696             TCGv_i64 fp64 = tcg_temp_new_i64();
11697
11698             gen_load_fpr32(ctx, fp32, fs);
11699             gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
11700             tcg_temp_free_i32(fp32);
11701             gen_store_fpr64(ctx, fp64, fd);
11702             tcg_temp_free_i64(fp64);
11703         }
11704         break;
11705     case OPC_CVT_S_L:
11706         check_cp1_64bitmode(ctx);
11707         {
11708             TCGv_i32 fp32 = tcg_temp_new_i32();
11709             TCGv_i64 fp64 = tcg_temp_new_i64();
11710
11711             gen_load_fpr64(ctx, fp64, fs);
11712             gen_helper_float_cvts_l(fp32, cpu_env, fp64);
11713             tcg_temp_free_i64(fp64);
11714             gen_store_fpr32(ctx, fp32, fd);
11715             tcg_temp_free_i32(fp32);
11716         }
11717         break;
11718     case OPC_CVT_D_L:
11719         check_cp1_64bitmode(ctx);
11720         {
11721             TCGv_i64 fp0 = tcg_temp_new_i64();
11722
11723             gen_load_fpr64(ctx, fp0, fs);
11724             gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
11725             gen_store_fpr64(ctx, fp0, fd);
11726             tcg_temp_free_i64(fp0);
11727         }
11728         break;
11729     case OPC_CVT_PS_PW:
11730         check_ps(ctx);
11731         {
11732             TCGv_i64 fp0 = tcg_temp_new_i64();
11733
11734             gen_load_fpr64(ctx, fp0, fs);
11735             gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
11736             gen_store_fpr64(ctx, fp0, fd);
11737             tcg_temp_free_i64(fp0);
11738         }
11739         break;
11740     case OPC_ADD_PS:
11741         check_ps(ctx);
11742         {
11743             TCGv_i64 fp0 = tcg_temp_new_i64();
11744             TCGv_i64 fp1 = tcg_temp_new_i64();
11745
11746             gen_load_fpr64(ctx, fp0, fs);
11747             gen_load_fpr64(ctx, fp1, ft);
11748             gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
11749             tcg_temp_free_i64(fp1);
11750             gen_store_fpr64(ctx, fp0, fd);
11751             tcg_temp_free_i64(fp0);
11752         }
11753         break;
11754     case OPC_SUB_PS:
11755         check_ps(ctx);
11756         {
11757             TCGv_i64 fp0 = tcg_temp_new_i64();
11758             TCGv_i64 fp1 = tcg_temp_new_i64();
11759
11760             gen_load_fpr64(ctx, fp0, fs);
11761             gen_load_fpr64(ctx, fp1, ft);
11762             gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
11763             tcg_temp_free_i64(fp1);
11764             gen_store_fpr64(ctx, fp0, fd);
11765             tcg_temp_free_i64(fp0);
11766         }
11767         break;
11768     case OPC_MUL_PS:
11769         check_ps(ctx);
11770         {
11771             TCGv_i64 fp0 = tcg_temp_new_i64();
11772             TCGv_i64 fp1 = tcg_temp_new_i64();
11773
11774             gen_load_fpr64(ctx, fp0, fs);
11775             gen_load_fpr64(ctx, fp1, ft);
11776             gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
11777             tcg_temp_free_i64(fp1);
11778             gen_store_fpr64(ctx, fp0, fd);
11779             tcg_temp_free_i64(fp0);
11780         }
11781         break;
11782     case OPC_ABS_PS:
11783         check_ps(ctx);
11784         {
11785             TCGv_i64 fp0 = tcg_temp_new_i64();
11786
11787             gen_load_fpr64(ctx, fp0, fs);
11788             gen_helper_float_abs_ps(fp0, fp0);
11789             gen_store_fpr64(ctx, fp0, fd);
11790             tcg_temp_free_i64(fp0);
11791         }
11792         break;
11793     case OPC_MOV_PS:
11794         check_ps(ctx);
11795         {
11796             TCGv_i64 fp0 = tcg_temp_new_i64();
11797
11798             gen_load_fpr64(ctx, fp0, fs);
11799             gen_store_fpr64(ctx, fp0, fd);
11800             tcg_temp_free_i64(fp0);
11801         }
11802         break;
11803     case OPC_NEG_PS:
11804         check_ps(ctx);
11805         {
11806             TCGv_i64 fp0 = tcg_temp_new_i64();
11807
11808             gen_load_fpr64(ctx, fp0, fs);
11809             gen_helper_float_chs_ps(fp0, fp0);
11810             gen_store_fpr64(ctx, fp0, fd);
11811             tcg_temp_free_i64(fp0);
11812         }
11813         break;
11814     case OPC_MOVCF_PS:
11815         check_ps(ctx);
11816         gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11817         break;
11818     case OPC_MOVZ_PS:
11819         check_ps(ctx);
11820         {
11821             TCGLabel *l1 = gen_new_label();
11822             TCGv_i64 fp0;
11823
11824             if (ft != 0)
11825                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11826             fp0 = tcg_temp_new_i64();
11827             gen_load_fpr64(ctx, fp0, fs);
11828             gen_store_fpr64(ctx, fp0, fd);
11829             tcg_temp_free_i64(fp0);
11830             gen_set_label(l1);
11831         }
11832         break;
11833     case OPC_MOVN_PS:
11834         check_ps(ctx);
11835         {
11836             TCGLabel *l1 = gen_new_label();
11837             TCGv_i64 fp0;
11838
11839             if (ft != 0) {
11840                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11841                 fp0 = tcg_temp_new_i64();
11842                 gen_load_fpr64(ctx, fp0, fs);
11843                 gen_store_fpr64(ctx, fp0, fd);
11844                 tcg_temp_free_i64(fp0);
11845                 gen_set_label(l1);
11846             }
11847         }
11848         break;
11849     case OPC_ADDR_PS:
11850         check_ps(ctx);
11851         {
11852             TCGv_i64 fp0 = tcg_temp_new_i64();
11853             TCGv_i64 fp1 = tcg_temp_new_i64();
11854
11855             gen_load_fpr64(ctx, fp0, ft);
11856             gen_load_fpr64(ctx, fp1, fs);
11857             gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
11858             tcg_temp_free_i64(fp1);
11859             gen_store_fpr64(ctx, fp0, fd);
11860             tcg_temp_free_i64(fp0);
11861         }
11862         break;
11863     case OPC_MULR_PS:
11864         check_ps(ctx);
11865         {
11866             TCGv_i64 fp0 = tcg_temp_new_i64();
11867             TCGv_i64 fp1 = tcg_temp_new_i64();
11868
11869             gen_load_fpr64(ctx, fp0, ft);
11870             gen_load_fpr64(ctx, fp1, fs);
11871             gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
11872             tcg_temp_free_i64(fp1);
11873             gen_store_fpr64(ctx, fp0, fd);
11874             tcg_temp_free_i64(fp0);
11875         }
11876         break;
11877     case OPC_RECIP2_PS:
11878         check_ps(ctx);
11879         {
11880             TCGv_i64 fp0 = tcg_temp_new_i64();
11881             TCGv_i64 fp1 = tcg_temp_new_i64();
11882
11883             gen_load_fpr64(ctx, fp0, fs);
11884             gen_load_fpr64(ctx, fp1, ft);
11885             gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
11886             tcg_temp_free_i64(fp1);
11887             gen_store_fpr64(ctx, fp0, fd);
11888             tcg_temp_free_i64(fp0);
11889         }
11890         break;
11891     case OPC_RECIP1_PS:
11892         check_ps(ctx);
11893         {
11894             TCGv_i64 fp0 = tcg_temp_new_i64();
11895
11896             gen_load_fpr64(ctx, fp0, fs);
11897             gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
11898             gen_store_fpr64(ctx, fp0, fd);
11899             tcg_temp_free_i64(fp0);
11900         }
11901         break;
11902     case OPC_RSQRT1_PS:
11903         check_ps(ctx);
11904         {
11905             TCGv_i64 fp0 = tcg_temp_new_i64();
11906
11907             gen_load_fpr64(ctx, fp0, fs);
11908             gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
11909             gen_store_fpr64(ctx, fp0, fd);
11910             tcg_temp_free_i64(fp0);
11911         }
11912         break;
11913     case OPC_RSQRT2_PS:
11914         check_ps(ctx);
11915         {
11916             TCGv_i64 fp0 = tcg_temp_new_i64();
11917             TCGv_i64 fp1 = tcg_temp_new_i64();
11918
11919             gen_load_fpr64(ctx, fp0, fs);
11920             gen_load_fpr64(ctx, fp1, ft);
11921             gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
11922             tcg_temp_free_i64(fp1);
11923             gen_store_fpr64(ctx, fp0, fd);
11924             tcg_temp_free_i64(fp0);
11925         }
11926         break;
11927     case OPC_CVT_S_PU:
11928         check_cp1_64bitmode(ctx);
11929         {
11930             TCGv_i32 fp0 = tcg_temp_new_i32();
11931
11932             gen_load_fpr32h(ctx, fp0, fs);
11933             gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
11934             gen_store_fpr32(ctx, fp0, fd);
11935             tcg_temp_free_i32(fp0);
11936         }
11937         break;
11938     case OPC_CVT_PW_PS:
11939         check_ps(ctx);
11940         {
11941             TCGv_i64 fp0 = tcg_temp_new_i64();
11942
11943             gen_load_fpr64(ctx, fp0, fs);
11944             gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
11945             gen_store_fpr64(ctx, fp0, fd);
11946             tcg_temp_free_i64(fp0);
11947         }
11948         break;
11949     case OPC_CVT_S_PL:
11950         check_cp1_64bitmode(ctx);
11951         {
11952             TCGv_i32 fp0 = tcg_temp_new_i32();
11953
11954             gen_load_fpr32(ctx, fp0, fs);
11955             gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
11956             gen_store_fpr32(ctx, fp0, fd);
11957             tcg_temp_free_i32(fp0);
11958         }
11959         break;
11960     case OPC_PLL_PS:
11961         check_ps(ctx);
11962         {
11963             TCGv_i32 fp0 = tcg_temp_new_i32();
11964             TCGv_i32 fp1 = tcg_temp_new_i32();
11965
11966             gen_load_fpr32(ctx, fp0, fs);
11967             gen_load_fpr32(ctx, fp1, ft);
11968             gen_store_fpr32h(ctx, fp0, fd);
11969             gen_store_fpr32(ctx, fp1, fd);
11970             tcg_temp_free_i32(fp0);
11971             tcg_temp_free_i32(fp1);
11972         }
11973         break;
11974     case OPC_PLU_PS:
11975         check_ps(ctx);
11976         {
11977             TCGv_i32 fp0 = tcg_temp_new_i32();
11978             TCGv_i32 fp1 = tcg_temp_new_i32();
11979
11980             gen_load_fpr32(ctx, fp0, fs);
11981             gen_load_fpr32h(ctx, fp1, ft);
11982             gen_store_fpr32(ctx, fp1, fd);
11983             gen_store_fpr32h(ctx, fp0, fd);
11984             tcg_temp_free_i32(fp0);
11985             tcg_temp_free_i32(fp1);
11986         }
11987         break;
11988     case OPC_PUL_PS:
11989         check_ps(ctx);
11990         {
11991             TCGv_i32 fp0 = tcg_temp_new_i32();
11992             TCGv_i32 fp1 = tcg_temp_new_i32();
11993
11994             gen_load_fpr32h(ctx, fp0, fs);
11995             gen_load_fpr32(ctx, fp1, ft);
11996             gen_store_fpr32(ctx, fp1, fd);
11997             gen_store_fpr32h(ctx, fp0, fd);
11998             tcg_temp_free_i32(fp0);
11999             tcg_temp_free_i32(fp1);
12000         }
12001         break;
12002     case OPC_PUU_PS:
12003         check_ps(ctx);
12004         {
12005             TCGv_i32 fp0 = tcg_temp_new_i32();
12006             TCGv_i32 fp1 = tcg_temp_new_i32();
12007
12008             gen_load_fpr32h(ctx, fp0, fs);
12009             gen_load_fpr32h(ctx, fp1, ft);
12010             gen_store_fpr32(ctx, fp1, fd);
12011             gen_store_fpr32h(ctx, fp0, fd);
12012             tcg_temp_free_i32(fp0);
12013             tcg_temp_free_i32(fp1);
12014         }
12015         break;
12016     case OPC_CMP_F_PS:
12017     case OPC_CMP_UN_PS:
12018     case OPC_CMP_EQ_PS:
12019     case OPC_CMP_UEQ_PS:
12020     case OPC_CMP_OLT_PS:
12021     case OPC_CMP_ULT_PS:
12022     case OPC_CMP_OLE_PS:
12023     case OPC_CMP_ULE_PS:
12024     case OPC_CMP_SF_PS:
12025     case OPC_CMP_NGLE_PS:
12026     case OPC_CMP_SEQ_PS:
12027     case OPC_CMP_NGL_PS:
12028     case OPC_CMP_LT_PS:
12029     case OPC_CMP_NGE_PS:
12030     case OPC_CMP_LE_PS:
12031     case OPC_CMP_NGT_PS:
12032         if (ctx->opcode & (1 << 6)) {
12033             gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
12034         } else {
12035             gen_cmp_ps(ctx, func-48, ft, fs, cc);
12036         }
12037         break;
12038     default:
12039         MIPS_INVAL("farith");
12040         generate_exception_end(ctx, EXCP_RI);
12041         return;
12042     }
12043 }
12044
12045 /* Coprocessor 3 (FPU) */
12046 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
12047                            int fd, int fs, int base, int index)
12048 {
12049     TCGv t0 = tcg_temp_new();
12050
12051     if (base == 0) {
12052         gen_load_gpr(t0, index);
12053     } else if (index == 0) {
12054         gen_load_gpr(t0, base);
12055     } else {
12056         gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
12057     }
12058     /* Don't do NOP if destination is zero: we must perform the actual
12059        memory access. */
12060     switch (opc) {
12061     case OPC_LWXC1:
12062         check_cop1x(ctx);
12063         {
12064             TCGv_i32 fp0 = tcg_temp_new_i32();
12065
12066             tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
12067             tcg_gen_trunc_tl_i32(fp0, t0);
12068             gen_store_fpr32(ctx, fp0, fd);
12069             tcg_temp_free_i32(fp0);
12070         }
12071         break;
12072     case OPC_LDXC1:
12073         check_cop1x(ctx);
12074         check_cp1_registers(ctx, fd);
12075         {
12076             TCGv_i64 fp0 = tcg_temp_new_i64();
12077             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12078             gen_store_fpr64(ctx, fp0, fd);
12079             tcg_temp_free_i64(fp0);
12080         }
12081         break;
12082     case OPC_LUXC1:
12083         check_cp1_64bitmode(ctx);
12084         tcg_gen_andi_tl(t0, t0, ~0x7);
12085         {
12086             TCGv_i64 fp0 = tcg_temp_new_i64();
12087
12088             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12089             gen_store_fpr64(ctx, fp0, fd);
12090             tcg_temp_free_i64(fp0);
12091         }
12092         break;
12093     case OPC_SWXC1:
12094         check_cop1x(ctx);
12095         {
12096             TCGv_i32 fp0 = tcg_temp_new_i32();
12097             gen_load_fpr32(ctx, fp0, fs);
12098             tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
12099             tcg_temp_free_i32(fp0);
12100         }
12101         break;
12102     case OPC_SDXC1:
12103         check_cop1x(ctx);
12104         check_cp1_registers(ctx, fs);
12105         {
12106             TCGv_i64 fp0 = tcg_temp_new_i64();
12107             gen_load_fpr64(ctx, fp0, fs);
12108             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12109             tcg_temp_free_i64(fp0);
12110         }
12111         break;
12112     case OPC_SUXC1:
12113         check_cp1_64bitmode(ctx);
12114         tcg_gen_andi_tl(t0, t0, ~0x7);
12115         {
12116             TCGv_i64 fp0 = tcg_temp_new_i64();
12117             gen_load_fpr64(ctx, fp0, fs);
12118             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12119             tcg_temp_free_i64(fp0);
12120         }
12121         break;
12122     }
12123     tcg_temp_free(t0);
12124 }
12125
12126 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
12127                             int fd, int fr, int fs, int ft)
12128 {
12129     switch (opc) {
12130     case OPC_ALNV_PS:
12131         check_ps(ctx);
12132         {
12133             TCGv t0 = tcg_temp_local_new();
12134             TCGv_i32 fp = tcg_temp_new_i32();
12135             TCGv_i32 fph = tcg_temp_new_i32();
12136             TCGLabel *l1 = gen_new_label();
12137             TCGLabel *l2 = gen_new_label();
12138
12139             gen_load_gpr(t0, fr);
12140             tcg_gen_andi_tl(t0, t0, 0x7);
12141
12142             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
12143             gen_load_fpr32(ctx, fp, fs);
12144             gen_load_fpr32h(ctx, fph, fs);
12145             gen_store_fpr32(ctx, fp, fd);
12146             gen_store_fpr32h(ctx, fph, fd);
12147             tcg_gen_br(l2);
12148             gen_set_label(l1);
12149             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
12150             tcg_temp_free(t0);
12151 #ifdef TARGET_WORDS_BIGENDIAN
12152             gen_load_fpr32(ctx, fp, fs);
12153             gen_load_fpr32h(ctx, fph, ft);
12154             gen_store_fpr32h(ctx, fp, fd);
12155             gen_store_fpr32(ctx, fph, fd);
12156 #else
12157             gen_load_fpr32h(ctx, fph, fs);
12158             gen_load_fpr32(ctx, fp, ft);
12159             gen_store_fpr32(ctx, fph, fd);
12160             gen_store_fpr32h(ctx, fp, fd);
12161 #endif
12162             gen_set_label(l2);
12163             tcg_temp_free_i32(fp);
12164             tcg_temp_free_i32(fph);
12165         }
12166         break;
12167     case OPC_MADD_S:
12168         check_cop1x(ctx);
12169         {
12170             TCGv_i32 fp0 = tcg_temp_new_i32();
12171             TCGv_i32 fp1 = tcg_temp_new_i32();
12172             TCGv_i32 fp2 = tcg_temp_new_i32();
12173
12174             gen_load_fpr32(ctx, fp0, fs);
12175             gen_load_fpr32(ctx, fp1, ft);
12176             gen_load_fpr32(ctx, fp2, fr);
12177             gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
12178             tcg_temp_free_i32(fp0);
12179             tcg_temp_free_i32(fp1);
12180             gen_store_fpr32(ctx, fp2, fd);
12181             tcg_temp_free_i32(fp2);
12182         }
12183         break;
12184     case OPC_MADD_D:
12185         check_cop1x(ctx);
12186         check_cp1_registers(ctx, fd | fs | ft | fr);
12187         {
12188             TCGv_i64 fp0 = tcg_temp_new_i64();
12189             TCGv_i64 fp1 = tcg_temp_new_i64();
12190             TCGv_i64 fp2 = tcg_temp_new_i64();
12191
12192             gen_load_fpr64(ctx, fp0, fs);
12193             gen_load_fpr64(ctx, fp1, ft);
12194             gen_load_fpr64(ctx, fp2, fr);
12195             gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
12196             tcg_temp_free_i64(fp0);
12197             tcg_temp_free_i64(fp1);
12198             gen_store_fpr64(ctx, fp2, fd);
12199             tcg_temp_free_i64(fp2);
12200         }
12201         break;
12202     case OPC_MADD_PS:
12203         check_ps(ctx);
12204         {
12205             TCGv_i64 fp0 = tcg_temp_new_i64();
12206             TCGv_i64 fp1 = tcg_temp_new_i64();
12207             TCGv_i64 fp2 = tcg_temp_new_i64();
12208
12209             gen_load_fpr64(ctx, fp0, fs);
12210             gen_load_fpr64(ctx, fp1, ft);
12211             gen_load_fpr64(ctx, fp2, fr);
12212             gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
12213             tcg_temp_free_i64(fp0);
12214             tcg_temp_free_i64(fp1);
12215             gen_store_fpr64(ctx, fp2, fd);
12216             tcg_temp_free_i64(fp2);
12217         }
12218         break;
12219     case OPC_MSUB_S:
12220         check_cop1x(ctx);
12221         {
12222             TCGv_i32 fp0 = tcg_temp_new_i32();
12223             TCGv_i32 fp1 = tcg_temp_new_i32();
12224             TCGv_i32 fp2 = tcg_temp_new_i32();
12225
12226             gen_load_fpr32(ctx, fp0, fs);
12227             gen_load_fpr32(ctx, fp1, ft);
12228             gen_load_fpr32(ctx, fp2, fr);
12229             gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
12230             tcg_temp_free_i32(fp0);
12231             tcg_temp_free_i32(fp1);
12232             gen_store_fpr32(ctx, fp2, fd);
12233             tcg_temp_free_i32(fp2);
12234         }
12235         break;
12236     case OPC_MSUB_D:
12237         check_cop1x(ctx);
12238         check_cp1_registers(ctx, fd | fs | ft | fr);
12239         {
12240             TCGv_i64 fp0 = tcg_temp_new_i64();
12241             TCGv_i64 fp1 = tcg_temp_new_i64();
12242             TCGv_i64 fp2 = tcg_temp_new_i64();
12243
12244             gen_load_fpr64(ctx, fp0, fs);
12245             gen_load_fpr64(ctx, fp1, ft);
12246             gen_load_fpr64(ctx, fp2, fr);
12247             gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
12248             tcg_temp_free_i64(fp0);
12249             tcg_temp_free_i64(fp1);
12250             gen_store_fpr64(ctx, fp2, fd);
12251             tcg_temp_free_i64(fp2);
12252         }
12253         break;
12254     case OPC_MSUB_PS:
12255         check_ps(ctx);
12256         {
12257             TCGv_i64 fp0 = tcg_temp_new_i64();
12258             TCGv_i64 fp1 = tcg_temp_new_i64();
12259             TCGv_i64 fp2 = tcg_temp_new_i64();
12260
12261             gen_load_fpr64(ctx, fp0, fs);
12262             gen_load_fpr64(ctx, fp1, ft);
12263             gen_load_fpr64(ctx, fp2, fr);
12264             gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
12265             tcg_temp_free_i64(fp0);
12266             tcg_temp_free_i64(fp1);
12267             gen_store_fpr64(ctx, fp2, fd);
12268             tcg_temp_free_i64(fp2);
12269         }
12270         break;
12271     case OPC_NMADD_S:
12272         check_cop1x(ctx);
12273         {
12274             TCGv_i32 fp0 = tcg_temp_new_i32();
12275             TCGv_i32 fp1 = tcg_temp_new_i32();
12276             TCGv_i32 fp2 = tcg_temp_new_i32();
12277
12278             gen_load_fpr32(ctx, fp0, fs);
12279             gen_load_fpr32(ctx, fp1, ft);
12280             gen_load_fpr32(ctx, fp2, fr);
12281             gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
12282             tcg_temp_free_i32(fp0);
12283             tcg_temp_free_i32(fp1);
12284             gen_store_fpr32(ctx, fp2, fd);
12285             tcg_temp_free_i32(fp2);
12286         }
12287         break;
12288     case OPC_NMADD_D:
12289         check_cop1x(ctx);
12290         check_cp1_registers(ctx, fd | fs | ft | fr);
12291         {
12292             TCGv_i64 fp0 = tcg_temp_new_i64();
12293             TCGv_i64 fp1 = tcg_temp_new_i64();
12294             TCGv_i64 fp2 = tcg_temp_new_i64();
12295
12296             gen_load_fpr64(ctx, fp0, fs);
12297             gen_load_fpr64(ctx, fp1, ft);
12298             gen_load_fpr64(ctx, fp2, fr);
12299             gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
12300             tcg_temp_free_i64(fp0);
12301             tcg_temp_free_i64(fp1);
12302             gen_store_fpr64(ctx, fp2, fd);
12303             tcg_temp_free_i64(fp2);
12304         }
12305         break;
12306     case OPC_NMADD_PS:
12307         check_ps(ctx);
12308         {
12309             TCGv_i64 fp0 = tcg_temp_new_i64();
12310             TCGv_i64 fp1 = tcg_temp_new_i64();
12311             TCGv_i64 fp2 = tcg_temp_new_i64();
12312
12313             gen_load_fpr64(ctx, fp0, fs);
12314             gen_load_fpr64(ctx, fp1, ft);
12315             gen_load_fpr64(ctx, fp2, fr);
12316             gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
12317             tcg_temp_free_i64(fp0);
12318             tcg_temp_free_i64(fp1);
12319             gen_store_fpr64(ctx, fp2, fd);
12320             tcg_temp_free_i64(fp2);
12321         }
12322         break;
12323     case OPC_NMSUB_S:
12324         check_cop1x(ctx);
12325         {
12326             TCGv_i32 fp0 = tcg_temp_new_i32();
12327             TCGv_i32 fp1 = tcg_temp_new_i32();
12328             TCGv_i32 fp2 = tcg_temp_new_i32();
12329
12330             gen_load_fpr32(ctx, fp0, fs);
12331             gen_load_fpr32(ctx, fp1, ft);
12332             gen_load_fpr32(ctx, fp2, fr);
12333             gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
12334             tcg_temp_free_i32(fp0);
12335             tcg_temp_free_i32(fp1);
12336             gen_store_fpr32(ctx, fp2, fd);
12337             tcg_temp_free_i32(fp2);
12338         }
12339         break;
12340     case OPC_NMSUB_D:
12341         check_cop1x(ctx);
12342         check_cp1_registers(ctx, fd | fs | ft | fr);
12343         {
12344             TCGv_i64 fp0 = tcg_temp_new_i64();
12345             TCGv_i64 fp1 = tcg_temp_new_i64();
12346             TCGv_i64 fp2 = tcg_temp_new_i64();
12347
12348             gen_load_fpr64(ctx, fp0, fs);
12349             gen_load_fpr64(ctx, fp1, ft);
12350             gen_load_fpr64(ctx, fp2, fr);
12351             gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
12352             tcg_temp_free_i64(fp0);
12353             tcg_temp_free_i64(fp1);
12354             gen_store_fpr64(ctx, fp2, fd);
12355             tcg_temp_free_i64(fp2);
12356         }
12357         break;
12358     case OPC_NMSUB_PS:
12359         check_ps(ctx);
12360         {
12361             TCGv_i64 fp0 = tcg_temp_new_i64();
12362             TCGv_i64 fp1 = tcg_temp_new_i64();
12363             TCGv_i64 fp2 = tcg_temp_new_i64();
12364
12365             gen_load_fpr64(ctx, fp0, fs);
12366             gen_load_fpr64(ctx, fp1, ft);
12367             gen_load_fpr64(ctx, fp2, fr);
12368             gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
12369             tcg_temp_free_i64(fp0);
12370             tcg_temp_free_i64(fp1);
12371             gen_store_fpr64(ctx, fp2, fd);
12372             tcg_temp_free_i64(fp2);
12373         }
12374         break;
12375     default:
12376         MIPS_INVAL("flt3_arith");
12377         generate_exception_end(ctx, EXCP_RI);
12378         return;
12379     }
12380 }
12381
12382 static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
12383 {
12384     TCGv t0;
12385
12386 #if !defined(CONFIG_USER_ONLY)
12387     /* The Linux kernel will emulate rdhwr if it's not supported natively.
12388        Therefore only check the ISA in system mode.  */
12389     check_insn(ctx, ISA_MIPS32R2);
12390 #endif
12391     t0 = tcg_temp_new();
12392
12393     switch (rd) {
12394     case 0:
12395         gen_helper_rdhwr_cpunum(t0, cpu_env);
12396         gen_store_gpr(t0, rt);
12397         break;
12398     case 1:
12399         gen_helper_rdhwr_synci_step(t0, cpu_env);
12400         gen_store_gpr(t0, rt);
12401         break;
12402     case 2:
12403         if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
12404             gen_io_start();
12405         }
12406         gen_helper_rdhwr_cc(t0, cpu_env);
12407         if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
12408             gen_io_end();
12409         }
12410         gen_store_gpr(t0, rt);
12411         /* Break the TB to be able to take timer interrupts immediately
12412            after reading count. DISAS_STOP isn't sufficient, we need to ensure
12413            we break completely out of translated code.  */
12414         gen_save_pc(ctx->base.pc_next + 4);
12415         ctx->base.is_jmp = DISAS_EXIT;
12416         break;
12417     case 3:
12418         gen_helper_rdhwr_ccres(t0, cpu_env);
12419         gen_store_gpr(t0, rt);
12420         break;
12421     case 4:
12422         check_insn(ctx, ISA_MIPS32R6);
12423         if (sel != 0) {
12424             /* Performance counter registers are not implemented other than
12425              * control register 0.
12426              */
12427             generate_exception(ctx, EXCP_RI);
12428         }
12429         gen_helper_rdhwr_performance(t0, cpu_env);
12430         gen_store_gpr(t0, rt);
12431         break;
12432     case 5:
12433         check_insn(ctx, ISA_MIPS32R6);
12434         gen_helper_rdhwr_xnp(t0, cpu_env);
12435         gen_store_gpr(t0, rt);
12436         break;
12437     case 29:
12438 #if defined(CONFIG_USER_ONLY)
12439         tcg_gen_ld_tl(t0, cpu_env,
12440                       offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12441         gen_store_gpr(t0, rt);
12442         break;
12443 #else
12444         if ((ctx->hflags & MIPS_HFLAG_CP0) ||
12445             (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
12446             tcg_gen_ld_tl(t0, cpu_env,
12447                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12448             gen_store_gpr(t0, rt);
12449         } else {
12450             generate_exception_end(ctx, EXCP_RI);
12451         }
12452         break;
12453 #endif
12454     default:            /* Invalid */
12455         MIPS_INVAL("rdhwr");
12456         generate_exception_end(ctx, EXCP_RI);
12457         break;
12458     }
12459     tcg_temp_free(t0);
12460 }
12461
12462 static inline void clear_branch_hflags(DisasContext *ctx)
12463 {
12464     ctx->hflags &= ~MIPS_HFLAG_BMASK;
12465     if (ctx->base.is_jmp == DISAS_NEXT) {
12466         save_cpu_state(ctx, 0);
12467     } else {
12468         /* it is not safe to save ctx->hflags as hflags may be changed
12469            in execution time by the instruction in delay / forbidden slot. */
12470         tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
12471     }
12472 }
12473
12474 static void gen_branch(DisasContext *ctx, int insn_bytes)
12475 {
12476     if (ctx->hflags & MIPS_HFLAG_BMASK) {
12477         int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
12478         /* Branches completion */
12479         clear_branch_hflags(ctx);
12480         ctx->base.is_jmp = DISAS_NORETURN;
12481         /* FIXME: Need to clear can_do_io.  */
12482         switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
12483         case MIPS_HFLAG_FBNSLOT:
12484             gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
12485             break;
12486         case MIPS_HFLAG_B:
12487             /* unconditional branch */
12488             if (proc_hflags & MIPS_HFLAG_BX) {
12489                 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
12490             }
12491             gen_goto_tb(ctx, 0, ctx->btarget);
12492             break;
12493         case MIPS_HFLAG_BL:
12494             /* blikely taken case */
12495             gen_goto_tb(ctx, 0, ctx->btarget);
12496             break;
12497         case MIPS_HFLAG_BC:
12498             /* Conditional branch */
12499             {
12500                 TCGLabel *l1 = gen_new_label();
12501
12502                 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
12503                 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
12504                 gen_set_label(l1);
12505                 gen_goto_tb(ctx, 0, ctx->btarget);
12506             }
12507             break;
12508         case MIPS_HFLAG_BR:
12509             /* unconditional branch to register */
12510             if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
12511                 TCGv t0 = tcg_temp_new();
12512                 TCGv_i32 t1 = tcg_temp_new_i32();
12513
12514                 tcg_gen_andi_tl(t0, btarget, 0x1);
12515                 tcg_gen_trunc_tl_i32(t1, t0);
12516                 tcg_temp_free(t0);
12517                 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
12518                 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
12519                 tcg_gen_or_i32(hflags, hflags, t1);
12520                 tcg_temp_free_i32(t1);
12521
12522                 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
12523             } else {
12524                 tcg_gen_mov_tl(cpu_PC, btarget);
12525             }
12526             if (ctx->base.singlestep_enabled) {
12527                 save_cpu_state(ctx, 0);
12528                 gen_helper_raise_exception_debug(cpu_env);
12529             }
12530             tcg_gen_lookup_and_goto_ptr();
12531             break;
12532         default:
12533             fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
12534             abort();
12535         }
12536     }
12537 }
12538
12539 /* Compact Branches */
12540 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
12541                                        int rs, int rt, int32_t offset)
12542 {
12543     int bcond_compute = 0;
12544     TCGv t0 = tcg_temp_new();
12545     TCGv t1 = tcg_temp_new();
12546     int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
12547
12548     if (ctx->hflags & MIPS_HFLAG_BMASK) {
12549 #ifdef MIPS_DEBUG_DISAS
12550         LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
12551                   "\n", ctx->base.pc_next);
12552 #endif
12553         generate_exception_end(ctx, EXCP_RI);
12554         goto out;
12555     }
12556
12557     /* Load needed operands and calculate btarget */
12558     switch (opc) {
12559     /* compact branch */
12560     case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12561     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12562         gen_load_gpr(t0, rs);
12563         gen_load_gpr(t1, rt);
12564         bcond_compute = 1;
12565         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12566         if (rs <= rt && rs == 0) {
12567             /* OPC_BEQZALC, OPC_BNEZALC */
12568             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12569         }
12570         break;
12571     case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12572     case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12573         gen_load_gpr(t0, rs);
12574         gen_load_gpr(t1, rt);
12575         bcond_compute = 1;
12576         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12577         break;
12578     case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12579     case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12580         if (rs == 0 || rs == rt) {
12581             /* OPC_BLEZALC, OPC_BGEZALC */
12582             /* OPC_BGTZALC, OPC_BLTZALC */
12583             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12584         }
12585         gen_load_gpr(t0, rs);
12586         gen_load_gpr(t1, rt);
12587         bcond_compute = 1;
12588         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12589         break;
12590     case OPC_BC:
12591     case OPC_BALC:
12592         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12593         break;
12594     case OPC_BEQZC:
12595     case OPC_BNEZC:
12596         if (rs != 0) {
12597             /* OPC_BEQZC, OPC_BNEZC */
12598             gen_load_gpr(t0, rs);
12599             bcond_compute = 1;
12600             ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12601         } else {
12602             /* OPC_JIC, OPC_JIALC */
12603             TCGv tbase = tcg_temp_new();
12604             TCGv toffset = tcg_temp_new();
12605
12606             gen_load_gpr(tbase, rt);
12607             tcg_gen_movi_tl(toffset, offset);
12608             gen_op_addr_add(ctx, btarget, tbase, toffset);
12609             tcg_temp_free(tbase);
12610             tcg_temp_free(toffset);
12611         }
12612         break;
12613     default:
12614         MIPS_INVAL("Compact branch/jump");
12615         generate_exception_end(ctx, EXCP_RI);
12616         goto out;
12617     }
12618
12619     if (bcond_compute == 0) {
12620         /* Uncoditional compact branch */
12621         switch (opc) {
12622         case OPC_JIALC:
12623             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12624             /* Fallthrough */
12625         case OPC_JIC:
12626             ctx->hflags |= MIPS_HFLAG_BR;
12627             break;
12628         case OPC_BALC:
12629             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12630             /* Fallthrough */
12631         case OPC_BC:
12632             ctx->hflags |= MIPS_HFLAG_B;
12633             break;
12634         default:
12635             MIPS_INVAL("Compact branch/jump");
12636             generate_exception_end(ctx, EXCP_RI);
12637             goto out;
12638         }
12639
12640         /* Generating branch here as compact branches don't have delay slot */
12641         gen_branch(ctx, 4);
12642     } else {
12643         /* Conditional compact branch */
12644         TCGLabel *fs = gen_new_label();
12645         save_cpu_state(ctx, 0);
12646
12647         switch (opc) {
12648         case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12649             if (rs == 0 && rt != 0) {
12650                 /* OPC_BLEZALC */
12651                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12652             } else if (rs != 0 && rt != 0 && rs == rt) {
12653                 /* OPC_BGEZALC */
12654                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12655             } else {
12656                 /* OPC_BGEUC */
12657                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
12658             }
12659             break;
12660         case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12661             if (rs == 0 && rt != 0) {
12662                 /* OPC_BGTZALC */
12663                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12664             } else if (rs != 0 && rt != 0 && rs == rt) {
12665                 /* OPC_BLTZALC */
12666                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12667             } else {
12668                 /* OPC_BLTUC */
12669                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
12670             }
12671             break;
12672         case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12673             if (rs == 0 && rt != 0) {
12674                 /* OPC_BLEZC */
12675                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12676             } else if (rs != 0 && rt != 0 && rs == rt) {
12677                 /* OPC_BGEZC */
12678                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12679             } else {
12680                 /* OPC_BGEC */
12681                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
12682             }
12683             break;
12684         case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12685             if (rs == 0 && rt != 0) {
12686                 /* OPC_BGTZC */
12687                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12688             } else if (rs != 0 && rt != 0 && rs == rt) {
12689                 /* OPC_BLTZC */
12690                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12691             } else {
12692                 /* OPC_BLTC */
12693                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
12694             }
12695             break;
12696         case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12697         case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12698             if (rs >= rt) {
12699                 /* OPC_BOVC, OPC_BNVC */
12700                 TCGv t2 = tcg_temp_new();
12701                 TCGv t3 = tcg_temp_new();
12702                 TCGv t4 = tcg_temp_new();
12703                 TCGv input_overflow = tcg_temp_new();
12704
12705                 gen_load_gpr(t0, rs);
12706                 gen_load_gpr(t1, rt);
12707                 tcg_gen_ext32s_tl(t2, t0);
12708                 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
12709                 tcg_gen_ext32s_tl(t3, t1);
12710                 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
12711                 tcg_gen_or_tl(input_overflow, input_overflow, t4);
12712
12713                 tcg_gen_add_tl(t4, t2, t3);
12714                 tcg_gen_ext32s_tl(t4, t4);
12715                 tcg_gen_xor_tl(t2, t2, t3);
12716                 tcg_gen_xor_tl(t3, t4, t3);
12717                 tcg_gen_andc_tl(t2, t3, t2);
12718                 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
12719                 tcg_gen_or_tl(t4, t4, input_overflow);
12720                 if (opc == OPC_BOVC) {
12721                     /* OPC_BOVC */
12722                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
12723                 } else {
12724                     /* OPC_BNVC */
12725                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
12726                 }
12727                 tcg_temp_free(input_overflow);
12728                 tcg_temp_free(t4);
12729                 tcg_temp_free(t3);
12730                 tcg_temp_free(t2);
12731             } else if (rs < rt && rs == 0) {
12732                 /* OPC_BEQZALC, OPC_BNEZALC */
12733                 if (opc == OPC_BEQZALC) {
12734                     /* OPC_BEQZALC */
12735                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
12736                 } else {
12737                     /* OPC_BNEZALC */
12738                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
12739                 }
12740             } else {
12741                 /* OPC_BEQC, OPC_BNEC */
12742                 if (opc == OPC_BEQC) {
12743                     /* OPC_BEQC */
12744                     tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
12745                 } else {
12746                     /* OPC_BNEC */
12747                     tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
12748                 }
12749             }
12750             break;
12751         case OPC_BEQZC:
12752             tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
12753             break;
12754         case OPC_BNEZC:
12755             tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
12756             break;
12757         default:
12758             MIPS_INVAL("Compact conditional branch/jump");
12759             generate_exception_end(ctx, EXCP_RI);
12760             goto out;
12761         }
12762
12763         /* Generating branch here as compact branches don't have delay slot */
12764         gen_goto_tb(ctx, 1, ctx->btarget);
12765         gen_set_label(fs);
12766
12767         ctx->hflags |= MIPS_HFLAG_FBNSLOT;
12768     }
12769
12770 out:
12771     tcg_temp_free(t0);
12772     tcg_temp_free(t1);
12773 }
12774
12775 /* ISA extensions (ASEs) */
12776 /* MIPS16 extension to MIPS32 */
12777
12778 /* MIPS16 major opcodes */
12779 enum {
12780   M16_OPC_ADDIUSP = 0x00,
12781   M16_OPC_ADDIUPC = 0x01,
12782   M16_OPC_B = 0x02,
12783   M16_OPC_JAL = 0x03,
12784   M16_OPC_BEQZ = 0x04,
12785   M16_OPC_BNEQZ = 0x05,
12786   M16_OPC_SHIFT = 0x06,
12787   M16_OPC_LD = 0x07,
12788   M16_OPC_RRIA = 0x08,
12789   M16_OPC_ADDIU8 = 0x09,
12790   M16_OPC_SLTI = 0x0a,
12791   M16_OPC_SLTIU = 0x0b,
12792   M16_OPC_I8 = 0x0c,
12793   M16_OPC_LI = 0x0d,
12794   M16_OPC_CMPI = 0x0e,
12795   M16_OPC_SD = 0x0f,
12796   M16_OPC_LB = 0x10,
12797   M16_OPC_LH = 0x11,
12798   M16_OPC_LWSP = 0x12,
12799   M16_OPC_LW = 0x13,
12800   M16_OPC_LBU = 0x14,
12801   M16_OPC_LHU = 0x15,
12802   M16_OPC_LWPC = 0x16,
12803   M16_OPC_LWU = 0x17,
12804   M16_OPC_SB = 0x18,
12805   M16_OPC_SH = 0x19,
12806   M16_OPC_SWSP = 0x1a,
12807   M16_OPC_SW = 0x1b,
12808   M16_OPC_RRR = 0x1c,
12809   M16_OPC_RR = 0x1d,
12810   M16_OPC_EXTEND = 0x1e,
12811   M16_OPC_I64 = 0x1f
12812 };
12813
12814 /* I8 funct field */
12815 enum {
12816   I8_BTEQZ = 0x0,
12817   I8_BTNEZ = 0x1,
12818   I8_SWRASP = 0x2,
12819   I8_ADJSP = 0x3,
12820   I8_SVRS = 0x4,
12821   I8_MOV32R = 0x5,
12822   I8_MOVR32 = 0x7
12823 };
12824
12825 /* RRR f field */
12826 enum {
12827   RRR_DADDU = 0x0,
12828   RRR_ADDU = 0x1,
12829   RRR_DSUBU = 0x2,
12830   RRR_SUBU = 0x3
12831 };
12832
12833 /* RR funct field */
12834 enum {
12835   RR_JR = 0x00,
12836   RR_SDBBP = 0x01,
12837   RR_SLT = 0x02,
12838   RR_SLTU = 0x03,
12839   RR_SLLV = 0x04,
12840   RR_BREAK = 0x05,
12841   RR_SRLV = 0x06,
12842   RR_SRAV = 0x07,
12843   RR_DSRL = 0x08,
12844   RR_CMP = 0x0a,
12845   RR_NEG = 0x0b,
12846   RR_AND = 0x0c,
12847   RR_OR = 0x0d,
12848   RR_XOR = 0x0e,
12849   RR_NOT = 0x0f,
12850   RR_MFHI = 0x10,
12851   RR_CNVT = 0x11,
12852   RR_MFLO = 0x12,
12853   RR_DSRA = 0x13,
12854   RR_DSLLV = 0x14,
12855   RR_DSRLV = 0x16,
12856   RR_DSRAV = 0x17,
12857   RR_MULT = 0x18,
12858   RR_MULTU = 0x19,
12859   RR_DIV = 0x1a,
12860   RR_DIVU = 0x1b,
12861   RR_DMULT = 0x1c,
12862   RR_DMULTU = 0x1d,
12863   RR_DDIV = 0x1e,
12864   RR_DDIVU = 0x1f
12865 };
12866
12867 /* I64 funct field */
12868 enum {
12869   I64_LDSP = 0x0,
12870   I64_SDSP = 0x1,
12871   I64_SDRASP = 0x2,
12872   I64_DADJSP = 0x3,
12873   I64_LDPC = 0x4,
12874   I64_DADDIU5 = 0x5,
12875   I64_DADDIUPC = 0x6,
12876   I64_DADDIUSP = 0x7
12877 };
12878
12879 /* RR ry field for CNVT */
12880 enum {
12881   RR_RY_CNVT_ZEB = 0x0,
12882   RR_RY_CNVT_ZEH = 0x1,
12883   RR_RY_CNVT_ZEW = 0x2,
12884   RR_RY_CNVT_SEB = 0x4,
12885   RR_RY_CNVT_SEH = 0x5,
12886   RR_RY_CNVT_SEW = 0x6,
12887 };
12888
12889 static int xlat (int r)
12890 {
12891   static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12892
12893   return map[r];
12894 }
12895
12896 static void gen_mips16_save (DisasContext *ctx,
12897                              int xsregs, int aregs,
12898                              int do_ra, int do_s0, int do_s1,
12899                              int framesize)
12900 {
12901     TCGv t0 = tcg_temp_new();
12902     TCGv t1 = tcg_temp_new();
12903     TCGv t2 = tcg_temp_new();
12904     int args, astatic;
12905
12906     switch (aregs) {
12907     case 0:
12908     case 1:
12909     case 2:
12910     case 3:
12911     case 11:
12912         args = 0;
12913         break;
12914     case 4:
12915     case 5:
12916     case 6:
12917     case 7:
12918         args = 1;
12919         break;
12920     case 8:
12921     case 9:
12922     case 10:
12923         args = 2;
12924         break;
12925     case 12:
12926     case 13:
12927         args = 3;
12928         break;
12929     case 14:
12930         args = 4;
12931         break;
12932     default:
12933         generate_exception_end(ctx, EXCP_RI);
12934         return;
12935     }
12936
12937     switch (args) {
12938     case 4:
12939         gen_base_offset_addr(ctx, t0, 29, 12);
12940         gen_load_gpr(t1, 7);
12941         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12942         /* Fall through */
12943     case 3:
12944         gen_base_offset_addr(ctx, t0, 29, 8);
12945         gen_load_gpr(t1, 6);
12946         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12947         /* Fall through */
12948     case 2:
12949         gen_base_offset_addr(ctx, t0, 29, 4);
12950         gen_load_gpr(t1, 5);
12951         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12952         /* Fall through */
12953     case 1:
12954         gen_base_offset_addr(ctx, t0, 29, 0);
12955         gen_load_gpr(t1, 4);
12956         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12957     }
12958
12959     gen_load_gpr(t0, 29);
12960
12961 #define DECR_AND_STORE(reg) do {                                 \
12962         tcg_gen_movi_tl(t2, -4);                                 \
12963         gen_op_addr_add(ctx, t0, t0, t2);                        \
12964         gen_load_gpr(t1, reg);                                   \
12965         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
12966     } while (0)
12967
12968     if (do_ra) {
12969         DECR_AND_STORE(31);
12970     }
12971
12972     switch (xsregs) {
12973     case 7:
12974         DECR_AND_STORE(30);
12975         /* Fall through */
12976     case 6:
12977         DECR_AND_STORE(23);
12978         /* Fall through */
12979     case 5:
12980         DECR_AND_STORE(22);
12981         /* Fall through */
12982     case 4:
12983         DECR_AND_STORE(21);
12984         /* Fall through */
12985     case 3:
12986         DECR_AND_STORE(20);
12987         /* Fall through */
12988     case 2:
12989         DECR_AND_STORE(19);
12990         /* Fall through */
12991     case 1:
12992         DECR_AND_STORE(18);
12993     }
12994
12995     if (do_s1) {
12996         DECR_AND_STORE(17);
12997     }
12998     if (do_s0) {
12999         DECR_AND_STORE(16);
13000     }
13001
13002     switch (aregs) {
13003     case 0:
13004     case 4:
13005     case 8:
13006     case 12:
13007     case 14:
13008         astatic = 0;
13009         break;
13010     case 1:
13011     case 5:
13012     case 9:
13013     case 13:
13014         astatic = 1;
13015         break;
13016     case 2:
13017     case 6:
13018     case 10:
13019         astatic = 2;
13020         break;
13021     case 3:
13022     case 7:
13023         astatic = 3;
13024         break;
13025     case 11:
13026         astatic = 4;
13027         break;
13028     default:
13029         generate_exception_end(ctx, EXCP_RI);
13030         return;
13031     }
13032
13033     if (astatic > 0) {
13034         DECR_AND_STORE(7);
13035         if (astatic > 1) {
13036             DECR_AND_STORE(6);
13037             if (astatic > 2) {
13038                 DECR_AND_STORE(5);
13039                 if (astatic > 3) {
13040                     DECR_AND_STORE(4);
13041                 }
13042             }
13043         }
13044     }
13045 #undef DECR_AND_STORE
13046
13047     tcg_gen_movi_tl(t2, -framesize);
13048     gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
13049     tcg_temp_free(t0);
13050     tcg_temp_free(t1);
13051     tcg_temp_free(t2);
13052 }
13053
13054 static void gen_mips16_restore (DisasContext *ctx,
13055                                 int xsregs, int aregs,
13056                                 int do_ra, int do_s0, int do_s1,
13057                                 int framesize)
13058 {
13059     int astatic;
13060     TCGv t0 = tcg_temp_new();
13061     TCGv t1 = tcg_temp_new();
13062     TCGv t2 = tcg_temp_new();
13063
13064     tcg_gen_movi_tl(t2, framesize);
13065     gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
13066
13067 #define DECR_AND_LOAD(reg) do {                            \
13068         tcg_gen_movi_tl(t2, -4);                           \
13069         gen_op_addr_add(ctx, t0, t0, t2);                  \
13070         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
13071         gen_store_gpr(t1, reg);                            \
13072     } while (0)
13073
13074     if (do_ra) {
13075         DECR_AND_LOAD(31);
13076     }
13077
13078     switch (xsregs) {
13079     case 7:
13080         DECR_AND_LOAD(30);
13081         /* Fall through */
13082     case 6:
13083         DECR_AND_LOAD(23);
13084         /* Fall through */
13085     case 5:
13086         DECR_AND_LOAD(22);
13087         /* Fall through */
13088     case 4:
13089         DECR_AND_LOAD(21);
13090         /* Fall through */
13091     case 3:
13092         DECR_AND_LOAD(20);
13093         /* Fall through */
13094     case 2:
13095         DECR_AND_LOAD(19);
13096         /* Fall through */
13097     case 1:
13098         DECR_AND_LOAD(18);
13099     }
13100
13101     if (do_s1) {
13102         DECR_AND_LOAD(17);
13103     }
13104     if (do_s0) {
13105         DECR_AND_LOAD(16);
13106     }
13107
13108     switch (aregs) {
13109     case 0:
13110     case 4:
13111     case 8:
13112     case 12:
13113     case 14:
13114         astatic = 0;
13115         break;
13116     case 1:
13117     case 5:
13118     case 9:
13119     case 13:
13120         astatic = 1;
13121         break;
13122     case 2:
13123     case 6:
13124     case 10:
13125         astatic = 2;
13126         break;
13127     case 3:
13128     case 7:
13129         astatic = 3;
13130         break;
13131     case 11:
13132         astatic = 4;
13133         break;
13134     default:
13135         generate_exception_end(ctx, EXCP_RI);
13136         return;
13137     }
13138
13139     if (astatic > 0) {
13140         DECR_AND_LOAD(7);
13141         if (astatic > 1) {
13142             DECR_AND_LOAD(6);
13143             if (astatic > 2) {
13144                 DECR_AND_LOAD(5);
13145                 if (astatic > 3) {
13146                     DECR_AND_LOAD(4);
13147                 }
13148             }
13149         }
13150     }
13151 #undef DECR_AND_LOAD
13152
13153     tcg_gen_movi_tl(t2, framesize);
13154     gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
13155     tcg_temp_free(t0);
13156     tcg_temp_free(t1);
13157     tcg_temp_free(t2);
13158 }
13159
13160 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
13161                          int is_64_bit, int extended)
13162 {
13163     TCGv t0;
13164
13165     if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
13166         generate_exception_end(ctx, EXCP_RI);
13167         return;
13168     }
13169
13170     t0 = tcg_temp_new();
13171
13172     tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
13173     tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
13174     if (!is_64_bit) {
13175         tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13176     }
13177
13178     tcg_temp_free(t0);
13179 }
13180
13181 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
13182                                 int16_t offset)
13183 {
13184     TCGv_i32 t0 = tcg_const_i32(op);
13185     TCGv t1 = tcg_temp_new();
13186     gen_base_offset_addr(ctx, t1, base, offset);
13187     gen_helper_cache(cpu_env, t1, t0);
13188 }
13189
13190 #if defined(TARGET_MIPS64)
13191 static void decode_i64_mips16 (DisasContext *ctx,
13192                                int ry, int funct, int16_t offset,
13193                                int extended)
13194 {
13195     switch (funct) {
13196     case I64_LDSP:
13197         check_insn(ctx, ISA_MIPS3);
13198         check_mips_64(ctx);
13199         offset = extended ? offset : offset << 3;
13200         gen_ld(ctx, OPC_LD, ry, 29, offset);
13201         break;
13202     case I64_SDSP:
13203         check_insn(ctx, ISA_MIPS3);
13204         check_mips_64(ctx);
13205         offset = extended ? offset : offset << 3;
13206         gen_st(ctx, OPC_SD, ry, 29, offset);
13207         break;
13208     case I64_SDRASP:
13209         check_insn(ctx, ISA_MIPS3);
13210         check_mips_64(ctx);
13211         offset = extended ? offset : (ctx->opcode & 0xff) << 3;
13212         gen_st(ctx, OPC_SD, 31, 29, offset);
13213         break;
13214     case I64_DADJSP:
13215         check_insn(ctx, ISA_MIPS3);
13216         check_mips_64(ctx);
13217         offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
13218         gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
13219         break;
13220     case I64_LDPC:
13221         check_insn(ctx, ISA_MIPS3);
13222         check_mips_64(ctx);
13223         if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
13224             generate_exception_end(ctx, EXCP_RI);
13225         } else {
13226             offset = extended ? offset : offset << 3;
13227             gen_ld(ctx, OPC_LDPC, ry, 0, offset);
13228         }
13229         break;
13230     case I64_DADDIU5:
13231         check_insn(ctx, ISA_MIPS3);
13232         check_mips_64(ctx);
13233         offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
13234         gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
13235         break;
13236     case I64_DADDIUPC:
13237         check_insn(ctx, ISA_MIPS3);
13238         check_mips_64(ctx);
13239         offset = extended ? offset : offset << 2;
13240         gen_addiupc(ctx, ry, offset, 1, extended);
13241         break;
13242     case I64_DADDIUSP:
13243         check_insn(ctx, ISA_MIPS3);
13244         check_mips_64(ctx);
13245         offset = extended ? offset : offset << 2;
13246         gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
13247         break;
13248     }
13249 }
13250 #endif
13251
13252 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
13253 {
13254     int extend = cpu_lduw_code(env, ctx->base.pc_next + 2);
13255     int op, rx, ry, funct, sa;
13256     int16_t imm, offset;
13257
13258     ctx->opcode = (ctx->opcode << 16) | extend;
13259     op = (ctx->opcode >> 11) & 0x1f;
13260     sa = (ctx->opcode >> 22) & 0x1f;
13261     funct = (ctx->opcode >> 8) & 0x7;
13262     rx = xlat((ctx->opcode >> 8) & 0x7);
13263     ry = xlat((ctx->opcode >> 5) & 0x7);
13264     offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
13265                               | ((ctx->opcode >> 21) & 0x3f) << 5
13266                               | (ctx->opcode & 0x1f));
13267
13268     /* The extended opcodes cleverly reuse the opcodes from their 16-bit
13269        counterparts.  */
13270     switch (op) {
13271     case M16_OPC_ADDIUSP:
13272         gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
13273         break;
13274     case M16_OPC_ADDIUPC:
13275         gen_addiupc(ctx, rx, imm, 0, 1);
13276         break;
13277     case M16_OPC_B:
13278         gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
13279         /* No delay slot, so just process as a normal instruction */
13280         break;
13281     case M16_OPC_BEQZ:
13282         gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
13283         /* No delay slot, so just process as a normal instruction */
13284         break;
13285     case M16_OPC_BNEQZ:
13286         gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
13287         /* No delay slot, so just process as a normal instruction */
13288         break;
13289     case M16_OPC_SHIFT:
13290         switch (ctx->opcode & 0x3) {
13291         case 0x0:
13292             gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
13293             break;
13294         case 0x1:
13295 #if defined(TARGET_MIPS64)
13296             check_mips_64(ctx);
13297             gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
13298 #else
13299             generate_exception_end(ctx, EXCP_RI);
13300 #endif
13301             break;
13302         case 0x2:
13303             gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
13304             break;
13305         case 0x3:
13306             gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
13307             break;
13308         }
13309         break;
13310 #if defined(TARGET_MIPS64)
13311     case M16_OPC_LD:
13312         check_insn(ctx, ISA_MIPS3);
13313         check_mips_64(ctx);
13314         gen_ld(ctx, OPC_LD, ry, rx, offset);
13315         break;
13316 #endif
13317     case M16_OPC_RRIA:
13318         imm = ctx->opcode & 0xf;
13319         imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
13320         imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
13321         imm = (int16_t) (imm << 1) >> 1;
13322         if ((ctx->opcode >> 4) & 0x1) {
13323 #if defined(TARGET_MIPS64)
13324             check_mips_64(ctx);
13325             gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
13326 #else
13327             generate_exception_end(ctx, EXCP_RI);
13328 #endif
13329         } else {
13330             gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
13331         }
13332         break;
13333     case M16_OPC_ADDIU8:
13334         gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
13335         break;
13336     case M16_OPC_SLTI:
13337         gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
13338         break;
13339     case M16_OPC_SLTIU:
13340         gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
13341         break;
13342     case M16_OPC_I8:
13343         switch (funct) {
13344         case I8_BTEQZ:
13345             gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
13346             break;
13347         case I8_BTNEZ:
13348             gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
13349             break;
13350         case I8_SWRASP:
13351             gen_st(ctx, OPC_SW, 31, 29, imm);
13352             break;
13353         case I8_ADJSP:
13354             gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
13355             break;
13356         case I8_SVRS:
13357             check_insn(ctx, ISA_MIPS32);
13358             {
13359                 int xsregs = (ctx->opcode >> 24) & 0x7;
13360                 int aregs = (ctx->opcode >> 16) & 0xf;
13361                 int do_ra = (ctx->opcode >> 6) & 0x1;
13362                 int do_s0 = (ctx->opcode >> 5) & 0x1;
13363                 int do_s1 = (ctx->opcode >> 4) & 0x1;
13364                 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
13365                                  | (ctx->opcode & 0xf)) << 3;
13366
13367                 if (ctx->opcode & (1 << 7)) {
13368                     gen_mips16_save(ctx, xsregs, aregs,
13369                                     do_ra, do_s0, do_s1,
13370                                     framesize);
13371                 } else {
13372                     gen_mips16_restore(ctx, xsregs, aregs,
13373                                        do_ra, do_s0, do_s1,
13374                                        framesize);
13375                 }
13376             }
13377             break;
13378         default:
13379             generate_exception_end(ctx, EXCP_RI);
13380             break;
13381         }
13382         break;
13383     case M16_OPC_LI:
13384         tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
13385         break;
13386     case M16_OPC_CMPI:
13387         tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
13388         break;
13389 #if defined(TARGET_MIPS64)
13390     case M16_OPC_SD:
13391         check_insn(ctx, ISA_MIPS3);
13392         check_mips_64(ctx);
13393         gen_st(ctx, OPC_SD, ry, rx, offset);
13394         break;
13395 #endif
13396     case M16_OPC_LB:
13397         gen_ld(ctx, OPC_LB, ry, rx, offset);
13398         break;
13399     case M16_OPC_LH:
13400         gen_ld(ctx, OPC_LH, ry, rx, offset);
13401         break;
13402     case M16_OPC_LWSP:
13403         gen_ld(ctx, OPC_LW, rx, 29, offset);
13404         break;
13405     case M16_OPC_LW:
13406         gen_ld(ctx, OPC_LW, ry, rx, offset);
13407         break;
13408     case M16_OPC_LBU:
13409         gen_ld(ctx, OPC_LBU, ry, rx, offset);
13410         break;
13411     case M16_OPC_LHU:
13412         gen_ld(ctx, OPC_LHU, ry, rx, offset);
13413         break;
13414     case M16_OPC_LWPC:
13415         gen_ld(ctx, OPC_LWPC, rx, 0, offset);
13416         break;
13417 #if defined(TARGET_MIPS64)
13418     case M16_OPC_LWU:
13419         check_insn(ctx, ISA_MIPS3);
13420         check_mips_64(ctx);
13421         gen_ld(ctx, OPC_LWU, ry, rx, offset);
13422         break;
13423 #endif
13424     case M16_OPC_SB:
13425         gen_st(ctx, OPC_SB, ry, rx, offset);
13426         break;
13427     case M16_OPC_SH:
13428         gen_st(ctx, OPC_SH, ry, rx, offset);
13429         break;
13430     case M16_OPC_SWSP:
13431         gen_st(ctx, OPC_SW, rx, 29, offset);
13432         break;
13433     case M16_OPC_SW:
13434         gen_st(ctx, OPC_SW, ry, rx, offset);
13435         break;
13436 #if defined(TARGET_MIPS64)
13437     case M16_OPC_I64:
13438         decode_i64_mips16(ctx, ry, funct, offset, 1);
13439         break;
13440 #endif
13441     default:
13442         generate_exception_end(ctx, EXCP_RI);
13443         break;
13444     }
13445
13446     return 4;
13447 }
13448
13449 static inline bool is_uhi(int sdbbp_code)
13450 {
13451 #ifdef CONFIG_USER_ONLY
13452     return false;
13453 #else
13454     return semihosting_enabled() && sdbbp_code == 1;
13455 #endif
13456 }
13457
13458 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
13459 {
13460     int rx, ry;
13461     int sa;
13462     int op, cnvt_op, op1, offset;
13463     int funct;
13464     int n_bytes;
13465
13466     op = (ctx->opcode >> 11) & 0x1f;
13467     sa = (ctx->opcode >> 2) & 0x7;
13468     sa = sa == 0 ? 8 : sa;
13469     rx = xlat((ctx->opcode >> 8) & 0x7);
13470     cnvt_op = (ctx->opcode >> 5) & 0x7;
13471     ry = xlat((ctx->opcode >> 5) & 0x7);
13472     op1 = offset = ctx->opcode & 0x1f;
13473
13474     n_bytes = 2;
13475
13476     switch (op) {
13477     case M16_OPC_ADDIUSP:
13478         {
13479             int16_t imm = ((uint8_t) ctx->opcode) << 2;
13480
13481             gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
13482         }
13483         break;
13484     case M16_OPC_ADDIUPC:
13485         gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
13486         break;
13487     case M16_OPC_B:
13488         offset = (ctx->opcode & 0x7ff) << 1;
13489         offset = (int16_t)(offset << 4) >> 4;
13490         gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
13491         /* No delay slot, so just process as a normal instruction */
13492         break;
13493     case M16_OPC_JAL:
13494         offset = cpu_lduw_code(env, ctx->base.pc_next + 2);
13495         offset = (((ctx->opcode & 0x1f) << 21)
13496                   | ((ctx->opcode >> 5) & 0x1f) << 16
13497                   | offset) << 2;
13498         op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
13499         gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
13500         n_bytes = 4;
13501         break;
13502     case M16_OPC_BEQZ:
13503         gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
13504                            ((int8_t)ctx->opcode) << 1, 0);
13505         /* No delay slot, so just process as a normal instruction */
13506         break;
13507     case M16_OPC_BNEQZ:
13508         gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
13509                            ((int8_t)ctx->opcode) << 1, 0);
13510         /* No delay slot, so just process as a normal instruction */
13511         break;
13512     case M16_OPC_SHIFT:
13513         switch (ctx->opcode & 0x3) {
13514         case 0x0:
13515             gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
13516             break;
13517         case 0x1:
13518 #if defined(TARGET_MIPS64)
13519             check_insn(ctx, ISA_MIPS3);
13520             check_mips_64(ctx);
13521             gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
13522 #else
13523             generate_exception_end(ctx, EXCP_RI);
13524 #endif
13525             break;
13526         case 0x2:
13527             gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
13528             break;
13529         case 0x3:
13530             gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
13531             break;
13532         }
13533         break;
13534 #if defined(TARGET_MIPS64)
13535     case M16_OPC_LD:
13536         check_insn(ctx, ISA_MIPS3);
13537         check_mips_64(ctx);
13538         gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
13539         break;
13540 #endif
13541     case M16_OPC_RRIA:
13542         {
13543             int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
13544
13545             if ((ctx->opcode >> 4) & 1) {
13546 #if defined(TARGET_MIPS64)
13547                 check_insn(ctx, ISA_MIPS3);
13548                 check_mips_64(ctx);
13549                 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
13550 #else
13551                 generate_exception_end(ctx, EXCP_RI);
13552 #endif
13553             } else {
13554                 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
13555             }
13556         }
13557         break;
13558     case M16_OPC_ADDIU8:
13559         {
13560             int16_t imm = (int8_t) ctx->opcode;
13561
13562             gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
13563         }
13564         break;
13565     case M16_OPC_SLTI:
13566         {
13567             int16_t imm = (uint8_t) ctx->opcode;
13568             gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
13569         }
13570         break;
13571     case M16_OPC_SLTIU:
13572         {
13573             int16_t imm = (uint8_t) ctx->opcode;
13574             gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
13575         }
13576         break;
13577     case M16_OPC_I8:
13578         {
13579             int reg32;
13580
13581             funct = (ctx->opcode >> 8) & 0x7;
13582             switch (funct) {
13583             case I8_BTEQZ:
13584                 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
13585                                    ((int8_t)ctx->opcode) << 1, 0);
13586                 break;
13587             case I8_BTNEZ:
13588                 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
13589                                    ((int8_t)ctx->opcode) << 1, 0);
13590                 break;
13591             case I8_SWRASP:
13592                 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
13593                 break;
13594             case I8_ADJSP:
13595                 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
13596                               ((int8_t)ctx->opcode) << 3);
13597                 break;
13598             case I8_SVRS:
13599                 check_insn(ctx, ISA_MIPS32);
13600                 {
13601                     int do_ra = ctx->opcode & (1 << 6);
13602                     int do_s0 = ctx->opcode & (1 << 5);
13603                     int do_s1 = ctx->opcode & (1 << 4);
13604                     int framesize = ctx->opcode & 0xf;
13605
13606                     if (framesize == 0) {
13607                         framesize = 128;
13608                     } else {
13609                         framesize = framesize << 3;
13610                     }
13611
13612                     if (ctx->opcode & (1 << 7)) {
13613                         gen_mips16_save(ctx, 0, 0,
13614                                         do_ra, do_s0, do_s1, framesize);
13615                     } else {
13616                         gen_mips16_restore(ctx, 0, 0,
13617                                            do_ra, do_s0, do_s1, framesize);
13618                     }
13619                 }
13620                 break;
13621             case I8_MOV32R:
13622                 {
13623                     int rz = xlat(ctx->opcode & 0x7);
13624
13625                     reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
13626                         ((ctx->opcode >> 5) & 0x7);
13627                     gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
13628                 }
13629                 break;
13630             case I8_MOVR32:
13631                 reg32 = ctx->opcode & 0x1f;
13632                 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
13633                 break;
13634             default:
13635                 generate_exception_end(ctx, EXCP_RI);
13636                 break;
13637             }
13638         }
13639         break;
13640     case M16_OPC_LI:
13641         {
13642             int16_t imm = (uint8_t) ctx->opcode;
13643
13644             gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
13645         }
13646         break;
13647     case M16_OPC_CMPI:
13648         {
13649             int16_t imm = (uint8_t) ctx->opcode;
13650             gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
13651         }
13652         break;
13653 #if defined(TARGET_MIPS64)
13654     case M16_OPC_SD:
13655         check_insn(ctx, ISA_MIPS3);
13656         check_mips_64(ctx);
13657         gen_st(ctx, OPC_SD, ry, rx, offset << 3);
13658         break;
13659 #endif
13660     case M16_OPC_LB:
13661         gen_ld(ctx, OPC_LB, ry, rx, offset);
13662         break;
13663     case M16_OPC_LH:
13664         gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
13665         break;
13666     case M16_OPC_LWSP:
13667         gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
13668         break;
13669     case M16_OPC_LW:
13670         gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
13671         break;
13672     case M16_OPC_LBU:
13673         gen_ld(ctx, OPC_LBU, ry, rx, offset);
13674         break;
13675     case M16_OPC_LHU:
13676         gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
13677         break;
13678     case M16_OPC_LWPC:
13679         gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
13680         break;
13681 #if defined (TARGET_MIPS64)
13682     case M16_OPC_LWU:
13683         check_insn(ctx, ISA_MIPS3);
13684         check_mips_64(ctx);
13685         gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
13686         break;
13687 #endif
13688     case M16_OPC_SB:
13689         gen_st(ctx, OPC_SB, ry, rx, offset);
13690         break;
13691     case M16_OPC_SH:
13692         gen_st(ctx, OPC_SH, ry, rx, offset << 1);
13693         break;
13694     case M16_OPC_SWSP:
13695         gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
13696         break;
13697     case M16_OPC_SW:
13698         gen_st(ctx, OPC_SW, ry, rx, offset << 2);
13699         break;
13700     case M16_OPC_RRR:
13701         {
13702             int rz = xlat((ctx->opcode >> 2) & 0x7);
13703             int mips32_op;
13704
13705             switch (ctx->opcode & 0x3) {
13706             case RRR_ADDU:
13707                 mips32_op = OPC_ADDU;
13708                 break;
13709             case RRR_SUBU:
13710                 mips32_op = OPC_SUBU;
13711                 break;
13712 #if defined(TARGET_MIPS64)
13713             case RRR_DADDU:
13714                 mips32_op = OPC_DADDU;
13715                 check_insn(ctx, ISA_MIPS3);
13716                 check_mips_64(ctx);
13717                 break;
13718             case RRR_DSUBU:
13719                 mips32_op = OPC_DSUBU;
13720                 check_insn(ctx, ISA_MIPS3);
13721                 check_mips_64(ctx);
13722                 break;
13723 #endif
13724             default:
13725                 generate_exception_end(ctx, EXCP_RI);
13726                 goto done;
13727             }
13728
13729             gen_arith(ctx, mips32_op, rz, rx, ry);
13730         done:
13731             ;
13732         }
13733         break;
13734     case M16_OPC_RR:
13735         switch (op1) {
13736         case RR_JR:
13737             {
13738                 int nd = (ctx->opcode >> 7) & 0x1;
13739                 int link = (ctx->opcode >> 6) & 0x1;
13740                 int ra = (ctx->opcode >> 5) & 0x1;
13741
13742                 if (nd) {
13743                     check_insn(ctx, ISA_MIPS32);
13744                 }
13745
13746                 if (link) {
13747                     op = OPC_JALR;
13748                 } else {
13749                     op = OPC_JR;
13750                 }
13751
13752                 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
13753                                    (nd ? 0 : 2));
13754             }
13755             break;
13756         case RR_SDBBP:
13757             if (is_uhi(extract32(ctx->opcode, 5, 6))) {
13758                 gen_helper_do_semihosting(cpu_env);
13759             } else {
13760                 /* XXX: not clear which exception should be raised
13761                  *      when in debug mode...
13762                  */
13763                 check_insn(ctx, ISA_MIPS32);
13764                 generate_exception_end(ctx, EXCP_DBp);
13765             }
13766             break;
13767         case RR_SLT:
13768             gen_slt(ctx, OPC_SLT, 24, rx, ry);
13769             break;
13770         case RR_SLTU:
13771             gen_slt(ctx, OPC_SLTU, 24, rx, ry);
13772             break;
13773         case RR_BREAK:
13774             generate_exception_end(ctx, EXCP_BREAK);
13775             break;
13776         case RR_SLLV:
13777             gen_shift(ctx, OPC_SLLV, ry, rx, ry);
13778             break;
13779         case RR_SRLV:
13780             gen_shift(ctx, OPC_SRLV, ry, rx, ry);
13781             break;
13782         case RR_SRAV:
13783             gen_shift(ctx, OPC_SRAV, ry, rx, ry);
13784             break;
13785 #if defined (TARGET_MIPS64)
13786         case RR_DSRL:
13787             check_insn(ctx, ISA_MIPS3);
13788             check_mips_64(ctx);
13789             gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
13790             break;
13791 #endif
13792         case RR_CMP:
13793             gen_logic(ctx, OPC_XOR, 24, rx, ry);
13794             break;
13795         case RR_NEG:
13796             gen_arith(ctx, OPC_SUBU, rx, 0, ry);
13797             break;
13798         case RR_AND:
13799             gen_logic(ctx, OPC_AND, rx, rx, ry);
13800             break;
13801         case RR_OR:
13802             gen_logic(ctx, OPC_OR, rx, rx, ry);
13803             break;
13804         case RR_XOR:
13805             gen_logic(ctx, OPC_XOR, rx, rx, ry);
13806             break;
13807         case RR_NOT:
13808             gen_logic(ctx, OPC_NOR, rx, ry, 0);
13809             break;
13810         case RR_MFHI:
13811             gen_HILO(ctx, OPC_MFHI, 0, rx);
13812             break;
13813         case RR_CNVT:
13814             check_insn(ctx, ISA_MIPS32);
13815             switch (cnvt_op) {
13816             case RR_RY_CNVT_ZEB:
13817                 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13818                 break;
13819             case RR_RY_CNVT_ZEH:
13820                 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13821                 break;
13822             case RR_RY_CNVT_SEB:
13823                 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13824                 break;
13825             case RR_RY_CNVT_SEH:
13826                 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13827                 break;
13828 #if defined (TARGET_MIPS64)
13829             case RR_RY_CNVT_ZEW:
13830                 check_insn(ctx, ISA_MIPS64);
13831                 check_mips_64(ctx);
13832                 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13833                 break;
13834             case RR_RY_CNVT_SEW:
13835                 check_insn(ctx, ISA_MIPS64);
13836                 check_mips_64(ctx);
13837                 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13838                 break;
13839 #endif
13840             default:
13841                 generate_exception_end(ctx, EXCP_RI);
13842                 break;
13843             }
13844             break;
13845         case RR_MFLO:
13846             gen_HILO(ctx, OPC_MFLO, 0, rx);
13847             break;
13848 #if defined (TARGET_MIPS64)
13849         case RR_DSRA:
13850             check_insn(ctx, ISA_MIPS3);
13851             check_mips_64(ctx);
13852             gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
13853             break;
13854         case RR_DSLLV:
13855             check_insn(ctx, ISA_MIPS3);
13856             check_mips_64(ctx);
13857             gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
13858             break;
13859         case RR_DSRLV:
13860             check_insn(ctx, ISA_MIPS3);
13861             check_mips_64(ctx);
13862             gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
13863             break;
13864         case RR_DSRAV:
13865             check_insn(ctx, ISA_MIPS3);
13866             check_mips_64(ctx);
13867             gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
13868             break;
13869 #endif
13870         case RR_MULT:
13871             gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
13872             break;
13873         case RR_MULTU:
13874             gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
13875             break;
13876         case RR_DIV:
13877             gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
13878             break;
13879         case RR_DIVU:
13880             gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
13881             break;
13882 #if defined (TARGET_MIPS64)
13883         case RR_DMULT:
13884             check_insn(ctx, ISA_MIPS3);
13885             check_mips_64(ctx);
13886             gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
13887             break;
13888         case RR_DMULTU:
13889             check_insn(ctx, ISA_MIPS3);
13890             check_mips_64(ctx);
13891             gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
13892             break;
13893         case RR_DDIV:
13894             check_insn(ctx, ISA_MIPS3);
13895             check_mips_64(ctx);
13896             gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
13897             break;
13898         case RR_DDIVU:
13899             check_insn(ctx, ISA_MIPS3);
13900             check_mips_64(ctx);
13901             gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
13902             break;
13903 #endif
13904         default:
13905             generate_exception_end(ctx, EXCP_RI);
13906             break;
13907         }
13908         break;
13909     case M16_OPC_EXTEND:
13910         decode_extended_mips16_opc(env, ctx);
13911         n_bytes = 4;
13912         break;
13913 #if defined(TARGET_MIPS64)
13914     case M16_OPC_I64:
13915         funct = (ctx->opcode >> 8) & 0x7;
13916         decode_i64_mips16(ctx, ry, funct, offset, 0);
13917         break;
13918 #endif
13919     default:
13920         generate_exception_end(ctx, EXCP_RI);
13921         break;
13922     }
13923
13924     return n_bytes;
13925 }
13926
13927 /* microMIPS extension to MIPS32/MIPS64 */
13928
13929 /*
13930  * microMIPS32/microMIPS64 major opcodes
13931  *
13932  * 1. MIPS Architecture for Programmers Volume II-B:
13933  *      The microMIPS32 Instruction Set (Revision 3.05)
13934  *
13935  *    Table 6.2 microMIPS32 Encoding of Major Opcode Field
13936  *
13937  * 2. MIPS Architecture For Programmers Volume II-A:
13938  *      The MIPS64 Instruction Set (Revision 3.51)
13939  */
13940
13941 enum {
13942     POOL32A = 0x00,
13943     POOL16A = 0x01,
13944     LBU16 = 0x02,
13945     MOVE16 = 0x03,
13946     ADDI32 = 0x04,
13947     R6_LUI = 0x04,
13948     AUI = 0x04,
13949     LBU32 = 0x05,
13950     SB32 = 0x06,
13951     LB32 = 0x07,
13952
13953     POOL32B = 0x08,
13954     POOL16B = 0x09,
13955     LHU16 = 0x0a,
13956     ANDI16 = 0x0b,
13957     ADDIU32 = 0x0c,
13958     LHU32 = 0x0d,
13959     SH32 = 0x0e,
13960     LH32 = 0x0f,
13961
13962     POOL32I = 0x10,
13963     POOL16C = 0x11,
13964     LWSP16 = 0x12,
13965     POOL16D = 0x13,
13966     ORI32 = 0x14,
13967     POOL32F = 0x15,
13968     POOL32S = 0x16,  /* MIPS64 */
13969     DADDIU32 = 0x17, /* MIPS64 */
13970
13971     POOL32C = 0x18,
13972     LWGP16 = 0x19,
13973     LW16 = 0x1a,
13974     POOL16E = 0x1b,
13975     XORI32 = 0x1c,
13976     JALS32 = 0x1d,
13977     BOVC = 0x1d,
13978     BEQC = 0x1d,
13979     BEQZALC = 0x1d,
13980     ADDIUPC = 0x1e,
13981     PCREL = 0x1e,
13982     BNVC = 0x1f,
13983     BNEC = 0x1f,
13984     BNEZALC = 0x1f,
13985
13986     R6_BEQZC = 0x20,
13987     JIC = 0x20,
13988     POOL16F = 0x21,
13989     SB16 = 0x22,
13990     BEQZ16 = 0x23,
13991     BEQZC16 = 0x23,
13992     SLTI32 = 0x24,
13993     BEQ32 = 0x25,
13994     BC = 0x25,
13995     SWC132 = 0x26,
13996     LWC132 = 0x27,
13997
13998     /* 0x29 is reserved */
13999     RES_29 = 0x29,
14000     R6_BNEZC = 0x28,
14001     JIALC = 0x28,
14002     SH16 = 0x2a,
14003     BNEZ16 = 0x2b,
14004     BNEZC16 = 0x2b,
14005     SLTIU32 = 0x2c,
14006     BNE32 = 0x2d,
14007     BALC = 0x2d,
14008     SDC132 = 0x2e,
14009     LDC132 = 0x2f,
14010
14011     /* 0x31 is reserved */
14012     RES_31 = 0x31,
14013     BLEZALC = 0x30,
14014     BGEZALC = 0x30,
14015     BGEUC = 0x30,
14016     SWSP16 = 0x32,
14017     B16 = 0x33,
14018     BC16 = 0x33,
14019     ANDI32 = 0x34,
14020     J32 = 0x35,
14021     BGTZC = 0x35,
14022     BLTZC = 0x35,
14023     BLTC = 0x35,
14024     SD32 = 0x36, /* MIPS64 */
14025     LD32 = 0x37, /* MIPS64 */
14026
14027     /* 0x39 is reserved */
14028     RES_39 = 0x39,
14029     BGTZALC = 0x38,
14030     BLTZALC = 0x38,
14031     BLTUC = 0x38,
14032     SW16 = 0x3a,
14033     LI16 = 0x3b,
14034     JALX32 = 0x3c,
14035     JAL32 = 0x3d,
14036     BLEZC = 0x3d,
14037     BGEZC = 0x3d,
14038     BGEC = 0x3d,
14039     SW32 = 0x3e,
14040     LW32 = 0x3f
14041 };
14042
14043 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
14044 enum {
14045     ADDIUPC_00 = 0x00,
14046     ADDIUPC_01 = 0x01,
14047     ADDIUPC_02 = 0x02,
14048     ADDIUPC_03 = 0x03,
14049     ADDIUPC_04 = 0x04,
14050     ADDIUPC_05 = 0x05,
14051     ADDIUPC_06 = 0x06,
14052     ADDIUPC_07 = 0x07,
14053     AUIPC = 0x1e,
14054     ALUIPC = 0x1f,
14055     LWPC_08 = 0x08,
14056     LWPC_09 = 0x09,
14057     LWPC_0A = 0x0A,
14058     LWPC_0B = 0x0B,
14059     LWPC_0C = 0x0C,
14060     LWPC_0D = 0x0D,
14061     LWPC_0E = 0x0E,
14062     LWPC_0F = 0x0F,
14063 };
14064
14065 /* POOL32A encoding of minor opcode field */
14066
14067 enum {
14068     /* These opcodes are distinguished only by bits 9..6; those bits are
14069      * what are recorded below. */
14070     SLL32 = 0x0,
14071     SRL32 = 0x1,
14072     SRA = 0x2,
14073     ROTR = 0x3,
14074     SELEQZ = 0x5,
14075     SELNEZ = 0x6,
14076     R6_RDHWR = 0x7,
14077
14078     SLLV = 0x0,
14079     SRLV = 0x1,
14080     SRAV = 0x2,
14081     ROTRV = 0x3,
14082     ADD = 0x4,
14083     ADDU32 = 0x5,
14084     SUB = 0x6,
14085     SUBU32 = 0x7,
14086     MUL = 0x8,
14087     AND = 0x9,
14088     OR32 = 0xa,
14089     NOR = 0xb,
14090     XOR32 = 0xc,
14091     SLT = 0xd,
14092     SLTU = 0xe,
14093
14094     MOVN = 0x0,
14095     R6_MUL  = 0x0,
14096     MOVZ = 0x1,
14097     MUH  = 0x1,
14098     MULU = 0x2,
14099     MUHU = 0x3,
14100     LWXS = 0x4,
14101     R6_DIV  = 0x4,
14102     MOD  = 0x5,
14103     R6_DIVU = 0x6,
14104     MODU = 0x7,
14105
14106     /* The following can be distinguished by their lower 6 bits. */
14107     BREAK32 = 0x07,
14108     INS = 0x0c,
14109     LSA = 0x0f,
14110     ALIGN = 0x1f,
14111     EXT = 0x2c,
14112     POOL32AXF = 0x3c,
14113     SIGRIE = 0x3f
14114 };
14115
14116 /* POOL32AXF encoding of minor opcode field extension */
14117
14118 /*
14119  * 1. MIPS Architecture for Programmers Volume II-B:
14120  *      The microMIPS32 Instruction Set (Revision 3.05)
14121  *
14122  *    Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
14123  *
14124  * 2. MIPS Architecture for Programmers VolumeIV-e:
14125  *      The MIPS DSP Application-Specific Extension
14126  *        to the microMIPS32 Architecture (Revision 2.34)
14127  *
14128  *    Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
14129  */
14130
14131 enum {
14132     /* bits 11..6 */
14133     TEQ = 0x00,
14134     TGE = 0x08,
14135     TGEU = 0x10,
14136     TLT = 0x20,
14137     TLTU = 0x28,
14138     TNE = 0x30,
14139
14140     MFC0 = 0x03,
14141     MTC0 = 0x0b,
14142
14143     /* begin of microMIPS32 DSP */
14144
14145     /* bits 13..12 for 0x01 */
14146     MFHI_ACC = 0x0,
14147     MFLO_ACC = 0x1,
14148     MTHI_ACC = 0x2,
14149     MTLO_ACC = 0x3,
14150
14151     /* bits 13..12 for 0x2a */
14152     MADD_ACC = 0x0,
14153     MADDU_ACC = 0x1,
14154     MSUB_ACC = 0x2,
14155     MSUBU_ACC = 0x3,
14156
14157     /* bits 13..12 for 0x32 */
14158     MULT_ACC = 0x0,
14159     MULTU_ACC = 0x1,
14160
14161     /* end of microMIPS32 DSP */
14162
14163     /* bits 15..12 for 0x2c */
14164     BITSWAP = 0x0,
14165     SEB = 0x2,
14166     SEH = 0x3,
14167     CLO = 0x4,
14168     CLZ = 0x5,
14169     RDHWR = 0x6,
14170     WSBH = 0x7,
14171     MULT = 0x8,
14172     MULTU = 0x9,
14173     DIV = 0xa,
14174     DIVU = 0xb,
14175     MADD = 0xc,
14176     MADDU = 0xd,
14177     MSUB = 0xe,
14178     MSUBU = 0xf,
14179
14180     /* bits 15..12 for 0x34 */
14181     MFC2 = 0x4,
14182     MTC2 = 0x5,
14183     MFHC2 = 0x8,
14184     MTHC2 = 0x9,
14185     CFC2 = 0xc,
14186     CTC2 = 0xd,
14187
14188     /* bits 15..12 for 0x3c */
14189     JALR = 0x0,
14190     JR = 0x0,                   /* alias */
14191     JALRC = 0x0,
14192     JRC = 0x0,
14193     JALR_HB = 0x1,
14194     JALRC_HB = 0x1,
14195     JALRS = 0x4,
14196     JALRS_HB = 0x5,
14197
14198     /* bits 15..12 for 0x05 */
14199     RDPGPR = 0xe,
14200     WRPGPR = 0xf,
14201
14202     /* bits 15..12 for 0x0d */
14203     TLBP = 0x0,
14204     TLBR = 0x1,
14205     TLBWI = 0x2,
14206     TLBWR = 0x3,
14207     TLBINV = 0x4,
14208     TLBINVF = 0x5,
14209     WAIT = 0x9,
14210     IRET = 0xd,
14211     DERET = 0xe,
14212     ERET = 0xf,
14213
14214     /* bits 15..12 for 0x15 */
14215     DMT = 0x0,
14216     DVPE = 0x1,
14217     EMT = 0x2,
14218     EVPE = 0x3,
14219
14220     /* bits 15..12 for 0x1d */
14221     DI = 0x4,
14222     EI = 0x5,
14223
14224     /* bits 15..12 for 0x2d */
14225     SYNC = 0x6,
14226     SYSCALL = 0x8,
14227     SDBBP = 0xd,
14228
14229     /* bits 15..12 for 0x35 */
14230     MFHI32 = 0x0,
14231     MFLO32 = 0x1,
14232     MTHI32 = 0x2,
14233     MTLO32 = 0x3,
14234 };
14235
14236 /* POOL32B encoding of minor opcode field (bits 15..12) */
14237
14238 enum {
14239     LWC2 = 0x0,
14240     LWP = 0x1,
14241     LDP = 0x4,
14242     LWM32 = 0x5,
14243     CACHE = 0x6,
14244     LDM = 0x7,
14245     SWC2 = 0x8,
14246     SWP = 0x9,
14247     SDP = 0xc,
14248     SWM32 = 0xd,
14249     SDM = 0xf
14250 };
14251
14252 /* POOL32C encoding of minor opcode field (bits 15..12) */
14253
14254 enum {
14255     LWL = 0x0,
14256     SWL = 0x8,
14257     LWR = 0x1,
14258     SWR = 0x9,
14259     PREF = 0x2,
14260     ST_EVA = 0xa,
14261     LL = 0x3,
14262     SC = 0xb,
14263     LDL = 0x4,
14264     SDL = 0xc,
14265     LDR = 0x5,
14266     SDR = 0xd,
14267     LD_EVA = 0x6,
14268     LWU = 0xe,
14269     LLD = 0x7,
14270     SCD = 0xf
14271 };
14272
14273 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
14274
14275 enum {
14276     LBUE = 0x0,
14277     LHUE = 0x1,
14278     LWLE = 0x2,
14279     LWRE = 0x3,
14280     LBE = 0x4,
14281     LHE = 0x5,
14282     LLE = 0x6,
14283     LWE = 0x7,
14284 };
14285
14286 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
14287
14288 enum {
14289     SWLE = 0x0,
14290     SWRE = 0x1,
14291     PREFE = 0x2,
14292     CACHEE = 0x3,
14293     SBE = 0x4,
14294     SHE = 0x5,
14295     SCE = 0x6,
14296     SWE = 0x7,
14297 };
14298
14299 /* POOL32F encoding of minor opcode field (bits 5..0) */
14300
14301 enum {
14302     /* These are the bit 7..6 values */
14303     ADD_FMT = 0x0,
14304
14305     SUB_FMT = 0x1,
14306
14307     MUL_FMT = 0x2,
14308
14309     DIV_FMT = 0x3,
14310
14311     /* These are the bit 8..6 values */
14312     MOVN_FMT = 0x0,
14313     RSQRT2_FMT = 0x0,
14314     MOVF_FMT = 0x0,
14315     RINT_FMT = 0x0,
14316     SELNEZ_FMT = 0x0,
14317
14318     MOVZ_FMT = 0x1,
14319     LWXC1 = 0x1,
14320     MOVT_FMT = 0x1,
14321     CLASS_FMT = 0x1,
14322     SELEQZ_FMT = 0x1,
14323
14324     PLL_PS = 0x2,
14325     SWXC1 = 0x2,
14326     SEL_FMT = 0x2,
14327
14328     PLU_PS = 0x3,
14329     LDXC1 = 0x3,
14330
14331     MOVN_FMT_04 = 0x4,
14332     PUL_PS = 0x4,
14333     SDXC1 = 0x4,
14334     RECIP2_FMT = 0x4,
14335
14336     MOVZ_FMT_05 = 0x05,
14337     PUU_PS = 0x5,
14338     LUXC1 = 0x5,
14339
14340     CVT_PS_S = 0x6,
14341     SUXC1 = 0x6,
14342     ADDR_PS = 0x6,
14343     PREFX = 0x6,
14344     MADDF_FMT = 0x6,
14345
14346     MULR_PS = 0x7,
14347     MSUBF_FMT = 0x7,
14348
14349     MADD_S = 0x01,
14350     MADD_D = 0x09,
14351     MADD_PS = 0x11,
14352     ALNV_PS = 0x19,
14353     MSUB_S = 0x21,
14354     MSUB_D = 0x29,
14355     MSUB_PS = 0x31,
14356
14357     NMADD_S = 0x02,
14358     NMADD_D = 0x0a,
14359     NMADD_PS = 0x12,
14360     NMSUB_S = 0x22,
14361     NMSUB_D = 0x2a,
14362     NMSUB_PS = 0x32,
14363
14364     MIN_FMT = 0x3,
14365     MAX_FMT = 0xb,
14366     MINA_FMT = 0x23,
14367     MAXA_FMT = 0x2b,
14368     POOL32FXF = 0x3b,
14369
14370     CABS_COND_FMT = 0x1c,              /* MIPS3D */
14371     C_COND_FMT = 0x3c,
14372
14373     CMP_CONDN_S = 0x5,
14374     CMP_CONDN_D = 0x15
14375 };
14376
14377 /* POOL32Fxf encoding of minor opcode extension field */
14378
14379 enum {
14380     CVT_L = 0x04,
14381     RSQRT_FMT = 0x08,
14382     FLOOR_L = 0x0c,
14383     CVT_PW_PS = 0x1c,
14384     CVT_W = 0x24,
14385     SQRT_FMT = 0x28,
14386     FLOOR_W = 0x2c,
14387     CVT_PS_PW = 0x3c,
14388     CFC1 = 0x40,
14389     RECIP_FMT = 0x48,
14390     CEIL_L = 0x4c,
14391     CTC1 = 0x60,
14392     CEIL_W = 0x6c,
14393     MFC1 = 0x80,
14394     CVT_S_PL = 0x84,
14395     TRUNC_L = 0x8c,
14396     MTC1 = 0xa0,
14397     CVT_S_PU = 0xa4,
14398     TRUNC_W = 0xac,
14399     MFHC1 = 0xc0,
14400     ROUND_L = 0xcc,
14401     MTHC1 = 0xe0,
14402     ROUND_W = 0xec,
14403
14404     MOV_FMT = 0x01,
14405     MOVF = 0x05,
14406     ABS_FMT = 0x0d,
14407     RSQRT1_FMT = 0x1d,
14408     MOVT = 0x25,
14409     NEG_FMT = 0x2d,
14410     CVT_D = 0x4d,
14411     RECIP1_FMT = 0x5d,
14412     CVT_S = 0x6d
14413 };
14414
14415 /* POOL32I encoding of minor opcode field (bits 25..21) */
14416
14417 enum {
14418     BLTZ = 0x00,
14419     BLTZAL = 0x01,
14420     BGEZ = 0x02,
14421     BGEZAL = 0x03,
14422     BLEZ = 0x04,
14423     BNEZC = 0x05,
14424     BGTZ = 0x06,
14425     BEQZC = 0x07,
14426     TLTI = 0x08,
14427     BC1EQZC = 0x08,
14428     TGEI = 0x09,
14429     BC1NEZC = 0x09,
14430     TLTIU = 0x0a,
14431     BC2EQZC = 0x0a,
14432     TGEIU = 0x0b,
14433     BC2NEZC = 0x0a,
14434     TNEI = 0x0c,
14435     R6_SYNCI = 0x0c,
14436     LUI = 0x0d,
14437     TEQI = 0x0e,
14438     SYNCI = 0x10,
14439     BLTZALS = 0x11,
14440     BGEZALS = 0x13,
14441     BC2F = 0x14,
14442     BC2T = 0x15,
14443     BPOSGE64 = 0x1a,
14444     BPOSGE32 = 0x1b,
14445     /* These overlap and are distinguished by bit16 of the instruction */
14446     BC1F = 0x1c,
14447     BC1T = 0x1d,
14448     BC1ANY2F = 0x1c,
14449     BC1ANY2T = 0x1d,
14450     BC1ANY4F = 0x1e,
14451     BC1ANY4T = 0x1f
14452 };
14453
14454 /* POOL16A encoding of minor opcode field */
14455
14456 enum {
14457     ADDU16 = 0x0,
14458     SUBU16 = 0x1
14459 };
14460
14461 /* POOL16B encoding of minor opcode field */
14462
14463 enum {
14464     SLL16 = 0x0,
14465     SRL16 = 0x1
14466 };
14467
14468 /* POOL16C encoding of minor opcode field */
14469
14470 enum {
14471     NOT16 = 0x00,
14472     XOR16 = 0x04,
14473     AND16 = 0x08,
14474     OR16 = 0x0c,
14475     LWM16 = 0x10,
14476     SWM16 = 0x14,
14477     JR16 = 0x18,
14478     JRC16 = 0x1a,
14479     JALR16 = 0x1c,
14480     JALR16S = 0x1e,
14481     MFHI16 = 0x20,
14482     MFLO16 = 0x24,
14483     BREAK16 = 0x28,
14484     SDBBP16 = 0x2c,
14485     JRADDIUSP = 0x30
14486 };
14487
14488 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
14489
14490 enum {
14491     R6_NOT16    = 0x00,
14492     R6_AND16    = 0x01,
14493     R6_LWM16    = 0x02,
14494     R6_JRC16    = 0x03,
14495     MOVEP       = 0x04,
14496     MOVEP_05    = 0x05,
14497     MOVEP_06    = 0x06,
14498     MOVEP_07    = 0x07,
14499     R6_XOR16    = 0x08,
14500     R6_OR16     = 0x09,
14501     R6_SWM16    = 0x0a,
14502     JALRC16     = 0x0b,
14503     MOVEP_0C    = 0x0c,
14504     MOVEP_0D    = 0x0d,
14505     MOVEP_0E    = 0x0e,
14506     MOVEP_0F    = 0x0f,
14507     JRCADDIUSP  = 0x13,
14508     R6_BREAK16  = 0x1b,
14509     R6_SDBBP16  = 0x3b
14510 };
14511
14512 /* POOL16D encoding of minor opcode field */
14513
14514 enum {
14515     ADDIUS5 = 0x0,
14516     ADDIUSP = 0x1
14517 };
14518
14519 /* POOL16E encoding of minor opcode field */
14520
14521 enum {
14522     ADDIUR2 = 0x0,
14523     ADDIUR1SP = 0x1
14524 };
14525
14526 static int mmreg (int r)
14527 {
14528     static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
14529
14530     return map[r];
14531 }
14532
14533 /* Used for 16-bit store instructions.  */
14534 static int mmreg2 (int r)
14535 {
14536     static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
14537
14538     return map[r];
14539 }
14540
14541 #define uMIPS_RD(op) ((op >> 7) & 0x7)
14542 #define uMIPS_RS(op) ((op >> 4) & 0x7)
14543 #define uMIPS_RS2(op) uMIPS_RS(op)
14544 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
14545 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
14546 #define uMIPS_RS5(op) (op & 0x1f)
14547
14548 /* Signed immediate */
14549 #define SIMM(op, start, width)                                          \
14550     ((int32_t)(((op >> start) & ((~0U) >> (32-width)))                 \
14551                << (32-width))                                           \
14552      >> (32-width))
14553 /* Zero-extended immediate */
14554 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
14555
14556 static void gen_addiur1sp(DisasContext *ctx)
14557 {
14558     int rd = mmreg(uMIPS_RD(ctx->opcode));
14559
14560     gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
14561 }
14562
14563 static void gen_addiur2(DisasContext *ctx)
14564 {
14565     static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
14566     int rd = mmreg(uMIPS_RD(ctx->opcode));
14567     int rs = mmreg(uMIPS_RS(ctx->opcode));
14568
14569     gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
14570 }
14571
14572 static void gen_addiusp(DisasContext *ctx)
14573 {
14574     int encoded = ZIMM(ctx->opcode, 1, 9);
14575     int decoded;
14576
14577     if (encoded <= 1) {
14578         decoded = 256 + encoded;
14579     } else if (encoded <= 255) {
14580         decoded = encoded;
14581     } else if (encoded <= 509) {
14582         decoded = encoded - 512;
14583     } else {
14584         decoded = encoded - 768;
14585     }
14586
14587     gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
14588 }
14589
14590 static void gen_addius5(DisasContext *ctx)
14591 {
14592     int imm = SIMM(ctx->opcode, 1, 4);
14593     int rd = (ctx->opcode >> 5) & 0x1f;
14594
14595     gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
14596 }
14597
14598 static void gen_andi16(DisasContext *ctx)
14599 {
14600     static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
14601                                  31, 32, 63, 64, 255, 32768, 65535 };
14602     int rd = mmreg(uMIPS_RD(ctx->opcode));
14603     int rs = mmreg(uMIPS_RS(ctx->opcode));
14604     int encoded = ZIMM(ctx->opcode, 0, 4);
14605
14606     gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
14607 }
14608
14609 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
14610                                int base, int16_t offset)
14611 {
14612     TCGv t0, t1;
14613     TCGv_i32 t2;
14614
14615     if (ctx->hflags & MIPS_HFLAG_BMASK) {
14616         generate_exception_end(ctx, EXCP_RI);
14617         return;
14618     }
14619
14620     t0 = tcg_temp_new();
14621
14622     gen_base_offset_addr(ctx, t0, base, offset);
14623
14624     t1 = tcg_const_tl(reglist);
14625     t2 = tcg_const_i32(ctx->mem_idx);
14626
14627     save_cpu_state(ctx, 1);
14628     switch (opc) {
14629     case LWM32:
14630         gen_helper_lwm(cpu_env, t0, t1, t2);
14631         break;
14632     case SWM32:
14633         gen_helper_swm(cpu_env, t0, t1, t2);
14634         break;
14635 #ifdef TARGET_MIPS64
14636     case LDM:
14637         gen_helper_ldm(cpu_env, t0, t1, t2);
14638         break;
14639     case SDM:
14640         gen_helper_sdm(cpu_env, t0, t1, t2);
14641         break;
14642 #endif
14643     }
14644     tcg_temp_free(t0);
14645     tcg_temp_free(t1);
14646     tcg_temp_free_i32(t2);
14647 }
14648
14649
14650 static void gen_pool16c_insn(DisasContext *ctx)
14651 {
14652     int rd = mmreg((ctx->opcode >> 3) & 0x7);
14653     int rs = mmreg(ctx->opcode & 0x7);
14654
14655     switch (((ctx->opcode) >> 4) & 0x3f) {
14656     case NOT16 + 0:
14657     case NOT16 + 1:
14658     case NOT16 + 2:
14659     case NOT16 + 3:
14660         gen_logic(ctx, OPC_NOR, rd, rs, 0);
14661         break;
14662     case XOR16 + 0:
14663     case XOR16 + 1:
14664     case XOR16 + 2:
14665     case XOR16 + 3:
14666         gen_logic(ctx, OPC_XOR, rd, rd, rs);
14667         break;
14668     case AND16 + 0:
14669     case AND16 + 1:
14670     case AND16 + 2:
14671     case AND16 + 3:
14672         gen_logic(ctx, OPC_AND, rd, rd, rs);
14673         break;
14674     case OR16 + 0:
14675     case OR16 + 1:
14676     case OR16 + 2:
14677     case OR16 + 3:
14678         gen_logic(ctx, OPC_OR, rd, rd, rs);
14679         break;
14680     case LWM16 + 0:
14681     case LWM16 + 1:
14682     case LWM16 + 2:
14683     case LWM16 + 3:
14684         {
14685             static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14686             int offset = ZIMM(ctx->opcode, 0, 4);
14687
14688             gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
14689                               29, offset << 2);
14690         }
14691         break;
14692     case SWM16 + 0:
14693     case SWM16 + 1:
14694     case SWM16 + 2:
14695     case SWM16 + 3:
14696         {
14697             static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14698             int offset = ZIMM(ctx->opcode, 0, 4);
14699
14700             gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
14701                               29, offset << 2);
14702         }
14703         break;
14704     case JR16 + 0:
14705     case JR16 + 1:
14706         {
14707             int reg = ctx->opcode & 0x1f;
14708
14709             gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
14710         }
14711         break;
14712     case JRC16 + 0:
14713     case JRC16 + 1:
14714         {
14715             int reg = ctx->opcode & 0x1f;
14716             gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
14717             /* Let normal delay slot handling in our caller take us
14718                to the branch target.  */
14719         }
14720         break;
14721     case JALR16 + 0:
14722     case JALR16 + 1:
14723         gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
14724         ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14725         break;
14726     case JALR16S + 0:
14727     case JALR16S + 1:
14728         gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
14729         ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14730         break;
14731     case MFHI16 + 0:
14732     case MFHI16 + 1:
14733         gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
14734         break;
14735     case MFLO16 + 0:
14736     case MFLO16 + 1:
14737         gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
14738         break;
14739     case BREAK16:
14740         generate_exception_end(ctx, EXCP_BREAK);
14741         break;
14742     case SDBBP16:
14743         if (is_uhi(extract32(ctx->opcode, 0, 4))) {
14744             gen_helper_do_semihosting(cpu_env);
14745         } else {
14746             /* XXX: not clear which exception should be raised
14747              *      when in debug mode...
14748              */
14749             check_insn(ctx, ISA_MIPS32);
14750             generate_exception_end(ctx, EXCP_DBp);
14751         }
14752         break;
14753     case JRADDIUSP + 0:
14754     case JRADDIUSP + 1:
14755         {
14756             int imm = ZIMM(ctx->opcode, 0, 5);
14757             gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
14758             gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
14759             /* Let normal delay slot handling in our caller take us
14760                to the branch target.  */
14761         }
14762         break;
14763     default:
14764         generate_exception_end(ctx, EXCP_RI);
14765         break;
14766     }
14767 }
14768
14769 static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
14770                              int enc_rs)
14771 {
14772     int rd, rs, re, rt;
14773     static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
14774     static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
14775     static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
14776     rd = rd_enc[enc_dest];
14777     re = re_enc[enc_dest];
14778     rs = rs_rt_enc[enc_rs];
14779     rt = rs_rt_enc[enc_rt];
14780     if (rs) {
14781         tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
14782     } else {
14783         tcg_gen_movi_tl(cpu_gpr[rd], 0);
14784     }
14785     if (rt) {
14786         tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
14787     } else {
14788         tcg_gen_movi_tl(cpu_gpr[re], 0);
14789     }
14790 }
14791
14792 static void gen_pool16c_r6_insn(DisasContext *ctx)
14793 {
14794     int rt = mmreg((ctx->opcode >> 7) & 0x7);
14795     int rs = mmreg((ctx->opcode >> 4) & 0x7);
14796
14797     switch (ctx->opcode & 0xf) {
14798     case R6_NOT16:
14799         gen_logic(ctx, OPC_NOR, rt, rs, 0);
14800         break;
14801     case R6_AND16:
14802         gen_logic(ctx, OPC_AND, rt, rt, rs);
14803         break;
14804     case R6_LWM16:
14805         {
14806             int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
14807             int offset = extract32(ctx->opcode, 4, 4);
14808             gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
14809         }
14810         break;
14811     case R6_JRC16: /* JRCADDIUSP */
14812         if ((ctx->opcode >> 4) & 1) {
14813             /* JRCADDIUSP */
14814             int imm = extract32(ctx->opcode, 5, 5);
14815             gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
14816             gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
14817         } else {
14818             /* JRC16 */
14819             rs = extract32(ctx->opcode, 5, 5);
14820             gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
14821         }
14822         break;
14823     case MOVEP:
14824     case MOVEP_05:
14825     case MOVEP_06:
14826     case MOVEP_07:
14827     case MOVEP_0C:
14828     case MOVEP_0D:
14829     case MOVEP_0E:
14830     case MOVEP_0F:
14831         {
14832             int enc_dest = uMIPS_RD(ctx->opcode);
14833             int enc_rt = uMIPS_RS2(ctx->opcode);
14834             int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
14835             gen_movep(ctx, enc_dest, enc_rt, enc_rs);
14836         }
14837         break;
14838     case R6_XOR16:
14839         gen_logic(ctx, OPC_XOR, rt, rt, rs);
14840         break;
14841     case R6_OR16:
14842         gen_logic(ctx, OPC_OR, rt, rt, rs);
14843         break;
14844     case R6_SWM16:
14845         {
14846             int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
14847             int offset = extract32(ctx->opcode, 4, 4);
14848             gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
14849         }
14850         break;
14851     case JALRC16: /* BREAK16, SDBBP16 */
14852         switch (ctx->opcode & 0x3f) {
14853         case JALRC16:
14854         case JALRC16 + 0x20:
14855             /* JALRC16 */
14856             gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
14857                                31, 0, 0);
14858             break;
14859         case R6_BREAK16:
14860             /* BREAK16 */
14861             generate_exception(ctx, EXCP_BREAK);
14862             break;
14863         case R6_SDBBP16:
14864             /* SDBBP16 */
14865             if (is_uhi(extract32(ctx->opcode, 6, 4))) {
14866                 gen_helper_do_semihosting(cpu_env);
14867             } else {
14868                 if (ctx->hflags & MIPS_HFLAG_SBRI) {
14869                     generate_exception(ctx, EXCP_RI);
14870                 } else {
14871                     generate_exception(ctx, EXCP_DBp);
14872                 }
14873             }
14874             break;
14875         }
14876         break;
14877     default:
14878         generate_exception(ctx, EXCP_RI);
14879         break;
14880     }
14881 }
14882
14883 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
14884 {
14885     TCGv t0 = tcg_temp_new();
14886     TCGv t1 = tcg_temp_new();
14887
14888     gen_load_gpr(t0, base);
14889
14890     if (index != 0) {
14891         gen_load_gpr(t1, index);
14892         tcg_gen_shli_tl(t1, t1, 2);
14893         gen_op_addr_add(ctx, t0, t1, t0);
14894     }
14895
14896     tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
14897     gen_store_gpr(t1, rd);
14898
14899     tcg_temp_free(t0);
14900     tcg_temp_free(t1);
14901 }
14902
14903 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
14904                            int base, int16_t offset)
14905 {
14906     TCGv t0, t1;
14907
14908     if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
14909         generate_exception_end(ctx, EXCP_RI);
14910         return;
14911     }
14912
14913     t0 = tcg_temp_new();
14914     t1 = tcg_temp_new();
14915
14916     gen_base_offset_addr(ctx, t0, base, offset);
14917
14918     switch (opc) {
14919     case LWP:
14920         if (rd == base) {
14921             generate_exception_end(ctx, EXCP_RI);
14922             return;
14923         }
14924         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
14925         gen_store_gpr(t1, rd);
14926         tcg_gen_movi_tl(t1, 4);
14927         gen_op_addr_add(ctx, t0, t0, t1);
14928         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
14929         gen_store_gpr(t1, rd+1);
14930         break;
14931     case SWP:
14932         gen_load_gpr(t1, rd);
14933         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
14934         tcg_gen_movi_tl(t1, 4);
14935         gen_op_addr_add(ctx, t0, t0, t1);
14936         gen_load_gpr(t1, rd+1);
14937         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
14938         break;
14939 #ifdef TARGET_MIPS64
14940     case LDP:
14941         if (rd == base) {
14942             generate_exception_end(ctx, EXCP_RI);
14943             return;
14944         }
14945         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14946         gen_store_gpr(t1, rd);
14947         tcg_gen_movi_tl(t1, 8);
14948         gen_op_addr_add(ctx, t0, t0, t1);
14949         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14950         gen_store_gpr(t1, rd+1);
14951         break;
14952     case SDP:
14953         gen_load_gpr(t1, rd);
14954         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14955         tcg_gen_movi_tl(t1, 8);
14956         gen_op_addr_add(ctx, t0, t0, t1);
14957         gen_load_gpr(t1, rd+1);
14958         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14959         break;
14960 #endif
14961     }
14962     tcg_temp_free(t0);
14963     tcg_temp_free(t1);
14964 }
14965
14966 static void gen_sync(int stype)
14967 {
14968     TCGBar tcg_mo = TCG_BAR_SC;
14969
14970     switch (stype) {
14971     case 0x4: /* SYNC_WMB */
14972         tcg_mo |= TCG_MO_ST_ST;
14973         break;
14974     case 0x10: /* SYNC_MB */
14975         tcg_mo |= TCG_MO_ALL;
14976         break;
14977     case 0x11: /* SYNC_ACQUIRE */
14978         tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
14979         break;
14980     case 0x12: /* SYNC_RELEASE */
14981         tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
14982         break;
14983     case 0x13: /* SYNC_RMB */
14984         tcg_mo |= TCG_MO_LD_LD;
14985         break;
14986     default:
14987         tcg_mo |= TCG_MO_ALL;
14988         break;
14989     }
14990
14991     tcg_gen_mb(tcg_mo);
14992 }
14993
14994 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
14995 {
14996     int extension = (ctx->opcode >> 6) & 0x3f;
14997     int minor = (ctx->opcode >> 12) & 0xf;
14998     uint32_t mips32_op;
14999
15000     switch (extension) {
15001     case TEQ:
15002         mips32_op = OPC_TEQ;
15003         goto do_trap;
15004     case TGE:
15005         mips32_op = OPC_TGE;
15006         goto do_trap;
15007     case TGEU:
15008         mips32_op = OPC_TGEU;
15009         goto do_trap;
15010     case TLT:
15011         mips32_op = OPC_TLT;
15012         goto do_trap;
15013     case TLTU:
15014         mips32_op = OPC_TLTU;
15015         goto do_trap;
15016     case TNE:
15017         mips32_op = OPC_TNE;
15018     do_trap:
15019         gen_trap(ctx, mips32_op, rs, rt, -1);
15020         break;
15021 #ifndef CONFIG_USER_ONLY
15022     case MFC0:
15023     case MFC0 + 32:
15024         check_cp0_enabled(ctx);
15025         if (rt == 0) {
15026             /* Treat as NOP. */
15027             break;
15028         }
15029         gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
15030         break;
15031     case MTC0:
15032     case MTC0 + 32:
15033         check_cp0_enabled(ctx);
15034         {
15035             TCGv t0 = tcg_temp_new();
15036
15037             gen_load_gpr(t0, rt);
15038             gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
15039             tcg_temp_free(t0);
15040         }
15041         break;
15042 #endif
15043     case 0x2a:
15044         switch (minor & 3) {
15045         case MADD_ACC:
15046             gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
15047             break;
15048         case MADDU_ACC:
15049             gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
15050             break;
15051         case MSUB_ACC:
15052             gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
15053             break;
15054         case MSUBU_ACC:
15055             gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
15056             break;
15057         default:
15058             goto pool32axf_invalid;
15059         }
15060         break;
15061     case 0x32:
15062         switch (minor & 3) {
15063         case MULT_ACC:
15064             gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
15065             break;
15066         case MULTU_ACC:
15067             gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
15068             break;
15069         default:
15070             goto pool32axf_invalid;
15071         }
15072         break;
15073     case 0x2c:
15074         switch (minor) {
15075         case BITSWAP:
15076             check_insn(ctx, ISA_MIPS32R6);
15077             gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
15078             break;
15079         case SEB:
15080             gen_bshfl(ctx, OPC_SEB, rs, rt);
15081             break;
15082         case SEH:
15083             gen_bshfl(ctx, OPC_SEH, rs, rt);
15084             break;
15085         case CLO:
15086             mips32_op = OPC_CLO;
15087             goto do_cl;
15088         case CLZ:
15089             mips32_op = OPC_CLZ;
15090         do_cl:
15091             check_insn(ctx, ISA_MIPS32);
15092             gen_cl(ctx, mips32_op, rt, rs);
15093             break;
15094         case RDHWR:
15095             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15096             gen_rdhwr(ctx, rt, rs, 0);
15097             break;
15098         case WSBH:
15099             gen_bshfl(ctx, OPC_WSBH, rs, rt);
15100             break;
15101         case MULT:
15102             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15103             mips32_op = OPC_MULT;
15104             goto do_mul;
15105         case MULTU:
15106             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15107             mips32_op = OPC_MULTU;
15108             goto do_mul;
15109         case DIV:
15110             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15111             mips32_op = OPC_DIV;
15112             goto do_div;
15113         case DIVU:
15114             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15115             mips32_op = OPC_DIVU;
15116             goto do_div;
15117         do_div:
15118             check_insn(ctx, ISA_MIPS32);
15119             gen_muldiv(ctx, mips32_op, 0, rs, rt);
15120             break;
15121         case MADD:
15122             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15123             mips32_op = OPC_MADD;
15124             goto do_mul;
15125         case MADDU:
15126             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15127             mips32_op = OPC_MADDU;
15128             goto do_mul;
15129         case MSUB:
15130             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15131             mips32_op = OPC_MSUB;
15132             goto do_mul;
15133         case MSUBU:
15134             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15135             mips32_op = OPC_MSUBU;
15136         do_mul:
15137             check_insn(ctx, ISA_MIPS32);
15138             gen_muldiv(ctx, mips32_op, 0, rs, rt);
15139             break;
15140         default:
15141             goto pool32axf_invalid;
15142         }
15143         break;
15144     case 0x34:
15145         switch (minor) {
15146         case MFC2:
15147         case MTC2:
15148         case MFHC2:
15149         case MTHC2:
15150         case CFC2:
15151         case CTC2:
15152             generate_exception_err(ctx, EXCP_CpU, 2);
15153             break;
15154         default:
15155             goto pool32axf_invalid;
15156         }
15157         break;
15158     case 0x3c:
15159         switch (minor) {
15160         case JALR:    /* JALRC */
15161         case JALR_HB: /* JALRC_HB */
15162             if (ctx->insn_flags & ISA_MIPS32R6) {
15163                 /* JALRC, JALRC_HB */
15164                 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
15165             } else {
15166                 /* JALR, JALR_HB */
15167                 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
15168                 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15169             }
15170             break;
15171         case JALRS:
15172         case JALRS_HB:
15173             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15174             gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
15175             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15176             break;
15177         default:
15178             goto pool32axf_invalid;
15179         }
15180         break;
15181     case 0x05:
15182         switch (minor) {
15183         case RDPGPR:
15184             check_cp0_enabled(ctx);
15185             check_insn(ctx, ISA_MIPS32R2);
15186             gen_load_srsgpr(rs, rt);
15187             break;
15188         case WRPGPR:
15189             check_cp0_enabled(ctx);
15190             check_insn(ctx, ISA_MIPS32R2);
15191             gen_store_srsgpr(rs, rt);
15192             break;
15193         default:
15194             goto pool32axf_invalid;
15195         }
15196         break;
15197 #ifndef CONFIG_USER_ONLY
15198     case 0x0d:
15199         switch (minor) {
15200         case TLBP:
15201             mips32_op = OPC_TLBP;
15202             goto do_cp0;
15203         case TLBR:
15204             mips32_op = OPC_TLBR;
15205             goto do_cp0;
15206         case TLBWI:
15207             mips32_op = OPC_TLBWI;
15208             goto do_cp0;
15209         case TLBWR:
15210             mips32_op = OPC_TLBWR;
15211             goto do_cp0;
15212         case TLBINV:
15213             mips32_op = OPC_TLBINV;
15214             goto do_cp0;
15215         case TLBINVF:
15216             mips32_op = OPC_TLBINVF;
15217             goto do_cp0;
15218         case WAIT:
15219             mips32_op = OPC_WAIT;
15220             goto do_cp0;
15221         case DERET:
15222             mips32_op = OPC_DERET;
15223             goto do_cp0;
15224         case ERET:
15225             mips32_op = OPC_ERET;
15226         do_cp0:
15227             gen_cp0(env, ctx, mips32_op, rt, rs);
15228             break;
15229         default:
15230             goto pool32axf_invalid;
15231         }
15232         break;
15233     case 0x1d:
15234         switch (minor) {
15235         case DI:
15236             check_cp0_enabled(ctx);
15237             {
15238                 TCGv t0 = tcg_temp_new();
15239
15240                 save_cpu_state(ctx, 1);
15241                 gen_helper_di(t0, cpu_env);
15242                 gen_store_gpr(t0, rs);
15243                 /* Stop translation as we may have switched the execution mode */
15244                 ctx->base.is_jmp = DISAS_STOP;
15245                 tcg_temp_free(t0);
15246             }
15247             break;
15248         case EI:
15249             check_cp0_enabled(ctx);
15250             {
15251                 TCGv t0 = tcg_temp_new();
15252
15253                 save_cpu_state(ctx, 1);
15254                 gen_helper_ei(t0, cpu_env);
15255                 gen_store_gpr(t0, rs);
15256                 /* DISAS_STOP isn't sufficient, we need to ensure we break out
15257                    of translated code to check for pending interrupts.  */
15258                 gen_save_pc(ctx->base.pc_next + 4);
15259                 ctx->base.is_jmp = DISAS_EXIT;
15260                 tcg_temp_free(t0);
15261             }
15262             break;
15263         default:
15264             goto pool32axf_invalid;
15265         }
15266         break;
15267 #endif
15268     case 0x2d:
15269         switch (minor) {
15270         case SYNC:
15271             gen_sync(extract32(ctx->opcode, 16, 5));
15272             break;
15273         case SYSCALL:
15274             generate_exception_end(ctx, EXCP_SYSCALL);
15275             break;
15276         case SDBBP:
15277             if (is_uhi(extract32(ctx->opcode, 16, 10))) {
15278                 gen_helper_do_semihosting(cpu_env);
15279             } else {
15280                 check_insn(ctx, ISA_MIPS32);
15281                 if (ctx->hflags & MIPS_HFLAG_SBRI) {
15282                     generate_exception_end(ctx, EXCP_RI);
15283                 } else {
15284                     generate_exception_end(ctx, EXCP_DBp);
15285                 }
15286             }
15287             break;
15288         default:
15289             goto pool32axf_invalid;
15290         }
15291         break;
15292     case 0x01:
15293         switch (minor & 3) {
15294         case MFHI_ACC:
15295             gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
15296             break;
15297         case MFLO_ACC:
15298             gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
15299             break;
15300         case MTHI_ACC:
15301             gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
15302             break;
15303         case MTLO_ACC:
15304             gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
15305             break;
15306         default:
15307             goto pool32axf_invalid;
15308         }
15309         break;
15310     case 0x35:
15311         check_insn_opc_removed(ctx, ISA_MIPS32R6);
15312         switch (minor) {
15313         case MFHI32:
15314             gen_HILO(ctx, OPC_MFHI, 0, rs);
15315             break;
15316         case MFLO32:
15317             gen_HILO(ctx, OPC_MFLO, 0, rs);
15318             break;
15319         case MTHI32:
15320             gen_HILO(ctx, OPC_MTHI, 0, rs);
15321             break;
15322         case MTLO32:
15323             gen_HILO(ctx, OPC_MTLO, 0, rs);
15324             break;
15325         default:
15326             goto pool32axf_invalid;
15327         }
15328         break;
15329     default:
15330     pool32axf_invalid:
15331         MIPS_INVAL("pool32axf");
15332         generate_exception_end(ctx, EXCP_RI);
15333         break;
15334     }
15335 }
15336
15337 /* Values for microMIPS fmt field.  Variable-width, depending on which
15338    formats the instruction supports.  */
15339
15340 enum {
15341     FMT_SD_S = 0,
15342     FMT_SD_D = 1,
15343
15344     FMT_SDPS_S = 0,
15345     FMT_SDPS_D = 1,
15346     FMT_SDPS_PS = 2,
15347
15348     FMT_SWL_S = 0,
15349     FMT_SWL_W = 1,
15350     FMT_SWL_L = 2,
15351
15352     FMT_DWL_D = 0,
15353     FMT_DWL_W = 1,
15354     FMT_DWL_L = 2
15355 };
15356
15357 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
15358 {
15359     int extension = (ctx->opcode >> 6) & 0x3ff;
15360     uint32_t mips32_op;
15361
15362 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
15363 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
15364 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
15365
15366     switch (extension) {
15367     case FLOAT_1BIT_FMT(CFC1, 0):
15368         mips32_op = OPC_CFC1;
15369         goto do_cp1;
15370     case FLOAT_1BIT_FMT(CTC1, 0):
15371         mips32_op = OPC_CTC1;
15372         goto do_cp1;
15373     case FLOAT_1BIT_FMT(MFC1, 0):
15374         mips32_op = OPC_MFC1;
15375         goto do_cp1;
15376     case FLOAT_1BIT_FMT(MTC1, 0):
15377         mips32_op = OPC_MTC1;
15378         goto do_cp1;
15379     case FLOAT_1BIT_FMT(MFHC1, 0):
15380         mips32_op = OPC_MFHC1;
15381         goto do_cp1;
15382     case FLOAT_1BIT_FMT(MTHC1, 0):
15383         mips32_op = OPC_MTHC1;
15384     do_cp1:
15385         gen_cp1(ctx, mips32_op, rt, rs);
15386         break;
15387
15388         /* Reciprocal square root */
15389     case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
15390         mips32_op = OPC_RSQRT_S;
15391         goto do_unaryfp;
15392     case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
15393         mips32_op = OPC_RSQRT_D;
15394         goto do_unaryfp;
15395
15396         /* Square root */
15397     case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
15398         mips32_op = OPC_SQRT_S;
15399         goto do_unaryfp;
15400     case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
15401         mips32_op = OPC_SQRT_D;
15402         goto do_unaryfp;
15403
15404         /* Reciprocal */
15405     case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
15406         mips32_op = OPC_RECIP_S;
15407         goto do_unaryfp;
15408     case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
15409         mips32_op = OPC_RECIP_D;
15410         goto do_unaryfp;
15411
15412         /* Floor */
15413     case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
15414         mips32_op = OPC_FLOOR_L_S;
15415         goto do_unaryfp;
15416     case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
15417         mips32_op = OPC_FLOOR_L_D;
15418         goto do_unaryfp;
15419     case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
15420         mips32_op = OPC_FLOOR_W_S;
15421         goto do_unaryfp;
15422     case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
15423         mips32_op = OPC_FLOOR_W_D;
15424         goto do_unaryfp;
15425
15426         /* Ceiling */
15427     case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
15428         mips32_op = OPC_CEIL_L_S;
15429         goto do_unaryfp;
15430     case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
15431         mips32_op = OPC_CEIL_L_D;
15432         goto do_unaryfp;
15433     case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
15434         mips32_op = OPC_CEIL_W_S;
15435         goto do_unaryfp;
15436     case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
15437         mips32_op = OPC_CEIL_W_D;
15438         goto do_unaryfp;
15439
15440         /* Truncation */
15441     case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
15442         mips32_op = OPC_TRUNC_L_S;
15443         goto do_unaryfp;
15444     case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
15445         mips32_op = OPC_TRUNC_L_D;
15446         goto do_unaryfp;
15447     case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
15448         mips32_op = OPC_TRUNC_W_S;
15449         goto do_unaryfp;
15450     case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
15451         mips32_op = OPC_TRUNC_W_D;
15452         goto do_unaryfp;
15453
15454         /* Round */
15455     case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
15456         mips32_op = OPC_ROUND_L_S;
15457         goto do_unaryfp;
15458     case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
15459         mips32_op = OPC_ROUND_L_D;
15460         goto do_unaryfp;
15461     case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
15462         mips32_op = OPC_ROUND_W_S;
15463         goto do_unaryfp;
15464     case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
15465         mips32_op = OPC_ROUND_W_D;
15466         goto do_unaryfp;
15467
15468         /* Integer to floating-point conversion */
15469     case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
15470         mips32_op = OPC_CVT_L_S;
15471         goto do_unaryfp;
15472     case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
15473         mips32_op = OPC_CVT_L_D;
15474         goto do_unaryfp;
15475     case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
15476         mips32_op = OPC_CVT_W_S;
15477         goto do_unaryfp;
15478     case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
15479         mips32_op = OPC_CVT_W_D;
15480         goto do_unaryfp;
15481
15482         /* Paired-foo conversions */
15483     case FLOAT_1BIT_FMT(CVT_S_PL, 0):
15484         mips32_op = OPC_CVT_S_PL;
15485         goto do_unaryfp;
15486     case FLOAT_1BIT_FMT(CVT_S_PU, 0):
15487         mips32_op = OPC_CVT_S_PU;
15488         goto do_unaryfp;
15489     case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
15490         mips32_op = OPC_CVT_PW_PS;
15491         goto do_unaryfp;
15492     case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
15493         mips32_op = OPC_CVT_PS_PW;
15494         goto do_unaryfp;
15495
15496         /* Floating-point moves */
15497     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
15498         mips32_op = OPC_MOV_S;
15499         goto do_unaryfp;
15500     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
15501         mips32_op = OPC_MOV_D;
15502         goto do_unaryfp;
15503     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
15504         mips32_op = OPC_MOV_PS;
15505         goto do_unaryfp;
15506
15507         /* Absolute value */
15508     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
15509         mips32_op = OPC_ABS_S;
15510         goto do_unaryfp;
15511     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
15512         mips32_op = OPC_ABS_D;
15513         goto do_unaryfp;
15514     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
15515         mips32_op = OPC_ABS_PS;
15516         goto do_unaryfp;
15517
15518         /* Negation */
15519     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
15520         mips32_op = OPC_NEG_S;
15521         goto do_unaryfp;
15522     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
15523         mips32_op = OPC_NEG_D;
15524         goto do_unaryfp;
15525     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
15526         mips32_op = OPC_NEG_PS;
15527         goto do_unaryfp;
15528
15529         /* Reciprocal square root step */
15530     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
15531         mips32_op = OPC_RSQRT1_S;
15532         goto do_unaryfp;
15533     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
15534         mips32_op = OPC_RSQRT1_D;
15535         goto do_unaryfp;
15536     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
15537         mips32_op = OPC_RSQRT1_PS;
15538         goto do_unaryfp;
15539
15540         /* Reciprocal step */
15541     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
15542         mips32_op = OPC_RECIP1_S;
15543         goto do_unaryfp;
15544     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
15545         mips32_op = OPC_RECIP1_S;
15546         goto do_unaryfp;
15547     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
15548         mips32_op = OPC_RECIP1_PS;
15549         goto do_unaryfp;
15550
15551         /* Conversions from double */
15552     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
15553         mips32_op = OPC_CVT_D_S;
15554         goto do_unaryfp;
15555     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
15556         mips32_op = OPC_CVT_D_W;
15557         goto do_unaryfp;
15558     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
15559         mips32_op = OPC_CVT_D_L;
15560         goto do_unaryfp;
15561
15562         /* Conversions from single */
15563     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
15564         mips32_op = OPC_CVT_S_D;
15565         goto do_unaryfp;
15566     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
15567         mips32_op = OPC_CVT_S_W;
15568         goto do_unaryfp;
15569     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
15570         mips32_op = OPC_CVT_S_L;
15571     do_unaryfp:
15572         gen_farith(ctx, mips32_op, -1, rs, rt, 0);
15573         break;
15574
15575         /* Conditional moves on floating-point codes */
15576     case COND_FLOAT_MOV(MOVT, 0):
15577     case COND_FLOAT_MOV(MOVT, 1):
15578     case COND_FLOAT_MOV(MOVT, 2):
15579     case COND_FLOAT_MOV(MOVT, 3):
15580     case COND_FLOAT_MOV(MOVT, 4):
15581     case COND_FLOAT_MOV(MOVT, 5):
15582     case COND_FLOAT_MOV(MOVT, 6):
15583     case COND_FLOAT_MOV(MOVT, 7):
15584         check_insn_opc_removed(ctx, ISA_MIPS32R6);
15585         gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
15586         break;
15587     case COND_FLOAT_MOV(MOVF, 0):
15588     case COND_FLOAT_MOV(MOVF, 1):
15589     case COND_FLOAT_MOV(MOVF, 2):
15590     case COND_FLOAT_MOV(MOVF, 3):
15591     case COND_FLOAT_MOV(MOVF, 4):
15592     case COND_FLOAT_MOV(MOVF, 5):
15593     case COND_FLOAT_MOV(MOVF, 6):
15594     case COND_FLOAT_MOV(MOVF, 7):
15595         check_insn_opc_removed(ctx, ISA_MIPS32R6);
15596         gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
15597         break;
15598     default:
15599         MIPS_INVAL("pool32fxf");
15600         generate_exception_end(ctx, EXCP_RI);
15601         break;
15602     }
15603 }
15604
15605 static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
15606 {
15607     int32_t offset;
15608     uint16_t insn;
15609     int rt, rs, rd, rr;
15610     int16_t imm;
15611     uint32_t op, minor, minor2, mips32_op;
15612     uint32_t cond, fmt, cc;
15613
15614     insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
15615     ctx->opcode = (ctx->opcode << 16) | insn;
15616
15617     rt = (ctx->opcode >> 21) & 0x1f;
15618     rs = (ctx->opcode >> 16) & 0x1f;
15619     rd = (ctx->opcode >> 11) & 0x1f;
15620     rr = (ctx->opcode >> 6) & 0x1f;
15621     imm = (int16_t) ctx->opcode;
15622
15623     op = (ctx->opcode >> 26) & 0x3f;
15624     switch (op) {
15625     case POOL32A:
15626         minor = ctx->opcode & 0x3f;
15627         switch (minor) {
15628         case 0x00:
15629             minor = (ctx->opcode >> 6) & 0xf;
15630             switch (minor) {
15631             case SLL32:
15632                 mips32_op = OPC_SLL;
15633                 goto do_shifti;
15634             case SRA:
15635                 mips32_op = OPC_SRA;
15636                 goto do_shifti;
15637             case SRL32:
15638                 mips32_op = OPC_SRL;
15639                 goto do_shifti;
15640             case ROTR:
15641                 mips32_op = OPC_ROTR;
15642             do_shifti:
15643                 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
15644                 break;
15645             case SELEQZ:
15646                 check_insn(ctx, ISA_MIPS32R6);
15647                 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
15648                 break;
15649             case SELNEZ:
15650                 check_insn(ctx, ISA_MIPS32R6);
15651                 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
15652                 break;
15653             case R6_RDHWR:
15654                 check_insn(ctx, ISA_MIPS32R6);
15655                 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
15656                 break;
15657             default:
15658                 goto pool32a_invalid;
15659             }
15660             break;
15661         case 0x10:
15662             minor = (ctx->opcode >> 6) & 0xf;
15663             switch (minor) {
15664                 /* Arithmetic */
15665             case ADD:
15666                 mips32_op = OPC_ADD;
15667                 goto do_arith;
15668             case ADDU32:
15669                 mips32_op = OPC_ADDU;
15670                 goto do_arith;
15671             case SUB:
15672                 mips32_op = OPC_SUB;
15673                 goto do_arith;
15674             case SUBU32:
15675                 mips32_op = OPC_SUBU;
15676                 goto do_arith;
15677             case MUL:
15678                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15679                 mips32_op = OPC_MUL;
15680             do_arith:
15681                 gen_arith(ctx, mips32_op, rd, rs, rt);
15682                 break;
15683                 /* Shifts */
15684             case SLLV:
15685                 mips32_op = OPC_SLLV;
15686                 goto do_shift;
15687             case SRLV:
15688                 mips32_op = OPC_SRLV;
15689                 goto do_shift;
15690             case SRAV:
15691                 mips32_op = OPC_SRAV;
15692                 goto do_shift;
15693             case ROTRV:
15694                 mips32_op = OPC_ROTRV;
15695             do_shift:
15696                 gen_shift(ctx, mips32_op, rd, rs, rt);
15697                 break;
15698                 /* Logical operations */
15699             case AND:
15700                 mips32_op = OPC_AND;
15701                 goto do_logic;
15702             case OR32:
15703                 mips32_op = OPC_OR;
15704                 goto do_logic;
15705             case NOR:
15706                 mips32_op = OPC_NOR;
15707                 goto do_logic;
15708             case XOR32:
15709                 mips32_op = OPC_XOR;
15710             do_logic:
15711                 gen_logic(ctx, mips32_op, rd, rs, rt);
15712                 break;
15713                 /* Set less than */
15714             case SLT:
15715                 mips32_op = OPC_SLT;
15716                 goto do_slt;
15717             case SLTU:
15718                 mips32_op = OPC_SLTU;
15719             do_slt:
15720                 gen_slt(ctx, mips32_op, rd, rs, rt);
15721                 break;
15722             default:
15723                 goto pool32a_invalid;
15724             }
15725             break;
15726         case 0x18:
15727             minor = (ctx->opcode >> 6) & 0xf;
15728             switch (minor) {
15729                 /* Conditional moves */
15730             case MOVN: /* MUL */
15731                 if (ctx->insn_flags & ISA_MIPS32R6) {
15732                     /* MUL */
15733                     gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
15734                 } else {
15735                     /* MOVN */
15736                     gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
15737                 }
15738                 break;
15739             case MOVZ: /* MUH */
15740                 if (ctx->insn_flags & ISA_MIPS32R6) {
15741                     /* MUH */
15742                     gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
15743                 } else {
15744                     /* MOVZ */
15745                     gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
15746                 }
15747                 break;
15748             case MULU:
15749                 check_insn(ctx, ISA_MIPS32R6);
15750                 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
15751                 break;
15752             case MUHU:
15753                 check_insn(ctx, ISA_MIPS32R6);
15754                 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
15755                 break;
15756             case LWXS: /* DIV */
15757                 if (ctx->insn_flags & ISA_MIPS32R6) {
15758                     /* DIV */
15759                     gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
15760                 } else {
15761                     /* LWXS */
15762                     gen_ldxs(ctx, rs, rt, rd);
15763                 }
15764                 break;
15765             case MOD:
15766                 check_insn(ctx, ISA_MIPS32R6);
15767                 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
15768                 break;
15769             case R6_DIVU:
15770                 check_insn(ctx, ISA_MIPS32R6);
15771                 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
15772                 break;
15773             case MODU:
15774                 check_insn(ctx, ISA_MIPS32R6);
15775                 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
15776                 break;
15777             default:
15778                 goto pool32a_invalid;
15779             }
15780             break;
15781         case INS:
15782             gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
15783             return;
15784         case LSA:
15785             check_insn(ctx, ISA_MIPS32R6);
15786             gen_lsa(ctx, OPC_LSA, rd, rs, rt,
15787                     extract32(ctx->opcode, 9, 2));
15788             break;
15789         case ALIGN:
15790             check_insn(ctx, ISA_MIPS32R6);
15791             gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2));
15792             break;
15793         case EXT:
15794             gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
15795             return;
15796         case POOL32AXF:
15797             gen_pool32axf(env, ctx, rt, rs);
15798             break;
15799         case BREAK32:
15800             generate_exception_end(ctx, EXCP_BREAK);
15801             break;
15802         case SIGRIE:
15803             check_insn(ctx, ISA_MIPS32R6);
15804             generate_exception_end(ctx, EXCP_RI);
15805             break;
15806         default:
15807         pool32a_invalid:
15808                 MIPS_INVAL("pool32a");
15809                 generate_exception_end(ctx, EXCP_RI);
15810                 break;
15811         }
15812         break;
15813     case POOL32B:
15814         minor = (ctx->opcode >> 12) & 0xf;
15815         switch (minor) {
15816         case CACHE:
15817             check_cp0_enabled(ctx);
15818             if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15819                 gen_cache_operation(ctx, rt, rs, imm);
15820             }
15821             break;
15822         case LWC2:
15823         case SWC2:
15824             /* COP2: Not implemented. */
15825             generate_exception_err(ctx, EXCP_CpU, 2);
15826             break;
15827 #ifdef TARGET_MIPS64
15828         case LDP:
15829         case SDP:
15830             check_insn(ctx, ISA_MIPS3);
15831             check_mips_64(ctx);
15832 #endif
15833             /* fall through */
15834         case LWP:
15835         case SWP:
15836             gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
15837             break;
15838 #ifdef TARGET_MIPS64
15839         case LDM:
15840         case SDM:
15841             check_insn(ctx, ISA_MIPS3);
15842             check_mips_64(ctx);
15843 #endif
15844             /* fall through */
15845         case LWM32:
15846         case SWM32:
15847             gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
15848             break;
15849         default:
15850             MIPS_INVAL("pool32b");
15851             generate_exception_end(ctx, EXCP_RI);
15852             break;
15853         }
15854         break;
15855     case POOL32F:
15856         if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
15857             minor = ctx->opcode & 0x3f;
15858             check_cp1_enabled(ctx);
15859             switch (minor) {
15860             case ALNV_PS:
15861                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15862                 mips32_op = OPC_ALNV_PS;
15863                 goto do_madd;
15864             case MADD_S:
15865                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15866                 mips32_op = OPC_MADD_S;
15867                 goto do_madd;
15868             case MADD_D:
15869                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15870                 mips32_op = OPC_MADD_D;
15871                 goto do_madd;
15872             case MADD_PS:
15873                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15874                 mips32_op = OPC_MADD_PS;
15875                 goto do_madd;
15876             case MSUB_S:
15877                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15878                 mips32_op = OPC_MSUB_S;
15879                 goto do_madd;
15880             case MSUB_D:
15881                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15882                 mips32_op = OPC_MSUB_D;
15883                 goto do_madd;
15884             case MSUB_PS:
15885                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15886                 mips32_op = OPC_MSUB_PS;
15887                 goto do_madd;
15888             case NMADD_S:
15889                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15890                 mips32_op = OPC_NMADD_S;
15891                 goto do_madd;
15892             case NMADD_D:
15893                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15894                 mips32_op = OPC_NMADD_D;
15895                 goto do_madd;
15896             case NMADD_PS:
15897                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15898                 mips32_op = OPC_NMADD_PS;
15899                 goto do_madd;
15900             case NMSUB_S:
15901                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15902                 mips32_op = OPC_NMSUB_S;
15903                 goto do_madd;
15904             case NMSUB_D:
15905                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15906                 mips32_op = OPC_NMSUB_D;
15907                 goto do_madd;
15908             case NMSUB_PS:
15909                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15910                 mips32_op = OPC_NMSUB_PS;
15911             do_madd:
15912                 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
15913                 break;
15914             case CABS_COND_FMT:
15915                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15916                 cond = (ctx->opcode >> 6) & 0xf;
15917                 cc = (ctx->opcode >> 13) & 0x7;
15918                 fmt = (ctx->opcode >> 10) & 0x3;
15919                 switch (fmt) {
15920                 case 0x0:
15921                     gen_cmpabs_s(ctx, cond, rt, rs, cc);
15922                     break;
15923                 case 0x1:
15924                     gen_cmpabs_d(ctx, cond, rt, rs, cc);
15925                     break;
15926                 case 0x2:
15927                     gen_cmpabs_ps(ctx, cond, rt, rs, cc);
15928                     break;
15929                 default:
15930                     goto pool32f_invalid;
15931                 }
15932                 break;
15933             case C_COND_FMT:
15934                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15935                 cond = (ctx->opcode >> 6) & 0xf;
15936                 cc = (ctx->opcode >> 13) & 0x7;
15937                 fmt = (ctx->opcode >> 10) & 0x3;
15938                 switch (fmt) {
15939                 case 0x0:
15940                     gen_cmp_s(ctx, cond, rt, rs, cc);
15941                     break;
15942                 case 0x1:
15943                     gen_cmp_d(ctx, cond, rt, rs, cc);
15944                     break;
15945                 case 0x2:
15946                     gen_cmp_ps(ctx, cond, rt, rs, cc);
15947                     break;
15948                 default:
15949                     goto pool32f_invalid;
15950                 }
15951                 break;
15952             case CMP_CONDN_S:
15953                 check_insn(ctx, ISA_MIPS32R6);
15954                 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
15955                 break;
15956             case CMP_CONDN_D:
15957                 check_insn(ctx, ISA_MIPS32R6);
15958                 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
15959                 break;
15960             case POOL32FXF:
15961                 gen_pool32fxf(ctx, rt, rs);
15962                 break;
15963             case 0x00:
15964                 /* PLL foo */
15965                 switch ((ctx->opcode >> 6) & 0x7) {
15966                 case PLL_PS:
15967                     mips32_op = OPC_PLL_PS;
15968                     goto do_ps;
15969                 case PLU_PS:
15970                     mips32_op = OPC_PLU_PS;
15971                     goto do_ps;
15972                 case PUL_PS:
15973                     mips32_op = OPC_PUL_PS;
15974                     goto do_ps;
15975                 case PUU_PS:
15976                     mips32_op = OPC_PUU_PS;
15977                     goto do_ps;
15978                 case CVT_PS_S:
15979                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
15980                     mips32_op = OPC_CVT_PS_S;
15981                 do_ps:
15982                     gen_farith(ctx, mips32_op, rt, rs, rd, 0);
15983                     break;
15984                 default:
15985                     goto pool32f_invalid;
15986                 }
15987                 break;
15988             case MIN_FMT:
15989                 check_insn(ctx, ISA_MIPS32R6);
15990                 switch ((ctx->opcode >> 9) & 0x3) {
15991                 case FMT_SDPS_S:
15992                     gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
15993                     break;
15994                 case FMT_SDPS_D:
15995                     gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
15996                     break;
15997                 default:
15998                     goto pool32f_invalid;
15999                 }
16000                 break;
16001             case 0x08:
16002                 /* [LS][WDU]XC1 */
16003                 switch ((ctx->opcode >> 6) & 0x7) {
16004                 case LWXC1:
16005                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16006                     mips32_op = OPC_LWXC1;
16007                     goto do_ldst_cp1;
16008                 case SWXC1:
16009                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16010                     mips32_op = OPC_SWXC1;
16011                     goto do_ldst_cp1;
16012                 case LDXC1:
16013                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16014                     mips32_op = OPC_LDXC1;
16015                     goto do_ldst_cp1;
16016                 case SDXC1:
16017                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16018                     mips32_op = OPC_SDXC1;
16019                     goto do_ldst_cp1;
16020                 case LUXC1:
16021                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16022                     mips32_op = OPC_LUXC1;
16023                     goto do_ldst_cp1;
16024                 case SUXC1:
16025                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16026                     mips32_op = OPC_SUXC1;
16027                 do_ldst_cp1:
16028                     gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
16029                     break;
16030                 default:
16031                     goto pool32f_invalid;
16032                 }
16033                 break;
16034             case MAX_FMT:
16035                 check_insn(ctx, ISA_MIPS32R6);
16036                 switch ((ctx->opcode >> 9) & 0x3) {
16037                 case FMT_SDPS_S:
16038                     gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
16039                     break;
16040                 case FMT_SDPS_D:
16041                     gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
16042                     break;
16043                 default:
16044                     goto pool32f_invalid;
16045                 }
16046                 break;
16047             case 0x18:
16048                 /* 3D insns */
16049                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16050                 fmt = (ctx->opcode >> 9) & 0x3;
16051                 switch ((ctx->opcode >> 6) & 0x7) {
16052                 case RSQRT2_FMT:
16053                     switch (fmt) {
16054                     case FMT_SDPS_S:
16055                         mips32_op = OPC_RSQRT2_S;
16056                         goto do_3d;
16057                     case FMT_SDPS_D:
16058                         mips32_op = OPC_RSQRT2_D;
16059                         goto do_3d;
16060                     case FMT_SDPS_PS:
16061                         mips32_op = OPC_RSQRT2_PS;
16062                         goto do_3d;
16063                     default:
16064                         goto pool32f_invalid;
16065                     }
16066                     break;
16067                 case RECIP2_FMT:
16068                     switch (fmt) {
16069                     case FMT_SDPS_S:
16070                         mips32_op = OPC_RECIP2_S;
16071                         goto do_3d;
16072                     case FMT_SDPS_D:
16073                         mips32_op = OPC_RECIP2_D;
16074                         goto do_3d;
16075                     case FMT_SDPS_PS:
16076                         mips32_op = OPC_RECIP2_PS;
16077                         goto do_3d;
16078                     default:
16079                         goto pool32f_invalid;
16080                     }
16081                     break;
16082                 case ADDR_PS:
16083                     mips32_op = OPC_ADDR_PS;
16084                     goto do_3d;
16085                 case MULR_PS:
16086                     mips32_op = OPC_MULR_PS;
16087                 do_3d:
16088                     gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16089                     break;
16090                 default:
16091                     goto pool32f_invalid;
16092                 }
16093                 break;
16094             case 0x20:
16095                 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
16096                 cc = (ctx->opcode >> 13) & 0x7;
16097                 fmt = (ctx->opcode >> 9) & 0x3;
16098                 switch ((ctx->opcode >> 6) & 0x7) {
16099                 case MOVF_FMT: /* RINT_FMT */
16100                     if (ctx->insn_flags & ISA_MIPS32R6) {
16101                         /* RINT_FMT */
16102                         switch (fmt) {
16103                         case FMT_SDPS_S:
16104                             gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
16105                             break;
16106                         case FMT_SDPS_D:
16107                             gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
16108                             break;
16109                         default:
16110                             goto pool32f_invalid;
16111                         }
16112                     } else {
16113                         /* MOVF_FMT */
16114                         switch (fmt) {
16115                         case FMT_SDPS_S:
16116                             gen_movcf_s(ctx, rs, rt, cc, 0);
16117                             break;
16118                         case FMT_SDPS_D:
16119                             gen_movcf_d(ctx, rs, rt, cc, 0);
16120                             break;
16121                         case FMT_SDPS_PS:
16122                             check_ps(ctx);
16123                             gen_movcf_ps(ctx, rs, rt, cc, 0);
16124                             break;
16125                         default:
16126                             goto pool32f_invalid;
16127                         }
16128                     }
16129                     break;
16130                 case MOVT_FMT: /* CLASS_FMT */
16131                     if (ctx->insn_flags & ISA_MIPS32R6) {
16132                         /* CLASS_FMT */
16133                         switch (fmt) {
16134                         case FMT_SDPS_S:
16135                             gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
16136                             break;
16137                         case FMT_SDPS_D:
16138                             gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
16139                             break;
16140                         default:
16141                             goto pool32f_invalid;
16142                         }
16143                     } else {
16144                         /* MOVT_FMT */
16145                         switch (fmt) {
16146                         case FMT_SDPS_S:
16147                             gen_movcf_s(ctx, rs, rt, cc, 1);
16148                             break;
16149                         case FMT_SDPS_D:
16150                             gen_movcf_d(ctx, rs, rt, cc, 1);
16151                             break;
16152                         case FMT_SDPS_PS:
16153                             check_ps(ctx);
16154                             gen_movcf_ps(ctx, rs, rt, cc, 1);
16155                             break;
16156                         default:
16157                             goto pool32f_invalid;
16158                         }
16159                     }
16160                     break;
16161                 case PREFX:
16162                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16163                     break;
16164                 default:
16165                     goto pool32f_invalid;
16166                 }
16167                 break;
16168 #define FINSN_3ARG_SDPS(prfx)                           \
16169                 switch ((ctx->opcode >> 8) & 0x3) {     \
16170                 case FMT_SDPS_S:                        \
16171                     mips32_op = OPC_##prfx##_S;         \
16172                     goto do_fpop;                       \
16173                 case FMT_SDPS_D:                        \
16174                     mips32_op = OPC_##prfx##_D;         \
16175                     goto do_fpop;                       \
16176                 case FMT_SDPS_PS:                       \
16177                     check_ps(ctx);                      \
16178                     mips32_op = OPC_##prfx##_PS;        \
16179                     goto do_fpop;                       \
16180                 default:                                \
16181                     goto pool32f_invalid;               \
16182                 }
16183             case MINA_FMT:
16184                 check_insn(ctx, ISA_MIPS32R6);
16185                 switch ((ctx->opcode >> 9) & 0x3) {
16186                 case FMT_SDPS_S:
16187                     gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
16188                     break;
16189                 case FMT_SDPS_D:
16190                     gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
16191                     break;
16192                 default:
16193                     goto pool32f_invalid;
16194                 }
16195                 break;
16196             case MAXA_FMT:
16197                 check_insn(ctx, ISA_MIPS32R6);
16198                 switch ((ctx->opcode >> 9) & 0x3) {
16199                 case FMT_SDPS_S:
16200                     gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
16201                     break;
16202                 case FMT_SDPS_D:
16203                     gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
16204                     break;
16205                 default:
16206                     goto pool32f_invalid;
16207                 }
16208                 break;
16209             case 0x30:
16210                 /* regular FP ops */
16211                 switch ((ctx->opcode >> 6) & 0x3) {
16212                 case ADD_FMT:
16213                     FINSN_3ARG_SDPS(ADD);
16214                     break;
16215                 case SUB_FMT:
16216                     FINSN_3ARG_SDPS(SUB);
16217                     break;
16218                 case MUL_FMT:
16219                     FINSN_3ARG_SDPS(MUL);
16220                     break;
16221                 case DIV_FMT:
16222                     fmt = (ctx->opcode >> 8) & 0x3;
16223                     if (fmt == 1) {
16224                         mips32_op = OPC_DIV_D;
16225                     } else if (fmt == 0) {
16226                         mips32_op = OPC_DIV_S;
16227                     } else {
16228                         goto pool32f_invalid;
16229                     }
16230                     goto do_fpop;
16231                 default:
16232                     goto pool32f_invalid;
16233                 }
16234                 break;
16235             case 0x38:
16236                 /* cmovs */
16237                 switch ((ctx->opcode >> 6) & 0x7) {
16238                 case MOVN_FMT: /* SELEQZ_FMT */
16239                     if (ctx->insn_flags & ISA_MIPS32R6) {
16240                         /* SELEQZ_FMT */
16241                         switch ((ctx->opcode >> 9) & 0x3) {
16242                         case FMT_SDPS_S:
16243                             gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
16244                             break;
16245                         case FMT_SDPS_D:
16246                             gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
16247                             break;
16248                         default:
16249                             goto pool32f_invalid;
16250                         }
16251                     } else {
16252                         /* MOVN_FMT */
16253                         FINSN_3ARG_SDPS(MOVN);
16254                     }
16255                     break;
16256                 case MOVN_FMT_04:
16257                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16258                     FINSN_3ARG_SDPS(MOVN);
16259                     break;
16260                 case MOVZ_FMT: /* SELNEZ_FMT */
16261                     if (ctx->insn_flags & ISA_MIPS32R6) {
16262                         /* SELNEZ_FMT */
16263                         switch ((ctx->opcode >> 9) & 0x3) {
16264                         case FMT_SDPS_S:
16265                             gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
16266                             break;
16267                         case FMT_SDPS_D:
16268                             gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
16269                             break;
16270                         default:
16271                             goto pool32f_invalid;
16272                         }
16273                     } else {
16274                         /* MOVZ_FMT */
16275                         FINSN_3ARG_SDPS(MOVZ);
16276                     }
16277                     break;
16278                 case MOVZ_FMT_05:
16279                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16280                     FINSN_3ARG_SDPS(MOVZ);
16281                     break;
16282                 case SEL_FMT:
16283                     check_insn(ctx, ISA_MIPS32R6);
16284                     switch ((ctx->opcode >> 9) & 0x3) {
16285                     case FMT_SDPS_S:
16286                         gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
16287                         break;
16288                     case FMT_SDPS_D:
16289                         gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
16290                         break;
16291                     default:
16292                         goto pool32f_invalid;
16293                     }
16294                     break;
16295                 case MADDF_FMT:
16296                     check_insn(ctx, ISA_MIPS32R6);
16297                     switch ((ctx->opcode >> 9) & 0x3) {
16298                     case FMT_SDPS_S:
16299                         mips32_op = OPC_MADDF_S;
16300                         goto do_fpop;
16301                     case FMT_SDPS_D:
16302                         mips32_op = OPC_MADDF_D;
16303                         goto do_fpop;
16304                     default:
16305                         goto pool32f_invalid;
16306                     }
16307                     break;
16308                 case MSUBF_FMT:
16309                     check_insn(ctx, ISA_MIPS32R6);
16310                     switch ((ctx->opcode >> 9) & 0x3) {
16311                     case FMT_SDPS_S:
16312                         mips32_op = OPC_MSUBF_S;
16313                         goto do_fpop;
16314                     case FMT_SDPS_D:
16315                         mips32_op = OPC_MSUBF_D;
16316                         goto do_fpop;
16317                     default:
16318                         goto pool32f_invalid;
16319                     }
16320                     break;
16321                 default:
16322                     goto pool32f_invalid;
16323                 }
16324                 break;
16325             do_fpop:
16326                 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16327                 break;
16328             default:
16329             pool32f_invalid:
16330                 MIPS_INVAL("pool32f");
16331                 generate_exception_end(ctx, EXCP_RI);
16332                 break;
16333             }
16334         } else {
16335             generate_exception_err(ctx, EXCP_CpU, 1);
16336         }
16337         break;
16338     case POOL32I:
16339         minor = (ctx->opcode >> 21) & 0x1f;
16340         switch (minor) {
16341         case BLTZ:
16342             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16343             gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
16344             break;
16345         case BLTZAL:
16346             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16347             gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
16348             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16349             break;
16350         case BLTZALS:
16351             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16352             gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
16353             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16354             break;
16355         case BGEZ:
16356             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16357             gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
16358             break;
16359         case BGEZAL:
16360             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16361             gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
16362             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16363             break;
16364         case BGEZALS:
16365             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16366             gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
16367             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16368             break;
16369         case BLEZ:
16370             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16371             gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
16372             break;
16373         case BGTZ:
16374             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16375             gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
16376             break;
16377
16378             /* Traps */
16379         case TLTI: /* BC1EQZC */
16380             if (ctx->insn_flags & ISA_MIPS32R6) {
16381                 /* BC1EQZC */
16382                 check_cp1_enabled(ctx);
16383                 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
16384             } else {
16385                 /* TLTI */
16386                 mips32_op = OPC_TLTI;
16387                 goto do_trapi;
16388             }
16389             break;
16390         case TGEI: /* BC1NEZC */
16391             if (ctx->insn_flags & ISA_MIPS32R6) {
16392                 /* BC1NEZC */
16393                 check_cp1_enabled(ctx);
16394                 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
16395             } else {
16396                 /* TGEI */
16397                 mips32_op = OPC_TGEI;
16398                 goto do_trapi;
16399             }
16400             break;
16401         case TLTIU:
16402             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16403             mips32_op = OPC_TLTIU;
16404             goto do_trapi;
16405         case TGEIU:
16406             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16407             mips32_op = OPC_TGEIU;
16408             goto do_trapi;
16409         case TNEI: /* SYNCI */
16410             if (ctx->insn_flags & ISA_MIPS32R6) {
16411                 /* SYNCI */
16412                 /* Break the TB to be able to sync copied instructions
16413                    immediately */
16414                 ctx->base.is_jmp = DISAS_STOP;
16415             } else {
16416                 /* TNEI */
16417                 mips32_op = OPC_TNEI;
16418                 goto do_trapi;
16419             }
16420             break;
16421         case TEQI:
16422             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16423             mips32_op = OPC_TEQI;
16424         do_trapi:
16425             gen_trap(ctx, mips32_op, rs, -1, imm);
16426             break;
16427
16428         case BNEZC:
16429         case BEQZC:
16430             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16431             gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
16432                                4, rs, 0, imm << 1, 0);
16433             /* Compact branches don't have a delay slot, so just let
16434                the normal delay slot handling take us to the branch
16435                target. */
16436             break;
16437         case LUI:
16438             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16439             gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
16440             break;
16441         case SYNCI:
16442             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16443             /* Break the TB to be able to sync copied instructions
16444                immediately */
16445             ctx->base.is_jmp = DISAS_STOP;
16446             break;
16447         case BC2F:
16448         case BC2T:
16449             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16450             /* COP2: Not implemented. */
16451             generate_exception_err(ctx, EXCP_CpU, 2);
16452             break;
16453         case BC1F:
16454             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16455             mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
16456             goto do_cp1branch;
16457         case BC1T:
16458             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16459             mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
16460             goto do_cp1branch;
16461         case BC1ANY4F:
16462             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16463             mips32_op = OPC_BC1FANY4;
16464             goto do_cp1mips3d;
16465         case BC1ANY4T:
16466             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16467             mips32_op = OPC_BC1TANY4;
16468         do_cp1mips3d:
16469             check_cop1x(ctx);
16470             check_insn(ctx, ASE_MIPS3D);
16471             /* Fall through */
16472         do_cp1branch:
16473             if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16474                 check_cp1_enabled(ctx);
16475                 gen_compute_branch1(ctx, mips32_op,
16476                                     (ctx->opcode >> 18) & 0x7, imm << 1);
16477             } else {
16478                 generate_exception_err(ctx, EXCP_CpU, 1);
16479             }
16480             break;
16481         case BPOSGE64:
16482         case BPOSGE32:
16483             /* MIPS DSP: not implemented */
16484             /* Fall through */
16485         default:
16486             MIPS_INVAL("pool32i");
16487             generate_exception_end(ctx, EXCP_RI);
16488             break;
16489         }
16490         break;
16491     case POOL32C:
16492         minor = (ctx->opcode >> 12) & 0xf;
16493         offset = sextract32(ctx->opcode, 0,
16494                             (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
16495         switch (minor) {
16496         case LWL:
16497             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16498             mips32_op = OPC_LWL;
16499             goto do_ld_lr;
16500         case SWL:
16501             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16502             mips32_op = OPC_SWL;
16503             goto do_st_lr;
16504         case LWR:
16505             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16506             mips32_op = OPC_LWR;
16507             goto do_ld_lr;
16508         case SWR:
16509             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16510             mips32_op = OPC_SWR;
16511             goto do_st_lr;
16512 #if defined(TARGET_MIPS64)
16513         case LDL:
16514             check_insn(ctx, ISA_MIPS3);
16515             check_mips_64(ctx);
16516             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16517             mips32_op = OPC_LDL;
16518             goto do_ld_lr;
16519         case SDL:
16520             check_insn(ctx, ISA_MIPS3);
16521             check_mips_64(ctx);
16522             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16523             mips32_op = OPC_SDL;
16524             goto do_st_lr;
16525         case LDR:
16526             check_insn(ctx, ISA_MIPS3);
16527             check_mips_64(ctx);
16528             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16529             mips32_op = OPC_LDR;
16530             goto do_ld_lr;
16531         case SDR:
16532             check_insn(ctx, ISA_MIPS3);
16533             check_mips_64(ctx);
16534             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16535             mips32_op = OPC_SDR;
16536             goto do_st_lr;
16537         case LWU:
16538             check_insn(ctx, ISA_MIPS3);
16539             check_mips_64(ctx);
16540             mips32_op = OPC_LWU;
16541             goto do_ld_lr;
16542         case LLD:
16543             check_insn(ctx, ISA_MIPS3);
16544             check_mips_64(ctx);
16545             mips32_op = OPC_LLD;
16546             goto do_ld_lr;
16547 #endif
16548         case LL:
16549             mips32_op = OPC_LL;
16550             goto do_ld_lr;
16551         do_ld_lr:
16552             gen_ld(ctx, mips32_op, rt, rs, offset);
16553             break;
16554         do_st_lr:
16555             gen_st(ctx, mips32_op, rt, rs, offset);
16556             break;
16557         case SC:
16558             gen_st_cond(ctx, OPC_SC, rt, rs, offset);
16559             break;
16560 #if defined(TARGET_MIPS64)
16561         case SCD:
16562             check_insn(ctx, ISA_MIPS3);
16563             check_mips_64(ctx);
16564             gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
16565             break;
16566 #endif
16567         case LD_EVA:
16568             if (!ctx->eva) {
16569                 MIPS_INVAL("pool32c ld-eva");
16570                 generate_exception_end(ctx, EXCP_RI);
16571                 break;
16572             }
16573             check_cp0_enabled(ctx);
16574
16575             minor2 = (ctx->opcode >> 9) & 0x7;
16576             offset = sextract32(ctx->opcode, 0, 9);
16577             switch (minor2) {
16578             case LBUE:
16579                 mips32_op = OPC_LBUE;
16580                 goto do_ld_lr;
16581             case LHUE:
16582                 mips32_op = OPC_LHUE;
16583                 goto do_ld_lr;
16584             case LWLE:
16585                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16586                 mips32_op = OPC_LWLE;
16587                 goto do_ld_lr;
16588             case LWRE:
16589                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16590                 mips32_op = OPC_LWRE;
16591                 goto do_ld_lr;
16592             case LBE:
16593                 mips32_op = OPC_LBE;
16594                 goto do_ld_lr;
16595             case LHE:
16596                 mips32_op = OPC_LHE;
16597                 goto do_ld_lr;
16598             case LLE:
16599                 mips32_op = OPC_LLE;
16600                 goto do_ld_lr;
16601             case LWE:
16602                 mips32_op = OPC_LWE;
16603                 goto do_ld_lr;
16604             };
16605             break;
16606         case ST_EVA:
16607             if (!ctx->eva) {
16608                 MIPS_INVAL("pool32c st-eva");
16609                 generate_exception_end(ctx, EXCP_RI);
16610                 break;
16611             }
16612             check_cp0_enabled(ctx);
16613
16614             minor2 = (ctx->opcode >> 9) & 0x7;
16615             offset = sextract32(ctx->opcode, 0, 9);
16616             switch (minor2) {
16617             case SWLE:
16618                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16619                 mips32_op = OPC_SWLE;
16620                 goto do_st_lr;
16621             case SWRE:
16622                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16623                 mips32_op = OPC_SWRE;
16624                 goto do_st_lr;
16625             case PREFE:
16626                 /* Treat as no-op */
16627                 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16628                     /* hint codes 24-31 are reserved and signal RI */
16629                     generate_exception(ctx, EXCP_RI);
16630                 }
16631                 break;
16632             case CACHEE:
16633                 /* Treat as no-op */
16634                 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
16635                     gen_cache_operation(ctx, rt, rs, offset);
16636                 }
16637                 break;
16638             case SBE:
16639                 mips32_op = OPC_SBE;
16640                 goto do_st_lr;
16641             case SHE:
16642                 mips32_op = OPC_SHE;
16643                 goto do_st_lr;
16644             case SCE:
16645                 gen_st_cond(ctx, OPC_SCE, rt, rs, offset);
16646                 break;
16647             case SWE:
16648                 mips32_op = OPC_SWE;
16649                 goto do_st_lr;
16650             };
16651             break;
16652         case PREF:
16653             /* Treat as no-op */
16654             if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16655                 /* hint codes 24-31 are reserved and signal RI */
16656                 generate_exception(ctx, EXCP_RI);
16657             }
16658             break;
16659         default:
16660             MIPS_INVAL("pool32c");
16661             generate_exception_end(ctx, EXCP_RI);
16662             break;
16663         }
16664         break;
16665     case ADDI32: /* AUI, LUI */
16666         if (ctx->insn_flags & ISA_MIPS32R6) {
16667             /* AUI, LUI */
16668             gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
16669         } else {
16670             /* ADDI32 */
16671             mips32_op = OPC_ADDI;
16672             goto do_addi;
16673         }
16674         break;
16675     case ADDIU32:
16676         mips32_op = OPC_ADDIU;
16677     do_addi:
16678         gen_arith_imm(ctx, mips32_op, rt, rs, imm);
16679         break;
16680
16681         /* Logical operations */
16682     case ORI32:
16683         mips32_op = OPC_ORI;
16684         goto do_logici;
16685     case XORI32:
16686         mips32_op = OPC_XORI;
16687         goto do_logici;
16688     case ANDI32:
16689         mips32_op = OPC_ANDI;
16690     do_logici:
16691         gen_logic_imm(ctx, mips32_op, rt, rs, imm);
16692         break;
16693
16694         /* Set less than immediate */
16695     case SLTI32:
16696         mips32_op = OPC_SLTI;
16697         goto do_slti;
16698     case SLTIU32:
16699         mips32_op = OPC_SLTIU;
16700     do_slti:
16701         gen_slt_imm(ctx, mips32_op, rt, rs, imm);
16702         break;
16703     case JALX32:
16704         check_insn_opc_removed(ctx, ISA_MIPS32R6);
16705         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
16706         gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
16707         ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16708         break;
16709     case JALS32: /* BOVC, BEQC, BEQZALC */
16710         if (ctx->insn_flags & ISA_MIPS32R6) {
16711             if (rs >= rt) {
16712                 /* BOVC */
16713                 mips32_op = OPC_BOVC;
16714             } else if (rs < rt && rs == 0) {
16715                 /* BEQZALC */
16716                 mips32_op = OPC_BEQZALC;
16717             } else {
16718                 /* BEQC */
16719                 mips32_op = OPC_BEQC;
16720             }
16721             gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16722         } else {
16723             /* JALS32 */
16724             offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
16725             gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
16726             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16727         }
16728         break;
16729     case BEQ32: /* BC */
16730         if (ctx->insn_flags & ISA_MIPS32R6) {
16731             /* BC */
16732             gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
16733                                        sextract32(ctx->opcode << 1, 0, 27));
16734         } else {
16735             /* BEQ32 */
16736             gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
16737         }
16738         break;
16739     case BNE32: /* BALC */
16740         if (ctx->insn_flags & ISA_MIPS32R6) {
16741             /* BALC */
16742             gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
16743                                        sextract32(ctx->opcode << 1, 0, 27));
16744         } else {
16745             /* BNE32 */
16746             gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
16747         }
16748         break;
16749     case J32: /* BGTZC, BLTZC, BLTC */
16750         if (ctx->insn_flags & ISA_MIPS32R6) {
16751             if (rs == 0 && rt != 0) {
16752                 /* BGTZC */
16753                 mips32_op = OPC_BGTZC;
16754             } else if (rs != 0 && rt != 0 && rs == rt) {
16755                 /* BLTZC */
16756                 mips32_op = OPC_BLTZC;
16757             } else {
16758                 /* BLTC */
16759                 mips32_op = OPC_BLTC;
16760             }
16761             gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16762         } else {
16763             /* J32 */
16764             gen_compute_branch(ctx, OPC_J, 4, rt, rs,
16765                                (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
16766         }
16767         break;
16768     case JAL32: /* BLEZC, BGEZC, BGEC */
16769         if (ctx->insn_flags & ISA_MIPS32R6) {
16770             if (rs == 0 && rt != 0) {
16771                 /* BLEZC */
16772                 mips32_op = OPC_BLEZC;
16773             } else if (rs != 0 && rt != 0 && rs == rt) {
16774                 /* BGEZC */
16775                 mips32_op = OPC_BGEZC;
16776             } else {
16777                 /* BGEC */
16778                 mips32_op = OPC_BGEC;
16779             }
16780             gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16781         } else {
16782             /* JAL32 */
16783             gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
16784                                (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
16785             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16786         }
16787         break;
16788         /* Floating point (COP1) */
16789     case LWC132:
16790         mips32_op = OPC_LWC1;
16791         goto do_cop1;
16792     case LDC132:
16793         mips32_op = OPC_LDC1;
16794         goto do_cop1;
16795     case SWC132:
16796         mips32_op = OPC_SWC1;
16797         goto do_cop1;
16798     case SDC132:
16799         mips32_op = OPC_SDC1;
16800     do_cop1:
16801         gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
16802         break;
16803     case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16804         if (ctx->insn_flags & ISA_MIPS32R6) {
16805             /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16806             switch ((ctx->opcode >> 16) & 0x1f) {
16807             case ADDIUPC_00:
16808             case ADDIUPC_01:
16809             case ADDIUPC_02:
16810             case ADDIUPC_03:
16811             case ADDIUPC_04:
16812             case ADDIUPC_05:
16813             case ADDIUPC_06:
16814             case ADDIUPC_07:
16815                 gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
16816                 break;
16817             case AUIPC:
16818                 gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
16819                 break;
16820             case ALUIPC:
16821                 gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
16822                 break;
16823             case LWPC_08:
16824             case LWPC_09:
16825             case LWPC_0A:
16826             case LWPC_0B:
16827             case LWPC_0C:
16828             case LWPC_0D:
16829             case LWPC_0E:
16830             case LWPC_0F:
16831                 gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
16832                 break;
16833             default:
16834                 generate_exception(ctx, EXCP_RI);
16835                 break;
16836             }
16837         } else {
16838             /* ADDIUPC */
16839             int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
16840             offset = SIMM(ctx->opcode, 0, 23) << 2;
16841
16842             gen_addiupc(ctx, reg, offset, 0, 0);
16843         }
16844         break;
16845     case BNVC: /* BNEC, BNEZALC */
16846         check_insn(ctx, ISA_MIPS32R6);
16847         if (rs >= rt) {
16848             /* BNVC */
16849             mips32_op = OPC_BNVC;
16850         } else if (rs < rt && rs == 0) {
16851             /* BNEZALC */
16852             mips32_op = OPC_BNEZALC;
16853         } else {
16854             /* BNEC */
16855             mips32_op = OPC_BNEC;
16856         }
16857         gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16858         break;
16859     case R6_BNEZC: /* JIALC */
16860         check_insn(ctx, ISA_MIPS32R6);
16861         if (rt != 0) {
16862             /* BNEZC */
16863             gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
16864                                        sextract32(ctx->opcode << 1, 0, 22));
16865         } else {
16866             /* JIALC */
16867             gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
16868         }
16869         break;
16870     case R6_BEQZC: /* JIC */
16871         check_insn(ctx, ISA_MIPS32R6);
16872         if (rt != 0) {
16873             /* BEQZC */
16874             gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
16875                                        sextract32(ctx->opcode << 1, 0, 22));
16876         } else {
16877             /* JIC */
16878             gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
16879         }
16880         break;
16881     case BLEZALC: /* BGEZALC, BGEUC */
16882         check_insn(ctx, ISA_MIPS32R6);
16883         if (rs == 0 && rt != 0) {
16884             /* BLEZALC */
16885             mips32_op = OPC_BLEZALC;
16886         } else if (rs != 0 && rt != 0 && rs == rt) {
16887             /* BGEZALC */
16888             mips32_op = OPC_BGEZALC;
16889         } else {
16890             /* BGEUC */
16891             mips32_op = OPC_BGEUC;
16892         }
16893         gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16894         break;
16895     case BGTZALC: /* BLTZALC, BLTUC */
16896         check_insn(ctx, ISA_MIPS32R6);
16897         if (rs == 0 && rt != 0) {
16898             /* BGTZALC */
16899             mips32_op = OPC_BGTZALC;
16900         } else if (rs != 0 && rt != 0 && rs == rt) {
16901             /* BLTZALC */
16902             mips32_op = OPC_BLTZALC;
16903         } else {
16904             /* BLTUC */
16905             mips32_op = OPC_BLTUC;
16906         }
16907         gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16908         break;
16909         /* Loads and stores */
16910     case LB32:
16911         mips32_op = OPC_LB;
16912         goto do_ld;
16913     case LBU32:
16914         mips32_op = OPC_LBU;
16915         goto do_ld;
16916     case LH32:
16917         mips32_op = OPC_LH;
16918         goto do_ld;
16919     case LHU32:
16920         mips32_op = OPC_LHU;
16921         goto do_ld;
16922     case LW32:
16923         mips32_op = OPC_LW;
16924         goto do_ld;
16925 #ifdef TARGET_MIPS64
16926     case LD32:
16927         check_insn(ctx, ISA_MIPS3);
16928         check_mips_64(ctx);
16929         mips32_op = OPC_LD;
16930         goto do_ld;
16931     case SD32:
16932         check_insn(ctx, ISA_MIPS3);
16933         check_mips_64(ctx);
16934         mips32_op = OPC_SD;
16935         goto do_st;
16936 #endif
16937     case SB32:
16938         mips32_op = OPC_SB;
16939         goto do_st;
16940     case SH32:
16941         mips32_op = OPC_SH;
16942         goto do_st;
16943     case SW32:
16944         mips32_op = OPC_SW;
16945         goto do_st;
16946     do_ld:
16947         gen_ld(ctx, mips32_op, rt, rs, imm);
16948         break;
16949     do_st:
16950         gen_st(ctx, mips32_op, rt, rs, imm);
16951         break;
16952     default:
16953         generate_exception_end(ctx, EXCP_RI);
16954         break;
16955     }
16956 }
16957
16958 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
16959 {
16960     uint32_t op;
16961
16962     /* make sure instructions are on a halfword boundary */
16963     if (ctx->base.pc_next & 0x1) {
16964         env->CP0_BadVAddr = ctx->base.pc_next;
16965         generate_exception_end(ctx, EXCP_AdEL);
16966         return 2;
16967     }
16968
16969     op = (ctx->opcode >> 10) & 0x3f;
16970     /* Enforce properly-sized instructions in a delay slot */
16971     if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
16972         switch (op & 0x7) { /* MSB-3..MSB-5 */
16973         case 0:
16974         /* POOL32A, POOL32B, POOL32I, POOL32C */
16975         case 4:
16976         /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
16977         case 5:
16978         /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
16979         case 6:
16980         /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
16981         case 7:
16982         /* LB32, LH32, LWC132, LDC132, LW32 */
16983             if (ctx->hflags & MIPS_HFLAG_BDS16) {
16984                 generate_exception_end(ctx, EXCP_RI);
16985                 return 2;
16986             }
16987             break;
16988         case 1:
16989         /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
16990         case 2:
16991         /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
16992         case 3:
16993         /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
16994             if (ctx->hflags & MIPS_HFLAG_BDS32) {
16995                 generate_exception_end(ctx, EXCP_RI);
16996                 return 2;
16997             }
16998             break;
16999         }
17000     }
17001
17002     switch (op) {
17003     case POOL16A:
17004         {
17005             int rd = mmreg(uMIPS_RD(ctx->opcode));
17006             int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
17007             int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
17008             uint32_t opc = 0;
17009
17010             switch (ctx->opcode & 0x1) {
17011             case ADDU16:
17012                 opc = OPC_ADDU;
17013                 break;
17014             case SUBU16:
17015                 opc = OPC_SUBU;
17016                 break;
17017             }
17018             if (ctx->insn_flags & ISA_MIPS32R6) {
17019                 /* In the Release 6 the register number location in
17020                  * the instruction encoding has changed.
17021                  */
17022                 gen_arith(ctx, opc, rs1, rd, rs2);
17023             } else {
17024                 gen_arith(ctx, opc, rd, rs1, rs2);
17025             }
17026         }
17027         break;
17028     case POOL16B:
17029         {
17030             int rd = mmreg(uMIPS_RD(ctx->opcode));
17031             int rs = mmreg(uMIPS_RS(ctx->opcode));
17032             int amount = (ctx->opcode >> 1) & 0x7;
17033             uint32_t opc = 0;
17034             amount = amount == 0 ? 8 : amount;
17035
17036             switch (ctx->opcode & 0x1) {
17037             case SLL16:
17038                 opc = OPC_SLL;
17039                 break;
17040             case SRL16:
17041                 opc = OPC_SRL;
17042                 break;
17043             }
17044
17045             gen_shift_imm(ctx, opc, rd, rs, amount);
17046         }
17047         break;
17048     case POOL16C:
17049         if (ctx->insn_flags & ISA_MIPS32R6) {
17050             gen_pool16c_r6_insn(ctx);
17051         } else {
17052             gen_pool16c_insn(ctx);
17053         }
17054         break;
17055     case LWGP16:
17056         {
17057             int rd = mmreg(uMIPS_RD(ctx->opcode));
17058             int rb = 28;            /* GP */
17059             int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
17060
17061             gen_ld(ctx, OPC_LW, rd, rb, offset);
17062         }
17063         break;
17064     case POOL16F:
17065         check_insn_opc_removed(ctx, ISA_MIPS32R6);
17066         if (ctx->opcode & 1) {
17067             generate_exception_end(ctx, EXCP_RI);
17068         } else {
17069             /* MOVEP */
17070             int enc_dest = uMIPS_RD(ctx->opcode);
17071             int enc_rt = uMIPS_RS2(ctx->opcode);
17072             int enc_rs = uMIPS_RS1(ctx->opcode);
17073             gen_movep(ctx, enc_dest, enc_rt, enc_rs);
17074         }
17075         break;
17076     case LBU16:
17077         {
17078             int rd = mmreg(uMIPS_RD(ctx->opcode));
17079             int rb = mmreg(uMIPS_RS(ctx->opcode));
17080             int16_t offset = ZIMM(ctx->opcode, 0, 4);
17081             offset = (offset == 0xf ? -1 : offset);
17082
17083             gen_ld(ctx, OPC_LBU, rd, rb, offset);
17084         }
17085         break;
17086     case LHU16:
17087         {
17088             int rd = mmreg(uMIPS_RD(ctx->opcode));
17089             int rb = mmreg(uMIPS_RS(ctx->opcode));
17090             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17091
17092             gen_ld(ctx, OPC_LHU, rd, rb, offset);
17093         }
17094         break;
17095     case LWSP16:
17096         {
17097             int rd = (ctx->opcode >> 5) & 0x1f;
17098             int rb = 29;            /* SP */
17099             int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17100
17101             gen_ld(ctx, OPC_LW, rd, rb, offset);
17102         }
17103         break;
17104     case LW16:
17105         {
17106             int rd = mmreg(uMIPS_RD(ctx->opcode));
17107             int rb = mmreg(uMIPS_RS(ctx->opcode));
17108             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17109
17110             gen_ld(ctx, OPC_LW, rd, rb, offset);
17111         }
17112         break;
17113     case SB16:
17114         {
17115             int rd = mmreg2(uMIPS_RD(ctx->opcode));
17116             int rb = mmreg(uMIPS_RS(ctx->opcode));
17117             int16_t offset = ZIMM(ctx->opcode, 0, 4);
17118
17119             gen_st(ctx, OPC_SB, rd, rb, offset);
17120         }
17121         break;
17122     case SH16:
17123         {
17124             int rd = mmreg2(uMIPS_RD(ctx->opcode));
17125             int rb = mmreg(uMIPS_RS(ctx->opcode));
17126             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17127
17128             gen_st(ctx, OPC_SH, rd, rb, offset);
17129         }
17130         break;
17131     case SWSP16:
17132         {
17133             int rd = (ctx->opcode >> 5) & 0x1f;
17134             int rb = 29;            /* SP */
17135             int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17136
17137             gen_st(ctx, OPC_SW, rd, rb, offset);
17138         }
17139         break;
17140     case SW16:
17141         {
17142             int rd = mmreg2(uMIPS_RD(ctx->opcode));
17143             int rb = mmreg(uMIPS_RS(ctx->opcode));
17144             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17145
17146             gen_st(ctx, OPC_SW, rd, rb, offset);
17147         }
17148         break;
17149     case MOVE16:
17150         {
17151             int rd = uMIPS_RD5(ctx->opcode);
17152             int rs = uMIPS_RS5(ctx->opcode);
17153
17154             gen_arith(ctx, OPC_ADDU, rd, rs, 0);
17155         }
17156         break;
17157     case ANDI16:
17158         gen_andi16(ctx);
17159         break;
17160     case POOL16D:
17161         switch (ctx->opcode & 0x1) {
17162         case ADDIUS5:
17163             gen_addius5(ctx);
17164             break;
17165         case ADDIUSP:
17166             gen_addiusp(ctx);
17167             break;
17168         }
17169         break;
17170     case POOL16E:
17171         switch (ctx->opcode & 0x1) {
17172         case ADDIUR2:
17173             gen_addiur2(ctx);
17174             break;
17175         case ADDIUR1SP:
17176             gen_addiur1sp(ctx);
17177             break;
17178         }
17179         break;
17180     case B16: /* BC16 */
17181         gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
17182                            sextract32(ctx->opcode, 0, 10) << 1,
17183                            (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17184         break;
17185     case BNEZ16: /* BNEZC16 */
17186     case BEQZ16: /* BEQZC16 */
17187         gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
17188                            mmreg(uMIPS_RD(ctx->opcode)),
17189                            0, sextract32(ctx->opcode, 0, 7) << 1,
17190                            (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17191
17192         break;
17193     case LI16:
17194         {
17195             int reg = mmreg(uMIPS_RD(ctx->opcode));
17196             int imm = ZIMM(ctx->opcode, 0, 7);
17197
17198             imm = (imm == 0x7f ? -1 : imm);
17199             tcg_gen_movi_tl(cpu_gpr[reg], imm);
17200         }
17201         break;
17202     case RES_29:
17203     case RES_31:
17204     case RES_39:
17205         generate_exception_end(ctx, EXCP_RI);
17206         break;
17207     default:
17208         decode_micromips32_opc(env, ctx);
17209         return 4;
17210     }
17211
17212     return 2;
17213 }
17214
17215 /*
17216  *
17217  * nanoMIPS opcodes
17218  *
17219  */
17220
17221 /* MAJOR, P16, and P32 pools opcodes */
17222 enum {
17223     NM_P_ADDIU      = 0x00,
17224     NM_ADDIUPC      = 0x01,
17225     NM_MOVE_BALC    = 0x02,
17226     NM_P16_MV       = 0x04,
17227     NM_LW16         = 0x05,
17228     NM_BC16         = 0x06,
17229     NM_P16_SR       = 0x07,
17230
17231     NM_POOL32A      = 0x08,
17232     NM_P_BAL        = 0x0a,
17233     NM_P16_SHIFT    = 0x0c,
17234     NM_LWSP16       = 0x0d,
17235     NM_BALC16       = 0x0e,
17236     NM_P16_4X4      = 0x0f,
17237
17238     NM_P_GP_W       = 0x10,
17239     NM_P_GP_BH      = 0x11,
17240     NM_P_J          = 0x12,
17241     NM_P16C         = 0x14,
17242     NM_LWGP16       = 0x15,
17243     NM_P16_LB       = 0x17,
17244
17245     NM_P48I         = 0x18,
17246     NM_P16_A1       = 0x1c,
17247     NM_LW4X4        = 0x1d,
17248     NM_P16_LH       = 0x1f,
17249
17250     NM_P_U12        = 0x20,
17251     NM_P_LS_U12     = 0x21,
17252     NM_P_BR1        = 0x22,
17253     NM_P16_A2       = 0x24,
17254     NM_SW16         = 0x25,
17255     NM_BEQZC16      = 0x26,
17256
17257     NM_POOL32F      = 0x28,
17258     NM_P_LS_S9      = 0x29,
17259     NM_P_BR2        = 0x2a,
17260
17261     NM_P16_ADDU     = 0x2c,
17262     NM_SWSP16       = 0x2d,
17263     NM_BNEZC16      = 0x2e,
17264     NM_MOVEP        = 0x2f,
17265
17266     NM_POOL32S      = 0x30,
17267     NM_P_BRI        = 0x32,
17268     NM_LI16         = 0x34,
17269     NM_SWGP16       = 0x35,
17270     NM_P16_BR       = 0x36,
17271
17272     NM_P_LUI        = 0x38,
17273     NM_ANDI16       = 0x3c,
17274     NM_SW4X4        = 0x3d,
17275     NM_MOVEPREV     = 0x3f,
17276 };
17277
17278 /* POOL32A instruction pool */
17279 enum {
17280     NM_POOL32A0    = 0x00,
17281     NM_SPECIAL2    = 0x01,
17282     NM_COP2_1      = 0x02,
17283     NM_UDI         = 0x03,
17284     NM_POOL32A5    = 0x05,
17285     NM_POOL32A7    = 0x07,
17286 };
17287
17288 /* P.GP.W instruction pool */
17289 enum {
17290     NM_ADDIUGP_W = 0x00,
17291     NM_LWGP      = 0x02,
17292     NM_SWGP      = 0x03,
17293 };
17294
17295 /* P48I instruction pool */
17296 enum {
17297     NM_LI48        = 0x00,
17298     NM_ADDIU48     = 0x01,
17299     NM_ADDIUGP48   = 0x02,
17300     NM_ADDIUPC48   = 0x03,
17301     NM_LWPC48      = 0x0b,
17302     NM_SWPC48      = 0x0f,
17303 };
17304
17305 /* P.U12 instruction pool */
17306 enum {
17307     NM_ORI      = 0x00,
17308     NM_XORI     = 0x01,
17309     NM_ANDI     = 0x02,
17310     NM_P_SR     = 0x03,
17311     NM_SLTI     = 0x04,
17312     NM_SLTIU    = 0x05,
17313     NM_SEQI     = 0x06,
17314     NM_ADDIUNEG = 0x08,
17315     NM_P_SHIFT  = 0x0c,
17316     NM_P_ROTX   = 0x0d,
17317     NM_P_INS    = 0x0e,
17318     NM_P_EXT    = 0x0f,
17319 };
17320
17321 /* POOL32F instruction pool */
17322 enum {
17323     NM_POOL32F_0   = 0x00,
17324     NM_POOL32F_3   = 0x03,
17325     NM_POOL32F_5   = 0x05,
17326 };
17327
17328 /* POOL32S instruction pool */
17329 enum {
17330     NM_POOL32S_0   = 0x00,
17331     NM_POOL32S_4   = 0x04,
17332 };
17333
17334 /* P.LUI instruction pool */
17335 enum {
17336     NM_LUI      = 0x00,
17337     NM_ALUIPC   = 0x01,
17338 };
17339
17340 /* P.GP.BH instruction pool */
17341 enum {
17342     NM_LBGP      = 0x00,
17343     NM_SBGP      = 0x01,
17344     NM_LBUGP     = 0x02,
17345     NM_ADDIUGP_B = 0x03,
17346     NM_P_GP_LH   = 0x04,
17347     NM_P_GP_SH   = 0x05,
17348     NM_P_GP_CP1  = 0x06,
17349 };
17350
17351 /* P.LS.U12 instruction pool */
17352 enum {
17353     NM_LB        = 0x00,
17354     NM_SB        = 0x01,
17355     NM_LBU       = 0x02,
17356     NM_P_PREFU12 = 0x03,
17357     NM_LH        = 0x04,
17358     NM_SH        = 0x05,
17359     NM_LHU       = 0x06,
17360     NM_LWU       = 0x07,
17361     NM_LW        = 0x08,
17362     NM_SW        = 0x09,
17363     NM_LWC1      = 0x0a,
17364     NM_SWC1      = 0x0b,
17365     NM_LDC1      = 0x0e,
17366     NM_SDC1      = 0x0f,
17367 };
17368
17369 /* P.LS.S9 instruction pool */
17370 enum {
17371     NM_P_LS_S0         = 0x00,
17372     NM_P_LS_S1         = 0x01,
17373     NM_P_LS_E0         = 0x02,
17374     NM_P_LS_WM         = 0x04,
17375     NM_P_LS_UAWM       = 0x05,
17376 };
17377
17378 /* P.BAL instruction pool */
17379 enum {
17380     NM_BC       = 0x00,
17381     NM_BALC     = 0x01,
17382 };
17383
17384 /* P.J instruction pool */
17385 enum {
17386     NM_JALRC    = 0x00,
17387     NM_JALRC_HB = 0x01,
17388     NM_P_BALRSC = 0x08,
17389 };
17390
17391 /* P.BR1 instruction pool */
17392 enum {
17393     NM_BEQC     = 0x00,
17394     NM_P_BR3A   = 0x01,
17395     NM_BGEC     = 0x02,
17396     NM_BGEUC    = 0x03,
17397 };
17398
17399 /* P.BR2 instruction pool */
17400 enum {
17401     NM_BNEC     = 0x00,
17402     NM_BLTC     = 0x02,
17403     NM_BLTUC    = 0x03,
17404 };
17405
17406 /* P.BRI instruction pool */
17407 enum {
17408     NM_BEQIC    = 0x00,
17409     NM_BBEQZC   = 0x01,
17410     NM_BGEIC    = 0x02,
17411     NM_BGEIUC   = 0x03,
17412     NM_BNEIC    = 0x04,
17413     NM_BBNEZC   = 0x05,
17414     NM_BLTIC    = 0x06,
17415     NM_BLTIUC   = 0x07,
17416 };
17417
17418 /* P16.SHIFT instruction pool */
17419 enum {
17420     NM_SLL16    = 0x00,
17421     NM_SRL16    = 0x01,
17422 };
17423
17424 /* POOL16C instruction pool */
17425 enum {
17426     NM_POOL16C_0  = 0x00,
17427     NM_LWXS16     = 0x01,
17428 };
17429
17430 /* P16.A1 instruction pool */
17431 enum {
17432     NM_ADDIUR1SP = 0x01,
17433 };
17434
17435 /* P16.A2 instruction pool */
17436 enum {
17437     NM_ADDIUR2  = 0x00,
17438     NM_P_ADDIURS5  = 0x01,
17439 };
17440
17441 /* P16.ADDU instruction pool */
17442 enum {
17443     NM_ADDU16     = 0x00,
17444     NM_SUBU16     = 0x01,
17445 };
17446
17447 /* P16.SR instruction pool */
17448 enum {
17449     NM_SAVE16        = 0x00,
17450     NM_RESTORE_JRC16 = 0x01,
17451 };
17452
17453 /* P16.4X4 instruction pool */
17454 enum {
17455     NM_ADDU4X4      = 0x00,
17456     NM_MUL4X4       = 0x01,
17457 };
17458
17459 /* P16.LB instruction pool */
17460 enum {
17461     NM_LB16       = 0x00,
17462     NM_SB16       = 0x01,
17463     NM_LBU16      = 0x02,
17464 };
17465
17466 /* P16.LH  instruction pool */
17467 enum {
17468     NM_LH16     = 0x00,
17469     NM_SH16     = 0x01,
17470     NM_LHU16    = 0x02,
17471 };
17472
17473 /* P.RI instruction pool */
17474 enum {
17475     NM_SIGRIE       = 0x00,
17476     NM_P_SYSCALL    = 0x01,
17477     NM_BREAK        = 0x02,
17478     NM_SDBBP        = 0x03,
17479 };
17480
17481 /* POOL32A0 instruction pool */
17482 enum {
17483     NM_P_TRAP   = 0x00,
17484     NM_SEB      = 0x01,
17485     NM_SLLV     = 0x02,
17486     NM_MUL      = 0x03,
17487     NM_MFC0     = 0x06,
17488     NM_MFHC0    = 0x07,
17489     NM_SEH      = 0x09,
17490     NM_SRLV     = 0x0a,
17491     NM_MUH      = 0x0b,
17492     NM_MTC0     = 0x0e,
17493     NM_MTHC0    = 0x0f,
17494     NM_SRAV     = 0x12,
17495     NM_MULU     = 0x13,
17496     NM_ROTRV    = 0x1a,
17497     NM_MUHU     = 0x1b,
17498     NM_ADD      = 0x22,
17499     NM_DIV      = 0x23,
17500     NM_ADDU     = 0x2a,
17501     NM_MOD      = 0x2b,
17502     NM_SUB      = 0x32,
17503     NM_DIVU     = 0x33,
17504     NM_RDHWR    = 0x38,
17505     NM_SUBU     = 0x3a,
17506     NM_MODU     = 0x3b,
17507     NM_P_CMOVE  = 0x42,
17508     NM_FORK     = 0x45,
17509     NM_MFTR     = 0x46,
17510     NM_MFHTR    = 0x47,
17511     NM_AND      = 0x4a,
17512     NM_YIELD    = 0x4d,
17513     NM_MTTR     = 0x4e,
17514     NM_MTHTR    = 0x4f,
17515     NM_OR       = 0x52,
17516     NM_D_E_MT_VPE = 0x56,
17517     NM_NOR      = 0x5a,
17518     NM_XOR      = 0x62,
17519     NM_SLT      = 0x6a,
17520     NM_P_SLTU   = 0x72,
17521     NM_SOV      = 0x7a,
17522 };
17523
17524 /* CRC32 instruction pool */
17525 enum {
17526     NM_CRC32B   = 0x00,
17527     NM_CRC32H   = 0x01,
17528     NM_CRC32W   = 0x02,
17529     NM_CRC32CB  = 0x04,
17530     NM_CRC32CH  = 0x05,
17531     NM_CRC32CW  = 0x06,
17532 };
17533
17534 /* POOL32A5 instruction pool */
17535 enum {
17536     NM_CMP_EQ_PH        = 0x00,
17537     NM_CMP_LT_PH        = 0x08,
17538     NM_CMP_LE_PH        = 0x10,
17539     NM_CMPGU_EQ_QB      = 0x18,
17540     NM_CMPGU_LT_QB      = 0x20,
17541     NM_CMPGU_LE_QB      = 0x28,
17542     NM_CMPGDU_EQ_QB     = 0x30,
17543     NM_CMPGDU_LT_QB     = 0x38,
17544     NM_CMPGDU_LE_QB     = 0x40,
17545     NM_CMPU_EQ_QB       = 0x48,
17546     NM_CMPU_LT_QB       = 0x50,
17547     NM_CMPU_LE_QB       = 0x58,
17548     NM_ADDQ_S_W         = 0x60,
17549     NM_SUBQ_S_W         = 0x68,
17550     NM_ADDSC            = 0x70,
17551     NM_ADDWC            = 0x78,
17552
17553     NM_ADDQ_S_PH   = 0x01,
17554     NM_ADDQH_R_PH  = 0x09,
17555     NM_ADDQH_R_W   = 0x11,
17556     NM_ADDU_S_QB   = 0x19,
17557     NM_ADDU_S_PH   = 0x21,
17558     NM_ADDUH_R_QB  = 0x29,
17559     NM_SHRAV_R_PH  = 0x31,
17560     NM_SHRAV_R_QB  = 0x39,
17561     NM_SUBQ_S_PH   = 0x41,
17562     NM_SUBQH_R_PH  = 0x49,
17563     NM_SUBQH_R_W   = 0x51,
17564     NM_SUBU_S_QB   = 0x59,
17565     NM_SUBU_S_PH   = 0x61,
17566     NM_SUBUH_R_QB  = 0x69,
17567     NM_SHLLV_S_PH  = 0x71,
17568     NM_PRECR_SRA_R_PH_W = 0x79,
17569
17570     NM_MULEU_S_PH_QBL   = 0x12,
17571     NM_MULEU_S_PH_QBR   = 0x1a,
17572     NM_MULQ_RS_PH       = 0x22,
17573     NM_MULQ_S_PH        = 0x2a,
17574     NM_MULQ_RS_W        = 0x32,
17575     NM_MULQ_S_W         = 0x3a,
17576     NM_APPEND           = 0x42,
17577     NM_MODSUB           = 0x52,
17578     NM_SHRAV_R_W        = 0x5a,
17579     NM_SHRLV_PH         = 0x62,
17580     NM_SHRLV_QB         = 0x6a,
17581     NM_SHLLV_QB         = 0x72,
17582     NM_SHLLV_S_W        = 0x7a,
17583
17584     NM_SHILO            = 0x03,
17585
17586     NM_MULEQ_S_W_PHL    = 0x04,
17587     NM_MULEQ_S_W_PHR    = 0x0c,
17588
17589     NM_MUL_S_PH         = 0x05,
17590     NM_PRECR_QB_PH      = 0x0d,
17591     NM_PRECRQ_QB_PH     = 0x15,
17592     NM_PRECRQ_PH_W      = 0x1d,
17593     NM_PRECRQ_RS_PH_W   = 0x25,
17594     NM_PRECRQU_S_QB_PH  = 0x2d,
17595     NM_PACKRL_PH        = 0x35,
17596     NM_PICK_QB          = 0x3d,
17597     NM_PICK_PH          = 0x45,
17598
17599     NM_SHRA_R_W         = 0x5e,
17600     NM_SHRA_R_PH        = 0x66,
17601     NM_SHLL_S_PH        = 0x76,
17602     NM_SHLL_S_W         = 0x7e,
17603
17604     NM_REPL_PH          = 0x07
17605 };
17606
17607 /* POOL32A7 instruction pool */
17608 enum {
17609     NM_P_LSX        = 0x00,
17610     NM_LSA          = 0x01,
17611     NM_EXTW         = 0x03,
17612     NM_POOL32AXF    = 0x07,
17613 };
17614
17615 /* P.SR instruction pool */
17616 enum {
17617     NM_PP_SR           = 0x00,
17618     NM_P_SR_F          = 0x01,
17619 };
17620
17621 /* P.SHIFT instruction pool */
17622 enum {
17623     NM_P_SLL        = 0x00,
17624     NM_SRL          = 0x02,
17625     NM_SRA          = 0x04,
17626     NM_ROTR         = 0x06,
17627 };
17628
17629 /* P.ROTX instruction pool */
17630 enum {
17631     NM_ROTX         = 0x00,
17632 };
17633
17634 /* P.INS instruction pool */
17635 enum {
17636     NM_INS          = 0x00,
17637 };
17638
17639 /* P.EXT instruction pool */
17640 enum {
17641     NM_EXT          = 0x00,
17642 };
17643
17644 /* POOL32F_0 (fmt) instruction pool */
17645 enum {
17646     NM_RINT_S              = 0x04,
17647     NM_RINT_D              = 0x44,
17648     NM_ADD_S               = 0x06,
17649     NM_SELEQZ_S            = 0x07,
17650     NM_SELEQZ_D            = 0x47,
17651     NM_CLASS_S             = 0x0c,
17652     NM_CLASS_D             = 0x4c,
17653     NM_SUB_S               = 0x0e,
17654     NM_SELNEZ_S            = 0x0f,
17655     NM_SELNEZ_D            = 0x4f,
17656     NM_MUL_S               = 0x16,
17657     NM_SEL_S               = 0x17,
17658     NM_SEL_D               = 0x57,
17659     NM_DIV_S               = 0x1e,
17660     NM_ADD_D               = 0x26,
17661     NM_SUB_D               = 0x2e,
17662     NM_MUL_D               = 0x36,
17663     NM_MADDF_S             = 0x37,
17664     NM_MADDF_D             = 0x77,
17665     NM_DIV_D               = 0x3e,
17666     NM_MSUBF_S             = 0x3f,
17667     NM_MSUBF_D             = 0x7f,
17668 };
17669
17670 /* POOL32F_3  instruction pool */
17671 enum {
17672     NM_MIN_FMT         = 0x00,
17673     NM_MAX_FMT         = 0x01,
17674     NM_MINA_FMT        = 0x04,
17675     NM_MAXA_FMT        = 0x05,
17676     NM_POOL32FXF       = 0x07,
17677 };
17678
17679 /* POOL32F_5  instruction pool */
17680 enum {
17681     NM_CMP_CONDN_S     = 0x00,
17682     NM_CMP_CONDN_D     = 0x02,
17683 };
17684
17685 /* P.GP.LH instruction pool */
17686 enum {
17687     NM_LHGP    = 0x00,
17688     NM_LHUGP   = 0x01,
17689 };
17690
17691 /* P.GP.SH instruction pool */
17692 enum {
17693     NM_SHGP    = 0x00,
17694 };
17695
17696 /* P.GP.CP1 instruction pool */
17697 enum {
17698     NM_LWC1GP       = 0x00,
17699     NM_SWC1GP       = 0x01,
17700     NM_LDC1GP       = 0x02,
17701     NM_SDC1GP       = 0x03,
17702 };
17703
17704 /* P.LS.S0 instruction pool */
17705 enum {
17706     NM_LBS9     = 0x00,
17707     NM_LHS9     = 0x04,
17708     NM_LWS9     = 0x08,
17709     NM_LDS9     = 0x0c,
17710
17711     NM_SBS9     = 0x01,
17712     NM_SHS9     = 0x05,
17713     NM_SWS9     = 0x09,
17714     NM_SDS9     = 0x0d,
17715
17716     NM_LBUS9    = 0x02,
17717     NM_LHUS9    = 0x06,
17718     NM_LWC1S9   = 0x0a,
17719     NM_LDC1S9   = 0x0e,
17720
17721     NM_P_PREFS9 = 0x03,
17722     NM_LWUS9    = 0x07,
17723     NM_SWC1S9   = 0x0b,
17724     NM_SDC1S9   = 0x0f,
17725 };
17726
17727 /* P.LS.S1 instruction pool */
17728 enum {
17729     NM_ASET_ACLR = 0x02,
17730     NM_UALH      = 0x04,
17731     NM_UASH      = 0x05,
17732     NM_CACHE     = 0x07,
17733     NM_P_LL      = 0x0a,
17734     NM_P_SC      = 0x0b,
17735 };
17736
17737 /* P.LS.E0 instruction pool */
17738 enum {
17739     NM_LBE      = 0x00,
17740     NM_SBE      = 0x01,
17741     NM_LBUE     = 0x02,
17742     NM_P_PREFE  = 0x03,
17743     NM_LHE      = 0x04,
17744     NM_SHE      = 0x05,
17745     NM_LHUE     = 0x06,
17746     NM_CACHEE   = 0x07,
17747     NM_LWE      = 0x08,
17748     NM_SWE      = 0x09,
17749     NM_P_LLE    = 0x0a,
17750     NM_P_SCE    = 0x0b,
17751 };
17752
17753 /* P.PREFE instruction pool */
17754 enum {
17755     NM_SYNCIE   = 0x00,
17756     NM_PREFE    = 0x01,
17757 };
17758
17759 /* P.LLE instruction pool */
17760 enum {
17761     NM_LLE      = 0x00,
17762     NM_LLWPE    = 0x01,
17763 };
17764
17765 /* P.SCE instruction pool */
17766 enum {
17767     NM_SCE      = 0x00,
17768     NM_SCWPE    = 0x01,
17769 };
17770
17771 /* P.LS.WM instruction pool */
17772 enum {
17773     NM_LWM       = 0x00,
17774     NM_SWM       = 0x01,
17775 };
17776
17777 /* P.LS.UAWM instruction pool */
17778 enum {
17779     NM_UALWM       = 0x00,
17780     NM_UASWM       = 0x01,
17781 };
17782
17783 /* P.BR3A instruction pool */
17784 enum {
17785     NM_BC1EQZC          = 0x00,
17786     NM_BC1NEZC          = 0x01,
17787     NM_BC2EQZC          = 0x02,
17788     NM_BC2NEZC          = 0x03,
17789     NM_BPOSGE32C        = 0x04,
17790 };
17791
17792 /* P16.RI instruction pool */
17793 enum {
17794     NM_P16_SYSCALL  = 0x01,
17795     NM_BREAK16      = 0x02,
17796     NM_SDBBP16      = 0x03,
17797 };
17798
17799 /* POOL16C_0 instruction pool */
17800 enum {
17801     NM_POOL16C_00      = 0x00,
17802 };
17803
17804 /* P16.JRC instruction pool */
17805 enum {
17806     NM_JRC          = 0x00,
17807     NM_JALRC16      = 0x01,
17808 };
17809
17810 /* P.SYSCALL instruction pool */
17811 enum {
17812     NM_SYSCALL      = 0x00,
17813     NM_HYPCALL      = 0x01,
17814 };
17815
17816 /* P.TRAP instruction pool */
17817 enum {
17818     NM_TEQ          = 0x00,
17819     NM_TNE          = 0x01,
17820 };
17821
17822 /* P.CMOVE instruction pool */
17823 enum {
17824     NM_MOVZ            = 0x00,
17825     NM_MOVN            = 0x01,
17826 };
17827
17828 /* POOL32Axf instruction pool */
17829 enum {
17830     NM_POOL32AXF_1 = 0x01,
17831     NM_POOL32AXF_2 = 0x02,
17832     NM_POOL32AXF_4 = 0x04,
17833     NM_POOL32AXF_5 = 0x05,
17834     NM_POOL32AXF_7 = 0x07,
17835 };
17836
17837 /* POOL32Axf_1 instruction pool */
17838 enum {
17839     NM_POOL32AXF_1_0 = 0x00,
17840     NM_POOL32AXF_1_1 = 0x01,
17841     NM_POOL32AXF_1_3 = 0x03,
17842     NM_POOL32AXF_1_4 = 0x04,
17843     NM_POOL32AXF_1_5 = 0x05,
17844     NM_POOL32AXF_1_7 = 0x07,
17845 };
17846
17847 /* POOL32Axf_2 instruction pool */
17848 enum {
17849     NM_POOL32AXF_2_0_7     = 0x00,
17850     NM_POOL32AXF_2_8_15    = 0x01,
17851     NM_POOL32AXF_2_16_23   = 0x02,
17852     NM_POOL32AXF_2_24_31   = 0x03,
17853 };
17854
17855 /* POOL32Axf_7 instruction pool */
17856 enum {
17857     NM_SHRA_R_QB    = 0x0,
17858     NM_SHRL_PH      = 0x1,
17859     NM_REPL_QB      = 0x2,
17860 };
17861
17862 /* POOL32Axf_1_0 instruction pool */
17863 enum {
17864     NM_MFHI = 0x0,
17865     NM_MFLO = 0x1,
17866     NM_MTHI = 0x2,
17867     NM_MTLO = 0x3,
17868 };
17869
17870 /* POOL32Axf_1_1 instruction pool */
17871 enum {
17872     NM_MTHLIP = 0x0,
17873     NM_SHILOV = 0x1,
17874 };
17875
17876 /* POOL32Axf_1_3 instruction pool */
17877 enum {
17878     NM_RDDSP    = 0x0,
17879     NM_WRDSP    = 0x1,
17880     NM_EXTP     = 0x2,
17881     NM_EXTPDP   = 0x3,
17882 };
17883
17884 /* POOL32Axf_1_4 instruction pool */
17885 enum {
17886     NM_SHLL_QB  = 0x0,
17887     NM_SHRL_QB  = 0x1,
17888 };
17889
17890 /* POOL32Axf_1_5 instruction pool */
17891 enum {
17892     NM_MAQ_S_W_PHR   = 0x0,
17893     NM_MAQ_S_W_PHL   = 0x1,
17894     NM_MAQ_SA_W_PHR  = 0x2,
17895     NM_MAQ_SA_W_PHL  = 0x3,
17896 };
17897
17898 /* POOL32Axf_1_7 instruction pool */
17899 enum {
17900     NM_EXTR_W       = 0x0,
17901     NM_EXTR_R_W     = 0x1,
17902     NM_EXTR_RS_W    = 0x2,
17903     NM_EXTR_S_H     = 0x3,
17904 };
17905
17906 /* POOL32Axf_2_0_7 instruction pool */
17907 enum {
17908     NM_DPA_W_PH     = 0x0,
17909     NM_DPAQ_S_W_PH  = 0x1,
17910     NM_DPS_W_PH     = 0x2,
17911     NM_DPSQ_S_W_PH  = 0x3,
17912     NM_BALIGN       = 0x4,
17913     NM_MADD         = 0x5,
17914     NM_MULT         = 0x6,
17915     NM_EXTRV_W      = 0x7,
17916 };
17917
17918 /* POOL32Axf_2_8_15 instruction pool */
17919 enum {
17920     NM_DPAX_W_PH    = 0x0,
17921     NM_DPAQ_SA_L_W  = 0x1,
17922     NM_DPSX_W_PH    = 0x2,
17923     NM_DPSQ_SA_L_W  = 0x3,
17924     NM_MADDU        = 0x5,
17925     NM_MULTU        = 0x6,
17926     NM_EXTRV_R_W    = 0x7,
17927 };
17928
17929 /* POOL32Axf_2_16_23 instruction pool */
17930 enum {
17931     NM_DPAU_H_QBL       = 0x0,
17932     NM_DPAQX_S_W_PH     = 0x1,
17933     NM_DPSU_H_QBL       = 0x2,
17934     NM_DPSQX_S_W_PH     = 0x3,
17935     NM_EXTPV            = 0x4,
17936     NM_MSUB             = 0x5,
17937     NM_MULSA_W_PH       = 0x6,
17938     NM_EXTRV_RS_W       = 0x7,
17939 };
17940
17941 /* POOL32Axf_2_24_31 instruction pool */
17942 enum {
17943     NM_DPAU_H_QBR       = 0x0,
17944     NM_DPAQX_SA_W_PH    = 0x1,
17945     NM_DPSU_H_QBR       = 0x2,
17946     NM_DPSQX_SA_W_PH    = 0x3,
17947     NM_EXTPDPV          = 0x4,
17948     NM_MSUBU            = 0x5,
17949     NM_MULSAQ_S_W_PH    = 0x6,
17950     NM_EXTRV_S_H        = 0x7,
17951 };
17952
17953 /* POOL32Axf_{4, 5} instruction pool */
17954 enum {
17955     NM_CLO      = 0x25,
17956     NM_CLZ      = 0x2d,
17957
17958     NM_TLBP     = 0x01,
17959     NM_TLBR     = 0x09,
17960     NM_TLBWI    = 0x11,
17961     NM_TLBWR    = 0x19,
17962     NM_TLBINV   = 0x03,
17963     NM_TLBINVF  = 0x0b,
17964     NM_DI       = 0x23,
17965     NM_EI       = 0x2b,
17966     NM_RDPGPR   = 0x70,
17967     NM_WRPGPR   = 0x78,
17968     NM_WAIT     = 0x61,
17969     NM_DERET    = 0x71,
17970     NM_ERETX    = 0x79,
17971
17972     /* nanoMIPS DSP instructions */
17973     NM_ABSQ_S_QB        = 0x00,
17974     NM_ABSQ_S_PH        = 0x08,
17975     NM_ABSQ_S_W         = 0x10,
17976     NM_PRECEQ_W_PHL     = 0x28,
17977     NM_PRECEQ_W_PHR     = 0x30,
17978     NM_PRECEQU_PH_QBL   = 0x38,
17979     NM_PRECEQU_PH_QBR   = 0x48,
17980     NM_PRECEU_PH_QBL    = 0x58,
17981     NM_PRECEU_PH_QBR    = 0x68,
17982     NM_PRECEQU_PH_QBLA  = 0x39,
17983     NM_PRECEQU_PH_QBRA  = 0x49,
17984     NM_PRECEU_PH_QBLA   = 0x59,
17985     NM_PRECEU_PH_QBRA   = 0x69,
17986     NM_REPLV_PH         = 0x01,
17987     NM_REPLV_QB         = 0x09,
17988     NM_BITREV           = 0x18,
17989     NM_INSV             = 0x20,
17990     NM_RADDU_W_QB       = 0x78,
17991
17992     NM_BITSWAP          = 0x05,
17993     NM_WSBH             = 0x3d,
17994 };
17995
17996 /* PP.SR instruction pool */
17997 enum {
17998     NM_SAVE         = 0x00,
17999     NM_RESTORE      = 0x02,
18000     NM_RESTORE_JRC  = 0x03,
18001 };
18002
18003 /* P.SR.F instruction pool */
18004 enum {
18005     NM_SAVEF        = 0x00,
18006     NM_RESTOREF     = 0x01,
18007 };
18008
18009 /* P16.SYSCALL  instruction pool */
18010 enum {
18011     NM_SYSCALL16     = 0x00,
18012     NM_HYPCALL16     = 0x01,
18013 };
18014
18015 /* POOL16C_00 instruction pool */
18016 enum {
18017     NM_NOT16           = 0x00,
18018     NM_XOR16           = 0x01,
18019     NM_AND16           = 0x02,
18020     NM_OR16            = 0x03,
18021 };
18022
18023 /* PP.LSX and PP.LSXS instruction pool */
18024 enum {
18025     NM_LBX      = 0x00,
18026     NM_LHX      = 0x04,
18027     NM_LWX      = 0x08,
18028     NM_LDX      = 0x0c,
18029
18030     NM_SBX      = 0x01,
18031     NM_SHX      = 0x05,
18032     NM_SWX      = 0x09,
18033     NM_SDX      = 0x0d,
18034
18035     NM_LBUX     = 0x02,
18036     NM_LHUX     = 0x06,
18037     NM_LWC1X    = 0x0a,
18038     NM_LDC1X    = 0x0e,
18039
18040     NM_LWUX     = 0x07,
18041     NM_SWC1X    = 0x0b,
18042     NM_SDC1X    = 0x0f,
18043
18044     NM_LHXS     = 0x04,
18045     NM_LWXS     = 0x08,
18046     NM_LDXS     = 0x0c,
18047
18048     NM_SHXS     = 0x05,
18049     NM_SWXS     = 0x09,
18050     NM_SDXS     = 0x0d,
18051
18052     NM_LHUXS    = 0x06,
18053     NM_LWC1XS   = 0x0a,
18054     NM_LDC1XS   = 0x0e,
18055
18056     NM_LWUXS    = 0x07,
18057     NM_SWC1XS   = 0x0b,
18058     NM_SDC1XS   = 0x0f,
18059 };
18060
18061 /* ERETx instruction pool */
18062 enum {
18063     NM_ERET     = 0x00,
18064     NM_ERETNC   = 0x01,
18065 };
18066
18067 /* POOL32FxF_{0, 1} insturction pool */
18068 enum {
18069     NM_CFC1     = 0x40,
18070     NM_CTC1     = 0x60,
18071     NM_MFC1     = 0x80,
18072     NM_MTC1     = 0xa0,
18073     NM_MFHC1    = 0xc0,
18074     NM_MTHC1    = 0xe0,
18075
18076     NM_CVT_S_PL = 0x84,
18077     NM_CVT_S_PU = 0xa4,
18078
18079     NM_CVT_L_S     = 0x004,
18080     NM_CVT_L_D     = 0x104,
18081     NM_CVT_W_S     = 0x024,
18082     NM_CVT_W_D     = 0x124,
18083
18084     NM_RSQRT_S     = 0x008,
18085     NM_RSQRT_D     = 0x108,
18086
18087     NM_SQRT_S      = 0x028,
18088     NM_SQRT_D      = 0x128,
18089
18090     NM_RECIP_S     = 0x048,
18091     NM_RECIP_D     = 0x148,
18092
18093     NM_FLOOR_L_S   = 0x00c,
18094     NM_FLOOR_L_D   = 0x10c,
18095
18096     NM_FLOOR_W_S   = 0x02c,
18097     NM_FLOOR_W_D   = 0x12c,
18098
18099     NM_CEIL_L_S    = 0x04c,
18100     NM_CEIL_L_D    = 0x14c,
18101     NM_CEIL_W_S    = 0x06c,
18102     NM_CEIL_W_D    = 0x16c,
18103     NM_TRUNC_L_S   = 0x08c,
18104     NM_TRUNC_L_D   = 0x18c,
18105     NM_TRUNC_W_S   = 0x0ac,
18106     NM_TRUNC_W_D   = 0x1ac,
18107     NM_ROUND_L_S   = 0x0cc,
18108     NM_ROUND_L_D   = 0x1cc,
18109     NM_ROUND_W_S   = 0x0ec,
18110     NM_ROUND_W_D   = 0x1ec,
18111
18112     NM_MOV_S       = 0x01,
18113     NM_MOV_D       = 0x81,
18114     NM_ABS_S       = 0x0d,
18115     NM_ABS_D       = 0x8d,
18116     NM_NEG_S       = 0x2d,
18117     NM_NEG_D       = 0xad,
18118     NM_CVT_D_S     = 0x04d,
18119     NM_CVT_D_W     = 0x0cd,
18120     NM_CVT_D_L     = 0x14d,
18121     NM_CVT_S_D     = 0x06d,
18122     NM_CVT_S_W     = 0x0ed,
18123     NM_CVT_S_L     = 0x16d,
18124 };
18125
18126 /* P.LL instruction pool */
18127 enum {
18128     NM_LL       = 0x00,
18129     NM_LLWP     = 0x01,
18130 };
18131
18132 /* P.SC instruction pool */
18133 enum {
18134     NM_SC       = 0x00,
18135     NM_SCWP     = 0x01,
18136 };
18137
18138 /* P.DVP instruction pool */
18139 enum {
18140     NM_DVP      = 0x00,
18141     NM_EVP      = 0x01,
18142 };
18143
18144
18145 /*
18146  *
18147  * nanoMIPS decoding engine
18148  *
18149  */
18150
18151
18152 /* extraction utilities */
18153
18154 #define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
18155 #define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
18156 #define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
18157 #define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
18158 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18159 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18160
18161 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
18162 static inline int decode_gpr_gpr3(int r)
18163 {
18164     static const int map[] = { 16, 17, 18, 19,  4,  5,  6,  7 };
18165
18166     return map[r & 0x7];
18167 }
18168
18169 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
18170 static inline int decode_gpr_gpr3_src_store(int r)
18171 {
18172     static const int map[] = {  0, 17, 18, 19,  4,  5,  6,  7 };
18173
18174     return map[r & 0x7];
18175 }
18176
18177 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
18178 static inline int decode_gpr_gpr4(int r)
18179 {
18180     static const int map[] = {  8,  9, 10, 11,  4,  5,  6,  7,
18181                                16, 17, 18, 19, 20, 21, 22, 23 };
18182
18183     return map[r & 0xf];
18184 }
18185
18186 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
18187 static inline int decode_gpr_gpr4_zero(int r)
18188 {
18189     static const int map[] = {  8,  9, 10,  0,  4,  5,  6,  7,
18190                                16, 17, 18, 19, 20, 21, 22, 23 };
18191
18192     return map[r & 0xf];
18193 }
18194
18195
18196 /* extraction utilities */
18197
18198 #define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
18199 #define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
18200 #define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
18201 #define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
18202 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18203 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18204
18205
18206 static void gen_adjust_sp(DisasContext *ctx, int u)
18207 {
18208     gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u);
18209 }
18210
18211 static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count,
18212                      uint8_t gp, uint16_t u)
18213 {
18214     int counter = 0;
18215     TCGv va = tcg_temp_new();
18216     TCGv t0 = tcg_temp_new();
18217
18218     while (counter != count) {
18219         bool use_gp = gp && (counter == count - 1);
18220         int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18221         int this_offset = -((counter + 1) << 2);
18222         gen_base_offset_addr(ctx, va, 29, this_offset);
18223         gen_load_gpr(t0, this_rt);
18224         tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx,
18225                            (MO_TEUL | ctx->default_tcg_memop_mask));
18226         counter++;
18227     }
18228
18229     /* adjust stack pointer */
18230     gen_adjust_sp(ctx, -u);
18231
18232     tcg_temp_free(t0);
18233     tcg_temp_free(va);
18234 }
18235
18236 static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count,
18237                         uint8_t gp, uint16_t u)
18238 {
18239     int counter = 0;
18240     TCGv va = tcg_temp_new();
18241     TCGv t0 = tcg_temp_new();
18242
18243     while (counter != count) {
18244         bool use_gp = gp && (counter == count - 1);
18245         int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18246         int this_offset = u - ((counter + 1) << 2);
18247         gen_base_offset_addr(ctx, va, 29, this_offset);
18248         tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL |
18249                         ctx->default_tcg_memop_mask);
18250         tcg_gen_ext32s_tl(t0, t0);
18251         gen_store_gpr(t0, this_rt);
18252         counter++;
18253     }
18254
18255     /* adjust stack pointer */
18256     gen_adjust_sp(ctx, u);
18257
18258     tcg_temp_free(t0);
18259     tcg_temp_free(va);
18260 }
18261
18262 static void gen_pool16c_nanomips_insn(DisasContext *ctx)
18263 {
18264     int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
18265     int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
18266
18267     switch (extract32(ctx->opcode, 2, 2)) {
18268     case NM_NOT16:
18269         gen_logic(ctx, OPC_NOR, rt, rs, 0);
18270         break;
18271     case NM_AND16:
18272         gen_logic(ctx, OPC_AND, rt, rt, rs);
18273         break;
18274     case NM_XOR16:
18275         gen_logic(ctx, OPC_XOR, rt, rt, rs);
18276         break;
18277     case NM_OR16:
18278         gen_logic(ctx, OPC_OR, rt, rt, rs);
18279         break;
18280     }
18281 }
18282
18283 static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
18284 {
18285     int rt = extract32(ctx->opcode, 21, 5);
18286     int rs = extract32(ctx->opcode, 16, 5);
18287     int rd = extract32(ctx->opcode, 11, 5);
18288
18289     switch (extract32(ctx->opcode, 3, 7)) {
18290     case NM_P_TRAP:
18291         switch (extract32(ctx->opcode, 10, 1)) {
18292         case NM_TEQ:
18293             check_nms(ctx);
18294             gen_trap(ctx, OPC_TEQ, rs, rt, -1);
18295             break;
18296         case NM_TNE:
18297             check_nms(ctx);
18298             gen_trap(ctx, OPC_TNE, rs, rt, -1);
18299             break;
18300         }
18301         break;
18302     case NM_RDHWR:
18303         check_nms(ctx);
18304         gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
18305         break;
18306     case NM_SEB:
18307         check_nms(ctx);
18308         gen_bshfl(ctx, OPC_SEB, rs, rt);
18309         break;
18310     case NM_SEH:
18311         gen_bshfl(ctx, OPC_SEH, rs, rt);
18312         break;
18313     case NM_SLLV:
18314         gen_shift(ctx, OPC_SLLV, rd, rt, rs);
18315         break;
18316     case NM_SRLV:
18317         gen_shift(ctx, OPC_SRLV, rd, rt, rs);
18318         break;
18319     case NM_SRAV:
18320         gen_shift(ctx, OPC_SRAV, rd, rt, rs);
18321         break;
18322     case NM_ROTRV:
18323         gen_shift(ctx, OPC_ROTRV, rd, rt, rs);
18324         break;
18325     case NM_ADD:
18326         gen_arith(ctx, OPC_ADD, rd, rs, rt);
18327         break;
18328     case NM_ADDU:
18329         gen_arith(ctx, OPC_ADDU, rd, rs, rt);
18330         break;
18331     case NM_SUB:
18332         check_nms(ctx);
18333         gen_arith(ctx, OPC_SUB, rd, rs, rt);
18334         break;
18335     case NM_SUBU:
18336         gen_arith(ctx, OPC_SUBU, rd, rs, rt);
18337         break;
18338     case NM_P_CMOVE:
18339         switch (extract32(ctx->opcode, 10, 1)) {
18340         case NM_MOVZ:
18341             gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
18342             break;
18343         case NM_MOVN:
18344             gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
18345             break;
18346         }
18347         break;
18348     case NM_AND:
18349         gen_logic(ctx, OPC_AND, rd, rs, rt);
18350         break;
18351     case NM_OR:
18352         gen_logic(ctx, OPC_OR, rd, rs, rt);
18353         break;
18354     case NM_NOR:
18355         gen_logic(ctx, OPC_NOR, rd, rs, rt);
18356         break;
18357     case NM_XOR:
18358         gen_logic(ctx, OPC_XOR, rd, rs, rt);
18359         break;
18360     case NM_SLT:
18361         gen_slt(ctx, OPC_SLT, rd, rs, rt);
18362         break;
18363     case NM_P_SLTU:
18364         if (rd == 0) {
18365             /* P_DVP */
18366 #ifndef CONFIG_USER_ONLY
18367             TCGv t0 = tcg_temp_new();
18368             switch (extract32(ctx->opcode, 10, 1)) {
18369             case NM_DVP:
18370                 if (ctx->vp) {
18371                     check_cp0_enabled(ctx);
18372                     gen_helper_dvp(t0, cpu_env);
18373                     gen_store_gpr(t0, rt);
18374                 }
18375                 break;
18376             case NM_EVP:
18377                 if (ctx->vp) {
18378                     check_cp0_enabled(ctx);
18379                     gen_helper_evp(t0, cpu_env);
18380                     gen_store_gpr(t0, rt);
18381                 }
18382                 break;
18383             }
18384             tcg_temp_free(t0);
18385 #endif
18386         } else {
18387             gen_slt(ctx, OPC_SLTU, rd, rs, rt);
18388         }
18389         break;
18390     case NM_SOV:
18391         {
18392             TCGv t0 = tcg_temp_new();
18393             TCGv t1 = tcg_temp_new();
18394             TCGv t2 = tcg_temp_new();
18395
18396             gen_load_gpr(t1, rs);
18397             gen_load_gpr(t2, rt);
18398             tcg_gen_add_tl(t0, t1, t2);
18399             tcg_gen_ext32s_tl(t0, t0);
18400             tcg_gen_xor_tl(t1, t1, t2);
18401             tcg_gen_xor_tl(t2, t0, t2);
18402             tcg_gen_andc_tl(t1, t2, t1);
18403
18404             /* operands of same sign, result different sign */
18405             tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0);
18406             gen_store_gpr(t0, rd);
18407
18408             tcg_temp_free(t0);
18409             tcg_temp_free(t1);
18410             tcg_temp_free(t2);
18411         }
18412         break;
18413     case NM_MUL:
18414         gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
18415         break;
18416     case NM_MUH:
18417         gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
18418         break;
18419     case NM_MULU:
18420         gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
18421         break;
18422     case NM_MUHU:
18423         gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
18424         break;
18425     case NM_DIV:
18426         gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
18427         break;
18428     case NM_MOD:
18429         gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
18430         break;
18431     case NM_DIVU:
18432         gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
18433         break;
18434     case NM_MODU:
18435         gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
18436         break;
18437 #ifndef CONFIG_USER_ONLY
18438     case NM_MFC0:
18439         check_cp0_enabled(ctx);
18440         if (rt == 0) {
18441             /* Treat as NOP. */
18442             break;
18443         }
18444         gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3));
18445         break;
18446     case NM_MTC0:
18447         check_cp0_enabled(ctx);
18448         {
18449             TCGv t0 = tcg_temp_new();
18450
18451             gen_load_gpr(t0, rt);
18452             gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3));
18453             tcg_temp_free(t0);
18454         }
18455         break;
18456     case NM_D_E_MT_VPE:
18457         {
18458             uint8_t sc = extract32(ctx->opcode, 10, 1);
18459             TCGv t0 = tcg_temp_new();
18460
18461             switch (sc) {
18462             case 0:
18463                 if (rs == 1) {
18464                     /* DMT */
18465                     check_cp0_mt(ctx);
18466                     gen_helper_dmt(t0);
18467                     gen_store_gpr(t0, rt);
18468                 } else if (rs == 0) {
18469                     /* DVPE */
18470                     check_cp0_mt(ctx);
18471                     gen_helper_dvpe(t0, cpu_env);
18472                     gen_store_gpr(t0, rt);
18473                 } else {
18474                     generate_exception_end(ctx, EXCP_RI);
18475                 }
18476                 break;
18477             case 1:
18478                 if (rs == 1) {
18479                     /* EMT */
18480                     check_cp0_mt(ctx);
18481                     gen_helper_emt(t0);
18482                     gen_store_gpr(t0, rt);
18483                 } else if (rs == 0) {
18484                     /* EVPE */
18485                     check_cp0_mt(ctx);
18486                     gen_helper_evpe(t0, cpu_env);
18487                     gen_store_gpr(t0, rt);
18488                 } else {
18489                     generate_exception_end(ctx, EXCP_RI);
18490                 }
18491                 break;
18492             }
18493
18494             tcg_temp_free(t0);
18495         }
18496         break;
18497     case NM_FORK:
18498         check_mt(ctx);
18499         {
18500             TCGv t0 = tcg_temp_new();
18501             TCGv t1 = tcg_temp_new();
18502
18503             gen_load_gpr(t0, rt);
18504             gen_load_gpr(t1, rs);
18505             gen_helper_fork(t0, t1);
18506             tcg_temp_free(t0);
18507             tcg_temp_free(t1);
18508         }
18509         break;
18510     case NM_MFTR:
18511     case NM_MFHTR:
18512         check_cp0_enabled(ctx);
18513         if (rd == 0) {
18514             /* Treat as NOP. */
18515             return;
18516         }
18517         gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18518                  extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18519         break;
18520     case NM_MTTR:
18521     case NM_MTHTR:
18522         check_cp0_enabled(ctx);
18523         gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18524                  extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18525         break;
18526     case NM_YIELD:
18527         check_mt(ctx);
18528         {
18529             TCGv t0 = tcg_temp_new();
18530
18531             gen_load_gpr(t0, rs);
18532             gen_helper_yield(t0, cpu_env, t0);
18533             gen_store_gpr(t0, rt);
18534             tcg_temp_free(t0);
18535         }
18536         break;
18537 #endif
18538     default:
18539         generate_exception_end(ctx, EXCP_RI);
18540         break;
18541     }
18542 }
18543
18544 /* dsp */
18545 static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc,
18546                                             int ret, int v1, int v2)
18547 {
18548     TCGv_i32 t0;
18549     TCGv v0_t;
18550     TCGv v1_t;
18551
18552     t0 = tcg_temp_new_i32();
18553
18554     v0_t = tcg_temp_new();
18555     v1_t = tcg_temp_new();
18556
18557     tcg_gen_movi_i32(t0, v2 >> 3);
18558
18559     gen_load_gpr(v0_t, ret);
18560     gen_load_gpr(v1_t, v1);
18561
18562     switch (opc) {
18563     case NM_MAQ_S_W_PHR:
18564         check_dsp(ctx);
18565         gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env);
18566         break;
18567     case NM_MAQ_S_W_PHL:
18568         check_dsp(ctx);
18569         gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env);
18570         break;
18571     case NM_MAQ_SA_W_PHR:
18572         check_dsp(ctx);
18573         gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env);
18574         break;
18575     case NM_MAQ_SA_W_PHL:
18576         check_dsp(ctx);
18577         gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env);
18578         break;
18579     default:
18580         generate_exception_end(ctx, EXCP_RI);
18581         break;
18582     }
18583
18584     tcg_temp_free_i32(t0);
18585
18586     tcg_temp_free(v0_t);
18587     tcg_temp_free(v1_t);
18588 }
18589
18590
18591 static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc,
18592                                     int ret, int v1, int v2)
18593 {
18594     int16_t imm;
18595     TCGv t0 = tcg_temp_new();
18596     TCGv t1 = tcg_temp_new();
18597     TCGv v0_t = tcg_temp_new();
18598
18599     gen_load_gpr(v0_t, v1);
18600
18601     switch (opc) {
18602     case NM_POOL32AXF_1_0:
18603         check_dsp(ctx);
18604         switch (extract32(ctx->opcode, 12, 2)) {
18605         case NM_MFHI:
18606             gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret);
18607             break;
18608         case NM_MFLO:
18609             gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret);
18610             break;
18611         case NM_MTHI:
18612             gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1);
18613             break;
18614         case NM_MTLO:
18615             gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1);
18616             break;
18617         }
18618         break;
18619     case NM_POOL32AXF_1_1:
18620         check_dsp(ctx);
18621         switch (extract32(ctx->opcode, 12, 2)) {
18622         case NM_MTHLIP:
18623             tcg_gen_movi_tl(t0, v2);
18624             gen_helper_mthlip(t0, v0_t, cpu_env);
18625             break;
18626         case NM_SHILOV:
18627             tcg_gen_movi_tl(t0, v2 >> 3);
18628             gen_helper_shilo(t0, v0_t, cpu_env);
18629             break;
18630         default:
18631             generate_exception_end(ctx, EXCP_RI);
18632             break;
18633         }
18634         break;
18635     case NM_POOL32AXF_1_3:
18636         check_dsp(ctx);
18637         imm = extract32(ctx->opcode, 14, 7);
18638         switch (extract32(ctx->opcode, 12, 2)) {
18639         case NM_RDDSP:
18640             tcg_gen_movi_tl(t0, imm);
18641             gen_helper_rddsp(t0, t0, cpu_env);
18642             gen_store_gpr(t0, ret);
18643             break;
18644         case NM_WRDSP:
18645             gen_load_gpr(t0, ret);
18646             tcg_gen_movi_tl(t1, imm);
18647             gen_helper_wrdsp(t0, t1, cpu_env);
18648             break;
18649         case NM_EXTP:
18650             tcg_gen_movi_tl(t0, v2 >> 3);
18651             tcg_gen_movi_tl(t1, v1);
18652             gen_helper_extp(t0, t0, t1, cpu_env);
18653             gen_store_gpr(t0, ret);
18654             break;
18655         case NM_EXTPDP:
18656             tcg_gen_movi_tl(t0, v2 >> 3);
18657             tcg_gen_movi_tl(t1, v1);
18658             gen_helper_extpdp(t0, t0, t1, cpu_env);
18659             gen_store_gpr(t0, ret);
18660             break;
18661         }
18662         break;
18663     case NM_POOL32AXF_1_4:
18664         check_dsp(ctx);
18665         tcg_gen_movi_tl(t0, v2 >> 2);
18666         switch (extract32(ctx->opcode, 12, 1)) {
18667         case NM_SHLL_QB:
18668             gen_helper_shll_qb(t0, t0, v0_t, cpu_env);
18669             gen_store_gpr(t0, ret);
18670             break;
18671         case NM_SHRL_QB:
18672             gen_helper_shrl_qb(t0, t0, v0_t);
18673             gen_store_gpr(t0, ret);
18674             break;
18675         }
18676         break;
18677     case NM_POOL32AXF_1_5:
18678         opc = extract32(ctx->opcode, 12, 2);
18679         gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2);
18680         break;
18681     case NM_POOL32AXF_1_7:
18682         check_dsp(ctx);
18683         tcg_gen_movi_tl(t0, v2 >> 3);
18684         tcg_gen_movi_tl(t1, v1);
18685         switch (extract32(ctx->opcode, 12, 2)) {
18686         case NM_EXTR_W:
18687             gen_helper_extr_w(t0, t0, t1, cpu_env);
18688             gen_store_gpr(t0, ret);
18689             break;
18690         case NM_EXTR_R_W:
18691             gen_helper_extr_r_w(t0, t0, t1, cpu_env);
18692             gen_store_gpr(t0, ret);
18693             break;
18694         case NM_EXTR_RS_W:
18695             gen_helper_extr_rs_w(t0, t0, t1, cpu_env);
18696             gen_store_gpr(t0, ret);
18697             break;
18698         case NM_EXTR_S_H:
18699             gen_helper_extr_s_h(t0, t0, t1, cpu_env);
18700             gen_store_gpr(t0, ret);
18701             break;
18702         }
18703         break;
18704     default:
18705         generate_exception_end(ctx, EXCP_RI);
18706         break;
18707     }
18708
18709     tcg_temp_free(t0);
18710     tcg_temp_free(t1);
18711     tcg_temp_free(v0_t);
18712 }
18713
18714 static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc,
18715                                     TCGv v0, TCGv v1, int rd)
18716 {
18717     TCGv_i32 t0;
18718
18719     t0 = tcg_temp_new_i32();
18720
18721     tcg_gen_movi_i32(t0, rd >> 3);
18722
18723     switch (opc) {
18724     case NM_POOL32AXF_2_0_7:
18725         switch (extract32(ctx->opcode, 9, 3)) {
18726         case NM_DPA_W_PH:
18727             check_dsp_r2(ctx);
18728             gen_helper_dpa_w_ph(t0, v1, v0, cpu_env);
18729             break;
18730         case NM_DPAQ_S_W_PH:
18731             check_dsp(ctx);
18732             gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env);
18733             break;
18734         case NM_DPS_W_PH:
18735             check_dsp_r2(ctx);
18736             gen_helper_dps_w_ph(t0, v1, v0, cpu_env);
18737             break;
18738         case NM_DPSQ_S_W_PH:
18739             check_dsp(ctx);
18740             gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env);
18741             break;
18742         default:
18743             generate_exception_end(ctx, EXCP_RI);
18744             break;
18745         }
18746         break;
18747     case NM_POOL32AXF_2_8_15:
18748         switch (extract32(ctx->opcode, 9, 3)) {
18749         case NM_DPAX_W_PH:
18750             check_dsp_r2(ctx);
18751             gen_helper_dpax_w_ph(t0, v0, v1, cpu_env);
18752             break;
18753         case NM_DPAQ_SA_L_W:
18754             check_dsp(ctx);
18755             gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env);
18756             break;
18757         case NM_DPSX_W_PH:
18758             check_dsp_r2(ctx);
18759             gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env);
18760             break;
18761         case NM_DPSQ_SA_L_W:
18762             check_dsp(ctx);
18763             gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env);
18764             break;
18765         default:
18766             generate_exception_end(ctx, EXCP_RI);
18767             break;
18768         }
18769         break;
18770     case NM_POOL32AXF_2_16_23:
18771         switch (extract32(ctx->opcode, 9, 3)) {
18772         case NM_DPAU_H_QBL:
18773             check_dsp(ctx);
18774             gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env);
18775             break;
18776         case NM_DPAQX_S_W_PH:
18777             check_dsp_r2(ctx);
18778             gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env);
18779             break;
18780         case NM_DPSU_H_QBL:
18781             check_dsp(ctx);
18782             gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env);
18783             break;
18784         case NM_DPSQX_S_W_PH:
18785             check_dsp_r2(ctx);
18786             gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env);
18787             break;
18788         case NM_MULSA_W_PH:
18789             check_dsp_r2(ctx);
18790             gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env);
18791             break;
18792         default:
18793             generate_exception_end(ctx, EXCP_RI);
18794             break;
18795         }
18796         break;
18797     case NM_POOL32AXF_2_24_31:
18798         switch (extract32(ctx->opcode, 9, 3)) {
18799         case NM_DPAU_H_QBR:
18800             check_dsp(ctx);
18801             gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env);
18802             break;
18803         case NM_DPAQX_SA_W_PH:
18804             check_dsp_r2(ctx);
18805             gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env);
18806             break;
18807         case NM_DPSU_H_QBR:
18808             check_dsp(ctx);
18809             gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env);
18810             break;
18811         case NM_DPSQX_SA_W_PH:
18812             check_dsp_r2(ctx);
18813             gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env);
18814             break;
18815         case NM_MULSAQ_S_W_PH:
18816             check_dsp(ctx);
18817             gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env);
18818             break;
18819         default:
18820             generate_exception_end(ctx, EXCP_RI);
18821             break;
18822         }
18823         break;
18824     default:
18825         generate_exception_end(ctx, EXCP_RI);
18826         break;
18827     }
18828
18829     tcg_temp_free_i32(t0);
18830 }
18831
18832 static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc,
18833                                           int rt, int rs, int rd)
18834 {
18835     int ret = rt;
18836     TCGv t0 = tcg_temp_new();
18837     TCGv t1 = tcg_temp_new();
18838     TCGv v0_t = tcg_temp_new();
18839     TCGv v1_t = tcg_temp_new();
18840
18841     gen_load_gpr(v0_t, rt);
18842     gen_load_gpr(v1_t, rs);
18843
18844     switch (opc) {
18845     case NM_POOL32AXF_2_0_7:
18846         switch (extract32(ctx->opcode, 9, 3)) {
18847         case NM_DPA_W_PH:
18848         case NM_DPAQ_S_W_PH:
18849         case NM_DPS_W_PH:
18850         case NM_DPSQ_S_W_PH:
18851             gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18852             break;
18853         case NM_BALIGN:
18854             check_dsp_r2(ctx);
18855             if (rt != 0) {
18856                 gen_load_gpr(t0, rs);
18857                 rd &= 3;
18858                 if (rd != 0 && rd != 2) {
18859                     tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd);
18860                     tcg_gen_ext32u_tl(t0, t0);
18861                     tcg_gen_shri_tl(t0, t0, 8 * (4 - rd));
18862                     tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
18863                 }
18864                 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
18865             }
18866             break;
18867         case NM_MADD:
18868             check_dsp(ctx);
18869             {
18870                 int acc = extract32(ctx->opcode, 14, 2);
18871                 TCGv_i64 t2 = tcg_temp_new_i64();
18872                 TCGv_i64 t3 = tcg_temp_new_i64();
18873
18874                 gen_load_gpr(t0, rt);
18875                 gen_load_gpr(t1, rs);
18876                 tcg_gen_ext_tl_i64(t2, t0);
18877                 tcg_gen_ext_tl_i64(t3, t1);
18878                 tcg_gen_mul_i64(t2, t2, t3);
18879                 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18880                 tcg_gen_add_i64(t2, t2, t3);
18881                 tcg_temp_free_i64(t3);
18882                 gen_move_low32(cpu_LO[acc], t2);
18883                 gen_move_high32(cpu_HI[acc], t2);
18884                 tcg_temp_free_i64(t2);
18885             }
18886             break;
18887         case NM_MULT:
18888             check_dsp(ctx);
18889             {
18890                 int acc = extract32(ctx->opcode, 14, 2);
18891                 TCGv_i32 t2 = tcg_temp_new_i32();
18892                 TCGv_i32 t3 = tcg_temp_new_i32();
18893
18894                 gen_load_gpr(t0, rs);
18895                 gen_load_gpr(t1, rt);
18896                 tcg_gen_trunc_tl_i32(t2, t0);
18897                 tcg_gen_trunc_tl_i32(t3, t1);
18898                 tcg_gen_muls2_i32(t2, t3, t2, t3);
18899                 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
18900                 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
18901                 tcg_temp_free_i32(t2);
18902                 tcg_temp_free_i32(t3);
18903             }
18904             break;
18905         case NM_EXTRV_W:
18906             check_dsp(ctx);
18907             gen_load_gpr(v1_t, rs);
18908             tcg_gen_movi_tl(t0, rd >> 3);
18909             gen_helper_extr_w(t0, t0, v1_t, cpu_env);
18910             gen_store_gpr(t0, ret);
18911             break;
18912         }
18913         break;
18914     case NM_POOL32AXF_2_8_15:
18915         switch (extract32(ctx->opcode, 9, 3)) {
18916         case NM_DPAX_W_PH:
18917         case NM_DPAQ_SA_L_W:
18918         case NM_DPSX_W_PH:
18919         case NM_DPSQ_SA_L_W:
18920             gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18921             break;
18922         case NM_MADDU:
18923             check_dsp(ctx);
18924             {
18925                 int acc = extract32(ctx->opcode, 14, 2);
18926                 TCGv_i64 t2 = tcg_temp_new_i64();
18927                 TCGv_i64 t3 = tcg_temp_new_i64();
18928
18929                 gen_load_gpr(t0, rs);
18930                 gen_load_gpr(t1, rt);
18931                 tcg_gen_ext32u_tl(t0, t0);
18932                 tcg_gen_ext32u_tl(t1, t1);
18933                 tcg_gen_extu_tl_i64(t2, t0);
18934                 tcg_gen_extu_tl_i64(t3, t1);
18935                 tcg_gen_mul_i64(t2, t2, t3);
18936                 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18937                 tcg_gen_add_i64(t2, t2, t3);
18938                 tcg_temp_free_i64(t3);
18939                 gen_move_low32(cpu_LO[acc], t2);
18940                 gen_move_high32(cpu_HI[acc], t2);
18941                 tcg_temp_free_i64(t2);
18942             }
18943             break;
18944         case NM_MULTU:
18945             check_dsp(ctx);
18946             {
18947                 int acc = extract32(ctx->opcode, 14, 2);
18948                 TCGv_i32 t2 = tcg_temp_new_i32();
18949                 TCGv_i32 t3 = tcg_temp_new_i32();
18950
18951                 gen_load_gpr(t0, rs);
18952                 gen_load_gpr(t1, rt);
18953                 tcg_gen_trunc_tl_i32(t2, t0);
18954                 tcg_gen_trunc_tl_i32(t3, t1);
18955                 tcg_gen_mulu2_i32(t2, t3, t2, t3);
18956                 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
18957                 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
18958                 tcg_temp_free_i32(t2);
18959                 tcg_temp_free_i32(t3);
18960             }
18961             break;
18962         case NM_EXTRV_R_W:
18963             check_dsp(ctx);
18964             tcg_gen_movi_tl(t0, rd >> 3);
18965             gen_helper_extr_r_w(t0, t0, v1_t, cpu_env);
18966             gen_store_gpr(t0, ret);
18967             break;
18968         default:
18969             generate_exception_end(ctx, EXCP_RI);
18970             break;
18971         }
18972         break;
18973     case NM_POOL32AXF_2_16_23:
18974         switch (extract32(ctx->opcode, 9, 3)) {
18975         case NM_DPAU_H_QBL:
18976         case NM_DPAQX_S_W_PH:
18977         case NM_DPSU_H_QBL:
18978         case NM_DPSQX_S_W_PH:
18979         case NM_MULSA_W_PH:
18980             gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18981             break;
18982         case NM_EXTPV:
18983             check_dsp(ctx);
18984             tcg_gen_movi_tl(t0, rd >> 3);
18985             gen_helper_extp(t0, t0, v1_t, cpu_env);
18986             gen_store_gpr(t0, ret);
18987             break;
18988         case NM_MSUB:
18989             check_dsp(ctx);
18990             {
18991                 int acc = extract32(ctx->opcode, 14, 2);
18992                 TCGv_i64 t2 = tcg_temp_new_i64();
18993                 TCGv_i64 t3 = tcg_temp_new_i64();
18994
18995                 gen_load_gpr(t0, rs);
18996                 gen_load_gpr(t1, rt);
18997                 tcg_gen_ext_tl_i64(t2, t0);
18998                 tcg_gen_ext_tl_i64(t3, t1);
18999                 tcg_gen_mul_i64(t2, t2, t3);
19000                 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19001                 tcg_gen_sub_i64(t2, t3, t2);
19002                 tcg_temp_free_i64(t3);
19003                 gen_move_low32(cpu_LO[acc], t2);
19004                 gen_move_high32(cpu_HI[acc], t2);
19005                 tcg_temp_free_i64(t2);
19006             }
19007             break;
19008         case NM_EXTRV_RS_W:
19009             check_dsp(ctx);
19010             tcg_gen_movi_tl(t0, rd >> 3);
19011             gen_helper_extr_rs_w(t0, t0, v1_t, cpu_env);
19012             gen_store_gpr(t0, ret);
19013             break;
19014         }
19015         break;
19016     case NM_POOL32AXF_2_24_31:
19017         switch (extract32(ctx->opcode, 9, 3)) {
19018         case NM_DPAU_H_QBR:
19019         case NM_DPAQX_SA_W_PH:
19020         case NM_DPSU_H_QBR:
19021         case NM_DPSQX_SA_W_PH:
19022         case NM_MULSAQ_S_W_PH:
19023             gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19024             break;
19025         case NM_EXTPDPV:
19026             check_dsp(ctx);
19027             tcg_gen_movi_tl(t0, rd >> 3);
19028             gen_helper_extpdp(t0, t0, v1_t, cpu_env);
19029             gen_store_gpr(t0, ret);
19030             break;
19031         case NM_MSUBU:
19032             check_dsp(ctx);
19033             {
19034                 int acc = extract32(ctx->opcode, 14, 2);
19035                 TCGv_i64 t2 = tcg_temp_new_i64();
19036                 TCGv_i64 t3 = tcg_temp_new_i64();
19037
19038                 gen_load_gpr(t0, rs);
19039                 gen_load_gpr(t1, rt);
19040                 tcg_gen_ext32u_tl(t0, t0);
19041                 tcg_gen_ext32u_tl(t1, t1);
19042                 tcg_gen_extu_tl_i64(t2, t0);
19043                 tcg_gen_extu_tl_i64(t3, t1);
19044                 tcg_gen_mul_i64(t2, t2, t3);
19045                 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19046                 tcg_gen_sub_i64(t2, t3, t2);
19047                 tcg_temp_free_i64(t3);
19048                 gen_move_low32(cpu_LO[acc], t2);
19049                 gen_move_high32(cpu_HI[acc], t2);
19050                 tcg_temp_free_i64(t2);
19051             }
19052             break;
19053         case NM_EXTRV_S_H:
19054             check_dsp(ctx);
19055             tcg_gen_movi_tl(t0, rd >> 3);
19056             gen_helper_extr_s_h(t0, t0, v0_t, cpu_env);
19057             gen_store_gpr(t0, ret);
19058             break;
19059         }
19060         break;
19061     default:
19062         generate_exception_end(ctx, EXCP_RI);
19063         break;
19064     }
19065
19066     tcg_temp_free(t0);
19067     tcg_temp_free(t1);
19068
19069     tcg_temp_free(v0_t);
19070     tcg_temp_free(v1_t);
19071 }
19072
19073 static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc,
19074                                           int rt, int rs)
19075 {
19076     int ret = rt;
19077     TCGv t0 = tcg_temp_new();
19078     TCGv v0_t = tcg_temp_new();
19079
19080     gen_load_gpr(v0_t, rs);
19081
19082     switch (opc) {
19083     case NM_ABSQ_S_QB:
19084         check_dsp_r2(ctx);
19085         gen_helper_absq_s_qb(v0_t, v0_t, cpu_env);
19086         gen_store_gpr(v0_t, ret);
19087         break;
19088     case NM_ABSQ_S_PH:
19089         check_dsp(ctx);
19090         gen_helper_absq_s_ph(v0_t, v0_t, cpu_env);
19091         gen_store_gpr(v0_t, ret);
19092         break;
19093     case NM_ABSQ_S_W:
19094         check_dsp(ctx);
19095         gen_helper_absq_s_w(v0_t, v0_t, cpu_env);
19096         gen_store_gpr(v0_t, ret);
19097         break;
19098     case NM_PRECEQ_W_PHL:
19099         check_dsp(ctx);
19100         tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000);
19101         tcg_gen_ext32s_tl(v0_t, v0_t);
19102         gen_store_gpr(v0_t, ret);
19103         break;
19104     case NM_PRECEQ_W_PHR:
19105         check_dsp(ctx);
19106         tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF);
19107         tcg_gen_shli_tl(v0_t, v0_t, 16);
19108         tcg_gen_ext32s_tl(v0_t, v0_t);
19109         gen_store_gpr(v0_t, ret);
19110         break;
19111     case NM_PRECEQU_PH_QBL:
19112         check_dsp(ctx);
19113         gen_helper_precequ_ph_qbl(v0_t, v0_t);
19114         gen_store_gpr(v0_t, ret);
19115         break;
19116     case NM_PRECEQU_PH_QBR:
19117         check_dsp(ctx);
19118         gen_helper_precequ_ph_qbr(v0_t, v0_t);
19119         gen_store_gpr(v0_t, ret);
19120         break;
19121     case NM_PRECEQU_PH_QBLA:
19122         check_dsp(ctx);
19123         gen_helper_precequ_ph_qbla(v0_t, v0_t);
19124         gen_store_gpr(v0_t, ret);
19125         break;
19126     case NM_PRECEQU_PH_QBRA:
19127         check_dsp(ctx);
19128         gen_helper_precequ_ph_qbra(v0_t, v0_t);
19129         gen_store_gpr(v0_t, ret);
19130         break;
19131     case NM_PRECEU_PH_QBL:
19132         check_dsp(ctx);
19133         gen_helper_preceu_ph_qbl(v0_t, v0_t);
19134         gen_store_gpr(v0_t, ret);
19135         break;
19136     case NM_PRECEU_PH_QBR:
19137         check_dsp(ctx);
19138         gen_helper_preceu_ph_qbr(v0_t, v0_t);
19139         gen_store_gpr(v0_t, ret);
19140         break;
19141     case NM_PRECEU_PH_QBLA:
19142         check_dsp(ctx);
19143         gen_helper_preceu_ph_qbla(v0_t, v0_t);
19144         gen_store_gpr(v0_t, ret);
19145         break;
19146     case NM_PRECEU_PH_QBRA:
19147         check_dsp(ctx);
19148         gen_helper_preceu_ph_qbra(v0_t, v0_t);
19149         gen_store_gpr(v0_t, ret);
19150         break;
19151     case NM_REPLV_PH:
19152         check_dsp(ctx);
19153         tcg_gen_ext16u_tl(v0_t, v0_t);
19154         tcg_gen_shli_tl(t0, v0_t, 16);
19155         tcg_gen_or_tl(v0_t, v0_t, t0);
19156         tcg_gen_ext32s_tl(v0_t, v0_t);
19157         gen_store_gpr(v0_t, ret);
19158         break;
19159     case NM_REPLV_QB:
19160         check_dsp(ctx);
19161         tcg_gen_ext8u_tl(v0_t, v0_t);
19162         tcg_gen_shli_tl(t0, v0_t, 8);
19163         tcg_gen_or_tl(v0_t, v0_t, t0);
19164         tcg_gen_shli_tl(t0, v0_t, 16);
19165         tcg_gen_or_tl(v0_t, v0_t, t0);
19166         tcg_gen_ext32s_tl(v0_t, v0_t);
19167         gen_store_gpr(v0_t, ret);
19168         break;
19169     case NM_BITREV:
19170         check_dsp(ctx);
19171         gen_helper_bitrev(v0_t, v0_t);
19172         gen_store_gpr(v0_t, ret);
19173         break;
19174     case NM_INSV:
19175         check_dsp(ctx);
19176         {
19177             TCGv tv0 = tcg_temp_new();
19178
19179             gen_load_gpr(tv0, rt);
19180             gen_helper_insv(v0_t, cpu_env, v0_t, tv0);
19181             gen_store_gpr(v0_t, ret);
19182             tcg_temp_free(tv0);
19183         }
19184         break;
19185     case NM_RADDU_W_QB:
19186         check_dsp(ctx);
19187         gen_helper_raddu_w_qb(v0_t, v0_t);
19188         gen_store_gpr(v0_t, ret);
19189         break;
19190     case NM_BITSWAP:
19191         gen_bitswap(ctx, OPC_BITSWAP, ret, rs);
19192         break;
19193     case NM_CLO:
19194         check_nms(ctx);
19195         gen_cl(ctx, OPC_CLO, ret, rs);
19196         break;
19197     case NM_CLZ:
19198         check_nms(ctx);
19199         gen_cl(ctx, OPC_CLZ, ret, rs);
19200         break;
19201     case NM_WSBH:
19202         gen_bshfl(ctx, OPC_WSBH, ret, rs);
19203         break;
19204     default:
19205         generate_exception_end(ctx, EXCP_RI);
19206         break;
19207     }
19208
19209     tcg_temp_free(v0_t);
19210     tcg_temp_free(t0);
19211 }
19212
19213 static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc,
19214                                           int rt, int rs, int rd)
19215 {
19216     TCGv t0 = tcg_temp_new();
19217     TCGv rs_t = tcg_temp_new();
19218
19219     gen_load_gpr(rs_t, rs);
19220
19221     switch (opc) {
19222     case NM_SHRA_R_QB:
19223         check_dsp_r2(ctx);
19224         tcg_gen_movi_tl(t0, rd >> 2);
19225         switch (extract32(ctx->opcode, 12, 1)) {
19226         case 0:
19227             /* NM_SHRA_QB */
19228             gen_helper_shra_qb(t0, t0, rs_t);
19229             gen_store_gpr(t0, rt);
19230             break;
19231         case 1:
19232             /* NM_SHRA_R_QB */
19233             gen_helper_shra_r_qb(t0, t0, rs_t);
19234             gen_store_gpr(t0, rt);
19235             break;
19236         }
19237         break;
19238     case NM_SHRL_PH:
19239         check_dsp_r2(ctx);
19240         tcg_gen_movi_tl(t0, rd >> 1);
19241         gen_helper_shrl_ph(t0, t0, rs_t);
19242         gen_store_gpr(t0, rt);
19243         break;
19244     case NM_REPL_QB:
19245         check_dsp(ctx);
19246         {
19247             int16_t imm;
19248             target_long result;
19249             imm = extract32(ctx->opcode, 13, 8);
19250             result = (uint32_t)imm << 24 |
19251                      (uint32_t)imm << 16 |
19252                      (uint32_t)imm << 8  |
19253                      (uint32_t)imm;
19254             result = (int32_t)result;
19255             tcg_gen_movi_tl(t0, result);
19256             gen_store_gpr(t0, rt);
19257         }
19258         break;
19259     default:
19260         generate_exception_end(ctx, EXCP_RI);
19261         break;
19262     }
19263     tcg_temp_free(t0);
19264     tcg_temp_free(rs_t);
19265 }
19266
19267
19268 static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
19269 {
19270     int rt = extract32(ctx->opcode, 21, 5);
19271     int rs = extract32(ctx->opcode, 16, 5);
19272     int rd = extract32(ctx->opcode, 11, 5);
19273
19274     switch (extract32(ctx->opcode, 6, 3)) {
19275     case NM_POOL32AXF_1:
19276         {
19277             int32_t op1 = extract32(ctx->opcode, 9, 3);
19278             gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd);
19279         }
19280         break;
19281     case NM_POOL32AXF_2:
19282         {
19283             int32_t op1 = extract32(ctx->opcode, 12, 2);
19284             gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd);
19285         }
19286         break;
19287     case NM_POOL32AXF_4:
19288         {
19289             int32_t op1 = extract32(ctx->opcode, 9, 7);
19290             gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs);
19291         }
19292         break;
19293     case NM_POOL32AXF_5:
19294         switch (extract32(ctx->opcode, 9, 7)) {
19295 #ifndef CONFIG_USER_ONLY
19296         case NM_TLBP:
19297             gen_cp0(env, ctx, OPC_TLBP, 0, 0);
19298             break;
19299         case NM_TLBR:
19300             gen_cp0(env, ctx, OPC_TLBR, 0, 0);
19301             break;
19302         case NM_TLBWI:
19303             gen_cp0(env, ctx, OPC_TLBWI, 0, 0);
19304             break;
19305         case NM_TLBWR:
19306             gen_cp0(env, ctx, OPC_TLBWR, 0, 0);
19307             break;
19308         case NM_TLBINV:
19309             gen_cp0(env, ctx, OPC_TLBINV, 0, 0);
19310             break;
19311         case NM_TLBINVF:
19312             gen_cp0(env, ctx, OPC_TLBINVF, 0, 0);
19313             break;
19314         case NM_DI:
19315             check_cp0_enabled(ctx);
19316             {
19317                 TCGv t0 = tcg_temp_new();
19318
19319                 save_cpu_state(ctx, 1);
19320                 gen_helper_di(t0, cpu_env);
19321                 gen_store_gpr(t0, rt);
19322             /* Stop translation as we may have switched the execution mode */
19323                 ctx->base.is_jmp = DISAS_STOP;
19324                 tcg_temp_free(t0);
19325             }
19326             break;
19327         case NM_EI:
19328             check_cp0_enabled(ctx);
19329             {
19330                 TCGv t0 = tcg_temp_new();
19331
19332                 save_cpu_state(ctx, 1);
19333                 gen_helper_ei(t0, cpu_env);
19334                 gen_store_gpr(t0, rt);
19335             /* Stop translation as we may have switched the execution mode */
19336                 ctx->base.is_jmp = DISAS_STOP;
19337                 tcg_temp_free(t0);
19338             }
19339             break;
19340         case NM_RDPGPR:
19341             gen_load_srsgpr(rs, rt);
19342             break;
19343         case NM_WRPGPR:
19344             gen_store_srsgpr(rs, rt);
19345             break;
19346         case NM_WAIT:
19347             gen_cp0(env, ctx, OPC_WAIT, 0, 0);
19348             break;
19349         case NM_DERET:
19350             gen_cp0(env, ctx, OPC_DERET, 0, 0);
19351             break;
19352         case NM_ERETX:
19353             gen_cp0(env, ctx, OPC_ERET, 0, 0);
19354             break;
19355 #endif
19356         default:
19357             generate_exception_end(ctx, EXCP_RI);
19358             break;
19359         }
19360         break;
19361     case NM_POOL32AXF_7:
19362         {
19363             int32_t op1 = extract32(ctx->opcode, 9, 3);
19364             gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd);
19365         }
19366         break;
19367     default:
19368         generate_exception_end(ctx, EXCP_RI);
19369         break;
19370     }
19371 }
19372
19373 /* Immediate Value Compact Branches */
19374 static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc,
19375                                    int rt, int32_t imm, int32_t offset)
19376 {
19377     TCGCond cond;
19378     int bcond_compute = 0;
19379     TCGv t0 = tcg_temp_new();
19380     TCGv t1 = tcg_temp_new();
19381
19382     gen_load_gpr(t0, rt);
19383     tcg_gen_movi_tl(t1, imm);
19384     ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19385
19386     /* Load needed operands and calculate btarget */
19387     switch (opc) {
19388     case NM_BEQIC:
19389         if (rt == 0 && imm == 0) {
19390             /* Unconditional branch */
19391         } else if (rt == 0 && imm != 0) {
19392             /* Treat as NOP */
19393             goto out;
19394         } else {
19395             bcond_compute = 1;
19396             cond = TCG_COND_EQ;
19397         }
19398         break;
19399     case NM_BBEQZC:
19400     case NM_BBNEZC:
19401         check_nms(ctx);
19402         if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) {
19403             generate_exception_end(ctx, EXCP_RI);
19404             goto out;
19405         } else if (rt == 0 && opc == NM_BBEQZC) {
19406             /* Unconditional branch */
19407         } else if (rt == 0 && opc == NM_BBNEZC) {
19408             /* Treat as NOP */
19409             goto out;
19410         } else {
19411             tcg_gen_shri_tl(t0, t0, imm);
19412             tcg_gen_andi_tl(t0, t0, 1);
19413             tcg_gen_movi_tl(t1, 0);
19414             bcond_compute = 1;
19415             if (opc == NM_BBEQZC) {
19416                 cond = TCG_COND_EQ;
19417             } else {
19418                 cond = TCG_COND_NE;
19419             }
19420         }
19421         break;
19422     case NM_BNEIC:
19423         if (rt == 0 && imm == 0) {
19424             /* Treat as NOP */
19425             goto out;
19426         } else if (rt == 0 && imm != 0) {
19427             /* Unconditional branch */
19428         } else {
19429             bcond_compute = 1;
19430             cond = TCG_COND_NE;
19431         }
19432         break;
19433     case NM_BGEIC:
19434         if (rt == 0 && imm == 0) {
19435             /* Unconditional branch */
19436         } else  {
19437             bcond_compute = 1;
19438             cond = TCG_COND_GE;
19439         }
19440         break;
19441     case NM_BLTIC:
19442         bcond_compute = 1;
19443         cond = TCG_COND_LT;
19444         break;
19445     case NM_BGEIUC:
19446         if (rt == 0 && imm == 0) {
19447             /* Unconditional branch */
19448         } else  {
19449             bcond_compute = 1;
19450             cond = TCG_COND_GEU;
19451         }
19452         break;
19453     case NM_BLTIUC:
19454         bcond_compute = 1;
19455         cond = TCG_COND_LTU;
19456         break;
19457     default:
19458         MIPS_INVAL("Immediate Value Compact branch");
19459         generate_exception_end(ctx, EXCP_RI);
19460         goto out;
19461     }
19462
19463     if (bcond_compute == 0) {
19464         /* Uncoditional compact branch */
19465         gen_goto_tb(ctx, 0, ctx->btarget);
19466     } else {
19467         /* Conditional compact branch */
19468         TCGLabel *fs = gen_new_label();
19469
19470         tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs);
19471
19472         gen_goto_tb(ctx, 1, ctx->btarget);
19473         gen_set_label(fs);
19474
19475         gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19476     }
19477
19478 out:
19479     tcg_temp_free(t0);
19480     tcg_temp_free(t1);
19481 }
19482
19483 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
19484 static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs,
19485                                                 int rt)
19486 {
19487     TCGv t0 = tcg_temp_new();
19488     TCGv t1 = tcg_temp_new();
19489
19490     /* load rs */
19491     gen_load_gpr(t0, rs);
19492
19493     /* link */
19494     if (rt != 0) {
19495         tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4);
19496     }
19497
19498     /* calculate btarget */
19499     tcg_gen_shli_tl(t0, t0, 1);
19500     tcg_gen_movi_tl(t1, ctx->base.pc_next + 4);
19501     gen_op_addr_add(ctx, btarget, t1, t0);
19502
19503     /* unconditional branch to register */
19504     tcg_gen_mov_tl(cpu_PC, btarget);
19505     tcg_gen_lookup_and_goto_ptr();
19506
19507     tcg_temp_free(t0);
19508     tcg_temp_free(t1);
19509 }
19510
19511 /* nanoMIPS Branches */
19512 static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc,
19513                                        int rs, int rt, int32_t offset)
19514 {
19515     int bcond_compute = 0;
19516     TCGv t0 = tcg_temp_new();
19517     TCGv t1 = tcg_temp_new();
19518
19519     /* Load needed operands and calculate btarget */
19520     switch (opc) {
19521     /* compact branch */
19522     case OPC_BGEC:
19523     case OPC_BLTC:
19524         gen_load_gpr(t0, rs);
19525         gen_load_gpr(t1, rt);
19526         bcond_compute = 1;
19527         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19528         break;
19529     case OPC_BGEUC:
19530     case OPC_BLTUC:
19531         if (rs == 0 || rs == rt) {
19532             /* OPC_BLEZALC, OPC_BGEZALC */
19533             /* OPC_BGTZALC, OPC_BLTZALC */
19534             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4);
19535         }
19536         gen_load_gpr(t0, rs);
19537         gen_load_gpr(t1, rt);
19538         bcond_compute = 1;
19539         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19540         break;
19541     case OPC_BC:
19542         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19543         break;
19544     case OPC_BEQZC:
19545         if (rs != 0) {
19546             /* OPC_BEQZC, OPC_BNEZC */
19547             gen_load_gpr(t0, rs);
19548             bcond_compute = 1;
19549             ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19550         } else {
19551             /* OPC_JIC, OPC_JIALC */
19552             TCGv tbase = tcg_temp_new();
19553             TCGv toffset = tcg_temp_new();
19554
19555             gen_load_gpr(tbase, rt);
19556             tcg_gen_movi_tl(toffset, offset);
19557             gen_op_addr_add(ctx, btarget, tbase, toffset);
19558             tcg_temp_free(tbase);
19559             tcg_temp_free(toffset);
19560         }
19561         break;
19562     default:
19563         MIPS_INVAL("Compact branch/jump");
19564         generate_exception_end(ctx, EXCP_RI);
19565         goto out;
19566     }
19567
19568     if (bcond_compute == 0) {
19569         /* Uncoditional compact branch */
19570         switch (opc) {
19571         case OPC_BC:
19572             gen_goto_tb(ctx, 0, ctx->btarget);
19573             break;
19574         default:
19575             MIPS_INVAL("Compact branch/jump");
19576             generate_exception_end(ctx, EXCP_RI);
19577             goto out;
19578         }
19579     } else {
19580         /* Conditional compact branch */
19581         TCGLabel *fs = gen_new_label();
19582
19583         switch (opc) {
19584         case OPC_BGEUC:
19585             if (rs == 0 && rt != 0) {
19586                 /* OPC_BLEZALC */
19587                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19588             } else if (rs != 0 && rt != 0 && rs == rt) {
19589                 /* OPC_BGEZALC */
19590                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19591             } else {
19592                 /* OPC_BGEUC */
19593                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
19594             }
19595             break;
19596         case OPC_BLTUC:
19597             if (rs == 0 && rt != 0) {
19598                 /* OPC_BGTZALC */
19599                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19600             } else if (rs != 0 && rt != 0 && rs == rt) {
19601                 /* OPC_BLTZALC */
19602                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19603             } else {
19604                 /* OPC_BLTUC */
19605                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
19606             }
19607             break;
19608         case OPC_BGEC:
19609             if (rs == 0 && rt != 0) {
19610                 /* OPC_BLEZC */
19611                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19612             } else if (rs != 0 && rt != 0 && rs == rt) {
19613                 /* OPC_BGEZC */
19614                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19615             } else {
19616                 /* OPC_BGEC */
19617                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
19618             }
19619             break;
19620         case OPC_BLTC:
19621             if (rs == 0 && rt != 0) {
19622                 /* OPC_BGTZC */
19623                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19624             } else if (rs != 0 && rt != 0 && rs == rt) {
19625                 /* OPC_BLTZC */
19626                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19627             } else {
19628                 /* OPC_BLTC */
19629                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
19630             }
19631             break;
19632         case OPC_BEQZC:
19633             tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
19634             break;
19635         default:
19636             MIPS_INVAL("Compact conditional branch/jump");
19637             generate_exception_end(ctx, EXCP_RI);
19638             goto out;
19639         }
19640
19641         /* Generating branch here as compact branches don't have delay slot */
19642         gen_goto_tb(ctx, 1, ctx->btarget);
19643         gen_set_label(fs);
19644
19645         gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19646     }
19647
19648 out:
19649     tcg_temp_free(t0);
19650     tcg_temp_free(t1);
19651 }
19652
19653
19654 /* nanoMIPS CP1 Branches */
19655 static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op,
19656                                    int32_t ft, int32_t offset)
19657 {
19658     target_ulong btarget;
19659     TCGv_i64 t0 = tcg_temp_new_i64();
19660
19661     gen_load_fpr64(ctx, t0, ft);
19662     tcg_gen_andi_i64(t0, t0, 1);
19663
19664     btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19665
19666     switch (op) {
19667     case NM_BC1EQZC:
19668         tcg_gen_xori_i64(t0, t0, 1);
19669         ctx->hflags |= MIPS_HFLAG_BC;
19670         break;
19671     case NM_BC1NEZC:
19672         /* t0 already set */
19673         ctx->hflags |= MIPS_HFLAG_BC;
19674         break;
19675     default:
19676         MIPS_INVAL("cp1 cond branch");
19677         generate_exception_end(ctx, EXCP_RI);
19678         goto out;
19679     }
19680
19681     tcg_gen_trunc_i64_tl(bcond, t0);
19682
19683     ctx->btarget = btarget;
19684
19685 out:
19686     tcg_temp_free_i64(t0);
19687 }
19688
19689
19690 static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt)
19691 {
19692     TCGv t0, t1;
19693     t0 = tcg_temp_new();
19694     t1 = tcg_temp_new();
19695
19696     gen_load_gpr(t0, rs);
19697     gen_load_gpr(t1, rt);
19698
19699     if ((extract32(ctx->opcode, 6, 1)) == 1) {
19700         /* PP.LSXS instructions require shifting */
19701         switch (extract32(ctx->opcode, 7, 4)) {
19702         case NM_SHXS:
19703             check_nms(ctx);
19704         case NM_LHXS:
19705         case NM_LHUXS:
19706             tcg_gen_shli_tl(t0, t0, 1);
19707             break;
19708         case NM_SWXS:
19709             check_nms(ctx);
19710         case NM_LWXS:
19711         case NM_LWC1XS:
19712         case NM_SWC1XS:
19713             tcg_gen_shli_tl(t0, t0, 2);
19714             break;
19715         case NM_LDC1XS:
19716         case NM_SDC1XS:
19717             tcg_gen_shli_tl(t0, t0, 3);
19718             break;
19719         }
19720     }
19721     gen_op_addr_add(ctx, t0, t0, t1);
19722
19723     switch (extract32(ctx->opcode, 7, 4)) {
19724     case NM_LBX:
19725         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19726                            MO_SB);
19727         gen_store_gpr(t0, rd);
19728         break;
19729     case NM_LHX:
19730     /*case NM_LHXS:*/
19731         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19732                            MO_TESW);
19733         gen_store_gpr(t0, rd);
19734         break;
19735     case NM_LWX:
19736     /*case NM_LWXS:*/
19737         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19738                            MO_TESL);
19739         gen_store_gpr(t0, rd);
19740         break;
19741     case NM_LBUX:
19742         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19743                            MO_UB);
19744         gen_store_gpr(t0, rd);
19745         break;
19746     case NM_LHUX:
19747     /*case NM_LHUXS:*/
19748         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19749                            MO_TEUW);
19750         gen_store_gpr(t0, rd);
19751         break;
19752     case NM_SBX:
19753         check_nms(ctx);
19754         gen_load_gpr(t1, rd);
19755         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19756                            MO_8);
19757         break;
19758     case NM_SHX:
19759     /*case NM_SHXS:*/
19760         check_nms(ctx);
19761         gen_load_gpr(t1, rd);
19762         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19763                            MO_TEUW);
19764         break;
19765     case NM_SWX:
19766     /*case NM_SWXS:*/
19767         check_nms(ctx);
19768         gen_load_gpr(t1, rd);
19769         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19770                            MO_TEUL);
19771         break;
19772     case NM_LWC1X:
19773     /*case NM_LWC1XS:*/
19774     case NM_LDC1X:
19775     /*case NM_LDC1XS:*/
19776     case NM_SWC1X:
19777     /*case NM_SWC1XS:*/
19778     case NM_SDC1X:
19779     /*case NM_SDC1XS:*/
19780         if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
19781             check_cp1_enabled(ctx);
19782             switch (extract32(ctx->opcode, 7, 4)) {
19783             case NM_LWC1X:
19784             /*case NM_LWC1XS:*/
19785                 gen_flt_ldst(ctx, OPC_LWC1, rd, t0);
19786                 break;
19787             case NM_LDC1X:
19788             /*case NM_LDC1XS:*/
19789                 gen_flt_ldst(ctx, OPC_LDC1, rd, t0);
19790                 break;
19791             case NM_SWC1X:
19792             /*case NM_SWC1XS:*/
19793                 gen_flt_ldst(ctx, OPC_SWC1, rd, t0);
19794                 break;
19795             case NM_SDC1X:
19796             /*case NM_SDC1XS:*/
19797                 gen_flt_ldst(ctx, OPC_SDC1, rd, t0);
19798                 break;
19799             }
19800         } else {
19801             generate_exception_err(ctx, EXCP_CpU, 1);
19802         }
19803         break;
19804     default:
19805         generate_exception_end(ctx, EXCP_RI);
19806         break;
19807     }
19808
19809     tcg_temp_free(t0);
19810     tcg_temp_free(t1);
19811 }
19812
19813 static void gen_pool32f_nanomips_insn(DisasContext *ctx)
19814 {
19815     int rt, rs, rd;
19816
19817     rt = extract32(ctx->opcode, 21, 5);
19818     rs = extract32(ctx->opcode, 16, 5);
19819     rd = extract32(ctx->opcode, 11, 5);
19820
19821     if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) {
19822         generate_exception_end(ctx, EXCP_RI);
19823         return;
19824     }
19825     check_cp1_enabled(ctx);
19826     switch (extract32(ctx->opcode, 0, 3)) {
19827     case NM_POOL32F_0:
19828         switch (extract32(ctx->opcode, 3, 7)) {
19829         case NM_RINT_S:
19830             gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
19831             break;
19832         case NM_RINT_D:
19833             gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
19834             break;
19835         case NM_CLASS_S:
19836             gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
19837             break;
19838         case NM_CLASS_D:
19839             gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
19840             break;
19841         case NM_ADD_S:
19842             gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0);
19843             break;
19844         case NM_ADD_D:
19845             gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0);
19846             break;
19847         case NM_SUB_S:
19848             gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0);
19849             break;
19850         case NM_SUB_D:
19851             gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0);
19852             break;
19853         case NM_MUL_S:
19854             gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0);
19855             break;
19856         case NM_MUL_D:
19857             gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0);
19858             break;
19859         case NM_DIV_S:
19860             gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0);
19861             break;
19862         case NM_DIV_D:
19863             gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0);
19864             break;
19865         case NM_SELEQZ_S:
19866             gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
19867             break;
19868         case NM_SELEQZ_D:
19869             gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
19870             break;
19871         case NM_SELNEZ_S:
19872             gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
19873             break;
19874         case NM_SELNEZ_D:
19875             gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
19876             break;
19877         case NM_SEL_S:
19878             gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
19879             break;
19880         case NM_SEL_D:
19881             gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
19882             break;
19883         case NM_MADDF_S:
19884             gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0);
19885             break;
19886         case NM_MADDF_D:
19887             gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0);
19888             break;
19889         case NM_MSUBF_S:
19890             gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0);
19891             break;
19892         case NM_MSUBF_D:
19893             gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0);
19894             break;
19895         default:
19896             generate_exception_end(ctx, EXCP_RI);
19897             break;
19898         }
19899         break;
19900     case NM_POOL32F_3:
19901         switch (extract32(ctx->opcode, 3, 3)) {
19902         case NM_MIN_FMT:
19903             switch (extract32(ctx->opcode, 9, 1)) {
19904             case FMT_SDPS_S:
19905                 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
19906                 break;
19907             case FMT_SDPS_D:
19908                 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
19909                 break;
19910             }
19911             break;
19912         case NM_MAX_FMT:
19913             switch (extract32(ctx->opcode, 9, 1)) {
19914             case FMT_SDPS_S:
19915                 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
19916                 break;
19917             case FMT_SDPS_D:
19918                 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
19919                 break;
19920             }
19921             break;
19922         case NM_MINA_FMT:
19923             switch (extract32(ctx->opcode, 9, 1)) {
19924             case FMT_SDPS_S:
19925                 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
19926                 break;
19927             case FMT_SDPS_D:
19928                 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
19929                 break;
19930             }
19931             break;
19932         case NM_MAXA_FMT:
19933             switch (extract32(ctx->opcode, 9, 1)) {
19934             case FMT_SDPS_S:
19935                 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
19936                 break;
19937             case FMT_SDPS_D:
19938                 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
19939                 break;
19940             }
19941             break;
19942         case NM_POOL32FXF:
19943             switch (extract32(ctx->opcode, 6, 8)) {
19944             case NM_CFC1:
19945                 gen_cp1(ctx, OPC_CFC1, rt, rs);
19946                 break;
19947             case NM_CTC1:
19948                 gen_cp1(ctx, OPC_CTC1, rt, rs);
19949                 break;
19950             case NM_MFC1:
19951                 gen_cp1(ctx, OPC_MFC1, rt, rs);
19952                 break;
19953             case NM_MTC1:
19954                 gen_cp1(ctx, OPC_MTC1, rt, rs);
19955                 break;
19956             case NM_MFHC1:
19957                 gen_cp1(ctx, OPC_MFHC1, rt, rs);
19958                 break;
19959             case NM_MTHC1:
19960                 gen_cp1(ctx, OPC_MTHC1, rt, rs);
19961                 break;
19962             case NM_CVT_S_PL:
19963                 gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0);
19964                 break;
19965             case NM_CVT_S_PU:
19966                 gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0);
19967                 break;
19968             default:
19969                 switch (extract32(ctx->opcode, 6, 9)) {
19970                 case NM_CVT_L_S:
19971                     gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0);
19972                     break;
19973                 case NM_CVT_L_D:
19974                     gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0);
19975                     break;
19976                 case NM_CVT_W_S:
19977                     gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0);
19978                     break;
19979                 case NM_CVT_W_D:
19980                     gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0);
19981                     break;
19982                 case NM_RSQRT_S:
19983                     gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0);
19984                     break;
19985                 case NM_RSQRT_D:
19986                     gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0);
19987                     break;
19988                 case NM_SQRT_S:
19989                     gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0);
19990                     break;
19991                 case NM_SQRT_D:
19992                     gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0);
19993                     break;
19994                 case NM_RECIP_S:
19995                     gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0);
19996                     break;
19997                 case NM_RECIP_D:
19998                     gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0);
19999                     break;
20000                 case NM_FLOOR_L_S:
20001                     gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0);
20002                     break;
20003                 case NM_FLOOR_L_D:
20004                     gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0);
20005                     break;
20006                 case NM_FLOOR_W_S:
20007                     gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0);
20008                     break;
20009                 case NM_FLOOR_W_D:
20010                     gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0);
20011                     break;
20012                 case NM_CEIL_L_S:
20013                     gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0);
20014                     break;
20015                 case NM_CEIL_L_D:
20016                     gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0);
20017                     break;
20018                 case NM_CEIL_W_S:
20019                     gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0);
20020                     break;
20021                 case NM_CEIL_W_D:
20022                     gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0);
20023                     break;
20024                 case NM_TRUNC_L_S:
20025                     gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0);
20026                     break;
20027                 case NM_TRUNC_L_D:
20028                     gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0);
20029                     break;
20030                 case NM_TRUNC_W_S:
20031                     gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0);
20032                     break;
20033                 case NM_TRUNC_W_D:
20034                     gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0);
20035                     break;
20036                 case NM_ROUND_L_S:
20037                     gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0);
20038                     break;
20039                 case NM_ROUND_L_D:
20040                     gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0);
20041                     break;
20042                 case NM_ROUND_W_S:
20043                     gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0);
20044                     break;
20045                 case NM_ROUND_W_D:
20046                     gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0);
20047                     break;
20048                 case NM_MOV_S:
20049                     gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0);
20050                     break;
20051                 case NM_MOV_D:
20052                     gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0);
20053                     break;
20054                 case NM_ABS_S:
20055                     gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0);
20056                     break;
20057                 case NM_ABS_D:
20058                     gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0);
20059                     break;
20060                 case NM_NEG_S:
20061                     gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0);
20062                     break;
20063                 case NM_NEG_D:
20064                     gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0);
20065                     break;
20066                 case NM_CVT_D_S:
20067                     gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0);
20068                     break;
20069                 case NM_CVT_D_W:
20070                     gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0);
20071                     break;
20072                 case NM_CVT_D_L:
20073                     gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0);
20074                     break;
20075                 case NM_CVT_S_D:
20076                     gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0);
20077                     break;
20078                 case NM_CVT_S_W:
20079                     gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0);
20080                     break;
20081                 case NM_CVT_S_L:
20082                     gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0);
20083                     break;
20084                 default:
20085                     generate_exception_end(ctx, EXCP_RI);
20086                     break;
20087                 }
20088                 break;
20089             }
20090             break;
20091         }
20092         break;
20093     case NM_POOL32F_5:
20094         switch (extract32(ctx->opcode, 3, 3)) {
20095         case NM_CMP_CONDN_S:
20096             gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20097             break;
20098         case NM_CMP_CONDN_D:
20099             gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20100             break;
20101         default:
20102             generate_exception_end(ctx, EXCP_RI);
20103             break;
20104         }
20105         break;
20106     default:
20107         generate_exception_end(ctx, EXCP_RI);
20108         break;
20109     }
20110 }
20111
20112 static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc,
20113                                        int rd, int rs, int rt)
20114 {
20115     int ret = rd;
20116     TCGv t0 = tcg_temp_new();
20117     TCGv v1_t = tcg_temp_new();
20118     TCGv v2_t = tcg_temp_new();
20119
20120     gen_load_gpr(v1_t, rs);
20121     gen_load_gpr(v2_t, rt);
20122
20123     switch (opc) {
20124     case NM_CMP_EQ_PH:
20125         check_dsp(ctx);
20126         gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
20127         break;
20128     case NM_CMP_LT_PH:
20129         check_dsp(ctx);
20130         gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
20131         break;
20132     case NM_CMP_LE_PH:
20133         check_dsp(ctx);
20134         gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
20135         break;
20136     case NM_CMPU_EQ_QB:
20137         check_dsp(ctx);
20138         gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
20139         break;
20140     case NM_CMPU_LT_QB:
20141         check_dsp(ctx);
20142         gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
20143         break;
20144     case NM_CMPU_LE_QB:
20145         check_dsp(ctx);
20146         gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
20147         break;
20148     case NM_CMPGU_EQ_QB:
20149         check_dsp(ctx);
20150         gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20151         gen_store_gpr(v1_t, ret);
20152         break;
20153     case NM_CMPGU_LT_QB:
20154         check_dsp(ctx);
20155         gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20156         gen_store_gpr(v1_t, ret);
20157         break;
20158     case NM_CMPGU_LE_QB:
20159         check_dsp(ctx);
20160         gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20161         gen_store_gpr(v1_t, ret);
20162         break;
20163     case NM_CMPGDU_EQ_QB:
20164         check_dsp_r2(ctx);
20165         gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20166         tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20167         gen_store_gpr(v1_t, ret);
20168         break;
20169     case NM_CMPGDU_LT_QB:
20170         check_dsp_r2(ctx);
20171         gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20172         tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20173         gen_store_gpr(v1_t, ret);
20174         break;
20175     case NM_CMPGDU_LE_QB:
20176         check_dsp_r2(ctx);
20177         gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20178         tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20179         gen_store_gpr(v1_t, ret);
20180         break;
20181     case NM_PACKRL_PH:
20182         check_dsp(ctx);
20183         gen_helper_packrl_ph(v1_t, v1_t, v2_t);
20184         gen_store_gpr(v1_t, ret);
20185         break;
20186     case NM_PICK_QB:
20187         check_dsp(ctx);
20188         gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env);
20189         gen_store_gpr(v1_t, ret);
20190         break;
20191     case NM_PICK_PH:
20192         check_dsp(ctx);
20193         gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env);
20194         gen_store_gpr(v1_t, ret);
20195         break;
20196     case NM_ADDQ_S_W:
20197         check_dsp(ctx);
20198         gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env);
20199         gen_store_gpr(v1_t, ret);
20200         break;
20201     case NM_SUBQ_S_W:
20202         check_dsp(ctx);
20203         gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env);
20204         gen_store_gpr(v1_t, ret);
20205         break;
20206     case NM_ADDSC:
20207         check_dsp(ctx);
20208         gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env);
20209         gen_store_gpr(v1_t, ret);
20210         break;
20211     case NM_ADDWC:
20212         check_dsp(ctx);
20213         gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env);
20214         gen_store_gpr(v1_t, ret);
20215         break;
20216     case NM_ADDQ_S_PH:
20217         check_dsp(ctx);
20218         switch (extract32(ctx->opcode, 10, 1)) {
20219         case 0:
20220             /* ADDQ_PH */
20221             gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env);
20222             gen_store_gpr(v1_t, ret);
20223             break;
20224         case 1:
20225             /* ADDQ_S_PH */
20226             gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20227             gen_store_gpr(v1_t, ret);
20228             break;
20229         }
20230         break;
20231     case NM_ADDQH_R_PH:
20232         check_dsp_r2(ctx);
20233         switch (extract32(ctx->opcode, 10, 1)) {
20234         case 0:
20235             /* ADDQH_PH */
20236             gen_helper_addqh_ph(v1_t, v1_t, v2_t);
20237             gen_store_gpr(v1_t, ret);
20238             break;
20239         case 1:
20240             /* ADDQH_R_PH */
20241             gen_helper_addqh_r_ph(v1_t, v1_t, v2_t);
20242             gen_store_gpr(v1_t, ret);
20243             break;
20244         }
20245         break;
20246     case NM_ADDQH_R_W:
20247         check_dsp_r2(ctx);
20248         switch (extract32(ctx->opcode, 10, 1)) {
20249         case 0:
20250             /* ADDQH_W */
20251             gen_helper_addqh_w(v1_t, v1_t, v2_t);
20252             gen_store_gpr(v1_t, ret);
20253             break;
20254         case 1:
20255             /* ADDQH_R_W */
20256             gen_helper_addqh_r_w(v1_t, v1_t, v2_t);
20257             gen_store_gpr(v1_t, ret);
20258             break;
20259         }
20260         break;
20261     case NM_ADDU_S_QB:
20262         check_dsp(ctx);
20263         switch (extract32(ctx->opcode, 10, 1)) {
20264         case 0:
20265             /* ADDU_QB */
20266             gen_helper_addu_qb(v1_t, v1_t, v2_t, cpu_env);
20267             gen_store_gpr(v1_t, ret);
20268             break;
20269         case 1:
20270             /* ADDU_S_QB */
20271             gen_helper_addu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20272             gen_store_gpr(v1_t, ret);
20273             break;
20274         }
20275         break;
20276     case NM_ADDU_S_PH:
20277         check_dsp_r2(ctx);
20278         switch (extract32(ctx->opcode, 10, 1)) {
20279         case 0:
20280             /* ADDU_PH */
20281             gen_helper_addu_ph(v1_t, v1_t, v2_t, cpu_env);
20282             gen_store_gpr(v1_t, ret);
20283             break;
20284         case 1:
20285             /* ADDU_S_PH */
20286             gen_helper_addu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20287             gen_store_gpr(v1_t, ret);
20288             break;
20289         }
20290         break;
20291     case NM_ADDUH_R_QB:
20292         check_dsp_r2(ctx);
20293         switch (extract32(ctx->opcode, 10, 1)) {
20294         case 0:
20295             /* ADDUH_QB */
20296             gen_helper_adduh_qb(v1_t, v1_t, v2_t);
20297             gen_store_gpr(v1_t, ret);
20298             break;
20299         case 1:
20300             /* ADDUH_R_QB */
20301             gen_helper_adduh_r_qb(v1_t, v1_t, v2_t);
20302             gen_store_gpr(v1_t, ret);
20303             break;
20304         }
20305         break;
20306     case NM_SHRAV_R_PH:
20307         check_dsp(ctx);
20308         switch (extract32(ctx->opcode, 10, 1)) {
20309         case 0:
20310             /* SHRAV_PH */
20311             gen_helper_shra_ph(v1_t, v1_t, v2_t);
20312             gen_store_gpr(v1_t, ret);
20313             break;
20314         case 1:
20315             /* SHRAV_R_PH */
20316             gen_helper_shra_r_ph(v1_t, v1_t, v2_t);
20317             gen_store_gpr(v1_t, ret);
20318             break;
20319         }
20320         break;
20321     case NM_SHRAV_R_QB:
20322         check_dsp_r2(ctx);
20323         switch (extract32(ctx->opcode, 10, 1)) {
20324         case 0:
20325             /* SHRAV_QB */
20326             gen_helper_shra_qb(v1_t, v1_t, v2_t);
20327             gen_store_gpr(v1_t, ret);
20328             break;
20329         case 1:
20330             /* SHRAV_R_QB */
20331             gen_helper_shra_r_qb(v1_t, v1_t, v2_t);
20332             gen_store_gpr(v1_t, ret);
20333             break;
20334         }
20335         break;
20336     case NM_SUBQ_S_PH:
20337         check_dsp(ctx);
20338         switch (extract32(ctx->opcode, 10, 1)) {
20339         case 0:
20340             /* SUBQ_PH */
20341             gen_helper_subq_ph(v1_t, v1_t, v2_t, cpu_env);
20342             gen_store_gpr(v1_t, ret);
20343             break;
20344         case 1:
20345             /* SUBQ_S_PH */
20346             gen_helper_subq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20347             gen_store_gpr(v1_t, ret);
20348             break;
20349         }
20350         break;
20351     case NM_SUBQH_R_PH:
20352         check_dsp_r2(ctx);
20353         switch (extract32(ctx->opcode, 10, 1)) {
20354         case 0:
20355             /* SUBQH_PH */
20356             gen_helper_subqh_ph(v1_t, v1_t, v2_t);
20357             gen_store_gpr(v1_t, ret);
20358             break;
20359         case 1:
20360             /* SUBQH_R_PH */
20361             gen_helper_subqh_r_ph(v1_t, v1_t, v2_t);
20362             gen_store_gpr(v1_t, ret);
20363             break;
20364         }
20365         break;
20366     case NM_SUBQH_R_W:
20367         check_dsp_r2(ctx);
20368         switch (extract32(ctx->opcode, 10, 1)) {
20369         case 0:
20370             /* SUBQH_W */
20371             gen_helper_subqh_w(v1_t, v1_t, v2_t);
20372             gen_store_gpr(v1_t, ret);
20373             break;
20374         case 1:
20375             /* SUBQH_R_W */
20376             gen_helper_subqh_r_w(v1_t, v1_t, v2_t);
20377             gen_store_gpr(v1_t, ret);
20378             break;
20379         }
20380         break;
20381     case NM_SUBU_S_QB:
20382         check_dsp(ctx);
20383         switch (extract32(ctx->opcode, 10, 1)) {
20384         case 0:
20385             /* SUBU_QB */
20386             gen_helper_subu_qb(v1_t, v1_t, v2_t, cpu_env);
20387             gen_store_gpr(v1_t, ret);
20388             break;
20389         case 1:
20390             /* SUBU_S_QB */
20391             gen_helper_subu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20392             gen_store_gpr(v1_t, ret);
20393             break;
20394         }
20395         break;
20396     case NM_SUBU_S_PH:
20397         check_dsp_r2(ctx);
20398         switch (extract32(ctx->opcode, 10, 1)) {
20399         case 0:
20400             /* SUBU_PH */
20401             gen_helper_subu_ph(v1_t, v1_t, v2_t, cpu_env);
20402             gen_store_gpr(v1_t, ret);
20403             break;
20404         case 1:
20405             /* SUBU_S_PH */
20406             gen_helper_subu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20407             gen_store_gpr(v1_t, ret);
20408             break;
20409         }
20410         break;
20411     case NM_SUBUH_R_QB:
20412         check_dsp_r2(ctx);
20413         switch (extract32(ctx->opcode, 10, 1)) {
20414         case 0:
20415             /* SUBUH_QB */
20416             gen_helper_subuh_qb(v1_t, v1_t, v2_t);
20417             gen_store_gpr(v1_t, ret);
20418             break;
20419         case 1:
20420             /* SUBUH_R_QB */
20421             gen_helper_subuh_r_qb(v1_t, v1_t, v2_t);
20422             gen_store_gpr(v1_t, ret);
20423             break;
20424         }
20425         break;
20426     case NM_SHLLV_S_PH:
20427         check_dsp(ctx);
20428         switch (extract32(ctx->opcode, 10, 1)) {
20429         case 0:
20430             /* SHLLV_PH */
20431             gen_helper_shll_ph(v1_t, v1_t, v2_t, cpu_env);
20432             gen_store_gpr(v1_t, ret);
20433             break;
20434         case 1:
20435             /* SHLLV_S_PH */
20436             gen_helper_shll_s_ph(v1_t, v1_t, v2_t, cpu_env);
20437             gen_store_gpr(v1_t, ret);
20438             break;
20439         }
20440         break;
20441     case NM_PRECR_SRA_R_PH_W:
20442         check_dsp_r2(ctx);
20443         switch (extract32(ctx->opcode, 10, 1)) {
20444         case 0:
20445             /* PRECR_SRA_PH_W */
20446             {
20447                 TCGv_i32 sa_t = tcg_const_i32(rd);
20448                 gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t,
20449                                           cpu_gpr[rt]);
20450                 gen_store_gpr(v1_t, rt);
20451                 tcg_temp_free_i32(sa_t);
20452             }
20453             break;
20454         case 1:
20455             /* PRECR_SRA_R_PH_W */
20456             {
20457                 TCGv_i32 sa_t = tcg_const_i32(rd);
20458                 gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t,
20459                                             cpu_gpr[rt]);
20460                 gen_store_gpr(v1_t, rt);
20461                 tcg_temp_free_i32(sa_t);
20462             }
20463             break;
20464        }
20465         break;
20466     case NM_MULEU_S_PH_QBL:
20467         check_dsp(ctx);
20468         gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, cpu_env);
20469         gen_store_gpr(v1_t, ret);
20470         break;
20471     case NM_MULEU_S_PH_QBR:
20472         check_dsp(ctx);
20473         gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, cpu_env);
20474         gen_store_gpr(v1_t, ret);
20475         break;
20476     case NM_MULQ_RS_PH:
20477         check_dsp(ctx);
20478         gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, cpu_env);
20479         gen_store_gpr(v1_t, ret);
20480         break;
20481     case NM_MULQ_S_PH:
20482         check_dsp_r2(ctx);
20483         gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20484         gen_store_gpr(v1_t, ret);
20485         break;
20486     case NM_MULQ_RS_W:
20487         check_dsp_r2(ctx);
20488         gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, cpu_env);
20489         gen_store_gpr(v1_t, ret);
20490         break;
20491     case NM_MULQ_S_W:
20492         check_dsp_r2(ctx);
20493         gen_helper_mulq_s_w(v1_t, v1_t, v2_t, cpu_env);
20494         gen_store_gpr(v1_t, ret);
20495         break;
20496     case NM_APPEND:
20497         check_dsp_r2(ctx);
20498         gen_load_gpr(t0, rs);
20499         if (rd != 0) {
20500             tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd);
20501         }
20502         tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20503         break;
20504     case NM_MODSUB:
20505         check_dsp(ctx);
20506         gen_helper_modsub(v1_t, v1_t, v2_t);
20507         gen_store_gpr(v1_t, ret);
20508         break;
20509     case NM_SHRAV_R_W:
20510         check_dsp(ctx);
20511         gen_helper_shra_r_w(v1_t, v1_t, v2_t);
20512         gen_store_gpr(v1_t, ret);
20513         break;
20514     case NM_SHRLV_PH:
20515         check_dsp_r2(ctx);
20516         gen_helper_shrl_ph(v1_t, v1_t, v2_t);
20517         gen_store_gpr(v1_t, ret);
20518         break;
20519     case NM_SHRLV_QB:
20520         check_dsp(ctx);
20521         gen_helper_shrl_qb(v1_t, v1_t, v2_t);
20522         gen_store_gpr(v1_t, ret);
20523         break;
20524     case NM_SHLLV_QB:
20525         check_dsp(ctx);
20526         gen_helper_shll_qb(v1_t, v1_t, v2_t, cpu_env);
20527         gen_store_gpr(v1_t, ret);
20528         break;
20529     case NM_SHLLV_S_W:
20530         check_dsp(ctx);
20531         gen_helper_shll_s_w(v1_t, v1_t, v2_t, cpu_env);
20532         gen_store_gpr(v1_t, ret);
20533         break;
20534     case NM_SHILO:
20535         check_dsp(ctx);
20536         {
20537             TCGv tv0 = tcg_temp_new();
20538             TCGv tv1 = tcg_temp_new();
20539             int16_t imm = extract32(ctx->opcode, 16, 7);
20540
20541             tcg_gen_movi_tl(tv0, rd >> 3);
20542             tcg_gen_movi_tl(tv1, imm);
20543             gen_helper_shilo(tv0, tv1, cpu_env);
20544         }
20545         break;
20546     case NM_MULEQ_S_W_PHL:
20547         check_dsp(ctx);
20548         gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, cpu_env);
20549         gen_store_gpr(v1_t, ret);
20550         break;
20551     case NM_MULEQ_S_W_PHR:
20552         check_dsp(ctx);
20553         gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, cpu_env);
20554         gen_store_gpr(v1_t, ret);
20555         break;
20556     case NM_MUL_S_PH:
20557         check_dsp_r2(ctx);
20558         switch (extract32(ctx->opcode, 10, 1)) {
20559         case 0:
20560             /* MUL_PH */
20561             gen_helper_mul_ph(v1_t, v1_t, v2_t, cpu_env);
20562             gen_store_gpr(v1_t, ret);
20563             break;
20564         case 1:
20565             /* MUL_S_PH */
20566             gen_helper_mul_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_PRECR_QB_PH:
20572         check_dsp_r2(ctx);
20573         gen_helper_precr_qb_ph(v1_t, v1_t, v2_t);
20574         gen_store_gpr(v1_t, ret);
20575         break;
20576     case NM_PRECRQ_QB_PH:
20577         check_dsp(ctx);
20578         gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t);
20579         gen_store_gpr(v1_t, ret);
20580         break;
20581     case NM_PRECRQ_PH_W:
20582         check_dsp(ctx);
20583         gen_helper_precrq_ph_w(v1_t, v1_t, v2_t);
20584         gen_store_gpr(v1_t, ret);
20585         break;
20586     case NM_PRECRQ_RS_PH_W:
20587         check_dsp(ctx);
20588         gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, cpu_env);
20589         gen_store_gpr(v1_t, ret);
20590         break;
20591     case NM_PRECRQU_S_QB_PH:
20592         check_dsp(ctx);
20593         gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, cpu_env);
20594         gen_store_gpr(v1_t, ret);
20595         break;
20596     case NM_SHRA_R_W:
20597         check_dsp(ctx);
20598         tcg_gen_movi_tl(t0, rd);
20599         gen_helper_shra_r_w(v1_t, t0, v1_t);
20600         gen_store_gpr(v1_t, rt);
20601         break;
20602     case NM_SHRA_R_PH:
20603         check_dsp(ctx);
20604         tcg_gen_movi_tl(t0, rd >> 1);
20605         switch (extract32(ctx->opcode, 10, 1)) {
20606         case 0:
20607             /* SHRA_PH */
20608             gen_helper_shra_ph(v1_t, t0, v1_t);
20609             gen_store_gpr(v1_t, rt);
20610             break;
20611         case 1:
20612             /* SHRA_R_PH */
20613             gen_helper_shra_r_ph(v1_t, t0, v1_t);
20614             gen_store_gpr(v1_t, rt);
20615             break;
20616         }
20617         break;
20618     case NM_SHLL_S_PH:
20619         check_dsp(ctx);
20620         tcg_gen_movi_tl(t0, rd >> 1);
20621         switch (extract32(ctx->opcode, 10, 2)) {
20622         case 0:
20623             /* SHLL_PH */
20624             gen_helper_shll_ph(v1_t, t0, v1_t, cpu_env);
20625             gen_store_gpr(v1_t, rt);
20626             break;
20627         case 2:
20628             /* SHLL_S_PH */
20629             gen_helper_shll_s_ph(v1_t, t0, v1_t, cpu_env);
20630             gen_store_gpr(v1_t, rt);
20631             break;
20632         default:
20633             generate_exception_end(ctx, EXCP_RI);
20634             break;
20635         }
20636         break;
20637     case NM_SHLL_S_W:
20638         check_dsp(ctx);
20639         tcg_gen_movi_tl(t0, rd);
20640         gen_helper_shll_s_w(v1_t, t0, v1_t, cpu_env);
20641         gen_store_gpr(v1_t, rt);
20642         break;
20643     case NM_REPL_PH:
20644         check_dsp(ctx);
20645         {
20646             int16_t imm;
20647             imm = sextract32(ctx->opcode, 11, 11);
20648             imm = (int16_t)(imm << 6) >> 6;
20649             if (rt != 0) {
20650                 tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm));
20651             }
20652         }
20653         break;
20654     default:
20655         generate_exception_end(ctx, EXCP_RI);
20656         break;
20657     }
20658 }
20659
20660 static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
20661 {
20662     uint16_t insn;
20663     uint32_t op;
20664     int rt, rs, rd;
20665     int offset;
20666     int imm;
20667
20668     insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
20669     ctx->opcode = (ctx->opcode << 16) | insn;
20670
20671     rt = extract32(ctx->opcode, 21, 5);
20672     rs = extract32(ctx->opcode, 16, 5);
20673     rd = extract32(ctx->opcode, 11, 5);
20674
20675     op = extract32(ctx->opcode, 26, 6);
20676     switch (op) {
20677     case NM_P_ADDIU:
20678         if (rt == 0) {
20679             /* P.RI */
20680             switch (extract32(ctx->opcode, 19, 2)) {
20681             case NM_SIGRIE:
20682             default:
20683                 generate_exception_end(ctx, EXCP_RI);
20684                 break;
20685             case NM_P_SYSCALL:
20686                 if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) {
20687                     generate_exception_end(ctx, EXCP_SYSCALL);
20688                 } else {
20689                     generate_exception_end(ctx, EXCP_RI);
20690                 }
20691                 break;
20692             case NM_BREAK:
20693                 generate_exception_end(ctx, EXCP_BREAK);
20694                 break;
20695             case NM_SDBBP:
20696                 if (is_uhi(extract32(ctx->opcode, 0, 19))) {
20697                     gen_helper_do_semihosting(cpu_env);
20698                 } else {
20699                     if (ctx->hflags & MIPS_HFLAG_SBRI) {
20700                         generate_exception_end(ctx, EXCP_RI);
20701                     } else {
20702                         generate_exception_end(ctx, EXCP_DBp);
20703                     }
20704                 }
20705                 break;
20706             }
20707         } else {
20708             /* NM_ADDIU */
20709             imm = extract32(ctx->opcode, 0, 16);
20710             if (rs != 0) {
20711                 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm);
20712             } else {
20713                 tcg_gen_movi_tl(cpu_gpr[rt], imm);
20714             }
20715             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20716         }
20717         break;
20718     case NM_ADDIUPC:
20719         if (rt != 0) {
20720             offset = sextract32(ctx->opcode, 0, 1) << 21 |
20721                      extract32(ctx->opcode, 1, 20) << 1;
20722             target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset);
20723             tcg_gen_movi_tl(cpu_gpr[rt], addr);
20724         }
20725         break;
20726     case NM_POOL32A:
20727         switch (ctx->opcode & 0x07) {
20728         case NM_POOL32A0:
20729             gen_pool32a0_nanomips_insn(env, ctx);
20730             break;
20731         case NM_POOL32A5:
20732             {
20733                 int32_t op1 = extract32(ctx->opcode, 3, 7);
20734                 gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt);
20735             }
20736             break;
20737         case NM_POOL32A7:
20738             switch (extract32(ctx->opcode, 3, 3)) {
20739             case NM_P_LSX:
20740                 gen_p_lsx(ctx, rd, rs, rt);
20741                 break;
20742             case NM_LSA:
20743                 /* In nanoMIPS, the shift field directly encodes the shift
20744                  * amount, meaning that the supported shift values are in
20745                  * the range 0 to 3 (instead of 1 to 4 in MIPSR6). */
20746                 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
20747                         extract32(ctx->opcode, 9, 2) - 1);
20748                 break;
20749             case NM_EXTW:
20750                 gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5));
20751                 break;
20752             case NM_POOL32AXF:
20753                 gen_pool32axf_nanomips_insn(env, ctx);
20754                 break;
20755             default:
20756                 generate_exception_end(ctx, EXCP_RI);
20757                 break;
20758             }
20759             break;
20760         default:
20761             generate_exception_end(ctx, EXCP_RI);
20762             break;
20763         }
20764         break;
20765     case NM_P_GP_W:
20766         switch (ctx->opcode & 0x03) {
20767         case NM_ADDIUGP_W:
20768             if (rt != 0) {
20769                 offset = extract32(ctx->opcode, 0, 21);
20770                 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset);
20771             }
20772             break;
20773         case NM_LWGP:
20774             gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
20775             break;
20776         case NM_SWGP:
20777             gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
20778             break;
20779         default:
20780             generate_exception_end(ctx, EXCP_RI);
20781             break;
20782         }
20783         break;
20784     case NM_P48I:
20785         {
20786             insn = cpu_lduw_code(env, ctx->base.pc_next + 4);
20787             target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16;
20788             switch (extract32(ctx->opcode, 16, 5)) {
20789             case NM_LI48:
20790                 check_nms(ctx);
20791                 if (rt != 0) {
20792                     tcg_gen_movi_tl(cpu_gpr[rt], addr_off);
20793                 }
20794                 break;
20795             case NM_ADDIU48:
20796                 check_nms(ctx);
20797                 if (rt != 0) {
20798                     tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off);
20799                     tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20800                 }
20801                 break;
20802             case NM_ADDIUGP48:
20803                 check_nms(ctx);
20804                 if (rt != 0) {
20805                     gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_off);
20806                 }
20807                 break;
20808             case NM_ADDIUPC48:
20809                 check_nms(ctx);
20810                 if (rt != 0) {
20811                     target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20812                                                 addr_off);
20813
20814                     tcg_gen_movi_tl(cpu_gpr[rt], addr);
20815                 }
20816                 break;
20817             case NM_LWPC48:
20818                 check_nms(ctx);
20819                 if (rt != 0) {
20820                     TCGv t0;
20821                     t0 = tcg_temp_new();
20822
20823                     target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20824                                                 addr_off);
20825
20826                     tcg_gen_movi_tl(t0, addr);
20827                     tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_TESL);
20828                     tcg_temp_free(t0);
20829                 }
20830                 break;
20831             case NM_SWPC48:
20832                 check_nms(ctx);
20833                 {
20834                     TCGv t0, t1;
20835                     t0 = tcg_temp_new();
20836                     t1 = tcg_temp_new();
20837
20838                     target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20839                                                 addr_off);
20840
20841                     tcg_gen_movi_tl(t0, addr);
20842                     gen_load_gpr(t1, rt);
20843
20844                     tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
20845
20846                     tcg_temp_free(t0);
20847                     tcg_temp_free(t1);
20848                 }
20849                 break;
20850             default:
20851                 generate_exception_end(ctx, EXCP_RI);
20852                 break;
20853             }
20854             return 6;
20855         }
20856     case NM_P_U12:
20857         switch (extract32(ctx->opcode, 12, 4)) {
20858         case NM_ORI:
20859             gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12));
20860             break;
20861         case NM_XORI:
20862             gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12));
20863             break;
20864         case NM_ANDI:
20865             gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12));
20866             break;
20867         case NM_P_SR:
20868             switch (extract32(ctx->opcode, 20, 1)) {
20869             case NM_PP_SR:
20870                 switch (ctx->opcode & 3) {
20871                 case NM_SAVE:
20872                     gen_save(ctx, rt, extract32(ctx->opcode, 16, 4),
20873                              extract32(ctx->opcode, 2, 1),
20874                              extract32(ctx->opcode, 3, 9) << 3);
20875                     break;
20876                 case NM_RESTORE:
20877                 case NM_RESTORE_JRC:
20878                     gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4),
20879                                 extract32(ctx->opcode, 2, 1),
20880                                 extract32(ctx->opcode, 3, 9) << 3);
20881                     if ((ctx->opcode & 3) == NM_RESTORE_JRC) {
20882                         gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
20883                     }
20884                     break;
20885                 default:
20886                     generate_exception_end(ctx, EXCP_RI);
20887                     break;
20888                 }
20889                 break;
20890             case NM_P_SR_F:
20891                 generate_exception_end(ctx, EXCP_RI);
20892                 break;
20893             }
20894             break;
20895         case NM_SLTI:
20896             gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12));
20897             break;
20898         case NM_SLTIU:
20899             gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12));
20900             break;
20901         case NM_SEQI:
20902             {
20903                 TCGv t0 = tcg_temp_new();
20904
20905                 imm = extract32(ctx->opcode, 0, 12);
20906                 gen_load_gpr(t0, rs);
20907                 tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm);
20908                 gen_store_gpr(t0, rt);
20909
20910                 tcg_temp_free(t0);
20911             }
20912             break;
20913         case NM_ADDIUNEG:
20914             imm = (int16_t) extract32(ctx->opcode, 0, 12);
20915             gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm);
20916             break;
20917         case NM_P_SHIFT:
20918             {
20919                 int shift = extract32(ctx->opcode, 0, 5);
20920                 switch (extract32(ctx->opcode, 5, 4)) {
20921                 case NM_P_SLL:
20922                     if (rt == 0 && shift == 0) {
20923                         /* NOP */
20924                     } else if (rt == 0 && shift == 3) {
20925                         /* EHB - treat as NOP */
20926                     } else if (rt == 0 && shift == 5) {
20927                         /* PAUSE - treat as NOP */
20928                     } else if (rt == 0 && shift == 6) {
20929                         /* SYNC */
20930                         gen_sync(extract32(ctx->opcode, 16, 5));
20931                     } else {
20932                         /* SLL */
20933                         gen_shift_imm(ctx, OPC_SLL, rt, rs,
20934                                       extract32(ctx->opcode, 0, 5));
20935                     }
20936                     break;
20937                 case NM_SRL:
20938                     gen_shift_imm(ctx, OPC_SRL, rt, rs,
20939                                   extract32(ctx->opcode, 0, 5));
20940                     break;
20941                 case NM_SRA:
20942                     gen_shift_imm(ctx, OPC_SRA, rt, rs,
20943                                   extract32(ctx->opcode, 0, 5));
20944                     break;
20945                 case NM_ROTR:
20946                     gen_shift_imm(ctx, OPC_ROTR, rt, rs,
20947                                   extract32(ctx->opcode, 0, 5));
20948                     break;
20949                 }
20950             }
20951             break;
20952         case NM_P_ROTX:
20953             check_nms(ctx);
20954             if (rt != 0) {
20955                 TCGv t0 = tcg_temp_new();
20956                 TCGv_i32 shift = tcg_const_i32(extract32(ctx->opcode, 0, 5));
20957                 TCGv_i32 shiftx = tcg_const_i32(extract32(ctx->opcode, 7, 4)
20958                                                 << 1);
20959                 TCGv_i32 stripe = tcg_const_i32(extract32(ctx->opcode, 6, 1));
20960
20961                 gen_load_gpr(t0, rs);
20962                 gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe);
20963                 tcg_temp_free(t0);
20964
20965                 tcg_temp_free_i32(shift);
20966                 tcg_temp_free_i32(shiftx);
20967                 tcg_temp_free_i32(stripe);
20968             }
20969             break;
20970         case NM_P_INS:
20971             switch (((ctx->opcode >> 10) & 2) |
20972                     (extract32(ctx->opcode, 5, 1))) {
20973             case NM_INS:
20974                 check_nms(ctx);
20975                 gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5),
20976                            extract32(ctx->opcode, 6, 5));
20977                 break;
20978             default:
20979                 generate_exception_end(ctx, EXCP_RI);
20980                 break;
20981             }
20982             break;
20983         case NM_P_EXT:
20984             switch (((ctx->opcode >> 10) & 2) |
20985                     (extract32(ctx->opcode, 5, 1))) {
20986             case NM_EXT:
20987                 check_nms(ctx);
20988                 gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5),
20989                            extract32(ctx->opcode, 6, 5));
20990                 break;
20991             default:
20992                 generate_exception_end(ctx, EXCP_RI);
20993                 break;
20994             }
20995             break;
20996         default:
20997             generate_exception_end(ctx, EXCP_RI);
20998             break;
20999         }
21000         break;
21001     case NM_POOL32F:
21002         gen_pool32f_nanomips_insn(ctx);
21003         break;
21004     case NM_POOL32S:
21005         break;
21006     case NM_P_LUI:
21007         switch (extract32(ctx->opcode, 1, 1)) {
21008         case NM_LUI:
21009             if (rt != 0) {
21010                 tcg_gen_movi_tl(cpu_gpr[rt],
21011                                 sextract32(ctx->opcode, 0, 1) << 31 |
21012                                 extract32(ctx->opcode, 2, 10) << 21 |
21013                                 extract32(ctx->opcode, 12, 9) << 12);
21014             }
21015             break;
21016         case NM_ALUIPC:
21017             if (rt != 0) {
21018                 offset = sextract32(ctx->opcode, 0, 1) << 31 |
21019                          extract32(ctx->opcode, 2, 10) << 21 |
21020                          extract32(ctx->opcode, 12, 9) << 12;
21021                 target_long addr;
21022                 addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset);
21023                 tcg_gen_movi_tl(cpu_gpr[rt], addr);
21024             }
21025             break;
21026         }
21027         break;
21028     case NM_P_GP_BH:
21029         {
21030             uint32_t u = extract32(ctx->opcode, 0, 18);
21031
21032             switch (extract32(ctx->opcode, 18, 3)) {
21033             case NM_LBGP:
21034                 gen_ld(ctx, OPC_LB, rt, 28, u);
21035                 break;
21036             case NM_SBGP:
21037                 gen_st(ctx, OPC_SB, rt, 28, u);
21038                 break;
21039             case NM_LBUGP:
21040                 gen_ld(ctx, OPC_LBU, rt, 28, u);
21041                 break;
21042             case NM_ADDIUGP_B:
21043                 if (rt != 0) {
21044                     gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u);
21045                 }
21046                 break;
21047             case NM_P_GP_LH:
21048                 u &= ~1;
21049                 switch (ctx->opcode & 1) {
21050                 case NM_LHGP:
21051                     gen_ld(ctx, OPC_LH, rt, 28, u);
21052                     break;
21053                 case NM_LHUGP:
21054                     gen_ld(ctx, OPC_LHU, rt, 28, u);
21055                     break;
21056                 }
21057                 break;
21058             case NM_P_GP_SH:
21059                 u &= ~1;
21060                 switch (ctx->opcode & 1) {
21061                 case NM_SHGP:
21062                     gen_st(ctx, OPC_SH, rt, 28, u);
21063                     break;
21064                 default:
21065                     generate_exception_end(ctx, EXCP_RI);
21066                     break;
21067                 }
21068                 break;
21069             case NM_P_GP_CP1:
21070                 u &= ~0x3;
21071                 switch (ctx->opcode & 0x3) {
21072                 case NM_LWC1GP:
21073                     gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u);
21074                     break;
21075                 case NM_LDC1GP:
21076                     gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u);
21077                     break;
21078                 case NM_SWC1GP:
21079                     gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u);
21080                     break;
21081                 case NM_SDC1GP:
21082                     gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u);
21083                     break;
21084                 }
21085                 break;
21086             default:
21087                 generate_exception_end(ctx, EXCP_RI);
21088                 break;
21089             }
21090         }
21091         break;
21092     case NM_P_LS_U12:
21093         {
21094             uint32_t u = extract32(ctx->opcode, 0, 12);
21095
21096             switch (extract32(ctx->opcode, 12, 4)) {
21097             case NM_P_PREFU12:
21098                 if (rt == 31) {
21099                     /* SYNCI */
21100                     /* Break the TB to be able to sync copied instructions
21101                        immediately */
21102                     ctx->base.is_jmp = DISAS_STOP;
21103                 } else {
21104                     /* PREF */
21105                     /* Treat as NOP. */
21106                 }
21107                 break;
21108             case NM_LB:
21109                 gen_ld(ctx, OPC_LB, rt, rs, u);
21110                 break;
21111             case NM_LH:
21112                 gen_ld(ctx, OPC_LH, rt, rs, u);
21113                 break;
21114             case NM_LW:
21115                 gen_ld(ctx, OPC_LW, rt, rs, u);
21116                 break;
21117             case NM_LBU:
21118                 gen_ld(ctx, OPC_LBU, rt, rs, u);
21119                 break;
21120             case NM_LHU:
21121                 gen_ld(ctx, OPC_LHU, rt, rs, u);
21122                 break;
21123             case NM_SB:
21124                 gen_st(ctx, OPC_SB, rt, rs, u);
21125                 break;
21126             case NM_SH:
21127                 gen_st(ctx, OPC_SH, rt, rs, u);
21128                 break;
21129             case NM_SW:
21130                 gen_st(ctx, OPC_SW, rt, rs, u);
21131                 break;
21132             case NM_LWC1:
21133                 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u);
21134                 break;
21135             case NM_LDC1:
21136                 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u);
21137                 break;
21138             case NM_SWC1:
21139                 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u);
21140                 break;
21141             case NM_SDC1:
21142                 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u);
21143                 break;
21144             default:
21145                 generate_exception_end(ctx, EXCP_RI);
21146                 break;
21147             }
21148         }
21149         break;
21150     case NM_P_LS_S9:
21151         {
21152             int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) |
21153                         extract32(ctx->opcode, 0, 8);
21154
21155             switch (extract32(ctx->opcode, 8, 3)) {
21156             case NM_P_LS_S0:
21157                 switch (extract32(ctx->opcode, 11, 4)) {
21158                 case NM_LBS9:
21159                     gen_ld(ctx, OPC_LB, rt, rs, s);
21160                     break;
21161                 case NM_LHS9:
21162                     gen_ld(ctx, OPC_LH, rt, rs, s);
21163                     break;
21164                 case NM_LWS9:
21165                     gen_ld(ctx, OPC_LW, rt, rs, s);
21166                     break;
21167                 case NM_LBUS9:
21168                     gen_ld(ctx, OPC_LBU, rt, rs, s);
21169                     break;
21170                 case NM_LHUS9:
21171                     gen_ld(ctx, OPC_LHU, rt, rs, s);
21172                     break;
21173                 case NM_SBS9:
21174                     gen_st(ctx, OPC_SB, rt, rs, s);
21175                     break;
21176                 case NM_SHS9:
21177                     gen_st(ctx, OPC_SH, rt, rs, s);
21178                     break;
21179                 case NM_SWS9:
21180                     gen_st(ctx, OPC_SW, rt, rs, s);
21181                     break;
21182                 case NM_LWC1S9:
21183                     gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s);
21184                     break;
21185                 case NM_LDC1S9:
21186                     gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s);
21187                     break;
21188                 case NM_SWC1S9:
21189                     gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s);
21190                     break;
21191                 case NM_SDC1S9:
21192                     gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s);
21193                     break;
21194                 case NM_P_PREFS9:
21195                     if (rt == 31) {
21196                         /* SYNCI */
21197                         /* Break the TB to be able to sync copied instructions
21198                            immediately */
21199                         ctx->base.is_jmp = DISAS_STOP;
21200                     } else {
21201                         /* PREF */
21202                         /* Treat as NOP. */
21203                     }
21204                     break;
21205                 default:
21206                     generate_exception_end(ctx, EXCP_RI);
21207                     break;
21208                 }
21209                 break;
21210             case NM_P_LS_S1:
21211                 switch (extract32(ctx->opcode, 11, 4)) {
21212                 case NM_UALH:
21213                 case NM_UASH:
21214                     check_nms(ctx);
21215                     {
21216                         TCGv t0 = tcg_temp_new();
21217                         TCGv t1 = tcg_temp_new();
21218
21219                         gen_base_offset_addr(ctx, t0, rs, s);
21220
21221                         switch (extract32(ctx->opcode, 11, 4)) {
21222                         case NM_UALH:
21223                             tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
21224                                                MO_UNALN);
21225                             gen_store_gpr(t0, rt);
21226                             break;
21227                         case NM_UASH:
21228                             gen_load_gpr(t1, rt);
21229                             tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
21230                                                MO_UNALN);
21231                             break;
21232                         }
21233                         tcg_temp_free(t0);
21234                         tcg_temp_free(t1);
21235                     }
21236                     break;
21237                 case NM_P_LL:
21238                     switch (ctx->opcode & 0x03) {
21239                     case NM_LL:
21240                         gen_ld(ctx, OPC_LL, rt, rs, s);
21241                         break;
21242                     case NM_LLWP:
21243                         check_xnp(ctx);
21244                         gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21245                         break;
21246                     }
21247                     break;
21248                 case NM_P_SC:
21249                     switch (ctx->opcode & 0x03) {
21250                     case NM_SC:
21251                         gen_st_cond(ctx, OPC_SC, rt, rs, s);
21252                         break;
21253                     case NM_SCWP:
21254                         check_xnp(ctx);
21255                         gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21256                         break;
21257                     }
21258                     break;
21259                 case NM_CACHE:
21260                     check_cp0_enabled(ctx);
21261                     if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
21262                         gen_cache_operation(ctx, rt, rs, s);
21263                     }
21264                     break;
21265                 }
21266                 break;
21267             case NM_P_LS_E0:
21268                 switch (extract32(ctx->opcode, 11, 4)) {
21269                 case NM_LBE:
21270                     check_eva(ctx);
21271                     check_cp0_enabled(ctx);
21272                     gen_ld(ctx, OPC_LBE, rt, rs, s);
21273                     break;
21274                 case NM_SBE:
21275                     check_eva(ctx);
21276                     check_cp0_enabled(ctx);
21277                     gen_st(ctx, OPC_SBE, rt, rs, s);
21278                     break;
21279                 case NM_LBUE:
21280                     check_eva(ctx);
21281                     check_cp0_enabled(ctx);
21282                     gen_ld(ctx, OPC_LBUE, rt, rs, s);
21283                     break;
21284                 case NM_P_PREFE:
21285                     if (rt == 31) {
21286                         /* case NM_SYNCIE */
21287                         check_eva(ctx);
21288                         check_cp0_enabled(ctx);
21289                         /* Break the TB to be able to sync copied instructions
21290                            immediately */
21291                         ctx->base.is_jmp = DISAS_STOP;
21292                     } else {
21293                         /* case NM_PREFE */
21294                         check_eva(ctx);
21295                         check_cp0_enabled(ctx);
21296                         /* Treat as NOP. */
21297                     }
21298                     break;
21299                 case NM_LHE:
21300                     check_eva(ctx);
21301                     check_cp0_enabled(ctx);
21302                     gen_ld(ctx, OPC_LHE, rt, rs, s);
21303                     break;
21304                 case NM_SHE:
21305                     check_eva(ctx);
21306                     check_cp0_enabled(ctx);
21307                     gen_st(ctx, OPC_SHE, rt, rs, s);
21308                     break;
21309                 case NM_LHUE:
21310                     check_eva(ctx);
21311                     check_cp0_enabled(ctx);
21312                     gen_ld(ctx, OPC_LHUE, rt, rs, s);
21313                     break;
21314                 case NM_CACHEE:
21315                     check_nms_dl_il_sl_tl_l2c(ctx);
21316                     gen_cache_operation(ctx, rt, rs, s);
21317                     break;
21318                 case NM_LWE:
21319                     check_eva(ctx);
21320                     check_cp0_enabled(ctx);
21321                     gen_ld(ctx, OPC_LWE, rt, rs, s);
21322                     break;
21323                 case NM_SWE:
21324                     check_eva(ctx);
21325                     check_cp0_enabled(ctx);
21326                     gen_st(ctx, OPC_SWE, rt, rs, s);
21327                     break;
21328                 case NM_P_LLE:
21329                     switch (extract32(ctx->opcode, 2, 2)) {
21330                     case NM_LLE:
21331                         check_xnp(ctx);
21332                         check_eva(ctx);
21333                         check_cp0_enabled(ctx);
21334                         gen_ld(ctx, OPC_LLE, rt, rs, s);
21335                         break;
21336                     case NM_LLWPE:
21337                         check_xnp(ctx);
21338                         check_eva(ctx);
21339                         check_cp0_enabled(ctx);
21340                         gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21341                         break;
21342                     default:
21343                         generate_exception_end(ctx, EXCP_RI);
21344                         break;
21345                     }
21346                     break;
21347                 case NM_P_SCE:
21348                     switch (extract32(ctx->opcode, 2, 2)) {
21349                     case NM_SCE:
21350                         check_xnp(ctx);
21351                         check_eva(ctx);
21352                         check_cp0_enabled(ctx);
21353                         gen_st_cond(ctx, OPC_SCE, rt, rs, s);
21354                         break;
21355                     case NM_SCWPE:
21356                         check_xnp(ctx);
21357                         check_eva(ctx);
21358                         check_cp0_enabled(ctx);
21359                         gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21360                         break;
21361                     default:
21362                         generate_exception_end(ctx, EXCP_RI);
21363                         break;
21364                     }
21365                     break;
21366                 }
21367                 break;
21368             case NM_P_LS_WM:
21369             case NM_P_LS_UAWM:
21370                 check_nms(ctx);
21371                 {
21372                     int count = extract32(ctx->opcode, 12, 3);
21373                     int counter = 0;
21374
21375                     offset = sextract32(ctx->opcode, 15, 1) << 8 |
21376                              extract32(ctx->opcode, 0, 8);
21377                     TCGv va = tcg_temp_new();
21378                     TCGv t1 = tcg_temp_new();
21379                     TCGMemOp memop = (extract32(ctx->opcode, 8, 3)) ==
21380                                       NM_P_LS_UAWM ? MO_UNALN : 0;
21381
21382                     count = (count == 0) ? 8 : count;
21383                     while (counter != count) {
21384                         int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10);
21385                         int this_offset = offset + (counter << 2);
21386
21387                         gen_base_offset_addr(ctx, va, rs, this_offset);
21388
21389                         switch (extract32(ctx->opcode, 11, 1)) {
21390                         case NM_LWM:
21391                             tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx,
21392                                                memop | MO_TESL);
21393                             gen_store_gpr(t1, this_rt);
21394                             if ((this_rt == rs) &&
21395                                 (counter != (count - 1))) {
21396                                 /* UNPREDICTABLE */
21397                             }
21398                             break;
21399                         case NM_SWM:
21400                             this_rt = (rt == 0) ? 0 : this_rt;
21401                             gen_load_gpr(t1, this_rt);
21402                             tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx,
21403                                                memop | MO_TEUL);
21404                             break;
21405                         }
21406                         counter++;
21407                     }
21408                     tcg_temp_free(va);
21409                     tcg_temp_free(t1);
21410                 }
21411                 break;
21412             default:
21413                 generate_exception_end(ctx, EXCP_RI);
21414                 break;
21415             }
21416         }
21417         break;
21418     case NM_MOVE_BALC:
21419         check_nms(ctx);
21420         {
21421             TCGv t0 = tcg_temp_new();
21422             int32_t s = sextract32(ctx->opcode, 0, 1) << 21 |
21423                         extract32(ctx->opcode, 1, 20) << 1;
21424             rd = (extract32(ctx->opcode, 24, 1)) == 0 ? 4 : 5;
21425             rt = decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3 |
21426                             extract32(ctx->opcode, 21, 3));
21427             gen_load_gpr(t0, rt);
21428             tcg_gen_mov_tl(cpu_gpr[rd], t0);
21429             gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21430             tcg_temp_free(t0);
21431         }
21432         break;
21433     case NM_P_BAL:
21434         {
21435             int32_t s = sextract32(ctx->opcode, 0, 1) << 25 |
21436                         extract32(ctx->opcode, 1, 24) << 1;
21437
21438             if ((extract32(ctx->opcode, 25, 1)) == 0) {
21439                 /* BC */
21440                 gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s);
21441             } else {
21442                 /* BALC */
21443                 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21444             }
21445         }
21446         break;
21447     case NM_P_J:
21448         switch (extract32(ctx->opcode, 12, 4)) {
21449         case NM_JALRC:
21450         case NM_JALRC_HB:
21451             gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0);
21452             break;
21453         case NM_P_BALRSC:
21454             gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt);
21455             break;
21456         default:
21457             generate_exception_end(ctx, EXCP_RI);
21458             break;
21459         }
21460         break;
21461     case NM_P_BR1:
21462         {
21463             int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21464                         extract32(ctx->opcode, 1, 13) << 1;
21465             switch (extract32(ctx->opcode, 14, 2)) {
21466             case NM_BEQC:
21467                 check_nms(ctx);
21468                 gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s);
21469                 break;
21470             case NM_P_BR3A:
21471                 s = sextract32(ctx->opcode, 0, 1) << 14 |
21472                     extract32(ctx->opcode, 1, 13) << 1;
21473                 check_cp1_enabled(ctx);
21474                 switch (extract32(ctx->opcode, 16, 5)) {
21475                 case NM_BC1EQZC:
21476                     gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s);
21477                     break;
21478                 case NM_BC1NEZC:
21479                     gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s);
21480                     break;
21481                 case NM_BPOSGE32C:
21482                     check_dsp_r3(ctx);
21483                     {
21484                         int32_t imm = extract32(ctx->opcode, 1, 13) |
21485                                       extract32(ctx->opcode, 0, 1) << 13;
21486
21487                         gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2,
21488                                               imm);
21489                     }
21490                     break;
21491                 default:
21492                     generate_exception_end(ctx, EXCP_RI);
21493                     break;
21494                 }
21495                 break;
21496             case NM_BGEC:
21497                 if (rs == rt) {
21498                     gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s);
21499                 } else {
21500                     gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s);
21501                 }
21502                 break;
21503             case NM_BGEUC:
21504                 if (rs == rt || rt == 0) {
21505                     gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s);
21506                 } else if (rs == 0) {
21507                     gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s);
21508                 } else {
21509                     gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, s);
21510                 }
21511                 break;
21512             }
21513         }
21514         break;
21515     case NM_P_BR2:
21516         {
21517             int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21518                         extract32(ctx->opcode, 1, 13) << 1;
21519             switch (extract32(ctx->opcode, 14, 2)) {
21520             case NM_BNEC:
21521                 check_nms(ctx);
21522                 gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s);
21523                 break;
21524             case NM_BLTC:
21525                 if (rs != 0 && rt != 0 && rs == rt) {
21526                     /* NOP */
21527                     ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21528                 } else {
21529                     gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s);
21530                 }
21531                 break;
21532             case NM_BLTUC:
21533                 if (rs == 0 || rs == rt) {
21534                     /* NOP */
21535                     ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21536                 } else {
21537                     gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, s);
21538                 }
21539                 break;
21540             default:
21541                 generate_exception_end(ctx, EXCP_RI);
21542                 break;
21543             }
21544         }
21545         break;
21546     case NM_P_BRI:
21547         {
21548             int32_t s = sextract32(ctx->opcode, 0, 1) << 11 |
21549                         extract32(ctx->opcode, 1, 10) << 1;
21550             uint32_t u = extract32(ctx->opcode, 11, 7);
21551
21552             gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3),
21553                                    rt, u, s);
21554         }
21555         break;
21556     default:
21557         generate_exception_end(ctx, EXCP_RI);
21558         break;
21559     }
21560     return 4;
21561 }
21562
21563 static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
21564 {
21565     uint32_t op;
21566     int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
21567     int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
21568     int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS1(ctx->opcode));
21569     int offset;
21570     int imm;
21571
21572     /* make sure instructions are on a halfword boundary */
21573     if (ctx->base.pc_next & 0x1) {
21574         TCGv tmp = tcg_const_tl(ctx->base.pc_next);
21575         tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
21576         tcg_temp_free(tmp);
21577         generate_exception_end(ctx, EXCP_AdEL);
21578         return 2;
21579     }
21580
21581     op = extract32(ctx->opcode, 10, 6);
21582     switch (op) {
21583     case NM_P16_MV:
21584         rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21585         if (rt != 0) {
21586             /* MOVE */
21587             rs = NANOMIPS_EXTRACT_RS5(ctx->opcode);
21588             gen_arith(ctx, OPC_ADDU, rt, rs, 0);
21589         } else {
21590             /* P16.RI */
21591             switch (extract32(ctx->opcode, 3, 2)) {
21592             case NM_P16_SYSCALL:
21593                 if (extract32(ctx->opcode, 2, 1) == 0) {
21594                     generate_exception_end(ctx, EXCP_SYSCALL);
21595                 } else {
21596                     generate_exception_end(ctx, EXCP_RI);
21597                 }
21598                 break;
21599             case NM_BREAK16:
21600                 generate_exception_end(ctx, EXCP_BREAK);
21601                 break;
21602             case NM_SDBBP16:
21603                 if (is_uhi(extract32(ctx->opcode, 0, 3))) {
21604                     gen_helper_do_semihosting(cpu_env);
21605                 } else {
21606                     if (ctx->hflags & MIPS_HFLAG_SBRI) {
21607                         generate_exception_end(ctx, EXCP_RI);
21608                     } else {
21609                         generate_exception_end(ctx, EXCP_DBp);
21610                     }
21611                 }
21612                 break;
21613             default:
21614                 generate_exception_end(ctx, EXCP_RI);
21615                 break;
21616             }
21617         }
21618         break;
21619     case NM_P16_SHIFT:
21620         {
21621             int shift = extract32(ctx->opcode, 0, 3);
21622             uint32_t opc = 0;
21623             shift = (shift == 0) ? 8 : shift;
21624
21625             switch (extract32(ctx->opcode, 3, 1)) {
21626             case NM_SLL16:
21627                 opc = OPC_SLL;
21628                 break;
21629             case NM_SRL16:
21630                 opc = OPC_SRL;
21631                 break;
21632             }
21633             gen_shift_imm(ctx, opc, rt, rs, shift);
21634         }
21635         break;
21636     case NM_P16C:
21637         switch (ctx->opcode & 1) {
21638         case NM_POOL16C_0:
21639             gen_pool16c_nanomips_insn(ctx);
21640             break;
21641         case NM_LWXS16:
21642             gen_ldxs(ctx, rt, rs, rd);
21643             break;
21644         }
21645         break;
21646     case NM_P16_A1:
21647         switch (extract32(ctx->opcode, 6, 1)) {
21648         case NM_ADDIUR1SP:
21649             imm = extract32(ctx->opcode, 0, 6) << 2;
21650             gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm);
21651             break;
21652         default:
21653             generate_exception_end(ctx, EXCP_RI);
21654             break;
21655         }
21656         break;
21657     case NM_P16_A2:
21658         switch (extract32(ctx->opcode, 3, 1)) {
21659         case NM_ADDIUR2:
21660             imm = extract32(ctx->opcode, 0, 3) << 2;
21661             gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm);
21662             break;
21663         case NM_P_ADDIURS5:
21664             rt = extract32(ctx->opcode, 5, 5);
21665             if (rt != 0) {
21666                 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
21667                 imm = (sextract32(ctx->opcode, 4, 1) << 3) |
21668                       (extract32(ctx->opcode, 0, 3));
21669                 gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm);
21670             }
21671             break;
21672         }
21673         break;
21674     case NM_P16_ADDU:
21675         switch (ctx->opcode & 0x1) {
21676         case NM_ADDU16:
21677             gen_arith(ctx, OPC_ADDU, rd, rs, rt);
21678             break;
21679         case NM_SUBU16:
21680             gen_arith(ctx, OPC_SUBU, rd, rs, rt);
21681             break;
21682         }
21683         break;
21684     case NM_P16_4X4:
21685         rt = (extract32(ctx->opcode, 9, 1) << 3) |
21686               extract32(ctx->opcode, 5, 3);
21687         rs = (extract32(ctx->opcode, 4, 1) << 3) |
21688               extract32(ctx->opcode, 0, 3);
21689         rt = decode_gpr_gpr4(rt);
21690         rs = decode_gpr_gpr4(rs);
21691         switch ((extract32(ctx->opcode, 7, 2) & 0x2) |
21692                 (extract32(ctx->opcode, 3, 1))) {
21693         case NM_ADDU4X4:
21694             check_nms(ctx);
21695             gen_arith(ctx, OPC_ADDU, rt, rs, rt);
21696             break;
21697         case NM_MUL4X4:
21698             check_nms(ctx);
21699             gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt);
21700             break;
21701         default:
21702             generate_exception_end(ctx, EXCP_RI);
21703             break;
21704         }
21705         break;
21706     case NM_LI16:
21707         {
21708             int imm = extract32(ctx->opcode, 0, 7);
21709             imm = (imm == 0x7f ? -1 : imm);
21710             if (rt != 0) {
21711                 tcg_gen_movi_tl(cpu_gpr[rt], imm);
21712             }
21713         }
21714         break;
21715     case NM_ANDI16:
21716         {
21717             uint32_t u = extract32(ctx->opcode, 0, 4);
21718             u = (u == 12) ? 0xff :
21719                 (u == 13) ? 0xffff : u;
21720             gen_logic_imm(ctx, OPC_ANDI, rt, rs, u);
21721         }
21722         break;
21723     case NM_P16_LB:
21724         offset = extract32(ctx->opcode, 0, 2);
21725         switch (extract32(ctx->opcode, 2, 2)) {
21726         case NM_LB16:
21727             gen_ld(ctx, OPC_LB, rt, rs, offset);
21728             break;
21729         case NM_SB16:
21730             rt = decode_gpr_gpr3_src_store(
21731                      NANOMIPS_EXTRACT_RD(ctx->opcode));
21732             gen_st(ctx, OPC_SB, rt, rs, offset);
21733             break;
21734         case NM_LBU16:
21735             gen_ld(ctx, OPC_LBU, rt, rs, offset);
21736             break;
21737         default:
21738             generate_exception_end(ctx, EXCP_RI);
21739             break;
21740         }
21741         break;
21742     case NM_P16_LH:
21743         offset = extract32(ctx->opcode, 1, 2) << 1;
21744         switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) {
21745         case NM_LH16:
21746             gen_ld(ctx, OPC_LH, rt, rs, offset);
21747             break;
21748         case NM_SH16:
21749             rt = decode_gpr_gpr3_src_store(
21750                      NANOMIPS_EXTRACT_RD(ctx->opcode));
21751             gen_st(ctx, OPC_SH, rt, rs, offset);
21752             break;
21753         case NM_LHU16:
21754             gen_ld(ctx, OPC_LHU, rt, rs, offset);
21755             break;
21756         default:
21757             generate_exception_end(ctx, EXCP_RI);
21758             break;
21759         }
21760         break;
21761     case NM_LW16:
21762         offset = extract32(ctx->opcode, 0, 4) << 2;
21763         gen_ld(ctx, OPC_LW, rt, rs, offset);
21764         break;
21765     case NM_LWSP16:
21766         rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21767         offset = extract32(ctx->opcode, 0, 5) << 2;
21768         gen_ld(ctx, OPC_LW, rt, 29, offset);
21769         break;
21770     case NM_LW4X4:
21771         check_nms(ctx);
21772         rt = (extract32(ctx->opcode, 9, 1) << 3) |
21773              extract32(ctx->opcode, 5, 3);
21774         rs = (extract32(ctx->opcode, 4, 1) << 3) |
21775              extract32(ctx->opcode, 0, 3);
21776         offset = (extract32(ctx->opcode, 3, 1) << 3) |
21777                  (extract32(ctx->opcode, 8, 1) << 2);
21778         rt = decode_gpr_gpr4(rt);
21779         rs = decode_gpr_gpr4(rs);
21780         gen_ld(ctx, OPC_LW, rt, rs, offset);
21781         break;
21782     case NM_SW4X4:
21783         check_nms(ctx);
21784         rt = (extract32(ctx->opcode, 9, 1) << 3) |
21785              extract32(ctx->opcode, 5, 3);
21786         rs = (extract32(ctx->opcode, 4, 1) << 3) |
21787              extract32(ctx->opcode, 0, 3);
21788         offset = (extract32(ctx->opcode, 3, 1) << 3) |
21789                  (extract32(ctx->opcode, 8, 1) << 2);
21790         rt = decode_gpr_gpr4_zero(rt);
21791         rs = decode_gpr_gpr4(rs);
21792         gen_st(ctx, OPC_SW, rt, rs, offset);
21793         break;
21794     case NM_LWGP16:
21795         offset = extract32(ctx->opcode, 0, 7) << 2;
21796         gen_ld(ctx, OPC_LW, rt, 28, offset);
21797         break;
21798     case NM_SWSP16:
21799         rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21800         offset = extract32(ctx->opcode, 0, 5) << 2;
21801         gen_st(ctx, OPC_SW, rt, 29, offset);
21802         break;
21803     case NM_SW16:
21804         rt = decode_gpr_gpr3_src_store(
21805                  NANOMIPS_EXTRACT_RD(ctx->opcode));
21806         rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
21807         offset = extract32(ctx->opcode, 0, 4) << 2;
21808         gen_st(ctx, OPC_SW, rt, rs, offset);
21809         break;
21810     case NM_SWGP16:
21811         rt = decode_gpr_gpr3_src_store(
21812                  NANOMIPS_EXTRACT_RD(ctx->opcode));
21813         offset = extract32(ctx->opcode, 0, 7) << 2;
21814         gen_st(ctx, OPC_SW, rt, 28, offset);
21815         break;
21816     case NM_BC16:
21817         gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0,
21818                            (sextract32(ctx->opcode, 0, 1) << 10) |
21819                            (extract32(ctx->opcode, 1, 9) << 1));
21820         break;
21821     case NM_BALC16:
21822         gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0,
21823                            (sextract32(ctx->opcode, 0, 1) << 10) |
21824                            (extract32(ctx->opcode, 1, 9) << 1));
21825         break;
21826     case NM_BEQZC16:
21827         gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0,
21828                            (sextract32(ctx->opcode, 0, 1) << 7) |
21829                            (extract32(ctx->opcode, 1, 6) << 1));
21830         break;
21831     case NM_BNEZC16:
21832         gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0,
21833                            (sextract32(ctx->opcode, 0, 1) << 7) |
21834                            (extract32(ctx->opcode, 1, 6) << 1));
21835         break;
21836     case NM_P16_BR:
21837         switch (ctx->opcode & 0xf) {
21838         case 0:
21839             /* P16.JRC */
21840             switch (extract32(ctx->opcode, 4, 1)) {
21841             case NM_JRC:
21842                 gen_compute_branch_nm(ctx, OPC_JR, 2,
21843                                    extract32(ctx->opcode, 5, 5), 0, 0);
21844                 break;
21845             case NM_JALRC16:
21846                 gen_compute_branch_nm(ctx, OPC_JALR, 2,
21847                                    extract32(ctx->opcode, 5, 5), 31, 0);
21848                 break;
21849             }
21850             break;
21851         default:
21852             {
21853                 /* P16.BRI */
21854                 uint32_t opc = extract32(ctx->opcode, 4, 3) <
21855                                extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE;
21856                 gen_compute_branch_nm(ctx, opc, 2, rs, rt,
21857                                    extract32(ctx->opcode, 0, 4) << 1);
21858             }
21859             break;
21860         }
21861         break;
21862     case NM_P16_SR:
21863         {
21864             int count = extract32(ctx->opcode, 0, 4);
21865             int u = extract32(ctx->opcode, 4, 4) << 4;
21866
21867             rt = 30 + extract32(ctx->opcode, 9, 1);
21868             switch (extract32(ctx->opcode, 8, 1)) {
21869             case NM_SAVE16:
21870                 gen_save(ctx, rt, count, 0, u);
21871                 break;
21872             case NM_RESTORE_JRC16:
21873                 gen_restore(ctx, rt, count, 0, u);
21874                 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
21875                 break;
21876             }
21877         }
21878         break;
21879     case NM_MOVEP:
21880     case NM_MOVEPREV:
21881         check_nms(ctx);
21882         {
21883             static const int gpr2reg1[] = {4, 5, 6, 7};
21884             static const int gpr2reg2[] = {5, 6, 7, 8};
21885             int re;
21886             int rd2 = extract32(ctx->opcode, 3, 1) << 1 |
21887                       extract32(ctx->opcode, 8, 1);
21888             int r1 = gpr2reg1[rd2];
21889             int r2 = gpr2reg2[rd2];
21890             int r3 = extract32(ctx->opcode, 4, 1) << 3 |
21891                      extract32(ctx->opcode, 0, 3);
21892             int r4 = extract32(ctx->opcode, 9, 1) << 3 |
21893                      extract32(ctx->opcode, 5, 3);
21894             TCGv t0 = tcg_temp_new();
21895             TCGv t1 = tcg_temp_new();
21896             if (op == NM_MOVEP) {
21897                 rd = r1;
21898                 re = r2;
21899                 rs = decode_gpr_gpr4_zero(r3);
21900                 rt = decode_gpr_gpr4_zero(r4);
21901             } else {
21902                 rd = decode_gpr_gpr4(r3);
21903                 re = decode_gpr_gpr4(r4);
21904                 rs = r1;
21905                 rt = r2;
21906             }
21907             gen_load_gpr(t0, rs);
21908             gen_load_gpr(t1, rt);
21909             tcg_gen_mov_tl(cpu_gpr[rd], t0);
21910             tcg_gen_mov_tl(cpu_gpr[re], t1);
21911             tcg_temp_free(t0);
21912             tcg_temp_free(t1);
21913         }
21914         break;
21915     default:
21916         return decode_nanomips_32_48_opc(env, ctx);
21917     }
21918
21919     return 2;
21920 }
21921
21922
21923 /* SmartMIPS extension to MIPS32 */
21924
21925 #if defined(TARGET_MIPS64)
21926
21927 /* MDMX extension to MIPS64 */
21928
21929 #endif
21930
21931 /* MIPSDSP functions. */
21932 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
21933                            int rd, int base, int offset)
21934 {
21935     TCGv t0;
21936
21937     check_dsp(ctx);
21938     t0 = tcg_temp_new();
21939
21940     if (base == 0) {
21941         gen_load_gpr(t0, offset);
21942     } else if (offset == 0) {
21943         gen_load_gpr(t0, base);
21944     } else {
21945         gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
21946     }
21947
21948     switch (opc) {
21949     case OPC_LBUX:
21950         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
21951         gen_store_gpr(t0, rd);
21952         break;
21953     case OPC_LHX:
21954         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
21955         gen_store_gpr(t0, rd);
21956         break;
21957     case OPC_LWX:
21958         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
21959         gen_store_gpr(t0, rd);
21960         break;
21961 #if defined(TARGET_MIPS64)
21962     case OPC_LDX:
21963         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
21964         gen_store_gpr(t0, rd);
21965         break;
21966 #endif
21967     }
21968     tcg_temp_free(t0);
21969 }
21970
21971 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
21972                               int ret, int v1, int v2)
21973 {
21974     TCGv v1_t;
21975     TCGv v2_t;
21976
21977     if (ret == 0) {
21978         /* Treat as NOP. */
21979         return;
21980     }
21981
21982     v1_t = tcg_temp_new();
21983     v2_t = tcg_temp_new();
21984
21985     gen_load_gpr(v1_t, v1);
21986     gen_load_gpr(v2_t, v2);
21987
21988     switch (op1) {
21989     /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
21990     case OPC_MULT_G_2E:
21991         check_dsp_r2(ctx);
21992         switch (op2) {
21993         case OPC_ADDUH_QB:
21994             gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
21995             break;
21996         case OPC_ADDUH_R_QB:
21997             gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
21998             break;
21999         case OPC_ADDQH_PH:
22000             gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
22001             break;
22002         case OPC_ADDQH_R_PH:
22003             gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22004             break;
22005         case OPC_ADDQH_W:
22006             gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
22007             break;
22008         case OPC_ADDQH_R_W:
22009             gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22010             break;
22011         case OPC_SUBUH_QB:
22012             gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
22013             break;
22014         case OPC_SUBUH_R_QB:
22015             gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22016             break;
22017         case OPC_SUBQH_PH:
22018             gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
22019             break;
22020         case OPC_SUBQH_R_PH:
22021             gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22022             break;
22023         case OPC_SUBQH_W:
22024             gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
22025             break;
22026         case OPC_SUBQH_R_W:
22027             gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22028             break;
22029         }
22030         break;
22031     case OPC_ABSQ_S_PH_DSP:
22032         switch (op2) {
22033         case OPC_ABSQ_S_QB:
22034             check_dsp_r2(ctx);
22035             gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
22036             break;
22037         case OPC_ABSQ_S_PH:
22038             check_dsp(ctx);
22039             gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
22040             break;
22041         case OPC_ABSQ_S_W:
22042             check_dsp(ctx);
22043             gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
22044             break;
22045         case OPC_PRECEQ_W_PHL:
22046             check_dsp(ctx);
22047             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
22048             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22049             break;
22050         case OPC_PRECEQ_W_PHR:
22051             check_dsp(ctx);
22052             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
22053             tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
22054             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22055             break;
22056         case OPC_PRECEQU_PH_QBL:
22057             check_dsp(ctx);
22058             gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
22059             break;
22060         case OPC_PRECEQU_PH_QBR:
22061             check_dsp(ctx);
22062             gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
22063             break;
22064         case OPC_PRECEQU_PH_QBLA:
22065             check_dsp(ctx);
22066             gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
22067             break;
22068         case OPC_PRECEQU_PH_QBRA:
22069             check_dsp(ctx);
22070             gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
22071             break;
22072         case OPC_PRECEU_PH_QBL:
22073             check_dsp(ctx);
22074             gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
22075             break;
22076         case OPC_PRECEU_PH_QBR:
22077             check_dsp(ctx);
22078             gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
22079             break;
22080         case OPC_PRECEU_PH_QBLA:
22081             check_dsp(ctx);
22082             gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
22083             break;
22084         case OPC_PRECEU_PH_QBRA:
22085             check_dsp(ctx);
22086             gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
22087             break;
22088         }
22089         break;
22090     case OPC_ADDU_QB_DSP:
22091         switch (op2) {
22092         case OPC_ADDQ_PH:
22093             check_dsp(ctx);
22094             gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22095             break;
22096         case OPC_ADDQ_S_PH:
22097             check_dsp(ctx);
22098             gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22099             break;
22100         case OPC_ADDQ_S_W:
22101             check_dsp(ctx);
22102             gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22103             break;
22104         case OPC_ADDU_QB:
22105             check_dsp(ctx);
22106             gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22107             break;
22108         case OPC_ADDU_S_QB:
22109             check_dsp(ctx);
22110             gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22111             break;
22112         case OPC_ADDU_PH:
22113             check_dsp_r2(ctx);
22114             gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22115             break;
22116         case OPC_ADDU_S_PH:
22117             check_dsp_r2(ctx);
22118             gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22119             break;
22120         case OPC_SUBQ_PH:
22121             check_dsp(ctx);
22122             gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22123             break;
22124         case OPC_SUBQ_S_PH:
22125             check_dsp(ctx);
22126             gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22127             break;
22128         case OPC_SUBQ_S_W:
22129             check_dsp(ctx);
22130             gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22131             break;
22132         case OPC_SUBU_QB:
22133             check_dsp(ctx);
22134             gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22135             break;
22136         case OPC_SUBU_S_QB:
22137             check_dsp(ctx);
22138             gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22139             break;
22140         case OPC_SUBU_PH:
22141             check_dsp_r2(ctx);
22142             gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22143             break;
22144         case OPC_SUBU_S_PH:
22145             check_dsp_r2(ctx);
22146             gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22147             break;
22148         case OPC_ADDSC:
22149             check_dsp(ctx);
22150             gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22151             break;
22152         case OPC_ADDWC:
22153             check_dsp(ctx);
22154             gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22155             break;
22156         case OPC_MODSUB:
22157             check_dsp(ctx);
22158             gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
22159             break;
22160         case OPC_RADDU_W_QB:
22161             check_dsp(ctx);
22162             gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
22163             break;
22164         }
22165         break;
22166     case OPC_CMPU_EQ_QB_DSP:
22167         switch (op2) {
22168         case OPC_PRECR_QB_PH:
22169             check_dsp_r2(ctx);
22170             gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22171             break;
22172         case OPC_PRECRQ_QB_PH:
22173             check_dsp(ctx);
22174             gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22175             break;
22176         case OPC_PRECR_SRA_PH_W:
22177             check_dsp_r2(ctx);
22178             {
22179                 TCGv_i32 sa_t = tcg_const_i32(v2);
22180                 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
22181                                           cpu_gpr[ret]);
22182                 tcg_temp_free_i32(sa_t);
22183                 break;
22184             }
22185         case OPC_PRECR_SRA_R_PH_W:
22186             check_dsp_r2(ctx);
22187             {
22188                 TCGv_i32 sa_t = tcg_const_i32(v2);
22189                 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
22190                                             cpu_gpr[ret]);
22191                 tcg_temp_free_i32(sa_t);
22192                 break;
22193             }
22194         case OPC_PRECRQ_PH_W:
22195             check_dsp(ctx);
22196             gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
22197             break;
22198         case OPC_PRECRQ_RS_PH_W:
22199             check_dsp(ctx);
22200             gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22201             break;
22202         case OPC_PRECRQU_S_QB_PH:
22203             check_dsp(ctx);
22204             gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22205             break;
22206         }
22207         break;
22208 #ifdef TARGET_MIPS64
22209     case OPC_ABSQ_S_QH_DSP:
22210         switch (op2) {
22211         case OPC_PRECEQ_L_PWL:
22212             check_dsp(ctx);
22213             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
22214             break;
22215         case OPC_PRECEQ_L_PWR:
22216             check_dsp(ctx);
22217             tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
22218             break;
22219         case OPC_PRECEQ_PW_QHL:
22220             check_dsp(ctx);
22221             gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
22222             break;
22223         case OPC_PRECEQ_PW_QHR:
22224             check_dsp(ctx);
22225             gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
22226             break;
22227         case OPC_PRECEQ_PW_QHLA:
22228             check_dsp(ctx);
22229             gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
22230             break;
22231         case OPC_PRECEQ_PW_QHRA:
22232             check_dsp(ctx);
22233             gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
22234             break;
22235         case OPC_PRECEQU_QH_OBL:
22236             check_dsp(ctx);
22237             gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
22238             break;
22239         case OPC_PRECEQU_QH_OBR:
22240             check_dsp(ctx);
22241             gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
22242             break;
22243         case OPC_PRECEQU_QH_OBLA:
22244             check_dsp(ctx);
22245             gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
22246             break;
22247         case OPC_PRECEQU_QH_OBRA:
22248             check_dsp(ctx);
22249             gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
22250             break;
22251         case OPC_PRECEU_QH_OBL:
22252             check_dsp(ctx);
22253             gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
22254             break;
22255         case OPC_PRECEU_QH_OBR:
22256             check_dsp(ctx);
22257             gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
22258             break;
22259         case OPC_PRECEU_QH_OBLA:
22260             check_dsp(ctx);
22261             gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
22262             break;
22263         case OPC_PRECEU_QH_OBRA:
22264             check_dsp(ctx);
22265             gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
22266             break;
22267         case OPC_ABSQ_S_OB:
22268             check_dsp_r2(ctx);
22269             gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
22270             break;
22271         case OPC_ABSQ_S_PW:
22272             check_dsp(ctx);
22273             gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
22274             break;
22275         case OPC_ABSQ_S_QH:
22276             check_dsp(ctx);
22277             gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
22278             break;
22279         }
22280         break;
22281     case OPC_ADDU_OB_DSP:
22282         switch (op2) {
22283         case OPC_RADDU_L_OB:
22284             check_dsp(ctx);
22285             gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
22286             break;
22287         case OPC_SUBQ_PW:
22288             check_dsp(ctx);
22289             gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22290             break;
22291         case OPC_SUBQ_S_PW:
22292             check_dsp(ctx);
22293             gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22294             break;
22295         case OPC_SUBQ_QH:
22296             check_dsp(ctx);
22297             gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22298             break;
22299         case OPC_SUBQ_S_QH:
22300             check_dsp(ctx);
22301             gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22302             break;
22303         case OPC_SUBU_OB:
22304             check_dsp(ctx);
22305             gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22306             break;
22307         case OPC_SUBU_S_OB:
22308             check_dsp(ctx);
22309             gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22310             break;
22311         case OPC_SUBU_QH:
22312             check_dsp_r2(ctx);
22313             gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22314             break;
22315         case OPC_SUBU_S_QH:
22316             check_dsp_r2(ctx);
22317             gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22318             break;
22319         case OPC_SUBUH_OB:
22320             check_dsp_r2(ctx);
22321             gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
22322             break;
22323         case OPC_SUBUH_R_OB:
22324             check_dsp_r2(ctx);
22325             gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22326             break;
22327         case OPC_ADDQ_PW:
22328             check_dsp(ctx);
22329             gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22330             break;
22331         case OPC_ADDQ_S_PW:
22332             check_dsp(ctx);
22333             gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22334             break;
22335         case OPC_ADDQ_QH:
22336             check_dsp(ctx);
22337             gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22338             break;
22339         case OPC_ADDQ_S_QH:
22340             check_dsp(ctx);
22341             gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22342             break;
22343         case OPC_ADDU_OB:
22344             check_dsp(ctx);
22345             gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22346             break;
22347         case OPC_ADDU_S_OB:
22348             check_dsp(ctx);
22349             gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22350             break;
22351         case OPC_ADDU_QH:
22352             check_dsp_r2(ctx);
22353             gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22354             break;
22355         case OPC_ADDU_S_QH:
22356             check_dsp_r2(ctx);
22357             gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22358             break;
22359         case OPC_ADDUH_OB:
22360             check_dsp_r2(ctx);
22361             gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
22362             break;
22363         case OPC_ADDUH_R_OB:
22364             check_dsp_r2(ctx);
22365             gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22366             break;
22367         }
22368         break;
22369     case OPC_CMPU_EQ_OB_DSP:
22370         switch (op2) {
22371         case OPC_PRECR_OB_QH:
22372             check_dsp_r2(ctx);
22373             gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22374             break;
22375         case OPC_PRECR_SRA_QH_PW:
22376             check_dsp_r2(ctx);
22377             {
22378                 TCGv_i32 ret_t = tcg_const_i32(ret);
22379                 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
22380                 tcg_temp_free_i32(ret_t);
22381                 break;
22382             }
22383         case OPC_PRECR_SRA_R_QH_PW:
22384             check_dsp_r2(ctx);
22385             {
22386                 TCGv_i32 sa_v = tcg_const_i32(ret);
22387                 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
22388                 tcg_temp_free_i32(sa_v);
22389                 break;
22390             }
22391         case OPC_PRECRQ_OB_QH:
22392             check_dsp(ctx);
22393             gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22394             break;
22395         case OPC_PRECRQ_PW_L:
22396             check_dsp(ctx);
22397             gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
22398             break;
22399         case OPC_PRECRQ_QH_PW:
22400             check_dsp(ctx);
22401             gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
22402             break;
22403         case OPC_PRECRQ_RS_QH_PW:
22404             check_dsp(ctx);
22405             gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22406             break;
22407         case OPC_PRECRQU_S_OB_QH:
22408             check_dsp(ctx);
22409             gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22410             break;
22411         }
22412         break;
22413 #endif
22414     }
22415
22416     tcg_temp_free(v1_t);
22417     tcg_temp_free(v2_t);
22418 }
22419
22420 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
22421                               int ret, int v1, int v2)
22422 {
22423     uint32_t op2;
22424     TCGv t0;
22425     TCGv v1_t;
22426     TCGv v2_t;
22427
22428     if (ret == 0) {
22429         /* Treat as NOP. */
22430         return;
22431     }
22432
22433     t0 = tcg_temp_new();
22434     v1_t = tcg_temp_new();
22435     v2_t = tcg_temp_new();
22436
22437     tcg_gen_movi_tl(t0, v1);
22438     gen_load_gpr(v1_t, v1);
22439     gen_load_gpr(v2_t, v2);
22440
22441     switch (opc) {
22442     case OPC_SHLL_QB_DSP:
22443         {
22444             op2 = MASK_SHLL_QB(ctx->opcode);
22445             switch (op2) {
22446             case OPC_SHLL_QB:
22447                 check_dsp(ctx);
22448                 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
22449                 break;
22450             case OPC_SHLLV_QB:
22451                 check_dsp(ctx);
22452                 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22453                 break;
22454             case OPC_SHLL_PH:
22455                 check_dsp(ctx);
22456                 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22457                 break;
22458             case OPC_SHLLV_PH:
22459                 check_dsp(ctx);
22460                 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22461                 break;
22462             case OPC_SHLL_S_PH:
22463                 check_dsp(ctx);
22464                 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22465                 break;
22466             case OPC_SHLLV_S_PH:
22467                 check_dsp(ctx);
22468                 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22469                 break;
22470             case OPC_SHLL_S_W:
22471                 check_dsp(ctx);
22472                 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
22473                 break;
22474             case OPC_SHLLV_S_W:
22475                 check_dsp(ctx);
22476                 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22477                 break;
22478             case OPC_SHRL_QB:
22479                 check_dsp(ctx);
22480                 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
22481                 break;
22482             case OPC_SHRLV_QB:
22483                 check_dsp(ctx);
22484                 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
22485                 break;
22486             case OPC_SHRL_PH:
22487                 check_dsp_r2(ctx);
22488                 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
22489                 break;
22490             case OPC_SHRLV_PH:
22491                 check_dsp_r2(ctx);
22492                 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
22493                 break;
22494             case OPC_SHRA_QB:
22495                 check_dsp_r2(ctx);
22496                 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
22497                 break;
22498             case OPC_SHRA_R_QB:
22499                 check_dsp_r2(ctx);
22500                 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
22501                 break;
22502             case OPC_SHRAV_QB:
22503                 check_dsp_r2(ctx);
22504                 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
22505                 break;
22506             case OPC_SHRAV_R_QB:
22507                 check_dsp_r2(ctx);
22508                 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
22509                 break;
22510             case OPC_SHRA_PH:
22511                 check_dsp(ctx);
22512                 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
22513                 break;
22514             case OPC_SHRA_R_PH:
22515                 check_dsp(ctx);
22516                 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
22517                 break;
22518             case OPC_SHRAV_PH:
22519                 check_dsp(ctx);
22520                 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
22521                 break;
22522             case OPC_SHRAV_R_PH:
22523                 check_dsp(ctx);
22524                 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
22525                 break;
22526             case OPC_SHRA_R_W:
22527                 check_dsp(ctx);
22528                 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
22529                 break;
22530             case OPC_SHRAV_R_W:
22531                 check_dsp(ctx);
22532                 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
22533                 break;
22534             default:            /* Invalid */
22535                 MIPS_INVAL("MASK SHLL.QB");
22536                 generate_exception_end(ctx, EXCP_RI);
22537                 break;
22538             }
22539             break;
22540         }
22541 #ifdef TARGET_MIPS64
22542     case OPC_SHLL_OB_DSP:
22543         op2 = MASK_SHLL_OB(ctx->opcode);
22544         switch (op2) {
22545         case OPC_SHLL_PW:
22546             check_dsp(ctx);
22547             gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22548             break;
22549         case OPC_SHLLV_PW:
22550             check_dsp(ctx);
22551             gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22552             break;
22553         case OPC_SHLL_S_PW:
22554             check_dsp(ctx);
22555             gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22556             break;
22557         case OPC_SHLLV_S_PW:
22558             check_dsp(ctx);
22559             gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22560             break;
22561         case OPC_SHLL_OB:
22562             check_dsp(ctx);
22563             gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
22564             break;
22565         case OPC_SHLLV_OB:
22566             check_dsp(ctx);
22567             gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22568             break;
22569         case OPC_SHLL_QH:
22570             check_dsp(ctx);
22571             gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
22572             break;
22573         case OPC_SHLLV_QH:
22574             check_dsp(ctx);
22575             gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22576             break;
22577         case OPC_SHLL_S_QH:
22578             check_dsp(ctx);
22579             gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
22580             break;
22581         case OPC_SHLLV_S_QH:
22582             check_dsp(ctx);
22583             gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22584             break;
22585         case OPC_SHRA_OB:
22586             check_dsp_r2(ctx);
22587             gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
22588             break;
22589         case OPC_SHRAV_OB:
22590             check_dsp_r2(ctx);
22591             gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
22592             break;
22593         case OPC_SHRA_R_OB:
22594             check_dsp_r2(ctx);
22595             gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
22596             break;
22597         case OPC_SHRAV_R_OB:
22598             check_dsp_r2(ctx);
22599             gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
22600             break;
22601         case OPC_SHRA_PW:
22602             check_dsp(ctx);
22603             gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
22604             break;
22605         case OPC_SHRAV_PW:
22606             check_dsp(ctx);
22607             gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
22608             break;
22609         case OPC_SHRA_R_PW:
22610             check_dsp(ctx);
22611             gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
22612             break;
22613         case OPC_SHRAV_R_PW:
22614             check_dsp(ctx);
22615             gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
22616             break;
22617         case OPC_SHRA_QH:
22618             check_dsp(ctx);
22619             gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
22620             break;
22621         case OPC_SHRAV_QH:
22622             check_dsp(ctx);
22623             gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
22624             break;
22625         case OPC_SHRA_R_QH:
22626             check_dsp(ctx);
22627             gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
22628             break;
22629         case OPC_SHRAV_R_QH:
22630             check_dsp(ctx);
22631             gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
22632             break;
22633         case OPC_SHRL_OB:
22634             check_dsp(ctx);
22635             gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
22636             break;
22637         case OPC_SHRLV_OB:
22638             check_dsp(ctx);
22639             gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
22640             break;
22641         case OPC_SHRL_QH:
22642             check_dsp_r2(ctx);
22643             gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
22644             break;
22645         case OPC_SHRLV_QH:
22646             check_dsp_r2(ctx);
22647             gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
22648             break;
22649         default:            /* Invalid */
22650             MIPS_INVAL("MASK SHLL.OB");
22651             generate_exception_end(ctx, EXCP_RI);
22652             break;
22653         }
22654         break;
22655 #endif
22656     }
22657
22658     tcg_temp_free(t0);
22659     tcg_temp_free(v1_t);
22660     tcg_temp_free(v2_t);
22661 }
22662
22663 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
22664                                  int ret, int v1, int v2, int check_ret)
22665 {
22666     TCGv_i32 t0;
22667     TCGv v1_t;
22668     TCGv v2_t;
22669
22670     if ((ret == 0) && (check_ret == 1)) {
22671         /* Treat as NOP. */
22672         return;
22673     }
22674
22675     t0 = tcg_temp_new_i32();
22676     v1_t = tcg_temp_new();
22677     v2_t = tcg_temp_new();
22678
22679     tcg_gen_movi_i32(t0, ret);
22680     gen_load_gpr(v1_t, v1);
22681     gen_load_gpr(v2_t, v2);
22682
22683     switch (op1) {
22684     /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
22685      * the same mask and op1. */
22686     case OPC_MULT_G_2E:
22687         check_dsp_r2(ctx);
22688         switch (op2) {
22689         case  OPC_MUL_PH:
22690             gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22691             break;
22692         case  OPC_MUL_S_PH:
22693             gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22694             break;
22695         case OPC_MULQ_S_W:
22696             gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22697             break;
22698         case OPC_MULQ_RS_W:
22699             gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22700             break;
22701         }
22702         break;
22703     case OPC_DPA_W_PH_DSP:
22704         switch (op2) {
22705         case OPC_DPAU_H_QBL:
22706             check_dsp(ctx);
22707             gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
22708             break;
22709         case OPC_DPAU_H_QBR:
22710             check_dsp(ctx);
22711             gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
22712             break;
22713         case OPC_DPSU_H_QBL:
22714             check_dsp(ctx);
22715             gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
22716             break;
22717         case OPC_DPSU_H_QBR:
22718             check_dsp(ctx);
22719             gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
22720             break;
22721         case OPC_DPA_W_PH:
22722             check_dsp_r2(ctx);
22723             gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
22724             break;
22725         case OPC_DPAX_W_PH:
22726             check_dsp_r2(ctx);
22727             gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
22728             break;
22729         case OPC_DPAQ_S_W_PH:
22730             check_dsp(ctx);
22731             gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22732             break;
22733         case OPC_DPAQX_S_W_PH:
22734             check_dsp_r2(ctx);
22735             gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
22736             break;
22737         case OPC_DPAQX_SA_W_PH:
22738             check_dsp_r2(ctx);
22739             gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
22740             break;
22741         case OPC_DPS_W_PH:
22742             check_dsp_r2(ctx);
22743             gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
22744             break;
22745         case OPC_DPSX_W_PH:
22746             check_dsp_r2(ctx);
22747             gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
22748             break;
22749         case OPC_DPSQ_S_W_PH:
22750             check_dsp(ctx);
22751             gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22752             break;
22753         case OPC_DPSQX_S_W_PH:
22754             check_dsp_r2(ctx);
22755             gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
22756             break;
22757         case OPC_DPSQX_SA_W_PH:
22758             check_dsp_r2(ctx);
22759             gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
22760             break;
22761         case OPC_MULSAQ_S_W_PH:
22762             check_dsp(ctx);
22763             gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22764             break;
22765         case OPC_DPAQ_SA_L_W:
22766             check_dsp(ctx);
22767             gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
22768             break;
22769         case OPC_DPSQ_SA_L_W:
22770             check_dsp(ctx);
22771             gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
22772             break;
22773         case OPC_MAQ_S_W_PHL:
22774             check_dsp(ctx);
22775             gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
22776             break;
22777         case OPC_MAQ_S_W_PHR:
22778             check_dsp(ctx);
22779             gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
22780             break;
22781         case OPC_MAQ_SA_W_PHL:
22782             check_dsp(ctx);
22783             gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
22784             break;
22785         case OPC_MAQ_SA_W_PHR:
22786             check_dsp(ctx);
22787             gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
22788             break;
22789         case OPC_MULSA_W_PH:
22790             check_dsp_r2(ctx);
22791             gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
22792             break;
22793         }
22794         break;
22795 #ifdef TARGET_MIPS64
22796     case OPC_DPAQ_W_QH_DSP:
22797         {
22798             int ac = ret & 0x03;
22799             tcg_gen_movi_i32(t0, ac);
22800
22801             switch (op2) {
22802             case OPC_DMADD:
22803                 check_dsp(ctx);
22804                 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
22805                 break;
22806             case OPC_DMADDU:
22807                 check_dsp(ctx);
22808                 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
22809                 break;
22810             case OPC_DMSUB:
22811                 check_dsp(ctx);
22812                 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
22813                 break;
22814             case OPC_DMSUBU:
22815                 check_dsp(ctx);
22816                 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
22817                 break;
22818             case OPC_DPA_W_QH:
22819                 check_dsp_r2(ctx);
22820                 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
22821                 break;
22822             case OPC_DPAQ_S_W_QH:
22823                 check_dsp(ctx);
22824                 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22825                 break;
22826             case OPC_DPAQ_SA_L_PW:
22827                 check_dsp(ctx);
22828                 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
22829                 break;
22830             case OPC_DPAU_H_OBL:
22831                 check_dsp(ctx);
22832                 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
22833                 break;
22834             case OPC_DPAU_H_OBR:
22835                 check_dsp(ctx);
22836                 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
22837                 break;
22838             case OPC_DPS_W_QH:
22839                 check_dsp_r2(ctx);
22840                 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
22841                 break;
22842             case OPC_DPSQ_S_W_QH:
22843                 check_dsp(ctx);
22844                 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22845                 break;
22846             case OPC_DPSQ_SA_L_PW:
22847                 check_dsp(ctx);
22848                 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
22849                 break;
22850             case OPC_DPSU_H_OBL:
22851                 check_dsp(ctx);
22852                 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
22853                 break;
22854             case OPC_DPSU_H_OBR:
22855                 check_dsp(ctx);
22856                 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
22857                 break;
22858             case OPC_MAQ_S_L_PWL:
22859                 check_dsp(ctx);
22860                 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
22861                 break;
22862             case OPC_MAQ_S_L_PWR:
22863                 check_dsp(ctx);
22864                 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
22865                 break;
22866             case OPC_MAQ_S_W_QHLL:
22867                 check_dsp(ctx);
22868                 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
22869                 break;
22870             case OPC_MAQ_SA_W_QHLL:
22871                 check_dsp(ctx);
22872                 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
22873                 break;
22874             case OPC_MAQ_S_W_QHLR:
22875                 check_dsp(ctx);
22876                 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
22877                 break;
22878             case OPC_MAQ_SA_W_QHLR:
22879                 check_dsp(ctx);
22880                 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
22881                 break;
22882             case OPC_MAQ_S_W_QHRL:
22883                 check_dsp(ctx);
22884                 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
22885                 break;
22886             case OPC_MAQ_SA_W_QHRL:
22887                 check_dsp(ctx);
22888                 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
22889                 break;
22890             case OPC_MAQ_S_W_QHRR:
22891                 check_dsp(ctx);
22892                 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
22893                 break;
22894             case OPC_MAQ_SA_W_QHRR:
22895                 check_dsp(ctx);
22896                 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
22897                 break;
22898             case OPC_MULSAQ_S_L_PW:
22899                 check_dsp(ctx);
22900                 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
22901                 break;
22902             case OPC_MULSAQ_S_W_QH:
22903                 check_dsp(ctx);
22904                 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22905                 break;
22906             }
22907         }
22908         break;
22909 #endif
22910     case OPC_ADDU_QB_DSP:
22911         switch (op2) {
22912         case OPC_MULEU_S_PH_QBL:
22913             check_dsp(ctx);
22914             gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22915             break;
22916         case OPC_MULEU_S_PH_QBR:
22917             check_dsp(ctx);
22918             gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22919             break;
22920         case OPC_MULQ_RS_PH:
22921             check_dsp(ctx);
22922             gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22923             break;
22924         case OPC_MULEQ_S_W_PHL:
22925             check_dsp(ctx);
22926             gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22927             break;
22928         case OPC_MULEQ_S_W_PHR:
22929             check_dsp(ctx);
22930             gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22931             break;
22932         case OPC_MULQ_S_PH:
22933             check_dsp_r2(ctx);
22934             gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22935             break;
22936         }
22937         break;
22938 #ifdef TARGET_MIPS64
22939     case OPC_ADDU_OB_DSP:
22940         switch (op2) {
22941         case OPC_MULEQ_S_PW_QHL:
22942             check_dsp(ctx);
22943             gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22944             break;
22945         case OPC_MULEQ_S_PW_QHR:
22946             check_dsp(ctx);
22947             gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22948             break;
22949         case OPC_MULEU_S_QH_OBL:
22950             check_dsp(ctx);
22951             gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22952             break;
22953         case OPC_MULEU_S_QH_OBR:
22954             check_dsp(ctx);
22955             gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22956             break;
22957         case OPC_MULQ_RS_QH:
22958             check_dsp(ctx);
22959             gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22960             break;
22961         }
22962         break;
22963 #endif
22964     }
22965
22966     tcg_temp_free_i32(t0);
22967     tcg_temp_free(v1_t);
22968     tcg_temp_free(v2_t);
22969 }
22970
22971 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
22972                                 int ret, int val)
22973 {
22974     int16_t imm;
22975     TCGv t0;
22976     TCGv val_t;
22977
22978     if (ret == 0) {
22979         /* Treat as NOP. */
22980         return;
22981     }
22982
22983     t0 = tcg_temp_new();
22984     val_t = tcg_temp_new();
22985     gen_load_gpr(val_t, val);
22986
22987     switch (op1) {
22988     case OPC_ABSQ_S_PH_DSP:
22989         switch (op2) {
22990         case OPC_BITREV:
22991             check_dsp(ctx);
22992             gen_helper_bitrev(cpu_gpr[ret], val_t);
22993             break;
22994         case OPC_REPL_QB:
22995             check_dsp(ctx);
22996             {
22997                 target_long result;
22998                 imm = (ctx->opcode >> 16) & 0xFF;
22999                 result = (uint32_t)imm << 24 |
23000                          (uint32_t)imm << 16 |
23001                          (uint32_t)imm << 8  |
23002                          (uint32_t)imm;
23003                 result = (int32_t)result;
23004                 tcg_gen_movi_tl(cpu_gpr[ret], result);
23005             }
23006             break;
23007         case OPC_REPLV_QB:
23008             check_dsp(ctx);
23009             tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23010             tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23011             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23012             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23013             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23014             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23015             break;
23016         case OPC_REPL_PH:
23017             check_dsp(ctx);
23018             {
23019                 imm = (ctx->opcode >> 16) & 0x03FF;
23020                 imm = (int16_t)(imm << 6) >> 6;
23021                 tcg_gen_movi_tl(cpu_gpr[ret], \
23022                                 (target_long)((int32_t)imm << 16 | \
23023                                 (uint16_t)imm));
23024             }
23025             break;
23026         case OPC_REPLV_PH:
23027             check_dsp(ctx);
23028             tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23029             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23030             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23031             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23032             break;
23033         }
23034         break;
23035 #ifdef TARGET_MIPS64
23036     case OPC_ABSQ_S_QH_DSP:
23037         switch (op2) {
23038         case OPC_REPL_OB:
23039             check_dsp(ctx);
23040             {
23041                 target_long temp;
23042
23043                 imm = (ctx->opcode >> 16) & 0xFF;
23044                 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
23045                 temp = (temp << 16) | temp;
23046                 temp = (temp << 32) | temp;
23047                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23048                 break;
23049             }
23050         case OPC_REPL_PW:
23051             check_dsp(ctx);
23052             {
23053                 target_long temp;
23054
23055                 imm = (ctx->opcode >> 16) & 0x03FF;
23056                 imm = (int16_t)(imm << 6) >> 6;
23057                 temp = ((target_long)imm << 32) \
23058                        | ((target_long)imm & 0xFFFFFFFF);
23059                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23060                 break;
23061             }
23062         case OPC_REPL_QH:
23063             check_dsp(ctx);
23064             {
23065                 target_long temp;
23066
23067                 imm = (ctx->opcode >> 16) & 0x03FF;
23068                 imm = (int16_t)(imm << 6) >> 6;
23069
23070                 temp = ((uint64_t)(uint16_t)imm << 48) |
23071                        ((uint64_t)(uint16_t)imm << 32) |
23072                        ((uint64_t)(uint16_t)imm << 16) |
23073                        (uint64_t)(uint16_t)imm;
23074                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23075                 break;
23076             }
23077         case OPC_REPLV_OB:
23078             check_dsp(ctx);
23079             tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23080             tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23081             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23082             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23083             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23084             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23085             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23086             break;
23087         case OPC_REPLV_PW:
23088             check_dsp(ctx);
23089             tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
23090             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23091             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23092             break;
23093         case OPC_REPLV_QH:
23094             check_dsp(ctx);
23095             tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23096             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23097             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23098             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23099             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23100             break;
23101         }
23102         break;
23103 #endif
23104     }
23105     tcg_temp_free(t0);
23106     tcg_temp_free(val_t);
23107 }
23108
23109 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
23110                                      uint32_t op1, uint32_t op2,
23111                                      int ret, int v1, int v2, int check_ret)
23112 {
23113     TCGv t1;
23114     TCGv v1_t;
23115     TCGv v2_t;
23116
23117     if ((ret == 0) && (check_ret == 1)) {
23118         /* Treat as NOP. */
23119         return;
23120     }
23121
23122     t1 = tcg_temp_new();
23123     v1_t = tcg_temp_new();
23124     v2_t = tcg_temp_new();
23125
23126     gen_load_gpr(v1_t, v1);
23127     gen_load_gpr(v2_t, v2);
23128
23129     switch (op1) {
23130     case OPC_CMPU_EQ_QB_DSP:
23131         switch (op2) {
23132         case OPC_CMPU_EQ_QB:
23133             check_dsp(ctx);
23134             gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
23135             break;
23136         case OPC_CMPU_LT_QB:
23137             check_dsp(ctx);
23138             gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
23139             break;
23140         case OPC_CMPU_LE_QB:
23141             check_dsp(ctx);
23142             gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
23143             break;
23144         case OPC_CMPGU_EQ_QB:
23145             check_dsp(ctx);
23146             gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
23147             break;
23148         case OPC_CMPGU_LT_QB:
23149             check_dsp(ctx);
23150             gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
23151             break;
23152         case OPC_CMPGU_LE_QB:
23153             check_dsp(ctx);
23154             gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
23155             break;
23156         case OPC_CMPGDU_EQ_QB:
23157             check_dsp_r2(ctx);
23158             gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
23159             tcg_gen_mov_tl(cpu_gpr[ret], t1);
23160             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23161             tcg_gen_shli_tl(t1, t1, 24);
23162             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23163             break;
23164         case OPC_CMPGDU_LT_QB:
23165             check_dsp_r2(ctx);
23166             gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
23167             tcg_gen_mov_tl(cpu_gpr[ret], t1);
23168             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23169             tcg_gen_shli_tl(t1, t1, 24);
23170             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23171             break;
23172         case OPC_CMPGDU_LE_QB:
23173             check_dsp_r2(ctx);
23174             gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
23175             tcg_gen_mov_tl(cpu_gpr[ret], t1);
23176             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23177             tcg_gen_shli_tl(t1, t1, 24);
23178             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23179             break;
23180         case OPC_CMP_EQ_PH:
23181             check_dsp(ctx);
23182             gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
23183             break;
23184         case OPC_CMP_LT_PH:
23185             check_dsp(ctx);
23186             gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
23187             break;
23188         case OPC_CMP_LE_PH:
23189             check_dsp(ctx);
23190             gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
23191             break;
23192         case OPC_PICK_QB:
23193             check_dsp(ctx);
23194             gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23195             break;
23196         case OPC_PICK_PH:
23197             check_dsp(ctx);
23198             gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23199             break;
23200         case OPC_PACKRL_PH:
23201             check_dsp(ctx);
23202             gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
23203             break;
23204         }
23205         break;
23206 #ifdef TARGET_MIPS64
23207     case OPC_CMPU_EQ_OB_DSP:
23208         switch (op2) {
23209         case OPC_CMP_EQ_PW:
23210             check_dsp(ctx);
23211             gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
23212             break;
23213         case OPC_CMP_LT_PW:
23214             check_dsp(ctx);
23215             gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
23216             break;
23217         case OPC_CMP_LE_PW:
23218             check_dsp(ctx);
23219             gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
23220             break;
23221         case OPC_CMP_EQ_QH:
23222             check_dsp(ctx);
23223             gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
23224             break;
23225         case OPC_CMP_LT_QH:
23226             check_dsp(ctx);
23227             gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
23228             break;
23229         case OPC_CMP_LE_QH:
23230             check_dsp(ctx);
23231             gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
23232             break;
23233         case OPC_CMPGDU_EQ_OB:
23234             check_dsp_r2(ctx);
23235             gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23236             break;
23237         case OPC_CMPGDU_LT_OB:
23238             check_dsp_r2(ctx);
23239             gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23240             break;
23241         case OPC_CMPGDU_LE_OB:
23242             check_dsp_r2(ctx);
23243             gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23244             break;
23245         case OPC_CMPGU_EQ_OB:
23246             check_dsp(ctx);
23247             gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
23248             break;
23249         case OPC_CMPGU_LT_OB:
23250             check_dsp(ctx);
23251             gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
23252             break;
23253         case OPC_CMPGU_LE_OB:
23254             check_dsp(ctx);
23255             gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
23256             break;
23257         case OPC_CMPU_EQ_OB:
23258             check_dsp(ctx);
23259             gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
23260             break;
23261         case OPC_CMPU_LT_OB:
23262             check_dsp(ctx);
23263             gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
23264             break;
23265         case OPC_CMPU_LE_OB:
23266             check_dsp(ctx);
23267             gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
23268             break;
23269         case OPC_PACKRL_PW:
23270             check_dsp(ctx);
23271             gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
23272             break;
23273         case OPC_PICK_OB:
23274             check_dsp(ctx);
23275             gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23276             break;
23277         case OPC_PICK_PW:
23278             check_dsp(ctx);
23279             gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23280             break;
23281         case OPC_PICK_QH:
23282             check_dsp(ctx);
23283             gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23284             break;
23285         }
23286         break;
23287 #endif
23288     }
23289
23290     tcg_temp_free(t1);
23291     tcg_temp_free(v1_t);
23292     tcg_temp_free(v2_t);
23293 }
23294
23295 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
23296                                uint32_t op1, int rt, int rs, int sa)
23297 {
23298     TCGv t0;
23299
23300     check_dsp_r2(ctx);
23301
23302     if (rt == 0) {
23303         /* Treat as NOP. */
23304         return;
23305     }
23306
23307     t0 = tcg_temp_new();
23308     gen_load_gpr(t0, rs);
23309
23310     switch (op1) {
23311     case OPC_APPEND_DSP:
23312         switch (MASK_APPEND(ctx->opcode)) {
23313         case OPC_APPEND:
23314             if (sa != 0) {
23315                 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
23316             }
23317             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23318             break;
23319         case OPC_PREPEND:
23320             if (sa != 0) {
23321                 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
23322                 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23323                 tcg_gen_shli_tl(t0, t0, 32 - sa);
23324                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23325             }
23326             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23327             break;
23328         case OPC_BALIGN:
23329             sa &= 3;
23330             if (sa != 0 && sa != 2) {
23331                 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23332                 tcg_gen_ext32u_tl(t0, t0);
23333                 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
23334                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23335             }
23336             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23337             break;
23338         default:            /* Invalid */
23339             MIPS_INVAL("MASK APPEND");
23340             generate_exception_end(ctx, EXCP_RI);
23341             break;
23342         }
23343         break;
23344 #ifdef TARGET_MIPS64
23345     case OPC_DAPPEND_DSP:
23346         switch (MASK_DAPPEND(ctx->opcode)) {
23347         case OPC_DAPPEND:
23348             if (sa != 0) {
23349                 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
23350             }
23351             break;
23352         case OPC_PREPENDD:
23353             tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
23354             tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
23355             tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
23356             break;
23357         case OPC_PREPENDW:
23358             if (sa != 0) {
23359                 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23360                 tcg_gen_shli_tl(t0, t0, 64 - sa);
23361                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23362             }
23363             break;
23364         case OPC_DBALIGN:
23365             sa &= 7;
23366             if (sa != 0 && sa != 2 && sa != 4) {
23367                 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23368                 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
23369                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23370             }
23371             break;
23372         default:            /* Invalid */
23373             MIPS_INVAL("MASK DAPPEND");
23374             generate_exception_end(ctx, EXCP_RI);
23375             break;
23376         }
23377         break;
23378 #endif
23379     }
23380     tcg_temp_free(t0);
23381 }
23382
23383 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
23384                                 int ret, int v1, int v2, int check_ret)
23385
23386 {
23387     TCGv t0;
23388     TCGv t1;
23389     TCGv v1_t;
23390     TCGv v2_t;
23391     int16_t imm;
23392
23393     if ((ret == 0) && (check_ret == 1)) {
23394         /* Treat as NOP. */
23395         return;
23396     }
23397
23398     t0 = tcg_temp_new();
23399     t1 = tcg_temp_new();
23400     v1_t = tcg_temp_new();
23401     v2_t = tcg_temp_new();
23402
23403     gen_load_gpr(v1_t, v1);
23404     gen_load_gpr(v2_t, v2);
23405
23406     switch (op1) {
23407     case OPC_EXTR_W_DSP:
23408         check_dsp(ctx);
23409         switch (op2) {
23410         case OPC_EXTR_W:
23411             tcg_gen_movi_tl(t0, v2);
23412             tcg_gen_movi_tl(t1, v1);
23413             gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
23414             break;
23415         case OPC_EXTR_R_W:
23416             tcg_gen_movi_tl(t0, v2);
23417             tcg_gen_movi_tl(t1, v1);
23418             gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23419             break;
23420         case OPC_EXTR_RS_W:
23421             tcg_gen_movi_tl(t0, v2);
23422             tcg_gen_movi_tl(t1, v1);
23423             gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23424             break;
23425         case OPC_EXTR_S_H:
23426             tcg_gen_movi_tl(t0, v2);
23427             tcg_gen_movi_tl(t1, v1);
23428             gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23429             break;
23430         case OPC_EXTRV_S_H:
23431             tcg_gen_movi_tl(t0, v2);
23432             gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
23433             break;
23434         case OPC_EXTRV_W:
23435             tcg_gen_movi_tl(t0, v2);
23436             gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23437             break;
23438         case OPC_EXTRV_R_W:
23439             tcg_gen_movi_tl(t0, v2);
23440             gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23441             break;
23442         case OPC_EXTRV_RS_W:
23443             tcg_gen_movi_tl(t0, v2);
23444             gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23445             break;
23446         case OPC_EXTP:
23447             tcg_gen_movi_tl(t0, v2);
23448             tcg_gen_movi_tl(t1, v1);
23449             gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
23450             break;
23451         case OPC_EXTPV:
23452             tcg_gen_movi_tl(t0, v2);
23453             gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
23454             break;
23455         case OPC_EXTPDP:
23456             tcg_gen_movi_tl(t0, v2);
23457             tcg_gen_movi_tl(t1, v1);
23458             gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
23459             break;
23460         case OPC_EXTPDPV:
23461             tcg_gen_movi_tl(t0, v2);
23462             gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23463             break;
23464         case OPC_SHILO:
23465             imm = (ctx->opcode >> 20) & 0x3F;
23466             tcg_gen_movi_tl(t0, ret);
23467             tcg_gen_movi_tl(t1, imm);
23468             gen_helper_shilo(t0, t1, cpu_env);
23469             break;
23470         case OPC_SHILOV:
23471             tcg_gen_movi_tl(t0, ret);
23472             gen_helper_shilo(t0, v1_t, cpu_env);
23473             break;
23474         case OPC_MTHLIP:
23475             tcg_gen_movi_tl(t0, ret);
23476             gen_helper_mthlip(t0, v1_t, cpu_env);
23477             break;
23478         case OPC_WRDSP:
23479             imm = (ctx->opcode >> 11) & 0x3FF;
23480             tcg_gen_movi_tl(t0, imm);
23481             gen_helper_wrdsp(v1_t, t0, cpu_env);
23482             break;
23483         case OPC_RDDSP:
23484             imm = (ctx->opcode >> 16) & 0x03FF;
23485             tcg_gen_movi_tl(t0, imm);
23486             gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
23487             break;
23488         }
23489         break;
23490 #ifdef TARGET_MIPS64
23491     case OPC_DEXTR_W_DSP:
23492         check_dsp(ctx);
23493         switch (op2) {
23494         case OPC_DMTHLIP:
23495             tcg_gen_movi_tl(t0, ret);
23496             gen_helper_dmthlip(v1_t, t0, cpu_env);
23497             break;
23498         case OPC_DSHILO:
23499             {
23500                 int shift = (ctx->opcode >> 19) & 0x7F;
23501                 int ac = (ctx->opcode >> 11) & 0x03;
23502                 tcg_gen_movi_tl(t0, shift);
23503                 tcg_gen_movi_tl(t1, ac);
23504                 gen_helper_dshilo(t0, t1, cpu_env);
23505                 break;
23506             }
23507         case OPC_DSHILOV:
23508             {
23509                 int ac = (ctx->opcode >> 11) & 0x03;
23510                 tcg_gen_movi_tl(t0, ac);
23511                 gen_helper_dshilo(v1_t, t0, cpu_env);
23512                 break;
23513             }
23514         case OPC_DEXTP:
23515             tcg_gen_movi_tl(t0, v2);
23516             tcg_gen_movi_tl(t1, v1);
23517
23518             gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
23519             break;
23520         case OPC_DEXTPV:
23521             tcg_gen_movi_tl(t0, v2);
23522             gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
23523             break;
23524         case OPC_DEXTPDP:
23525             tcg_gen_movi_tl(t0, v2);
23526             tcg_gen_movi_tl(t1, v1);
23527             gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
23528             break;
23529         case OPC_DEXTPDPV:
23530             tcg_gen_movi_tl(t0, v2);
23531             gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23532             break;
23533         case OPC_DEXTR_L:
23534             tcg_gen_movi_tl(t0, v2);
23535             tcg_gen_movi_tl(t1, v1);
23536             gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
23537             break;
23538         case OPC_DEXTR_R_L:
23539             tcg_gen_movi_tl(t0, v2);
23540             tcg_gen_movi_tl(t1, v1);
23541             gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
23542             break;
23543         case OPC_DEXTR_RS_L:
23544             tcg_gen_movi_tl(t0, v2);
23545             tcg_gen_movi_tl(t1, v1);
23546             gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
23547             break;
23548         case OPC_DEXTR_W:
23549             tcg_gen_movi_tl(t0, v2);
23550             tcg_gen_movi_tl(t1, v1);
23551             gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
23552             break;
23553         case OPC_DEXTR_R_W:
23554             tcg_gen_movi_tl(t0, v2);
23555             tcg_gen_movi_tl(t1, v1);
23556             gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23557             break;
23558         case OPC_DEXTR_RS_W:
23559             tcg_gen_movi_tl(t0, v2);
23560             tcg_gen_movi_tl(t1, v1);
23561             gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23562             break;
23563         case OPC_DEXTR_S_H:
23564             tcg_gen_movi_tl(t0, v2);
23565             tcg_gen_movi_tl(t1, v1);
23566             gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23567             break;
23568         case OPC_DEXTRV_S_H:
23569             tcg_gen_movi_tl(t0, v2);
23570             tcg_gen_movi_tl(t1, v1);
23571             gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23572             break;
23573         case OPC_DEXTRV_L:
23574             tcg_gen_movi_tl(t0, v2);
23575             gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23576             break;
23577         case OPC_DEXTRV_R_L:
23578             tcg_gen_movi_tl(t0, v2);
23579             gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23580             break;
23581         case OPC_DEXTRV_RS_L:
23582             tcg_gen_movi_tl(t0, v2);
23583             gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23584             break;
23585         case OPC_DEXTRV_W:
23586             tcg_gen_movi_tl(t0, v2);
23587             gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23588             break;
23589         case OPC_DEXTRV_R_W:
23590             tcg_gen_movi_tl(t0, v2);
23591             gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23592             break;
23593         case OPC_DEXTRV_RS_W:
23594             tcg_gen_movi_tl(t0, v2);
23595             gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23596             break;
23597         }
23598         break;
23599 #endif
23600     }
23601
23602     tcg_temp_free(t0);
23603     tcg_temp_free(t1);
23604     tcg_temp_free(v1_t);
23605     tcg_temp_free(v2_t);
23606 }
23607
23608 /* End MIPSDSP functions. */
23609
23610 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
23611 {
23612     int rs, rt, rd, sa;
23613     uint32_t op1, op2;
23614
23615     rs = (ctx->opcode >> 21) & 0x1f;
23616     rt = (ctx->opcode >> 16) & 0x1f;
23617     rd = (ctx->opcode >> 11) & 0x1f;
23618     sa = (ctx->opcode >> 6) & 0x1f;
23619
23620     op1 = MASK_SPECIAL(ctx->opcode);
23621     switch (op1) {
23622     case OPC_LSA:
23623         gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
23624         break;
23625     case OPC_MULT:
23626     case OPC_MULTU:
23627     case OPC_DIV:
23628     case OPC_DIVU:
23629         op2 = MASK_R6_MULDIV(ctx->opcode);
23630         switch (op2) {
23631         case R6_OPC_MUL:
23632         case R6_OPC_MUH:
23633         case R6_OPC_MULU:
23634         case R6_OPC_MUHU:
23635         case R6_OPC_DIV:
23636         case R6_OPC_MOD:
23637         case R6_OPC_DIVU:
23638         case R6_OPC_MODU:
23639             gen_r6_muldiv(ctx, op2, rd, rs, rt);
23640             break;
23641         default:
23642             MIPS_INVAL("special_r6 muldiv");
23643             generate_exception_end(ctx, EXCP_RI);
23644             break;
23645         }
23646         break;
23647     case OPC_SELEQZ:
23648     case OPC_SELNEZ:
23649         gen_cond_move(ctx, op1, rd, rs, rt);
23650         break;
23651     case R6_OPC_CLO:
23652     case R6_OPC_CLZ:
23653         if (rt == 0 && sa == 1) {
23654             /* Major opcode and function field is shared with preR6 MFHI/MTHI.
23655                We need additionally to check other fields */
23656             gen_cl(ctx, op1, rd, rs);
23657         } else {
23658             generate_exception_end(ctx, EXCP_RI);
23659         }
23660         break;
23661     case R6_OPC_SDBBP:
23662         if (is_uhi(extract32(ctx->opcode, 6, 20))) {
23663             gen_helper_do_semihosting(cpu_env);
23664         } else {
23665             if (ctx->hflags & MIPS_HFLAG_SBRI) {
23666                 generate_exception_end(ctx, EXCP_RI);
23667             } else {
23668                 generate_exception_end(ctx, EXCP_DBp);
23669             }
23670         }
23671         break;
23672 #if defined(TARGET_MIPS64)
23673     case OPC_DLSA:
23674         check_mips_64(ctx);
23675         gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
23676         break;
23677     case R6_OPC_DCLO:
23678     case R6_OPC_DCLZ:
23679         if (rt == 0 && sa == 1) {
23680             /* Major opcode and function field is shared with preR6 MFHI/MTHI.
23681                We need additionally to check other fields */
23682             check_mips_64(ctx);
23683             gen_cl(ctx, op1, rd, rs);
23684         } else {
23685             generate_exception_end(ctx, EXCP_RI);
23686         }
23687         break;
23688     case OPC_DMULT:
23689     case OPC_DMULTU:
23690     case OPC_DDIV:
23691     case OPC_DDIVU:
23692
23693         op2 = MASK_R6_MULDIV(ctx->opcode);
23694         switch (op2) {
23695         case R6_OPC_DMUL:
23696         case R6_OPC_DMUH:
23697         case R6_OPC_DMULU:
23698         case R6_OPC_DMUHU:
23699         case R6_OPC_DDIV:
23700         case R6_OPC_DMOD:
23701         case R6_OPC_DDIVU:
23702         case R6_OPC_DMODU:
23703             check_mips_64(ctx);
23704             gen_r6_muldiv(ctx, op2, rd, rs, rt);
23705             break;
23706         default:
23707             MIPS_INVAL("special_r6 muldiv");
23708             generate_exception_end(ctx, EXCP_RI);
23709             break;
23710         }
23711         break;
23712 #endif
23713     default:            /* Invalid */
23714         MIPS_INVAL("special_r6");
23715         generate_exception_end(ctx, EXCP_RI);
23716         break;
23717     }
23718 }
23719
23720 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
23721 {
23722     int rs, rt, rd, sa;
23723     uint32_t op1;
23724
23725     rs = (ctx->opcode >> 21) & 0x1f;
23726     rt = (ctx->opcode >> 16) & 0x1f;
23727     rd = (ctx->opcode >> 11) & 0x1f;
23728     sa = (ctx->opcode >> 6) & 0x1f;
23729
23730     op1 = MASK_SPECIAL(ctx->opcode);
23731     switch (op1) {
23732     case OPC_MOVN:         /* Conditional move */
23733     case OPC_MOVZ:
23734         check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
23735                    INSN_LOONGSON2E | INSN_LOONGSON2F | INSN_R5900);
23736         gen_cond_move(ctx, op1, rd, rs, rt);
23737         break;
23738     case OPC_MFHI:          /* Move from HI/LO */
23739     case OPC_MFLO:
23740         gen_HILO(ctx, op1, rs & 3, rd);
23741         break;
23742     case OPC_MTHI:
23743     case OPC_MTLO:          /* Move to HI/LO */
23744         gen_HILO(ctx, op1, rd & 3, rs);
23745         break;
23746     case OPC_MOVCI:
23747         check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
23748         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
23749             check_cp1_enabled(ctx);
23750             gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
23751                       (ctx->opcode >> 16) & 1);
23752         } else {
23753             generate_exception_err(ctx, EXCP_CpU, 1);
23754         }
23755         break;
23756     case OPC_MULT:
23757     case OPC_MULTU:
23758         if (sa) {
23759             check_insn(ctx, INSN_VR54XX);
23760             op1 = MASK_MUL_VR54XX(ctx->opcode);
23761             gen_mul_vr54xx(ctx, op1, rd, rs, rt);
23762         } else if (ctx->insn_flags & INSN_R5900) {
23763             gen_mul_txx9(ctx, op1, rd, rs, rt);
23764         } else {
23765             gen_muldiv(ctx, op1, rd & 3, rs, rt);
23766         }
23767         break;
23768     case OPC_DIV:
23769     case OPC_DIVU:
23770         gen_muldiv(ctx, op1, 0, rs, rt);
23771         break;
23772 #if defined(TARGET_MIPS64)
23773     case OPC_DMULT:
23774     case OPC_DMULTU:
23775     case OPC_DDIV:
23776     case OPC_DDIVU:
23777         check_insn(ctx, ISA_MIPS3);
23778         check_insn_opc_user_only(ctx, INSN_R5900);
23779         check_mips_64(ctx);
23780         gen_muldiv(ctx, op1, 0, rs, rt);
23781         break;
23782 #endif
23783     case OPC_JR:
23784         gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
23785         break;
23786     case OPC_SPIM:
23787 #ifdef MIPS_STRICT_STANDARD
23788         MIPS_INVAL("SPIM");
23789         generate_exception_end(ctx, EXCP_RI);
23790 #else
23791         /* Implemented as RI exception for now. */
23792         MIPS_INVAL("spim (unofficial)");
23793         generate_exception_end(ctx, EXCP_RI);
23794 #endif
23795         break;
23796     default:            /* Invalid */
23797         MIPS_INVAL("special_legacy");
23798         generate_exception_end(ctx, EXCP_RI);
23799         break;
23800     }
23801 }
23802
23803 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
23804 {
23805     int rs, rt, rd, sa;
23806     uint32_t op1;
23807
23808     rs = (ctx->opcode >> 21) & 0x1f;
23809     rt = (ctx->opcode >> 16) & 0x1f;
23810     rd = (ctx->opcode >> 11) & 0x1f;
23811     sa = (ctx->opcode >> 6) & 0x1f;
23812
23813     op1 = MASK_SPECIAL(ctx->opcode);
23814     switch (op1) {
23815     case OPC_SLL:          /* Shift with immediate */
23816         if (sa == 5 && rd == 0 &&
23817             rs == 0 && rt == 0) { /* PAUSE */
23818             if ((ctx->insn_flags & ISA_MIPS32R6) &&
23819                 (ctx->hflags & MIPS_HFLAG_BMASK)) {
23820                 generate_exception_end(ctx, EXCP_RI);
23821                 break;
23822             }
23823         }
23824         /* Fallthrough */
23825     case OPC_SRA:
23826         gen_shift_imm(ctx, op1, rd, rt, sa);
23827         break;
23828     case OPC_SRL:
23829         switch ((ctx->opcode >> 21) & 0x1f) {
23830         case 1:
23831             /* rotr is decoded as srl on non-R2 CPUs */
23832             if (ctx->insn_flags & ISA_MIPS32R2) {
23833                 op1 = OPC_ROTR;
23834             }
23835             /* Fallthrough */
23836         case 0:
23837             gen_shift_imm(ctx, op1, rd, rt, sa);
23838             break;
23839         default:
23840             generate_exception_end(ctx, EXCP_RI);
23841             break;
23842         }
23843         break;
23844     case OPC_ADD:
23845     case OPC_ADDU:
23846     case OPC_SUB:
23847     case OPC_SUBU:
23848         gen_arith(ctx, op1, rd, rs, rt);
23849         break;
23850     case OPC_SLLV:         /* Shifts */
23851     case OPC_SRAV:
23852         gen_shift(ctx, op1, rd, rs, rt);
23853         break;
23854     case OPC_SRLV:
23855         switch ((ctx->opcode >> 6) & 0x1f) {
23856         case 1:
23857             /* rotrv is decoded as srlv on non-R2 CPUs */
23858             if (ctx->insn_flags & ISA_MIPS32R2) {
23859                 op1 = OPC_ROTRV;
23860             }
23861             /* Fallthrough */
23862         case 0:
23863             gen_shift(ctx, op1, rd, rs, rt);
23864             break;
23865         default:
23866             generate_exception_end(ctx, EXCP_RI);
23867             break;
23868         }
23869         break;
23870     case OPC_SLT:          /* Set on less than */
23871     case OPC_SLTU:
23872         gen_slt(ctx, op1, rd, rs, rt);
23873         break;
23874     case OPC_AND:          /* Logic*/
23875     case OPC_OR:
23876     case OPC_NOR:
23877     case OPC_XOR:
23878         gen_logic(ctx, op1, rd, rs, rt);
23879         break;
23880     case OPC_JALR:
23881         gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
23882         break;
23883     case OPC_TGE: /* Traps */
23884     case OPC_TGEU:
23885     case OPC_TLT:
23886     case OPC_TLTU:
23887     case OPC_TEQ:
23888     case OPC_TNE:
23889         check_insn(ctx, ISA_MIPS2);
23890         gen_trap(ctx, op1, rs, rt, -1);
23891         break;
23892     case OPC_LSA: /* OPC_PMON */
23893         if ((ctx->insn_flags & ISA_MIPS32R6) ||
23894             (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
23895             decode_opc_special_r6(env, ctx);
23896         } else {
23897             /* Pmon entry point, also R4010 selsl */
23898 #ifdef MIPS_STRICT_STANDARD
23899             MIPS_INVAL("PMON / selsl");
23900             generate_exception_end(ctx, EXCP_RI);
23901 #else
23902             gen_helper_0e0i(pmon, sa);
23903 #endif
23904         }
23905         break;
23906     case OPC_SYSCALL:
23907         generate_exception_end(ctx, EXCP_SYSCALL);
23908         break;
23909     case OPC_BREAK:
23910         generate_exception_end(ctx, EXCP_BREAK);
23911         break;
23912     case OPC_SYNC:
23913         check_insn(ctx, ISA_MIPS2);
23914         gen_sync(extract32(ctx->opcode, 6, 5));
23915         break;
23916
23917 #if defined(TARGET_MIPS64)
23918         /* MIPS64 specific opcodes */
23919     case OPC_DSLL:
23920     case OPC_DSRA:
23921     case OPC_DSLL32:
23922     case OPC_DSRA32:
23923         check_insn(ctx, ISA_MIPS3);
23924         check_mips_64(ctx);
23925         gen_shift_imm(ctx, op1, rd, rt, sa);
23926         break;
23927     case OPC_DSRL:
23928         switch ((ctx->opcode >> 21) & 0x1f) {
23929         case 1:
23930             /* drotr is decoded as dsrl on non-R2 CPUs */
23931             if (ctx->insn_flags & ISA_MIPS32R2) {
23932                 op1 = OPC_DROTR;
23933             }
23934             /* Fallthrough */
23935         case 0:
23936             check_insn(ctx, ISA_MIPS3);
23937             check_mips_64(ctx);
23938             gen_shift_imm(ctx, op1, rd, rt, sa);
23939             break;
23940         default:
23941             generate_exception_end(ctx, EXCP_RI);
23942             break;
23943         }
23944         break;
23945     case OPC_DSRL32:
23946         switch ((ctx->opcode >> 21) & 0x1f) {
23947         case 1:
23948             /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
23949             if (ctx->insn_flags & ISA_MIPS32R2) {
23950                 op1 = OPC_DROTR32;
23951             }
23952             /* Fallthrough */
23953         case 0:
23954             check_insn(ctx, ISA_MIPS3);
23955             check_mips_64(ctx);
23956             gen_shift_imm(ctx, op1, rd, rt, sa);
23957             break;
23958         default:
23959             generate_exception_end(ctx, EXCP_RI);
23960             break;
23961         }
23962         break;
23963     case OPC_DADD:
23964     case OPC_DADDU:
23965     case OPC_DSUB:
23966     case OPC_DSUBU:
23967         check_insn(ctx, ISA_MIPS3);
23968         check_mips_64(ctx);
23969         gen_arith(ctx, op1, rd, rs, rt);
23970         break;
23971     case OPC_DSLLV:
23972     case OPC_DSRAV:
23973         check_insn(ctx, ISA_MIPS3);
23974         check_mips_64(ctx);
23975         gen_shift(ctx, op1, rd, rs, rt);
23976         break;
23977     case OPC_DSRLV:
23978         switch ((ctx->opcode >> 6) & 0x1f) {
23979         case 1:
23980             /* drotrv is decoded as dsrlv on non-R2 CPUs */
23981             if (ctx->insn_flags & ISA_MIPS32R2) {
23982                 op1 = OPC_DROTRV;
23983             }
23984             /* Fallthrough */
23985         case 0:
23986             check_insn(ctx, ISA_MIPS3);
23987             check_mips_64(ctx);
23988             gen_shift(ctx, op1, rd, rs, rt);
23989             break;
23990         default:
23991             generate_exception_end(ctx, EXCP_RI);
23992             break;
23993         }
23994         break;
23995     case OPC_DLSA:
23996         if ((ctx->insn_flags & ISA_MIPS32R6) ||
23997             (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
23998             decode_opc_special_r6(env, ctx);
23999         }
24000         break;
24001 #endif
24002     default:
24003         if (ctx->insn_flags & ISA_MIPS32R6) {
24004             decode_opc_special_r6(env, ctx);
24005         } else {
24006             decode_opc_special_legacy(env, ctx);
24007         }
24008     }
24009 }
24010
24011
24012 /* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
24013 #define MXU_APTN1_A    0
24014 #define MXU_APTN1_S    1
24015
24016 /* MXU accumulate add/subtract 2-bit pattern 'aptn2' */
24017 #define MXU_APTN2_AA    0
24018 #define MXU_APTN2_AS    1
24019 #define MXU_APTN2_SA    2
24020 #define MXU_APTN2_SS    3
24021
24022 /* MXU execute add/subtract 2-bit pattern 'eptn2' */
24023 #define MXU_EPTN2_AA    0
24024 #define MXU_EPTN2_AS    1
24025 #define MXU_EPTN2_SA    2
24026 #define MXU_EPTN2_SS    3
24027
24028 /* MXU operand getting pattern 'optn2' */
24029 #define MXU_OPTN2_WW    0
24030 #define MXU_OPTN2_LW    1
24031 #define MXU_OPTN2_HW    2
24032 #define MXU_OPTN2_XW    3
24033
24034 /* MXU operand getting pattern 'optn3' */
24035 #define MXU_OPTN3_PTN0  0
24036 #define MXU_OPTN3_PTN1  1
24037 #define MXU_OPTN3_PTN2  2
24038 #define MXU_OPTN3_PTN3  3
24039 #define MXU_OPTN3_PTN4  4
24040 #define MXU_OPTN3_PTN5  5
24041 #define MXU_OPTN3_PTN6  6
24042 #define MXU_OPTN3_PTN7  7
24043
24044
24045 /*
24046  * S32I2M XRa, rb - Register move from GRF to XRF
24047  */
24048 static void gen_mxu_s32i2m(DisasContext *ctx)
24049 {
24050     TCGv t0;
24051     uint32_t XRa, Rb;
24052
24053     t0 = tcg_temp_new();
24054
24055     XRa = extract32(ctx->opcode, 6, 5);
24056     Rb = extract32(ctx->opcode, 16, 5);
24057
24058     gen_load_gpr(t0, Rb);
24059     if (XRa <= 15) {
24060         gen_store_mxu_gpr(t0, XRa);
24061     } else if (XRa == 16) {
24062         gen_store_mxu_cr(t0);
24063     }
24064
24065     tcg_temp_free(t0);
24066 }
24067
24068 /*
24069  * S32M2I XRa, rb - Register move from XRF to GRF
24070  */
24071 static void gen_mxu_s32m2i(DisasContext *ctx)
24072 {
24073     TCGv t0;
24074     uint32_t XRa, Rb;
24075
24076     t0 = tcg_temp_new();
24077
24078     XRa = extract32(ctx->opcode, 6, 5);
24079     Rb = extract32(ctx->opcode, 16, 5);
24080
24081     if (XRa <= 15) {
24082         gen_load_mxu_gpr(t0, XRa);
24083     } else if (XRa == 16) {
24084         gen_load_mxu_cr(t0);
24085     }
24086
24087     gen_store_gpr(t0, Rb);
24088
24089     tcg_temp_free(t0);
24090 }
24091
24092
24093 /*
24094  * Decoding engine for MXU
24095  * =======================
24096  */
24097
24098 /*
24099  *
24100  * Decode MXU pool00
24101  *
24102  *   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
24103  *  +-----------+---------+-----+-------+-------+-------+-----------+
24104  *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL00|
24105  *  +-----------+---------+-----+-------+-------+-------+-----------+
24106  *
24107  */
24108 static void decode_opc_mxu__pool00(CPUMIPSState *env, DisasContext *ctx)
24109 {
24110     uint32_t opcode = extract32(ctx->opcode, 18, 3);
24111
24112     switch (opcode) {
24113     case OPC_MXU_S32MAX:
24114         /* TODO: Implement emulation of S32MAX instruction. */
24115         MIPS_INVAL("OPC_MXU_S32MAX");
24116         generate_exception_end(ctx, EXCP_RI);
24117         break;
24118     case OPC_MXU_S32MIN:
24119         /* TODO: Implement emulation of S32MIN instruction. */
24120         MIPS_INVAL("OPC_MXU_S32MIN");
24121         generate_exception_end(ctx, EXCP_RI);
24122         break;
24123     case OPC_MXU_D16MAX:
24124         /* TODO: Implement emulation of D16MAX instruction. */
24125         MIPS_INVAL("OPC_MXU_D16MAX");
24126         generate_exception_end(ctx, EXCP_RI);
24127         break;
24128     case OPC_MXU_D16MIN:
24129         /* TODO: Implement emulation of D16MIN instruction. */
24130         MIPS_INVAL("OPC_MXU_D16MIN");
24131         generate_exception_end(ctx, EXCP_RI);
24132         break;
24133     case OPC_MXU_Q8MAX:
24134         /* TODO: Implement emulation of Q8MAX instruction. */
24135         MIPS_INVAL("OPC_MXU_Q8MAX");
24136         generate_exception_end(ctx, EXCP_RI);
24137         break;
24138     case OPC_MXU_Q8MIN:
24139         /* TODO: Implement emulation of Q8MIN instruction. */
24140         MIPS_INVAL("OPC_MXU_Q8MIN");
24141         generate_exception_end(ctx, EXCP_RI);
24142         break;
24143     case OPC_MXU_Q8SLT:
24144         /* TODO: Implement emulation of Q8SLT instruction. */
24145         MIPS_INVAL("OPC_MXU_Q8SLT");
24146         generate_exception_end(ctx, EXCP_RI);
24147         break;
24148     case OPC_MXU_Q8SLTU:
24149         /* TODO: Implement emulation of Q8SLTU instruction. */
24150         MIPS_INVAL("OPC_MXU_Q8SLTU");
24151         generate_exception_end(ctx, EXCP_RI);
24152         break;
24153     default:
24154         MIPS_INVAL("decode_opc_mxu");
24155         generate_exception_end(ctx, EXCP_RI);
24156         break;
24157     }
24158 }
24159
24160 /*
24161  *
24162  * Decode MXU pool01
24163  *
24164  *  S32SLT, D16SLT, D16AVG, D16AVGR, Q8AVG, Q8AVGR:
24165  *   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
24166  *  +-----------+---------+-----+-------+-------+-------+-----------+
24167  *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL01|
24168  *  +-----------+---------+-----+-------+-------+-------+-----------+
24169  *
24170  *  Q8ADD:
24171  *   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
24172  *  +-----------+---+-----+-----+-------+-------+-------+-----------+
24173  *  |  SPECIAL2 |en2|0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL01|
24174  *  +-----------+---+-----+-----+-------+-------+-------+-----------+
24175  *
24176  */
24177 static void decode_opc_mxu__pool01(CPUMIPSState *env, DisasContext *ctx)
24178 {
24179     uint32_t opcode = extract32(ctx->opcode, 18, 3);
24180
24181     switch (opcode) {
24182     case OPC_MXU_S32SLT:
24183         /* TODO: Implement emulation of S32SLT instruction. */
24184         MIPS_INVAL("OPC_MXU_S32SLT");
24185         generate_exception_end(ctx, EXCP_RI);
24186         break;
24187     case OPC_MXU_D16SLT:
24188         /* TODO: Implement emulation of D16SLT instruction. */
24189         MIPS_INVAL("OPC_MXU_D16SLT");
24190         generate_exception_end(ctx, EXCP_RI);
24191         break;
24192     case OPC_MXU_D16AVG:
24193         /* TODO: Implement emulation of D16AVG instruction. */
24194         MIPS_INVAL("OPC_MXU_D16AVG");
24195         generate_exception_end(ctx, EXCP_RI);
24196         break;
24197     case OPC_MXU_D16AVGR:
24198         /* TODO: Implement emulation of D16AVGR instruction. */
24199         MIPS_INVAL("OPC_MXU_D16AVGR");
24200         generate_exception_end(ctx, EXCP_RI);
24201         break;
24202     case OPC_MXU_Q8AVG:
24203         /* TODO: Implement emulation of Q8AVG instruction. */
24204         MIPS_INVAL("OPC_MXU_Q8AVG");
24205         generate_exception_end(ctx, EXCP_RI);
24206         break;
24207     case OPC_MXU_Q8AVGR:
24208         /* TODO: Implement emulation of Q8AVGR instruction. */
24209         MIPS_INVAL("OPC_MXU_Q8AVGR");
24210         generate_exception_end(ctx, EXCP_RI);
24211         break;
24212     case OPC_MXU_Q8ADD:
24213         /* TODO: Implement emulation of Q8ADD instruction. */
24214         MIPS_INVAL("OPC_MXU_Q8ADD");
24215         generate_exception_end(ctx, EXCP_RI);
24216         break;
24217     default:
24218         MIPS_INVAL("decode_opc_mxu");
24219         generate_exception_end(ctx, EXCP_RI);
24220         break;
24221     }
24222 }
24223
24224 /*
24225  *
24226  * Decode MXU pool02
24227  *
24228  *   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
24229  *  +-----------+---------+-----+-------+-------+-------+-----------+
24230  *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL02|
24231  *  +-----------+---------+-----+-------+-------+-------+-----------+
24232  *
24233  */
24234 static void decode_opc_mxu__pool02(CPUMIPSState *env, DisasContext *ctx)
24235 {
24236     uint32_t opcode = extract32(ctx->opcode, 18, 3);
24237
24238     switch (opcode) {
24239     case OPC_MXU_S32CPS:
24240         /* TODO: Implement emulation of S32CPS instruction. */
24241         MIPS_INVAL("OPC_MXU_S32CPS");
24242         generate_exception_end(ctx, EXCP_RI);
24243         break;
24244     case OPC_MXU_D16CPS:
24245         /* TODO: Implement emulation of D16CPS instruction. */
24246         MIPS_INVAL("OPC_MXU_D16CPS");
24247         generate_exception_end(ctx, EXCP_RI);
24248         break;
24249     case OPC_MXU_Q8ABD:
24250         /* TODO: Implement emulation of Q8ABD instruction. */
24251         MIPS_INVAL("OPC_MXU_Q8ABD");
24252         generate_exception_end(ctx, EXCP_RI);
24253         break;
24254     case OPC_MXU_Q16SAT:
24255         /* TODO: Implement emulation of Q16SAT instruction. */
24256         MIPS_INVAL("OPC_MXU_Q16SAT");
24257         generate_exception_end(ctx, EXCP_RI);
24258         break;
24259     default:
24260         MIPS_INVAL("decode_opc_mxu");
24261         generate_exception_end(ctx, EXCP_RI);
24262         break;
24263     }
24264 }
24265
24266 /*
24267  *
24268  * Decode MXU pool03
24269  *
24270  *  D16MULF:
24271  *   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
24272  *  +-----------+---+---+-------+-------+-------+-------+-----------+
24273  *  |  SPECIAL2 |x x|on2|0 0 0 0|  XRc  |  XRb  |  XRa  |MXU__POOL03|
24274  *  +-----------+---+---+-------+-------+-------+-------+-----------+
24275  *
24276  *  D16MULE:
24277  *   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
24278  *  +-----------+---+---+-------+-------+-------+-------+-----------+
24279  *  |  SPECIAL2 |x x|on2|   Xd  |  XRc  |  XRb  |  XRa  |MXU__POOL03|
24280  *  +-----------+---+---+-------+-------+-------+-------+-----------+
24281  *
24282  */
24283 static void decode_opc_mxu__pool03(CPUMIPSState *env, DisasContext *ctx)
24284 {
24285     uint32_t opcode = extract32(ctx->opcode, 24, 2);
24286
24287     switch (opcode) {
24288     case OPC_MXU_D16MULF:
24289         /* TODO: Implement emulation of D16MULF instruction. */
24290         MIPS_INVAL("OPC_MXU_D16MULF");
24291         generate_exception_end(ctx, EXCP_RI);
24292         break;
24293     case OPC_MXU_D16MULE:
24294         /* TODO: Implement emulation of D16MULE instruction. */
24295         MIPS_INVAL("OPC_MXU_D16MULE");
24296         generate_exception_end(ctx, EXCP_RI);
24297         break;
24298     default:
24299         MIPS_INVAL("decode_opc_mxu");
24300         generate_exception_end(ctx, EXCP_RI);
24301         break;
24302     }
24303 }
24304
24305 /*
24306  *
24307  * Decode MXU pool04
24308  *
24309  *   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
24310  *  +-----------+---------+-+-------------------+-------+-----------+
24311  *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL04|
24312  *  +-----------+---------+-+-------------------+-------+-----------+
24313  *
24314  */
24315 static void decode_opc_mxu__pool04(CPUMIPSState *env, DisasContext *ctx)
24316 {
24317     uint32_t opcode = extract32(ctx->opcode, 20, 1);
24318
24319     switch (opcode) {
24320     case OPC_MXU_S32LDD:
24321         /* TODO: Implement emulation of S32LDD instruction. */
24322         MIPS_INVAL("OPC_MXU_S32LDD");
24323         generate_exception_end(ctx, EXCP_RI);
24324         break;
24325     case OPC_MXU_S32LDDR:
24326         /* TODO: Implement emulation of S32LDDR instruction. */
24327         MIPS_INVAL("OPC_MXU_S32LDDR");
24328         generate_exception_end(ctx, EXCP_RI);
24329         break;
24330     default:
24331         MIPS_INVAL("decode_opc_mxu");
24332         generate_exception_end(ctx, EXCP_RI);
24333         break;
24334     }
24335 }
24336
24337 /*
24338  *
24339  * Decode MXU pool05
24340  *
24341  *   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
24342  *  +-----------+---------+-+-------------------+-------+-----------+
24343  *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL05|
24344  *  +-----------+---------+-+-------------------+-------+-----------+
24345  *
24346  */
24347 static void decode_opc_mxu__pool05(CPUMIPSState *env, DisasContext *ctx)
24348 {
24349     uint32_t opcode = extract32(ctx->opcode, 20, 1);
24350
24351     switch (opcode) {
24352     case OPC_MXU_S32STD:
24353         /* TODO: Implement emulation of S32STD instruction. */
24354         MIPS_INVAL("OPC_MXU_S32STD");
24355         generate_exception_end(ctx, EXCP_RI);
24356         break;
24357     case OPC_MXU_S32STDR:
24358         /* TODO: Implement emulation of S32STDR instruction. */
24359         MIPS_INVAL("OPC_MXU_S32STDR");
24360         generate_exception_end(ctx, EXCP_RI);
24361         break;
24362     default:
24363         MIPS_INVAL("decode_opc_mxu");
24364         generate_exception_end(ctx, EXCP_RI);
24365         break;
24366     }
24367 }
24368
24369 /*
24370  *
24371  * Decode MXU pool06
24372  *
24373  *   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
24374  *  +-----------+---------+---------+---+-------+-------+-----------+
24375  *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL06|
24376  *  +-----------+---------+---------+---+-------+-------+-----------+
24377  *
24378  */
24379 static void decode_opc_mxu__pool06(CPUMIPSState *env, DisasContext *ctx)
24380 {
24381     uint32_t opcode = extract32(ctx->opcode, 10, 4);
24382
24383     switch (opcode) {
24384     case OPC_MXU_S32LDDV:
24385         /* TODO: Implement emulation of S32LDDV instruction. */
24386         MIPS_INVAL("OPC_MXU_S32LDDV");
24387         generate_exception_end(ctx, EXCP_RI);
24388         break;
24389     case OPC_MXU_S32LDDVR:
24390         /* TODO: Implement emulation of S32LDDVR instruction. */
24391         MIPS_INVAL("OPC_MXU_S32LDDVR");
24392         generate_exception_end(ctx, EXCP_RI);
24393         break;
24394     default:
24395         MIPS_INVAL("decode_opc_mxu");
24396         generate_exception_end(ctx, EXCP_RI);
24397         break;
24398     }
24399 }
24400
24401 /*
24402  *
24403  * Decode MXU pool07
24404  *
24405  *   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
24406  *  +-----------+---------+---------+---+-------+-------+-----------+
24407  *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL07|
24408  *  +-----------+---------+---------+---+-------+-------+-----------+
24409  *
24410  */
24411 static void decode_opc_mxu__pool07(CPUMIPSState *env, DisasContext *ctx)
24412 {
24413     uint32_t opcode = extract32(ctx->opcode, 10, 4);
24414
24415     switch (opcode) {
24416     case OPC_MXU_S32STDV:
24417         /* TODO: Implement emulation of S32TDV instruction. */
24418         MIPS_INVAL("OPC_MXU_S32TDV");
24419         generate_exception_end(ctx, EXCP_RI);
24420         break;
24421     case OPC_MXU_S32STDVR:
24422         /* TODO: Implement emulation of S32TDVR instruction. */
24423         MIPS_INVAL("OPC_MXU_S32TDVR");
24424         generate_exception_end(ctx, EXCP_RI);
24425         break;
24426     default:
24427         MIPS_INVAL("decode_opc_mxu");
24428         generate_exception_end(ctx, EXCP_RI);
24429         break;
24430     }
24431 }
24432
24433 /*
24434  *
24435  * Decode MXU pool08
24436  *
24437  *   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
24438  *  +-----------+---------+-+-------------------+-------+-----------+
24439  *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL08|
24440  *  +-----------+---------+-+-------------------+-------+-----------+
24441  *
24442 */
24443 static void decode_opc_mxu__pool08(CPUMIPSState *env, DisasContext *ctx)
24444 {
24445     uint32_t opcode = extract32(ctx->opcode, 20, 1);
24446
24447     switch (opcode) {
24448     case OPC_MXU_S32LDI:
24449         /* TODO: Implement emulation of S32LDI instruction. */
24450         MIPS_INVAL("OPC_MXU_S32LDI");
24451         generate_exception_end(ctx, EXCP_RI);
24452         break;
24453     case OPC_MXU_S32LDIR:
24454         /* TODO: Implement emulation of S32LDIR instruction. */
24455         MIPS_INVAL("OPC_MXU_S32LDIR");
24456         generate_exception_end(ctx, EXCP_RI);
24457         break;
24458     default:
24459         MIPS_INVAL("decode_opc_mxu");
24460         generate_exception_end(ctx, EXCP_RI);
24461         break;
24462     }
24463 }
24464
24465 /*
24466  *
24467  * Decode MXU pool09
24468  *
24469  *   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
24470  *  +-----------+---------+-+-------------------+-------+-----------+
24471  *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL09|
24472  *  +-----------+---------+-+-------------------+-------+-----------+
24473  *
24474  */
24475 static void decode_opc_mxu__pool09(CPUMIPSState *env, DisasContext *ctx)
24476 {
24477     uint32_t opcode = extract32(ctx->opcode, 5, 0);
24478
24479     switch (opcode) {
24480     case OPC_MXU_S32SDI:
24481         /* TODO: Implement emulation of S32SDI instruction. */
24482         MIPS_INVAL("OPC_MXU_S32SDI");
24483         generate_exception_end(ctx, EXCP_RI);
24484         break;
24485     case OPC_MXU_S32SDIR:
24486         /* TODO: Implement emulation of S32SDIR instruction. */
24487         MIPS_INVAL("OPC_MXU_S32SDIR");
24488         generate_exception_end(ctx, EXCP_RI);
24489         break;
24490     default:
24491         MIPS_INVAL("decode_opc_mxu");
24492         generate_exception_end(ctx, EXCP_RI);
24493         break;
24494     }
24495 }
24496
24497 /*
24498  *
24499  * Decode MXU pool10
24500  *
24501  *   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
24502  *  +-----------+---------+---------+---+-------+-------+-----------+
24503  *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL10|
24504  *  +-----------+---------+---------+---+-------+-------+-----------+
24505  *
24506  */
24507 static void decode_opc_mxu__pool10(CPUMIPSState *env, DisasContext *ctx)
24508 {
24509     uint32_t opcode = extract32(ctx->opcode, 5, 0);
24510
24511     switch (opcode) {
24512     case OPC_MXU_S32LDIV:
24513         /* TODO: Implement emulation of S32LDIV instruction. */
24514         MIPS_INVAL("OPC_MXU_S32LDIV");
24515         generate_exception_end(ctx, EXCP_RI);
24516         break;
24517     case OPC_MXU_S32LDIVR:
24518         /* TODO: Implement emulation of S32LDIVR instruction. */
24519         MIPS_INVAL("OPC_MXU_S32LDIVR");
24520         generate_exception_end(ctx, EXCP_RI);
24521         break;
24522     default:
24523         MIPS_INVAL("decode_opc_mxu");
24524         generate_exception_end(ctx, EXCP_RI);
24525         break;
24526     }
24527 }
24528
24529 /*
24530  *
24531  * Decode MXU pool11
24532  *
24533  *   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
24534  *  +-----------+---------+---------+---+-------+-------+-----------+
24535  *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL11|
24536  *  +-----------+---------+---------+---+-------+-------+-----------+
24537  *
24538  */
24539 static void decode_opc_mxu__pool11(CPUMIPSState *env, DisasContext *ctx)
24540 {
24541     uint32_t opcode = extract32(ctx->opcode, 10, 4);
24542
24543     switch (opcode) {
24544     case OPC_MXU_S32SDIV:
24545         /* TODO: Implement emulation of S32SDIV instruction. */
24546         MIPS_INVAL("OPC_MXU_S32SDIV");
24547         generate_exception_end(ctx, EXCP_RI);
24548         break;
24549     case OPC_MXU_S32SDIVR:
24550         /* TODO: Implement emulation of S32SDIVR instruction. */
24551         MIPS_INVAL("OPC_MXU_S32SDIVR");
24552         generate_exception_end(ctx, EXCP_RI);
24553         break;
24554     default:
24555         MIPS_INVAL("decode_opc_mxu");
24556         generate_exception_end(ctx, EXCP_RI);
24557         break;
24558     }
24559 }
24560
24561 /*
24562  *
24563  * Decode MXU pool12
24564  *
24565  *   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
24566  *  +-----------+---+---+-------+-------+-------+-------+-----------+
24567  *  |  SPECIAL2 |an2|x x|   Xd  |  XRc  |  XRb  |  XRa  |MXU__POOL12|
24568  *  +-----------+---+---+-------+-------+-------+-------+-----------+
24569  *
24570  */
24571 static void decode_opc_mxu__pool12(CPUMIPSState *env, DisasContext *ctx)
24572 {
24573     uint32_t opcode = extract32(ctx->opcode, 22, 2);
24574
24575     switch (opcode) {
24576     case OPC_MXU_D32ACC:
24577         /* TODO: Implement emulation of D32ACC instruction. */
24578         MIPS_INVAL("OPC_MXU_D32ACC");
24579         generate_exception_end(ctx, EXCP_RI);
24580         break;
24581     case OPC_MXU_D32ACCM:
24582         /* TODO: Implement emulation of D32ACCM instruction. */
24583         MIPS_INVAL("OPC_MXU_D32ACCM");
24584         generate_exception_end(ctx, EXCP_RI);
24585         break;
24586     case OPC_MXU_D32ASUM:
24587         /* TODO: Implement emulation of D32ASUM instruction. */
24588         MIPS_INVAL("OPC_MXU_D32ASUM");
24589         generate_exception_end(ctx, EXCP_RI);
24590         break;
24591     default:
24592         MIPS_INVAL("decode_opc_mxu");
24593         generate_exception_end(ctx, EXCP_RI);
24594         break;
24595     }
24596 }
24597
24598 /*
24599  *
24600  * Decode MXU pool13
24601  *
24602  *   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
24603  *  +-----------+---+---+-------+-------+-------+-------+-----------+
24604  *  |  SPECIAL2 |en2|x x|0 0 0 0|  XRc  |  XRb  |  XRa  |MXU__POOL13|
24605  *  +-----------+---+---+-------+-------+-------+-------+-----------+
24606  *
24607  */
24608 static void decode_opc_mxu__pool13(CPUMIPSState *env, DisasContext *ctx)
24609 {
24610     uint32_t opcode = extract32(ctx->opcode, 22, 2);
24611
24612     switch (opcode) {
24613     case OPC_MXU_Q16ACC:
24614         /* TODO: Implement emulation of Q16ACC instruction. */
24615         MIPS_INVAL("OPC_MXU_Q16ACC");
24616         generate_exception_end(ctx, EXCP_RI);
24617         break;
24618     case OPC_MXU_Q16ACCM:
24619         /* TODO: Implement emulation of Q16ACCM instruction. */
24620         MIPS_INVAL("OPC_MXU_Q16ACCM");
24621         generate_exception_end(ctx, EXCP_RI);
24622         break;
24623     case OPC_MXU_Q16ASUM:
24624         /* TODO: Implement emulation of Q16ASUM instruction. */
24625         MIPS_INVAL("OPC_MXU_Q16ASUM");
24626         generate_exception_end(ctx, EXCP_RI);
24627         break;
24628     default:
24629         MIPS_INVAL("decode_opc_mxu");
24630         generate_exception_end(ctx, EXCP_RI);
24631         break;
24632     }
24633 }
24634
24635 /*
24636  *
24637  * Decode MXU pool14
24638  *
24639  *  Q8ADDE, Q8ACCE:
24640  *   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
24641  *  +-----------+---+---+-------+-------+-------+-------+-----------+
24642  *  |  SPECIAL2 |0 0|x x|  XRd  |  XRc  |  XRb  |  XRa  |MXU__POOL14|
24643  *  +-----------+---+---+-------+-------+-------+-------+-----------+
24644  *
24645  *  D8SUM, D8SUMC:
24646  *   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
24647  *  +-----------+---+---+-------+-------+-------+-------+-----------+
24648  *  |  SPECIAL2 |en2|x x|0 0 0 0|  XRc  |  XRb  |  XRa  |MXU__POOL14|
24649  *  +-----------+---+---+-------+-------+-------+-------+-----------+
24650  *
24651  */
24652 static void decode_opc_mxu__pool14(CPUMIPSState *env, DisasContext *ctx)
24653 {
24654     uint32_t opcode = extract32(ctx->opcode, 22, 2);
24655
24656     switch (opcode) {
24657     case OPC_MXU_Q8ADDE:
24658         /* TODO: Implement emulation of Q8ADDE instruction. */
24659         MIPS_INVAL("OPC_MXU_Q8ADDE");
24660         generate_exception_end(ctx, EXCP_RI);
24661         break;
24662     case OPC_MXU_D8SUM:
24663         /* TODO: Implement emulation of D8SUM instruction. */
24664         MIPS_INVAL("OPC_MXU_D8SUM");
24665         generate_exception_end(ctx, EXCP_RI);
24666         break;
24667     case OPC_MXU_D8SUMC:
24668         /* TODO: Implement emulation of D8SUMC instruction. */
24669         MIPS_INVAL("OPC_MXU_D8SUMC");
24670         generate_exception_end(ctx, EXCP_RI);
24671         break;
24672     default:
24673         MIPS_INVAL("decode_opc_mxu");
24674         generate_exception_end(ctx, EXCP_RI);
24675         break;
24676     }
24677 }
24678
24679 /*
24680  *
24681  * Decode MXU pool15
24682  *
24683  *  S32MUL, S32MULU, S32EXTRV:
24684  *   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
24685  *  +-----------+---------+---------+---+-------+-------+-----------+
24686  *  |  SPECIAL2 |    rs   |    rt   |x x|  XRd  |  XRa  |MXU__POOL15|
24687  *  +-----------+---------+---------+---+-------+-------+-----------+
24688  *
24689  *  S32EXTR:
24690  *   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
24691  *  +-----------+---------+---------+---+-------+-------+-----------+
24692  *  |  SPECIAL2 |    rb   |   sft5  |x x|  XRd  |  XRa  |MXU__POOL15|
24693  *  +-----------+---------+---------+---+-------+-------+-----------+
24694  *
24695  */
24696 static void decode_opc_mxu__pool15(CPUMIPSState *env, DisasContext *ctx)
24697 {
24698     uint32_t opcode = extract32(ctx->opcode, 14, 2);
24699
24700     switch (opcode) {
24701     case OPC_MXU_S32MUL:
24702         /* TODO: Implement emulation of S32MUL instruction. */
24703         MIPS_INVAL("OPC_MXU_S32MUL");
24704         generate_exception_end(ctx, EXCP_RI);
24705         break;
24706     case OPC_MXU_S32MULU:
24707         /* TODO: Implement emulation of S32MULU instruction. */
24708         MIPS_INVAL("OPC_MXU_S32MULU");
24709         generate_exception_end(ctx, EXCP_RI);
24710         break;
24711     case OPC_MXU_S32EXTR:
24712         /* TODO: Implement emulation of S32EXTR instruction. */
24713         MIPS_INVAL("OPC_MXU_S32EXTR");
24714         generate_exception_end(ctx, EXCP_RI);
24715         break;
24716     case OPC_MXU_S32EXTRV:
24717         /* TODO: Implement emulation of S32EXTRV instruction. */
24718         MIPS_INVAL("OPC_MXU_S32EXTRV");
24719         generate_exception_end(ctx, EXCP_RI);
24720         break;
24721     default:
24722         MIPS_INVAL("decode_opc_mxu");
24723         generate_exception_end(ctx, EXCP_RI);
24724         break;
24725     }
24726 }
24727
24728 /*
24729  *
24730  * Decode MXU pool16
24731  *
24732  *  D32SARW:
24733  *   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
24734  *  +-----------+---------+-----+-------+-------+-------+-----------+
24735  *  |  SPECIAL2 |    rb   |x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
24736  *  +-----------+---------+-----+-------+-------+-------+-----------+
24737  *
24738  *  S32ALN:
24739  *   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
24740  *  +-----------+---------+-----+-------+-------+-------+-----------+
24741  *  |  SPECIAL2 |    rs   |x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
24742  *  +-----------+---------+-----+-------+-------+-------+-----------+
24743  *
24744  *  S32ALNI:
24745  *   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
24746  *  +-----------+-----+---+-----+-------+-------+-------+-----------+
24747  *  |  SPECIAL2 |  s3 |0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
24748  *  +-----------+-----+---+-----+-------+-------+-------+-----------+
24749  *
24750  *  S32NOR, S32AND, S32OR, S32XOR:
24751  *   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
24752  *  +-----------+---------+-----+-------+-------+-------+-----------+
24753  *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
24754  *  +-----------+---------+-----+-------+-------+-------+-----------+
24755  *
24756  *  S32LUI:
24757  *   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
24758  *  +-----------+-----+---+-----+-------+---------------+-----------+
24759  *  |  SPECIAL2 |optn3|0 0|x x x|  XRc  |       s8      |MXU__POOL16|
24760  *  +-----------+-----+---+-----+-------+---------------+-----------+
24761  *
24762  */
24763 static void decode_opc_mxu__pool16(CPUMIPSState *env, DisasContext *ctx)
24764 {
24765     uint32_t opcode = extract32(ctx->opcode, 18, 3);
24766
24767     switch (opcode) {
24768     case OPC_MXU_D32SARW:
24769         /* TODO: Implement emulation of D32SARW instruction. */
24770         MIPS_INVAL("OPC_MXU_D32SARW");
24771         generate_exception_end(ctx, EXCP_RI);
24772         break;
24773     case OPC_MXU_S32ALN:
24774         /* TODO: Implement emulation of S32ALN instruction. */
24775         MIPS_INVAL("OPC_MXU_S32ALN");
24776         generate_exception_end(ctx, EXCP_RI);
24777         break;
24778     case OPC_MXU_S32ALNI:
24779         /* TODO: Implement emulation of S32ALNI instruction. */
24780         MIPS_INVAL("OPC_MXU_S32ALNI");
24781         generate_exception_end(ctx, EXCP_RI);
24782         break;
24783     case OPC_MXU_S32NOR:
24784         /* TODO: Implement emulation of S32NOR instruction. */
24785         MIPS_INVAL("OPC_MXU_S32NOR");
24786         generate_exception_end(ctx, EXCP_RI);
24787         break;
24788     case OPC_MXU_S32AND:
24789         /* TODO: Implement emulation of S32AND instruction. */
24790         MIPS_INVAL("OPC_MXU_S32AND");
24791         generate_exception_end(ctx, EXCP_RI);
24792         break;
24793     case OPC_MXU_S32OR:
24794         /* TODO: Implement emulation of S32OR instruction. */
24795         MIPS_INVAL("OPC_MXU_S32OR");
24796         generate_exception_end(ctx, EXCP_RI);
24797         break;
24798     case OPC_MXU_S32XOR:
24799         /* TODO: Implement emulation of S32XOR instruction. */
24800         MIPS_INVAL("OPC_MXU_S32XOR");
24801         generate_exception_end(ctx, EXCP_RI);
24802         break;
24803     case OPC_MXU_S32LUI:
24804         /* TODO: Implement emulation of S32LUI instruction. */
24805         MIPS_INVAL("OPC_MXU_S32LUI");
24806         generate_exception_end(ctx, EXCP_RI);
24807         break;
24808     default:
24809         MIPS_INVAL("decode_opc_mxu");
24810         generate_exception_end(ctx, EXCP_RI);
24811         break;
24812     }
24813 }
24814
24815 /*
24816  *
24817  * Decode MXU pool17
24818  *
24819  *   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
24820  *  +-----------+---------+-----+-------+-------+-------+-----------+
24821  *  |  SPECIAL2 |    rb   |x x x|  XRd  |  XRa  |0 0 0 0|MXU__POOL17|
24822  *  +-----------+---------+-----+-------+-------+-------+-----------+
24823  *
24824  */
24825 static void decode_opc_mxu__pool17(CPUMIPSState *env, DisasContext *ctx)
24826 {
24827     uint32_t opcode = extract32(ctx->opcode, 18, 3);
24828
24829     switch (opcode) {
24830     case OPC_MXU_D32SLLV:
24831         /* TODO: Implement emulation of D32SLLV instruction. */
24832         MIPS_INVAL("OPC_MXU_D32SLLV");
24833         generate_exception_end(ctx, EXCP_RI);
24834         break;
24835     case OPC_MXU_D32SLRV:
24836         /* TODO: Implement emulation of D32SLRV instruction. */
24837         MIPS_INVAL("OPC_MXU_D32SLRV");
24838         generate_exception_end(ctx, EXCP_RI);
24839         break;
24840     case OPC_MXU_D32SARV:
24841         /* TODO: Implement emulation of D32SARV instruction. */
24842         MIPS_INVAL("OPC_MXU_D32SARV");
24843         generate_exception_end(ctx, EXCP_RI);
24844         break;
24845     case OPC_MXU_Q16SLLV:
24846         /* TODO: Implement emulation of Q16SLLV instruction. */
24847         MIPS_INVAL("OPC_MXU_Q16SLLV");
24848         generate_exception_end(ctx, EXCP_RI);
24849         break;
24850     case OPC_MXU_Q16SLRV:
24851         /* TODO: Implement emulation of Q16SLRV instruction. */
24852         MIPS_INVAL("OPC_MXU_Q16SLRV");
24853         generate_exception_end(ctx, EXCP_RI);
24854         break;
24855     case OPC_MXU_Q16SARV:
24856         /* TODO: Implement emulation of Q16SARV instruction. */
24857         MIPS_INVAL("OPC_MXU_Q16SARV");
24858         generate_exception_end(ctx, EXCP_RI);
24859         break;
24860     default:
24861         MIPS_INVAL("decode_opc_mxu");
24862         generate_exception_end(ctx, EXCP_RI);
24863         break;
24864     }
24865 }
24866
24867 /*
24868  *
24869  * Decode MXU pool18
24870  *
24871  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24872  *  +-----------+---+---+-------+-------+-------+-------+-----------+
24873  *  |  SPECIAL2 |0 0|x x|  XRd  |  XRc  |  XRb  |  XRa  |MXU__POOL18|
24874  *  +-----------+---+---+-------+-------+-------+-------+-----------+
24875  *
24876  */
24877 static void decode_opc_mxu__pool18(CPUMIPSState *env, DisasContext *ctx)
24878 {
24879     uint32_t opcode = extract32(ctx->opcode, 22, 2);
24880
24881     switch (opcode) {
24882     case OPC_MXU_Q8MUL:
24883         /* TODO: Implement emulation of Q8MUL instruction. */
24884         MIPS_INVAL("OPC_MXU_Q8MUL");
24885         generate_exception_end(ctx, EXCP_RI);
24886         break;
24887     case OPC_MXU_Q8MULSU:
24888         /* TODO: Implement emulation of Q8MULSU instruction. */
24889         MIPS_INVAL("OPC_MXU_Q8MULSU");
24890         generate_exception_end(ctx, EXCP_RI);
24891         break;
24892     default:
24893         MIPS_INVAL("decode_opc_mxu");
24894         generate_exception_end(ctx, EXCP_RI);
24895         break;
24896     }
24897 }
24898
24899 /*
24900  *
24901  * Decode MXU pool19
24902  *
24903  *   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
24904  *  +-----------+---------+-----+-------+-------+-------+-----------+
24905  *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL19|
24906  *  +-----------+---------+-----+-------+-------+-------+-----------+
24907  *
24908  */
24909 static void decode_opc_mxu__pool19(CPUMIPSState *env, DisasContext *ctx)
24910 {
24911     uint32_t opcode = extract32(ctx->opcode, 18, 3);
24912
24913     switch (opcode) {
24914     case OPC_MXU_Q8MOVZ:
24915         /* TODO: Implement emulation of Q8MOVZ instruction. */
24916         MIPS_INVAL("OPC_MXU_Q8MOVZ");
24917         generate_exception_end(ctx, EXCP_RI);
24918         break;
24919     case OPC_MXU_Q8MOVN:
24920         /* TODO: Implement emulation of Q8MOVN instruction. */
24921         MIPS_INVAL("OPC_MXU_Q8MOVN");
24922         generate_exception_end(ctx, EXCP_RI);
24923         break;
24924     case OPC_MXU_D16MOVZ:
24925         /* TODO: Implement emulation of D16MOVZ instruction. */
24926         MIPS_INVAL("OPC_MXU_D16MOVZ");
24927         generate_exception_end(ctx, EXCP_RI);
24928         break;
24929     case OPC_MXU_D16MOVN:
24930         /* TODO: Implement emulation of D16MOVN instruction. */
24931         MIPS_INVAL("OPC_MXU_D16MOVN");
24932         generate_exception_end(ctx, EXCP_RI);
24933         break;
24934     case OPC_MXU_S32MOVZ:
24935         /* TODO: Implement emulation of S32MOVZ instruction. */
24936         MIPS_INVAL("OPC_MXU_S32MOVZ");
24937         generate_exception_end(ctx, EXCP_RI);
24938         break;
24939     case OPC_MXU_S32MOVN:
24940         /* TODO: Implement emulation of S32MOVN instruction. */
24941         MIPS_INVAL("OPC_MXU_S32MOVN");
24942         generate_exception_end(ctx, EXCP_RI);
24943         break;
24944     default:
24945         MIPS_INVAL("decode_opc_mxu");
24946         generate_exception_end(ctx, EXCP_RI);
24947         break;
24948     }
24949 }
24950
24951 /*
24952  *
24953  * Decode MXU pool20
24954  *
24955  *   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
24956  *  +-----------+---+---+-------+-------+-------+-------+-----------+
24957  *  |  SPECIAL2 |an2|x x|  XRd  |  XRc  |  XRb  |  XRa  |MXU__POOL20|
24958  *  +-----------+---+---+-------+-------+-------+-------+-----------+
24959  *
24960  */
24961 static void decode_opc_mxu__pool20(CPUMIPSState *env, DisasContext *ctx)
24962 {
24963     uint32_t opcode = extract32(ctx->opcode, 22, 2);
24964
24965     switch (opcode) {
24966     case OPC_MXU_Q8MAC:
24967         /* TODO: Implement emulation of Q8MAC instruction. */
24968         MIPS_INVAL("OPC_MXU_Q8MAC");
24969         generate_exception_end(ctx, EXCP_RI);
24970         break;
24971     case OPC_MXU_Q8MACSU:
24972         /* TODO: Implement emulation of Q8MACSU instruction. */
24973         MIPS_INVAL("OPC_MXU_Q8MACSU");
24974         generate_exception_end(ctx, EXCP_RI);
24975         break;
24976     default:
24977         MIPS_INVAL("decode_opc_mxu");
24978         generate_exception_end(ctx, EXCP_RI);
24979         break;
24980     }
24981 }
24982
24983
24984 /*
24985  * Main MXU decoding function
24986  *
24987  *   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
24988  *  +-----------+---------------------------------------+-----------+
24989  *  |  SPECIAL2 |                                       |x x x x x x|
24990  *  +-----------+---------------------------------------+-----------+
24991  *
24992  */
24993 static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx)
24994 {
24995     /*
24996      * TODO: Investigate necessity of including handling of
24997      * CLZ, CLO, SDBB in this function, as they belong to
24998      * SPECIAL2 opcode space for regular pre-R6 MIPS ISAs.
24999      */
25000     uint32_t opcode = extract32(ctx->opcode, 0, 6);
25001
25002     switch (opcode) {
25003     case OPC_MXU_S32MADD:
25004         /* TODO: Implement emulation of S32MADD instruction. */
25005         MIPS_INVAL("OPC_MXU_S32MADD");
25006         generate_exception_end(ctx, EXCP_RI);
25007         break;
25008     case OPC_MXU_S32MADDU:
25009         /* TODO: Implement emulation of S32MADDU instruction. */
25010         MIPS_INVAL("OPC_MXU_S32MADDU");
25011         generate_exception_end(ctx, EXCP_RI);
25012         break;
25013     case OPC__MXU_MUL:     /* 0x2 - unused in MXU specs */
25014         {
25015             uint32_t  rs, rt, rd, op1;
25016
25017             rs = extract32(ctx->opcode, 21, 5);
25018             rt = extract32(ctx->opcode, 16, 5);
25019             rd = extract32(ctx->opcode, 11, 5);
25020             op1 = MASK_SPECIAL2(ctx->opcode);
25021
25022             gen_arith(ctx, op1, rd, rs, rt);
25023         }
25024         break;
25025     case OPC_MXU__POOL00:
25026         decode_opc_mxu__pool00(env, ctx);
25027         break;
25028     case OPC_MXU_S32MSUB:
25029         /* TODO: Implement emulation of S32MSUB instruction. */
25030         MIPS_INVAL("OPC_MXU_S32MSUB");
25031         generate_exception_end(ctx, EXCP_RI);
25032         break;
25033     case OPC_MXU_S32MSUBU:
25034         /* TODO: Implement emulation of S32MSUBU instruction. */
25035         MIPS_INVAL("OPC_MXU_S32MSUBU");
25036         generate_exception_end(ctx, EXCP_RI);
25037         break;
25038     case OPC_MXU__POOL01:
25039         decode_opc_mxu__pool01(env, ctx);
25040         break;
25041     case OPC_MXU__POOL02:
25042         decode_opc_mxu__pool02(env, ctx);
25043         break;
25044     case OPC_MXU_D16MUL:
25045         /* TODO: Implement emulation of D16MUL instruction. */
25046         MIPS_INVAL("OPC_MXU_D16MUL");
25047         generate_exception_end(ctx, EXCP_RI);
25048         break;
25049     case OPC_MXU__POOL03:
25050         decode_opc_mxu__pool03(env, ctx);
25051         break;
25052     case OPC_MXU_D16MAC:
25053         /* TODO: Implement emulation of D16MAC instruction. */
25054         MIPS_INVAL("OPC_MXU_D16MAC");
25055         generate_exception_end(ctx, EXCP_RI);
25056         break;
25057     case OPC_MXU_D16MACF:
25058         /* TODO: Implement emulation of D16MACF instruction. */
25059         MIPS_INVAL("OPC_MXU_D16MACF");
25060         generate_exception_end(ctx, EXCP_RI);
25061         break;
25062     case OPC_MXU_D16MADL:
25063         /* TODO: Implement emulation of D16MADL instruction. */
25064         MIPS_INVAL("OPC_MXU_D16MADL");
25065         generate_exception_end(ctx, EXCP_RI);
25066         break;
25067     case OPC_MXU_S16MAD:
25068         /* TODO: Implement emulation of S16MAD instruction. */
25069         MIPS_INVAL("OPC_MXU_S16MAD");
25070         generate_exception_end(ctx, EXCP_RI);
25071         break;
25072     case OPC_MXU_Q16ADD:
25073         /* TODO: Implement emulation of Q16ADD instruction. */
25074         MIPS_INVAL("OPC_MXU_Q16ADD");
25075         generate_exception_end(ctx, EXCP_RI);
25076         break;
25077     case OPC_MXU_D16MACE:
25078         /* TODO: Implement emulation of D16MACE instruction. */
25079         MIPS_INVAL("OPC_MXU_D16MACE");
25080         generate_exception_end(ctx, EXCP_RI);
25081         break;
25082     case OPC_MXU__POOL04:
25083         decode_opc_mxu__pool04(env, ctx);
25084         break;
25085     case OPC_MXU__POOL05:
25086         decode_opc_mxu__pool05(env, ctx);
25087         break;
25088     case OPC_MXU__POOL06:
25089         decode_opc_mxu__pool06(env, ctx);
25090         break;
25091     case OPC_MXU__POOL07:
25092         decode_opc_mxu__pool07(env, ctx);
25093         break;
25094     case OPC_MXU__POOL08:
25095         decode_opc_mxu__pool08(env, ctx);
25096         break;
25097     case OPC_MXU__POOL09:
25098         decode_opc_mxu__pool09(env, ctx);
25099         break;
25100     case OPC_MXU__POOL10:
25101         decode_opc_mxu__pool10(env, ctx);
25102         break;
25103     case OPC_MXU__POOL11:
25104         decode_opc_mxu__pool11(env, ctx);
25105         break;
25106     case OPC_MXU_D32ADD:
25107         /* TODO: Implement emulation of D32ADD instruction. */
25108         MIPS_INVAL("OPC_MXU_D32ADD");
25109         generate_exception_end(ctx, EXCP_RI);
25110         break;
25111     case OPC_MXU__POOL12:
25112         decode_opc_mxu__pool12(env, ctx);
25113         break;
25114     case OPC_MXU__POOL13:
25115         decode_opc_mxu__pool13(env, ctx);
25116         break;
25117     case OPC_MXU__POOL14:
25118         decode_opc_mxu__pool14(env, ctx);
25119         break;
25120     case OPC_MXU_Q8ACCE:
25121         /* TODO: Implement emulation of Q8ACCE instruction. */
25122         MIPS_INVAL("OPC_MXU_Q8ACCE");
25123         generate_exception_end(ctx, EXCP_RI);
25124         break;
25125     case OPC_MXU_S8LDD:
25126         /* TODO: Implement emulation of S8LDD instruction. */
25127         MIPS_INVAL("OPC_MXU_S8LDD");
25128         generate_exception_end(ctx, EXCP_RI);
25129         break;
25130     case OPC_MXU_S8STD:
25131         /* TODO: Implement emulation of S8STD instruction. */
25132         MIPS_INVAL("OPC_MXU_S8STD");
25133         generate_exception_end(ctx, EXCP_RI);
25134         break;
25135     case OPC_MXU_S8LDI:
25136         /* TODO: Implement emulation of S8LDI instruction. */
25137         MIPS_INVAL("OPC_MXU_S8LDI");
25138         generate_exception_end(ctx, EXCP_RI);
25139         break;
25140     case OPC_MXU_S8SDI:
25141         /* TODO: Implement emulation of S8SDI instruction. */
25142         MIPS_INVAL("OPC_MXU_S8SDI");
25143         generate_exception_end(ctx, EXCP_RI);
25144         break;
25145     case OPC_MXU__POOL15:
25146         decode_opc_mxu__pool15(env, ctx);
25147         break;
25148     case OPC_MXU__POOL16:
25149         decode_opc_mxu__pool16(env, ctx);
25150         break;
25151     case OPC_MXU_LXB:
25152         /* TODO: Implement emulation of LXB instruction. */
25153         MIPS_INVAL("OPC_MXU_LXB");
25154         generate_exception_end(ctx, EXCP_RI);
25155         break;
25156     case OPC_MXU_S16LDD:
25157         /* TODO: Implement emulation of S16LDD instruction. */
25158         MIPS_INVAL("OPC_MXU_S16LDD");
25159         generate_exception_end(ctx, EXCP_RI);
25160         break;
25161     case OPC_MXU_S16STD:
25162         /* TODO: Implement emulation of S16STD instruction. */
25163         MIPS_INVAL("OPC_MXU_S16STD");
25164         generate_exception_end(ctx, EXCP_RI);
25165         break;
25166     case OPC_MXU_S16LDI:
25167         /* TODO: Implement emulation of S16LDI instruction. */
25168         MIPS_INVAL("OPC_MXU_S16LDI");
25169         generate_exception_end(ctx, EXCP_RI);
25170         break;
25171     case OPC_MXU_S16SDI:
25172         /* TODO: Implement emulation of S16SDI instruction. */
25173         MIPS_INVAL("OPC_MXU_S16SDI");
25174         generate_exception_end(ctx, EXCP_RI);
25175         break;
25176     case OPC_MXU_S32M2I:
25177         gen_mxu_s32m2i(ctx);
25178         break;
25179     case OPC_MXU_S32I2M:
25180         gen_mxu_s32i2m(ctx);
25181         break;
25182     case OPC_MXU_D32SLL:
25183         /* TODO: Implement emulation of D32SLL instruction. */
25184         MIPS_INVAL("OPC_MXU_D32SLL");
25185         generate_exception_end(ctx, EXCP_RI);
25186         break;
25187     case OPC_MXU_D32SLR:
25188         /* TODO: Implement emulation of D32SLR instruction. */
25189         MIPS_INVAL("OPC_MXU_D32SLR");
25190         generate_exception_end(ctx, EXCP_RI);
25191         break;
25192     case OPC_MXU_D32SARL:
25193         /* TODO: Implement emulation of D32SARL instruction. */
25194         MIPS_INVAL("OPC_MXU_D32SARL");
25195         generate_exception_end(ctx, EXCP_RI);
25196         break;
25197     case OPC_MXU_D32SAR:
25198         /* TODO: Implement emulation of D32SAR instruction. */
25199         MIPS_INVAL("OPC_MXU_D32SAR");
25200         generate_exception_end(ctx, EXCP_RI);
25201         break;
25202     case OPC_MXU_Q16SLL:
25203         /* TODO: Implement emulation of Q16SLL instruction. */
25204         MIPS_INVAL("OPC_MXU_Q16SLL");
25205         generate_exception_end(ctx, EXCP_RI);
25206         break;
25207     case OPC_MXU_Q16SLR:
25208         /* TODO: Implement emulation of Q16SLR instruction. */
25209         MIPS_INVAL("OPC_MXU_Q16SLR");
25210         generate_exception_end(ctx, EXCP_RI);
25211         break;
25212     case OPC_MXU__POOL17:
25213         decode_opc_mxu__pool17(env, ctx);
25214         break;
25215     case OPC_MXU_Q16SAR:
25216         /* TODO: Implement emulation of Q16SAR instruction. */
25217         MIPS_INVAL("OPC_MXU_Q16SAR");
25218         generate_exception_end(ctx, EXCP_RI);
25219         break;
25220     case OPC_MXU__POOL18:
25221         decode_opc_mxu__pool18(env, ctx);
25222         break;
25223     case OPC_MXU__POOL19:
25224         decode_opc_mxu__pool19(env, ctx);
25225         break;
25226     case OPC_MXU__POOL20:
25227         decode_opc_mxu__pool20(env, ctx);
25228         break;
25229     case OPC_MXU_Q16SCOP:
25230         /* TODO: Implement emulation of Q16SCOP instruction. */
25231         MIPS_INVAL("OPC_MXU_Q16SCOP");
25232         generate_exception_end(ctx, EXCP_RI);
25233         break;
25234     case OPC_MXU_Q8MADL:
25235         /* TODO: Implement emulation of Q8MADL instruction. */
25236         MIPS_INVAL("OPC_MXU_Q8MADL");
25237         generate_exception_end(ctx, EXCP_RI);
25238         break;
25239     case OPC_MXU_S32SFL:
25240         /* TODO: Implement emulation of S32SFL instruction. */
25241         MIPS_INVAL("OPC_MXU_S32SFL");
25242         generate_exception_end(ctx, EXCP_RI);
25243         break;
25244     case OPC_MXU_Q8SAD:
25245         /* TODO: Implement emulation of Q8SAD instruction. */
25246         MIPS_INVAL("OPC_MXU_Q8SAD");
25247         generate_exception_end(ctx, EXCP_RI);
25248         break;
25249     default:
25250         MIPS_INVAL("decode_opc_mxu");
25251         generate_exception_end(ctx, EXCP_RI);
25252     }
25253 }
25254
25255
25256 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
25257 {
25258     int rs, rt, rd;
25259     uint32_t op1;
25260
25261     check_insn_opc_removed(ctx, ISA_MIPS32R6);
25262
25263     rs = (ctx->opcode >> 21) & 0x1f;
25264     rt = (ctx->opcode >> 16) & 0x1f;
25265     rd = (ctx->opcode >> 11) & 0x1f;
25266
25267     op1 = MASK_SPECIAL2(ctx->opcode);
25268     switch (op1) {
25269     case OPC_MADD: /* Multiply and add/sub */
25270     case OPC_MADDU:
25271     case OPC_MSUB:
25272     case OPC_MSUBU:
25273         check_insn(ctx, ISA_MIPS32);
25274         gen_muldiv(ctx, op1, rd & 3, rs, rt);
25275         break;
25276     case OPC_MUL:
25277         gen_arith(ctx, op1, rd, rs, rt);
25278         break;
25279     case OPC_DIV_G_2F:
25280     case OPC_DIVU_G_2F:
25281     case OPC_MULT_G_2F:
25282     case OPC_MULTU_G_2F:
25283     case OPC_MOD_G_2F:
25284     case OPC_MODU_G_2F:
25285         check_insn(ctx, INSN_LOONGSON2F);
25286         gen_loongson_integer(ctx, op1, rd, rs, rt);
25287         break;
25288     case OPC_CLO:
25289     case OPC_CLZ:
25290         check_insn(ctx, ISA_MIPS32);
25291         gen_cl(ctx, op1, rd, rs);
25292         break;
25293     case OPC_SDBBP:
25294         if (is_uhi(extract32(ctx->opcode, 6, 20))) {
25295             gen_helper_do_semihosting(cpu_env);
25296         } else {
25297             /* XXX: not clear which exception should be raised
25298              *      when in debug mode...
25299              */
25300             check_insn(ctx, ISA_MIPS32);
25301             generate_exception_end(ctx, EXCP_DBp);
25302         }
25303         break;
25304 #if defined(TARGET_MIPS64)
25305     case OPC_DCLO:
25306     case OPC_DCLZ:
25307         check_insn(ctx, ISA_MIPS64);
25308         check_mips_64(ctx);
25309         gen_cl(ctx, op1, rd, rs);
25310         break;
25311     case OPC_DMULT_G_2F:
25312     case OPC_DMULTU_G_2F:
25313     case OPC_DDIV_G_2F:
25314     case OPC_DDIVU_G_2F:
25315     case OPC_DMOD_G_2F:
25316     case OPC_DMODU_G_2F:
25317         check_insn(ctx, INSN_LOONGSON2F);
25318         gen_loongson_integer(ctx, op1, rd, rs, rt);
25319         break;
25320 #endif
25321     default:            /* Invalid */
25322         MIPS_INVAL("special2_legacy");
25323         generate_exception_end(ctx, EXCP_RI);
25324         break;
25325     }
25326 }
25327
25328 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
25329 {
25330     int rs, rt, rd, sa;
25331     uint32_t op1, op2;
25332     int16_t imm;
25333
25334     rs = (ctx->opcode >> 21) & 0x1f;
25335     rt = (ctx->opcode >> 16) & 0x1f;
25336     rd = (ctx->opcode >> 11) & 0x1f;
25337     sa = (ctx->opcode >> 6) & 0x1f;
25338     imm = (int16_t)ctx->opcode >> 7;
25339
25340     op1 = MASK_SPECIAL3(ctx->opcode);
25341     switch (op1) {
25342     case R6_OPC_PREF:
25343         if (rt >= 24) {
25344             /* hint codes 24-31 are reserved and signal RI */
25345             generate_exception_end(ctx, EXCP_RI);
25346         }
25347         /* Treat as NOP. */
25348         break;
25349     case R6_OPC_CACHE:
25350         check_cp0_enabled(ctx);
25351         if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
25352             gen_cache_operation(ctx, rt, rs, imm);
25353         }
25354         break;
25355     case R6_OPC_SC:
25356         gen_st_cond(ctx, op1, rt, rs, imm);
25357         break;
25358     case R6_OPC_LL:
25359         gen_ld(ctx, op1, rt, rs, imm);
25360         break;
25361     case OPC_BSHFL:
25362         {
25363             if (rd == 0) {
25364                 /* Treat as NOP. */
25365                 break;
25366             }
25367             op2 = MASK_BSHFL(ctx->opcode);
25368             switch (op2) {
25369             case OPC_ALIGN:
25370             case OPC_ALIGN_1:
25371             case OPC_ALIGN_2:
25372             case OPC_ALIGN_3:
25373                 gen_align(ctx, 32, rd, rs, rt, sa & 3);
25374                 break;
25375             case OPC_BITSWAP:
25376                 gen_bitswap(ctx, op2, rd, rt);
25377                 break;
25378             }
25379         }
25380         break;
25381 #if defined(TARGET_MIPS64)
25382     case R6_OPC_SCD:
25383         gen_st_cond(ctx, op1, rt, rs, imm);
25384         break;
25385     case R6_OPC_LLD:
25386         gen_ld(ctx, op1, rt, rs, imm);
25387         break;
25388     case OPC_DBSHFL:
25389         check_mips_64(ctx);
25390         {
25391             if (rd == 0) {
25392                 /* Treat as NOP. */
25393                 break;
25394             }
25395             op2 = MASK_DBSHFL(ctx->opcode);
25396             switch (op2) {
25397             case OPC_DALIGN:
25398             case OPC_DALIGN_1:
25399             case OPC_DALIGN_2:
25400             case OPC_DALIGN_3:
25401             case OPC_DALIGN_4:
25402             case OPC_DALIGN_5:
25403             case OPC_DALIGN_6:
25404             case OPC_DALIGN_7:
25405                 gen_align(ctx, 64, rd, rs, rt, sa & 7);
25406                 break;
25407             case OPC_DBITSWAP:
25408                 gen_bitswap(ctx, op2, rd, rt);
25409                 break;
25410             }
25411
25412         }
25413         break;
25414 #endif
25415     default:            /* Invalid */
25416         MIPS_INVAL("special3_r6");
25417         generate_exception_end(ctx, EXCP_RI);
25418         break;
25419     }
25420 }
25421
25422 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
25423 {
25424     int rs, rt, rd;
25425     uint32_t op1, op2;
25426
25427     rs = (ctx->opcode >> 21) & 0x1f;
25428     rt = (ctx->opcode >> 16) & 0x1f;
25429     rd = (ctx->opcode >> 11) & 0x1f;
25430
25431     op1 = MASK_SPECIAL3(ctx->opcode);
25432     switch (op1) {
25433     case OPC_DIV_G_2E:
25434     case OPC_DIVU_G_2E:
25435     case OPC_MOD_G_2E:
25436     case OPC_MODU_G_2E:
25437     case OPC_MULT_G_2E:
25438     case OPC_MULTU_G_2E:
25439         /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
25440          * the same mask and op1. */
25441         if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
25442             op2 = MASK_ADDUH_QB(ctx->opcode);
25443             switch (op2) {
25444             case OPC_ADDUH_QB:
25445             case OPC_ADDUH_R_QB:
25446             case OPC_ADDQH_PH:
25447             case OPC_ADDQH_R_PH:
25448             case OPC_ADDQH_W:
25449             case OPC_ADDQH_R_W:
25450             case OPC_SUBUH_QB:
25451             case OPC_SUBUH_R_QB:
25452             case OPC_SUBQH_PH:
25453             case OPC_SUBQH_R_PH:
25454             case OPC_SUBQH_W:
25455             case OPC_SUBQH_R_W:
25456                 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
25457                 break;
25458             case OPC_MUL_PH:
25459             case OPC_MUL_S_PH:
25460             case OPC_MULQ_S_W:
25461             case OPC_MULQ_RS_W:
25462                 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
25463                 break;
25464             default:
25465                 MIPS_INVAL("MASK ADDUH.QB");
25466                 generate_exception_end(ctx, EXCP_RI);
25467                 break;
25468             }
25469         } else if (ctx->insn_flags & INSN_LOONGSON2E) {
25470             gen_loongson_integer(ctx, op1, rd, rs, rt);
25471         } else {
25472             generate_exception_end(ctx, EXCP_RI);
25473         }
25474         break;
25475     case OPC_LX_DSP:
25476         op2 = MASK_LX(ctx->opcode);
25477         switch (op2) {
25478 #if defined(TARGET_MIPS64)
25479         case OPC_LDX:
25480 #endif
25481         case OPC_LBUX:
25482         case OPC_LHX:
25483         case OPC_LWX:
25484             gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
25485             break;
25486         default:            /* Invalid */
25487             MIPS_INVAL("MASK LX");
25488             generate_exception_end(ctx, EXCP_RI);
25489             break;
25490         }
25491         break;
25492     case OPC_ABSQ_S_PH_DSP:
25493         op2 = MASK_ABSQ_S_PH(ctx->opcode);
25494         switch (op2) {
25495         case OPC_ABSQ_S_QB:
25496         case OPC_ABSQ_S_PH:
25497         case OPC_ABSQ_S_W:
25498         case OPC_PRECEQ_W_PHL:
25499         case OPC_PRECEQ_W_PHR:
25500         case OPC_PRECEQU_PH_QBL:
25501         case OPC_PRECEQU_PH_QBR:
25502         case OPC_PRECEQU_PH_QBLA:
25503         case OPC_PRECEQU_PH_QBRA:
25504         case OPC_PRECEU_PH_QBL:
25505         case OPC_PRECEU_PH_QBR:
25506         case OPC_PRECEU_PH_QBLA:
25507         case OPC_PRECEU_PH_QBRA:
25508             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
25509             break;
25510         case OPC_BITREV:
25511         case OPC_REPL_QB:
25512         case OPC_REPLV_QB:
25513         case OPC_REPL_PH:
25514         case OPC_REPLV_PH:
25515             gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
25516             break;
25517         default:
25518             MIPS_INVAL("MASK ABSQ_S.PH");
25519             generate_exception_end(ctx, EXCP_RI);
25520             break;
25521         }
25522         break;
25523     case OPC_ADDU_QB_DSP:
25524         op2 = MASK_ADDU_QB(ctx->opcode);
25525         switch (op2) {
25526         case OPC_ADDQ_PH:
25527         case OPC_ADDQ_S_PH:
25528         case OPC_ADDQ_S_W:
25529         case OPC_ADDU_QB:
25530         case OPC_ADDU_S_QB:
25531         case OPC_ADDU_PH:
25532         case OPC_ADDU_S_PH:
25533         case OPC_SUBQ_PH:
25534         case OPC_SUBQ_S_PH:
25535         case OPC_SUBQ_S_W:
25536         case OPC_SUBU_QB:
25537         case OPC_SUBU_S_QB:
25538         case OPC_SUBU_PH:
25539         case OPC_SUBU_S_PH:
25540         case OPC_ADDSC:
25541         case OPC_ADDWC:
25542         case OPC_MODSUB:
25543         case OPC_RADDU_W_QB:
25544             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
25545             break;
25546         case OPC_MULEU_S_PH_QBL:
25547         case OPC_MULEU_S_PH_QBR:
25548         case OPC_MULQ_RS_PH:
25549         case OPC_MULEQ_S_W_PHL:
25550         case OPC_MULEQ_S_W_PHR:
25551         case OPC_MULQ_S_PH:
25552             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
25553             break;
25554         default:            /* Invalid */
25555             MIPS_INVAL("MASK ADDU.QB");
25556             generate_exception_end(ctx, EXCP_RI);
25557             break;
25558
25559         }
25560         break;
25561     case OPC_CMPU_EQ_QB_DSP:
25562         op2 = MASK_CMPU_EQ_QB(ctx->opcode);
25563         switch (op2) {
25564         case OPC_PRECR_SRA_PH_W:
25565         case OPC_PRECR_SRA_R_PH_W:
25566             gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
25567             break;
25568         case OPC_PRECR_QB_PH:
25569         case OPC_PRECRQ_QB_PH:
25570         case OPC_PRECRQ_PH_W:
25571         case OPC_PRECRQ_RS_PH_W:
25572         case OPC_PRECRQU_S_QB_PH:
25573             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
25574             break;
25575         case OPC_CMPU_EQ_QB:
25576         case OPC_CMPU_LT_QB:
25577         case OPC_CMPU_LE_QB:
25578         case OPC_CMP_EQ_PH:
25579         case OPC_CMP_LT_PH:
25580         case OPC_CMP_LE_PH:
25581             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
25582             break;
25583         case OPC_CMPGU_EQ_QB:
25584         case OPC_CMPGU_LT_QB:
25585         case OPC_CMPGU_LE_QB:
25586         case OPC_CMPGDU_EQ_QB:
25587         case OPC_CMPGDU_LT_QB:
25588         case OPC_CMPGDU_LE_QB:
25589         case OPC_PICK_QB:
25590         case OPC_PICK_PH:
25591         case OPC_PACKRL_PH:
25592             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
25593             break;
25594         default:            /* Invalid */
25595             MIPS_INVAL("MASK CMPU.EQ.QB");
25596             generate_exception_end(ctx, EXCP_RI);
25597             break;
25598         }
25599         break;
25600     case OPC_SHLL_QB_DSP:
25601         gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
25602         break;
25603     case OPC_DPA_W_PH_DSP:
25604         op2 = MASK_DPA_W_PH(ctx->opcode);
25605         switch (op2) {
25606         case OPC_DPAU_H_QBL:
25607         case OPC_DPAU_H_QBR:
25608         case OPC_DPSU_H_QBL:
25609         case OPC_DPSU_H_QBR:
25610         case OPC_DPA_W_PH:
25611         case OPC_DPAX_W_PH:
25612         case OPC_DPAQ_S_W_PH:
25613         case OPC_DPAQX_S_W_PH:
25614         case OPC_DPAQX_SA_W_PH:
25615         case OPC_DPS_W_PH:
25616         case OPC_DPSX_W_PH:
25617         case OPC_DPSQ_S_W_PH:
25618         case OPC_DPSQX_S_W_PH:
25619         case OPC_DPSQX_SA_W_PH:
25620         case OPC_MULSAQ_S_W_PH:
25621         case OPC_DPAQ_SA_L_W:
25622         case OPC_DPSQ_SA_L_W:
25623         case OPC_MAQ_S_W_PHL:
25624         case OPC_MAQ_S_W_PHR:
25625         case OPC_MAQ_SA_W_PHL:
25626         case OPC_MAQ_SA_W_PHR:
25627         case OPC_MULSA_W_PH:
25628             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
25629             break;
25630         default:            /* Invalid */
25631             MIPS_INVAL("MASK DPAW.PH");
25632             generate_exception_end(ctx, EXCP_RI);
25633             break;
25634         }
25635         break;
25636     case OPC_INSV_DSP:
25637         op2 = MASK_INSV(ctx->opcode);
25638         switch (op2) {
25639         case OPC_INSV:
25640             check_dsp(ctx);
25641             {
25642                 TCGv t0, t1;
25643
25644                 if (rt == 0) {
25645                     break;
25646                 }
25647
25648                 t0 = tcg_temp_new();
25649                 t1 = tcg_temp_new();
25650
25651                 gen_load_gpr(t0, rt);
25652                 gen_load_gpr(t1, rs);
25653
25654                 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
25655
25656                 tcg_temp_free(t0);
25657                 tcg_temp_free(t1);
25658                 break;
25659             }
25660         default:            /* Invalid */
25661             MIPS_INVAL("MASK INSV");
25662             generate_exception_end(ctx, EXCP_RI);
25663             break;
25664         }
25665         break;
25666     case OPC_APPEND_DSP:
25667         gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
25668         break;
25669     case OPC_EXTR_W_DSP:
25670         op2 = MASK_EXTR_W(ctx->opcode);
25671         switch (op2) {
25672         case OPC_EXTR_W:
25673         case OPC_EXTR_R_W:
25674         case OPC_EXTR_RS_W:
25675         case OPC_EXTR_S_H:
25676         case OPC_EXTRV_S_H:
25677         case OPC_EXTRV_W:
25678         case OPC_EXTRV_R_W:
25679         case OPC_EXTRV_RS_W:
25680         case OPC_EXTP:
25681         case OPC_EXTPV:
25682         case OPC_EXTPDP:
25683         case OPC_EXTPDPV:
25684             gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
25685             break;
25686         case OPC_RDDSP:
25687             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
25688             break;
25689         case OPC_SHILO:
25690         case OPC_SHILOV:
25691         case OPC_MTHLIP:
25692         case OPC_WRDSP:
25693             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
25694             break;
25695         default:            /* Invalid */
25696             MIPS_INVAL("MASK EXTR.W");
25697             generate_exception_end(ctx, EXCP_RI);
25698             break;
25699         }
25700         break;
25701 #if defined(TARGET_MIPS64)
25702     case OPC_DDIV_G_2E:
25703     case OPC_DDIVU_G_2E:
25704     case OPC_DMULT_G_2E:
25705     case OPC_DMULTU_G_2E:
25706     case OPC_DMOD_G_2E:
25707     case OPC_DMODU_G_2E:
25708         check_insn(ctx, INSN_LOONGSON2E);
25709         gen_loongson_integer(ctx, op1, rd, rs, rt);
25710         break;
25711     case OPC_ABSQ_S_QH_DSP:
25712         op2 = MASK_ABSQ_S_QH(ctx->opcode);
25713         switch (op2) {
25714         case OPC_PRECEQ_L_PWL:
25715         case OPC_PRECEQ_L_PWR:
25716         case OPC_PRECEQ_PW_QHL:
25717         case OPC_PRECEQ_PW_QHR:
25718         case OPC_PRECEQ_PW_QHLA:
25719         case OPC_PRECEQ_PW_QHRA:
25720         case OPC_PRECEQU_QH_OBL:
25721         case OPC_PRECEQU_QH_OBR:
25722         case OPC_PRECEQU_QH_OBLA:
25723         case OPC_PRECEQU_QH_OBRA:
25724         case OPC_PRECEU_QH_OBL:
25725         case OPC_PRECEU_QH_OBR:
25726         case OPC_PRECEU_QH_OBLA:
25727         case OPC_PRECEU_QH_OBRA:
25728         case OPC_ABSQ_S_OB:
25729         case OPC_ABSQ_S_PW:
25730         case OPC_ABSQ_S_QH:
25731             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
25732             break;
25733         case OPC_REPL_OB:
25734         case OPC_REPL_PW:
25735         case OPC_REPL_QH:
25736         case OPC_REPLV_OB:
25737         case OPC_REPLV_PW:
25738         case OPC_REPLV_QH:
25739             gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
25740             break;
25741         default:            /* Invalid */
25742             MIPS_INVAL("MASK ABSQ_S.QH");
25743             generate_exception_end(ctx, EXCP_RI);
25744             break;
25745         }
25746         break;
25747     case OPC_ADDU_OB_DSP:
25748         op2 = MASK_ADDU_OB(ctx->opcode);
25749         switch (op2) {
25750         case OPC_RADDU_L_OB:
25751         case OPC_SUBQ_PW:
25752         case OPC_SUBQ_S_PW:
25753         case OPC_SUBQ_QH:
25754         case OPC_SUBQ_S_QH:
25755         case OPC_SUBU_OB:
25756         case OPC_SUBU_S_OB:
25757         case OPC_SUBU_QH:
25758         case OPC_SUBU_S_QH:
25759         case OPC_SUBUH_OB:
25760         case OPC_SUBUH_R_OB:
25761         case OPC_ADDQ_PW:
25762         case OPC_ADDQ_S_PW:
25763         case OPC_ADDQ_QH:
25764         case OPC_ADDQ_S_QH:
25765         case OPC_ADDU_OB:
25766         case OPC_ADDU_S_OB:
25767         case OPC_ADDU_QH:
25768         case OPC_ADDU_S_QH:
25769         case OPC_ADDUH_OB:
25770         case OPC_ADDUH_R_OB:
25771             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
25772             break;
25773         case OPC_MULEQ_S_PW_QHL:
25774         case OPC_MULEQ_S_PW_QHR:
25775         case OPC_MULEU_S_QH_OBL:
25776         case OPC_MULEU_S_QH_OBR:
25777         case OPC_MULQ_RS_QH:
25778             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
25779             break;
25780         default:            /* Invalid */
25781             MIPS_INVAL("MASK ADDU.OB");
25782             generate_exception_end(ctx, EXCP_RI);
25783             break;
25784         }
25785         break;
25786     case OPC_CMPU_EQ_OB_DSP:
25787         op2 = MASK_CMPU_EQ_OB(ctx->opcode);
25788         switch (op2) {
25789         case OPC_PRECR_SRA_QH_PW:
25790         case OPC_PRECR_SRA_R_QH_PW:
25791             /* Return value is rt. */
25792             gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
25793             break;
25794         case OPC_PRECR_OB_QH:
25795         case OPC_PRECRQ_OB_QH:
25796         case OPC_PRECRQ_PW_L:
25797         case OPC_PRECRQ_QH_PW:
25798         case OPC_PRECRQ_RS_QH_PW:
25799         case OPC_PRECRQU_S_OB_QH:
25800             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
25801             break;
25802         case OPC_CMPU_EQ_OB:
25803         case OPC_CMPU_LT_OB:
25804         case OPC_CMPU_LE_OB:
25805         case OPC_CMP_EQ_QH:
25806         case OPC_CMP_LT_QH:
25807         case OPC_CMP_LE_QH:
25808         case OPC_CMP_EQ_PW:
25809         case OPC_CMP_LT_PW:
25810         case OPC_CMP_LE_PW:
25811             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
25812             break;
25813         case OPC_CMPGDU_EQ_OB:
25814         case OPC_CMPGDU_LT_OB:
25815         case OPC_CMPGDU_LE_OB:
25816         case OPC_CMPGU_EQ_OB:
25817         case OPC_CMPGU_LT_OB:
25818         case OPC_CMPGU_LE_OB:
25819         case OPC_PACKRL_PW:
25820         case OPC_PICK_OB:
25821         case OPC_PICK_PW:
25822         case OPC_PICK_QH:
25823             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
25824             break;
25825         default:            /* Invalid */
25826             MIPS_INVAL("MASK CMPU_EQ.OB");
25827             generate_exception_end(ctx, EXCP_RI);
25828             break;
25829         }
25830         break;
25831     case OPC_DAPPEND_DSP:
25832         gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
25833         break;
25834     case OPC_DEXTR_W_DSP:
25835         op2 = MASK_DEXTR_W(ctx->opcode);
25836         switch (op2) {
25837         case OPC_DEXTP:
25838         case OPC_DEXTPDP:
25839         case OPC_DEXTPDPV:
25840         case OPC_DEXTPV:
25841         case OPC_DEXTR_L:
25842         case OPC_DEXTR_R_L:
25843         case OPC_DEXTR_RS_L:
25844         case OPC_DEXTR_W:
25845         case OPC_DEXTR_R_W:
25846         case OPC_DEXTR_RS_W:
25847         case OPC_DEXTR_S_H:
25848         case OPC_DEXTRV_L:
25849         case OPC_DEXTRV_R_L:
25850         case OPC_DEXTRV_RS_L:
25851         case OPC_DEXTRV_S_H:
25852         case OPC_DEXTRV_W:
25853         case OPC_DEXTRV_R_W:
25854         case OPC_DEXTRV_RS_W:
25855             gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
25856             break;
25857         case OPC_DMTHLIP:
25858         case OPC_DSHILO:
25859         case OPC_DSHILOV:
25860             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
25861             break;
25862         default:            /* Invalid */
25863             MIPS_INVAL("MASK EXTR.W");
25864             generate_exception_end(ctx, EXCP_RI);
25865             break;
25866         }
25867         break;
25868     case OPC_DPAQ_W_QH_DSP:
25869         op2 = MASK_DPAQ_W_QH(ctx->opcode);
25870         switch (op2) {
25871         case OPC_DPAU_H_OBL:
25872         case OPC_DPAU_H_OBR:
25873         case OPC_DPSU_H_OBL:
25874         case OPC_DPSU_H_OBR:
25875         case OPC_DPA_W_QH:
25876         case OPC_DPAQ_S_W_QH:
25877         case OPC_DPS_W_QH:
25878         case OPC_DPSQ_S_W_QH:
25879         case OPC_MULSAQ_S_W_QH:
25880         case OPC_DPAQ_SA_L_PW:
25881         case OPC_DPSQ_SA_L_PW:
25882         case OPC_MULSAQ_S_L_PW:
25883             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
25884             break;
25885         case OPC_MAQ_S_W_QHLL:
25886         case OPC_MAQ_S_W_QHLR:
25887         case OPC_MAQ_S_W_QHRL:
25888         case OPC_MAQ_S_W_QHRR:
25889         case OPC_MAQ_SA_W_QHLL:
25890         case OPC_MAQ_SA_W_QHLR:
25891         case OPC_MAQ_SA_W_QHRL:
25892         case OPC_MAQ_SA_W_QHRR:
25893         case OPC_MAQ_S_L_PWL:
25894         case OPC_MAQ_S_L_PWR:
25895         case OPC_DMADD:
25896         case OPC_DMADDU:
25897         case OPC_DMSUB:
25898         case OPC_DMSUBU:
25899             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
25900             break;
25901         default:            /* Invalid */
25902             MIPS_INVAL("MASK DPAQ.W.QH");
25903             generate_exception_end(ctx, EXCP_RI);
25904             break;
25905         }
25906         break;
25907     case OPC_DINSV_DSP:
25908         op2 = MASK_INSV(ctx->opcode);
25909         switch (op2) {
25910         case OPC_DINSV:
25911         {
25912             TCGv t0, t1;
25913
25914             if (rt == 0) {
25915                 break;
25916             }
25917             check_dsp(ctx);
25918
25919             t0 = tcg_temp_new();
25920             t1 = tcg_temp_new();
25921
25922             gen_load_gpr(t0, rt);
25923             gen_load_gpr(t1, rs);
25924
25925             gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
25926
25927             tcg_temp_free(t0);
25928             tcg_temp_free(t1);
25929             break;
25930         }
25931         default:            /* Invalid */
25932             MIPS_INVAL("MASK DINSV");
25933             generate_exception_end(ctx, EXCP_RI);
25934             break;
25935         }
25936         break;
25937     case OPC_SHLL_OB_DSP:
25938         gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
25939         break;
25940 #endif
25941     default:            /* Invalid */
25942         MIPS_INVAL("special3_legacy");
25943         generate_exception_end(ctx, EXCP_RI);
25944         break;
25945     }
25946 }
25947
25948 static void decode_tx79_mmi0(CPUMIPSState *env, DisasContext *ctx)
25949 {
25950     uint32_t opc = MASK_TX79_MMI0(ctx->opcode);
25951
25952     switch (opc) {
25953     case TX79_MMI0_PADDW:     /* TODO: TX79_MMI0_PADDW */
25954     case TX79_MMI0_PSUBW:     /* TODO: TX79_MMI0_PSUBW */
25955     case TX79_MMI0_PCGTW:     /* TODO: TX79_MMI0_PCGTW */
25956     case TX79_MMI0_PMAXW:     /* TODO: TX79_MMI0_PMAXW */
25957     case TX79_MMI0_PADDH:     /* TODO: TX79_MMI0_PADDH */
25958     case TX79_MMI0_PSUBH:     /* TODO: TX79_MMI0_PSUBH */
25959     case TX79_MMI0_PCGTH:     /* TODO: TX79_MMI0_PCGTH */
25960     case TX79_MMI0_PMAXH:     /* TODO: TX79_MMI0_PMAXH */
25961     case TX79_MMI0_PADDB:     /* TODO: TX79_MMI0_PADDB */
25962     case TX79_MMI0_PSUBB:     /* TODO: TX79_MMI0_PSUBB */
25963     case TX79_MMI0_PCGTB:     /* TODO: TX79_MMI0_PCGTB */
25964     case TX79_MMI0_PADDSW:    /* TODO: TX79_MMI0_PADDSW */
25965     case TX79_MMI0_PSUBSW:    /* TODO: TX79_MMI0_PSUBSW */
25966     case TX79_MMI0_PEXTLW:    /* TODO: TX79_MMI0_PEXTLW */
25967     case TX79_MMI0_PPACW:     /* TODO: TX79_MMI0_PPACW */
25968     case TX79_MMI0_PADDSH:    /* TODO: TX79_MMI0_PADDSH */
25969     case TX79_MMI0_PSUBSH:    /* TODO: TX79_MMI0_PSUBSH */
25970     case TX79_MMI0_PEXTLH:    /* TODO: TX79_MMI0_PEXTLH */
25971     case TX79_MMI0_PPACH:     /* TODO: TX79_MMI0_PPACH */
25972     case TX79_MMI0_PADDSB:    /* TODO: TX79_MMI0_PADDSB */
25973     case TX79_MMI0_PSUBSB:    /* TODO: TX79_MMI0_PSUBSB */
25974     case TX79_MMI0_PEXTLB:    /* TODO: TX79_MMI0_PEXTLB */
25975     case TX79_MMI0_PPACB:     /* TODO: TX79_MMI0_PPACB */
25976     case TX79_MMI0_PEXT5:     /* TODO: TX79_MMI0_PEXT5 */
25977     case TX79_MMI0_PPAC5:     /* TODO: TX79_MMI0_PPAC5 */
25978         generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_MMI_CLASS_MMI0 */
25979         break;
25980     default:
25981         MIPS_INVAL("TX79 MMI class MMI0");
25982         generate_exception_end(ctx, EXCP_RI);
25983         break;
25984     }
25985 }
25986
25987 static void decode_tx79_mmi1(CPUMIPSState *env, DisasContext *ctx)
25988 {
25989     uint32_t opc = MASK_TX79_MMI1(ctx->opcode);
25990
25991     switch (opc) {
25992     case TX79_MMI1_PABSW:     /* TODO: TX79_MMI1_PABSW */
25993     case TX79_MMI1_PCEQW:     /* TODO: TX79_MMI1_PCEQW */
25994     case TX79_MMI1_PMINW:     /* TODO: TX79_MMI1_PMINW */
25995     case TX79_MMI1_PADSBH:    /* TODO: TX79_MMI1_PADSBH */
25996     case TX79_MMI1_PABSH:     /* TODO: TX79_MMI1_PABSH */
25997     case TX79_MMI1_PCEQH:     /* TODO: TX79_MMI1_PCEQH */
25998     case TX79_MMI1_PMINH:     /* TODO: TX79_MMI1_PMINH */
25999     case TX79_MMI1_PCEQB:     /* TODO: TX79_MMI1_PCEQB */
26000     case TX79_MMI1_PADDUW:    /* TODO: TX79_MMI1_PADDUW */
26001     case TX79_MMI1_PSUBUW:    /* TODO: TX79_MMI1_PSUBUW */
26002     case TX79_MMI1_PEXTUW:    /* TODO: TX79_MMI1_PEXTUW */
26003     case TX79_MMI1_PADDUH:    /* TODO: TX79_MMI1_PADDUH */
26004     case TX79_MMI1_PSUBUH:    /* TODO: TX79_MMI1_PSUBUH */
26005     case TX79_MMI1_PEXTUH:    /* TODO: TX79_MMI1_PEXTUH */
26006     case TX79_MMI1_PADDUB:    /* TODO: TX79_MMI1_PADDUB */
26007     case TX79_MMI1_PSUBUB:    /* TODO: TX79_MMI1_PSUBUB */
26008     case TX79_MMI1_PEXTUB:    /* TODO: TX79_MMI1_PEXTUB */
26009     case TX79_MMI1_QFSRV:     /* TODO: TX79_MMI1_QFSRV */
26010         generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_MMI_CLASS_MMI1 */
26011         break;
26012     default:
26013         MIPS_INVAL("TX79 MMI class MMI1");
26014         generate_exception_end(ctx, EXCP_RI);
26015         break;
26016     }
26017 }
26018
26019 static void decode_tx79_mmi2(CPUMIPSState *env, DisasContext *ctx)
26020 {
26021     uint32_t opc = MASK_TX79_MMI2(ctx->opcode);
26022
26023     switch (opc) {
26024     case TX79_MMI2_PMADDW:    /* TODO: TX79_MMI2_PMADDW */
26025     case TX79_MMI2_PSLLVW:    /* TODO: TX79_MMI2_PSLLVW */
26026     case TX79_MMI2_PSRLVW:    /* TODO: TX79_MMI2_PSRLVW */
26027     case TX79_MMI2_PMSUBW:    /* TODO: TX79_MMI2_PMSUBW */
26028     case TX79_MMI2_PMFHI:     /* TODO: TX79_MMI2_PMFHI */
26029     case TX79_MMI2_PMFLO:     /* TODO: TX79_MMI2_PMFLO */
26030     case TX79_MMI2_PINTH:     /* TODO: TX79_MMI2_PINTH */
26031     case TX79_MMI2_PMULTW:    /* TODO: TX79_MMI2_PMULTW */
26032     case TX79_MMI2_PDIVW:     /* TODO: TX79_MMI2_PDIVW */
26033     case TX79_MMI2_PCPYLD:    /* TODO: TX79_MMI2_PCPYLD */
26034     case TX79_MMI2_PMADDH:    /* TODO: TX79_MMI2_PMADDH */
26035     case TX79_MMI2_PHMADH:    /* TODO: TX79_MMI2_PHMADH */
26036     case TX79_MMI2_PAND:      /* TODO: TX79_MMI2_PAND */
26037     case TX79_MMI2_PXOR:      /* TODO: TX79_MMI2_PXOR */
26038     case TX79_MMI2_PMSUBH:    /* TODO: TX79_MMI2_PMSUBH */
26039     case TX79_MMI2_PHMSBH:    /* TODO: TX79_MMI2_PHMSBH */
26040     case TX79_MMI2_PEXEH:     /* TODO: TX79_MMI2_PEXEH */
26041     case TX79_MMI2_PREVH:     /* TODO: TX79_MMI2_PREVH */
26042     case TX79_MMI2_PMULTH:    /* TODO: TX79_MMI2_PMULTH */
26043     case TX79_MMI2_PDIVBW:    /* TODO: TX79_MMI2_PDIVBW */
26044     case TX79_MMI2_PEXEW:     /* TODO: TX79_MMI2_PEXEW */
26045     case TX79_MMI2_PROT3W:    /* TODO: TX79_MMI2_PROT3W */
26046         generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_MMI_CLASS_MMI2 */
26047         break;
26048     default:
26049         MIPS_INVAL("TX79 MMI class MMI2");
26050         generate_exception_end(ctx, EXCP_RI);
26051         break;
26052     }
26053 }
26054
26055 static void decode_tx79_mmi3(CPUMIPSState *env, DisasContext *ctx)
26056 {
26057     uint32_t opc = MASK_TX79_MMI3(ctx->opcode);
26058
26059     switch (opc) {
26060     case TX79_MMI3_PMADDUW:    /* TODO: TX79_MMI3_PMADDUW */
26061     case TX79_MMI3_PSRAVW:     /* TODO: TX79_MMI3_PSRAVW */
26062     case TX79_MMI3_PMTHI:      /* TODO: TX79_MMI3_PMTHI */
26063     case TX79_MMI3_PMTLO:      /* TODO: TX79_MMI3_PMTLO */
26064     case TX79_MMI3_PINTEH:     /* TODO: TX79_MMI3_PINTEH */
26065     case TX79_MMI3_PMULTUW:    /* TODO: TX79_MMI3_PMULTUW */
26066     case TX79_MMI3_PDIVUW:     /* TODO: TX79_MMI3_PDIVUW */
26067     case TX79_MMI3_PCPYUD:     /* TODO: TX79_MMI3_PCPYUD */
26068     case TX79_MMI3_POR:        /* TODO: TX79_MMI3_POR */
26069     case TX79_MMI3_PNOR:       /* TODO: TX79_MMI3_PNOR */
26070     case TX79_MMI3_PEXCH:      /* TODO: TX79_MMI3_PEXCH */
26071     case TX79_MMI3_PCPYH:      /* TODO: TX79_MMI3_PCPYH */
26072     case TX79_MMI3_PEXCW:      /* TODO: TX79_MMI3_PEXCW */
26073         generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_MMI_CLASS_MMI3 */
26074         break;
26075     default:
26076         MIPS_INVAL("TX79 MMI class MMI3");
26077         generate_exception_end(ctx, EXCP_RI);
26078         break;
26079     }
26080 }
26081
26082 static void decode_tx79_mmi(CPUMIPSState *env, DisasContext *ctx)
26083 {
26084     uint32_t opc = MASK_TX79_MMI(ctx->opcode);
26085     int rs = extract32(ctx->opcode, 21, 5);
26086     int rt = extract32(ctx->opcode, 16, 5);
26087     int rd = extract32(ctx->opcode, 11, 5);
26088
26089     switch (opc) {
26090     case TX79_MMI_CLASS_MMI0:
26091         decode_tx79_mmi0(env, ctx);
26092         break;
26093     case TX79_MMI_CLASS_MMI1:
26094         decode_tx79_mmi1(env, ctx);
26095         break;
26096     case TX79_MMI_CLASS_MMI2:
26097         decode_tx79_mmi2(env, ctx);
26098         break;
26099     case TX79_MMI_CLASS_MMI3:
26100         decode_tx79_mmi3(env, ctx);
26101         break;
26102     case TX79_MMI_MULT1:
26103     case TX79_MMI_MULTU1:
26104         gen_mul_txx9(ctx, opc, rd, rs, rt);
26105         break;
26106     case TX79_MMI_DIV1:
26107     case TX79_MMI_DIVU1:
26108         gen_muldiv(ctx, opc, 1, rs, rt);
26109         break;
26110     case TX79_MMI_MTLO1:
26111     case TX79_MMI_MTHI1:
26112         gen_HILO(ctx, opc, 1, rs);
26113         break;
26114     case TX79_MMI_MFLO1:
26115     case TX79_MMI_MFHI1:
26116         gen_HILO(ctx, opc, 1, rd);
26117         break;
26118     case TX79_MMI_MADD:          /* TODO: TX79_MMI_MADD */
26119     case TX79_MMI_MADDU:         /* TODO: TX79_MMI_MADDU */
26120     case TX79_MMI_PLZCW:         /* TODO: TX79_MMI_PLZCW */
26121     case TX79_MMI_MADD1:         /* TODO: TX79_MMI_MADD1 */
26122     case TX79_MMI_MADDU1:        /* TODO: TX79_MMI_MADDU1 */
26123     case TX79_MMI_PMFHL:         /* TODO: TX79_MMI_PMFHL */
26124     case TX79_MMI_PMTHL:         /* TODO: TX79_MMI_PMTHL */
26125     case TX79_MMI_PSLLH:         /* TODO: TX79_MMI_PSLLH */
26126     case TX79_MMI_PSRLH:         /* TODO: TX79_MMI_PSRLH */
26127     case TX79_MMI_PSRAH:         /* TODO: TX79_MMI_PSRAH */
26128     case TX79_MMI_PSLLW:         /* TODO: TX79_MMI_PSLLW */
26129     case TX79_MMI_PSRLW:         /* TODO: TX79_MMI_PSRLW */
26130     case TX79_MMI_PSRAW:         /* TODO: TX79_MMI_PSRAW */
26131         generate_exception_end(ctx, EXCP_RI);    /* TODO: TX79_CLASS_MMI */
26132         break;
26133     default:
26134         MIPS_INVAL("TX79 MMI class");
26135         generate_exception_end(ctx, EXCP_RI);
26136         break;
26137     }
26138 }
26139
26140 static void decode_tx79_lq(CPUMIPSState *env, DisasContext *ctx)
26141 {
26142     generate_exception_end(ctx, EXCP_RI);    /* TODO: TX79_LQ */
26143 }
26144
26145 static void gen_tx79_sq(DisasContext *ctx, int base, int rt, int offset)
26146 {
26147     generate_exception_end(ctx, EXCP_RI);    /* TODO: TX79_SQ */
26148 }
26149
26150 /*
26151  * The TX79-specific instruction Store Quadword
26152  *
26153  * +--------+-------+-------+------------------------+
26154  * | 011111 |  base |   rt  |           offset       | SQ
26155  * +--------+-------+-------+------------------------+
26156  *      6       5       5                 16
26157  *
26158  * has the same opcode as the Read Hardware Register instruction
26159  *
26160  * +--------+-------+-------+-------+-------+--------+
26161  * | 011111 | 00000 |   rt  |   rd  | 00000 | 111011 | RDHWR
26162  * +--------+-------+-------+-------+-------+--------+
26163  *      6       5       5       5       5        6
26164  *
26165  * that is required, trapped and emulated by the Linux kernel. However, all
26166  * RDHWR encodings yield address error exceptions on the TX79 since the SQ
26167  * offset is odd. Therefore all valid SQ instructions can execute normally.
26168  * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
26169  * between SQ and RDHWR, as the Linux kernel does.
26170  */
26171 static void decode_tx79_sq(CPUMIPSState *env, DisasContext *ctx)
26172 {
26173     int base = extract32(ctx->opcode, 21, 5);
26174     int rt = extract32(ctx->opcode, 16, 5);
26175     int offset = extract32(ctx->opcode, 0, 16);
26176
26177 #ifdef CONFIG_USER_ONLY
26178     uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
26179     uint32_t op2 = extract32(ctx->opcode, 6, 5);
26180
26181     if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
26182         int rd = extract32(ctx->opcode, 11, 5);
26183
26184         gen_rdhwr(ctx, rt, rd, 0);
26185         return;
26186     }
26187 #endif
26188
26189     gen_tx79_sq(ctx, base, rt, offset);
26190 }
26191
26192 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
26193 {
26194     int rs, rt, rd, sa;
26195     uint32_t op1, op2;
26196     int16_t imm;
26197
26198     rs = (ctx->opcode >> 21) & 0x1f;
26199     rt = (ctx->opcode >> 16) & 0x1f;
26200     rd = (ctx->opcode >> 11) & 0x1f;
26201     sa = (ctx->opcode >> 6) & 0x1f;
26202     imm = sextract32(ctx->opcode, 7, 9);
26203
26204     op1 = MASK_SPECIAL3(ctx->opcode);
26205
26206     /*
26207      * EVA loads and stores overlap Loongson 2E instructions decoded by
26208      * decode_opc_special3_legacy(), so be careful to allow their decoding when
26209      * EVA is absent.
26210      */
26211     if (ctx->eva) {
26212         switch (op1) {
26213         case OPC_LWLE:
26214         case OPC_LWRE:
26215             check_insn_opc_removed(ctx, ISA_MIPS32R6);
26216             /* fall through */
26217         case OPC_LBUE:
26218         case OPC_LHUE:
26219         case OPC_LBE:
26220         case OPC_LHE:
26221         case OPC_LLE:
26222         case OPC_LWE:
26223             check_cp0_enabled(ctx);
26224             gen_ld(ctx, op1, rt, rs, imm);
26225             return;
26226         case OPC_SWLE:
26227         case OPC_SWRE:
26228             check_insn_opc_removed(ctx, ISA_MIPS32R6);
26229             /* fall through */
26230         case OPC_SBE:
26231         case OPC_SHE:
26232         case OPC_SWE:
26233             check_cp0_enabled(ctx);
26234             gen_st(ctx, op1, rt, rs, imm);
26235             return;
26236         case OPC_SCE:
26237             check_cp0_enabled(ctx);
26238             gen_st_cond(ctx, op1, rt, rs, imm);
26239             return;
26240         case OPC_CACHEE:
26241             check_cp0_enabled(ctx);
26242             if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
26243                 gen_cache_operation(ctx, rt, rs, imm);
26244             }
26245             /* Treat as NOP. */
26246             return;
26247         case OPC_PREFE:
26248             check_cp0_enabled(ctx);
26249             /* Treat as NOP. */
26250             return;
26251         }
26252     }
26253
26254     switch (op1) {
26255     case OPC_EXT:
26256     case OPC_INS:
26257         check_insn(ctx, ISA_MIPS32R2);
26258         gen_bitops(ctx, op1, rt, rs, sa, rd);
26259         break;
26260     case OPC_BSHFL:
26261         op2 = MASK_BSHFL(ctx->opcode);
26262         switch (op2) {
26263         case OPC_ALIGN:
26264         case OPC_ALIGN_1:
26265         case OPC_ALIGN_2:
26266         case OPC_ALIGN_3:
26267         case OPC_BITSWAP:
26268             check_insn(ctx, ISA_MIPS32R6);
26269             decode_opc_special3_r6(env, ctx);
26270             break;
26271         default:
26272             check_insn(ctx, ISA_MIPS32R2);
26273             gen_bshfl(ctx, op2, rt, rd);
26274             break;
26275         }
26276         break;
26277 #if defined(TARGET_MIPS64)
26278     case OPC_DEXTM:
26279     case OPC_DEXTU:
26280     case OPC_DEXT:
26281     case OPC_DINSM:
26282     case OPC_DINSU:
26283     case OPC_DINS:
26284         check_insn(ctx, ISA_MIPS64R2);
26285         check_mips_64(ctx);
26286         gen_bitops(ctx, op1, rt, rs, sa, rd);
26287         break;
26288     case OPC_DBSHFL:
26289         op2 = MASK_DBSHFL(ctx->opcode);
26290         switch (op2) {
26291         case OPC_DALIGN:
26292         case OPC_DALIGN_1:
26293         case OPC_DALIGN_2:
26294         case OPC_DALIGN_3:
26295         case OPC_DALIGN_4:
26296         case OPC_DALIGN_5:
26297         case OPC_DALIGN_6:
26298         case OPC_DALIGN_7:
26299         case OPC_DBITSWAP:
26300             check_insn(ctx, ISA_MIPS32R6);
26301             decode_opc_special3_r6(env, ctx);
26302             break;
26303         default:
26304             check_insn(ctx, ISA_MIPS64R2);
26305             check_mips_64(ctx);
26306             op2 = MASK_DBSHFL(ctx->opcode);
26307             gen_bshfl(ctx, op2, rt, rd);
26308             break;
26309         }
26310         break;
26311 #endif
26312     case OPC_RDHWR:
26313         gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
26314         break;
26315     case OPC_FORK:
26316         check_mt(ctx);
26317         {
26318             TCGv t0 = tcg_temp_new();
26319             TCGv t1 = tcg_temp_new();
26320
26321             gen_load_gpr(t0, rt);
26322             gen_load_gpr(t1, rs);
26323             gen_helper_fork(t0, t1);
26324             tcg_temp_free(t0);
26325             tcg_temp_free(t1);
26326         }
26327         break;
26328     case OPC_YIELD:
26329         check_mt(ctx);
26330         {
26331             TCGv t0 = tcg_temp_new();
26332
26333             gen_load_gpr(t0, rs);
26334             gen_helper_yield(t0, cpu_env, t0);
26335             gen_store_gpr(t0, rd);
26336             tcg_temp_free(t0);
26337         }
26338         break;
26339     default:
26340         if (ctx->insn_flags & ISA_MIPS32R6) {
26341             decode_opc_special3_r6(env, ctx);
26342         } else {
26343             decode_opc_special3_legacy(env, ctx);
26344         }
26345     }
26346 }
26347
26348 /* MIPS SIMD Architecture (MSA)  */
26349 static inline int check_msa_access(DisasContext *ctx)
26350 {
26351     if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
26352                  !(ctx->hflags & MIPS_HFLAG_F64))) {
26353         generate_exception_end(ctx, EXCP_RI);
26354         return 0;
26355     }
26356
26357     if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
26358         if (ctx->insn_flags & ASE_MSA) {
26359             generate_exception_end(ctx, EXCP_MSADIS);
26360             return 0;
26361         } else {
26362             generate_exception_end(ctx, EXCP_RI);
26363             return 0;
26364         }
26365     }
26366     return 1;
26367 }
26368
26369 static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
26370 {
26371     /* generates tcg ops to check if any element is 0 */
26372     /* Note this function only works with MSA_WRLEN = 128 */
26373     uint64_t eval_zero_or_big = 0;
26374     uint64_t eval_big = 0;
26375     TCGv_i64 t0 = tcg_temp_new_i64();
26376     TCGv_i64 t1 = tcg_temp_new_i64();
26377     switch (df) {
26378     case DF_BYTE:
26379         eval_zero_or_big = 0x0101010101010101ULL;
26380         eval_big = 0x8080808080808080ULL;
26381         break;
26382     case DF_HALF:
26383         eval_zero_or_big = 0x0001000100010001ULL;
26384         eval_big = 0x8000800080008000ULL;
26385         break;
26386     case DF_WORD:
26387         eval_zero_or_big = 0x0000000100000001ULL;
26388         eval_big = 0x8000000080000000ULL;
26389         break;
26390     case DF_DOUBLE:
26391         eval_zero_or_big = 0x0000000000000001ULL;
26392         eval_big = 0x8000000000000000ULL;
26393         break;
26394     }
26395     tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
26396     tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
26397     tcg_gen_andi_i64(t0, t0, eval_big);
26398     tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
26399     tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
26400     tcg_gen_andi_i64(t1, t1, eval_big);
26401     tcg_gen_or_i64(t0, t0, t1);
26402     /* if all bits are zero then all elements are not zero */
26403     /* if some bit is non-zero then some element is zero */
26404     tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
26405     tcg_gen_trunc_i64_tl(tresult, t0);
26406     tcg_temp_free_i64(t0);
26407     tcg_temp_free_i64(t1);
26408 }
26409
26410 static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
26411 {
26412     uint8_t df = (ctx->opcode >> 21) & 0x3;
26413     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
26414     int64_t s16 = (int16_t)ctx->opcode;
26415
26416     check_msa_access(ctx);
26417
26418     if (ctx->hflags & MIPS_HFLAG_BMASK) {
26419         generate_exception_end(ctx, EXCP_RI);
26420         return;
26421     }
26422     switch (op1) {
26423     case OPC_BZ_V:
26424     case OPC_BNZ_V:
26425         {
26426             TCGv_i64 t0 = tcg_temp_new_i64();
26427             tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
26428             tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
26429                     TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
26430             tcg_gen_trunc_i64_tl(bcond, t0);
26431             tcg_temp_free_i64(t0);
26432         }
26433         break;
26434     case OPC_BZ_B:
26435     case OPC_BZ_H:
26436     case OPC_BZ_W:
26437     case OPC_BZ_D:
26438         gen_check_zero_element(bcond, df, wt);
26439         break;
26440     case OPC_BNZ_B:
26441     case OPC_BNZ_H:
26442     case OPC_BNZ_W:
26443     case OPC_BNZ_D:
26444         gen_check_zero_element(bcond, df, wt);
26445         tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
26446         break;
26447     }
26448
26449     ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
26450
26451     ctx->hflags |= MIPS_HFLAG_BC;
26452     ctx->hflags |= MIPS_HFLAG_BDS32;
26453 }
26454
26455 static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
26456 {
26457 #define MASK_MSA_I8(op)    (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
26458     uint8_t i8 = (ctx->opcode >> 16) & 0xff;
26459     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
26460     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
26461
26462     TCGv_i32 twd = tcg_const_i32(wd);
26463     TCGv_i32 tws = tcg_const_i32(ws);
26464     TCGv_i32 ti8 = tcg_const_i32(i8);
26465
26466     switch (MASK_MSA_I8(ctx->opcode)) {
26467     case OPC_ANDI_B:
26468         gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
26469         break;
26470     case OPC_ORI_B:
26471         gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
26472         break;
26473     case OPC_NORI_B:
26474         gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
26475         break;
26476     case OPC_XORI_B:
26477         gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
26478         break;
26479     case OPC_BMNZI_B:
26480         gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
26481         break;
26482     case OPC_BMZI_B:
26483         gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
26484         break;
26485     case OPC_BSELI_B:
26486         gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
26487         break;
26488     case OPC_SHF_B:
26489     case OPC_SHF_H:
26490     case OPC_SHF_W:
26491         {
26492             uint8_t df = (ctx->opcode >> 24) & 0x3;
26493             if (df == DF_DOUBLE) {
26494                 generate_exception_end(ctx, EXCP_RI);
26495             } else {
26496                 TCGv_i32 tdf = tcg_const_i32(df);
26497                 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
26498                 tcg_temp_free_i32(tdf);
26499             }
26500         }
26501         break;
26502     default:
26503         MIPS_INVAL("MSA instruction");
26504         generate_exception_end(ctx, EXCP_RI);
26505         break;
26506     }
26507
26508     tcg_temp_free_i32(twd);
26509     tcg_temp_free_i32(tws);
26510     tcg_temp_free_i32(ti8);
26511 }
26512
26513 static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
26514 {
26515 #define MASK_MSA_I5(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
26516     uint8_t df = (ctx->opcode >> 21) & 0x3;
26517     int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
26518     uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
26519     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
26520     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
26521
26522     TCGv_i32 tdf = tcg_const_i32(df);
26523     TCGv_i32 twd = tcg_const_i32(wd);
26524     TCGv_i32 tws = tcg_const_i32(ws);
26525     TCGv_i32 timm = tcg_temp_new_i32();
26526     tcg_gen_movi_i32(timm, u5);
26527
26528     switch (MASK_MSA_I5(ctx->opcode)) {
26529     case OPC_ADDVI_df:
26530         gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
26531         break;
26532     case OPC_SUBVI_df:
26533         gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
26534         break;
26535     case OPC_MAXI_S_df:
26536         tcg_gen_movi_i32(timm, s5);
26537         gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
26538         break;
26539     case OPC_MAXI_U_df:
26540         gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
26541         break;
26542     case OPC_MINI_S_df:
26543         tcg_gen_movi_i32(timm, s5);
26544         gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
26545         break;
26546     case OPC_MINI_U_df:
26547         gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
26548         break;
26549     case OPC_CEQI_df:
26550         tcg_gen_movi_i32(timm, s5);
26551         gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
26552         break;
26553     case OPC_CLTI_S_df:
26554         tcg_gen_movi_i32(timm, s5);
26555         gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
26556         break;
26557     case OPC_CLTI_U_df:
26558         gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
26559         break;
26560     case OPC_CLEI_S_df:
26561         tcg_gen_movi_i32(timm, s5);
26562         gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
26563         break;
26564     case OPC_CLEI_U_df:
26565         gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
26566         break;
26567     case OPC_LDI_df:
26568         {
26569             int32_t s10 = sextract32(ctx->opcode, 11, 10);
26570             tcg_gen_movi_i32(timm, s10);
26571             gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
26572         }
26573         break;
26574     default:
26575         MIPS_INVAL("MSA instruction");
26576         generate_exception_end(ctx, EXCP_RI);
26577         break;
26578     }
26579
26580     tcg_temp_free_i32(tdf);
26581     tcg_temp_free_i32(twd);
26582     tcg_temp_free_i32(tws);
26583     tcg_temp_free_i32(timm);
26584 }
26585
26586 static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
26587 {
26588 #define MASK_MSA_BIT(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
26589     uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
26590     uint32_t df = 0, m = 0;
26591     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
26592     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
26593
26594     TCGv_i32 tdf;
26595     TCGv_i32 tm;
26596     TCGv_i32 twd;
26597     TCGv_i32 tws;
26598
26599     if ((dfm & 0x40) == 0x00) {
26600         m = dfm & 0x3f;
26601         df = DF_DOUBLE;
26602     } else if ((dfm & 0x60) == 0x40) {
26603         m = dfm & 0x1f;
26604         df = DF_WORD;
26605     } else if ((dfm & 0x70) == 0x60) {
26606         m = dfm & 0x0f;
26607         df = DF_HALF;
26608     } else if ((dfm & 0x78) == 0x70) {
26609         m = dfm & 0x7;
26610         df = DF_BYTE;
26611     } else {
26612         generate_exception_end(ctx, EXCP_RI);
26613         return;
26614     }
26615
26616     tdf = tcg_const_i32(df);
26617     tm  = tcg_const_i32(m);
26618     twd = tcg_const_i32(wd);
26619     tws = tcg_const_i32(ws);
26620
26621     switch (MASK_MSA_BIT(ctx->opcode)) {
26622     case OPC_SLLI_df:
26623         gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
26624         break;
26625     case OPC_SRAI_df:
26626         gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
26627         break;
26628     case OPC_SRLI_df:
26629         gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
26630         break;
26631     case OPC_BCLRI_df:
26632         gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
26633         break;
26634     case OPC_BSETI_df:
26635         gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
26636         break;
26637     case OPC_BNEGI_df:
26638         gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
26639         break;
26640     case OPC_BINSLI_df:
26641         gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
26642         break;
26643     case OPC_BINSRI_df:
26644         gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
26645         break;
26646     case OPC_SAT_S_df:
26647         gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
26648         break;
26649     case OPC_SAT_U_df:
26650         gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
26651         break;
26652     case OPC_SRARI_df:
26653         gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
26654         break;
26655     case OPC_SRLRI_df:
26656         gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
26657         break;
26658     default:
26659         MIPS_INVAL("MSA instruction");
26660         generate_exception_end(ctx, EXCP_RI);
26661         break;
26662     }
26663
26664     tcg_temp_free_i32(tdf);
26665     tcg_temp_free_i32(tm);
26666     tcg_temp_free_i32(twd);
26667     tcg_temp_free_i32(tws);
26668 }
26669
26670 static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
26671 {
26672 #define MASK_MSA_3R(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
26673     uint8_t df = (ctx->opcode >> 21) & 0x3;
26674     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
26675     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
26676     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
26677
26678     TCGv_i32 tdf = tcg_const_i32(df);
26679     TCGv_i32 twd = tcg_const_i32(wd);
26680     TCGv_i32 tws = tcg_const_i32(ws);
26681     TCGv_i32 twt = tcg_const_i32(wt);
26682
26683     switch (MASK_MSA_3R(ctx->opcode)) {
26684     case OPC_SLL_df:
26685         gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
26686         break;
26687     case OPC_ADDV_df:
26688         gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
26689         break;
26690     case OPC_CEQ_df:
26691         gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
26692         break;
26693     case OPC_ADD_A_df:
26694         gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
26695         break;
26696     case OPC_SUBS_S_df:
26697         gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
26698         break;
26699     case OPC_MULV_df:
26700         gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
26701         break;
26702     case OPC_SLD_df:
26703         gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
26704         break;
26705     case OPC_VSHF_df:
26706         gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
26707         break;
26708     case OPC_SRA_df:
26709         gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
26710         break;
26711     case OPC_SUBV_df:
26712         gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
26713         break;
26714     case OPC_ADDS_A_df:
26715         gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
26716         break;
26717     case OPC_SUBS_U_df:
26718         gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
26719         break;
26720     case OPC_MADDV_df:
26721         gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
26722         break;
26723     case OPC_SPLAT_df:
26724         gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
26725         break;
26726     case OPC_SRAR_df:
26727         gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
26728         break;
26729     case OPC_SRL_df:
26730         gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
26731         break;
26732     case OPC_MAX_S_df:
26733         gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
26734         break;
26735     case OPC_CLT_S_df:
26736         gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
26737         break;
26738     case OPC_ADDS_S_df:
26739         gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
26740         break;
26741     case OPC_SUBSUS_U_df:
26742         gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
26743         break;
26744     case OPC_MSUBV_df:
26745         gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
26746         break;
26747     case OPC_PCKEV_df:
26748         gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
26749         break;
26750     case OPC_SRLR_df:
26751         gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
26752         break;
26753     case OPC_BCLR_df:
26754         gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
26755         break;
26756     case OPC_MAX_U_df:
26757         gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
26758         break;
26759     case OPC_CLT_U_df:
26760         gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
26761         break;
26762     case OPC_ADDS_U_df:
26763         gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
26764         break;
26765     case OPC_SUBSUU_S_df:
26766         gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
26767         break;
26768     case OPC_PCKOD_df:
26769         gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
26770         break;
26771     case OPC_BSET_df:
26772         gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
26773         break;
26774     case OPC_MIN_S_df:
26775         gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
26776         break;
26777     case OPC_CLE_S_df:
26778         gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
26779         break;
26780     case OPC_AVE_S_df:
26781         gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
26782         break;
26783     case OPC_ASUB_S_df:
26784         gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
26785         break;
26786     case OPC_DIV_S_df:
26787         gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
26788         break;
26789     case OPC_ILVL_df:
26790         gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
26791         break;
26792     case OPC_BNEG_df:
26793         gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
26794         break;
26795     case OPC_MIN_U_df:
26796         gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
26797         break;
26798     case OPC_CLE_U_df:
26799         gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
26800         break;
26801     case OPC_AVE_U_df:
26802         gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
26803         break;
26804     case OPC_ASUB_U_df:
26805         gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
26806         break;
26807     case OPC_DIV_U_df:
26808         gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
26809         break;
26810     case OPC_ILVR_df:
26811         gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
26812         break;
26813     case OPC_BINSL_df:
26814         gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
26815         break;
26816     case OPC_MAX_A_df:
26817         gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
26818         break;
26819     case OPC_AVER_S_df:
26820         gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
26821         break;
26822     case OPC_MOD_S_df:
26823         gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
26824         break;
26825     case OPC_ILVEV_df:
26826         gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
26827         break;
26828     case OPC_BINSR_df:
26829         gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
26830         break;
26831     case OPC_MIN_A_df:
26832         gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
26833         break;
26834     case OPC_AVER_U_df:
26835         gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
26836         break;
26837     case OPC_MOD_U_df:
26838         gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
26839         break;
26840     case OPC_ILVOD_df:
26841         gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
26842         break;
26843
26844     case OPC_DOTP_S_df:
26845     case OPC_DOTP_U_df:
26846     case OPC_DPADD_S_df:
26847     case OPC_DPADD_U_df:
26848     case OPC_DPSUB_S_df:
26849     case OPC_HADD_S_df:
26850     case OPC_DPSUB_U_df:
26851     case OPC_HADD_U_df:
26852     case OPC_HSUB_S_df:
26853     case OPC_HSUB_U_df:
26854         if (df == DF_BYTE) {
26855             generate_exception_end(ctx, EXCP_RI);
26856             break;
26857         }
26858         switch (MASK_MSA_3R(ctx->opcode)) {
26859         case OPC_DOTP_S_df:
26860             gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
26861             break;
26862         case OPC_DOTP_U_df:
26863             gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
26864             break;
26865         case OPC_DPADD_S_df:
26866             gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
26867             break;
26868         case OPC_DPADD_U_df:
26869             gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
26870             break;
26871         case OPC_DPSUB_S_df:
26872             gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
26873             break;
26874         case OPC_HADD_S_df:
26875             gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
26876             break;
26877         case OPC_DPSUB_U_df:
26878             gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
26879             break;
26880         case OPC_HADD_U_df:
26881             gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
26882             break;
26883         case OPC_HSUB_S_df:
26884             gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
26885             break;
26886         case OPC_HSUB_U_df:
26887             gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
26888             break;
26889         }
26890         break;
26891     default:
26892         MIPS_INVAL("MSA instruction");
26893         generate_exception_end(ctx, EXCP_RI);
26894         break;
26895     }
26896     tcg_temp_free_i32(twd);
26897     tcg_temp_free_i32(tws);
26898     tcg_temp_free_i32(twt);
26899     tcg_temp_free_i32(tdf);
26900 }
26901
26902 static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
26903 {
26904 #define MASK_MSA_ELM_DF3E(op)   (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
26905     uint8_t source = (ctx->opcode >> 11) & 0x1f;
26906     uint8_t dest = (ctx->opcode >> 6) & 0x1f;
26907     TCGv telm = tcg_temp_new();
26908     TCGv_i32 tsr = tcg_const_i32(source);
26909     TCGv_i32 tdt = tcg_const_i32(dest);
26910
26911     switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
26912     case OPC_CTCMSA:
26913         gen_load_gpr(telm, source);
26914         gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
26915         break;
26916     case OPC_CFCMSA:
26917         gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
26918         gen_store_gpr(telm, dest);
26919         break;
26920     case OPC_MOVE_V:
26921         gen_helper_msa_move_v(cpu_env, tdt, tsr);
26922         break;
26923     default:
26924         MIPS_INVAL("MSA instruction");
26925         generate_exception_end(ctx, EXCP_RI);
26926         break;
26927     }
26928
26929     tcg_temp_free(telm);
26930     tcg_temp_free_i32(tdt);
26931     tcg_temp_free_i32(tsr);
26932 }
26933
26934 static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
26935         uint32_t n)
26936 {
26937 #define MASK_MSA_ELM(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
26938     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
26939     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
26940
26941     TCGv_i32 tws = tcg_const_i32(ws);
26942     TCGv_i32 twd = tcg_const_i32(wd);
26943     TCGv_i32 tn  = tcg_const_i32(n);
26944     TCGv_i32 tdf = tcg_const_i32(df);
26945
26946     switch (MASK_MSA_ELM(ctx->opcode)) {
26947     case OPC_SLDI_df:
26948         gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
26949         break;
26950     case OPC_SPLATI_df:
26951         gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
26952         break;
26953     case OPC_INSVE_df:
26954         gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
26955         break;
26956     case OPC_COPY_S_df:
26957     case OPC_COPY_U_df:
26958     case OPC_INSERT_df:
26959 #if !defined(TARGET_MIPS64)
26960         /* Double format valid only for MIPS64 */
26961         if (df == DF_DOUBLE) {
26962             generate_exception_end(ctx, EXCP_RI);
26963             break;
26964         }
26965 #endif
26966         switch (MASK_MSA_ELM(ctx->opcode)) {
26967         case OPC_COPY_S_df:
26968             if (likely(wd != 0)) {
26969                 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
26970             }
26971             break;
26972         case OPC_COPY_U_df:
26973             if (likely(wd != 0)) {
26974                 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
26975             }
26976             break;
26977         case OPC_INSERT_df:
26978             gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
26979             break;
26980         }
26981         break;
26982     default:
26983         MIPS_INVAL("MSA instruction");
26984         generate_exception_end(ctx, EXCP_RI);
26985     }
26986     tcg_temp_free_i32(twd);
26987     tcg_temp_free_i32(tws);
26988     tcg_temp_free_i32(tn);
26989     tcg_temp_free_i32(tdf);
26990 }
26991
26992 static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
26993 {
26994     uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
26995     uint32_t df = 0, n = 0;
26996
26997     if ((dfn & 0x30) == 0x00) {
26998         n = dfn & 0x0f;
26999         df = DF_BYTE;
27000     } else if ((dfn & 0x38) == 0x20) {
27001         n = dfn & 0x07;
27002         df = DF_HALF;
27003     } else if ((dfn & 0x3c) == 0x30) {
27004         n = dfn & 0x03;
27005         df = DF_WORD;
27006     } else if ((dfn & 0x3e) == 0x38) {
27007         n = dfn & 0x01;
27008         df = DF_DOUBLE;
27009     } else if (dfn == 0x3E) {
27010         /* CTCMSA, CFCMSA, MOVE.V */
27011         gen_msa_elm_3e(env, ctx);
27012         return;
27013     } else {
27014         generate_exception_end(ctx, EXCP_RI);
27015         return;
27016     }
27017
27018     gen_msa_elm_df(env, ctx, df, n);
27019 }
27020
27021 static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
27022 {
27023 #define MASK_MSA_3RF(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
27024     uint8_t df = (ctx->opcode >> 21) & 0x1;
27025     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
27026     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27027     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27028
27029     TCGv_i32 twd = tcg_const_i32(wd);
27030     TCGv_i32 tws = tcg_const_i32(ws);
27031     TCGv_i32 twt = tcg_const_i32(wt);
27032     TCGv_i32 tdf = tcg_temp_new_i32();
27033
27034     /* adjust df value for floating-point instruction */
27035     tcg_gen_movi_i32(tdf, df + 2);
27036
27037     switch (MASK_MSA_3RF(ctx->opcode)) {
27038     case OPC_FCAF_df:
27039         gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
27040         break;
27041     case OPC_FADD_df:
27042         gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
27043         break;
27044     case OPC_FCUN_df:
27045         gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
27046         break;
27047     case OPC_FSUB_df:
27048         gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
27049         break;
27050     case OPC_FCOR_df:
27051         gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
27052         break;
27053     case OPC_FCEQ_df:
27054         gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
27055         break;
27056     case OPC_FMUL_df:
27057         gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
27058         break;
27059     case OPC_FCUNE_df:
27060         gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
27061         break;
27062     case OPC_FCUEQ_df:
27063         gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
27064         break;
27065     case OPC_FDIV_df:
27066         gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
27067         break;
27068     case OPC_FCNE_df:
27069         gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
27070         break;
27071     case OPC_FCLT_df:
27072         gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
27073         break;
27074     case OPC_FMADD_df:
27075         gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
27076         break;
27077     case OPC_MUL_Q_df:
27078         tcg_gen_movi_i32(tdf, df + 1);
27079         gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
27080         break;
27081     case OPC_FCULT_df:
27082         gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
27083         break;
27084     case OPC_FMSUB_df:
27085         gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
27086         break;
27087     case OPC_MADD_Q_df:
27088         tcg_gen_movi_i32(tdf, df + 1);
27089         gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
27090         break;
27091     case OPC_FCLE_df:
27092         gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
27093         break;
27094     case OPC_MSUB_Q_df:
27095         tcg_gen_movi_i32(tdf, df + 1);
27096         gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
27097         break;
27098     case OPC_FCULE_df:
27099         gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
27100         break;
27101     case OPC_FEXP2_df:
27102         gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
27103         break;
27104     case OPC_FSAF_df:
27105         gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
27106         break;
27107     case OPC_FEXDO_df:
27108         gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
27109         break;
27110     case OPC_FSUN_df:
27111         gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
27112         break;
27113     case OPC_FSOR_df:
27114         gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
27115         break;
27116     case OPC_FSEQ_df:
27117         gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
27118         break;
27119     case OPC_FTQ_df:
27120         gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
27121         break;
27122     case OPC_FSUNE_df:
27123         gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
27124         break;
27125     case OPC_FSUEQ_df:
27126         gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
27127         break;
27128     case OPC_FSNE_df:
27129         gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
27130         break;
27131     case OPC_FSLT_df:
27132         gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
27133         break;
27134     case OPC_FMIN_df:
27135         gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
27136         break;
27137     case OPC_MULR_Q_df:
27138         tcg_gen_movi_i32(tdf, df + 1);
27139         gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
27140         break;
27141     case OPC_FSULT_df:
27142         gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
27143         break;
27144     case OPC_FMIN_A_df:
27145         gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
27146         break;
27147     case OPC_MADDR_Q_df:
27148         tcg_gen_movi_i32(tdf, df + 1);
27149         gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
27150         break;
27151     case OPC_FSLE_df:
27152         gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
27153         break;
27154     case OPC_FMAX_df:
27155         gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
27156         break;
27157     case OPC_MSUBR_Q_df:
27158         tcg_gen_movi_i32(tdf, df + 1);
27159         gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
27160         break;
27161     case OPC_FSULE_df:
27162         gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
27163         break;
27164     case OPC_FMAX_A_df:
27165         gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
27166         break;
27167     default:
27168         MIPS_INVAL("MSA instruction");
27169         generate_exception_end(ctx, EXCP_RI);
27170         break;
27171     }
27172
27173     tcg_temp_free_i32(twd);
27174     tcg_temp_free_i32(tws);
27175     tcg_temp_free_i32(twt);
27176     tcg_temp_free_i32(tdf);
27177 }
27178
27179 static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
27180 {
27181 #define MASK_MSA_2R(op)     (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
27182                             (op & (0x7 << 18)))
27183     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
27184     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27185     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27186     uint8_t df = (ctx->opcode >> 16) & 0x3;
27187     TCGv_i32 twd = tcg_const_i32(wd);
27188     TCGv_i32 tws = tcg_const_i32(ws);
27189     TCGv_i32 twt = tcg_const_i32(wt);
27190     TCGv_i32 tdf = tcg_const_i32(df);
27191
27192     switch (MASK_MSA_2R(ctx->opcode)) {
27193     case OPC_FILL_df:
27194 #if !defined(TARGET_MIPS64)
27195         /* Double format valid only for MIPS64 */
27196         if (df == DF_DOUBLE) {
27197             generate_exception_end(ctx, EXCP_RI);
27198             break;
27199         }
27200 #endif
27201         gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
27202         break;
27203     case OPC_PCNT_df:
27204         gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
27205         break;
27206     case OPC_NLOC_df:
27207         gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
27208         break;
27209     case OPC_NLZC_df:
27210         gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
27211         break;
27212     default:
27213         MIPS_INVAL("MSA instruction");
27214         generate_exception_end(ctx, EXCP_RI);
27215         break;
27216     }
27217
27218     tcg_temp_free_i32(twd);
27219     tcg_temp_free_i32(tws);
27220     tcg_temp_free_i32(twt);
27221     tcg_temp_free_i32(tdf);
27222 }
27223
27224 static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
27225 {
27226 #define MASK_MSA_2RF(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
27227                             (op & (0xf << 17)))
27228     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
27229     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27230     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27231     uint8_t df = (ctx->opcode >> 16) & 0x1;
27232     TCGv_i32 twd = tcg_const_i32(wd);
27233     TCGv_i32 tws = tcg_const_i32(ws);
27234     TCGv_i32 twt = tcg_const_i32(wt);
27235     /* adjust df value for floating-point instruction */
27236     TCGv_i32 tdf = tcg_const_i32(df + 2);
27237
27238     switch (MASK_MSA_2RF(ctx->opcode)) {
27239     case OPC_FCLASS_df:
27240         gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
27241         break;
27242     case OPC_FTRUNC_S_df:
27243         gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
27244         break;
27245     case OPC_FTRUNC_U_df:
27246         gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
27247         break;
27248     case OPC_FSQRT_df:
27249         gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
27250         break;
27251     case OPC_FRSQRT_df:
27252         gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
27253         break;
27254     case OPC_FRCP_df:
27255         gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
27256         break;
27257     case OPC_FRINT_df:
27258         gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
27259         break;
27260     case OPC_FLOG2_df:
27261         gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
27262         break;
27263     case OPC_FEXUPL_df:
27264         gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
27265         break;
27266     case OPC_FEXUPR_df:
27267         gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
27268         break;
27269     case OPC_FFQL_df:
27270         gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
27271         break;
27272     case OPC_FFQR_df:
27273         gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
27274         break;
27275     case OPC_FTINT_S_df:
27276         gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
27277         break;
27278     case OPC_FTINT_U_df:
27279         gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
27280         break;
27281     case OPC_FFINT_S_df:
27282         gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
27283         break;
27284     case OPC_FFINT_U_df:
27285         gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
27286         break;
27287     }
27288
27289     tcg_temp_free_i32(twd);
27290     tcg_temp_free_i32(tws);
27291     tcg_temp_free_i32(twt);
27292     tcg_temp_free_i32(tdf);
27293 }
27294
27295 static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
27296 {
27297 #define MASK_MSA_VEC(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
27298     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
27299     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27300     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27301     TCGv_i32 twd = tcg_const_i32(wd);
27302     TCGv_i32 tws = tcg_const_i32(ws);
27303     TCGv_i32 twt = tcg_const_i32(wt);
27304
27305     switch (MASK_MSA_VEC(ctx->opcode)) {
27306     case OPC_AND_V:
27307         gen_helper_msa_and_v(cpu_env, twd, tws, twt);
27308         break;
27309     case OPC_OR_V:
27310         gen_helper_msa_or_v(cpu_env, twd, tws, twt);
27311         break;
27312     case OPC_NOR_V:
27313         gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
27314         break;
27315     case OPC_XOR_V:
27316         gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
27317         break;
27318     case OPC_BMNZ_V:
27319         gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
27320         break;
27321     case OPC_BMZ_V:
27322         gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
27323         break;
27324     case OPC_BSEL_V:
27325         gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
27326         break;
27327     default:
27328         MIPS_INVAL("MSA instruction");
27329         generate_exception_end(ctx, EXCP_RI);
27330         break;
27331     }
27332
27333     tcg_temp_free_i32(twd);
27334     tcg_temp_free_i32(tws);
27335     tcg_temp_free_i32(twt);
27336 }
27337
27338 static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
27339 {
27340     switch (MASK_MSA_VEC(ctx->opcode)) {
27341     case OPC_AND_V:
27342     case OPC_OR_V:
27343     case OPC_NOR_V:
27344     case OPC_XOR_V:
27345     case OPC_BMNZ_V:
27346     case OPC_BMZ_V:
27347     case OPC_BSEL_V:
27348         gen_msa_vec_v(env, ctx);
27349         break;
27350     case OPC_MSA_2R:
27351         gen_msa_2r(env, ctx);
27352         break;
27353     case OPC_MSA_2RF:
27354         gen_msa_2rf(env, ctx);
27355         break;
27356     default:
27357         MIPS_INVAL("MSA instruction");
27358         generate_exception_end(ctx, EXCP_RI);
27359         break;
27360     }
27361 }
27362
27363 static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
27364 {
27365     uint32_t opcode = ctx->opcode;
27366     check_insn(ctx, ASE_MSA);
27367     check_msa_access(ctx);
27368
27369     switch (MASK_MSA_MINOR(opcode)) {
27370     case OPC_MSA_I8_00:
27371     case OPC_MSA_I8_01:
27372     case OPC_MSA_I8_02:
27373         gen_msa_i8(env, ctx);
27374         break;
27375     case OPC_MSA_I5_06:
27376     case OPC_MSA_I5_07:
27377         gen_msa_i5(env, ctx);
27378         break;
27379     case OPC_MSA_BIT_09:
27380     case OPC_MSA_BIT_0A:
27381         gen_msa_bit(env, ctx);
27382         break;
27383     case OPC_MSA_3R_0D:
27384     case OPC_MSA_3R_0E:
27385     case OPC_MSA_3R_0F:
27386     case OPC_MSA_3R_10:
27387     case OPC_MSA_3R_11:
27388     case OPC_MSA_3R_12:
27389     case OPC_MSA_3R_13:
27390     case OPC_MSA_3R_14:
27391     case OPC_MSA_3R_15:
27392         gen_msa_3r(env, ctx);
27393         break;
27394     case OPC_MSA_ELM:
27395         gen_msa_elm(env, ctx);
27396         break;
27397     case OPC_MSA_3RF_1A:
27398     case OPC_MSA_3RF_1B:
27399     case OPC_MSA_3RF_1C:
27400         gen_msa_3rf(env, ctx);
27401         break;
27402     case OPC_MSA_VEC:
27403         gen_msa_vec(env, ctx);
27404         break;
27405     case OPC_LD_B:
27406     case OPC_LD_H:
27407     case OPC_LD_W:
27408     case OPC_LD_D:
27409     case OPC_ST_B:
27410     case OPC_ST_H:
27411     case OPC_ST_W:
27412     case OPC_ST_D:
27413         {
27414             int32_t s10 = sextract32(ctx->opcode, 16, 10);
27415             uint8_t rs = (ctx->opcode >> 11) & 0x1f;
27416             uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27417             uint8_t df = (ctx->opcode >> 0) & 0x3;
27418
27419             TCGv_i32 twd = tcg_const_i32(wd);
27420             TCGv taddr = tcg_temp_new();
27421             gen_base_offset_addr(ctx, taddr, rs, s10 << df);
27422
27423             switch (MASK_MSA_MINOR(opcode)) {
27424             case OPC_LD_B:
27425                 gen_helper_msa_ld_b(cpu_env, twd, taddr);
27426                 break;
27427             case OPC_LD_H:
27428                 gen_helper_msa_ld_h(cpu_env, twd, taddr);
27429                 break;
27430             case OPC_LD_W:
27431                 gen_helper_msa_ld_w(cpu_env, twd, taddr);
27432                 break;
27433             case OPC_LD_D:
27434                 gen_helper_msa_ld_d(cpu_env, twd, taddr);
27435                 break;
27436             case OPC_ST_B:
27437                 gen_helper_msa_st_b(cpu_env, twd, taddr);
27438                 break;
27439             case OPC_ST_H:
27440                 gen_helper_msa_st_h(cpu_env, twd, taddr);
27441                 break;
27442             case OPC_ST_W:
27443                 gen_helper_msa_st_w(cpu_env, twd, taddr);
27444                 break;
27445             case OPC_ST_D:
27446                 gen_helper_msa_st_d(cpu_env, twd, taddr);
27447                 break;
27448             }
27449
27450             tcg_temp_free_i32(twd);
27451             tcg_temp_free(taddr);
27452         }
27453         break;
27454     default:
27455         MIPS_INVAL("MSA instruction");
27456         generate_exception_end(ctx, EXCP_RI);
27457         break;
27458     }
27459
27460 }
27461
27462 static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
27463 {
27464     int32_t offset;
27465     int rs, rt, rd, sa;
27466     uint32_t op, op1;
27467     int16_t imm;
27468
27469     /* make sure instructions are on a word boundary */
27470     if (ctx->base.pc_next & 0x3) {
27471         env->CP0_BadVAddr = ctx->base.pc_next;
27472         generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
27473         return;
27474     }
27475
27476     /* Handle blikely not taken case */
27477     if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
27478         TCGLabel *l1 = gen_new_label();
27479
27480         tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
27481         tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
27482         gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
27483         gen_set_label(l1);
27484     }
27485
27486     op = MASK_OP_MAJOR(ctx->opcode);
27487     rs = (ctx->opcode >> 21) & 0x1f;
27488     rt = (ctx->opcode >> 16) & 0x1f;
27489     rd = (ctx->opcode >> 11) & 0x1f;
27490     sa = (ctx->opcode >> 6) & 0x1f;
27491     imm = (int16_t)ctx->opcode;
27492     switch (op) {
27493     case OPC_SPECIAL:
27494         decode_opc_special(env, ctx);
27495         break;
27496     case OPC_SPECIAL2:
27497         if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
27498             decode_tx79_mmi(env, ctx);
27499         } else if (ctx->insn_flags & ASE_MXU) {
27500             decode_opc_mxu(env, ctx);
27501         } else {
27502             decode_opc_special2_legacy(env, ctx);
27503         }
27504         break;
27505     case OPC_SPECIAL3:
27506         if (ctx->insn_flags & INSN_R5900) {
27507             decode_tx79_sq(env, ctx);    /* TX79_SQ */
27508         } else {
27509             decode_opc_special3(env, ctx);
27510         }
27511         break;
27512     case OPC_REGIMM:
27513         op1 = MASK_REGIMM(ctx->opcode);
27514         switch (op1) {
27515         case OPC_BLTZL: /* REGIMM branches */
27516         case OPC_BGEZL:
27517         case OPC_BLTZALL:
27518         case OPC_BGEZALL:
27519             check_insn(ctx, ISA_MIPS2);
27520             check_insn_opc_removed(ctx, ISA_MIPS32R6);
27521             /* Fallthrough */
27522         case OPC_BLTZ:
27523         case OPC_BGEZ:
27524             gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
27525             break;
27526         case OPC_BLTZAL:
27527         case OPC_BGEZAL:
27528             if (ctx->insn_flags & ISA_MIPS32R6) {
27529                 if (rs == 0) {
27530                     /* OPC_NAL, OPC_BAL */
27531                     gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
27532                 } else {
27533                     generate_exception_end(ctx, EXCP_RI);
27534                 }
27535             } else {
27536                 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
27537             }
27538             break;
27539         case OPC_TGEI: /* REGIMM traps */
27540         case OPC_TGEIU:
27541         case OPC_TLTI:
27542         case OPC_TLTIU:
27543         case OPC_TEQI:
27544
27545         case OPC_TNEI:
27546             check_insn(ctx, ISA_MIPS2);
27547             check_insn_opc_removed(ctx, ISA_MIPS32R6);
27548             gen_trap(ctx, op1, rs, -1, imm);
27549             break;
27550         case OPC_SIGRIE:
27551             check_insn(ctx, ISA_MIPS32R6);
27552             generate_exception_end(ctx, EXCP_RI);
27553             break;
27554         case OPC_SYNCI:
27555             check_insn(ctx, ISA_MIPS32R2);
27556             /* Break the TB to be able to sync copied instructions
27557                immediately */
27558             ctx->base.is_jmp = DISAS_STOP;
27559             break;
27560         case OPC_BPOSGE32:    /* MIPS DSP branch */
27561 #if defined(TARGET_MIPS64)
27562         case OPC_BPOSGE64:
27563 #endif
27564             check_dsp(ctx);
27565             gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
27566             break;
27567 #if defined(TARGET_MIPS64)
27568         case OPC_DAHI:
27569             check_insn(ctx, ISA_MIPS32R6);
27570             check_mips_64(ctx);
27571             if (rs != 0) {
27572                 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
27573             }
27574             break;
27575         case OPC_DATI:
27576             check_insn(ctx, ISA_MIPS32R6);
27577             check_mips_64(ctx);
27578             if (rs != 0) {
27579                 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
27580             }
27581             break;
27582 #endif
27583         default:            /* Invalid */
27584             MIPS_INVAL("regimm");
27585             generate_exception_end(ctx, EXCP_RI);
27586             break;
27587         }
27588         break;
27589     case OPC_CP0:
27590         check_cp0_enabled(ctx);
27591         op1 = MASK_CP0(ctx->opcode);
27592         switch (op1) {
27593         case OPC_MFC0:
27594         case OPC_MTC0:
27595         case OPC_MFTR:
27596         case OPC_MTTR:
27597         case OPC_MFHC0:
27598         case OPC_MTHC0:
27599 #if defined(TARGET_MIPS64)
27600         case OPC_DMFC0:
27601         case OPC_DMTC0:
27602 #endif
27603 #ifndef CONFIG_USER_ONLY
27604             gen_cp0(env, ctx, op1, rt, rd);
27605 #endif /* !CONFIG_USER_ONLY */
27606             break;
27607         case OPC_C0:
27608         case OPC_C0_1:
27609         case OPC_C0_2:
27610         case OPC_C0_3:
27611         case OPC_C0_4:
27612         case OPC_C0_5:
27613         case OPC_C0_6:
27614         case OPC_C0_7:
27615         case OPC_C0_8:
27616         case OPC_C0_9:
27617         case OPC_C0_A:
27618         case OPC_C0_B:
27619         case OPC_C0_C:
27620         case OPC_C0_D:
27621         case OPC_C0_E:
27622         case OPC_C0_F:
27623 #ifndef CONFIG_USER_ONLY
27624             gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
27625 #endif /* !CONFIG_USER_ONLY */
27626             break;
27627         case OPC_MFMC0:
27628 #ifndef CONFIG_USER_ONLY
27629             {
27630                 uint32_t op2;
27631                 TCGv t0 = tcg_temp_new();
27632
27633                 op2 = MASK_MFMC0(ctx->opcode);
27634                 switch (op2) {
27635                 case OPC_DMT:
27636                     check_cp0_mt(ctx);
27637                     gen_helper_dmt(t0);
27638                     gen_store_gpr(t0, rt);
27639                     break;
27640                 case OPC_EMT:
27641                     check_cp0_mt(ctx);
27642                     gen_helper_emt(t0);
27643                     gen_store_gpr(t0, rt);
27644                     break;
27645                 case OPC_DVPE:
27646                     check_cp0_mt(ctx);
27647                     gen_helper_dvpe(t0, cpu_env);
27648                     gen_store_gpr(t0, rt);
27649                     break;
27650                 case OPC_EVPE:
27651                     check_cp0_mt(ctx);
27652                     gen_helper_evpe(t0, cpu_env);
27653                     gen_store_gpr(t0, rt);
27654                     break;
27655                 case OPC_DVP:
27656                     check_insn(ctx, ISA_MIPS32R6);
27657                     if (ctx->vp) {
27658                         gen_helper_dvp(t0, cpu_env);
27659                         gen_store_gpr(t0, rt);
27660                     }
27661                     break;
27662                 case OPC_EVP:
27663                     check_insn(ctx, ISA_MIPS32R6);
27664                     if (ctx->vp) {
27665                         gen_helper_evp(t0, cpu_env);
27666                         gen_store_gpr(t0, rt);
27667                     }
27668                     break;
27669                 case OPC_DI:
27670                     check_insn(ctx, ISA_MIPS32R2);
27671                     save_cpu_state(ctx, 1);
27672                     gen_helper_di(t0, cpu_env);
27673                     gen_store_gpr(t0, rt);
27674                     /* Stop translation as we may have switched
27675                        the execution mode.  */
27676                     ctx->base.is_jmp = DISAS_STOP;
27677                     break;
27678                 case OPC_EI:
27679                     check_insn(ctx, ISA_MIPS32R2);
27680                     save_cpu_state(ctx, 1);
27681                     gen_helper_ei(t0, cpu_env);
27682                     gen_store_gpr(t0, rt);
27683                     /* DISAS_STOP isn't sufficient, we need to ensure we break
27684                        out of translated code to check for pending interrupts */
27685                     gen_save_pc(ctx->base.pc_next + 4);
27686                     ctx->base.is_jmp = DISAS_EXIT;
27687                     break;
27688                 default:            /* Invalid */
27689                     MIPS_INVAL("mfmc0");
27690                     generate_exception_end(ctx, EXCP_RI);
27691                     break;
27692                 }
27693                 tcg_temp_free(t0);
27694             }
27695 #endif /* !CONFIG_USER_ONLY */
27696             break;
27697         case OPC_RDPGPR:
27698             check_insn(ctx, ISA_MIPS32R2);
27699             gen_load_srsgpr(rt, rd);
27700             break;
27701         case OPC_WRPGPR:
27702             check_insn(ctx, ISA_MIPS32R2);
27703             gen_store_srsgpr(rt, rd);
27704             break;
27705         default:
27706             MIPS_INVAL("cp0");
27707             generate_exception_end(ctx, EXCP_RI);
27708             break;
27709         }
27710         break;
27711     case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
27712         if (ctx->insn_flags & ISA_MIPS32R6) {
27713             /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
27714             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
27715         } else {
27716             /* OPC_ADDI */
27717             /* Arithmetic with immediate opcode */
27718             gen_arith_imm(ctx, op, rt, rs, imm);
27719         }
27720         break;
27721     case OPC_ADDIU:
27722          gen_arith_imm(ctx, op, rt, rs, imm);
27723          break;
27724     case OPC_SLTI: /* Set on less than with immediate opcode */
27725     case OPC_SLTIU:
27726          gen_slt_imm(ctx, op, rt, rs, imm);
27727          break;
27728     case OPC_ANDI: /* Arithmetic with immediate opcode */
27729     case OPC_LUI: /* OPC_AUI */
27730     case OPC_ORI:
27731     case OPC_XORI:
27732          gen_logic_imm(ctx, op, rt, rs, imm);
27733          break;
27734     case OPC_J: /* Jump */
27735     case OPC_JAL:
27736          offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
27737          gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
27738          break;
27739     /* Branch */
27740     case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
27741         if (ctx->insn_flags & ISA_MIPS32R6) {
27742             if (rt == 0) {
27743                 generate_exception_end(ctx, EXCP_RI);
27744                 break;
27745             }
27746             /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
27747             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
27748         } else {
27749             /* OPC_BLEZL */
27750             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
27751         }
27752         break;
27753     case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
27754         if (ctx->insn_flags & ISA_MIPS32R6) {
27755             if (rt == 0) {
27756                 generate_exception_end(ctx, EXCP_RI);
27757                 break;
27758             }
27759             /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
27760             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
27761         } else {
27762             /* OPC_BGTZL */
27763             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
27764         }
27765         break;
27766     case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
27767         if (rt == 0) {
27768             /* OPC_BLEZ */
27769             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
27770         } else {
27771             check_insn(ctx, ISA_MIPS32R6);
27772             /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
27773             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
27774         }
27775         break;
27776     case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
27777         if (rt == 0) {
27778             /* OPC_BGTZ */
27779             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
27780         } else {
27781             check_insn(ctx, ISA_MIPS32R6);
27782             /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
27783             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
27784         }
27785         break;
27786     case OPC_BEQL:
27787     case OPC_BNEL:
27788         check_insn(ctx, ISA_MIPS2);
27789          check_insn_opc_removed(ctx, ISA_MIPS32R6);
27790         /* Fallthrough */
27791     case OPC_BEQ:
27792     case OPC_BNE:
27793          gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
27794          break;
27795     case OPC_LL: /* Load and stores */
27796         check_insn(ctx, ISA_MIPS2);
27797         check_insn_opc_user_only(ctx, INSN_R5900);
27798         /* Fallthrough */
27799     case OPC_LWL:
27800     case OPC_LWR:
27801         check_insn_opc_removed(ctx, ISA_MIPS32R6);
27802          /* Fallthrough */
27803     case OPC_LB:
27804     case OPC_LH:
27805     case OPC_LW:
27806     case OPC_LWPC:
27807     case OPC_LBU:
27808     case OPC_LHU:
27809          gen_ld(ctx, op, rt, rs, imm);
27810          break;
27811     case OPC_SWL:
27812     case OPC_SWR:
27813         check_insn_opc_removed(ctx, ISA_MIPS32R6);
27814         /* fall through */
27815     case OPC_SB:
27816     case OPC_SH:
27817     case OPC_SW:
27818          gen_st(ctx, op, rt, rs, imm);
27819          break;
27820     case OPC_SC:
27821         check_insn(ctx, ISA_MIPS2);
27822          check_insn_opc_removed(ctx, ISA_MIPS32R6);
27823         check_insn_opc_user_only(ctx, INSN_R5900);
27824          gen_st_cond(ctx, op, rt, rs, imm);
27825          break;
27826     case OPC_CACHE:
27827         check_insn_opc_removed(ctx, ISA_MIPS32R6);
27828         check_cp0_enabled(ctx);
27829         check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
27830         if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
27831             gen_cache_operation(ctx, rt, rs, imm);
27832         }
27833         /* Treat as NOP. */
27834         break;
27835     case OPC_PREF:
27836         check_insn_opc_removed(ctx, ISA_MIPS32R6);
27837         check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
27838                    INSN_R5900);
27839         /* Treat as NOP. */
27840         break;
27841
27842     /* Floating point (COP1). */
27843     case OPC_LWC1:
27844     case OPC_LDC1:
27845     case OPC_SWC1:
27846     case OPC_SDC1:
27847         gen_cop1_ldst(ctx, op, rt, rs, imm);
27848         break;
27849
27850     case OPC_CP1:
27851         op1 = MASK_CP1(ctx->opcode);
27852
27853         switch (op1) {
27854         case OPC_MFHC1:
27855         case OPC_MTHC1:
27856             check_cp1_enabled(ctx);
27857             check_insn(ctx, ISA_MIPS32R2);
27858             /* fall through */
27859         case OPC_MFC1:
27860         case OPC_CFC1:
27861         case OPC_MTC1:
27862         case OPC_CTC1:
27863             check_cp1_enabled(ctx);
27864             gen_cp1(ctx, op1, rt, rd);
27865             break;
27866 #if defined(TARGET_MIPS64)
27867         case OPC_DMFC1:
27868         case OPC_DMTC1:
27869             check_cp1_enabled(ctx);
27870             check_insn(ctx, ISA_MIPS3);
27871             check_mips_64(ctx);
27872             gen_cp1(ctx, op1, rt, rd);
27873             break;
27874 #endif
27875         case OPC_BC1EQZ: /* OPC_BC1ANY2 */
27876             check_cp1_enabled(ctx);
27877             if (ctx->insn_flags & ISA_MIPS32R6) {
27878                 /* OPC_BC1EQZ */
27879                 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
27880                                        rt, imm << 2, 4);
27881             } else {
27882                 /* OPC_BC1ANY2 */
27883                 check_cop1x(ctx);
27884                 check_insn(ctx, ASE_MIPS3D);
27885                 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
27886                                     (rt >> 2) & 0x7, imm << 2);
27887             }
27888             break;
27889         case OPC_BC1NEZ:
27890             check_cp1_enabled(ctx);
27891             check_insn(ctx, ISA_MIPS32R6);
27892             gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
27893                                    rt, imm << 2, 4);
27894             break;
27895         case OPC_BC1ANY4:
27896             check_cp1_enabled(ctx);
27897             check_insn_opc_removed(ctx, ISA_MIPS32R6);
27898             check_cop1x(ctx);
27899             check_insn(ctx, ASE_MIPS3D);
27900             /* fall through */
27901         case OPC_BC1:
27902             check_cp1_enabled(ctx);
27903             check_insn_opc_removed(ctx, ISA_MIPS32R6);
27904             gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
27905                                 (rt >> 2) & 0x7, imm << 2);
27906             break;
27907         case OPC_PS_FMT:
27908             check_ps(ctx);
27909             /* fall through */
27910         case OPC_S_FMT:
27911         case OPC_D_FMT:
27912             check_cp1_enabled(ctx);
27913             gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
27914                        (imm >> 8) & 0x7);
27915             break;
27916         case OPC_W_FMT:
27917         case OPC_L_FMT:
27918         {
27919             int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
27920             check_cp1_enabled(ctx);
27921             if (ctx->insn_flags & ISA_MIPS32R6) {
27922                 switch (r6_op) {
27923                 case R6_OPC_CMP_AF_S:
27924                 case R6_OPC_CMP_UN_S:
27925                 case R6_OPC_CMP_EQ_S:
27926                 case R6_OPC_CMP_UEQ_S:
27927                 case R6_OPC_CMP_LT_S:
27928                 case R6_OPC_CMP_ULT_S:
27929                 case R6_OPC_CMP_LE_S:
27930                 case R6_OPC_CMP_ULE_S:
27931                 case R6_OPC_CMP_SAF_S:
27932                 case R6_OPC_CMP_SUN_S:
27933                 case R6_OPC_CMP_SEQ_S:
27934                 case R6_OPC_CMP_SEUQ_S:
27935                 case R6_OPC_CMP_SLT_S:
27936                 case R6_OPC_CMP_SULT_S:
27937                 case R6_OPC_CMP_SLE_S:
27938                 case R6_OPC_CMP_SULE_S:
27939                 case R6_OPC_CMP_OR_S:
27940                 case R6_OPC_CMP_UNE_S:
27941                 case R6_OPC_CMP_NE_S:
27942                 case R6_OPC_CMP_SOR_S:
27943                 case R6_OPC_CMP_SUNE_S:
27944                 case R6_OPC_CMP_SNE_S:
27945                     gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
27946                     break;
27947                 case R6_OPC_CMP_AF_D:
27948                 case R6_OPC_CMP_UN_D:
27949                 case R6_OPC_CMP_EQ_D:
27950                 case R6_OPC_CMP_UEQ_D:
27951                 case R6_OPC_CMP_LT_D:
27952                 case R6_OPC_CMP_ULT_D:
27953                 case R6_OPC_CMP_LE_D:
27954                 case R6_OPC_CMP_ULE_D:
27955                 case R6_OPC_CMP_SAF_D:
27956                 case R6_OPC_CMP_SUN_D:
27957                 case R6_OPC_CMP_SEQ_D:
27958                 case R6_OPC_CMP_SEUQ_D:
27959                 case R6_OPC_CMP_SLT_D:
27960                 case R6_OPC_CMP_SULT_D:
27961                 case R6_OPC_CMP_SLE_D:
27962                 case R6_OPC_CMP_SULE_D:
27963                 case R6_OPC_CMP_OR_D:
27964                 case R6_OPC_CMP_UNE_D:
27965                 case R6_OPC_CMP_NE_D:
27966                 case R6_OPC_CMP_SOR_D:
27967                 case R6_OPC_CMP_SUNE_D:
27968                 case R6_OPC_CMP_SNE_D:
27969                     gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
27970                     break;
27971                 default:
27972                     gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
27973                                rt, rd, sa, (imm >> 8) & 0x7);
27974
27975                     break;
27976                 }
27977             } else {
27978                 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
27979                            (imm >> 8) & 0x7);
27980             }
27981             break;
27982         }
27983         case OPC_BZ_V:
27984         case OPC_BNZ_V:
27985         case OPC_BZ_B:
27986         case OPC_BZ_H:
27987         case OPC_BZ_W:
27988         case OPC_BZ_D:
27989         case OPC_BNZ_B:
27990         case OPC_BNZ_H:
27991         case OPC_BNZ_W:
27992         case OPC_BNZ_D:
27993             check_insn(ctx, ASE_MSA);
27994             gen_msa_branch(env, ctx, op1);
27995             break;
27996         default:
27997             MIPS_INVAL("cp1");
27998             generate_exception_end(ctx, EXCP_RI);
27999             break;
28000         }
28001         break;
28002
28003     /* Compact branches [R6] and COP2 [non-R6] */
28004     case OPC_BC: /* OPC_LWC2 */
28005     case OPC_BALC: /* OPC_SWC2 */
28006         if (ctx->insn_flags & ISA_MIPS32R6) {
28007             /* OPC_BC, OPC_BALC */
28008             gen_compute_compact_branch(ctx, op, 0, 0,
28009                                        sextract32(ctx->opcode << 2, 0, 28));
28010         } else {
28011             /* OPC_LWC2, OPC_SWC2 */
28012             /* COP2: Not implemented. */
28013             generate_exception_err(ctx, EXCP_CpU, 2);
28014         }
28015         break;
28016     case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
28017     case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
28018         if (ctx->insn_flags & ISA_MIPS32R6) {
28019             if (rs != 0) {
28020                 /* OPC_BEQZC, OPC_BNEZC */
28021                 gen_compute_compact_branch(ctx, op, rs, 0,
28022                                            sextract32(ctx->opcode << 2, 0, 23));
28023             } else {
28024                 /* OPC_JIC, OPC_JIALC */
28025                 gen_compute_compact_branch(ctx, op, 0, rt, imm);
28026             }
28027         } else {
28028             /* OPC_LWC2, OPC_SWC2 */
28029             /* COP2: Not implemented. */
28030             generate_exception_err(ctx, EXCP_CpU, 2);
28031         }
28032         break;
28033     case OPC_CP2:
28034         check_insn(ctx, INSN_LOONGSON2F);
28035         /* Note that these instructions use different fields.  */
28036         gen_loongson_multimedia(ctx, sa, rd, rt);
28037         break;
28038
28039     case OPC_CP3:
28040         check_insn_opc_removed(ctx, ISA_MIPS32R6);
28041         if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
28042             check_cp1_enabled(ctx);
28043             op1 = MASK_CP3(ctx->opcode);
28044             switch (op1) {
28045             case OPC_LUXC1:
28046             case OPC_SUXC1:
28047                 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
28048                 /* Fallthrough */
28049             case OPC_LWXC1:
28050             case OPC_LDXC1:
28051             case OPC_SWXC1:
28052             case OPC_SDXC1:
28053                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
28054                 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
28055                 break;
28056             case OPC_PREFX:
28057                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
28058                 /* Treat as NOP. */
28059                 break;
28060             case OPC_ALNV_PS:
28061                 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
28062                 /* Fallthrough */
28063             case OPC_MADD_S:
28064             case OPC_MADD_D:
28065             case OPC_MADD_PS:
28066             case OPC_MSUB_S:
28067             case OPC_MSUB_D:
28068             case OPC_MSUB_PS:
28069             case OPC_NMADD_S:
28070             case OPC_NMADD_D:
28071             case OPC_NMADD_PS:
28072             case OPC_NMSUB_S:
28073             case OPC_NMSUB_D:
28074             case OPC_NMSUB_PS:
28075                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
28076                 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
28077                 break;
28078             default:
28079                 MIPS_INVAL("cp3");
28080                 generate_exception_end(ctx, EXCP_RI);
28081                 break;
28082             }
28083         } else {
28084             generate_exception_err(ctx, EXCP_CpU, 1);
28085         }
28086         break;
28087
28088 #if defined(TARGET_MIPS64)
28089     /* MIPS64 opcodes */
28090     case OPC_LLD:
28091         check_insn_opc_user_only(ctx, INSN_R5900);
28092         /* fall through */
28093     case OPC_LDL:
28094     case OPC_LDR:
28095         check_insn_opc_removed(ctx, ISA_MIPS32R6);
28096         /* fall through */
28097     case OPC_LWU:
28098     case OPC_LD:
28099         check_insn(ctx, ISA_MIPS3);
28100         check_mips_64(ctx);
28101         gen_ld(ctx, op, rt, rs, imm);
28102         break;
28103     case OPC_SDL:
28104     case OPC_SDR:
28105         check_insn_opc_removed(ctx, ISA_MIPS32R6);
28106         /* fall through */
28107     case OPC_SD:
28108         check_insn(ctx, ISA_MIPS3);
28109         check_mips_64(ctx);
28110         gen_st(ctx, op, rt, rs, imm);
28111         break;
28112     case OPC_SCD:
28113         check_insn_opc_removed(ctx, ISA_MIPS32R6);
28114         check_insn(ctx, ISA_MIPS3);
28115         check_insn_opc_user_only(ctx, INSN_R5900);
28116         check_mips_64(ctx);
28117         gen_st_cond(ctx, op, rt, rs, imm);
28118         break;
28119     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
28120         if (ctx->insn_flags & ISA_MIPS32R6) {
28121             /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
28122             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
28123         } else {
28124             /* OPC_DADDI */
28125             check_insn(ctx, ISA_MIPS3);
28126             check_mips_64(ctx);
28127             gen_arith_imm(ctx, op, rt, rs, imm);
28128         }
28129         break;
28130     case OPC_DADDIU:
28131         check_insn(ctx, ISA_MIPS3);
28132         check_mips_64(ctx);
28133         gen_arith_imm(ctx, op, rt, rs, imm);
28134         break;
28135 #else
28136     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
28137         if (ctx->insn_flags & ISA_MIPS32R6) {
28138             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
28139         } else {
28140             MIPS_INVAL("major opcode");
28141             generate_exception_end(ctx, EXCP_RI);
28142         }
28143         break;
28144 #endif
28145     case OPC_DAUI: /* OPC_JALX */
28146         if (ctx->insn_flags & ISA_MIPS32R6) {
28147 #if defined(TARGET_MIPS64)
28148             /* OPC_DAUI */
28149             check_mips_64(ctx);
28150             if (rs == 0) {
28151                 generate_exception(ctx, EXCP_RI);
28152             } else if (rt != 0) {
28153                 TCGv t0 = tcg_temp_new();
28154                 gen_load_gpr(t0, rs);
28155                 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
28156                 tcg_temp_free(t0);
28157             }
28158 #else
28159             generate_exception_end(ctx, EXCP_RI);
28160             MIPS_INVAL("major opcode");
28161 #endif
28162         } else {
28163             /* OPC_JALX */
28164             check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
28165             offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
28166             gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
28167         }
28168         break;
28169     case OPC_MSA: /* OPC_MDMX */
28170         if (ctx->insn_flags & INSN_R5900) {
28171             decode_tx79_lq(env, ctx);    /* TX79_LQ */
28172         } else {
28173             /* MDMX: Not implemented. */
28174             gen_msa(env, ctx);
28175         }
28176         break;
28177     case OPC_PCREL:
28178         check_insn(ctx, ISA_MIPS32R6);
28179         gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
28180         break;
28181     default:            /* Invalid */
28182         MIPS_INVAL("major opcode");
28183         generate_exception_end(ctx, EXCP_RI);
28184         break;
28185     }
28186 }
28187
28188 static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
28189 {
28190     DisasContext *ctx = container_of(dcbase, DisasContext, base);
28191     CPUMIPSState *env = cs->env_ptr;
28192
28193     ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
28194     ctx->saved_pc = -1;
28195     ctx->insn_flags = env->insn_flags;
28196     ctx->CP0_Config1 = env->CP0_Config1;
28197     ctx->CP0_Config2 = env->CP0_Config2;
28198     ctx->CP0_Config3 = env->CP0_Config3;
28199     ctx->CP0_Config5 = env->CP0_Config5;
28200     ctx->btarget = 0;
28201     ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
28202     ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
28203     ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
28204     ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
28205     ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
28206     ctx->PAMask = env->PAMask;
28207     ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
28208     ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
28209     ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
28210     ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
28211     ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
28212     /* Restore delay slot state from the tb context.  */
28213     ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
28214     ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
28215     ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
28216              (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
28217     ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
28218     ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
28219     ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
28220     ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
28221     restore_cpu_state(env, ctx);
28222 #ifdef CONFIG_USER_ONLY
28223         ctx->mem_idx = MIPS_HFLAG_UM;
28224 #else
28225         ctx->mem_idx = hflags_mmu_index(ctx->hflags);
28226 #endif
28227     ctx->default_tcg_memop_mask = (ctx->insn_flags & ISA_MIPS32R6) ?
28228                                   MO_UNALN : MO_ALIGN;
28229
28230     LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
28231               ctx->hflags);
28232 }
28233
28234 static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
28235 {
28236 }
28237
28238 static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
28239 {
28240     DisasContext *ctx = container_of(dcbase, DisasContext, base);
28241
28242     tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
28243                        ctx->btarget);
28244 }
28245
28246 static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
28247                                      const CPUBreakpoint *bp)
28248 {
28249     DisasContext *ctx = container_of(dcbase, DisasContext, base);
28250
28251     save_cpu_state(ctx, 1);
28252     ctx->base.is_jmp = DISAS_NORETURN;
28253     gen_helper_raise_exception_debug(cpu_env);
28254     /* The address covered by the breakpoint must be included in
28255        [tb->pc, tb->pc + tb->size) in order to for it to be
28256        properly cleared -- thus we increment the PC here so that
28257        the logic setting tb->size below does the right thing.  */
28258     ctx->base.pc_next += 4;
28259     return true;
28260 }
28261
28262 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
28263 {
28264     CPUMIPSState *env = cs->env_ptr;
28265     DisasContext *ctx = container_of(dcbase, DisasContext, base);
28266     int insn_bytes;
28267     int is_slot;
28268
28269     is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
28270     if (ctx->insn_flags & ISA_NANOMIPS32) {
28271         ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
28272         insn_bytes = decode_nanomips_opc(env, ctx);
28273     } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
28274         ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
28275         insn_bytes = 4;
28276         decode_opc(env, ctx);
28277     } else if (ctx->insn_flags & ASE_MICROMIPS) {
28278         ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
28279         insn_bytes = decode_micromips_opc(env, ctx);
28280     } else if (ctx->insn_flags & ASE_MIPS16) {
28281         ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
28282         insn_bytes = decode_mips16_opc(env, ctx);
28283     } else {
28284         generate_exception_end(ctx, EXCP_RI);
28285         g_assert(ctx->base.is_jmp == DISAS_NORETURN);
28286         return;
28287     }
28288
28289     if (ctx->hflags & MIPS_HFLAG_BMASK) {
28290         if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
28291                              MIPS_HFLAG_FBNSLOT))) {
28292             /* force to generate branch as there is neither delay nor
28293                forbidden slot */
28294             is_slot = 1;
28295         }
28296         if ((ctx->hflags & MIPS_HFLAG_M16) &&
28297             (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
28298             /* Force to generate branch as microMIPS R6 doesn't restrict
28299                branches in the forbidden slot. */
28300             is_slot = 1;
28301         }
28302     }
28303     if (is_slot) {
28304         gen_branch(ctx, insn_bytes);
28305     }
28306     ctx->base.pc_next += insn_bytes;
28307
28308     if (ctx->base.is_jmp != DISAS_NEXT) {
28309         return;
28310     }
28311     /* Execute a branch and its delay slot as a single instruction.
28312        This is what GDB expects and is consistent with what the
28313        hardware does (e.g. if a delay slot instruction faults, the
28314        reported PC is the PC of the branch).  */
28315     if (ctx->base.singlestep_enabled &&
28316         (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
28317         ctx->base.is_jmp = DISAS_TOO_MANY;
28318     }
28319     if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
28320         ctx->base.is_jmp = DISAS_TOO_MANY;
28321     }
28322 }
28323
28324 static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
28325 {
28326     DisasContext *ctx = container_of(dcbase, DisasContext, base);
28327
28328     if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
28329         save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
28330         gen_helper_raise_exception_debug(cpu_env);
28331     } else {
28332         switch (ctx->base.is_jmp) {
28333         case DISAS_STOP:
28334             gen_save_pc(ctx->base.pc_next);
28335             tcg_gen_lookup_and_goto_ptr();
28336             break;
28337         case DISAS_NEXT:
28338         case DISAS_TOO_MANY:
28339             save_cpu_state(ctx, 0);
28340             gen_goto_tb(ctx, 0, ctx->base.pc_next);
28341             break;
28342         case DISAS_EXIT:
28343             tcg_gen_exit_tb(NULL, 0);
28344             break;
28345         case DISAS_NORETURN:
28346             break;
28347         default:
28348             g_assert_not_reached();
28349         }
28350     }
28351 }
28352
28353 static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
28354 {
28355     qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
28356     log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
28357 }
28358
28359 static const TranslatorOps mips_tr_ops = {
28360     .init_disas_context = mips_tr_init_disas_context,
28361     .tb_start           = mips_tr_tb_start,
28362     .insn_start         = mips_tr_insn_start,
28363     .breakpoint_check   = mips_tr_breakpoint_check,
28364     .translate_insn     = mips_tr_translate_insn,
28365     .tb_stop            = mips_tr_tb_stop,
28366     .disas_log          = mips_tr_disas_log,
28367 };
28368
28369 void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
28370 {
28371     DisasContext ctx;
28372
28373     translator_loop(&mips_tr_ops, &ctx.base, cs, tb);
28374 }
28375
28376 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
28377                            int flags)
28378 {
28379     int i;
28380     int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
28381
28382 #define printfpr(fp)                                                    \
28383     do {                                                                \
28384         if (is_fpu64)                                                   \
28385             fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
28386                         " fd:%13g fs:%13g psu: %13g\n",                 \
28387                         (fp)->w[FP_ENDIAN_IDX], (fp)->d,                \
28388                         (double)(fp)->fd,                               \
28389                         (double)(fp)->fs[FP_ENDIAN_IDX],                \
28390                         (double)(fp)->fs[!FP_ENDIAN_IDX]);              \
28391         else {                                                          \
28392             fpr_t tmp;                                                  \
28393             tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];              \
28394             tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];       \
28395             fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
28396                         " fd:%13g fs:%13g psu:%13g\n",                  \
28397                         tmp.w[FP_ENDIAN_IDX], tmp.d,                    \
28398                         (double)tmp.fd,                                 \
28399                         (double)tmp.fs[FP_ENDIAN_IDX],                  \
28400                         (double)tmp.fs[!FP_ENDIAN_IDX]);                \
28401         }                                                               \
28402     } while(0)
28403
28404
28405     fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%02x\n",
28406                 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
28407                 get_float_exception_flags(&env->active_fpu.fp_status));
28408     for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
28409         fpu_fprintf(f, "%3s: ", fregnames[i]);
28410         printfpr(&env->active_fpu.fpr[i]);
28411     }
28412
28413 #undef printfpr
28414 }
28415
28416 void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
28417                          int flags)
28418 {
28419     MIPSCPU *cpu = MIPS_CPU(cs);
28420     CPUMIPSState *env = &cpu->env;
28421     int i;
28422
28423     cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
28424                 " LO=0x" TARGET_FMT_lx " ds %04x "
28425                 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
28426                 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
28427                 env->hflags, env->btarget, env->bcond);
28428     for (i = 0; i < 32; i++) {
28429         if ((i & 3) == 0)
28430             cpu_fprintf(f, "GPR%02d:", i);
28431         cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
28432         if ((i & 3) == 3)
28433             cpu_fprintf(f, "\n");
28434     }
28435
28436     cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
28437                 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
28438     cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
28439                 PRIx64 "\n",
28440                 env->CP0_Config0, env->CP0_Config1, env->lladdr);
28441     cpu_fprintf(f, "    Config2 0x%08x Config3 0x%08x\n",
28442                 env->CP0_Config2, env->CP0_Config3);
28443     cpu_fprintf(f, "    Config4 0x%08x Config5 0x%08x\n",
28444                 env->CP0_Config4, env->CP0_Config5);
28445     if ((flags & CPU_DUMP_FPU) && (env->hflags & MIPS_HFLAG_FPU)) {
28446         fpu_dump_state(env, f, cpu_fprintf, flags);
28447     }
28448 }
28449
28450 void mips_tcg_init(void)
28451 {
28452     int i;
28453
28454     cpu_gpr[0] = NULL;
28455     for (i = 1; i < 32; i++)
28456         cpu_gpr[i] = tcg_global_mem_new(cpu_env,
28457                                         offsetof(CPUMIPSState, active_tc.gpr[i]),
28458                                         regnames[i]);
28459
28460     for (i = 0; i < 32; i++) {
28461         int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
28462         msa_wr_d[i * 2] =
28463                 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
28464         /* The scalar floating-point unit (FPU) registers are mapped on
28465          * the MSA vector registers. */
28466         fpu_f64[i] = msa_wr_d[i * 2];
28467         off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
28468         msa_wr_d[i * 2 + 1] =
28469                 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
28470     }
28471
28472     cpu_PC = tcg_global_mem_new(cpu_env,
28473                                 offsetof(CPUMIPSState, active_tc.PC), "PC");
28474     for (i = 0; i < MIPS_DSP_ACC; i++) {
28475         cpu_HI[i] = tcg_global_mem_new(cpu_env,
28476                                        offsetof(CPUMIPSState, active_tc.HI[i]),
28477                                        regnames_HI[i]);
28478         cpu_LO[i] = tcg_global_mem_new(cpu_env,
28479                                        offsetof(CPUMIPSState, active_tc.LO[i]),
28480                                        regnames_LO[i]);
28481     }
28482     cpu_dspctrl = tcg_global_mem_new(cpu_env,
28483                                      offsetof(CPUMIPSState, active_tc.DSPControl),
28484                                      "DSPControl");
28485     bcond = tcg_global_mem_new(cpu_env,
28486                                offsetof(CPUMIPSState, bcond), "bcond");
28487     btarget = tcg_global_mem_new(cpu_env,
28488                                  offsetof(CPUMIPSState, btarget), "btarget");
28489     hflags = tcg_global_mem_new_i32(cpu_env,
28490                                     offsetof(CPUMIPSState, hflags), "hflags");
28491
28492     fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
28493                                       offsetof(CPUMIPSState, active_fpu.fcr0),
28494                                       "fcr0");
28495     fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
28496                                        offsetof(CPUMIPSState, active_fpu.fcr31),
28497                                        "fcr31");
28498
28499     for (i = 0; i < NUMBER_OF_MXU_REGISTERS - 1; i++) {
28500         mxu_gpr[i] = tcg_global_mem_new(cpu_env,
28501                                         offsetof(CPUMIPSState,
28502                                                  active_tc.mxu_gpr[i]),
28503                                         mxuregnames[i]);
28504     }
28505
28506     mxu_CR = tcg_global_mem_new(cpu_env,
28507                                 offsetof(CPUMIPSState, active_tc.mxu_cr),
28508                                 mxuregnames[NUMBER_OF_MXU_REGISTERS - 1]);
28509 }
28510
28511 #include "translate_init.inc.c"
28512
28513 void cpu_mips_realize_env(CPUMIPSState *env)
28514 {
28515     env->exception_base = (int32_t)0xBFC00000;
28516
28517 #ifndef CONFIG_USER_ONLY
28518     mmu_init(env, env->cpu_model);
28519 #endif
28520     fpu_init(env, env->cpu_model);
28521     mvp_init(env, env->cpu_model);
28522 }
28523
28524 bool cpu_supports_cps_smp(const char *cpu_type)
28525 {
28526     const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
28527     return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
28528 }
28529
28530 bool cpu_supports_isa(const char *cpu_type, unsigned int isa)
28531 {
28532     const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
28533     return (mcc->cpu_def->insn_flags & isa) != 0;
28534 }
28535
28536 void cpu_set_exception_base(int vp_index, target_ulong address)
28537 {
28538     MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
28539     vp->env.exception_base = address;
28540 }
28541
28542 void cpu_state_reset(CPUMIPSState *env)
28543 {
28544     MIPSCPU *cpu = mips_env_get_cpu(env);
28545     CPUState *cs = CPU(cpu);
28546
28547     /* Reset registers to their default values */
28548     env->CP0_PRid = env->cpu_model->CP0_PRid;
28549     env->CP0_Config0 = env->cpu_model->CP0_Config0;
28550 #ifdef TARGET_WORDS_BIGENDIAN
28551     env->CP0_Config0 |= (1 << CP0C0_BE);
28552 #endif
28553     env->CP0_Config1 = env->cpu_model->CP0_Config1;
28554     env->CP0_Config2 = env->cpu_model->CP0_Config2;
28555     env->CP0_Config3 = env->cpu_model->CP0_Config3;
28556     env->CP0_Config4 = env->cpu_model->CP0_Config4;
28557     env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
28558     env->CP0_Config5 = env->cpu_model->CP0_Config5;
28559     env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
28560     env->CP0_Config6 = env->cpu_model->CP0_Config6;
28561     env->CP0_Config7 = env->cpu_model->CP0_Config7;
28562     env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
28563                                  << env->cpu_model->CP0_LLAddr_shift;
28564     env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
28565     env->SYNCI_Step = env->cpu_model->SYNCI_Step;
28566     env->CCRes = env->cpu_model->CCRes;
28567     env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
28568     env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
28569     env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
28570     env->current_tc = 0;
28571     env->SEGBITS = env->cpu_model->SEGBITS;
28572     env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
28573 #if defined(TARGET_MIPS64)
28574     if (env->cpu_model->insn_flags & ISA_MIPS3) {
28575         env->SEGMask |= 3ULL << 62;
28576     }
28577 #endif
28578     env->PABITS = env->cpu_model->PABITS;
28579     env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
28580     env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
28581     env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
28582     env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
28583     env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
28584     env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
28585     env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
28586     env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
28587     env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
28588     env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
28589     env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
28590     env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
28591     env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
28592     env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
28593     env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
28594     env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
28595     env->msair = env->cpu_model->MSAIR;
28596     env->insn_flags = env->cpu_model->insn_flags;
28597
28598 #if defined(CONFIG_USER_ONLY)
28599     env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
28600 # ifdef TARGET_MIPS64
28601     /* Enable 64-bit register mode.  */
28602     env->CP0_Status |= (1 << CP0St_PX);
28603 # endif
28604 # ifdef TARGET_ABI_MIPSN64
28605     /* Enable 64-bit address mode.  */
28606     env->CP0_Status |= (1 << CP0St_UX);
28607 # endif
28608     /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
28609        hardware registers.  */
28610     env->CP0_HWREna |= 0x0000000F;
28611     if (env->CP0_Config1 & (1 << CP0C1_FP)) {
28612         env->CP0_Status |= (1 << CP0St_CU1);
28613     }
28614     if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
28615         env->CP0_Status |= (1 << CP0St_MX);
28616     }
28617 # if defined(TARGET_MIPS64)
28618     /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
28619     if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
28620         (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
28621         env->CP0_Status |= (1 << CP0St_FR);
28622     }
28623 # endif
28624 #else
28625     if (env->hflags & MIPS_HFLAG_BMASK) {
28626         /* If the exception was raised from a delay slot,
28627            come back to the jump.  */
28628         env->CP0_ErrorEPC = (env->active_tc.PC
28629                              - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
28630     } else {
28631         env->CP0_ErrorEPC = env->active_tc.PC;
28632     }
28633     env->active_tc.PC = env->exception_base;
28634     env->CP0_Random = env->tlb->nb_tlb - 1;
28635     env->tlb->tlb_in_use = env->tlb->nb_tlb;
28636     env->CP0_Wired = 0;
28637     env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
28638     env->CP0_EBase = (cs->cpu_index & 0x3FF);
28639     if (mips_um_ksegs_enabled()) {
28640         env->CP0_EBase |= 0x40000000;
28641     } else {
28642         env->CP0_EBase |= (int32_t)0x80000000;
28643     }
28644     if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
28645         env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
28646     }
28647     env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
28648                                  0x3ff : 0xff;
28649     env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
28650     /* vectored interrupts not implemented, timer on int 7,
28651        no performance counters. */
28652     env->CP0_IntCtl = 0xe0000000;
28653     {
28654         int i;
28655
28656         for (i = 0; i < 7; i++) {
28657             env->CP0_WatchLo[i] = 0;
28658             env->CP0_WatchHi[i] = 0x80000000;
28659         }
28660         env->CP0_WatchLo[7] = 0;
28661         env->CP0_WatchHi[7] = 0;
28662     }
28663     /* Count register increments in debug mode, EJTAG version 1 */
28664     env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
28665
28666     cpu_mips_store_count(env, 1);
28667
28668     if (env->CP0_Config3 & (1 << CP0C3_MT)) {
28669         int i;
28670
28671         /* Only TC0 on VPE 0 starts as active.  */
28672         for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
28673             env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
28674             env->tcs[i].CP0_TCHalt = 1;
28675         }
28676         env->active_tc.CP0_TCHalt = 1;
28677         cs->halted = 1;
28678
28679         if (cs->cpu_index == 0) {
28680             /* VPE0 starts up enabled.  */
28681             env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
28682             env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
28683
28684             /* TC0 starts up unhalted.  */
28685             cs->halted = 0;
28686             env->active_tc.CP0_TCHalt = 0;
28687             env->tcs[0].CP0_TCHalt = 0;
28688             /* With thread 0 active.  */
28689             env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
28690             env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
28691         }
28692     }
28693
28694     /*
28695      * Configure default legacy segmentation control. We use this regardless of
28696      * whether segmentation control is presented to the guest.
28697      */
28698     /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
28699     env->CP0_SegCtl0 =   (CP0SC_AM_MK << CP0SC_AM);
28700     /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
28701     env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
28702     /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
28703     env->CP0_SegCtl1 =   (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
28704                          (2 << CP0SC_C);
28705     /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
28706     env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
28707                          (3 << CP0SC_C)) << 16;
28708     /* USeg (seg4 0x40000000..0x7FFFFFFF) */
28709     env->CP0_SegCtl2 =   (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
28710                          (1 << CP0SC_EU) | (2 << CP0SC_C);
28711     /* USeg (seg5 0x00000000..0x3FFFFFFF) */
28712     env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
28713                          (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
28714     /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
28715     env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
28716 #endif
28717     if ((env->insn_flags & ISA_MIPS32R6) &&
28718         (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
28719         /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
28720         env->CP0_Status |= (1 << CP0St_FR);
28721     }
28722
28723     if (env->insn_flags & ISA_MIPS32R6) {
28724         /* PTW  =  1 */
28725         env->CP0_PWSize = 0x40;
28726         /* GDI  = 12 */
28727         /* UDI  = 12 */
28728         /* MDI  = 12 */
28729         /* PRI  = 12 */
28730         /* PTEI =  2 */
28731         env->CP0_PWField = 0x0C30C302;
28732     } else {
28733         /* GDI  =  0 */
28734         /* UDI  =  0 */
28735         /* MDI  =  0 */
28736         /* PRI  =  0 */
28737         /* PTEI =  2 */
28738         env->CP0_PWField = 0x02;
28739     }
28740
28741     if (env->CP0_Config3 & (1 << CP0C3_ISA) & (1 << (CP0C3_ISA + 1))) {
28742         /*  microMIPS on reset when Config3.ISA is 3 */
28743         env->hflags |= MIPS_HFLAG_M16;
28744     }
28745
28746     /* MSA */
28747     if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
28748         msa_reset(env);
28749     }
28750
28751     compute_hflags(env);
28752     restore_fp_status(env);
28753     restore_pamask(env);
28754     cs->exception_index = EXCP_NONE;
28755
28756     if (semihosting_get_argc()) {
28757         /* UHI interface can be used to obtain argc and argv */
28758         env->active_tc.gpr[4] = -1;
28759     }
28760 }
28761
28762 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
28763                           target_ulong *data)
28764 {
28765     env->active_tc.PC = data[0];
28766     env->hflags &= ~MIPS_HFLAG_BMASK;
28767     env->hflags |= data[1];
28768     switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
28769     case MIPS_HFLAG_BR:
28770         break;
28771     case MIPS_HFLAG_BC:
28772     case MIPS_HFLAG_BL:
28773     case MIPS_HFLAG_B:
28774         env->btarget = data[2];
28775         break;
28776     }
28777 }
This page took 1.573297 seconds and 4 git commands to generate.