]> Git Repo - qemu.git/blob - target/mips/translate.c
Merge remote-tracking branch 'remotes/jasowang/tags/net-pull-request' into staging
[qemu.git] / target / mips / translate.c
1 /*
2  *  MIPS32 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 */
467     OPC_ALIGN_END = (0x0B << 6) | OPC_BSHFL, /* 010.00 to 010.11 */
468     OPC_BITSWAP   = (0x00 << 6) | OPC_BSHFL  /* 00000 */
469 };
470
471 /* DBSHFL opcodes */
472 #define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
473
474 enum {
475     OPC_DSBH       = (0x02 << 6) | OPC_DBSHFL,
476     OPC_DSHD       = (0x05 << 6) | OPC_DBSHFL,
477     OPC_DALIGN     = (0x08 << 6) | OPC_DBSHFL, /* 01.bp */
478     OPC_DALIGN_END = (0x0F << 6) | OPC_DBSHFL, /* 01.000 to 01.111 */
479     OPC_DBITSWAP   = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
480 };
481
482 /* MIPS DSP REGIMM opcodes */
483 enum {
484     OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
485     OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
486 };
487
488 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
489 /* MIPS DSP Load */
490 enum {
491     OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
492     OPC_LHX  = (0x04 << 6) | OPC_LX_DSP,
493     OPC_LWX  = (0x00 << 6) | OPC_LX_DSP,
494     OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
495 };
496
497 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
498 enum {
499     /* MIPS DSP Arithmetic Sub-class */
500     OPC_ADDQ_PH        = (0x0A << 6) | OPC_ADDU_QB_DSP,
501     OPC_ADDQ_S_PH      = (0x0E << 6) | OPC_ADDU_QB_DSP,
502     OPC_ADDQ_S_W       = (0x16 << 6) | OPC_ADDU_QB_DSP,
503     OPC_ADDU_QB        = (0x00 << 6) | OPC_ADDU_QB_DSP,
504     OPC_ADDU_S_QB      = (0x04 << 6) | OPC_ADDU_QB_DSP,
505     OPC_ADDU_PH        = (0x08 << 6) | OPC_ADDU_QB_DSP,
506     OPC_ADDU_S_PH      = (0x0C << 6) | OPC_ADDU_QB_DSP,
507     OPC_SUBQ_PH        = (0x0B << 6) | OPC_ADDU_QB_DSP,
508     OPC_SUBQ_S_PH      = (0x0F << 6) | OPC_ADDU_QB_DSP,
509     OPC_SUBQ_S_W       = (0x17 << 6) | OPC_ADDU_QB_DSP,
510     OPC_SUBU_QB        = (0x01 << 6) | OPC_ADDU_QB_DSP,
511     OPC_SUBU_S_QB      = (0x05 << 6) | OPC_ADDU_QB_DSP,
512     OPC_SUBU_PH        = (0x09 << 6) | OPC_ADDU_QB_DSP,
513     OPC_SUBU_S_PH      = (0x0D << 6) | OPC_ADDU_QB_DSP,
514     OPC_ADDSC          = (0x10 << 6) | OPC_ADDU_QB_DSP,
515     OPC_ADDWC          = (0x11 << 6) | OPC_ADDU_QB_DSP,
516     OPC_MODSUB         = (0x12 << 6) | OPC_ADDU_QB_DSP,
517     OPC_RADDU_W_QB     = (0x14 << 6) | OPC_ADDU_QB_DSP,
518     /* MIPS DSP Multiply Sub-class insns */
519     OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
520     OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
521     OPC_MULQ_RS_PH     = (0x1F << 6) | OPC_ADDU_QB_DSP,
522     OPC_MULEQ_S_W_PHL  = (0x1C << 6) | OPC_ADDU_QB_DSP,
523     OPC_MULEQ_S_W_PHR  = (0x1D << 6) | OPC_ADDU_QB_DSP,
524     OPC_MULQ_S_PH      = (0x1E << 6) | OPC_ADDU_QB_DSP,
525 };
526
527 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
528 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
529 enum {
530     /* MIPS DSP Arithmetic Sub-class */
531     OPC_ADDUH_QB   = (0x00 << 6) | OPC_ADDUH_QB_DSP,
532     OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
533     OPC_ADDQH_PH   = (0x08 << 6) | OPC_ADDUH_QB_DSP,
534     OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
535     OPC_ADDQH_W    = (0x10 << 6) | OPC_ADDUH_QB_DSP,
536     OPC_ADDQH_R_W  = (0x12 << 6) | OPC_ADDUH_QB_DSP,
537     OPC_SUBUH_QB   = (0x01 << 6) | OPC_ADDUH_QB_DSP,
538     OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
539     OPC_SUBQH_PH   = (0x09 << 6) | OPC_ADDUH_QB_DSP,
540     OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
541     OPC_SUBQH_W    = (0x11 << 6) | OPC_ADDUH_QB_DSP,
542     OPC_SUBQH_R_W  = (0x13 << 6) | OPC_ADDUH_QB_DSP,
543     /* MIPS DSP Multiply Sub-class insns */
544     OPC_MUL_PH     = (0x0C << 6) | OPC_ADDUH_QB_DSP,
545     OPC_MUL_S_PH   = (0x0E << 6) | OPC_ADDUH_QB_DSP,
546     OPC_MULQ_S_W   = (0x16 << 6) | OPC_ADDUH_QB_DSP,
547     OPC_MULQ_RS_W  = (0x17 << 6) | OPC_ADDUH_QB_DSP,
548 };
549
550 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
551 enum {
552     /* MIPS DSP Arithmetic Sub-class */
553     OPC_ABSQ_S_QB       = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
554     OPC_ABSQ_S_PH       = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
555     OPC_ABSQ_S_W        = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
556     OPC_PRECEQ_W_PHL    = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
557     OPC_PRECEQ_W_PHR    = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
558     OPC_PRECEQU_PH_QBL  = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
559     OPC_PRECEQU_PH_QBR  = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
560     OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
561     OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
562     OPC_PRECEU_PH_QBL   = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
563     OPC_PRECEU_PH_QBR   = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
564     OPC_PRECEU_PH_QBLA  = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
565     OPC_PRECEU_PH_QBRA  = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
566     /* DSP Bit/Manipulation Sub-class */
567     OPC_BITREV          = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
568     OPC_REPL_QB         = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
569     OPC_REPLV_QB        = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
570     OPC_REPL_PH         = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
571     OPC_REPLV_PH        = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
572 };
573
574 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
575 enum {
576     /* MIPS DSP Arithmetic Sub-class */
577     OPC_PRECR_QB_PH      = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
578     OPC_PRECRQ_QB_PH     = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
579     OPC_PRECR_SRA_PH_W   = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
580     OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
581     OPC_PRECRQ_PH_W      = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
582     OPC_PRECRQ_RS_PH_W   = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
583     OPC_PRECRQU_S_QB_PH  = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
584     /* DSP Compare-Pick Sub-class */
585     OPC_CMPU_EQ_QB       = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
586     OPC_CMPU_LT_QB       = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
587     OPC_CMPU_LE_QB       = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
588     OPC_CMPGU_EQ_QB      = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
589     OPC_CMPGU_LT_QB      = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
590     OPC_CMPGU_LE_QB      = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
591     OPC_CMPGDU_EQ_QB     = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
592     OPC_CMPGDU_LT_QB     = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
593     OPC_CMPGDU_LE_QB     = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
594     OPC_CMP_EQ_PH        = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
595     OPC_CMP_LT_PH        = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
596     OPC_CMP_LE_PH        = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
597     OPC_PICK_QB          = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
598     OPC_PICK_PH          = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
599     OPC_PACKRL_PH        = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
600 };
601
602 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
603 enum {
604     /* MIPS DSP GPR-Based Shift Sub-class */
605     OPC_SHLL_QB    = (0x00 << 6) | OPC_SHLL_QB_DSP,
606     OPC_SHLLV_QB   = (0x02 << 6) | OPC_SHLL_QB_DSP,
607     OPC_SHLL_PH    = (0x08 << 6) | OPC_SHLL_QB_DSP,
608     OPC_SHLLV_PH   = (0x0A << 6) | OPC_SHLL_QB_DSP,
609     OPC_SHLL_S_PH  = (0x0C << 6) | OPC_SHLL_QB_DSP,
610     OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
611     OPC_SHLL_S_W   = (0x14 << 6) | OPC_SHLL_QB_DSP,
612     OPC_SHLLV_S_W  = (0x16 << 6) | OPC_SHLL_QB_DSP,
613     OPC_SHRL_QB    = (0x01 << 6) | OPC_SHLL_QB_DSP,
614     OPC_SHRLV_QB   = (0x03 << 6) | OPC_SHLL_QB_DSP,
615     OPC_SHRL_PH    = (0x19 << 6) | OPC_SHLL_QB_DSP,
616     OPC_SHRLV_PH   = (0x1B << 6) | OPC_SHLL_QB_DSP,
617     OPC_SHRA_QB    = (0x04 << 6) | OPC_SHLL_QB_DSP,
618     OPC_SHRA_R_QB  = (0x05 << 6) | OPC_SHLL_QB_DSP,
619     OPC_SHRAV_QB   = (0x06 << 6) | OPC_SHLL_QB_DSP,
620     OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
621     OPC_SHRA_PH    = (0x09 << 6) | OPC_SHLL_QB_DSP,
622     OPC_SHRAV_PH   = (0x0B << 6) | OPC_SHLL_QB_DSP,
623     OPC_SHRA_R_PH  = (0x0D << 6) | OPC_SHLL_QB_DSP,
624     OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
625     OPC_SHRA_R_W   = (0x15 << 6) | OPC_SHLL_QB_DSP,
626     OPC_SHRAV_R_W  = (0x17 << 6) | OPC_SHLL_QB_DSP,
627 };
628
629 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
630 enum {
631     /* MIPS DSP Multiply Sub-class insns */
632     OPC_DPAU_H_QBL    = (0x03 << 6) | OPC_DPA_W_PH_DSP,
633     OPC_DPAU_H_QBR    = (0x07 << 6) | OPC_DPA_W_PH_DSP,
634     OPC_DPSU_H_QBL    = (0x0B << 6) | OPC_DPA_W_PH_DSP,
635     OPC_DPSU_H_QBR    = (0x0F << 6) | OPC_DPA_W_PH_DSP,
636     OPC_DPA_W_PH      = (0x00 << 6) | OPC_DPA_W_PH_DSP,
637     OPC_DPAX_W_PH     = (0x08 << 6) | OPC_DPA_W_PH_DSP,
638     OPC_DPAQ_S_W_PH   = (0x04 << 6) | OPC_DPA_W_PH_DSP,
639     OPC_DPAQX_S_W_PH  = (0x18 << 6) | OPC_DPA_W_PH_DSP,
640     OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
641     OPC_DPS_W_PH      = (0x01 << 6) | OPC_DPA_W_PH_DSP,
642     OPC_DPSX_W_PH     = (0x09 << 6) | OPC_DPA_W_PH_DSP,
643     OPC_DPSQ_S_W_PH   = (0x05 << 6) | OPC_DPA_W_PH_DSP,
644     OPC_DPSQX_S_W_PH  = (0x19 << 6) | OPC_DPA_W_PH_DSP,
645     OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
646     OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
647     OPC_DPAQ_SA_L_W   = (0x0C << 6) | OPC_DPA_W_PH_DSP,
648     OPC_DPSQ_SA_L_W   = (0x0D << 6) | OPC_DPA_W_PH_DSP,
649     OPC_MAQ_S_W_PHL   = (0x14 << 6) | OPC_DPA_W_PH_DSP,
650     OPC_MAQ_S_W_PHR   = (0x16 << 6) | OPC_DPA_W_PH_DSP,
651     OPC_MAQ_SA_W_PHL  = (0x10 << 6) | OPC_DPA_W_PH_DSP,
652     OPC_MAQ_SA_W_PHR  = (0x12 << 6) | OPC_DPA_W_PH_DSP,
653     OPC_MULSA_W_PH    = (0x02 << 6) | OPC_DPA_W_PH_DSP,
654 };
655
656 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
657 enum {
658     /* DSP Bit/Manipulation Sub-class */
659     OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
660 };
661
662 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
663 enum {
664     /* MIPS DSP Append Sub-class */
665     OPC_APPEND  = (0x00 << 6) | OPC_APPEND_DSP,
666     OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
667     OPC_BALIGN  = (0x10 << 6) | OPC_APPEND_DSP,
668 };
669
670 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
671 enum {
672     /* MIPS DSP Accumulator and DSPControl Access Sub-class */
673     OPC_EXTR_W     = (0x00 << 6) | OPC_EXTR_W_DSP,
674     OPC_EXTR_R_W   = (0x04 << 6) | OPC_EXTR_W_DSP,
675     OPC_EXTR_RS_W  = (0x06 << 6) | OPC_EXTR_W_DSP,
676     OPC_EXTR_S_H   = (0x0E << 6) | OPC_EXTR_W_DSP,
677     OPC_EXTRV_S_H  = (0x0F << 6) | OPC_EXTR_W_DSP,
678     OPC_EXTRV_W    = (0x01 << 6) | OPC_EXTR_W_DSP,
679     OPC_EXTRV_R_W  = (0x05 << 6) | OPC_EXTR_W_DSP,
680     OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
681     OPC_EXTP       = (0x02 << 6) | OPC_EXTR_W_DSP,
682     OPC_EXTPV      = (0x03 << 6) | OPC_EXTR_W_DSP,
683     OPC_EXTPDP     = (0x0A << 6) | OPC_EXTR_W_DSP,
684     OPC_EXTPDPV    = (0x0B << 6) | OPC_EXTR_W_DSP,
685     OPC_SHILO      = (0x1A << 6) | OPC_EXTR_W_DSP,
686     OPC_SHILOV     = (0x1B << 6) | OPC_EXTR_W_DSP,
687     OPC_MTHLIP     = (0x1F << 6) | OPC_EXTR_W_DSP,
688     OPC_WRDSP      = (0x13 << 6) | OPC_EXTR_W_DSP,
689     OPC_RDDSP      = (0x12 << 6) | OPC_EXTR_W_DSP,
690 };
691
692 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
693 enum {
694     /* MIPS DSP Arithmetic Sub-class */
695     OPC_PRECEQ_L_PWL    = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
696     OPC_PRECEQ_L_PWR    = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
697     OPC_PRECEQ_PW_QHL   = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
698     OPC_PRECEQ_PW_QHR   = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
699     OPC_PRECEQ_PW_QHLA  = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
700     OPC_PRECEQ_PW_QHRA  = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
701     OPC_PRECEQU_QH_OBL  = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
702     OPC_PRECEQU_QH_OBR  = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
703     OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
704     OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
705     OPC_PRECEU_QH_OBL   = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
706     OPC_PRECEU_QH_OBR   = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
707     OPC_PRECEU_QH_OBLA  = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
708     OPC_PRECEU_QH_OBRA  = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
709     OPC_ABSQ_S_OB       = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
710     OPC_ABSQ_S_PW       = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
711     OPC_ABSQ_S_QH       = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
712     /* DSP Bit/Manipulation Sub-class */
713     OPC_REPL_OB         = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
714     OPC_REPL_PW         = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
715     OPC_REPL_QH         = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
716     OPC_REPLV_OB        = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
717     OPC_REPLV_PW        = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
718     OPC_REPLV_QH        = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
719 };
720
721 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
722 enum {
723     /* MIPS DSP Multiply Sub-class insns */
724     OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
725     OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
726     OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
727     OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
728     OPC_MULQ_RS_QH     = (0x1F << 6) | OPC_ADDU_OB_DSP,
729     /* MIPS DSP Arithmetic Sub-class */
730     OPC_RADDU_L_OB     = (0x14 << 6) | OPC_ADDU_OB_DSP,
731     OPC_SUBQ_PW        = (0x13 << 6) | OPC_ADDU_OB_DSP,
732     OPC_SUBQ_S_PW      = (0x17 << 6) | OPC_ADDU_OB_DSP,
733     OPC_SUBQ_QH        = (0x0B << 6) | OPC_ADDU_OB_DSP,
734     OPC_SUBQ_S_QH      = (0x0F << 6) | OPC_ADDU_OB_DSP,
735     OPC_SUBU_OB        = (0x01 << 6) | OPC_ADDU_OB_DSP,
736     OPC_SUBU_S_OB      = (0x05 << 6) | OPC_ADDU_OB_DSP,
737     OPC_SUBU_QH        = (0x09 << 6) | OPC_ADDU_OB_DSP,
738     OPC_SUBU_S_QH      = (0x0D << 6) | OPC_ADDU_OB_DSP,
739     OPC_SUBUH_OB       = (0x19 << 6) | OPC_ADDU_OB_DSP,
740     OPC_SUBUH_R_OB     = (0x1B << 6) | OPC_ADDU_OB_DSP,
741     OPC_ADDQ_PW        = (0x12 << 6) | OPC_ADDU_OB_DSP,
742     OPC_ADDQ_S_PW      = (0x16 << 6) | OPC_ADDU_OB_DSP,
743     OPC_ADDQ_QH        = (0x0A << 6) | OPC_ADDU_OB_DSP,
744     OPC_ADDQ_S_QH      = (0x0E << 6) | OPC_ADDU_OB_DSP,
745     OPC_ADDU_OB        = (0x00 << 6) | OPC_ADDU_OB_DSP,
746     OPC_ADDU_S_OB      = (0x04 << 6) | OPC_ADDU_OB_DSP,
747     OPC_ADDU_QH        = (0x08 << 6) | OPC_ADDU_OB_DSP,
748     OPC_ADDU_S_QH      = (0x0C << 6) | OPC_ADDU_OB_DSP,
749     OPC_ADDUH_OB       = (0x18 << 6) | OPC_ADDU_OB_DSP,
750     OPC_ADDUH_R_OB     = (0x1A << 6) | OPC_ADDU_OB_DSP,
751 };
752
753 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
754 enum {
755     /* DSP Compare-Pick Sub-class */
756     OPC_CMP_EQ_PW         = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
757     OPC_CMP_LT_PW         = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
758     OPC_CMP_LE_PW         = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
759     OPC_CMP_EQ_QH         = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
760     OPC_CMP_LT_QH         = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
761     OPC_CMP_LE_QH         = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
762     OPC_CMPGDU_EQ_OB      = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
763     OPC_CMPGDU_LT_OB      = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
764     OPC_CMPGDU_LE_OB      = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
765     OPC_CMPGU_EQ_OB       = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
766     OPC_CMPGU_LT_OB       = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
767     OPC_CMPGU_LE_OB       = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
768     OPC_CMPU_EQ_OB        = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
769     OPC_CMPU_LT_OB        = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
770     OPC_CMPU_LE_OB        = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
771     OPC_PACKRL_PW         = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
772     OPC_PICK_OB           = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
773     OPC_PICK_PW           = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
774     OPC_PICK_QH           = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
775     /* MIPS DSP Arithmetic Sub-class */
776     OPC_PRECR_OB_QH       = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
777     OPC_PRECR_SRA_QH_PW   = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
778     OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
779     OPC_PRECRQ_OB_QH      = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
780     OPC_PRECRQ_PW_L       = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
781     OPC_PRECRQ_QH_PW      = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
782     OPC_PRECRQ_RS_QH_PW   = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
783     OPC_PRECRQU_S_OB_QH   = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
784 };
785
786 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
787 enum {
788     /* DSP Append Sub-class */
789     OPC_DAPPEND  = (0x00 << 6) | OPC_DAPPEND_DSP,
790     OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
791     OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
792     OPC_DBALIGN  = (0x10 << 6) | OPC_DAPPEND_DSP,
793 };
794
795 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
796 enum {
797     /* MIPS DSP Accumulator and DSPControl Access Sub-class */
798     OPC_DMTHLIP     = (0x1F << 6) | OPC_DEXTR_W_DSP,
799     OPC_DSHILO      = (0x1A << 6) | OPC_DEXTR_W_DSP,
800     OPC_DEXTP       = (0x02 << 6) | OPC_DEXTR_W_DSP,
801     OPC_DEXTPDP     = (0x0A << 6) | OPC_DEXTR_W_DSP,
802     OPC_DEXTPDPV    = (0x0B << 6) | OPC_DEXTR_W_DSP,
803     OPC_DEXTPV      = (0x03 << 6) | OPC_DEXTR_W_DSP,
804     OPC_DEXTR_L     = (0x10 << 6) | OPC_DEXTR_W_DSP,
805     OPC_DEXTR_R_L   = (0x14 << 6) | OPC_DEXTR_W_DSP,
806     OPC_DEXTR_RS_L  = (0x16 << 6) | OPC_DEXTR_W_DSP,
807     OPC_DEXTR_W     = (0x00 << 6) | OPC_DEXTR_W_DSP,
808     OPC_DEXTR_R_W   = (0x04 << 6) | OPC_DEXTR_W_DSP,
809     OPC_DEXTR_RS_W  = (0x06 << 6) | OPC_DEXTR_W_DSP,
810     OPC_DEXTR_S_H   = (0x0E << 6) | OPC_DEXTR_W_DSP,
811     OPC_DEXTRV_L    = (0x11 << 6) | OPC_DEXTR_W_DSP,
812     OPC_DEXTRV_R_L  = (0x15 << 6) | OPC_DEXTR_W_DSP,
813     OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
814     OPC_DEXTRV_S_H  = (0x0F << 6) | OPC_DEXTR_W_DSP,
815     OPC_DEXTRV_W    = (0x01 << 6) | OPC_DEXTR_W_DSP,
816     OPC_DEXTRV_R_W  = (0x05 << 6) | OPC_DEXTR_W_DSP,
817     OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
818     OPC_DSHILOV     = (0x1B << 6) | OPC_DEXTR_W_DSP,
819 };
820
821 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
822 enum {
823     /* DSP Bit/Manipulation Sub-class */
824     OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
825 };
826
827 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
828 enum {
829     /* MIPS DSP Multiply Sub-class insns */
830     OPC_DMADD         = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
831     OPC_DMADDU        = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
832     OPC_DMSUB         = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
833     OPC_DMSUBU        = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
834     OPC_DPA_W_QH      = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
835     OPC_DPAQ_S_W_QH   = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
836     OPC_DPAQ_SA_L_PW  = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
837     OPC_DPAU_H_OBL    = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
838     OPC_DPAU_H_OBR    = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
839     OPC_DPS_W_QH      = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
840     OPC_DPSQ_S_W_QH   = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
841     OPC_DPSQ_SA_L_PW  = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
842     OPC_DPSU_H_OBL    = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
843     OPC_DPSU_H_OBR    = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
844     OPC_MAQ_S_L_PWL   = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
845     OPC_MAQ_S_L_PWR   = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
846     OPC_MAQ_S_W_QHLL  = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
847     OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
848     OPC_MAQ_S_W_QHLR  = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
849     OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
850     OPC_MAQ_S_W_QHRL  = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
851     OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
852     OPC_MAQ_S_W_QHRR  = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
853     OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
854     OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
855     OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
856 };
857
858 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
859 enum {
860     /* MIPS DSP GPR-Based Shift Sub-class */
861     OPC_SHLL_PW    = (0x10 << 6) | OPC_SHLL_OB_DSP,
862     OPC_SHLL_S_PW  = (0x14 << 6) | OPC_SHLL_OB_DSP,
863     OPC_SHLLV_OB   = (0x02 << 6) | OPC_SHLL_OB_DSP,
864     OPC_SHLLV_PW   = (0x12 << 6) | OPC_SHLL_OB_DSP,
865     OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
866     OPC_SHLLV_QH   = (0x0A << 6) | OPC_SHLL_OB_DSP,
867     OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
868     OPC_SHRA_PW    = (0x11 << 6) | OPC_SHLL_OB_DSP,
869     OPC_SHRA_R_PW  = (0x15 << 6) | OPC_SHLL_OB_DSP,
870     OPC_SHRAV_OB   = (0x06 << 6) | OPC_SHLL_OB_DSP,
871     OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
872     OPC_SHRAV_PW   = (0x13 << 6) | OPC_SHLL_OB_DSP,
873     OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
874     OPC_SHRAV_QH   = (0x0B << 6) | OPC_SHLL_OB_DSP,
875     OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
876     OPC_SHRLV_OB   = (0x03 << 6) | OPC_SHLL_OB_DSP,
877     OPC_SHRLV_QH   = (0x1B << 6) | OPC_SHLL_OB_DSP,
878     OPC_SHLL_OB    = (0x00 << 6) | OPC_SHLL_OB_DSP,
879     OPC_SHLL_QH    = (0x08 << 6) | OPC_SHLL_OB_DSP,
880     OPC_SHLL_S_QH  = (0x0C << 6) | OPC_SHLL_OB_DSP,
881     OPC_SHRA_OB    = (0x04 << 6) | OPC_SHLL_OB_DSP,
882     OPC_SHRA_R_OB  = (0x05 << 6) | OPC_SHLL_OB_DSP,
883     OPC_SHRA_QH    = (0x09 << 6) | OPC_SHLL_OB_DSP,
884     OPC_SHRA_R_QH  = (0x0D << 6) | OPC_SHLL_OB_DSP,
885     OPC_SHRL_OB    = (0x01 << 6) | OPC_SHLL_OB_DSP,
886     OPC_SHRL_QH    = (0x19 << 6) | OPC_SHLL_OB_DSP,
887 };
888
889 /* Coprocessor 0 (rs field) */
890 #define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
891
892 enum {
893     OPC_MFC0     = (0x00 << 21) | OPC_CP0,
894     OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
895     OPC_MFHC0    = (0x02 << 21) | OPC_CP0,
896     OPC_MTC0     = (0x04 << 21) | OPC_CP0,
897     OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
898     OPC_MTHC0    = (0x06 << 21) | OPC_CP0,
899     OPC_MFTR     = (0x08 << 21) | OPC_CP0,
900     OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
901     OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
902     OPC_MTTR     = (0x0C << 21) | OPC_CP0,
903     OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
904     OPC_C0       = (0x10 << 21) | OPC_CP0,
905     OPC_C0_1     = (0x11 << 21) | OPC_CP0,
906     OPC_C0_2     = (0x12 << 21) | OPC_CP0,
907     OPC_C0_3     = (0x13 << 21) | OPC_CP0,
908     OPC_C0_4     = (0x14 << 21) | OPC_CP0,
909     OPC_C0_5     = (0x15 << 21) | OPC_CP0,
910     OPC_C0_6     = (0x16 << 21) | OPC_CP0,
911     OPC_C0_7     = (0x17 << 21) | OPC_CP0,
912     OPC_C0_8     = (0x18 << 21) | OPC_CP0,
913     OPC_C0_9     = (0x19 << 21) | OPC_CP0,
914     OPC_C0_A     = (0x1A << 21) | OPC_CP0,
915     OPC_C0_B     = (0x1B << 21) | OPC_CP0,
916     OPC_C0_C     = (0x1C << 21) | OPC_CP0,
917     OPC_C0_D     = (0x1D << 21) | OPC_CP0,
918     OPC_C0_E     = (0x1E << 21) | OPC_CP0,
919     OPC_C0_F     = (0x1F << 21) | OPC_CP0,
920 };
921
922 /* MFMC0 opcodes */
923 #define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
924
925 enum {
926     OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
927     OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
928     OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
929     OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
930     OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
931     OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
932     OPC_DVP      = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
933     OPC_EVP      = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
934 };
935
936 /* Coprocessor 0 (with rs == C0) */
937 #define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
938
939 enum {
940     OPC_TLBR     = 0x01 | OPC_C0,
941     OPC_TLBWI    = 0x02 | OPC_C0,
942     OPC_TLBINV   = 0x03 | OPC_C0,
943     OPC_TLBINVF  = 0x04 | OPC_C0,
944     OPC_TLBWR    = 0x06 | OPC_C0,
945     OPC_TLBP     = 0x08 | OPC_C0,
946     OPC_RFE      = 0x10 | OPC_C0,
947     OPC_ERET     = 0x18 | OPC_C0,
948     OPC_DERET    = 0x1F | OPC_C0,
949     OPC_WAIT     = 0x20 | OPC_C0,
950 };
951
952 /* Coprocessor 1 (rs field) */
953 #define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
954
955 /* Values for the fmt field in FP instructions */
956 enum {
957     /* 0 - 15 are reserved */
958     FMT_S = 16,          /* single fp */
959     FMT_D = 17,          /* double fp */
960     FMT_E = 18,          /* extended fp */
961     FMT_Q = 19,          /* quad fp */
962     FMT_W = 20,          /* 32-bit fixed */
963     FMT_L = 21,          /* 64-bit fixed */
964     FMT_PS = 22,         /* paired single fp */
965     /* 23 - 31 are reserved */
966 };
967
968 enum {
969     OPC_MFC1     = (0x00 << 21) | OPC_CP1,
970     OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
971     OPC_CFC1     = (0x02 << 21) | OPC_CP1,
972     OPC_MFHC1    = (0x03 << 21) | OPC_CP1,
973     OPC_MTC1     = (0x04 << 21) | OPC_CP1,
974     OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
975     OPC_CTC1     = (0x06 << 21) | OPC_CP1,
976     OPC_MTHC1    = (0x07 << 21) | OPC_CP1,
977     OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
978     OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
979     OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
980     OPC_BZ_V     = (0x0B << 21) | OPC_CP1,
981     OPC_BNZ_V    = (0x0F << 21) | OPC_CP1,
982     OPC_S_FMT    = (FMT_S << 21) | OPC_CP1,
983     OPC_D_FMT    = (FMT_D << 21) | OPC_CP1,
984     OPC_E_FMT    = (FMT_E << 21) | OPC_CP1,
985     OPC_Q_FMT    = (FMT_Q << 21) | OPC_CP1,
986     OPC_W_FMT    = (FMT_W << 21) | OPC_CP1,
987     OPC_L_FMT    = (FMT_L << 21) | OPC_CP1,
988     OPC_PS_FMT   = (FMT_PS << 21) | OPC_CP1,
989     OPC_BC1EQZ   = (0x09 << 21) | OPC_CP1,
990     OPC_BC1NEZ   = (0x0D << 21) | OPC_CP1,
991     OPC_BZ_B     = (0x18 << 21) | OPC_CP1,
992     OPC_BZ_H     = (0x19 << 21) | OPC_CP1,
993     OPC_BZ_W     = (0x1A << 21) | OPC_CP1,
994     OPC_BZ_D     = (0x1B << 21) | OPC_CP1,
995     OPC_BNZ_B    = (0x1C << 21) | OPC_CP1,
996     OPC_BNZ_H    = (0x1D << 21) | OPC_CP1,
997     OPC_BNZ_W    = (0x1E << 21) | OPC_CP1,
998     OPC_BNZ_D    = (0x1F << 21) | OPC_CP1,
999 };
1000
1001 #define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
1002 #define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
1003
1004 enum {
1005     OPC_BC1F     = (0x00 << 16) | OPC_BC1,
1006     OPC_BC1T     = (0x01 << 16) | OPC_BC1,
1007     OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
1008     OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
1009 };
1010
1011 enum {
1012     OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
1013     OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
1014 };
1015
1016 enum {
1017     OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
1018     OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
1019 };
1020
1021 #define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
1022
1023 enum {
1024     OPC_MFC2    = (0x00 << 21) | OPC_CP2,
1025     OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
1026     OPC_CFC2    = (0x02 << 21) | OPC_CP2,
1027     OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
1028     OPC_MTC2    = (0x04 << 21) | OPC_CP2,
1029     OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
1030     OPC_CTC2    = (0x06 << 21) | OPC_CP2,
1031     OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
1032     OPC_BC2     = (0x08 << 21) | OPC_CP2,
1033     OPC_BC2EQZ  = (0x09 << 21) | OPC_CP2,
1034     OPC_BC2NEZ  = (0x0D << 21) | OPC_CP2,
1035 };
1036
1037 #define MASK_LMI(op)  (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1038
1039 enum {
1040     OPC_PADDSH  = (24 << 21) | (0x00) | OPC_CP2,
1041     OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1042     OPC_PADDH   = (26 << 21) | (0x00) | OPC_CP2,
1043     OPC_PADDW   = (27 << 21) | (0x00) | OPC_CP2,
1044     OPC_PADDSB  = (28 << 21) | (0x00) | OPC_CP2,
1045     OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1046     OPC_PADDB   = (30 << 21) | (0x00) | OPC_CP2,
1047     OPC_PADDD   = (31 << 21) | (0x00) | OPC_CP2,
1048
1049     OPC_PSUBSH  = (24 << 21) | (0x01) | OPC_CP2,
1050     OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1051     OPC_PSUBH   = (26 << 21) | (0x01) | OPC_CP2,
1052     OPC_PSUBW   = (27 << 21) | (0x01) | OPC_CP2,
1053     OPC_PSUBSB  = (28 << 21) | (0x01) | OPC_CP2,
1054     OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1055     OPC_PSUBB   = (30 << 21) | (0x01) | OPC_CP2,
1056     OPC_PSUBD   = (31 << 21) | (0x01) | OPC_CP2,
1057
1058     OPC_PSHUFH   = (24 << 21) | (0x02) | OPC_CP2,
1059     OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1060     OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1061     OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1062     OPC_XOR_CP2  = (28 << 21) | (0x02) | OPC_CP2,
1063     OPC_NOR_CP2  = (29 << 21) | (0x02) | OPC_CP2,
1064     OPC_AND_CP2  = (30 << 21) | (0x02) | OPC_CP2,
1065     OPC_PANDN    = (31 << 21) | (0x02) | OPC_CP2,
1066
1067     OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1068     OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1069     OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1070     OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1071     OPC_PINSRH_0  = (28 << 21) | (0x03) | OPC_CP2,
1072     OPC_PINSRH_1  = (29 << 21) | (0x03) | OPC_CP2,
1073     OPC_PINSRH_2  = (30 << 21) | (0x03) | OPC_CP2,
1074     OPC_PINSRH_3  = (31 << 21) | (0x03) | OPC_CP2,
1075
1076     OPC_PAVGH   = (24 << 21) | (0x08) | OPC_CP2,
1077     OPC_PAVGB   = (25 << 21) | (0x08) | OPC_CP2,
1078     OPC_PMAXSH  = (26 << 21) | (0x08) | OPC_CP2,
1079     OPC_PMINSH  = (27 << 21) | (0x08) | OPC_CP2,
1080     OPC_PMAXUB  = (28 << 21) | (0x08) | OPC_CP2,
1081     OPC_PMINUB  = (29 << 21) | (0x08) | OPC_CP2,
1082
1083     OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1084     OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1085     OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1086     OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1087     OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1088     OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1089
1090     OPC_PSLLW   = (24 << 21) | (0x0A) | OPC_CP2,
1091     OPC_PSLLH   = (25 << 21) | (0x0A) | OPC_CP2,
1092     OPC_PMULLH  = (26 << 21) | (0x0A) | OPC_CP2,
1093     OPC_PMULHH  = (27 << 21) | (0x0A) | OPC_CP2,
1094     OPC_PMULUW  = (28 << 21) | (0x0A) | OPC_CP2,
1095     OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1096
1097     OPC_PSRLW     = (24 << 21) | (0x0B) | OPC_CP2,
1098     OPC_PSRLH     = (25 << 21) | (0x0B) | OPC_CP2,
1099     OPC_PSRAW     = (26 << 21) | (0x0B) | OPC_CP2,
1100     OPC_PSRAH     = (27 << 21) | (0x0B) | OPC_CP2,
1101     OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1102     OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1103
1104     OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1105     OPC_OR_CP2   = (25 << 21) | (0x0C) | OPC_CP2,
1106     OPC_ADD_CP2  = (26 << 21) | (0x0C) | OPC_CP2,
1107     OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1108     OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1109     OPC_SEQ_CP2  = (29 << 21) | (0x0C) | OPC_CP2,
1110
1111     OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1112     OPC_PASUBUB  = (25 << 21) | (0x0D) | OPC_CP2,
1113     OPC_SUB_CP2  = (26 << 21) | (0x0D) | OPC_CP2,
1114     OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1115     OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1116     OPC_SLT_CP2  = (29 << 21) | (0x0D) | OPC_CP2,
1117
1118     OPC_SLL_CP2  = (24 << 21) | (0x0E) | OPC_CP2,
1119     OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1120     OPC_PEXTRH   = (26 << 21) | (0x0E) | OPC_CP2,
1121     OPC_PMADDHW  = (27 << 21) | (0x0E) | OPC_CP2,
1122     OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1123     OPC_SLE_CP2  = (29 << 21) | (0x0E) | OPC_CP2,
1124
1125     OPC_SRL_CP2  = (24 << 21) | (0x0F) | OPC_CP2,
1126     OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1127     OPC_SRA_CP2  = (26 << 21) | (0x0F) | OPC_CP2,
1128     OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1129     OPC_BIADD    = (28 << 21) | (0x0F) | OPC_CP2,
1130     OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1131 };
1132
1133
1134 #define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
1135
1136 enum {
1137     OPC_LWXC1   = 0x00 | OPC_CP3,
1138     OPC_LDXC1   = 0x01 | OPC_CP3,
1139     OPC_LUXC1   = 0x05 | OPC_CP3,
1140     OPC_SWXC1   = 0x08 | OPC_CP3,
1141     OPC_SDXC1   = 0x09 | OPC_CP3,
1142     OPC_SUXC1   = 0x0D | OPC_CP3,
1143     OPC_PREFX   = 0x0F | OPC_CP3,
1144     OPC_ALNV_PS = 0x1E | OPC_CP3,
1145     OPC_MADD_S  = 0x20 | OPC_CP3,
1146     OPC_MADD_D  = 0x21 | OPC_CP3,
1147     OPC_MADD_PS = 0x26 | OPC_CP3,
1148     OPC_MSUB_S  = 0x28 | OPC_CP3,
1149     OPC_MSUB_D  = 0x29 | OPC_CP3,
1150     OPC_MSUB_PS = 0x2E | OPC_CP3,
1151     OPC_NMADD_S = 0x30 | OPC_CP3,
1152     OPC_NMADD_D = 0x31 | OPC_CP3,
1153     OPC_NMADD_PS= 0x36 | OPC_CP3,
1154     OPC_NMSUB_S = 0x38 | OPC_CP3,
1155     OPC_NMSUB_D = 0x39 | OPC_CP3,
1156     OPC_NMSUB_PS= 0x3E | OPC_CP3,
1157 };
1158
1159 /* MSA Opcodes */
1160 #define MASK_MSA_MINOR(op)    (MASK_OP_MAJOR(op) | (op & 0x3F))
1161 enum {
1162     OPC_MSA_I8_00   = 0x00 | OPC_MSA,
1163     OPC_MSA_I8_01   = 0x01 | OPC_MSA,
1164     OPC_MSA_I8_02   = 0x02 | OPC_MSA,
1165     OPC_MSA_I5_06   = 0x06 | OPC_MSA,
1166     OPC_MSA_I5_07   = 0x07 | OPC_MSA,
1167     OPC_MSA_BIT_09  = 0x09 | OPC_MSA,
1168     OPC_MSA_BIT_0A  = 0x0A | OPC_MSA,
1169     OPC_MSA_3R_0D   = 0x0D | OPC_MSA,
1170     OPC_MSA_3R_0E   = 0x0E | OPC_MSA,
1171     OPC_MSA_3R_0F   = 0x0F | OPC_MSA,
1172     OPC_MSA_3R_10   = 0x10 | OPC_MSA,
1173     OPC_MSA_3R_11   = 0x11 | OPC_MSA,
1174     OPC_MSA_3R_12   = 0x12 | OPC_MSA,
1175     OPC_MSA_3R_13   = 0x13 | OPC_MSA,
1176     OPC_MSA_3R_14   = 0x14 | OPC_MSA,
1177     OPC_MSA_3R_15   = 0x15 | OPC_MSA,
1178     OPC_MSA_ELM     = 0x19 | OPC_MSA,
1179     OPC_MSA_3RF_1A  = 0x1A | OPC_MSA,
1180     OPC_MSA_3RF_1B  = 0x1B | OPC_MSA,
1181     OPC_MSA_3RF_1C  = 0x1C | OPC_MSA,
1182     OPC_MSA_VEC     = 0x1E | OPC_MSA,
1183
1184     /* MI10 instruction */
1185     OPC_LD_B    = (0x20) | OPC_MSA,
1186     OPC_LD_H    = (0x21) | OPC_MSA,
1187     OPC_LD_W    = (0x22) | OPC_MSA,
1188     OPC_LD_D    = (0x23) | OPC_MSA,
1189     OPC_ST_B    = (0x24) | OPC_MSA,
1190     OPC_ST_H    = (0x25) | OPC_MSA,
1191     OPC_ST_W    = (0x26) | OPC_MSA,
1192     OPC_ST_D    = (0x27) | OPC_MSA,
1193 };
1194
1195 enum {
1196     /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1197     OPC_ADDVI_df    = (0x0 << 23) | OPC_MSA_I5_06,
1198     OPC_CEQI_df     = (0x0 << 23) | OPC_MSA_I5_07,
1199     OPC_SUBVI_df    = (0x1 << 23) | OPC_MSA_I5_06,
1200     OPC_MAXI_S_df   = (0x2 << 23) | OPC_MSA_I5_06,
1201     OPC_CLTI_S_df   = (0x2 << 23) | OPC_MSA_I5_07,
1202     OPC_MAXI_U_df   = (0x3 << 23) | OPC_MSA_I5_06,
1203     OPC_CLTI_U_df   = (0x3 << 23) | OPC_MSA_I5_07,
1204     OPC_MINI_S_df   = (0x4 << 23) | OPC_MSA_I5_06,
1205     OPC_CLEI_S_df   = (0x4 << 23) | OPC_MSA_I5_07,
1206     OPC_MINI_U_df   = (0x5 << 23) | OPC_MSA_I5_06,
1207     OPC_CLEI_U_df   = (0x5 << 23) | OPC_MSA_I5_07,
1208     OPC_LDI_df      = (0x6 << 23) | OPC_MSA_I5_07,
1209
1210     /* I8 instruction */
1211     OPC_ANDI_B  = (0x0 << 24) | OPC_MSA_I8_00,
1212     OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1213     OPC_SHF_B   = (0x0 << 24) | OPC_MSA_I8_02,
1214     OPC_ORI_B   = (0x1 << 24) | OPC_MSA_I8_00,
1215     OPC_BMZI_B  = (0x1 << 24) | OPC_MSA_I8_01,
1216     OPC_SHF_H   = (0x1 << 24) | OPC_MSA_I8_02,
1217     OPC_NORI_B  = (0x2 << 24) | OPC_MSA_I8_00,
1218     OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1219     OPC_SHF_W   = (0x2 << 24) | OPC_MSA_I8_02,
1220     OPC_XORI_B  = (0x3 << 24) | OPC_MSA_I8_00,
1221
1222     /* VEC/2R/2RF instruction */
1223     OPC_AND_V   = (0x00 << 21) | OPC_MSA_VEC,
1224     OPC_OR_V    = (0x01 << 21) | OPC_MSA_VEC,
1225     OPC_NOR_V   = (0x02 << 21) | OPC_MSA_VEC,
1226     OPC_XOR_V   = (0x03 << 21) | OPC_MSA_VEC,
1227     OPC_BMNZ_V  = (0x04 << 21) | OPC_MSA_VEC,
1228     OPC_BMZ_V   = (0x05 << 21) | OPC_MSA_VEC,
1229     OPC_BSEL_V  = (0x06 << 21) | OPC_MSA_VEC,
1230
1231     OPC_MSA_2R      = (0x18 << 21) | OPC_MSA_VEC,
1232     OPC_MSA_2RF     = (0x19 << 21) | OPC_MSA_VEC,
1233
1234     /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1235     OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1236     OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1237     OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1238     OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1239
1240     /* 2RF instruction df(bit 16) = _w, _d */
1241     OPC_FCLASS_df   = (0x00 << 17) | OPC_MSA_2RF,
1242     OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1243     OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1244     OPC_FSQRT_df    = (0x03 << 17) | OPC_MSA_2RF,
1245     OPC_FRSQRT_df   = (0x04 << 17) | OPC_MSA_2RF,
1246     OPC_FRCP_df     = (0x05 << 17) | OPC_MSA_2RF,
1247     OPC_FRINT_df    = (0x06 << 17) | OPC_MSA_2RF,
1248     OPC_FLOG2_df    = (0x07 << 17) | OPC_MSA_2RF,
1249     OPC_FEXUPL_df   = (0x08 << 17) | OPC_MSA_2RF,
1250     OPC_FEXUPR_df   = (0x09 << 17) | OPC_MSA_2RF,
1251     OPC_FFQL_df     = (0x0A << 17) | OPC_MSA_2RF,
1252     OPC_FFQR_df     = (0x0B << 17) | OPC_MSA_2RF,
1253     OPC_FTINT_S_df  = (0x0C << 17) | OPC_MSA_2RF,
1254     OPC_FTINT_U_df  = (0x0D << 17) | OPC_MSA_2RF,
1255     OPC_FFINT_S_df  = (0x0E << 17) | OPC_MSA_2RF,
1256     OPC_FFINT_U_df  = (0x0F << 17) | OPC_MSA_2RF,
1257
1258     /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1259     OPC_SLL_df      = (0x0 << 23) | OPC_MSA_3R_0D,
1260     OPC_ADDV_df     = (0x0 << 23) | OPC_MSA_3R_0E,
1261     OPC_CEQ_df      = (0x0 << 23) | OPC_MSA_3R_0F,
1262     OPC_ADD_A_df    = (0x0 << 23) | OPC_MSA_3R_10,
1263     OPC_SUBS_S_df   = (0x0 << 23) | OPC_MSA_3R_11,
1264     OPC_MULV_df     = (0x0 << 23) | OPC_MSA_3R_12,
1265     OPC_DOTP_S_df   = (0x0 << 23) | OPC_MSA_3R_13,
1266     OPC_SLD_df      = (0x0 << 23) | OPC_MSA_3R_14,
1267     OPC_VSHF_df     = (0x0 << 23) | OPC_MSA_3R_15,
1268     OPC_SRA_df      = (0x1 << 23) | OPC_MSA_3R_0D,
1269     OPC_SUBV_df     = (0x1 << 23) | OPC_MSA_3R_0E,
1270     OPC_ADDS_A_df   = (0x1 << 23) | OPC_MSA_3R_10,
1271     OPC_SUBS_U_df   = (0x1 << 23) | OPC_MSA_3R_11,
1272     OPC_MADDV_df    = (0x1 << 23) | OPC_MSA_3R_12,
1273     OPC_DOTP_U_df   = (0x1 << 23) | OPC_MSA_3R_13,
1274     OPC_SPLAT_df    = (0x1 << 23) | OPC_MSA_3R_14,
1275     OPC_SRAR_df     = (0x1 << 23) | OPC_MSA_3R_15,
1276     OPC_SRL_df      = (0x2 << 23) | OPC_MSA_3R_0D,
1277     OPC_MAX_S_df    = (0x2 << 23) | OPC_MSA_3R_0E,
1278     OPC_CLT_S_df    = (0x2 << 23) | OPC_MSA_3R_0F,
1279     OPC_ADDS_S_df   = (0x2 << 23) | OPC_MSA_3R_10,
1280     OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1281     OPC_MSUBV_df    = (0x2 << 23) | OPC_MSA_3R_12,
1282     OPC_DPADD_S_df  = (0x2 << 23) | OPC_MSA_3R_13,
1283     OPC_PCKEV_df    = (0x2 << 23) | OPC_MSA_3R_14,
1284     OPC_SRLR_df     = (0x2 << 23) | OPC_MSA_3R_15,
1285     OPC_BCLR_df     = (0x3 << 23) | OPC_MSA_3R_0D,
1286     OPC_MAX_U_df    = (0x3 << 23) | OPC_MSA_3R_0E,
1287     OPC_CLT_U_df    = (0x3 << 23) | OPC_MSA_3R_0F,
1288     OPC_ADDS_U_df   = (0x3 << 23) | OPC_MSA_3R_10,
1289     OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1290     OPC_DPADD_U_df  = (0x3 << 23) | OPC_MSA_3R_13,
1291     OPC_PCKOD_df    = (0x3 << 23) | OPC_MSA_3R_14,
1292     OPC_BSET_df     = (0x4 << 23) | OPC_MSA_3R_0D,
1293     OPC_MIN_S_df    = (0x4 << 23) | OPC_MSA_3R_0E,
1294     OPC_CLE_S_df    = (0x4 << 23) | OPC_MSA_3R_0F,
1295     OPC_AVE_S_df    = (0x4 << 23) | OPC_MSA_3R_10,
1296     OPC_ASUB_S_df   = (0x4 << 23) | OPC_MSA_3R_11,
1297     OPC_DIV_S_df    = (0x4 << 23) | OPC_MSA_3R_12,
1298     OPC_DPSUB_S_df  = (0x4 << 23) | OPC_MSA_3R_13,
1299     OPC_ILVL_df     = (0x4 << 23) | OPC_MSA_3R_14,
1300     OPC_HADD_S_df   = (0x4 << 23) | OPC_MSA_3R_15,
1301     OPC_BNEG_df     = (0x5 << 23) | OPC_MSA_3R_0D,
1302     OPC_MIN_U_df    = (0x5 << 23) | OPC_MSA_3R_0E,
1303     OPC_CLE_U_df    = (0x5 << 23) | OPC_MSA_3R_0F,
1304     OPC_AVE_U_df    = (0x5 << 23) | OPC_MSA_3R_10,
1305     OPC_ASUB_U_df   = (0x5 << 23) | OPC_MSA_3R_11,
1306     OPC_DIV_U_df    = (0x5 << 23) | OPC_MSA_3R_12,
1307     OPC_DPSUB_U_df  = (0x5 << 23) | OPC_MSA_3R_13,
1308     OPC_ILVR_df     = (0x5 << 23) | OPC_MSA_3R_14,
1309     OPC_HADD_U_df   = (0x5 << 23) | OPC_MSA_3R_15,
1310     OPC_BINSL_df    = (0x6 << 23) | OPC_MSA_3R_0D,
1311     OPC_MAX_A_df    = (0x6 << 23) | OPC_MSA_3R_0E,
1312     OPC_AVER_S_df   = (0x6 << 23) | OPC_MSA_3R_10,
1313     OPC_MOD_S_df    = (0x6 << 23) | OPC_MSA_3R_12,
1314     OPC_ILVEV_df    = (0x6 << 23) | OPC_MSA_3R_14,
1315     OPC_HSUB_S_df   = (0x6 << 23) | OPC_MSA_3R_15,
1316     OPC_BINSR_df    = (0x7 << 23) | OPC_MSA_3R_0D,
1317     OPC_MIN_A_df    = (0x7 << 23) | OPC_MSA_3R_0E,
1318     OPC_AVER_U_df   = (0x7 << 23) | OPC_MSA_3R_10,
1319     OPC_MOD_U_df    = (0x7 << 23) | OPC_MSA_3R_12,
1320     OPC_ILVOD_df    = (0x7 << 23) | OPC_MSA_3R_14,
1321     OPC_HSUB_U_df   = (0x7 << 23) | OPC_MSA_3R_15,
1322
1323     /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1324     OPC_SLDI_df     = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1325     OPC_CTCMSA      = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1326     OPC_SPLATI_df   = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1327     OPC_CFCMSA      = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1328     OPC_COPY_S_df   = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1329     OPC_MOVE_V      = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1330     OPC_COPY_U_df   = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1331     OPC_INSERT_df   = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1332     OPC_INSVE_df    = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1333
1334     /* 3RF instruction _df(bit 21) = _w, _d */
1335     OPC_FCAF_df     = (0x0 << 22) | OPC_MSA_3RF_1A,
1336     OPC_FADD_df     = (0x0 << 22) | OPC_MSA_3RF_1B,
1337     OPC_FCUN_df     = (0x1 << 22) | OPC_MSA_3RF_1A,
1338     OPC_FSUB_df     = (0x1 << 22) | OPC_MSA_3RF_1B,
1339     OPC_FCOR_df     = (0x1 << 22) | OPC_MSA_3RF_1C,
1340     OPC_FCEQ_df     = (0x2 << 22) | OPC_MSA_3RF_1A,
1341     OPC_FMUL_df     = (0x2 << 22) | OPC_MSA_3RF_1B,
1342     OPC_FCUNE_df    = (0x2 << 22) | OPC_MSA_3RF_1C,
1343     OPC_FCUEQ_df    = (0x3 << 22) | OPC_MSA_3RF_1A,
1344     OPC_FDIV_df     = (0x3 << 22) | OPC_MSA_3RF_1B,
1345     OPC_FCNE_df     = (0x3 << 22) | OPC_MSA_3RF_1C,
1346     OPC_FCLT_df     = (0x4 << 22) | OPC_MSA_3RF_1A,
1347     OPC_FMADD_df    = (0x4 << 22) | OPC_MSA_3RF_1B,
1348     OPC_MUL_Q_df    = (0x4 << 22) | OPC_MSA_3RF_1C,
1349     OPC_FCULT_df    = (0x5 << 22) | OPC_MSA_3RF_1A,
1350     OPC_FMSUB_df    = (0x5 << 22) | OPC_MSA_3RF_1B,
1351     OPC_MADD_Q_df   = (0x5 << 22) | OPC_MSA_3RF_1C,
1352     OPC_FCLE_df     = (0x6 << 22) | OPC_MSA_3RF_1A,
1353     OPC_MSUB_Q_df   = (0x6 << 22) | OPC_MSA_3RF_1C,
1354     OPC_FCULE_df    = (0x7 << 22) | OPC_MSA_3RF_1A,
1355     OPC_FEXP2_df    = (0x7 << 22) | OPC_MSA_3RF_1B,
1356     OPC_FSAF_df     = (0x8 << 22) | OPC_MSA_3RF_1A,
1357     OPC_FEXDO_df    = (0x8 << 22) | OPC_MSA_3RF_1B,
1358     OPC_FSUN_df     = (0x9 << 22) | OPC_MSA_3RF_1A,
1359     OPC_FSOR_df     = (0x9 << 22) | OPC_MSA_3RF_1C,
1360     OPC_FSEQ_df     = (0xA << 22) | OPC_MSA_3RF_1A,
1361     OPC_FTQ_df      = (0xA << 22) | OPC_MSA_3RF_1B,
1362     OPC_FSUNE_df    = (0xA << 22) | OPC_MSA_3RF_1C,
1363     OPC_FSUEQ_df    = (0xB << 22) | OPC_MSA_3RF_1A,
1364     OPC_FSNE_df     = (0xB << 22) | OPC_MSA_3RF_1C,
1365     OPC_FSLT_df     = (0xC << 22) | OPC_MSA_3RF_1A,
1366     OPC_FMIN_df     = (0xC << 22) | OPC_MSA_3RF_1B,
1367     OPC_MULR_Q_df   = (0xC << 22) | OPC_MSA_3RF_1C,
1368     OPC_FSULT_df    = (0xD << 22) | OPC_MSA_3RF_1A,
1369     OPC_FMIN_A_df   = (0xD << 22) | OPC_MSA_3RF_1B,
1370     OPC_MADDR_Q_df  = (0xD << 22) | OPC_MSA_3RF_1C,
1371     OPC_FSLE_df     = (0xE << 22) | OPC_MSA_3RF_1A,
1372     OPC_FMAX_df     = (0xE << 22) | OPC_MSA_3RF_1B,
1373     OPC_MSUBR_Q_df  = (0xE << 22) | OPC_MSA_3RF_1C,
1374     OPC_FSULE_df    = (0xF << 22) | OPC_MSA_3RF_1A,
1375     OPC_FMAX_A_df   = (0xF << 22) | OPC_MSA_3RF_1B,
1376
1377     /* BIT instruction df(bits 22..16) = _B _H _W _D */
1378     OPC_SLLI_df     = (0x0 << 23) | OPC_MSA_BIT_09,
1379     OPC_SAT_S_df    = (0x0 << 23) | OPC_MSA_BIT_0A,
1380     OPC_SRAI_df     = (0x1 << 23) | OPC_MSA_BIT_09,
1381     OPC_SAT_U_df    = (0x1 << 23) | OPC_MSA_BIT_0A,
1382     OPC_SRLI_df     = (0x2 << 23) | OPC_MSA_BIT_09,
1383     OPC_SRARI_df    = (0x2 << 23) | OPC_MSA_BIT_0A,
1384     OPC_BCLRI_df    = (0x3 << 23) | OPC_MSA_BIT_09,
1385     OPC_SRLRI_df    = (0x3 << 23) | OPC_MSA_BIT_0A,
1386     OPC_BSETI_df    = (0x4 << 23) | OPC_MSA_BIT_09,
1387     OPC_BNEGI_df    = (0x5 << 23) | OPC_MSA_BIT_09,
1388     OPC_BINSLI_df   = (0x6 << 23) | OPC_MSA_BIT_09,
1389     OPC_BINSRI_df   = (0x7 << 23) | OPC_MSA_BIT_09,
1390 };
1391
1392
1393 /*
1394  *    AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
1395  *    ============================================
1396  *
1397  * MXU (full name: MIPS eXtension/enhanced Unit) is an SIMD extension of MIPS32
1398  * instructions set. It is designed to fit the needs of signal, graphical and
1399  * video processing applications. MXU instruction set is used in Xburst family
1400  * of microprocessors by Ingenic.
1401  *
1402  * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X16 is
1403  * the control register.
1404  *
1405  * The notation used in MXU assembler mnemonics:
1406  *
1407  *   XRa, XRb, XRc, XRd - MXU registers
1408  *   Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
1409  *   s12                - a subfield of an instruction code
1410  *   strd2              - a subfield of an instruction code
1411  *   eptn2              - a subfield of an instruction code
1412  *   eptn3              - a subfield of an instruction code
1413  *   optn2              - a subfield of an instruction code
1414  *   optn3              - a subfield of an instruction code
1415  *   sft4               - a subfield of an instruction code
1416  *
1417  * Load/Store instructions           Multiplication instructions
1418  * -----------------------           ---------------------------
1419  *
1420  *  S32LDD XRa, Rb, s12               S32MADD XRa, XRd, Rs, Rt
1421  *  S32STD XRa, Rb, s12               S32MADDU XRa, XRd, Rs, Rt
1422  *  S32LDDV XRa, Rb, rc, strd2        S32SUB XRa, XRd, Rs, Rt
1423  *  S32STDV XRa, Rb, rc, strd2        S32SUBU XRa, XRd, Rs, Rt
1424  *  S32LDI XRa, Rb, s12               S32MUL XRa, XRd, Rs, Rt
1425  *  S32SDI XRa, Rb, s12               S32MULU XRa, XRd, Rs, Rt
1426  *  S32LDIV XRa, Rb, rc, strd2        D16MUL XRa, XRb, XRc, XRd, optn2
1427  *  S32SDIV XRa, Rb, rc, strd2        D16MULE XRa, XRb, XRc, optn2
1428  *  S32LDDR XRa, Rb, s12              D16MULF XRa, XRb, XRc, optn2
1429  *  S32STDR XRa, Rb, s12              D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
1430  *  S32LDDVR XRa, Rb, rc, strd2       D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
1431  *  S32STDVR XRa, Rb, rc, strd2       D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
1432  *  S32LDIR XRa, Rb, s12              D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
1433  *  S32SDIR XRa, Rb, s12              S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
1434  *  S32LDIVR XRa, Rb, rc, strd2       Q8MUL XRa, XRb, XRc, XRd
1435  *  S32SDIVR XRa, Rb, rc, strd2       Q8MULSU XRa, XRb, XRc, XRd
1436  *  S16LDD XRa, Rb, s10, eptn2        Q8MAC XRa, XRb, XRc, XRd, aptn2
1437  *  S16STD XRa, Rb, s10, eptn2        Q8MACSU XRa, XRb, XRc, XRd, aptn2
1438  *  S16LDI XRa, Rb, s10, eptn2        Q8MADL XRa, XRb, XRc, XRd, aptn2
1439  *  S16SDI XRa, Rb, s10, eptn2
1440  *  S8LDD XRa, Rb, s8, eptn3
1441  *  S8STD XRa, Rb, s8, eptn3         Addition and subtraction instructions
1442  *  S8LDI XRa, Rb, s8, eptn3         -------------------------------------
1443  *  S8SDI XRa, Rb, s8, eptn3
1444  *  LXW Rd, Rs, Rt, strd2             D32ADD XRa, XRb, XRc, XRd, eptn2
1445  *  LXH Rd, Rs, Rt, strd2             D32ADDC XRa, XRb, XRc, XRd
1446  *  LXHU Rd, Rs, Rt, strd2            D32ACC XRa, XRb, XRc, XRd, eptn2
1447  *  LXB Rd, Rs, Rt, strd2             D32ACCM XRa, XRb, XRc, XRd, eptn2
1448  *  LXBU Rd, Rs, Rt, strd2            D32ASUM XRa, XRb, XRc, XRd, eptn2
1449  *                                    S32CPS XRa, XRb, XRc
1450  *                                    Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
1451  * Comparison instructions            Q16ACC XRa, XRb, XRc, XRd, eptn2
1452  * -----------------------            Q16ACCM XRa, XRb, XRc, XRd, eptn2
1453  *                                    D16ASUM XRa, XRb, XRc, XRd, eptn2
1454  *  S32MAX XRa, XRb, XRc              D16CPS XRa, XRb,
1455  *  S32MIN XRa, XRb, XRc              D16AVG XRa, XRb, XRc
1456  *  S32SLT XRa, XRb, XRc              D16AVGR XRa, XRb, XRc
1457  *  S32MOVZ XRa, XRb, XRc             Q8ADD XRa, XRb, XRc, eptn2
1458  *  S32MOVN XRa, XRb, XRc             Q8ADDE XRa, XRb, XRc, XRd, eptn2
1459  *  D16MAX XRa, XRb, XRc              Q8ACCE XRa, XRb, XRc, XRd, eptn2
1460  *  D16MIN XRa, XRb, XRc              Q8ABD XRa, XRb, XRc
1461  *  D16SLT XRa, XRb, XRc              Q8SAD XRa, XRb, XRc, XRd
1462  *  D16MOVZ XRa, XRb, XRc             Q8AVG XRa, XRb, XRc
1463  *  D16MOVN XRa, XRb, XRc             Q8AVGR XRa, XRb, XRc
1464  *  Q8MAX XRa, XRb, XRc               D8SUM XRa, XRb, XRc, XRd
1465  *  Q8MIN XRa, XRb, XRc               D8SUMC XRa, XRb, XRc, XRd
1466  *  Q8SLT XRa, XRb, XRc
1467  *  Q8SLTU XRa, XRb, XRc
1468  *  Q8MOVZ XRa, XRb, XRc             Shift instructions
1469  *  Q8MOVN XRa, XRb, XRc             ------------------
1470  *
1471  *                                    D32SLL XRa, XRb, XRc, XRd, sft4
1472  * Bitwise instructions               D32SLR XRa, XRb, XRc, XRd, sft4
1473  * --------------------               D32SAR XRa, XRb, XRc, XRd, sft4
1474  *                                    D32SARL XRa, XRb, XRc, sft4
1475  *  S32NOR XRa, XRb, XRc              D32SLLV XRa, XRb, Rb
1476  *  S32AND XRa, XRb, XRc              D32SLRV XRa, XRb, Rb
1477  *  S32XOR XRa, XRb, XRc              D32SARV XRa, XRb, Rb
1478  *  S32OR XRa, XRb, XRc               D32SARW XRa, XRb, XRc, Rb
1479  *                                    Q16SLL XRa, XRb, XRc, XRd, sft4
1480  *                                    Q16SLR XRa, XRb, XRc, XRd, sft4
1481  * Miscelaneous instructions          Q16SAR XRa, XRb, XRc, XRd, sft4
1482  * -------------------------          Q16SLLV XRa, XRb, Rb
1483  *                                    Q16SLRV XRa, XRb, Rb
1484  *  S32SFL XRa, XRb, XRc, XRd, optn2  Q16SARV XRa, XRb, Rb
1485  *  S32ALN XRa, XRb, XRc, Rb
1486  *  S32ALNI XRa, XRb, XRc, s3
1487  *  S32LUI XRa, s8, optn3            Move instructions
1488  *  S32EXTR XRa, XRb, Rb, bits5      -----------------
1489  *  S32EXTRV XRa, XRb, Rs, Rt
1490  *  Q16SCOP XRa, XRb, XRc, XRd        S32M2I XRa, Rb
1491  *  Q16SAT XRa, XRb, XRc              S32I2M XRa, Rb
1492  *
1493  *
1494  *              bits
1495  *             05..00
1496  *
1497  *          â”Œâ”€ 000000 â”€ OPC_MXU_S32MADD
1498  *          â”œâ”€ 000001 â”€ OPC_MXU_S32MADDU
1499  *          â”œâ”€ 000010 â”€ <not assigned>
1500  *          â”‚                               20..18
1501  *          â”œâ”€ 000011 â”€ OPC_MXU__POOL00 â”€â”¬â”€ 000 â”€ OPC_MXU_S32MAX
1502  *          â”‚                            â”œâ”€ 001 â”€ OPC_MXU_S32MIN
1503  *          â”‚                            â”œâ”€ 010 â”€ OPC_MXU_D16MAX
1504  *          â”‚                            â”œâ”€ 011 â”€ OPC_MXU_D16MIN
1505  *          â”‚                            â”œâ”€ 100 â”€ OPC_MXU_Q8MAX
1506  *          â”‚                            â”œâ”€ 101 â”€ OPC_MXU_Q8MIN
1507  *          â”‚                            â”œâ”€ 110 â”€ OPC_MXU_Q8SLT
1508  *          â”‚                            â””─ 111 â”€ OPC_MXU_Q8SLTU
1509  *          â”œâ”€ 000100 â”€ OPC_MXU_S32MSUB
1510  *          â”œâ”€ 000101 â”€ OPC_MXU_S32MSUBU    20..18
1511  *          â”œâ”€ 000110 â”€ OPC_MXU__POOL01 â”€â”¬â”€ 000 â”€ OPC_MXU_S32SLT
1512  *          â”‚                            â”œâ”€ 001 â”€ OPC_MXU_D16SLT
1513  *          â”‚                            â”œâ”€ 010 â”€ OPC_MXU_D16AVG
1514  *          â”‚                            â”œâ”€ 011 â”€ OPC_MXU_D16AVGR
1515  *          â”‚                            â”œâ”€ 100 â”€ OPC_MXU_Q8AVG
1516  *          â”‚                            â”œâ”€ 101 â”€ OPC_MXU_Q8AVGR
1517  *          â”‚                            â””─ 111 â”€ OPC_MXU_Q8ADD
1518  *          â”‚
1519  *          â”‚                               20..18
1520  *          â”œâ”€ 000111 â”€ OPC_MXU__POOL02 â”€â”¬â”€ 000 â”€ OPC_MXU_S32CPS
1521  *          â”‚                            â”œâ”€ 010 â”€ OPC_MXU_D16CPS
1522  *          â”‚                            â”œâ”€ 100 â”€ OPC_MXU_Q8ABD
1523  *          â”‚                            â””─ 110 â”€ OPC_MXU_Q16SAT
1524  *          â”œâ”€ 001000 â”€ OPC_MXU_D16MUL
1525  *          â”‚                               25..24
1526  *          â”œâ”€ 001001 â”€ OPC_MXU__POOL03 â”€â”¬â”€ 00 â”€ OPC_MXU_D16MULF
1527  *          â”‚                            â””─ 01 â”€ OPC_MXU_D16MULE
1528  *          â”œâ”€ 001010 â”€ OPC_MXU_D16MAC
1529  *          â”œâ”€ 001011 â”€ OPC_MXU_D16MACF
1530  *          â”œâ”€ 001100 â”€ OPC_MXU_D16MADL
1531  *          â”‚                               25..24
1532  *          â”œâ”€ 001101 â”€ OPC_MXU__POOL04 â”€â”¬â”€ 00 â”€ OPC_MXU_S16MAD
1533  *          â”‚                            â””─ 01 â”€ OPC_MXU_S16MAD_1
1534  *          â”œâ”€ 001110 â”€ OPC_MXU_Q16ADD
1535  *          â”œâ”€ 001111 â”€ OPC_MXU_D16MACE
1536  *          â”‚                               23
1537  *          â”œâ”€ 010000 â”€ OPC_MXU__POOL05 â”€â”¬â”€ 0 â”€ OPC_MXU_S32LDD
1538  *          â”‚                            â””─ 1 â”€ OPC_MXU_S32LDDR
1539  *          â”‚
1540  *          â”‚                               23
1541  *          â”œâ”€ 010001 â”€ OPC_MXU__POOL06 â”€â”¬â”€ 0 â”€ OPC_MXU_S32STD
1542  *          â”‚                            â””─ 1 â”€ OPC_MXU_S32STDR
1543  *          â”‚
1544  *          â”‚                               13..10
1545  *          â”œâ”€ 010010 â”€ OPC_MXU__POOL07 â”€â”¬â”€ 0000 â”€ OPC_MXU_S32LDDV
1546  *          â”‚                            â””─ 0001 â”€ OPC_MXU_S32LDDVR
1547  *          â”‚
1548  *          â”‚                               13..10
1549  *          â”œâ”€ 010011 â”€ OPC_MXU__POOL08 â”€â”¬â”€ 0000 â”€ OPC_MXU_S32STDV
1550  *          â”‚                            â””─ 0001 â”€ OPC_MXU_S32STDVR
1551  *          â”‚
1552  *          â”‚                               23
1553  *          â”œâ”€ 010100 â”€ OPC_MXU__POOL09 â”€â”¬â”€ 0 â”€ OPC_MXU_S32LDI
1554  *          â”‚                            â””─ 1 â”€ OPC_MXU_S32LDIR
1555  *          â”‚
1556  *          â”‚                               23
1557  *          â”œâ”€ 010101 â”€ OPC_MXU__POOL10 â”€â”¬â”€ 0 â”€ OPC_MXU_S32SDI
1558  *          â”‚                            â””─ 1 â”€ OPC_MXU_S32SDIR
1559  *          â”‚
1560  *          â”‚                               13..10
1561  *          â”œâ”€ 010110 â”€ OPC_MXU__POOL11 â”€â”¬â”€ 0000 â”€ OPC_MXU_S32LDIV
1562  *          â”‚                            â””─ 0001 â”€ OPC_MXU_S32LDIVR
1563  *          â”‚
1564  *          â”‚                               13..10
1565  *          â”œâ”€ 010111 â”€ OPC_MXU__POOL12 â”€â”¬â”€ 0000 â”€ OPC_MXU_S32SDIV
1566  *          â”‚                            â””─ 0001 â”€ OPC_MXU_S32SDIVR
1567  *          â”œâ”€ 011000 â”€ OPC_MXU_D32ADD
1568  *          â”‚                               23..22
1569  *   MXU    â”œâ”€ 011001 â”€ OPC_MXU__POOL13 â”€â”¬â”€ 00 â”€ OPC_MXU_D32ACC
1570  * opcodes â”€â”¤                            â”œâ”€ 01 â”€ OPC_MXU_D32ACCM
1571  *          â”‚                            â””─ 10 â”€ OPC_MXU_D32ASUM
1572  *          â”œâ”€ 011010 â”€ <not assigned>
1573  *          â”‚                               23..22
1574  *          â”œâ”€ 011011 â”€ OPC_MXU__POOL14 â”€â”¬â”€ 00 â”€ OPC_MXU_Q16ACC
1575  *          â”‚                            â”œâ”€ 01 â”€ OPC_MXU_Q16ACCM
1576  *          â”‚                            â””─ 10 â”€ OPC_MXU_Q16ASUM
1577  *          â”‚
1578  *          â”‚                               23..22
1579  *          â”œâ”€ 011100 â”€ OPC_MXU__POOL15 â”€â”¬â”€ 00 â”€ OPC_MXU_Q8ADDE
1580  *          â”‚                            â”œâ”€ 01 â”€ OPC_MXU_D8SUM
1581  *          â”œâ”€ 011101 â”€ OPC_MXU_Q8ACCE   â””─ 10 â”€ OPC_MXU_D8SUMC
1582  *          â”œâ”€ 011110 â”€ <not assigned>
1583  *          â”œâ”€ 011111 â”€ <not assigned>
1584  *          â”œâ”€ 100000 â”€ <not assigned>
1585  *          â”œâ”€ 100001 â”€ <not assigned>
1586  *          â”œâ”€ 100010 â”€ OPC_MXU_S8LDD
1587  *          â”œâ”€ 100011 â”€ OPC_MXU_S8STD
1588  *          â”œâ”€ 100100 â”€ OPC_MXU_S8LDI
1589  *          â”œâ”€ 100101 â”€ OPC_MXU_S8SDI
1590  *          â”‚                               15..14
1591  *          â”œâ”€ 100110 â”€ OPC_MXU__POOL16 â”€â”¬â”€ 00 â”€ OPC_MXU_S32MUL
1592  *          â”‚                            â”œâ”€ 00 â”€ OPC_MXU_S32MULU
1593  *          â”‚                            â”œâ”€ 00 â”€ OPC_MXU_S32EXTR
1594  *          â”‚                            â””─ 00 â”€ OPC_MXU_S32EXTRV
1595  *          â”‚
1596  *          â”‚                               20..18
1597  *          â”œâ”€ 100111 â”€ OPC_MXU__POOL17 â”€â”¬â”€ 000 â”€ OPC_MXU_D32SARW
1598  *          â”‚                            â”œâ”€ 001 â”€ OPC_MXU_S32ALN
1599  *          â”œâ”€ 101000 â”€ OPC_MXU_LXB      â”œâ”€ 010 â”€ OPC_MXU_S32ALNI
1600  *          â”œâ”€ 101001 â”€ <not assigned>   â”œâ”€ 011 â”€ OPC_MXU_S32NOR
1601  *          â”œâ”€ 101010 â”€ OPC_MXU_S16LDD   â”œâ”€ 100 â”€ OPC_MXU_S32AND
1602  *          â”œâ”€ 101011 â”€ OPC_MXU_S16STD   â”œâ”€ 101 â”€ OPC_MXU_S32OR
1603  *          â”œâ”€ 101100 â”€ OPC_MXU_S16LDI   â”œâ”€ 110 â”€ OPC_MXU_S32XOR
1604  *          â”œâ”€ 101101 â”€ OPC_MXU_S16SDI   â””─ 111 â”€ OPC_MXU_S32LUI
1605  *          â”œâ”€ 101000 â”€ <not assigned>
1606  *          â”œâ”€ 101001 â”€ <not assigned>
1607  *          â”œâ”€ 101010 â”€ <not assigned>
1608  *          â”œâ”€ 101011 â”€ <not assigned>
1609  *          â”œâ”€ 101100 â”€ <not assigned>
1610  *          â”œâ”€ 101101 â”€ <not assigned>
1611  *          â”œâ”€ 101110 â”€ OPC_MXU_S32M2I
1612  *          â”œâ”€ 101111 â”€ OPC_MXU_S32I2M
1613  *          â”œâ”€ 110000 â”€ OPC_MXU_D32SLL
1614  *          â”œâ”€ 110001 â”€ OPC_MXU_D32SLR
1615  *          â”œâ”€ 110010 â”€ OPC_MXU_D32SARL
1616  *          â”œâ”€ 110011 â”€ OPC_MXU_D32SAR
1617  *          â”œâ”€ 110100 â”€ OPC_MXU_Q16SLL
1618  *          â”œâ”€ 110101 â”€ OPC_MXU_Q16SLR      20..18
1619  *          â”œâ”€ 110110 â”€ OPC_MXU__POOL18 â”€â”¬â”€ 000 â”€ OPC_MXU_D32SLLV
1620  *          â”‚                            â”œâ”€ 001 â”€ OPC_MXU_D32SLRV
1621  *          â”‚                            â”œâ”€ 010 â”€ OPC_MXU_D32SARV
1622  *          â”‚                            â”œâ”€ 011 â”€ OPC_MXU_Q16SLLV
1623  *          â”‚                            â”œâ”€ 100 â”€ OPC_MXU_Q16SLRV
1624  *          â”‚                            â””─ 101 â”€ OPC_MXU_Q16SARV
1625  *          â”œâ”€ 110111 â”€ OPC_MXU_Q16SAR
1626  *          â”‚                               23..22
1627  *          â”œâ”€ 111000 â”€ OPC_MXU__POOL19 â”€â”¬â”€ 00 â”€ OPC_MXU_Q8MUL
1628  *          â”‚                            â””─ 01 â”€ OPC_MXU_Q8MULSU
1629  *          â”‚
1630  *          â”‚                               20..18
1631  *          â”œâ”€ 111001 â”€ OPC_MXU__POOL20 â”€â”¬â”€ 000 â”€ OPC_MXU_Q8MOVZ
1632  *          â”‚                            â”œâ”€ 001 â”€ OPC_MXU_Q8MOVN
1633  *          â”‚                            â”œâ”€ 010 â”€ OPC_MXU_D16MOVZ
1634  *          â”‚                            â”œâ”€ 011 â”€ OPC_MXU_D16MOVN
1635  *          â”‚                            â”œâ”€ 100 â”€ OPC_MXU_S32MOVZ
1636  *          â”‚                            â””─ 101 â”€ OPC_MXU_S32MOV
1637  *          â”‚
1638  *          â”‚                               23..22
1639  *          â”œâ”€ 111010 â”€ OPC_MXU__POOL21 â”€â”¬â”€ 00 â”€ OPC_MXU_Q8MAC
1640  *          â”‚                            â””─ 10 â”€ OPC_MXU_Q8MACSU
1641  *          â”œâ”€ 111011 â”€ OPC_MXU_Q16SCOP
1642  *          â”œâ”€ 111100 â”€ OPC_MXU_Q8MADL
1643  *          â”œâ”€ 111101 â”€ OPC_MXU_S32SFL
1644  *          â”œâ”€ 111110 â”€ OPC_MXU_Q8SAD
1645  *          â””─ 111111 â”€ <not assigned>
1646  *
1647  *
1648  *   Compiled after:
1649  *
1650  *   "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
1651  *   Programming Manual", Ingenic Semiconductor Co, Ltd., 2017
1652  */
1653
1654 enum {
1655     OPC_MXU_S32MADD  = 0x00,
1656     OPC_MXU_S32MADDU = 0x01,
1657     /* not assigned 0x02 */
1658     OPC_MXU__POOL00  = 0x03,
1659     OPC_MXU_S32MSUB  = 0x04,
1660     OPC_MXU_S32MSUBU = 0x05,
1661     OPC_MXU__POOL01  = 0x06,
1662     OPC_MXU__POOL02  = 0x07,
1663     OPC_MXU_D16MUL   = 0x08,
1664     OPC_MXU__POOL03  = 0x09,
1665     OPC_MXU_D16MAC   = 0x0A,
1666     OPC_MXU_D16MACF  = 0x0B,
1667     OPC_MXU_D16MADL  = 0x0C,
1668     OPC_MXU__POOL04  = 0x0D,
1669     OPC_MXU_Q16ADD   = 0x0E,
1670     OPC_MXU_D16MACE  = 0x0F,
1671     OPC_MXU__POOL05  = 0x10,
1672     OPC_MXU__POOL06  = 0x11,
1673     OPC_MXU__POOL07  = 0x12,
1674     OPC_MXU__POOL08  = 0x13,
1675     OPC_MXU__POOL09  = 0x14,
1676     OPC_MXU__POOL10  = 0x15,
1677     OPC_MXU__POOL11  = 0x16,
1678     OPC_MXU__POOL12  = 0x17,
1679     OPC_MXU_D32ADD   = 0x18,
1680     OPC_MXU__POOL13  = 0x19,
1681     /* not assigned 0x1A */
1682     OPC_MXU__POOL14  = 0x1B,
1683     OPC_MXU__POOL15  = 0x1C,
1684     OPC_MXU_Q8ACCE   = 0x1D,
1685     /* not assigned 0x1E */
1686     /* not assigned 0x1F */
1687     /* not assigned 0x20 */
1688     /* not assigned 0x21 */
1689     OPC_MXU_S8LDD    = 0x22,
1690     OPC_MXU_S8STD    = 0x23,
1691     OPC_MXU_S8LDI    = 0x24,
1692     OPC_MXU_S8SDI    = 0x25,
1693     OPC_MXU__POOL16  = 0x26,
1694     OPC_MXU__POOL17  = 0x27,
1695     OPC_MXU_LXB      = 0x28,
1696     /* not assigned 0x29 */
1697     OPC_MXU_S16LDD   = 0x2A,
1698     OPC_MXU_S16STD   = 0x2B,
1699     OPC_MXU_S16LDI   = 0x2C,
1700     OPC_MXU_S16SDI   = 0x2D,
1701     OPC_MXU_S32M2I   = 0x2E,
1702     OPC_MXU_S32I2M   = 0x2F,
1703     OPC_MXU_D32SLL   = 0x30,
1704     OPC_MXU_D32SLR   = 0x31,
1705     OPC_MXU_D32SARL  = 0x32,
1706     OPC_MXU_D32SAR   = 0x33,
1707     OPC_MXU_Q16SLL   = 0x34,
1708     OPC_MXU_Q16SLR   = 0x35,
1709     OPC_MXU__POOL18  = 0x36,
1710     OPC_MXU_Q16SAR   = 0x37,
1711     OPC_MXU__POOL19  = 0x38,
1712     OPC_MXU__POOL20  = 0x39,
1713     OPC_MXU__POOL21  = 0x3A,
1714     OPC_MXU_Q16SCOP  = 0x3B,
1715     OPC_MXU_Q8MADL   = 0x3C,
1716     OPC_MXU_S32SFL   = 0x3D,
1717     OPC_MXU_Q8SAD    = 0x3E,
1718     /* not assigned 0x3F */
1719 };
1720
1721
1722 /*
1723  * MXU pool 00
1724  */
1725 enum {
1726     OPC_MXU_S32MAX   = 0x00,
1727     OPC_MXU_S32MIN   = 0x01,
1728     OPC_MXU_D16MAX   = 0x02,
1729     OPC_MXU_D16MIN   = 0x03,
1730     OPC_MXU_Q8MAX    = 0x04,
1731     OPC_MXU_Q8MIN    = 0x05,
1732     OPC_MXU_Q8SLT    = 0x06,
1733     OPC_MXU_Q8SLTU   = 0x07,
1734 };
1735
1736 /*
1737  * MXU pool 01
1738  */
1739 enum {
1740     OPC_MXU_S32SLT   = 0x00,
1741     OPC_MXU_D16SLT   = 0x01,
1742     OPC_MXU_D16AVG   = 0x02,
1743     OPC_MXU_D16AVGR  = 0x03,
1744     OPC_MXU_Q8AVG    = 0x04,
1745     OPC_MXU_Q8AVGR   = 0x05,
1746     OPC_MXU_Q8ADD    = 0x07,
1747 };
1748
1749 /*
1750  * MXU pool 02
1751  */
1752 enum {
1753     OPC_MXU_S32CPS   = 0x00,
1754     OPC_MXU_D16CPS   = 0x02,
1755     OPC_MXU_Q8ABD    = 0x04,
1756     OPC_MXU_Q16SAT   = 0x06,
1757 };
1758
1759 /*
1760  * MXU pool 03
1761  */
1762 enum {
1763     OPC_MXU_D16MULF  = 0x00,
1764     OPC_MXU_D16MULE  = 0x01,
1765 };
1766
1767 /*
1768  * MXU pool 04
1769  */
1770 enum {
1771     OPC_MXU_S16MAD   = 0x00,
1772     OPC_MXU_S16MAD_1 = 0x01,
1773 };
1774
1775 /*
1776  * MXU pool 05
1777  */
1778 enum {
1779     OPC_MXU_S32LDD   = 0x00,
1780     OPC_MXU_S32LDDR  = 0x01,
1781 };
1782
1783 /*
1784  * MXU pool 06
1785  */
1786 enum {
1787     OPC_MXU_S32STD   = 0x00,
1788     OPC_MXU_S32STDR  = 0x01,
1789 };
1790
1791 /*
1792  * MXU pool 07
1793  */
1794 enum {
1795     OPC_MXU_S32LDDV  = 0x00,
1796     OPC_MXU_S32LDDVR = 0x01,
1797 };
1798
1799 /*
1800  * MXU pool 08
1801  */
1802 enum {
1803     OPC_MXU_S32STDV  = 0x00,
1804     OPC_MXU_S32STDVR = 0x01,
1805 };
1806
1807 /*
1808  * MXU pool 09
1809  */
1810 enum {
1811     OPC_MXU_S32LDI   = 0x00,
1812     OPC_MXU_S32LDIR  = 0x01,
1813 };
1814
1815 /*
1816  * MXU pool 10
1817  */
1818 enum {
1819     OPC_MXU_S32SDI   = 0x00,
1820     OPC_MXU_S32SDIR  = 0x01,
1821 };
1822
1823 /*
1824  * MXU pool 11
1825  */
1826 enum {
1827     OPC_MXU_S32LDIV  = 0x00,
1828     OPC_MXU_S32LDIVR = 0x01,
1829 };
1830
1831 /*
1832  * MXU pool 12
1833  */
1834 enum {
1835     OPC_MXU_S32SDIV  = 0x00,
1836     OPC_MXU_S32SDIVR = 0x01,
1837 };
1838
1839 /*
1840  * MXU pool 13
1841  */
1842 enum {
1843     OPC_MXU_D32ACC   = 0x00,
1844     OPC_MXU_D32ACCM  = 0x01,
1845     OPC_MXU_D32ASUM  = 0x02,
1846 };
1847
1848 /*
1849  * MXU pool 14
1850  */
1851 enum {
1852     OPC_MXU_Q16ACC   = 0x00,
1853     OPC_MXU_Q16ACCM  = 0x01,
1854     OPC_MXU_Q16ASUM  = 0x02,
1855 };
1856
1857 /*
1858  * MXU pool 15
1859  */
1860 enum {
1861     OPC_MXU_Q8ADDE   = 0x00,
1862     OPC_MXU_D8SUM    = 0x01,
1863     OPC_MXU_D8SUMC   = 0x02,
1864 };
1865
1866 /*
1867  * MXU pool 16
1868  */
1869 enum {
1870     OPC_MXU_S32MUL   = 0x00,
1871     OPC_MXU_S32MULU  = 0x01,
1872     OPC_MXU_S32EXTR  = 0x02,
1873     OPC_MXU_S32EXTRV = 0x03,
1874 };
1875
1876 /*
1877  * MXU pool 17
1878  */
1879 enum {
1880     OPC_MXU_D32SARW  = 0x00,
1881     OPC_MXU_S32ALN   = 0x01,
1882     OPC_MXU_S32ALNI  = 0x02,
1883     OPC_MXU_S32NOR   = 0x03,
1884     OPC_MXU_S32AND   = 0x04,
1885     OPC_MXU_S32OR    = 0x05,
1886     OPC_MXU_S32XOR   = 0x06,
1887     OPC_MXU_S32LUI   = 0x07,
1888 };
1889
1890 /*
1891  * MXU pool 18
1892  */
1893 enum {
1894     OPC_MXU_D32SLLV  = 0x00,
1895     OPC_MXU_D32SLRV  = 0x01,
1896     OPC_MXU_D32SARV  = 0x03,
1897     OPC_MXU_Q16SLLV  = 0x04,
1898     OPC_MXU_Q16SLRV  = 0x05,
1899     OPC_MXU_Q16SARV  = 0x07,
1900 };
1901
1902 /*
1903  * MXU pool 19
1904  */
1905 enum {
1906     OPC_MXU_Q8MUL    = 0x00,
1907     OPC_MXU_Q8MULSU  = 0x01,
1908 };
1909
1910 /*
1911  * MXU pool 20
1912  */
1913 enum {
1914     OPC_MXU_Q8MOVZ   = 0x00,
1915     OPC_MXU_Q8MOVN   = 0x01,
1916     OPC_MXU_D16MOVZ  = 0x02,
1917     OPC_MXU_D16MOVN  = 0x03,
1918     OPC_MXU_S32MOVZ  = 0x04,
1919     OPC_MXU_S32MOVN  = 0x05,
1920 };
1921
1922 /*
1923  * MXU pool 21
1924  */
1925 enum {
1926     OPC_MXU_Q8MAC    = 0x00,
1927     OPC_MXU_Q8MACSU  = 0x01,
1928 };
1929
1930
1931 /* global register indices */
1932 static TCGv cpu_gpr[32], cpu_PC;
1933 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
1934 static TCGv cpu_dspctrl, btarget, bcond;
1935 static TCGv_i32 hflags;
1936 static TCGv_i32 fpu_fcr0, fpu_fcr31;
1937 static TCGv_i64 fpu_f64[32];
1938 static TCGv_i64 msa_wr_d[64];
1939
1940 #include "exec/gen-icount.h"
1941
1942 #define gen_helper_0e0i(name, arg) do {                           \
1943     TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
1944     gen_helper_##name(cpu_env, helper_tmp);                       \
1945     tcg_temp_free_i32(helper_tmp);                                \
1946     } while(0)
1947
1948 #define gen_helper_0e1i(name, arg1, arg2) do {                    \
1949     TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
1950     gen_helper_##name(cpu_env, arg1, helper_tmp);                 \
1951     tcg_temp_free_i32(helper_tmp);                                \
1952     } while(0)
1953
1954 #define gen_helper_1e0i(name, ret, arg1) do {                     \
1955     TCGv_i32 helper_tmp = tcg_const_i32(arg1);                    \
1956     gen_helper_##name(ret, cpu_env, helper_tmp);                  \
1957     tcg_temp_free_i32(helper_tmp);                                \
1958     } while(0)
1959
1960 #define gen_helper_1e1i(name, ret, arg1, arg2) do {               \
1961     TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
1962     gen_helper_##name(ret, cpu_env, arg1, helper_tmp);            \
1963     tcg_temp_free_i32(helper_tmp);                                \
1964     } while(0)
1965
1966 #define gen_helper_0e2i(name, arg1, arg2, arg3) do {              \
1967     TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
1968     gen_helper_##name(cpu_env, arg1, arg2, helper_tmp);           \
1969     tcg_temp_free_i32(helper_tmp);                                \
1970     } while(0)
1971
1972 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do {         \
1973     TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
1974     gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp);      \
1975     tcg_temp_free_i32(helper_tmp);                                \
1976     } while(0)
1977
1978 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do {        \
1979     TCGv_i32 helper_tmp = tcg_const_i32(arg4);                    \
1980     gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp);     \
1981     tcg_temp_free_i32(helper_tmp);                                \
1982     } while(0)
1983
1984 typedef struct DisasContext {
1985     DisasContextBase base;
1986     target_ulong saved_pc;
1987     target_ulong page_start;
1988     uint32_t opcode;
1989     uint64_t insn_flags;
1990     int32_t CP0_Config1;
1991     int32_t CP0_Config2;
1992     int32_t CP0_Config3;
1993     int32_t CP0_Config5;
1994     /* Routine used to access memory */
1995     int mem_idx;
1996     TCGMemOp default_tcg_memop_mask;
1997     uint32_t hflags, saved_hflags;
1998     target_ulong btarget;
1999     bool ulri;
2000     int kscrexist;
2001     bool rxi;
2002     int ie;
2003     bool bi;
2004     bool bp;
2005     uint64_t PAMask;
2006     bool mvh;
2007     bool eva;
2008     bool sc;
2009     int CP0_LLAddr_shift;
2010     bool ps;
2011     bool vp;
2012     bool cmgcr;
2013     bool mrp;
2014     bool nan2008;
2015     bool abs2008;
2016 } DisasContext;
2017
2018 #define DISAS_STOP       DISAS_TARGET_0
2019 #define DISAS_EXIT       DISAS_TARGET_1
2020
2021 static const char * const regnames[] = {
2022     "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2023     "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2024     "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2025     "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2026 };
2027
2028 static const char * const regnames_HI[] = {
2029     "HI0", "HI1", "HI2", "HI3",
2030 };
2031
2032 static const char * const regnames_LO[] = {
2033     "LO0", "LO1", "LO2", "LO3",
2034 };
2035
2036 static const char * const fregnames[] = {
2037     "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
2038     "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
2039     "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2040     "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2041 };
2042
2043 static const char * const msaregnames[] = {
2044     "w0.d0",  "w0.d1",  "w1.d0",  "w1.d1",
2045     "w2.d0",  "w2.d1",  "w3.d0",  "w3.d1",
2046     "w4.d0",  "w4.d1",  "w5.d0",  "w5.d1",
2047     "w6.d0",  "w6.d1",  "w7.d0",  "w7.d1",
2048     "w8.d0",  "w8.d1",  "w9.d0",  "w9.d1",
2049     "w10.d0", "w10.d1", "w11.d0", "w11.d1",
2050     "w12.d0", "w12.d1", "w13.d0", "w13.d1",
2051     "w14.d0", "w14.d1", "w15.d0", "w15.d1",
2052     "w16.d0", "w16.d1", "w17.d0", "w17.d1",
2053     "w18.d0", "w18.d1", "w19.d0", "w19.d1",
2054     "w20.d0", "w20.d1", "w21.d0", "w21.d1",
2055     "w22.d0", "w22.d1", "w23.d0", "w23.d1",
2056     "w24.d0", "w24.d1", "w25.d0", "w25.d1",
2057     "w26.d0", "w26.d1", "w27.d0", "w27.d1",
2058     "w28.d0", "w28.d1", "w29.d0", "w29.d1",
2059     "w30.d0", "w30.d1", "w31.d0", "w31.d1",
2060 };
2061
2062 #define LOG_DISAS(...)                                                        \
2063     do {                                                                      \
2064         if (MIPS_DEBUG_DISAS) {                                               \
2065             qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__);                 \
2066         }                                                                     \
2067     } while (0)
2068
2069 #define MIPS_INVAL(op)                                                        \
2070     do {                                                                      \
2071         if (MIPS_DEBUG_DISAS) {                                               \
2072             qemu_log_mask(CPU_LOG_TB_IN_ASM,                                  \
2073                           TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
2074                           ctx->base.pc_next, ctx->opcode, op,                 \
2075                           ctx->opcode >> 26, ctx->opcode & 0x3F,              \
2076                           ((ctx->opcode >> 16) & 0x1F));                      \
2077         }                                                                     \
2078     } while (0)
2079
2080 /* General purpose registers moves. */
2081 static inline void gen_load_gpr (TCGv t, int reg)
2082 {
2083     if (reg == 0)
2084         tcg_gen_movi_tl(t, 0);
2085     else
2086         tcg_gen_mov_tl(t, cpu_gpr[reg]);
2087 }
2088
2089 static inline void gen_store_gpr (TCGv t, int reg)
2090 {
2091     if (reg != 0)
2092         tcg_gen_mov_tl(cpu_gpr[reg], t);
2093 }
2094
2095 /* Moves to/from shadow registers. */
2096 static inline void gen_load_srsgpr (int from, int to)
2097 {
2098     TCGv t0 = tcg_temp_new();
2099
2100     if (from == 0)
2101         tcg_gen_movi_tl(t0, 0);
2102     else {
2103         TCGv_i32 t2 = tcg_temp_new_i32();
2104         TCGv_ptr addr = tcg_temp_new_ptr();
2105
2106         tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2107         tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2108         tcg_gen_andi_i32(t2, t2, 0xf);
2109         tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2110         tcg_gen_ext_i32_ptr(addr, t2);
2111         tcg_gen_add_ptr(addr, cpu_env, addr);
2112
2113         tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
2114         tcg_temp_free_ptr(addr);
2115         tcg_temp_free_i32(t2);
2116     }
2117     gen_store_gpr(t0, to);
2118     tcg_temp_free(t0);
2119 }
2120
2121 static inline void gen_store_srsgpr (int from, int to)
2122 {
2123     if (to != 0) {
2124         TCGv t0 = tcg_temp_new();
2125         TCGv_i32 t2 = tcg_temp_new_i32();
2126         TCGv_ptr addr = tcg_temp_new_ptr();
2127
2128         gen_load_gpr(t0, from);
2129         tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2130         tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2131         tcg_gen_andi_i32(t2, t2, 0xf);
2132         tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2133         tcg_gen_ext_i32_ptr(addr, t2);
2134         tcg_gen_add_ptr(addr, cpu_env, addr);
2135
2136         tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
2137         tcg_temp_free_ptr(addr);
2138         tcg_temp_free_i32(t2);
2139         tcg_temp_free(t0);
2140     }
2141 }
2142
2143 /* Tests */
2144 static inline void gen_save_pc(target_ulong pc)
2145 {
2146     tcg_gen_movi_tl(cpu_PC, pc);
2147 }
2148
2149 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
2150 {
2151     LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
2152     if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
2153         gen_save_pc(ctx->base.pc_next);
2154         ctx->saved_pc = ctx->base.pc_next;
2155     }
2156     if (ctx->hflags != ctx->saved_hflags) {
2157         tcg_gen_movi_i32(hflags, ctx->hflags);
2158         ctx->saved_hflags = ctx->hflags;
2159         switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2160         case MIPS_HFLAG_BR:
2161             break;
2162         case MIPS_HFLAG_BC:
2163         case MIPS_HFLAG_BL:
2164         case MIPS_HFLAG_B:
2165             tcg_gen_movi_tl(btarget, ctx->btarget);
2166             break;
2167         }
2168     }
2169 }
2170
2171 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
2172 {
2173     ctx->saved_hflags = ctx->hflags;
2174     switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2175     case MIPS_HFLAG_BR:
2176         break;
2177     case MIPS_HFLAG_BC:
2178     case MIPS_HFLAG_BL:
2179     case MIPS_HFLAG_B:
2180         ctx->btarget = env->btarget;
2181         break;
2182     }
2183 }
2184
2185 static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
2186 {
2187     TCGv_i32 texcp = tcg_const_i32(excp);
2188     TCGv_i32 terr = tcg_const_i32(err);
2189     save_cpu_state(ctx, 1);
2190     gen_helper_raise_exception_err(cpu_env, texcp, terr);
2191     tcg_temp_free_i32(terr);
2192     tcg_temp_free_i32(texcp);
2193     ctx->base.is_jmp = DISAS_NORETURN;
2194 }
2195
2196 static inline void generate_exception(DisasContext *ctx, int excp)
2197 {
2198     gen_helper_0e0i(raise_exception, excp);
2199 }
2200
2201 static inline void generate_exception_end(DisasContext *ctx, int excp)
2202 {
2203     generate_exception_err(ctx, excp, 0);
2204 }
2205
2206 /* Floating point register moves. */
2207 static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2208 {
2209     if (ctx->hflags & MIPS_HFLAG_FRE) {
2210         generate_exception(ctx, EXCP_RI);
2211     }
2212     tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
2213 }
2214
2215 static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2216 {
2217     TCGv_i64 t64;
2218     if (ctx->hflags & MIPS_HFLAG_FRE) {
2219         generate_exception(ctx, EXCP_RI);
2220     }
2221     t64 = tcg_temp_new_i64();
2222     tcg_gen_extu_i32_i64(t64, t);
2223     tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
2224     tcg_temp_free_i64(t64);
2225 }
2226
2227 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2228 {
2229     if (ctx->hflags & MIPS_HFLAG_F64) {
2230         tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
2231     } else {
2232         gen_load_fpr32(ctx, t, reg | 1);
2233     }
2234 }
2235
2236 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2237 {
2238     if (ctx->hflags & MIPS_HFLAG_F64) {
2239         TCGv_i64 t64 = tcg_temp_new_i64();
2240         tcg_gen_extu_i32_i64(t64, t);
2241         tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
2242         tcg_temp_free_i64(t64);
2243     } else {
2244         gen_store_fpr32(ctx, t, reg | 1);
2245     }
2246 }
2247
2248 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2249 {
2250     if (ctx->hflags & MIPS_HFLAG_F64) {
2251         tcg_gen_mov_i64(t, fpu_f64[reg]);
2252     } else {
2253         tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
2254     }
2255 }
2256
2257 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2258 {
2259     if (ctx->hflags & MIPS_HFLAG_F64) {
2260         tcg_gen_mov_i64(fpu_f64[reg], t);
2261     } else {
2262         TCGv_i64 t0;
2263         tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
2264         t0 = tcg_temp_new_i64();
2265         tcg_gen_shri_i64(t0, t, 32);
2266         tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
2267         tcg_temp_free_i64(t0);
2268     }
2269 }
2270
2271 static inline int get_fp_bit (int cc)
2272 {
2273     if (cc)
2274         return 24 + cc;
2275     else
2276         return 23;
2277 }
2278
2279 /* Addresses computation */
2280 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
2281 {
2282     tcg_gen_add_tl(ret, arg0, arg1);
2283
2284 #if defined(TARGET_MIPS64)
2285     if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2286         tcg_gen_ext32s_i64(ret, ret);
2287     }
2288 #endif
2289 }
2290
2291 static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
2292                                     target_long ofs)
2293 {
2294     tcg_gen_addi_tl(ret, base, ofs);
2295
2296 #if defined(TARGET_MIPS64)
2297     if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2298         tcg_gen_ext32s_i64(ret, ret);
2299     }
2300 #endif
2301 }
2302
2303 /* Addresses computation (translation time) */
2304 static target_long addr_add(DisasContext *ctx, target_long base,
2305                             target_long offset)
2306 {
2307     target_long sum = base + offset;
2308
2309 #if defined(TARGET_MIPS64)
2310     if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2311         sum = (int32_t)sum;
2312     }
2313 #endif
2314     return sum;
2315 }
2316
2317 /* Sign-extract the low 32-bits to a target_long.  */
2318 static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
2319 {
2320 #if defined(TARGET_MIPS64)
2321     tcg_gen_ext32s_i64(ret, arg);
2322 #else
2323     tcg_gen_extrl_i64_i32(ret, arg);
2324 #endif
2325 }
2326
2327 /* Sign-extract the high 32-bits to a target_long.  */
2328 static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
2329 {
2330 #if defined(TARGET_MIPS64)
2331     tcg_gen_sari_i64(ret, arg, 32);
2332 #else
2333     tcg_gen_extrh_i64_i32(ret, arg);
2334 #endif
2335 }
2336
2337 static inline void check_cp0_enabled(DisasContext *ctx)
2338 {
2339     if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
2340         generate_exception_err(ctx, EXCP_CpU, 0);
2341 }
2342
2343 static inline void check_cp1_enabled(DisasContext *ctx)
2344 {
2345     if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
2346         generate_exception_err(ctx, EXCP_CpU, 1);
2347 }
2348
2349 /* Verify that the processor is running with COP1X instructions enabled.
2350    This is associated with the nabla symbol in the MIPS32 and MIPS64
2351    opcode tables.  */
2352
2353 static inline void check_cop1x(DisasContext *ctx)
2354 {
2355     if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
2356         generate_exception_end(ctx, EXCP_RI);
2357 }
2358
2359 /* Verify that the processor is running with 64-bit floating-point
2360    operations enabled.  */
2361
2362 static inline void check_cp1_64bitmode(DisasContext *ctx)
2363 {
2364     if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
2365         generate_exception_end(ctx, EXCP_RI);
2366 }
2367
2368 /*
2369  * Verify if floating point register is valid; an operation is not defined
2370  * if bit 0 of any register specification is set and the FR bit in the
2371  * Status register equals zero, since the register numbers specify an
2372  * even-odd pair of adjacent coprocessor general registers. When the FR bit
2373  * in the Status register equals one, both even and odd register numbers
2374  * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
2375  *
2376  * Multiple 64 bit wide registers can be checked by calling
2377  * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
2378  */
2379 static inline void check_cp1_registers(DisasContext *ctx, int regs)
2380 {
2381     if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
2382         generate_exception_end(ctx, EXCP_RI);
2383 }
2384
2385 /* Verify that the processor is running with DSP instructions enabled.
2386    This is enabled by CP0 Status register MX(24) bit.
2387  */
2388
2389 static inline void check_dsp(DisasContext *ctx)
2390 {
2391     if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
2392         if (ctx->insn_flags & ASE_DSP) {
2393             generate_exception_end(ctx, EXCP_DSPDIS);
2394         } else {
2395             generate_exception_end(ctx, EXCP_RI);
2396         }
2397     }
2398 }
2399
2400 static inline void check_dsp_r2(DisasContext *ctx)
2401 {
2402     if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
2403         if (ctx->insn_flags & ASE_DSP) {
2404             generate_exception_end(ctx, EXCP_DSPDIS);
2405         } else {
2406             generate_exception_end(ctx, EXCP_RI);
2407         }
2408     }
2409 }
2410
2411 static inline void check_dsp_r3(DisasContext *ctx)
2412 {
2413     if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
2414         if (ctx->insn_flags & ASE_DSP) {
2415             generate_exception_end(ctx, EXCP_DSPDIS);
2416         } else {
2417             generate_exception_end(ctx, EXCP_RI);
2418         }
2419     }
2420 }
2421
2422 /* This code generates a "reserved instruction" exception if the
2423    CPU does not support the instruction set corresponding to flags. */
2424 static inline void check_insn(DisasContext *ctx, uint64_t flags)
2425 {
2426     if (unlikely(!(ctx->insn_flags & flags))) {
2427         generate_exception_end(ctx, EXCP_RI);
2428     }
2429 }
2430
2431 /* This code generates a "reserved instruction" exception if the
2432    CPU has corresponding flag set which indicates that the instruction
2433    has been removed. */
2434 static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
2435 {
2436     if (unlikely(ctx->insn_flags & flags)) {
2437         generate_exception_end(ctx, EXCP_RI);
2438     }
2439 }
2440
2441 /* This code generates a "reserved instruction" exception if the
2442    CPU does not support 64-bit paired-single (PS) floating point data type */
2443 static inline void check_ps(DisasContext *ctx)
2444 {
2445     if (unlikely(!ctx->ps)) {
2446         generate_exception(ctx, EXCP_RI);
2447     }
2448     check_cp1_64bitmode(ctx);
2449 }
2450
2451 #ifdef TARGET_MIPS64
2452 /* This code generates a "reserved instruction" exception if 64-bit
2453    instructions are not enabled. */
2454 static inline void check_mips_64(DisasContext *ctx)
2455 {
2456     if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
2457         generate_exception_end(ctx, EXCP_RI);
2458 }
2459 #endif
2460
2461 #ifndef CONFIG_USER_ONLY
2462 static inline void check_mvh(DisasContext *ctx)
2463 {
2464     if (unlikely(!ctx->mvh)) {
2465         generate_exception(ctx, EXCP_RI);
2466     }
2467 }
2468 #endif
2469
2470 /*
2471  * This code generates a "reserved instruction" exception if the
2472  * Config5 XNP bit is set.
2473  */
2474 static inline void check_xnp(DisasContext *ctx)
2475 {
2476     if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
2477         generate_exception_end(ctx, EXCP_RI);
2478     }
2479 }
2480
2481 #ifndef CONFIG_USER_ONLY
2482 /*
2483  * This code generates a "reserved instruction" exception if the
2484  * Config3 PW bit is NOT set.
2485  */
2486 static inline void check_pw(DisasContext *ctx)
2487 {
2488     if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
2489         generate_exception_end(ctx, EXCP_RI);
2490     }
2491 }
2492 #endif
2493
2494 /*
2495  * This code generates a "reserved instruction" exception if the
2496  * Config3 MT bit is NOT set.
2497  */
2498 static inline void check_mt(DisasContext *ctx)
2499 {
2500     if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
2501         generate_exception_end(ctx, EXCP_RI);
2502     }
2503 }
2504
2505 #ifndef CONFIG_USER_ONLY
2506 /*
2507  * This code generates a "coprocessor unusable" exception if CP0 is not
2508  * available, and, if that is not the case, generates a "reserved instruction"
2509  * exception if the Config5 MT bit is NOT set. This is needed for availability
2510  * control of some of MT ASE instructions.
2511  */
2512 static inline void check_cp0_mt(DisasContext *ctx)
2513 {
2514     if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
2515         generate_exception_err(ctx, EXCP_CpU, 0);
2516     } else {
2517         if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
2518             generate_exception_err(ctx, EXCP_RI, 0);
2519         }
2520     }
2521 }
2522 #endif
2523
2524 /*
2525  * This code generates a "reserved instruction" exception if the
2526  * Config5 NMS bit is set.
2527  */
2528 static inline void check_nms(DisasContext *ctx)
2529 {
2530     if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
2531         generate_exception_end(ctx, EXCP_RI);
2532     }
2533 }
2534
2535
2536 /* Define small wrappers for gen_load_fpr* so that we have a uniform
2537    calling interface for 32 and 64-bit FPRs.  No sense in changing
2538    all callers for gen_load_fpr32 when we need the CTX parameter for
2539    this one use.  */
2540 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
2541 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
2542 #define FOP_CONDS(type, abs, fmt, ifmt, bits)                                 \
2543 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
2544                                                int ft, int fs, int cc)        \
2545 {                                                                             \
2546     TCGv_i##bits fp0 = tcg_temp_new_i##bits ();                               \
2547     TCGv_i##bits fp1 = tcg_temp_new_i##bits ();                               \
2548     switch (ifmt) {                                                           \
2549     case FMT_PS:                                                              \
2550         check_ps(ctx);                                                        \
2551         break;                                                                \
2552     case FMT_D:                                                               \
2553         if (abs) {                                                            \
2554             check_cop1x(ctx);                                                 \
2555         }                                                                     \
2556         check_cp1_registers(ctx, fs | ft);                                    \
2557         break;                                                                \
2558     case FMT_S:                                                               \
2559         if (abs) {                                                            \
2560             check_cop1x(ctx);                                                 \
2561         }                                                                     \
2562         break;                                                                \
2563     }                                                                         \
2564     gen_ldcmp_fpr##bits (ctx, fp0, fs);                                       \
2565     gen_ldcmp_fpr##bits (ctx, fp1, ft);                                       \
2566     switch (n) {                                                              \
2567     case  0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc);    break;\
2568     case  1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc);   break;\
2569     case  2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc);   break;\
2570     case  3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc);  break;\
2571     case  4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc);  break;\
2572     case  5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc);  break;\
2573     case  6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc);  break;\
2574     case  7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc);  break;\
2575     case  8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc);   break;\
2576     case  9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
2577     case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc);  break;\
2578     case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc);  break;\
2579     case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc);   break;\
2580     case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc);  break;\
2581     case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc);   break;\
2582     case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc);  break;\
2583     default: abort();                                                         \
2584     }                                                                         \
2585     tcg_temp_free_i##bits (fp0);                                              \
2586     tcg_temp_free_i##bits (fp1);                                              \
2587 }
2588
2589 FOP_CONDS(, 0, d, FMT_D, 64)
2590 FOP_CONDS(abs, 1, d, FMT_D, 64)
2591 FOP_CONDS(, 0, s, FMT_S, 32)
2592 FOP_CONDS(abs, 1, s, FMT_S, 32)
2593 FOP_CONDS(, 0, ps, FMT_PS, 64)
2594 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
2595 #undef FOP_CONDS
2596
2597 #define FOP_CONDNS(fmt, ifmt, bits, STORE)                              \
2598 static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n,        \
2599                                       int ft, int fs, int fd)           \
2600 {                                                                       \
2601     TCGv_i ## bits fp0 = tcg_temp_new_i ## bits();                      \
2602     TCGv_i ## bits fp1 = tcg_temp_new_i ## bits();                      \
2603     if (ifmt == FMT_D) {                                                \
2604         check_cp1_registers(ctx, fs | ft | fd);                         \
2605     }                                                                   \
2606     gen_ldcmp_fpr ## bits(ctx, fp0, fs);                                \
2607     gen_ldcmp_fpr ## bits(ctx, fp1, ft);                                \
2608     switch (n) {                                                        \
2609     case  0:                                                            \
2610         gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1);       \
2611         break;                                                          \
2612     case  1:                                                            \
2613         gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1);       \
2614         break;                                                          \
2615     case  2:                                                            \
2616         gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1);       \
2617         break;                                                          \
2618     case  3:                                                            \
2619         gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1);      \
2620         break;                                                          \
2621     case  4:                                                            \
2622         gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1);       \
2623         break;                                                          \
2624     case  5:                                                            \
2625         gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1);      \
2626         break;                                                          \
2627     case  6:                                                            \
2628         gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1);       \
2629         break;                                                          \
2630     case  7:                                                            \
2631         gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1);      \
2632         break;                                                          \
2633     case  8:                                                            \
2634         gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1);      \
2635         break;                                                          \
2636     case  9:                                                            \
2637         gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1);      \
2638         break;                                                          \
2639     case 10:                                                            \
2640         gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1);      \
2641         break;                                                          \
2642     case 11:                                                            \
2643         gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1);     \
2644         break;                                                          \
2645     case 12:                                                            \
2646         gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1);      \
2647         break;                                                          \
2648     case 13:                                                            \
2649         gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1);     \
2650         break;                                                          \
2651     case 14:                                                            \
2652         gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1);      \
2653         break;                                                          \
2654     case 15:                                                            \
2655         gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1);     \
2656         break;                                                          \
2657     case 17:                                                            \
2658         gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1);       \
2659         break;                                                          \
2660     case 18:                                                            \
2661         gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1);      \
2662         break;                                                          \
2663     case 19:                                                            \
2664         gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1);       \
2665         break;                                                          \
2666     case 25:                                                            \
2667         gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1);      \
2668         break;                                                          \
2669     case 26:                                                            \
2670         gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1);     \
2671         break;                                                          \
2672     case 27:                                                            \
2673         gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1);      \
2674         break;                                                          \
2675     default:                                                            \
2676         abort();                                                        \
2677     }                                                                   \
2678     STORE;                                                              \
2679     tcg_temp_free_i ## bits (fp0);                                      \
2680     tcg_temp_free_i ## bits (fp1);                                      \
2681 }
2682
2683 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
2684 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
2685 #undef FOP_CONDNS
2686 #undef gen_ldcmp_fpr32
2687 #undef gen_ldcmp_fpr64
2688
2689 /* load/store instructions. */
2690 #ifdef CONFIG_USER_ONLY
2691 #define OP_LD_ATOMIC(insn,fname)                                           \
2692 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
2693                                 DisasContext *ctx)                         \
2694 {                                                                          \
2695     TCGv t0 = tcg_temp_new();                                              \
2696     tcg_gen_mov_tl(t0, arg1);                                              \
2697     tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
2698     tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));                \
2699     tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval));                \
2700     tcg_temp_free(t0);                                                     \
2701 }
2702 #else
2703 #define OP_LD_ATOMIC(insn,fname)                                           \
2704 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
2705                                 DisasContext *ctx)                         \
2706 {                                                                          \
2707     gen_helper_1e1i(insn, ret, arg1, mem_idx);                             \
2708 }
2709 #endif
2710 OP_LD_ATOMIC(ll,ld32s);
2711 #if defined(TARGET_MIPS64)
2712 OP_LD_ATOMIC(lld,ld64);
2713 #endif
2714 #undef OP_LD_ATOMIC
2715
2716 #ifdef CONFIG_USER_ONLY
2717 #define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
2718 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx,   \
2719                                 DisasContext *ctx)                           \
2720 {                                                                            \
2721     TCGv t0 = tcg_temp_new();                                                \
2722     TCGLabel *l1 = gen_new_label();                                          \
2723     TCGLabel *l2 = gen_new_label();                                          \
2724                                                                              \
2725     tcg_gen_andi_tl(t0, arg2, almask);                                       \
2726     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);                              \
2727     tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));          \
2728     generate_exception(ctx, EXCP_AdES);                                      \
2729     gen_set_label(l1);                                                       \
2730     tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));                  \
2731     tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2);                            \
2732     tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20));                        \
2733     tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg));                   \
2734     tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval));              \
2735     generate_exception_end(ctx, EXCP_SC);                                    \
2736     gen_set_label(l2);                                                       \
2737     tcg_gen_movi_tl(t0, 0);                                                  \
2738     gen_store_gpr(t0, rt);                                                   \
2739     tcg_temp_free(t0);                                                       \
2740 }
2741 #else
2742 #define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
2743 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx,   \
2744                                 DisasContext *ctx)                           \
2745 {                                                                            \
2746     TCGv t0 = tcg_temp_new();                                                \
2747     gen_helper_1e2i(insn, t0, arg1, arg2, mem_idx);                          \
2748     gen_store_gpr(t0, rt);                                                   \
2749     tcg_temp_free(t0);                                                       \
2750 }
2751 #endif
2752 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
2753 #if defined(TARGET_MIPS64)
2754 OP_ST_ATOMIC(scd,st64,ld64,0x7);
2755 #endif
2756 #undef OP_ST_ATOMIC
2757
2758 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
2759                                   int base, int offset)
2760 {
2761     if (base == 0) {
2762         tcg_gen_movi_tl(addr, offset);
2763     } else if (offset == 0) {
2764         gen_load_gpr(addr, base);
2765     } else {
2766         tcg_gen_movi_tl(addr, offset);
2767         gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2768     }
2769 }
2770
2771 static target_ulong pc_relative_pc (DisasContext *ctx)
2772 {
2773     target_ulong pc = ctx->base.pc_next;
2774
2775     if (ctx->hflags & MIPS_HFLAG_BMASK) {
2776         int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2777
2778         pc -= branch_bytes;
2779     }
2780
2781     pc &= ~(target_ulong)3;
2782     return pc;
2783 }
2784
2785 /* Load */
2786 static void gen_ld(DisasContext *ctx, uint32_t opc,
2787                    int rt, int base, int offset)
2788 {
2789     TCGv t0, t1, t2;
2790     int mem_idx = ctx->mem_idx;
2791
2792     if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
2793         /* Loongson CPU uses a load to zero register for prefetch.
2794            We emulate it as a NOP. On other CPU we must perform the
2795            actual memory access. */
2796         return;
2797     }
2798
2799     t0 = tcg_temp_new();
2800     gen_base_offset_addr(ctx, t0, base, offset);
2801
2802     switch (opc) {
2803 #if defined(TARGET_MIPS64)
2804     case OPC_LWU:
2805         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
2806                            ctx->default_tcg_memop_mask);
2807         gen_store_gpr(t0, rt);
2808         break;
2809     case OPC_LD:
2810         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
2811                            ctx->default_tcg_memop_mask);
2812         gen_store_gpr(t0, rt);
2813         break;
2814     case OPC_LLD:
2815     case R6_OPC_LLD:
2816         op_ld_lld(t0, t0, mem_idx, ctx);
2817         gen_store_gpr(t0, rt);
2818         break;
2819     case OPC_LDL:
2820         t1 = tcg_temp_new();
2821         /* Do a byte access to possibly trigger a page
2822            fault with the unaligned address.  */
2823         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2824         tcg_gen_andi_tl(t1, t0, 7);
2825 #ifndef TARGET_WORDS_BIGENDIAN
2826         tcg_gen_xori_tl(t1, t1, 7);
2827 #endif
2828         tcg_gen_shli_tl(t1, t1, 3);
2829         tcg_gen_andi_tl(t0, t0, ~7);
2830         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
2831         tcg_gen_shl_tl(t0, t0, t1);
2832         t2 = tcg_const_tl(-1);
2833         tcg_gen_shl_tl(t2, t2, t1);
2834         gen_load_gpr(t1, rt);
2835         tcg_gen_andc_tl(t1, t1, t2);
2836         tcg_temp_free(t2);
2837         tcg_gen_or_tl(t0, t0, t1);
2838         tcg_temp_free(t1);
2839         gen_store_gpr(t0, rt);
2840         break;
2841     case OPC_LDR:
2842         t1 = tcg_temp_new();
2843         /* Do a byte access to possibly trigger a page
2844            fault with the unaligned address.  */
2845         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2846         tcg_gen_andi_tl(t1, t0, 7);
2847 #ifdef TARGET_WORDS_BIGENDIAN
2848         tcg_gen_xori_tl(t1, t1, 7);
2849 #endif
2850         tcg_gen_shli_tl(t1, t1, 3);
2851         tcg_gen_andi_tl(t0, t0, ~7);
2852         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
2853         tcg_gen_shr_tl(t0, t0, t1);
2854         tcg_gen_xori_tl(t1, t1, 63);
2855         t2 = tcg_const_tl(0xfffffffffffffffeull);
2856         tcg_gen_shl_tl(t2, t2, t1);
2857         gen_load_gpr(t1, rt);
2858         tcg_gen_and_tl(t1, t1, t2);
2859         tcg_temp_free(t2);
2860         tcg_gen_or_tl(t0, t0, t1);
2861         tcg_temp_free(t1);
2862         gen_store_gpr(t0, rt);
2863         break;
2864     case OPC_LDPC:
2865         t1 = tcg_const_tl(pc_relative_pc(ctx));
2866         gen_op_addr_add(ctx, t0, t0, t1);
2867         tcg_temp_free(t1);
2868         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
2869         gen_store_gpr(t0, rt);
2870         break;
2871 #endif
2872     case OPC_LWPC:
2873         t1 = tcg_const_tl(pc_relative_pc(ctx));
2874         gen_op_addr_add(ctx, t0, t0, t1);
2875         tcg_temp_free(t1);
2876         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
2877         gen_store_gpr(t0, rt);
2878         break;
2879     case OPC_LWE:
2880         mem_idx = MIPS_HFLAG_UM;
2881         /* fall through */
2882     case OPC_LW:
2883         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
2884                            ctx->default_tcg_memop_mask);
2885         gen_store_gpr(t0, rt);
2886         break;
2887     case OPC_LHE:
2888         mem_idx = MIPS_HFLAG_UM;
2889         /* fall through */
2890     case OPC_LH:
2891         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
2892                            ctx->default_tcg_memop_mask);
2893         gen_store_gpr(t0, rt);
2894         break;
2895     case OPC_LHUE:
2896         mem_idx = MIPS_HFLAG_UM;
2897         /* fall through */
2898     case OPC_LHU:
2899         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
2900                            ctx->default_tcg_memop_mask);
2901         gen_store_gpr(t0, rt);
2902         break;
2903     case OPC_LBE:
2904         mem_idx = MIPS_HFLAG_UM;
2905         /* fall through */
2906     case OPC_LB:
2907         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
2908         gen_store_gpr(t0, rt);
2909         break;
2910     case OPC_LBUE:
2911         mem_idx = MIPS_HFLAG_UM;
2912         /* fall through */
2913     case OPC_LBU:
2914         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
2915         gen_store_gpr(t0, rt);
2916         break;
2917     case OPC_LWLE:
2918         mem_idx = MIPS_HFLAG_UM;
2919         /* fall through */
2920     case OPC_LWL:
2921         t1 = tcg_temp_new();
2922         /* Do a byte access to possibly trigger a page
2923            fault with the unaligned address.  */
2924         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2925         tcg_gen_andi_tl(t1, t0, 3);
2926 #ifndef TARGET_WORDS_BIGENDIAN
2927         tcg_gen_xori_tl(t1, t1, 3);
2928 #endif
2929         tcg_gen_shli_tl(t1, t1, 3);
2930         tcg_gen_andi_tl(t0, t0, ~3);
2931         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
2932         tcg_gen_shl_tl(t0, t0, t1);
2933         t2 = tcg_const_tl(-1);
2934         tcg_gen_shl_tl(t2, t2, t1);
2935         gen_load_gpr(t1, rt);
2936         tcg_gen_andc_tl(t1, t1, t2);
2937         tcg_temp_free(t2);
2938         tcg_gen_or_tl(t0, t0, t1);
2939         tcg_temp_free(t1);
2940         tcg_gen_ext32s_tl(t0, t0);
2941         gen_store_gpr(t0, rt);
2942         break;
2943     case OPC_LWRE:
2944         mem_idx = MIPS_HFLAG_UM;
2945         /* fall through */
2946     case OPC_LWR:
2947         t1 = tcg_temp_new();
2948         /* Do a byte access to possibly trigger a page
2949            fault with the unaligned address.  */
2950         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2951         tcg_gen_andi_tl(t1, t0, 3);
2952 #ifdef TARGET_WORDS_BIGENDIAN
2953         tcg_gen_xori_tl(t1, t1, 3);
2954 #endif
2955         tcg_gen_shli_tl(t1, t1, 3);
2956         tcg_gen_andi_tl(t0, t0, ~3);
2957         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
2958         tcg_gen_shr_tl(t0, t0, t1);
2959         tcg_gen_xori_tl(t1, t1, 31);
2960         t2 = tcg_const_tl(0xfffffffeull);
2961         tcg_gen_shl_tl(t2, t2, t1);
2962         gen_load_gpr(t1, rt);
2963         tcg_gen_and_tl(t1, t1, t2);
2964         tcg_temp_free(t2);
2965         tcg_gen_or_tl(t0, t0, t1);
2966         tcg_temp_free(t1);
2967         tcg_gen_ext32s_tl(t0, t0);
2968         gen_store_gpr(t0, rt);
2969         break;
2970     case OPC_LLE:
2971         mem_idx = MIPS_HFLAG_UM;
2972         /* fall through */
2973     case OPC_LL:
2974     case R6_OPC_LL:
2975         op_ld_ll(t0, t0, mem_idx, ctx);
2976         gen_store_gpr(t0, rt);
2977         break;
2978     }
2979     tcg_temp_free(t0);
2980 }
2981
2982 static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
2983                     uint32_t reg1, uint32_t reg2)
2984 {
2985     TCGv taddr = tcg_temp_new();
2986     TCGv_i64 tval = tcg_temp_new_i64();
2987     TCGv tmp1 = tcg_temp_new();
2988     TCGv tmp2 = tcg_temp_new();
2989
2990     gen_base_offset_addr(ctx, taddr, base, offset);
2991     tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx);
2992 #ifdef TARGET_WORDS_BIGENDIAN
2993     tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
2994 #else
2995     tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
2996 #endif
2997     gen_store_gpr(tmp1, reg1);
2998     tcg_temp_free(tmp1);
2999     gen_store_gpr(tmp2, reg2);
3000     tcg_temp_free(tmp2);
3001     tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3002     tcg_temp_free_i64(tval);
3003     tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr));
3004     tcg_temp_free(taddr);
3005 }
3006
3007 /* Store */
3008 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
3009                     int base, int offset)
3010 {
3011     TCGv t0 = tcg_temp_new();
3012     TCGv t1 = tcg_temp_new();
3013     int mem_idx = ctx->mem_idx;
3014
3015     gen_base_offset_addr(ctx, t0, base, offset);
3016     gen_load_gpr(t1, rt);
3017     switch (opc) {
3018 #if defined(TARGET_MIPS64)
3019     case OPC_SD:
3020         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
3021                            ctx->default_tcg_memop_mask);
3022         break;
3023     case OPC_SDL:
3024         gen_helper_0e2i(sdl, t1, t0, mem_idx);
3025         break;
3026     case OPC_SDR:
3027         gen_helper_0e2i(sdr, t1, t0, mem_idx);
3028         break;
3029 #endif
3030     case OPC_SWE:
3031         mem_idx = MIPS_HFLAG_UM;
3032         /* fall through */
3033     case OPC_SW:
3034         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
3035                            ctx->default_tcg_memop_mask);
3036         break;
3037     case OPC_SHE:
3038         mem_idx = MIPS_HFLAG_UM;
3039         /* fall through */
3040     case OPC_SH:
3041         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
3042                            ctx->default_tcg_memop_mask);
3043         break;
3044     case OPC_SBE:
3045         mem_idx = MIPS_HFLAG_UM;
3046         /* fall through */
3047     case OPC_SB:
3048         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
3049         break;
3050     case OPC_SWLE:
3051         mem_idx = MIPS_HFLAG_UM;
3052         /* fall through */
3053     case OPC_SWL:
3054         gen_helper_0e2i(swl, t1, t0, mem_idx);
3055         break;
3056     case OPC_SWRE:
3057         mem_idx = MIPS_HFLAG_UM;
3058         /* fall through */
3059     case OPC_SWR:
3060         gen_helper_0e2i(swr, t1, t0, mem_idx);
3061         break;
3062     }
3063     tcg_temp_free(t0);
3064     tcg_temp_free(t1);
3065 }
3066
3067
3068 /* Store conditional */
3069 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
3070                          int base, int16_t offset)
3071 {
3072     TCGv t0, t1;
3073     int mem_idx = ctx->mem_idx;
3074
3075 #ifdef CONFIG_USER_ONLY
3076     t0 = tcg_temp_local_new();
3077     t1 = tcg_temp_local_new();
3078 #else
3079     t0 = tcg_temp_new();
3080     t1 = tcg_temp_new();
3081 #endif
3082     gen_base_offset_addr(ctx, t0, base, offset);
3083     gen_load_gpr(t1, rt);
3084     switch (opc) {
3085 #if defined(TARGET_MIPS64)
3086     case OPC_SCD:
3087     case R6_OPC_SCD:
3088         op_st_scd(t1, t0, rt, mem_idx, ctx);
3089         break;
3090 #endif
3091     case OPC_SCE:
3092         mem_idx = MIPS_HFLAG_UM;
3093         /* fall through */
3094     case OPC_SC:
3095     case R6_OPC_SC:
3096         op_st_sc(t1, t0, rt, mem_idx, ctx);
3097         break;
3098     }
3099     tcg_temp_free(t1);
3100     tcg_temp_free(t0);
3101 }
3102
3103 static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
3104                     uint32_t reg1, uint32_t reg2)
3105 {
3106     TCGv taddr = tcg_temp_local_new();
3107     TCGv lladdr = tcg_temp_local_new();
3108     TCGv_i64 tval = tcg_temp_new_i64();
3109     TCGv_i64 llval = tcg_temp_new_i64();
3110     TCGv_i64 val = tcg_temp_new_i64();
3111     TCGv tmp1 = tcg_temp_new();
3112     TCGv tmp2 = tcg_temp_new();
3113     TCGLabel *lab_fail = gen_new_label();
3114     TCGLabel *lab_done = gen_new_label();
3115
3116     gen_base_offset_addr(ctx, taddr, base, offset);
3117
3118     tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3119     tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail);
3120
3121     gen_load_gpr(tmp1, reg1);
3122     gen_load_gpr(tmp2, reg2);
3123
3124 #ifdef TARGET_WORDS_BIGENDIAN
3125     tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
3126 #else
3127     tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
3128 #endif
3129
3130     tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3131     tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
3132                                ctx->mem_idx, MO_64);
3133     if (reg1 != 0) {
3134         tcg_gen_movi_tl(cpu_gpr[reg1], 1);
3135     }
3136     tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done);
3137
3138     gen_set_label(lab_fail);
3139
3140     if (reg1 != 0) {
3141         tcg_gen_movi_tl(cpu_gpr[reg1], 0);
3142     }
3143     gen_set_label(lab_done);
3144     tcg_gen_movi_tl(lladdr, -1);
3145     tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3146 }
3147
3148 /* Load and store */
3149 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
3150                           TCGv t0)
3151 {
3152     /* Don't do NOP if destination is zero: we must perform the actual
3153        memory access. */
3154     switch (opc) {
3155     case OPC_LWC1:
3156         {
3157             TCGv_i32 fp0 = tcg_temp_new_i32();
3158             tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
3159                                 ctx->default_tcg_memop_mask);
3160             gen_store_fpr32(ctx, fp0, ft);
3161             tcg_temp_free_i32(fp0);
3162         }
3163         break;
3164     case OPC_SWC1:
3165         {
3166             TCGv_i32 fp0 = tcg_temp_new_i32();
3167             gen_load_fpr32(ctx, fp0, ft);
3168             tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
3169                                 ctx->default_tcg_memop_mask);
3170             tcg_temp_free_i32(fp0);
3171         }
3172         break;
3173     case OPC_LDC1:
3174         {
3175             TCGv_i64 fp0 = tcg_temp_new_i64();
3176             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3177                                 ctx->default_tcg_memop_mask);
3178             gen_store_fpr64(ctx, fp0, ft);
3179             tcg_temp_free_i64(fp0);
3180         }
3181         break;
3182     case OPC_SDC1:
3183         {
3184             TCGv_i64 fp0 = tcg_temp_new_i64();
3185             gen_load_fpr64(ctx, fp0, ft);
3186             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3187                                 ctx->default_tcg_memop_mask);
3188             tcg_temp_free_i64(fp0);
3189         }
3190         break;
3191     default:
3192         MIPS_INVAL("flt_ldst");
3193         generate_exception_end(ctx, EXCP_RI);
3194         break;
3195     }
3196 }
3197
3198 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
3199                           int rs, int16_t imm)
3200 {
3201     TCGv t0 = tcg_temp_new();
3202
3203     if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3204         check_cp1_enabled(ctx);
3205         switch (op) {
3206         case OPC_LDC1:
3207         case OPC_SDC1:
3208             check_insn(ctx, ISA_MIPS2);
3209             /* Fallthrough */
3210         default:
3211             gen_base_offset_addr(ctx, t0, rs, imm);
3212             gen_flt_ldst(ctx, op, rt, t0);
3213         }
3214     } else {
3215         generate_exception_err(ctx, EXCP_CpU, 1);
3216     }
3217     tcg_temp_free(t0);
3218 }
3219
3220 /* Arithmetic with immediate operand */
3221 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
3222                           int rt, int rs, int imm)
3223 {
3224     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3225
3226     if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
3227         /* If no destination, treat it as a NOP.
3228            For addi, we must generate the overflow exception when needed. */
3229         return;
3230     }
3231     switch (opc) {
3232     case OPC_ADDI:
3233         {
3234             TCGv t0 = tcg_temp_local_new();
3235             TCGv t1 = tcg_temp_new();
3236             TCGv t2 = tcg_temp_new();
3237             TCGLabel *l1 = gen_new_label();
3238
3239             gen_load_gpr(t1, rs);
3240             tcg_gen_addi_tl(t0, t1, uimm);
3241             tcg_gen_ext32s_tl(t0, t0);
3242
3243             tcg_gen_xori_tl(t1, t1, ~uimm);
3244             tcg_gen_xori_tl(t2, t0, uimm);
3245             tcg_gen_and_tl(t1, t1, t2);
3246             tcg_temp_free(t2);
3247             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3248             tcg_temp_free(t1);
3249             /* operands of same sign, result different sign */
3250             generate_exception(ctx, EXCP_OVERFLOW);
3251             gen_set_label(l1);
3252             tcg_gen_ext32s_tl(t0, t0);
3253             gen_store_gpr(t0, rt);
3254             tcg_temp_free(t0);
3255         }
3256         break;
3257     case OPC_ADDIU:
3258         if (rs != 0) {
3259             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3260             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3261         } else {
3262             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3263         }
3264         break;
3265 #if defined(TARGET_MIPS64)
3266     case OPC_DADDI:
3267         {
3268             TCGv t0 = tcg_temp_local_new();
3269             TCGv t1 = tcg_temp_new();
3270             TCGv t2 = tcg_temp_new();
3271             TCGLabel *l1 = gen_new_label();
3272
3273             gen_load_gpr(t1, rs);
3274             tcg_gen_addi_tl(t0, t1, uimm);
3275
3276             tcg_gen_xori_tl(t1, t1, ~uimm);
3277             tcg_gen_xori_tl(t2, t0, uimm);
3278             tcg_gen_and_tl(t1, t1, t2);
3279             tcg_temp_free(t2);
3280             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3281             tcg_temp_free(t1);
3282             /* operands of same sign, result different sign */
3283             generate_exception(ctx, EXCP_OVERFLOW);
3284             gen_set_label(l1);
3285             gen_store_gpr(t0, rt);
3286             tcg_temp_free(t0);
3287         }
3288         break;
3289     case OPC_DADDIU:
3290         if (rs != 0) {
3291             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3292         } else {
3293             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3294         }
3295         break;
3296 #endif
3297     }
3298 }
3299
3300 /* Logic with immediate operand */
3301 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
3302                           int rt, int rs, int16_t imm)
3303 {
3304     target_ulong uimm;
3305
3306     if (rt == 0) {
3307         /* If no destination, treat it as a NOP. */
3308         return;
3309     }
3310     uimm = (uint16_t)imm;
3311     switch (opc) {
3312     case OPC_ANDI:
3313         if (likely(rs != 0))
3314             tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3315         else
3316             tcg_gen_movi_tl(cpu_gpr[rt], 0);
3317         break;
3318     case OPC_ORI:
3319         if (rs != 0)
3320             tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3321         else
3322             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3323         break;
3324     case OPC_XORI:
3325         if (likely(rs != 0))
3326             tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3327         else
3328             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3329         break;
3330     case OPC_LUI:
3331         if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
3332             /* OPC_AUI */
3333             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
3334             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3335         } else {
3336             tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
3337         }
3338         break;
3339
3340     default:
3341         break;
3342     }
3343 }
3344
3345 /* Set on less than with immediate operand */
3346 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
3347                         int rt, int rs, int16_t imm)
3348 {
3349     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3350     TCGv t0;
3351
3352     if (rt == 0) {
3353         /* If no destination, treat it as a NOP. */
3354         return;
3355     }
3356     t0 = tcg_temp_new();
3357     gen_load_gpr(t0, rs);
3358     switch (opc) {
3359     case OPC_SLTI:
3360         tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
3361         break;
3362     case OPC_SLTIU:
3363         tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
3364         break;
3365     }
3366     tcg_temp_free(t0);
3367 }
3368
3369 /* Shifts with immediate operand */
3370 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
3371                           int rt, int rs, int16_t imm)
3372 {
3373     target_ulong uimm = ((uint16_t)imm) & 0x1f;
3374     TCGv t0;
3375
3376     if (rt == 0) {
3377         /* If no destination, treat it as a NOP. */
3378         return;
3379     }
3380
3381     t0 = tcg_temp_new();
3382     gen_load_gpr(t0, rs);
3383     switch (opc) {
3384     case OPC_SLL:
3385         tcg_gen_shli_tl(t0, t0, uimm);
3386         tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3387         break;
3388     case OPC_SRA:
3389         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
3390         break;
3391     case OPC_SRL:
3392         if (uimm != 0) {
3393             tcg_gen_ext32u_tl(t0, t0);
3394             tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3395         } else {
3396             tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3397         }
3398         break;
3399     case OPC_ROTR:
3400         if (uimm != 0) {
3401             TCGv_i32 t1 = tcg_temp_new_i32();
3402
3403             tcg_gen_trunc_tl_i32(t1, t0);
3404             tcg_gen_rotri_i32(t1, t1, uimm);
3405             tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
3406             tcg_temp_free_i32(t1);
3407         } else {
3408             tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3409         }
3410         break;
3411 #if defined(TARGET_MIPS64)
3412     case OPC_DSLL:
3413         tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
3414         break;
3415     case OPC_DSRA:
3416         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
3417         break;
3418     case OPC_DSRL:
3419         tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3420         break;
3421     case OPC_DROTR:
3422         if (uimm != 0) {
3423             tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3424         } else {
3425             tcg_gen_mov_tl(cpu_gpr[rt], t0);
3426         }
3427         break;
3428     case OPC_DSLL32:
3429         tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
3430         break;
3431     case OPC_DSRA32:
3432         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
3433         break;
3434     case OPC_DSRL32:
3435         tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
3436         break;
3437     case OPC_DROTR32:
3438         tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
3439         break;
3440 #endif
3441     }
3442     tcg_temp_free(t0);
3443 }
3444
3445 /* Arithmetic */
3446 static void gen_arith(DisasContext *ctx, uint32_t opc,
3447                       int rd, int rs, int rt)
3448 {
3449     if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
3450        && opc != OPC_DADD && opc != OPC_DSUB) {
3451         /* If no destination, treat it as a NOP.
3452            For add & sub, we must generate the overflow exception when needed. */
3453         return;
3454     }
3455
3456     switch (opc) {
3457     case OPC_ADD:
3458         {
3459             TCGv t0 = tcg_temp_local_new();
3460             TCGv t1 = tcg_temp_new();
3461             TCGv t2 = tcg_temp_new();
3462             TCGLabel *l1 = gen_new_label();
3463
3464             gen_load_gpr(t1, rs);
3465             gen_load_gpr(t2, rt);
3466             tcg_gen_add_tl(t0, t1, t2);
3467             tcg_gen_ext32s_tl(t0, t0);
3468             tcg_gen_xor_tl(t1, t1, t2);
3469             tcg_gen_xor_tl(t2, t0, t2);
3470             tcg_gen_andc_tl(t1, t2, t1);
3471             tcg_temp_free(t2);
3472             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3473             tcg_temp_free(t1);
3474             /* operands of same sign, result different sign */
3475             generate_exception(ctx, EXCP_OVERFLOW);
3476             gen_set_label(l1);
3477             gen_store_gpr(t0, rd);
3478             tcg_temp_free(t0);
3479         }
3480         break;
3481     case OPC_ADDU:
3482         if (rs != 0 && rt != 0) {
3483             tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3484             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3485         } else if (rs == 0 && rt != 0) {
3486             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3487         } else if (rs != 0 && rt == 0) {
3488             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3489         } else {
3490             tcg_gen_movi_tl(cpu_gpr[rd], 0);
3491         }
3492         break;
3493     case OPC_SUB:
3494         {
3495             TCGv t0 = tcg_temp_local_new();
3496             TCGv t1 = tcg_temp_new();
3497             TCGv t2 = tcg_temp_new();
3498             TCGLabel *l1 = gen_new_label();
3499
3500             gen_load_gpr(t1, rs);
3501             gen_load_gpr(t2, rt);
3502             tcg_gen_sub_tl(t0, t1, t2);
3503             tcg_gen_ext32s_tl(t0, t0);
3504             tcg_gen_xor_tl(t2, t1, t2);
3505             tcg_gen_xor_tl(t1, t0, t1);
3506             tcg_gen_and_tl(t1, t1, t2);
3507             tcg_temp_free(t2);
3508             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3509             tcg_temp_free(t1);
3510             /* operands of different sign, first operand and result different sign */
3511             generate_exception(ctx, EXCP_OVERFLOW);
3512             gen_set_label(l1);
3513             gen_store_gpr(t0, rd);
3514             tcg_temp_free(t0);
3515         }
3516         break;
3517     case OPC_SUBU:
3518         if (rs != 0 && rt != 0) {
3519             tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3520             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3521         } else if (rs == 0 && rt != 0) {
3522             tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
3523             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3524         } else if (rs != 0 && rt == 0) {
3525             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3526         } else {
3527             tcg_gen_movi_tl(cpu_gpr[rd], 0);
3528         }
3529         break;
3530 #if defined(TARGET_MIPS64)
3531     case OPC_DADD:
3532         {
3533             TCGv t0 = tcg_temp_local_new();
3534             TCGv t1 = tcg_temp_new();
3535             TCGv t2 = tcg_temp_new();
3536             TCGLabel *l1 = gen_new_label();
3537
3538             gen_load_gpr(t1, rs);
3539             gen_load_gpr(t2, rt);
3540             tcg_gen_add_tl(t0, t1, t2);
3541             tcg_gen_xor_tl(t1, t1, t2);
3542             tcg_gen_xor_tl(t2, t0, t2);
3543             tcg_gen_andc_tl(t1, t2, t1);
3544             tcg_temp_free(t2);
3545             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3546             tcg_temp_free(t1);
3547             /* operands of same sign, result different sign */
3548             generate_exception(ctx, EXCP_OVERFLOW);
3549             gen_set_label(l1);
3550             gen_store_gpr(t0, rd);
3551             tcg_temp_free(t0);
3552         }
3553         break;
3554     case OPC_DADDU:
3555         if (rs != 0 && rt != 0) {
3556             tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3557         } else if (rs == 0 && rt != 0) {
3558             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3559         } else if (rs != 0 && rt == 0) {
3560             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3561         } else {
3562             tcg_gen_movi_tl(cpu_gpr[rd], 0);
3563         }
3564         break;
3565     case OPC_DSUB:
3566         {
3567             TCGv t0 = tcg_temp_local_new();
3568             TCGv t1 = tcg_temp_new();
3569             TCGv t2 = tcg_temp_new();
3570             TCGLabel *l1 = gen_new_label();
3571
3572             gen_load_gpr(t1, rs);
3573             gen_load_gpr(t2, rt);
3574             tcg_gen_sub_tl(t0, t1, t2);
3575             tcg_gen_xor_tl(t2, t1, t2);
3576             tcg_gen_xor_tl(t1, t0, t1);
3577             tcg_gen_and_tl(t1, t1, t2);
3578             tcg_temp_free(t2);
3579             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3580             tcg_temp_free(t1);
3581             /* operands of different sign, first operand and result different sign */
3582             generate_exception(ctx, EXCP_OVERFLOW);
3583             gen_set_label(l1);
3584             gen_store_gpr(t0, rd);
3585             tcg_temp_free(t0);
3586         }
3587         break;
3588     case OPC_DSUBU:
3589         if (rs != 0 && rt != 0) {
3590             tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3591         } else if (rs == 0 && rt != 0) {
3592             tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
3593         } else if (rs != 0 && rt == 0) {
3594             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3595         } else {
3596             tcg_gen_movi_tl(cpu_gpr[rd], 0);
3597         }
3598         break;
3599 #endif
3600     case OPC_MUL:
3601         if (likely(rs != 0 && rt != 0)) {
3602             tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3603             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3604         } else {
3605             tcg_gen_movi_tl(cpu_gpr[rd], 0);
3606         }
3607         break;
3608     }
3609 }
3610
3611 /* Conditional move */
3612 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
3613                           int rd, int rs, int rt)
3614 {
3615     TCGv t0, t1, t2;
3616
3617     if (rd == 0) {
3618         /* If no destination, treat it as a NOP. */
3619         return;
3620     }
3621
3622     t0 = tcg_temp_new();
3623     gen_load_gpr(t0, rt);
3624     t1 = tcg_const_tl(0);
3625     t2 = tcg_temp_new();
3626     gen_load_gpr(t2, rs);
3627     switch (opc) {
3628     case OPC_MOVN:
3629         tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
3630         break;
3631     case OPC_MOVZ:
3632         tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
3633         break;
3634     case OPC_SELNEZ:
3635         tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
3636         break;
3637     case OPC_SELEQZ:
3638         tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
3639         break;
3640     }
3641     tcg_temp_free(t2);
3642     tcg_temp_free(t1);
3643     tcg_temp_free(t0);
3644 }
3645
3646 /* Logic */
3647 static void gen_logic(DisasContext *ctx, uint32_t opc,
3648                       int rd, int rs, int rt)
3649 {
3650     if (rd == 0) {
3651         /* If no destination, treat it as a NOP. */
3652         return;
3653     }
3654
3655     switch (opc) {
3656     case OPC_AND:
3657         if (likely(rs != 0 && rt != 0)) {
3658             tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3659         } else {
3660             tcg_gen_movi_tl(cpu_gpr[rd], 0);
3661         }
3662         break;
3663     case OPC_NOR:
3664         if (rs != 0 && rt != 0) {
3665             tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3666         } else if (rs == 0 && rt != 0) {
3667             tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
3668         } else if (rs != 0 && rt == 0) {
3669             tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
3670         } else {
3671             tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
3672         }
3673         break;
3674     case OPC_OR:
3675         if (likely(rs != 0 && rt != 0)) {
3676             tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3677         } else if (rs == 0 && rt != 0) {
3678             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3679         } else if (rs != 0 && rt == 0) {
3680             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3681         } else {
3682             tcg_gen_movi_tl(cpu_gpr[rd], 0);
3683         }
3684         break;
3685     case OPC_XOR:
3686         if (likely(rs != 0 && rt != 0)) {
3687             tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3688         } else if (rs == 0 && rt != 0) {
3689             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3690         } else if (rs != 0 && rt == 0) {
3691             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3692         } else {
3693             tcg_gen_movi_tl(cpu_gpr[rd], 0);
3694         }
3695         break;
3696     }
3697 }
3698
3699 /* Set on lower than */
3700 static void gen_slt(DisasContext *ctx, uint32_t opc,
3701                     int rd, int rs, int rt)
3702 {
3703     TCGv t0, t1;
3704
3705     if (rd == 0) {
3706         /* If no destination, treat it as a NOP. */
3707         return;
3708     }
3709
3710     t0 = tcg_temp_new();
3711     t1 = tcg_temp_new();
3712     gen_load_gpr(t0, rs);
3713     gen_load_gpr(t1, rt);
3714     switch (opc) {
3715     case OPC_SLT:
3716         tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
3717         break;
3718     case OPC_SLTU:
3719         tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
3720         break;
3721     }
3722     tcg_temp_free(t0);
3723     tcg_temp_free(t1);
3724 }
3725
3726 /* Shifts */
3727 static void gen_shift(DisasContext *ctx, uint32_t opc,
3728                       int rd, int rs, int rt)
3729 {
3730     TCGv t0, t1;
3731
3732     if (rd == 0) {
3733         /* If no destination, treat it as a NOP.
3734            For add & sub, we must generate the overflow exception when needed. */
3735         return;
3736     }
3737
3738     t0 = tcg_temp_new();
3739     t1 = tcg_temp_new();
3740     gen_load_gpr(t0, rs);
3741     gen_load_gpr(t1, rt);
3742     switch (opc) {
3743     case OPC_SLLV:
3744         tcg_gen_andi_tl(t0, t0, 0x1f);
3745         tcg_gen_shl_tl(t0, t1, t0);
3746         tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3747         break;
3748     case OPC_SRAV:
3749         tcg_gen_andi_tl(t0, t0, 0x1f);
3750         tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
3751         break;
3752     case OPC_SRLV:
3753         tcg_gen_ext32u_tl(t1, t1);
3754         tcg_gen_andi_tl(t0, t0, 0x1f);
3755         tcg_gen_shr_tl(t0, t1, t0);
3756         tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3757         break;
3758     case OPC_ROTRV:
3759         {
3760             TCGv_i32 t2 = tcg_temp_new_i32();
3761             TCGv_i32 t3 = tcg_temp_new_i32();
3762
3763             tcg_gen_trunc_tl_i32(t2, t0);
3764             tcg_gen_trunc_tl_i32(t3, t1);
3765             tcg_gen_andi_i32(t2, t2, 0x1f);
3766             tcg_gen_rotr_i32(t2, t3, t2);
3767             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3768             tcg_temp_free_i32(t2);
3769             tcg_temp_free_i32(t3);
3770         }
3771         break;
3772 #if defined(TARGET_MIPS64)
3773     case OPC_DSLLV:
3774         tcg_gen_andi_tl(t0, t0, 0x3f);
3775         tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
3776         break;
3777     case OPC_DSRAV:
3778         tcg_gen_andi_tl(t0, t0, 0x3f);
3779         tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
3780         break;
3781     case OPC_DSRLV:
3782         tcg_gen_andi_tl(t0, t0, 0x3f);
3783         tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
3784         break;
3785     case OPC_DROTRV:
3786         tcg_gen_andi_tl(t0, t0, 0x3f);
3787         tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
3788         break;
3789 #endif
3790     }
3791     tcg_temp_free(t0);
3792     tcg_temp_free(t1);
3793 }
3794
3795 /* Arithmetic on HI/LO registers */
3796 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
3797 {
3798     if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
3799         /* Treat as NOP. */
3800         return;
3801     }
3802
3803     if (acc != 0) {
3804         check_dsp(ctx);
3805     }
3806
3807     switch (opc) {
3808     case OPC_MFHI:
3809 #if defined(TARGET_MIPS64)
3810         if (acc != 0) {
3811             tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
3812         } else
3813 #endif
3814         {
3815             tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3816         }
3817         break;
3818     case OPC_MFLO:
3819 #if defined(TARGET_MIPS64)
3820         if (acc != 0) {
3821             tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3822         } else
3823 #endif
3824         {
3825             tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3826         }
3827         break;
3828     case OPC_MTHI:
3829         if (reg != 0) {
3830 #if defined(TARGET_MIPS64)
3831             if (acc != 0) {
3832                 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3833             } else
3834 #endif
3835             {
3836                 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3837             }
3838         } else {
3839             tcg_gen_movi_tl(cpu_HI[acc], 0);
3840         }
3841         break;
3842     case OPC_MTLO:
3843         if (reg != 0) {
3844 #if defined(TARGET_MIPS64)
3845             if (acc != 0) {
3846                 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3847             } else
3848 #endif
3849             {
3850                 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3851             }
3852         } else {
3853             tcg_gen_movi_tl(cpu_LO[acc], 0);
3854         }
3855         break;
3856     }
3857 }
3858
3859 static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3860                              TCGMemOp memop)
3861 {
3862     TCGv t0 = tcg_const_tl(addr);
3863     tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3864     gen_store_gpr(t0, reg);
3865     tcg_temp_free(t0);
3866 }
3867
3868 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
3869                              int rs)
3870 {
3871     target_long offset;
3872     target_long addr;
3873
3874     switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
3875     case OPC_ADDIUPC:
3876         if (rs != 0) {
3877             offset = sextract32(ctx->opcode << 2, 0, 21);
3878             addr = addr_add(ctx, pc, offset);
3879             tcg_gen_movi_tl(cpu_gpr[rs], addr);
3880         }
3881         break;
3882     case R6_OPC_LWPC:
3883         offset = sextract32(ctx->opcode << 2, 0, 21);
3884         addr = addr_add(ctx, pc, offset);
3885         gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3886         break;
3887 #if defined(TARGET_MIPS64)
3888     case OPC_LWUPC:
3889         check_mips_64(ctx);
3890         offset = sextract32(ctx->opcode << 2, 0, 21);
3891         addr = addr_add(ctx, pc, offset);
3892         gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3893         break;
3894 #endif
3895     default:
3896         switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
3897         case OPC_AUIPC:
3898             if (rs != 0) {
3899                 offset = sextract32(ctx->opcode, 0, 16) << 16;
3900                 addr = addr_add(ctx, pc, offset);
3901                 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3902             }
3903             break;
3904         case OPC_ALUIPC:
3905             if (rs != 0) {
3906                 offset = sextract32(ctx->opcode, 0, 16) << 16;
3907                 addr = ~0xFFFF & addr_add(ctx, pc, offset);
3908                 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3909             }
3910             break;
3911 #if defined(TARGET_MIPS64)
3912         case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3913         case R6_OPC_LDPC + (1 << 16):
3914         case R6_OPC_LDPC + (2 << 16):
3915         case R6_OPC_LDPC + (3 << 16):
3916             check_mips_64(ctx);
3917             offset = sextract32(ctx->opcode << 3, 0, 21);
3918             addr = addr_add(ctx, (pc & ~0x7), offset);
3919             gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3920             break;
3921 #endif
3922         default:
3923             MIPS_INVAL("OPC_PCREL");
3924             generate_exception_end(ctx, EXCP_RI);
3925             break;
3926         }
3927         break;
3928     }
3929 }
3930
3931 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3932 {
3933     TCGv t0, t1;
3934
3935     if (rd == 0) {
3936         /* Treat as NOP. */
3937         return;
3938     }
3939
3940     t0 = tcg_temp_new();
3941     t1 = tcg_temp_new();
3942
3943     gen_load_gpr(t0, rs);
3944     gen_load_gpr(t1, rt);
3945
3946     switch (opc) {
3947     case R6_OPC_DIV:
3948         {
3949             TCGv t2 = tcg_temp_new();
3950             TCGv t3 = tcg_temp_new();
3951             tcg_gen_ext32s_tl(t0, t0);
3952             tcg_gen_ext32s_tl(t1, t1);
3953             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3954             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3955             tcg_gen_and_tl(t2, t2, t3);
3956             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3957             tcg_gen_or_tl(t2, t2, t3);
3958             tcg_gen_movi_tl(t3, 0);
3959             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3960             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3961             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3962             tcg_temp_free(t3);
3963             tcg_temp_free(t2);
3964         }
3965         break;
3966     case R6_OPC_MOD:
3967         {
3968             TCGv t2 = tcg_temp_new();
3969             TCGv t3 = tcg_temp_new();
3970             tcg_gen_ext32s_tl(t0, t0);
3971             tcg_gen_ext32s_tl(t1, t1);
3972             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3973             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3974             tcg_gen_and_tl(t2, t2, t3);
3975             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3976             tcg_gen_or_tl(t2, t2, t3);
3977             tcg_gen_movi_tl(t3, 0);
3978             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3979             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3980             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3981             tcg_temp_free(t3);
3982             tcg_temp_free(t2);
3983         }
3984         break;
3985     case R6_OPC_DIVU:
3986         {
3987             TCGv t2 = tcg_const_tl(0);
3988             TCGv t3 = tcg_const_tl(1);
3989             tcg_gen_ext32u_tl(t0, t0);
3990             tcg_gen_ext32u_tl(t1, t1);
3991             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3992             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3993             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3994             tcg_temp_free(t3);
3995             tcg_temp_free(t2);
3996         }
3997         break;
3998     case R6_OPC_MODU:
3999         {
4000             TCGv t2 = tcg_const_tl(0);
4001             TCGv t3 = tcg_const_tl(1);
4002             tcg_gen_ext32u_tl(t0, t0);
4003             tcg_gen_ext32u_tl(t1, t1);
4004             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4005             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4006             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4007             tcg_temp_free(t3);
4008             tcg_temp_free(t2);
4009         }
4010         break;
4011     case R6_OPC_MUL:
4012         {
4013             TCGv_i32 t2 = tcg_temp_new_i32();
4014             TCGv_i32 t3 = tcg_temp_new_i32();
4015             tcg_gen_trunc_tl_i32(t2, t0);
4016             tcg_gen_trunc_tl_i32(t3, t1);
4017             tcg_gen_mul_i32(t2, t2, t3);
4018             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4019             tcg_temp_free_i32(t2);
4020             tcg_temp_free_i32(t3);
4021         }
4022         break;
4023     case R6_OPC_MUH:
4024         {
4025             TCGv_i32 t2 = tcg_temp_new_i32();
4026             TCGv_i32 t3 = tcg_temp_new_i32();
4027             tcg_gen_trunc_tl_i32(t2, t0);
4028             tcg_gen_trunc_tl_i32(t3, t1);
4029             tcg_gen_muls2_i32(t2, t3, t2, t3);
4030             tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4031             tcg_temp_free_i32(t2);
4032             tcg_temp_free_i32(t3);
4033         }
4034         break;
4035     case R6_OPC_MULU:
4036         {
4037             TCGv_i32 t2 = tcg_temp_new_i32();
4038             TCGv_i32 t3 = tcg_temp_new_i32();
4039             tcg_gen_trunc_tl_i32(t2, t0);
4040             tcg_gen_trunc_tl_i32(t3, t1);
4041             tcg_gen_mul_i32(t2, t2, t3);
4042             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4043             tcg_temp_free_i32(t2);
4044             tcg_temp_free_i32(t3);
4045         }
4046         break;
4047     case R6_OPC_MUHU:
4048         {
4049             TCGv_i32 t2 = tcg_temp_new_i32();
4050             TCGv_i32 t3 = tcg_temp_new_i32();
4051             tcg_gen_trunc_tl_i32(t2, t0);
4052             tcg_gen_trunc_tl_i32(t3, t1);
4053             tcg_gen_mulu2_i32(t2, t3, t2, t3);
4054             tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4055             tcg_temp_free_i32(t2);
4056             tcg_temp_free_i32(t3);
4057         }
4058         break;
4059 #if defined(TARGET_MIPS64)
4060     case R6_OPC_DDIV:
4061         {
4062             TCGv t2 = tcg_temp_new();
4063             TCGv t3 = tcg_temp_new();
4064             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4065             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4066             tcg_gen_and_tl(t2, t2, t3);
4067             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4068             tcg_gen_or_tl(t2, t2, t3);
4069             tcg_gen_movi_tl(t3, 0);
4070             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4071             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4072             tcg_temp_free(t3);
4073             tcg_temp_free(t2);
4074         }
4075         break;
4076     case R6_OPC_DMOD:
4077         {
4078             TCGv t2 = tcg_temp_new();
4079             TCGv t3 = tcg_temp_new();
4080             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4081             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4082             tcg_gen_and_tl(t2, t2, t3);
4083             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4084             tcg_gen_or_tl(t2, t2, t3);
4085             tcg_gen_movi_tl(t3, 0);
4086             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4087             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4088             tcg_temp_free(t3);
4089             tcg_temp_free(t2);
4090         }
4091         break;
4092     case R6_OPC_DDIVU:
4093         {
4094             TCGv t2 = tcg_const_tl(0);
4095             TCGv t3 = tcg_const_tl(1);
4096             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4097             tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
4098             tcg_temp_free(t3);
4099             tcg_temp_free(t2);
4100         }
4101         break;
4102     case R6_OPC_DMODU:
4103         {
4104             TCGv t2 = tcg_const_tl(0);
4105             TCGv t3 = tcg_const_tl(1);
4106             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4107             tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
4108             tcg_temp_free(t3);
4109             tcg_temp_free(t2);
4110         }
4111         break;
4112     case R6_OPC_DMUL:
4113         tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4114         break;
4115     case R6_OPC_DMUH:
4116         {
4117             TCGv t2 = tcg_temp_new();
4118             tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
4119             tcg_temp_free(t2);
4120         }
4121         break;
4122     case R6_OPC_DMULU:
4123         tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4124         break;
4125     case R6_OPC_DMUHU:
4126         {
4127             TCGv t2 = tcg_temp_new();
4128             tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
4129             tcg_temp_free(t2);
4130         }
4131         break;
4132 #endif
4133     default:
4134         MIPS_INVAL("r6 mul/div");
4135         generate_exception_end(ctx, EXCP_RI);
4136         goto out;
4137     }
4138  out:
4139     tcg_temp_free(t0);
4140     tcg_temp_free(t1);
4141 }
4142
4143 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
4144                        int acc, int rs, int rt)
4145 {
4146     TCGv t0, t1;
4147
4148     t0 = tcg_temp_new();
4149     t1 = tcg_temp_new();
4150
4151     gen_load_gpr(t0, rs);
4152     gen_load_gpr(t1, rt);
4153
4154     if (acc != 0) {
4155         check_dsp(ctx);
4156     }
4157
4158     switch (opc) {
4159     case OPC_DIV:
4160         {
4161             TCGv t2 = tcg_temp_new();
4162             TCGv t3 = tcg_temp_new();
4163             tcg_gen_ext32s_tl(t0, t0);
4164             tcg_gen_ext32s_tl(t1, t1);
4165             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4166             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4167             tcg_gen_and_tl(t2, t2, t3);
4168             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4169             tcg_gen_or_tl(t2, t2, t3);
4170             tcg_gen_movi_tl(t3, 0);
4171             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4172             tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4173             tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4174             tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4175             tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4176             tcg_temp_free(t3);
4177             tcg_temp_free(t2);
4178         }
4179         break;
4180     case OPC_DIVU:
4181         {
4182             TCGv t2 = tcg_const_tl(0);
4183             TCGv t3 = tcg_const_tl(1);
4184             tcg_gen_ext32u_tl(t0, t0);
4185             tcg_gen_ext32u_tl(t1, t1);
4186             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4187             tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
4188             tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
4189             tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4190             tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4191             tcg_temp_free(t3);
4192             tcg_temp_free(t2);
4193         }
4194         break;
4195     case OPC_MULT:
4196         {
4197             TCGv_i32 t2 = tcg_temp_new_i32();
4198             TCGv_i32 t3 = tcg_temp_new_i32();
4199             tcg_gen_trunc_tl_i32(t2, t0);
4200             tcg_gen_trunc_tl_i32(t3, t1);
4201             tcg_gen_muls2_i32(t2, t3, t2, t3);
4202             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4203             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4204             tcg_temp_free_i32(t2);
4205             tcg_temp_free_i32(t3);
4206         }
4207         break;
4208     case OPC_MULTU:
4209         {
4210             TCGv_i32 t2 = tcg_temp_new_i32();
4211             TCGv_i32 t3 = tcg_temp_new_i32();
4212             tcg_gen_trunc_tl_i32(t2, t0);
4213             tcg_gen_trunc_tl_i32(t3, t1);
4214             tcg_gen_mulu2_i32(t2, t3, t2, t3);
4215             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4216             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4217             tcg_temp_free_i32(t2);
4218             tcg_temp_free_i32(t3);
4219         }
4220         break;
4221 #if defined(TARGET_MIPS64)
4222     case OPC_DDIV:
4223         {
4224             TCGv t2 = tcg_temp_new();
4225             TCGv t3 = tcg_temp_new();
4226             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4227             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4228             tcg_gen_and_tl(t2, t2, t3);
4229             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4230             tcg_gen_or_tl(t2, t2, t3);
4231             tcg_gen_movi_tl(t3, 0);
4232             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4233             tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4234             tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4235             tcg_temp_free(t3);
4236             tcg_temp_free(t2);
4237         }
4238         break;
4239     case OPC_DDIVU:
4240         {
4241             TCGv t2 = tcg_const_tl(0);
4242             TCGv t3 = tcg_const_tl(1);
4243             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4244             tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
4245             tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
4246             tcg_temp_free(t3);
4247             tcg_temp_free(t2);
4248         }
4249         break;
4250     case OPC_DMULT:
4251         tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
4252         break;
4253     case OPC_DMULTU:
4254         tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
4255         break;
4256 #endif
4257     case OPC_MADD:
4258         {
4259             TCGv_i64 t2 = tcg_temp_new_i64();
4260             TCGv_i64 t3 = tcg_temp_new_i64();
4261
4262             tcg_gen_ext_tl_i64(t2, t0);
4263             tcg_gen_ext_tl_i64(t3, t1);
4264             tcg_gen_mul_i64(t2, t2, t3);
4265             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4266             tcg_gen_add_i64(t2, t2, t3);
4267             tcg_temp_free_i64(t3);
4268             gen_move_low32(cpu_LO[acc], t2);
4269             gen_move_high32(cpu_HI[acc], t2);
4270             tcg_temp_free_i64(t2);
4271         }
4272         break;
4273     case OPC_MADDU:
4274         {
4275             TCGv_i64 t2 = tcg_temp_new_i64();
4276             TCGv_i64 t3 = tcg_temp_new_i64();
4277
4278             tcg_gen_ext32u_tl(t0, t0);
4279             tcg_gen_ext32u_tl(t1, t1);
4280             tcg_gen_extu_tl_i64(t2, t0);
4281             tcg_gen_extu_tl_i64(t3, t1);
4282             tcg_gen_mul_i64(t2, t2, t3);
4283             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4284             tcg_gen_add_i64(t2, t2, t3);
4285             tcg_temp_free_i64(t3);
4286             gen_move_low32(cpu_LO[acc], t2);
4287             gen_move_high32(cpu_HI[acc], t2);
4288             tcg_temp_free_i64(t2);
4289         }
4290         break;
4291     case OPC_MSUB:
4292         {
4293             TCGv_i64 t2 = tcg_temp_new_i64();
4294             TCGv_i64 t3 = tcg_temp_new_i64();
4295
4296             tcg_gen_ext_tl_i64(t2, t0);
4297             tcg_gen_ext_tl_i64(t3, t1);
4298             tcg_gen_mul_i64(t2, t2, t3);
4299             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4300             tcg_gen_sub_i64(t2, t3, t2);
4301             tcg_temp_free_i64(t3);
4302             gen_move_low32(cpu_LO[acc], t2);
4303             gen_move_high32(cpu_HI[acc], t2);
4304             tcg_temp_free_i64(t2);
4305         }
4306         break;
4307     case OPC_MSUBU:
4308         {
4309             TCGv_i64 t2 = tcg_temp_new_i64();
4310             TCGv_i64 t3 = tcg_temp_new_i64();
4311
4312             tcg_gen_ext32u_tl(t0, t0);
4313             tcg_gen_ext32u_tl(t1, t1);
4314             tcg_gen_extu_tl_i64(t2, t0);
4315             tcg_gen_extu_tl_i64(t3, t1);
4316             tcg_gen_mul_i64(t2, t2, t3);
4317             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4318             tcg_gen_sub_i64(t2, t3, t2);
4319             tcg_temp_free_i64(t3);
4320             gen_move_low32(cpu_LO[acc], t2);
4321             gen_move_high32(cpu_HI[acc], t2);
4322             tcg_temp_free_i64(t2);
4323         }
4324         break;
4325     default:
4326         MIPS_INVAL("mul/div");
4327         generate_exception_end(ctx, EXCP_RI);
4328         goto out;
4329     }
4330  out:
4331     tcg_temp_free(t0);
4332     tcg_temp_free(t1);
4333 }
4334
4335 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
4336                             int rd, int rs, int rt)
4337 {
4338     TCGv t0 = tcg_temp_new();
4339     TCGv t1 = tcg_temp_new();
4340
4341     gen_load_gpr(t0, rs);
4342     gen_load_gpr(t1, rt);
4343
4344     switch (opc) {
4345     case OPC_VR54XX_MULS:
4346         gen_helper_muls(t0, cpu_env, t0, t1);
4347         break;
4348     case OPC_VR54XX_MULSU:
4349         gen_helper_mulsu(t0, cpu_env, t0, t1);
4350         break;
4351     case OPC_VR54XX_MACC:
4352         gen_helper_macc(t0, cpu_env, t0, t1);
4353         break;
4354     case OPC_VR54XX_MACCU:
4355         gen_helper_maccu(t0, cpu_env, t0, t1);
4356         break;
4357     case OPC_VR54XX_MSAC:
4358         gen_helper_msac(t0, cpu_env, t0, t1);
4359         break;
4360     case OPC_VR54XX_MSACU:
4361         gen_helper_msacu(t0, cpu_env, t0, t1);
4362         break;
4363     case OPC_VR54XX_MULHI:
4364         gen_helper_mulhi(t0, cpu_env, t0, t1);
4365         break;
4366     case OPC_VR54XX_MULHIU:
4367         gen_helper_mulhiu(t0, cpu_env, t0, t1);
4368         break;
4369     case OPC_VR54XX_MULSHI:
4370         gen_helper_mulshi(t0, cpu_env, t0, t1);
4371         break;
4372     case OPC_VR54XX_MULSHIU:
4373         gen_helper_mulshiu(t0, cpu_env, t0, t1);
4374         break;
4375     case OPC_VR54XX_MACCHI:
4376         gen_helper_macchi(t0, cpu_env, t0, t1);
4377         break;
4378     case OPC_VR54XX_MACCHIU:
4379         gen_helper_macchiu(t0, cpu_env, t0, t1);
4380         break;
4381     case OPC_VR54XX_MSACHI:
4382         gen_helper_msachi(t0, cpu_env, t0, t1);
4383         break;
4384     case OPC_VR54XX_MSACHIU:
4385         gen_helper_msachiu(t0, cpu_env, t0, t1);
4386         break;
4387     default:
4388         MIPS_INVAL("mul vr54xx");
4389         generate_exception_end(ctx, EXCP_RI);
4390         goto out;
4391     }
4392     gen_store_gpr(t0, rd);
4393
4394  out:
4395     tcg_temp_free(t0);
4396     tcg_temp_free(t1);
4397 }
4398
4399 static void gen_cl (DisasContext *ctx, uint32_t opc,
4400                     int rd, int rs)
4401 {
4402     TCGv t0;
4403
4404     if (rd == 0) {
4405         /* Treat as NOP. */
4406         return;
4407     }
4408     t0 = cpu_gpr[rd];
4409     gen_load_gpr(t0, rs);
4410
4411     switch (opc) {
4412     case OPC_CLO:
4413     case R6_OPC_CLO:
4414 #if defined(TARGET_MIPS64)
4415     case OPC_DCLO:
4416     case R6_OPC_DCLO:
4417 #endif
4418         tcg_gen_not_tl(t0, t0);
4419         break;
4420     }
4421
4422     switch (opc) {
4423     case OPC_CLO:
4424     case R6_OPC_CLO:
4425     case OPC_CLZ:
4426     case R6_OPC_CLZ:
4427         tcg_gen_ext32u_tl(t0, t0);
4428         tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
4429         tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
4430         break;
4431 #if defined(TARGET_MIPS64)
4432     case OPC_DCLO:
4433     case R6_OPC_DCLO:
4434     case OPC_DCLZ:
4435     case R6_OPC_DCLZ:
4436         tcg_gen_clzi_i64(t0, t0, 64);
4437         break;
4438 #endif
4439     }
4440 }
4441
4442 /* Godson integer instructions */
4443 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
4444                                  int rd, int rs, int rt)
4445 {
4446     TCGv t0, t1;
4447
4448     if (rd == 0) {
4449         /* Treat as NOP. */
4450         return;
4451     }
4452
4453     switch (opc) {
4454     case OPC_MULT_G_2E:
4455     case OPC_MULT_G_2F:
4456     case OPC_MULTU_G_2E:
4457     case OPC_MULTU_G_2F:
4458 #if defined(TARGET_MIPS64)
4459     case OPC_DMULT_G_2E:
4460     case OPC_DMULT_G_2F:
4461     case OPC_DMULTU_G_2E:
4462     case OPC_DMULTU_G_2F:
4463 #endif
4464         t0 = tcg_temp_new();
4465         t1 = tcg_temp_new();
4466         break;
4467     default:
4468         t0 = tcg_temp_local_new();
4469         t1 = tcg_temp_local_new();
4470         break;
4471     }
4472
4473     gen_load_gpr(t0, rs);
4474     gen_load_gpr(t1, rt);
4475
4476     switch (opc) {
4477     case OPC_MULT_G_2E:
4478     case OPC_MULT_G_2F:
4479         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
4480         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4481         break;
4482     case OPC_MULTU_G_2E:
4483     case OPC_MULTU_G_2F:
4484         tcg_gen_ext32u_tl(t0, t0);
4485         tcg_gen_ext32u_tl(t1, t1);
4486         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
4487         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4488         break;
4489     case OPC_DIV_G_2E:
4490     case OPC_DIV_G_2F:
4491         {
4492             TCGLabel *l1 = gen_new_label();
4493             TCGLabel *l2 = gen_new_label();
4494             TCGLabel *l3 = gen_new_label();
4495             tcg_gen_ext32s_tl(t0, t0);
4496             tcg_gen_ext32s_tl(t1, t1);
4497             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4498             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4499             tcg_gen_br(l3);
4500             gen_set_label(l1);
4501             tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
4502             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
4503             tcg_gen_mov_tl(cpu_gpr[rd], t0);
4504             tcg_gen_br(l3);
4505             gen_set_label(l2);
4506             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4507             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4508             gen_set_label(l3);
4509         }
4510         break;
4511     case OPC_DIVU_G_2E:
4512     case OPC_DIVU_G_2F:
4513         {
4514             TCGLabel *l1 = gen_new_label();
4515             TCGLabel *l2 = gen_new_label();
4516             tcg_gen_ext32u_tl(t0, t0);
4517             tcg_gen_ext32u_tl(t1, t1);
4518             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4519             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4520             tcg_gen_br(l2);
4521             gen_set_label(l1);
4522             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4523             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4524             gen_set_label(l2);
4525         }
4526         break;
4527     case OPC_MOD_G_2E:
4528     case OPC_MOD_G_2F:
4529         {
4530             TCGLabel *l1 = gen_new_label();
4531             TCGLabel *l2 = gen_new_label();
4532             TCGLabel *l3 = gen_new_label();
4533             tcg_gen_ext32u_tl(t0, t0);
4534             tcg_gen_ext32u_tl(t1, t1);
4535             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
4536             tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
4537             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
4538             gen_set_label(l1);
4539             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4540             tcg_gen_br(l3);
4541             gen_set_label(l2);
4542             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4543             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4544             gen_set_label(l3);
4545         }
4546         break;
4547     case OPC_MODU_G_2E:
4548     case OPC_MODU_G_2F:
4549         {
4550             TCGLabel *l1 = gen_new_label();
4551             TCGLabel *l2 = gen_new_label();
4552             tcg_gen_ext32u_tl(t0, t0);
4553             tcg_gen_ext32u_tl(t1, t1);
4554             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4555             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4556             tcg_gen_br(l2);
4557             gen_set_label(l1);
4558             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4559             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4560             gen_set_label(l2);
4561         }
4562         break;
4563 #if defined(TARGET_MIPS64)
4564     case OPC_DMULT_G_2E:
4565     case OPC_DMULT_G_2F:
4566         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
4567         break;
4568     case OPC_DMULTU_G_2E:
4569     case OPC_DMULTU_G_2F:
4570         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
4571         break;
4572     case OPC_DDIV_G_2E:
4573     case OPC_DDIV_G_2F:
4574         {
4575             TCGLabel *l1 = gen_new_label();
4576             TCGLabel *l2 = gen_new_label();
4577             TCGLabel *l3 = gen_new_label();
4578             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4579             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4580             tcg_gen_br(l3);
4581             gen_set_label(l1);
4582             tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
4583             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
4584             tcg_gen_mov_tl(cpu_gpr[rd], t0);
4585             tcg_gen_br(l3);
4586             gen_set_label(l2);
4587             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4588             gen_set_label(l3);
4589         }
4590         break;
4591     case OPC_DDIVU_G_2E:
4592     case OPC_DDIVU_G_2F:
4593         {
4594             TCGLabel *l1 = gen_new_label();
4595             TCGLabel *l2 = gen_new_label();
4596             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4597             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4598             tcg_gen_br(l2);
4599             gen_set_label(l1);
4600             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4601             gen_set_label(l2);
4602         }
4603         break;
4604     case OPC_DMOD_G_2E:
4605     case OPC_DMOD_G_2F:
4606         {
4607             TCGLabel *l1 = gen_new_label();
4608             TCGLabel *l2 = gen_new_label();
4609             TCGLabel *l3 = gen_new_label();
4610             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
4611             tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
4612             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
4613             gen_set_label(l1);
4614             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4615             tcg_gen_br(l3);
4616             gen_set_label(l2);
4617             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4618             gen_set_label(l3);
4619         }
4620         break;
4621     case OPC_DMODU_G_2E:
4622     case OPC_DMODU_G_2F:
4623         {
4624             TCGLabel *l1 = gen_new_label();
4625             TCGLabel *l2 = gen_new_label();
4626             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4627             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4628             tcg_gen_br(l2);
4629             gen_set_label(l1);
4630             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4631             gen_set_label(l2);
4632         }
4633         break;
4634 #endif
4635     }
4636
4637     tcg_temp_free(t0);
4638     tcg_temp_free(t1);
4639 }
4640
4641 /* Loongson multimedia instructions */
4642 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
4643 {
4644     uint32_t opc, shift_max;
4645     TCGv_i64 t0, t1;
4646
4647     opc = MASK_LMI(ctx->opcode);
4648     switch (opc) {
4649     case OPC_ADD_CP2:
4650     case OPC_SUB_CP2:
4651     case OPC_DADD_CP2:
4652     case OPC_DSUB_CP2:
4653         t0 = tcg_temp_local_new_i64();
4654         t1 = tcg_temp_local_new_i64();
4655         break;
4656     default:
4657         t0 = tcg_temp_new_i64();
4658         t1 = tcg_temp_new_i64();
4659         break;
4660     }
4661
4662     check_cp1_enabled(ctx);
4663     gen_load_fpr64(ctx, t0, rs);
4664     gen_load_fpr64(ctx, t1, rt);
4665
4666 #define LMI_HELPER(UP, LO) \
4667     case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
4668 #define LMI_HELPER_1(UP, LO) \
4669     case OPC_##UP: gen_helper_##LO(t0, t0); break
4670 #define LMI_DIRECT(UP, LO, OP) \
4671     case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
4672
4673     switch (opc) {
4674     LMI_HELPER(PADDSH, paddsh);
4675     LMI_HELPER(PADDUSH, paddush);
4676     LMI_HELPER(PADDH, paddh);
4677     LMI_HELPER(PADDW, paddw);
4678     LMI_HELPER(PADDSB, paddsb);
4679     LMI_HELPER(PADDUSB, paddusb);
4680     LMI_HELPER(PADDB, paddb);
4681
4682     LMI_HELPER(PSUBSH, psubsh);
4683     LMI_HELPER(PSUBUSH, psubush);
4684     LMI_HELPER(PSUBH, psubh);
4685     LMI_HELPER(PSUBW, psubw);
4686     LMI_HELPER(PSUBSB, psubsb);
4687     LMI_HELPER(PSUBUSB, psubusb);
4688     LMI_HELPER(PSUBB, psubb);
4689
4690     LMI_HELPER(PSHUFH, pshufh);
4691     LMI_HELPER(PACKSSWH, packsswh);
4692     LMI_HELPER(PACKSSHB, packsshb);
4693     LMI_HELPER(PACKUSHB, packushb);
4694
4695     LMI_HELPER(PUNPCKLHW, punpcklhw);
4696     LMI_HELPER(PUNPCKHHW, punpckhhw);
4697     LMI_HELPER(PUNPCKLBH, punpcklbh);
4698     LMI_HELPER(PUNPCKHBH, punpckhbh);
4699     LMI_HELPER(PUNPCKLWD, punpcklwd);
4700     LMI_HELPER(PUNPCKHWD, punpckhwd);
4701
4702     LMI_HELPER(PAVGH, pavgh);
4703     LMI_HELPER(PAVGB, pavgb);
4704     LMI_HELPER(PMAXSH, pmaxsh);
4705     LMI_HELPER(PMINSH, pminsh);
4706     LMI_HELPER(PMAXUB, pmaxub);
4707     LMI_HELPER(PMINUB, pminub);
4708
4709     LMI_HELPER(PCMPEQW, pcmpeqw);
4710     LMI_HELPER(PCMPGTW, pcmpgtw);
4711     LMI_HELPER(PCMPEQH, pcmpeqh);
4712     LMI_HELPER(PCMPGTH, pcmpgth);
4713     LMI_HELPER(PCMPEQB, pcmpeqb);
4714     LMI_HELPER(PCMPGTB, pcmpgtb);
4715
4716     LMI_HELPER(PSLLW, psllw);
4717     LMI_HELPER(PSLLH, psllh);
4718     LMI_HELPER(PSRLW, psrlw);
4719     LMI_HELPER(PSRLH, psrlh);
4720     LMI_HELPER(PSRAW, psraw);
4721     LMI_HELPER(PSRAH, psrah);
4722
4723     LMI_HELPER(PMULLH, pmullh);
4724     LMI_HELPER(PMULHH, pmulhh);
4725     LMI_HELPER(PMULHUH, pmulhuh);
4726     LMI_HELPER(PMADDHW, pmaddhw);
4727
4728     LMI_HELPER(PASUBUB, pasubub);
4729     LMI_HELPER_1(BIADD, biadd);
4730     LMI_HELPER_1(PMOVMSKB, pmovmskb);
4731
4732     LMI_DIRECT(PADDD, paddd, add);
4733     LMI_DIRECT(PSUBD, psubd, sub);
4734     LMI_DIRECT(XOR_CP2, xor, xor);
4735     LMI_DIRECT(NOR_CP2, nor, nor);
4736     LMI_DIRECT(AND_CP2, and, and);
4737     LMI_DIRECT(OR_CP2, or, or);
4738
4739     case OPC_PANDN:
4740         tcg_gen_andc_i64(t0, t1, t0);
4741         break;
4742
4743     case OPC_PINSRH_0:
4744         tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
4745         break;
4746     case OPC_PINSRH_1:
4747         tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
4748         break;
4749     case OPC_PINSRH_2:
4750         tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
4751         break;
4752     case OPC_PINSRH_3:
4753         tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
4754         break;
4755
4756     case OPC_PEXTRH:
4757         tcg_gen_andi_i64(t1, t1, 3);
4758         tcg_gen_shli_i64(t1, t1, 4);
4759         tcg_gen_shr_i64(t0, t0, t1);
4760         tcg_gen_ext16u_i64(t0, t0);
4761         break;
4762
4763     case OPC_ADDU_CP2:
4764         tcg_gen_add_i64(t0, t0, t1);
4765         tcg_gen_ext32s_i64(t0, t0);
4766         break;
4767     case OPC_SUBU_CP2:
4768         tcg_gen_sub_i64(t0, t0, t1);
4769         tcg_gen_ext32s_i64(t0, t0);
4770         break;
4771
4772     case OPC_SLL_CP2:
4773         shift_max = 32;
4774         goto do_shift;
4775     case OPC_SRL_CP2:
4776         shift_max = 32;
4777         goto do_shift;
4778     case OPC_SRA_CP2:
4779         shift_max = 32;
4780         goto do_shift;
4781     case OPC_DSLL_CP2:
4782         shift_max = 64;
4783         goto do_shift;
4784     case OPC_DSRL_CP2:
4785         shift_max = 64;
4786         goto do_shift;
4787     case OPC_DSRA_CP2:
4788         shift_max = 64;
4789         goto do_shift;
4790     do_shift:
4791         /* Make sure shift count isn't TCG undefined behaviour.  */
4792         tcg_gen_andi_i64(t1, t1, shift_max - 1);
4793
4794         switch (opc) {
4795         case OPC_SLL_CP2:
4796         case OPC_DSLL_CP2:
4797             tcg_gen_shl_i64(t0, t0, t1);
4798             break;
4799         case OPC_SRA_CP2:
4800         case OPC_DSRA_CP2:
4801             /* Since SRA is UndefinedResult without sign-extended inputs,
4802                we can treat SRA and DSRA the same.  */
4803             tcg_gen_sar_i64(t0, t0, t1);
4804             break;
4805         case OPC_SRL_CP2:
4806             /* We want to shift in zeros for SRL; zero-extend first.  */
4807             tcg_gen_ext32u_i64(t0, t0);
4808             /* FALLTHRU */
4809         case OPC_DSRL_CP2:
4810             tcg_gen_shr_i64(t0, t0, t1);
4811             break;
4812         }
4813
4814         if (shift_max == 32) {
4815             tcg_gen_ext32s_i64(t0, t0);
4816         }
4817
4818         /* Shifts larger than MAX produce zero.  */
4819         tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4820         tcg_gen_neg_i64(t1, t1);
4821         tcg_gen_and_i64(t0, t0, t1);
4822         break;
4823
4824     case OPC_ADD_CP2:
4825     case OPC_DADD_CP2:
4826         {
4827             TCGv_i64 t2 = tcg_temp_new_i64();
4828             TCGLabel *lab = gen_new_label();
4829
4830             tcg_gen_mov_i64(t2, t0);
4831             tcg_gen_add_i64(t0, t1, t2);
4832             if (opc == OPC_ADD_CP2) {
4833                 tcg_gen_ext32s_i64(t0, t0);
4834             }
4835             tcg_gen_xor_i64(t1, t1, t2);
4836             tcg_gen_xor_i64(t2, t2, t0);
4837             tcg_gen_andc_i64(t1, t2, t1);
4838             tcg_temp_free_i64(t2);
4839             tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4840             generate_exception(ctx, EXCP_OVERFLOW);
4841             gen_set_label(lab);
4842             break;
4843         }
4844
4845     case OPC_SUB_CP2:
4846     case OPC_DSUB_CP2:
4847         {
4848             TCGv_i64 t2 = tcg_temp_new_i64();
4849             TCGLabel *lab = gen_new_label();
4850
4851             tcg_gen_mov_i64(t2, t0);
4852             tcg_gen_sub_i64(t0, t1, t2);
4853             if (opc == OPC_SUB_CP2) {
4854                 tcg_gen_ext32s_i64(t0, t0);
4855             }
4856             tcg_gen_xor_i64(t1, t1, t2);
4857             tcg_gen_xor_i64(t2, t2, t0);
4858             tcg_gen_and_i64(t1, t1, t2);
4859             tcg_temp_free_i64(t2);
4860             tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4861             generate_exception(ctx, EXCP_OVERFLOW);
4862             gen_set_label(lab);
4863             break;
4864         }
4865
4866     case OPC_PMULUW:
4867         tcg_gen_ext32u_i64(t0, t0);
4868         tcg_gen_ext32u_i64(t1, t1);
4869         tcg_gen_mul_i64(t0, t0, t1);
4870         break;
4871
4872     case OPC_SEQU_CP2:
4873     case OPC_SEQ_CP2:
4874     case OPC_SLTU_CP2:
4875     case OPC_SLT_CP2:
4876     case OPC_SLEU_CP2:
4877     case OPC_SLE_CP2:
4878         /* ??? Document is unclear: Set FCC[CC].  Does that mean the
4879            FD field is the CC field?  */
4880     default:
4881         MIPS_INVAL("loongson_cp2");
4882         generate_exception_end(ctx, EXCP_RI);
4883         return;
4884     }
4885
4886 #undef LMI_HELPER
4887 #undef LMI_DIRECT
4888
4889     gen_store_fpr64(ctx, t0, rd);
4890
4891     tcg_temp_free_i64(t0);
4892     tcg_temp_free_i64(t1);
4893 }
4894
4895 /* Traps */
4896 static void gen_trap (DisasContext *ctx, uint32_t opc,
4897                       int rs, int rt, int16_t imm)
4898 {
4899     int cond;
4900     TCGv t0 = tcg_temp_new();
4901     TCGv t1 = tcg_temp_new();
4902
4903     cond = 0;
4904     /* Load needed operands */
4905     switch (opc) {
4906     case OPC_TEQ:
4907     case OPC_TGE:
4908     case OPC_TGEU:
4909     case OPC_TLT:
4910     case OPC_TLTU:
4911     case OPC_TNE:
4912         /* Compare two registers */
4913         if (rs != rt) {
4914             gen_load_gpr(t0, rs);
4915             gen_load_gpr(t1, rt);
4916             cond = 1;
4917         }
4918         break;
4919     case OPC_TEQI:
4920     case OPC_TGEI:
4921     case OPC_TGEIU:
4922     case OPC_TLTI:
4923     case OPC_TLTIU:
4924     case OPC_TNEI:
4925         /* Compare register to immediate */
4926         if (rs != 0 || imm != 0) {
4927             gen_load_gpr(t0, rs);
4928             tcg_gen_movi_tl(t1, (int32_t)imm);
4929             cond = 1;
4930         }
4931         break;
4932     }
4933     if (cond == 0) {
4934         switch (opc) {
4935         case OPC_TEQ:   /* rs == rs */
4936         case OPC_TEQI:  /* r0 == 0  */
4937         case OPC_TGE:   /* rs >= rs */
4938         case OPC_TGEI:  /* r0 >= 0  */
4939         case OPC_TGEU:  /* rs >= rs unsigned */
4940         case OPC_TGEIU: /* r0 >= 0  unsigned */
4941             /* Always trap */
4942             generate_exception_end(ctx, EXCP_TRAP);
4943             break;
4944         case OPC_TLT:   /* rs < rs           */
4945         case OPC_TLTI:  /* r0 < 0            */
4946         case OPC_TLTU:  /* rs < rs unsigned  */
4947         case OPC_TLTIU: /* r0 < 0  unsigned  */
4948         case OPC_TNE:   /* rs != rs          */
4949         case OPC_TNEI:  /* r0 != 0           */
4950             /* Never trap: treat as NOP. */
4951             break;
4952         }
4953     } else {
4954         TCGLabel *l1 = gen_new_label();
4955
4956         switch (opc) {
4957         case OPC_TEQ:
4958         case OPC_TEQI:
4959             tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
4960             break;
4961         case OPC_TGE:
4962         case OPC_TGEI:
4963             tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
4964             break;
4965         case OPC_TGEU:
4966         case OPC_TGEIU:
4967             tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
4968             break;
4969         case OPC_TLT:
4970         case OPC_TLTI:
4971             tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4972             break;
4973         case OPC_TLTU:
4974         case OPC_TLTIU:
4975             tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
4976             break;
4977         case OPC_TNE:
4978         case OPC_TNEI:
4979             tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
4980             break;
4981         }
4982         generate_exception(ctx, EXCP_TRAP);
4983         gen_set_label(l1);
4984     }
4985     tcg_temp_free(t0);
4986     tcg_temp_free(t1);
4987 }
4988
4989 static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
4990 {
4991     if (unlikely(ctx->base.singlestep_enabled)) {
4992         return false;
4993     }
4994
4995 #ifndef CONFIG_USER_ONLY
4996     return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
4997 #else
4998     return true;
4999 #endif
5000 }
5001
5002 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
5003 {
5004     if (use_goto_tb(ctx, dest)) {
5005         tcg_gen_goto_tb(n);
5006         gen_save_pc(dest);
5007         tcg_gen_exit_tb(ctx->base.tb, n);
5008     } else {
5009         gen_save_pc(dest);
5010         if (ctx->base.singlestep_enabled) {
5011             save_cpu_state(ctx, 0);
5012             gen_helper_raise_exception_debug(cpu_env);
5013         }
5014         tcg_gen_lookup_and_goto_ptr();
5015     }
5016 }
5017
5018 /* Branches (before delay slot) */
5019 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
5020                                 int insn_bytes,
5021                                 int rs, int rt, int32_t offset,
5022                                 int delayslot_size)
5023 {
5024     target_ulong btgt = -1;
5025     int blink = 0;
5026     int bcond_compute = 0;
5027     TCGv t0 = tcg_temp_new();
5028     TCGv t1 = tcg_temp_new();
5029
5030     if (ctx->hflags & MIPS_HFLAG_BMASK) {
5031 #ifdef MIPS_DEBUG_DISAS
5032         LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
5033                   TARGET_FMT_lx "\n", ctx->base.pc_next);
5034 #endif
5035         generate_exception_end(ctx, EXCP_RI);
5036         goto out;
5037     }
5038
5039     /* Load needed operands */
5040     switch (opc) {
5041     case OPC_BEQ:
5042     case OPC_BEQL:
5043     case OPC_BNE:
5044     case OPC_BNEL:
5045         /* Compare two registers */
5046         if (rs != rt) {
5047             gen_load_gpr(t0, rs);
5048             gen_load_gpr(t1, rt);
5049             bcond_compute = 1;
5050         }
5051         btgt = ctx->base.pc_next + insn_bytes + offset;
5052         break;
5053     case OPC_BGEZ:
5054     case OPC_BGEZAL:
5055     case OPC_BGEZALL:
5056     case OPC_BGEZL:
5057     case OPC_BGTZ:
5058     case OPC_BGTZL:
5059     case OPC_BLEZ:
5060     case OPC_BLEZL:
5061     case OPC_BLTZ:
5062     case OPC_BLTZAL:
5063     case OPC_BLTZALL:
5064     case OPC_BLTZL:
5065         /* Compare to zero */
5066         if (rs != 0) {
5067             gen_load_gpr(t0, rs);
5068             bcond_compute = 1;
5069         }
5070         btgt = ctx->base.pc_next + insn_bytes + offset;
5071         break;
5072     case OPC_BPOSGE32:
5073 #if defined(TARGET_MIPS64)
5074     case OPC_BPOSGE64:
5075         tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
5076 #else
5077         tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5078 #endif
5079         bcond_compute = 1;
5080         btgt = ctx->base.pc_next + insn_bytes + offset;
5081         break;
5082     case OPC_J:
5083     case OPC_JAL:
5084     case OPC_JALX:
5085         /* Jump to immediate */
5086         btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
5087             (uint32_t)offset;
5088         break;
5089     case OPC_JR:
5090     case OPC_JALR:
5091         /* Jump to register */
5092         if (offset != 0 && offset != 16) {
5093             /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5094                others are reserved. */
5095             MIPS_INVAL("jump hint");
5096             generate_exception_end(ctx, EXCP_RI);
5097             goto out;
5098         }
5099         gen_load_gpr(btarget, rs);
5100         break;
5101     default:
5102         MIPS_INVAL("branch/jump");
5103         generate_exception_end(ctx, EXCP_RI);
5104         goto out;
5105     }
5106     if (bcond_compute == 0) {
5107         /* No condition to be computed */
5108         switch (opc) {
5109         case OPC_BEQ:     /* rx == rx        */
5110         case OPC_BEQL:    /* rx == rx likely */
5111         case OPC_BGEZ:    /* 0 >= 0          */
5112         case OPC_BGEZL:   /* 0 >= 0 likely   */
5113         case OPC_BLEZ:    /* 0 <= 0          */
5114         case OPC_BLEZL:   /* 0 <= 0 likely   */
5115             /* Always take */
5116             ctx->hflags |= MIPS_HFLAG_B;
5117             break;
5118         case OPC_BGEZAL:  /* 0 >= 0          */
5119         case OPC_BGEZALL: /* 0 >= 0 likely   */
5120             /* Always take and link */
5121             blink = 31;
5122             ctx->hflags |= MIPS_HFLAG_B;
5123             break;
5124         case OPC_BNE:     /* rx != rx        */
5125         case OPC_BGTZ:    /* 0 > 0           */
5126         case OPC_BLTZ:    /* 0 < 0           */
5127             /* Treat as NOP. */
5128             goto out;
5129         case OPC_BLTZAL:  /* 0 < 0           */
5130             /* Handle as an unconditional branch to get correct delay
5131                slot checking.  */
5132             blink = 31;
5133             btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
5134             ctx->hflags |= MIPS_HFLAG_B;
5135             break;
5136         case OPC_BLTZALL: /* 0 < 0 likely */
5137             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
5138             /* Skip the instruction in the delay slot */
5139             ctx->base.pc_next += 4;
5140             goto out;
5141         case OPC_BNEL:    /* rx != rx likely */
5142         case OPC_BGTZL:   /* 0 > 0 likely */
5143         case OPC_BLTZL:   /* 0 < 0 likely */
5144             /* Skip the instruction in the delay slot */
5145             ctx->base.pc_next += 4;
5146             goto out;
5147         case OPC_J:
5148             ctx->hflags |= MIPS_HFLAG_B;
5149             break;
5150         case OPC_JALX:
5151             ctx->hflags |= MIPS_HFLAG_BX;
5152             /* Fallthrough */
5153         case OPC_JAL:
5154             blink = 31;
5155             ctx->hflags |= MIPS_HFLAG_B;
5156             break;
5157         case OPC_JR:
5158             ctx->hflags |= MIPS_HFLAG_BR;
5159             break;
5160         case OPC_JALR:
5161             blink = rt;
5162             ctx->hflags |= MIPS_HFLAG_BR;
5163             break;
5164         default:
5165             MIPS_INVAL("branch/jump");
5166             generate_exception_end(ctx, EXCP_RI);
5167             goto out;
5168         }
5169     } else {
5170         switch (opc) {
5171         case OPC_BEQ:
5172             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5173             goto not_likely;
5174         case OPC_BEQL:
5175             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5176             goto likely;
5177         case OPC_BNE:
5178             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5179             goto not_likely;
5180         case OPC_BNEL:
5181             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5182             goto likely;
5183         case OPC_BGEZ:
5184             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5185             goto not_likely;
5186         case OPC_BGEZL:
5187             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5188             goto likely;
5189         case OPC_BGEZAL:
5190             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5191             blink = 31;
5192             goto not_likely;
5193         case OPC_BGEZALL:
5194             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5195             blink = 31;
5196             goto likely;
5197         case OPC_BGTZ:
5198             tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5199             goto not_likely;
5200         case OPC_BGTZL:
5201             tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5202             goto likely;
5203         case OPC_BLEZ:
5204             tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
5205             goto not_likely;
5206         case OPC_BLEZL:
5207             tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
5208             goto likely;
5209         case OPC_BLTZ:
5210             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5211             goto not_likely;
5212         case OPC_BLTZL:
5213             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5214             goto likely;
5215         case OPC_BPOSGE32:
5216             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
5217             goto not_likely;
5218 #if defined(TARGET_MIPS64)
5219         case OPC_BPOSGE64:
5220             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
5221             goto not_likely;
5222 #endif
5223         case OPC_BLTZAL:
5224             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5225             blink = 31;
5226         not_likely:
5227             ctx->hflags |= MIPS_HFLAG_BC;
5228             break;
5229         case OPC_BLTZALL:
5230             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5231             blink = 31;
5232         likely:
5233             ctx->hflags |= MIPS_HFLAG_BL;
5234             break;
5235         default:
5236             MIPS_INVAL("conditional branch/jump");
5237             generate_exception_end(ctx, EXCP_RI);
5238             goto out;
5239         }
5240     }
5241
5242     ctx->btarget = btgt;
5243
5244     switch (delayslot_size) {
5245     case 2:
5246         ctx->hflags |= MIPS_HFLAG_BDS16;
5247         break;
5248     case 4:
5249         ctx->hflags |= MIPS_HFLAG_BDS32;
5250         break;
5251     }
5252
5253     if (blink > 0) {
5254         int post_delay = insn_bytes + delayslot_size;
5255         int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
5256
5257         tcg_gen_movi_tl(cpu_gpr[blink],
5258                         ctx->base.pc_next + post_delay + lowbit);
5259     }
5260
5261  out:
5262     if (insn_bytes == 2)
5263         ctx->hflags |= MIPS_HFLAG_B16;
5264     tcg_temp_free(t0);
5265     tcg_temp_free(t1);
5266 }
5267
5268
5269 /* nanoMIPS Branches */
5270 static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc,
5271                                 int insn_bytes,
5272                                 int rs, int rt, int32_t offset)
5273 {
5274     target_ulong btgt = -1;
5275     int bcond_compute = 0;
5276     TCGv t0 = tcg_temp_new();
5277     TCGv t1 = tcg_temp_new();
5278
5279     /* Load needed operands */
5280     switch (opc) {
5281     case OPC_BEQ:
5282     case OPC_BNE:
5283         /* Compare two registers */
5284         if (rs != rt) {
5285             gen_load_gpr(t0, rs);
5286             gen_load_gpr(t1, rt);
5287             bcond_compute = 1;
5288         }
5289         btgt = ctx->base.pc_next + insn_bytes + offset;
5290         break;
5291     case OPC_BGEZAL:
5292         /* Compare to zero */
5293         if (rs != 0) {
5294             gen_load_gpr(t0, rs);
5295             bcond_compute = 1;
5296         }
5297         btgt = ctx->base.pc_next + insn_bytes + offset;
5298         break;
5299     case OPC_BPOSGE32:
5300         tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5301         bcond_compute = 1;
5302         btgt = ctx->base.pc_next + insn_bytes + offset;
5303         break;
5304     case OPC_JR:
5305     case OPC_JALR:
5306         /* Jump to register */
5307         if (offset != 0 && offset != 16) {
5308             /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5309                others are reserved. */
5310             MIPS_INVAL("jump hint");
5311             generate_exception_end(ctx, EXCP_RI);
5312             goto out;
5313         }
5314         gen_load_gpr(btarget, rs);
5315         break;
5316     default:
5317         MIPS_INVAL("branch/jump");
5318         generate_exception_end(ctx, EXCP_RI);
5319         goto out;
5320     }
5321     if (bcond_compute == 0) {
5322         /* No condition to be computed */
5323         switch (opc) {
5324         case OPC_BEQ:     /* rx == rx        */
5325             /* Always take */
5326             ctx->hflags |= MIPS_HFLAG_B;
5327             break;
5328         case OPC_BGEZAL:  /* 0 >= 0          */
5329             /* Always take and link */
5330             tcg_gen_movi_tl(cpu_gpr[31],
5331                             ctx->base.pc_next + insn_bytes);
5332             ctx->hflags |= MIPS_HFLAG_B;
5333             break;
5334         case OPC_BNE:     /* rx != rx        */
5335             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
5336             /* Skip the instruction in the delay slot */
5337             ctx->base.pc_next += 4;
5338             goto out;
5339         case OPC_JR:
5340             ctx->hflags |= MIPS_HFLAG_BR;
5341             break;
5342         case OPC_JALR:
5343             if (rt > 0) {
5344                 tcg_gen_movi_tl(cpu_gpr[rt],
5345                                 ctx->base.pc_next + insn_bytes);
5346             }
5347             ctx->hflags |= MIPS_HFLAG_BR;
5348             break;
5349         default:
5350             MIPS_INVAL("branch/jump");
5351             generate_exception_end(ctx, EXCP_RI);
5352             goto out;
5353         }
5354     } else {
5355         switch (opc) {
5356         case OPC_BEQ:
5357             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5358             goto not_likely;
5359         case OPC_BNE:
5360             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5361             goto not_likely;
5362         case OPC_BGEZAL:
5363             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5364             tcg_gen_movi_tl(cpu_gpr[31],
5365                             ctx->base.pc_next + insn_bytes);
5366             goto not_likely;
5367         case OPC_BPOSGE32:
5368             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
5369         not_likely:
5370             ctx->hflags |= MIPS_HFLAG_BC;
5371             break;
5372         default:
5373             MIPS_INVAL("conditional branch/jump");
5374             generate_exception_end(ctx, EXCP_RI);
5375             goto out;
5376         }
5377     }
5378
5379     ctx->btarget = btgt;
5380
5381  out:
5382     if (insn_bytes == 2) {
5383         ctx->hflags |= MIPS_HFLAG_B16;
5384     }
5385     tcg_temp_free(t0);
5386     tcg_temp_free(t1);
5387 }
5388
5389
5390 /* special3 bitfield operations */
5391 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
5392                         int rs, int lsb, int msb)
5393 {
5394     TCGv t0 = tcg_temp_new();
5395     TCGv t1 = tcg_temp_new();
5396
5397     gen_load_gpr(t1, rs);
5398     switch (opc) {
5399     case OPC_EXT:
5400         if (lsb + msb > 31) {
5401             goto fail;
5402         }
5403         if (msb != 31) {
5404             tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
5405         } else {
5406             /* The two checks together imply that lsb == 0,
5407                so this is a simple sign-extension.  */
5408             tcg_gen_ext32s_tl(t0, t1);
5409         }
5410         break;
5411 #if defined(TARGET_MIPS64)
5412     case OPC_DEXTU:
5413         lsb += 32;
5414         goto do_dext;
5415     case OPC_DEXTM:
5416         msb += 32;
5417         goto do_dext;
5418     case OPC_DEXT:
5419     do_dext:
5420         if (lsb + msb > 63) {
5421             goto fail;
5422         }
5423         tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
5424         break;
5425 #endif
5426     case OPC_INS:
5427         if (lsb > msb) {
5428             goto fail;
5429         }
5430         gen_load_gpr(t0, rt);
5431         tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
5432         tcg_gen_ext32s_tl(t0, t0);
5433         break;
5434 #if defined(TARGET_MIPS64)
5435     case OPC_DINSU:
5436         lsb += 32;
5437         /* FALLTHRU */
5438     case OPC_DINSM:
5439         msb += 32;
5440         /* FALLTHRU */
5441     case OPC_DINS:
5442         if (lsb > msb) {
5443             goto fail;
5444         }
5445         gen_load_gpr(t0, rt);
5446         tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
5447         break;
5448 #endif
5449     default:
5450 fail:
5451         MIPS_INVAL("bitops");
5452         generate_exception_end(ctx, EXCP_RI);
5453         tcg_temp_free(t0);
5454         tcg_temp_free(t1);
5455         return;
5456     }
5457     gen_store_gpr(t0, rt);
5458     tcg_temp_free(t0);
5459     tcg_temp_free(t1);
5460 }
5461
5462 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
5463 {
5464     TCGv t0;
5465
5466     if (rd == 0) {
5467         /* If no destination, treat it as a NOP. */
5468         return;
5469     }
5470
5471     t0 = tcg_temp_new();
5472     gen_load_gpr(t0, rt);
5473     switch (op2) {
5474     case OPC_WSBH:
5475         {
5476             TCGv t1 = tcg_temp_new();
5477             TCGv t2 = tcg_const_tl(0x00FF00FF);
5478
5479             tcg_gen_shri_tl(t1, t0, 8);
5480             tcg_gen_and_tl(t1, t1, t2);
5481             tcg_gen_and_tl(t0, t0, t2);
5482             tcg_gen_shli_tl(t0, t0, 8);
5483             tcg_gen_or_tl(t0, t0, t1);
5484             tcg_temp_free(t2);
5485             tcg_temp_free(t1);
5486             tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
5487         }
5488         break;
5489     case OPC_SEB:
5490         tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
5491         break;
5492     case OPC_SEH:
5493         tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
5494         break;
5495 #if defined(TARGET_MIPS64)
5496     case OPC_DSBH:
5497         {
5498             TCGv t1 = tcg_temp_new();
5499             TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
5500
5501             tcg_gen_shri_tl(t1, t0, 8);
5502             tcg_gen_and_tl(t1, t1, t2);
5503             tcg_gen_and_tl(t0, t0, t2);
5504             tcg_gen_shli_tl(t0, t0, 8);
5505             tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
5506             tcg_temp_free(t2);
5507             tcg_temp_free(t1);
5508         }
5509         break;
5510     case OPC_DSHD:
5511         {
5512             TCGv t1 = tcg_temp_new();
5513             TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
5514
5515             tcg_gen_shri_tl(t1, t0, 16);
5516             tcg_gen_and_tl(t1, t1, t2);
5517             tcg_gen_and_tl(t0, t0, t2);
5518             tcg_gen_shli_tl(t0, t0, 16);
5519             tcg_gen_or_tl(t0, t0, t1);
5520             tcg_gen_shri_tl(t1, t0, 32);
5521             tcg_gen_shli_tl(t0, t0, 32);
5522             tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
5523             tcg_temp_free(t2);
5524             tcg_temp_free(t1);
5525         }
5526         break;
5527 #endif
5528     default:
5529         MIPS_INVAL("bsfhl");
5530         generate_exception_end(ctx, EXCP_RI);
5531         tcg_temp_free(t0);
5532         return;
5533     }
5534     tcg_temp_free(t0);
5535 }
5536
5537 static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
5538                     int imm2)
5539 {
5540     TCGv t0;
5541     TCGv t1;
5542     if (rd == 0) {
5543         /* Treat as NOP. */
5544         return;
5545     }
5546     t0 = tcg_temp_new();
5547     t1 = tcg_temp_new();
5548     gen_load_gpr(t0, rs);
5549     gen_load_gpr(t1, rt);
5550     tcg_gen_shli_tl(t0, t0, imm2 + 1);
5551     tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
5552     if (opc == OPC_LSA) {
5553         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5554     }
5555
5556     tcg_temp_free(t1);
5557     tcg_temp_free(t0);
5558
5559     return;
5560 }
5561
5562 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
5563                            int rt, int bits)
5564 {
5565     TCGv t0;
5566     if (rd == 0) {
5567         /* Treat as NOP. */
5568         return;
5569     }
5570     t0 = tcg_temp_new();
5571     if (bits == 0 || bits == wordsz) {
5572         if (bits == 0) {
5573             gen_load_gpr(t0, rt);
5574         } else {
5575             gen_load_gpr(t0, rs);
5576         }
5577         switch (wordsz) {
5578         case 32:
5579             tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
5580             break;
5581 #if defined(TARGET_MIPS64)
5582         case 64:
5583             tcg_gen_mov_tl(cpu_gpr[rd], t0);
5584             break;
5585 #endif
5586         }
5587     } else {
5588         TCGv t1 = tcg_temp_new();
5589         gen_load_gpr(t0, rt);
5590         gen_load_gpr(t1, rs);
5591         switch (wordsz) {
5592         case 32:
5593             {
5594                 TCGv_i64 t2 = tcg_temp_new_i64();
5595                 tcg_gen_concat_tl_i64(t2, t1, t0);
5596                 tcg_gen_shri_i64(t2, t2, 32 - bits);
5597                 gen_move_low32(cpu_gpr[rd], t2);
5598                 tcg_temp_free_i64(t2);
5599             }
5600             break;
5601 #if defined(TARGET_MIPS64)
5602         case 64:
5603             tcg_gen_shli_tl(t0, t0, bits);
5604             tcg_gen_shri_tl(t1, t1, 64 - bits);
5605             tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
5606             break;
5607 #endif
5608         }
5609         tcg_temp_free(t1);
5610     }
5611
5612     tcg_temp_free(t0);
5613 }
5614
5615 static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
5616                       int bp)
5617 {
5618     gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
5619 }
5620
5621 static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
5622                     int shift)
5623 {
5624     gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift);
5625 }
5626
5627 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
5628 {
5629     TCGv t0;
5630     if (rd == 0) {
5631         /* Treat as NOP. */
5632         return;
5633     }
5634     t0 = tcg_temp_new();
5635     gen_load_gpr(t0, rt);
5636     switch (opc) {
5637     case OPC_BITSWAP:
5638         gen_helper_bitswap(cpu_gpr[rd], t0);
5639         break;
5640 #if defined(TARGET_MIPS64)
5641     case OPC_DBITSWAP:
5642         gen_helper_dbitswap(cpu_gpr[rd], t0);
5643         break;
5644 #endif
5645     }
5646     tcg_temp_free(t0);
5647 }
5648
5649 #ifndef CONFIG_USER_ONLY
5650 /* CP0 (MMU and control) */
5651 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
5652 {
5653     TCGv_i64 t0 = tcg_temp_new_i64();
5654     TCGv_i64 t1 = tcg_temp_new_i64();
5655
5656     tcg_gen_ext_tl_i64(t0, arg);
5657     tcg_gen_ld_i64(t1, cpu_env, off);
5658 #if defined(TARGET_MIPS64)
5659     tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
5660 #else
5661     tcg_gen_concat32_i64(t1, t1, t0);
5662 #endif
5663     tcg_gen_st_i64(t1, cpu_env, off);
5664     tcg_temp_free_i64(t1);
5665     tcg_temp_free_i64(t0);
5666 }
5667
5668 static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
5669 {
5670     TCGv_i64 t0 = tcg_temp_new_i64();
5671     TCGv_i64 t1 = tcg_temp_new_i64();
5672
5673     tcg_gen_ext_tl_i64(t0, arg);
5674     tcg_gen_ld_i64(t1, cpu_env, off);
5675     tcg_gen_concat32_i64(t1, t1, t0);
5676     tcg_gen_st_i64(t1, cpu_env, off);
5677     tcg_temp_free_i64(t1);
5678     tcg_temp_free_i64(t0);
5679 }
5680
5681 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
5682 {
5683     TCGv_i64 t0 = tcg_temp_new_i64();
5684
5685     tcg_gen_ld_i64(t0, cpu_env, off);
5686 #if defined(TARGET_MIPS64)
5687     tcg_gen_shri_i64(t0, t0, 30);
5688 #else
5689     tcg_gen_shri_i64(t0, t0, 32);
5690 #endif
5691     gen_move_low32(arg, t0);
5692     tcg_temp_free_i64(t0);
5693 }
5694
5695 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
5696 {
5697     TCGv_i64 t0 = tcg_temp_new_i64();
5698
5699     tcg_gen_ld_i64(t0, cpu_env, off);
5700     tcg_gen_shri_i64(t0, t0, 32 + shift);
5701     gen_move_low32(arg, t0);
5702     tcg_temp_free_i64(t0);
5703 }
5704
5705 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
5706 {
5707     TCGv_i32 t0 = tcg_temp_new_i32();
5708
5709     tcg_gen_ld_i32(t0, cpu_env, off);
5710     tcg_gen_ext_i32_tl(arg, t0);
5711     tcg_temp_free_i32(t0);
5712 }
5713
5714 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
5715 {
5716     tcg_gen_ld_tl(arg, cpu_env, off);
5717     tcg_gen_ext32s_tl(arg, arg);
5718 }
5719
5720 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
5721 {
5722     TCGv_i32 t0 = tcg_temp_new_i32();
5723
5724     tcg_gen_trunc_tl_i32(t0, arg);
5725     tcg_gen_st_i32(t0, cpu_env, off);
5726     tcg_temp_free_i32(t0);
5727 }
5728
5729 #define CP0_CHECK(c)                            \
5730     do {                                        \
5731         if (!(c)) {                             \
5732             goto cp0_unimplemented;             \
5733         }                                       \
5734     } while (0)
5735
5736 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5737 {
5738     const char *rn = "invalid";
5739
5740     switch (reg) {
5741     case 2:
5742         switch (sel) {
5743         case 0:
5744             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5745             gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5746             rn = "EntryLo0";
5747             break;
5748         default:
5749             goto cp0_unimplemented;
5750         }
5751         break;
5752     case 3:
5753         switch (sel) {
5754         case 0:
5755             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5756             gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5757             rn = "EntryLo1";
5758             break;
5759         default:
5760             goto cp0_unimplemented;
5761         }
5762         break;
5763     case 17:
5764         switch (sel) {
5765         case 0:
5766             gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
5767                              ctx->CP0_LLAddr_shift);
5768             rn = "LLAddr";
5769             break;
5770         case 1:
5771             CP0_CHECK(ctx->mrp);
5772             gen_helper_mfhc0_maar(arg, cpu_env);
5773             rn = "MAAR";
5774             break;
5775         default:
5776             goto cp0_unimplemented;
5777         }
5778         break;
5779     case 28:
5780         switch (sel) {
5781         case 0:
5782         case 2:
5783         case 4:
5784         case 6:
5785             gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
5786             rn = "TagLo";
5787             break;
5788         default:
5789             goto cp0_unimplemented;
5790         }
5791         break;
5792     default:
5793         goto cp0_unimplemented;
5794     }
5795     trace_mips_translate_c0("mfhc0", rn, reg, sel);
5796     return;
5797
5798 cp0_unimplemented:
5799     qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
5800     tcg_gen_movi_tl(arg, 0);
5801 }
5802
5803 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5804 {
5805     const char *rn = "invalid";
5806     uint64_t mask = ctx->PAMask >> 36;
5807
5808     switch (reg) {
5809     case 2:
5810         switch (sel) {
5811         case 0:
5812             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5813             tcg_gen_andi_tl(arg, arg, mask);
5814             gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5815             rn = "EntryLo0";
5816             break;
5817         default:
5818             goto cp0_unimplemented;
5819         }
5820         break;
5821     case 3:
5822         switch (sel) {
5823         case 0:
5824             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5825             tcg_gen_andi_tl(arg, arg, mask);
5826             gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5827             rn = "EntryLo1";
5828             break;
5829         default:
5830             goto cp0_unimplemented;
5831         }
5832         break;
5833     case 17:
5834         switch (sel) {
5835         case 0:
5836             /* LLAddr is read-only (the only exception is bit 0 if LLB is
5837                supported); the CP0_LLAddr_rw_bitmask does not seem to be
5838                relevant for modern MIPS cores supporting MTHC0, therefore
5839                treating MTHC0 to LLAddr as NOP. */
5840             rn = "LLAddr";
5841             break;
5842         case 1:
5843             CP0_CHECK(ctx->mrp);
5844             gen_helper_mthc0_maar(cpu_env, arg);
5845             rn = "MAAR";
5846             break;
5847         default:
5848             goto cp0_unimplemented;
5849         }
5850         break;
5851     case 28:
5852         switch (sel) {
5853         case 0:
5854         case 2:
5855         case 4:
5856         case 6:
5857             tcg_gen_andi_tl(arg, arg, mask);
5858             gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
5859             rn = "TagLo";
5860             break;
5861         default:
5862             goto cp0_unimplemented;
5863         }
5864         break;
5865     default:
5866         goto cp0_unimplemented;
5867     }
5868     trace_mips_translate_c0("mthc0", rn, reg, sel);
5869
5870 cp0_unimplemented:
5871     qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
5872 }
5873
5874 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
5875 {
5876     if (ctx->insn_flags & ISA_MIPS32R6) {
5877         tcg_gen_movi_tl(arg, 0);
5878     } else {
5879         tcg_gen_movi_tl(arg, ~0);
5880     }
5881 }
5882
5883 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5884 {
5885     const char *rn = "invalid";
5886
5887     if (sel != 0)
5888         check_insn(ctx, ISA_MIPS32);
5889
5890     switch (reg) {
5891     case 0:
5892         switch (sel) {
5893         case 0:
5894             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5895             rn = "Index";
5896             break;
5897         case 1:
5898             CP0_CHECK(ctx->insn_flags & ASE_MT);
5899             gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5900             rn = "MVPControl";
5901             break;
5902         case 2:
5903             CP0_CHECK(ctx->insn_flags & ASE_MT);
5904             gen_helper_mfc0_mvpconf0(arg, cpu_env);
5905             rn = "MVPConf0";
5906             break;
5907         case 3:
5908             CP0_CHECK(ctx->insn_flags & ASE_MT);
5909             gen_helper_mfc0_mvpconf1(arg, cpu_env);
5910             rn = "MVPConf1";
5911             break;
5912         case 4:
5913             CP0_CHECK(ctx->vp);
5914             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
5915             rn = "VPControl";
5916             break;
5917         default:
5918             goto cp0_unimplemented;
5919         }
5920         break;
5921     case 1:
5922         switch (sel) {
5923         case 0:
5924             CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
5925             gen_helper_mfc0_random(arg, cpu_env);
5926             rn = "Random";
5927             break;
5928         case 1:
5929             CP0_CHECK(ctx->insn_flags & ASE_MT);
5930             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5931             rn = "VPEControl";
5932             break;
5933         case 2:
5934             CP0_CHECK(ctx->insn_flags & ASE_MT);
5935             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5936             rn = "VPEConf0";
5937             break;
5938         case 3:
5939             CP0_CHECK(ctx->insn_flags & ASE_MT);
5940             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5941             rn = "VPEConf1";
5942             break;
5943         case 4:
5944             CP0_CHECK(ctx->insn_flags & ASE_MT);
5945             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
5946             rn = "YQMask";
5947             break;
5948         case 5:
5949             CP0_CHECK(ctx->insn_flags & ASE_MT);
5950             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
5951             rn = "VPESchedule";
5952             break;
5953         case 6:
5954             CP0_CHECK(ctx->insn_flags & ASE_MT);
5955             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5956             rn = "VPEScheFBack";
5957             break;
5958         case 7:
5959             CP0_CHECK(ctx->insn_flags & ASE_MT);
5960             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5961             rn = "VPEOpt";
5962             break;
5963         default:
5964             goto cp0_unimplemented;
5965         }
5966         break;
5967     case 2:
5968         switch (sel) {
5969         case 0:
5970             {
5971                 TCGv_i64 tmp = tcg_temp_new_i64();
5972                 tcg_gen_ld_i64(tmp, cpu_env,
5973                                offsetof(CPUMIPSState, CP0_EntryLo0));
5974 #if defined(TARGET_MIPS64)
5975                 if (ctx->rxi) {
5976                     /* Move RI/XI fields to bits 31:30 */
5977                     tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5978                     tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5979                 }
5980 #endif
5981                 gen_move_low32(arg, tmp);
5982                 tcg_temp_free_i64(tmp);
5983             }
5984             rn = "EntryLo0";
5985             break;
5986         case 1:
5987             CP0_CHECK(ctx->insn_flags & ASE_MT);
5988             gen_helper_mfc0_tcstatus(arg, cpu_env);
5989             rn = "TCStatus";
5990             break;
5991         case 2:
5992             CP0_CHECK(ctx->insn_flags & ASE_MT);
5993             gen_helper_mfc0_tcbind(arg, cpu_env);
5994             rn = "TCBind";
5995             break;
5996         case 3:
5997             CP0_CHECK(ctx->insn_flags & ASE_MT);
5998             gen_helper_mfc0_tcrestart(arg, cpu_env);
5999             rn = "TCRestart";
6000             break;
6001         case 4:
6002             CP0_CHECK(ctx->insn_flags & ASE_MT);
6003             gen_helper_mfc0_tchalt(arg, cpu_env);
6004             rn = "TCHalt";
6005             break;
6006         case 5:
6007             CP0_CHECK(ctx->insn_flags & ASE_MT);
6008             gen_helper_mfc0_tccontext(arg, cpu_env);
6009             rn = "TCContext";
6010             break;
6011         case 6:
6012             CP0_CHECK(ctx->insn_flags & ASE_MT);
6013             gen_helper_mfc0_tcschedule(arg, cpu_env);
6014             rn = "TCSchedule";
6015             break;
6016         case 7:
6017             CP0_CHECK(ctx->insn_flags & ASE_MT);
6018             gen_helper_mfc0_tcschefback(arg, cpu_env);
6019             rn = "TCScheFBack";
6020             break;
6021         default:
6022             goto cp0_unimplemented;
6023         }
6024         break;
6025     case 3:
6026         switch (sel) {
6027         case 0:
6028             {
6029                 TCGv_i64 tmp = tcg_temp_new_i64();
6030                 tcg_gen_ld_i64(tmp, cpu_env,
6031                                offsetof(CPUMIPSState, CP0_EntryLo1));
6032 #if defined(TARGET_MIPS64)
6033                 if (ctx->rxi) {
6034                     /* Move RI/XI fields to bits 31:30 */
6035                     tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6036                     tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6037                 }
6038 #endif
6039                 gen_move_low32(arg, tmp);
6040                 tcg_temp_free_i64(tmp);
6041             }
6042             rn = "EntryLo1";
6043             break;
6044         case 1:
6045             CP0_CHECK(ctx->vp);
6046             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6047             rn = "GlobalNumber";
6048             break;
6049         default:
6050             goto cp0_unimplemented;
6051         }
6052         break;
6053     case 4:
6054         switch (sel) {
6055         case 0:
6056             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
6057             tcg_gen_ext32s_tl(arg, arg);
6058             rn = "Context";
6059             break;
6060         case 1:
6061 //            gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
6062             rn = "ContextConfig";
6063             goto cp0_unimplemented;
6064         case 2:
6065             CP0_CHECK(ctx->ulri);
6066             tcg_gen_ld_tl(arg, cpu_env,
6067                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6068             tcg_gen_ext32s_tl(arg, arg);
6069             rn = "UserLocal";
6070             break;
6071         default:
6072             goto cp0_unimplemented;
6073         }
6074         break;
6075     case 5:
6076         switch (sel) {
6077         case 0:
6078             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
6079             rn = "PageMask";
6080             break;
6081         case 1:
6082             check_insn(ctx, ISA_MIPS32R2);
6083             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
6084             rn = "PageGrain";
6085             break;
6086         case 2:
6087             CP0_CHECK(ctx->sc);
6088             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
6089             tcg_gen_ext32s_tl(arg, arg);
6090             rn = "SegCtl0";
6091             break;
6092         case 3:
6093             CP0_CHECK(ctx->sc);
6094             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
6095             tcg_gen_ext32s_tl(arg, arg);
6096             rn = "SegCtl1";
6097             break;
6098         case 4:
6099             CP0_CHECK(ctx->sc);
6100             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
6101             tcg_gen_ext32s_tl(arg, arg);
6102             rn = "SegCtl2";
6103             break;
6104         case 5:
6105             check_pw(ctx);
6106             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6107             rn = "PWBase";
6108             break;
6109         case 6:
6110             check_pw(ctx);
6111             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
6112             rn = "PWField";
6113             break;
6114         case 7:
6115             check_pw(ctx);
6116             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
6117             rn = "PWSize";
6118             break;
6119         default:
6120             goto cp0_unimplemented;
6121         }
6122         break;
6123     case 6:
6124         switch (sel) {
6125         case 0:
6126             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
6127             rn = "Wired";
6128             break;
6129         case 1:
6130             check_insn(ctx, ISA_MIPS32R2);
6131             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
6132             rn = "SRSConf0";
6133             break;
6134         case 2:
6135             check_insn(ctx, ISA_MIPS32R2);
6136             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
6137             rn = "SRSConf1";
6138             break;
6139         case 3:
6140             check_insn(ctx, ISA_MIPS32R2);
6141             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
6142             rn = "SRSConf2";
6143             break;
6144         case 4:
6145             check_insn(ctx, ISA_MIPS32R2);
6146             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
6147             rn = "SRSConf3";
6148             break;
6149         case 5:
6150             check_insn(ctx, ISA_MIPS32R2);
6151             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
6152             rn = "SRSConf4";
6153             break;
6154         case 6:
6155             check_pw(ctx);
6156             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
6157             rn = "PWCtl";
6158             break;
6159         default:
6160             goto cp0_unimplemented;
6161         }
6162         break;
6163     case 7:
6164         switch (sel) {
6165         case 0:
6166             check_insn(ctx, ISA_MIPS32R2);
6167             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
6168             rn = "HWREna";
6169             break;
6170         default:
6171             goto cp0_unimplemented;
6172         }
6173         break;
6174     case 8:
6175         switch (sel) {
6176         case 0:
6177             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
6178             tcg_gen_ext32s_tl(arg, arg);
6179             rn = "BadVAddr";
6180             break;
6181         case 1:
6182             CP0_CHECK(ctx->bi);
6183             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6184             rn = "BadInstr";
6185             break;
6186         case 2:
6187             CP0_CHECK(ctx->bp);
6188             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6189             rn = "BadInstrP";
6190             break;
6191         case 3:
6192             CP0_CHECK(ctx->bi);
6193             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
6194             tcg_gen_andi_tl(arg, arg, ~0xffff);
6195             rn = "BadInstrX";
6196             break;
6197        default:
6198             goto cp0_unimplemented;
6199         }
6200         break;
6201     case 9:
6202         switch (sel) {
6203         case 0:
6204             /* Mark as an IO operation because we read the time.  */
6205             if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
6206                 gen_io_start();
6207             }
6208             gen_helper_mfc0_count(arg, cpu_env);
6209             if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
6210                 gen_io_end();
6211             }
6212             /* Break the TB to be able to take timer interrupts immediately
6213                after reading count. DISAS_STOP isn't sufficient, we need to
6214                ensure we break completely out of translated code.  */
6215             gen_save_pc(ctx->base.pc_next + 4);
6216             ctx->base.is_jmp = DISAS_EXIT;
6217             rn = "Count";
6218             break;
6219         /* 6,7 are implementation dependent */
6220         default:
6221             goto cp0_unimplemented;
6222         }
6223         break;
6224     case 10:
6225         switch (sel) {
6226         case 0:
6227             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
6228             tcg_gen_ext32s_tl(arg, arg);
6229             rn = "EntryHi";
6230             break;
6231         default:
6232             goto cp0_unimplemented;
6233         }
6234         break;
6235     case 11:
6236         switch (sel) {
6237         case 0:
6238             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
6239             rn = "Compare";
6240             break;
6241         /* 6,7 are implementation dependent */
6242         default:
6243             goto cp0_unimplemented;
6244         }
6245         break;
6246     case 12:
6247         switch (sel) {
6248         case 0:
6249             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
6250             rn = "Status";
6251             break;
6252         case 1:
6253             check_insn(ctx, ISA_MIPS32R2);
6254             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
6255             rn = "IntCtl";
6256             break;
6257         case 2:
6258             check_insn(ctx, ISA_MIPS32R2);
6259             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
6260             rn = "SRSCtl";
6261             break;
6262         case 3:
6263             check_insn(ctx, ISA_MIPS32R2);
6264             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6265             rn = "SRSMap";
6266             break;
6267         default:
6268             goto cp0_unimplemented;
6269        }
6270         break;
6271     case 13:
6272         switch (sel) {
6273         case 0:
6274             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
6275             rn = "Cause";
6276             break;
6277         default:
6278             goto cp0_unimplemented;
6279        }
6280         break;
6281     case 14:
6282         switch (sel) {
6283         case 0:
6284             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6285             tcg_gen_ext32s_tl(arg, arg);
6286             rn = "EPC";
6287             break;
6288         default:
6289             goto cp0_unimplemented;
6290         }
6291         break;
6292     case 15:
6293         switch (sel) {
6294         case 0:
6295             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
6296             rn = "PRid";
6297             break;
6298         case 1:
6299             check_insn(ctx, ISA_MIPS32R2);
6300             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
6301             tcg_gen_ext32s_tl(arg, arg);
6302             rn = "EBase";
6303             break;
6304         case 3:
6305             check_insn(ctx, ISA_MIPS32R2);
6306             CP0_CHECK(ctx->cmgcr);
6307             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6308             tcg_gen_ext32s_tl(arg, arg);
6309             rn = "CMGCRBase";
6310             break;
6311         default:
6312             goto cp0_unimplemented;
6313        }
6314         break;
6315     case 16:
6316         switch (sel) {
6317         case 0:
6318             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
6319             rn = "Config";
6320             break;
6321         case 1:
6322             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
6323             rn = "Config1";
6324             break;
6325         case 2:
6326             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
6327             rn = "Config2";
6328             break;
6329         case 3:
6330             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
6331             rn = "Config3";
6332             break;
6333         case 4:
6334             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6335             rn = "Config4";
6336             break;
6337         case 5:
6338             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6339             rn = "Config5";
6340             break;
6341         /* 6,7 are implementation dependent */
6342         case 6:
6343             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
6344             rn = "Config6";
6345             break;
6346         case 7:
6347             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
6348             rn = "Config7";
6349             break;
6350         default:
6351             goto cp0_unimplemented;
6352         }
6353         break;
6354     case 17:
6355         switch (sel) {
6356         case 0:
6357             gen_helper_mfc0_lladdr(arg, cpu_env);
6358             rn = "LLAddr";
6359             break;
6360         case 1:
6361             CP0_CHECK(ctx->mrp);
6362             gen_helper_mfc0_maar(arg, cpu_env);
6363             rn = "MAAR";
6364             break;
6365         case 2:
6366             CP0_CHECK(ctx->mrp);
6367             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
6368             rn = "MAARI";
6369             break;
6370         default:
6371             goto cp0_unimplemented;
6372         }
6373         break;
6374     case 18:
6375         switch (sel) {
6376         case 0:
6377         case 1:
6378         case 2:
6379         case 3:
6380         case 4:
6381         case 5:
6382         case 6:
6383         case 7:
6384             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6385             gen_helper_1e0i(mfc0_watchlo, arg, sel);
6386             rn = "WatchLo";
6387             break;
6388         default:
6389             goto cp0_unimplemented;
6390         }
6391         break;
6392     case 19:
6393         switch (sel) {
6394         case 0:
6395         case 1:
6396         case 2:
6397         case 3:
6398         case 4:
6399         case 5:
6400         case 6:
6401         case 7:
6402             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6403             gen_helper_1e0i(mfc0_watchhi, arg, sel);
6404             rn = "WatchHi";
6405             break;
6406         default:
6407             goto cp0_unimplemented;
6408         }
6409         break;
6410     case 20:
6411         switch (sel) {
6412         case 0:
6413 #if defined(TARGET_MIPS64)
6414             check_insn(ctx, ISA_MIPS3);
6415             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
6416             tcg_gen_ext32s_tl(arg, arg);
6417             rn = "XContext";
6418             break;
6419 #endif
6420         default:
6421             goto cp0_unimplemented;
6422         }
6423         break;
6424     case 21:
6425        /* Officially reserved, but sel 0 is used for R1x000 framemask */
6426         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6427         switch (sel) {
6428         case 0:
6429             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
6430             rn = "Framemask";
6431             break;
6432         default:
6433             goto cp0_unimplemented;
6434         }
6435         break;
6436     case 22:
6437         tcg_gen_movi_tl(arg, 0); /* unimplemented */
6438         rn = "'Diagnostic"; /* implementation dependent */
6439         break;
6440     case 23:
6441         switch (sel) {
6442         case 0:
6443             gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
6444             rn = "Debug";
6445             break;
6446         case 1:
6447 //            gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
6448             rn = "TraceControl";
6449             goto cp0_unimplemented;
6450         case 2:
6451 //            gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
6452             rn = "TraceControl2";
6453             goto cp0_unimplemented;
6454         case 3:
6455 //            gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
6456             rn = "UserTraceData";
6457             goto cp0_unimplemented;
6458         case 4:
6459 //            gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
6460             rn = "TraceBPC";
6461             goto cp0_unimplemented;
6462         default:
6463             goto cp0_unimplemented;
6464         }
6465         break;
6466     case 24:
6467         switch (sel) {
6468         case 0:
6469             /* EJTAG support */
6470             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6471             tcg_gen_ext32s_tl(arg, arg);
6472             rn = "DEPC";
6473             break;
6474         default:
6475             goto cp0_unimplemented;
6476         }
6477         break;
6478     case 25:
6479         switch (sel) {
6480         case 0:
6481             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
6482             rn = "Performance0";
6483             break;
6484         case 1:
6485 //            gen_helper_mfc0_performance1(arg);
6486             rn = "Performance1";
6487             goto cp0_unimplemented;
6488         case 2:
6489 //            gen_helper_mfc0_performance2(arg);
6490             rn = "Performance2";
6491             goto cp0_unimplemented;
6492         case 3:
6493 //            gen_helper_mfc0_performance3(arg);
6494             rn = "Performance3";
6495             goto cp0_unimplemented;
6496         case 4:
6497 //            gen_helper_mfc0_performance4(arg);
6498             rn = "Performance4";
6499             goto cp0_unimplemented;
6500         case 5:
6501 //            gen_helper_mfc0_performance5(arg);
6502             rn = "Performance5";
6503             goto cp0_unimplemented;
6504         case 6:
6505 //            gen_helper_mfc0_performance6(arg);
6506             rn = "Performance6";
6507             goto cp0_unimplemented;
6508         case 7:
6509 //            gen_helper_mfc0_performance7(arg);
6510             rn = "Performance7";
6511             goto cp0_unimplemented;
6512         default:
6513             goto cp0_unimplemented;
6514         }
6515         break;
6516     case 26:
6517         switch (sel) {
6518         case 0:
6519             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
6520             rn = "ErrCtl";
6521             break;
6522         default:
6523             goto cp0_unimplemented;
6524         }
6525         break;
6526     case 27:
6527         switch (sel) {
6528         case 0:
6529         case 1:
6530         case 2:
6531         case 3:
6532             tcg_gen_movi_tl(arg, 0); /* unimplemented */
6533             rn = "CacheErr";
6534             break;
6535         default:
6536             goto cp0_unimplemented;
6537         }
6538         break;
6539     case 28:
6540         switch (sel) {
6541         case 0:
6542         case 2:
6543         case 4:
6544         case 6:
6545             {
6546                 TCGv_i64 tmp = tcg_temp_new_i64();
6547                 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
6548                 gen_move_low32(arg, tmp);
6549                 tcg_temp_free_i64(tmp);
6550             }
6551             rn = "TagLo";
6552             break;
6553         case 1:
6554         case 3:
6555         case 5:
6556         case 7:
6557             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
6558             rn = "DataLo";
6559             break;
6560         default:
6561             goto cp0_unimplemented;
6562         }
6563         break;
6564     case 29:
6565         switch (sel) {
6566         case 0:
6567         case 2:
6568         case 4:
6569         case 6:
6570             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
6571             rn = "TagHi";
6572             break;
6573         case 1:
6574         case 3:
6575         case 5:
6576         case 7:
6577             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
6578             rn = "DataHi";
6579             break;
6580         default:
6581             goto cp0_unimplemented;
6582         }
6583         break;
6584     case 30:
6585         switch (sel) {
6586         case 0:
6587             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6588             tcg_gen_ext32s_tl(arg, arg);
6589             rn = "ErrorEPC";
6590             break;
6591         default:
6592             goto cp0_unimplemented;
6593         }
6594         break;
6595     case 31:
6596         switch (sel) {
6597         case 0:
6598             /* EJTAG support */
6599             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6600             rn = "DESAVE";
6601             break;
6602         case 2:
6603         case 3:
6604         case 4:
6605         case 5:
6606         case 6:
6607         case 7:
6608             CP0_CHECK(ctx->kscrexist & (1 << sel));
6609             tcg_gen_ld_tl(arg, cpu_env,
6610                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6611             tcg_gen_ext32s_tl(arg, arg);
6612             rn = "KScratch";
6613             break;
6614         default:
6615             goto cp0_unimplemented;
6616         }
6617         break;
6618     default:
6619        goto cp0_unimplemented;
6620     }
6621     trace_mips_translate_c0("mfc0", rn, reg, sel);
6622     return;
6623
6624 cp0_unimplemented:
6625     qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
6626     gen_mfc0_unimplemented(ctx, arg);
6627 }
6628
6629 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6630 {
6631     const char *rn = "invalid";
6632
6633     if (sel != 0)
6634         check_insn(ctx, ISA_MIPS32);
6635
6636     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
6637         gen_io_start();
6638     }
6639
6640     switch (reg) {
6641     case 0:
6642         switch (sel) {
6643         case 0:
6644             gen_helper_mtc0_index(cpu_env, arg);
6645             rn = "Index";
6646             break;
6647         case 1:
6648             CP0_CHECK(ctx->insn_flags & ASE_MT);
6649             gen_helper_mtc0_mvpcontrol(cpu_env, arg);
6650             rn = "MVPControl";
6651             break;
6652         case 2:
6653             CP0_CHECK(ctx->insn_flags & ASE_MT);
6654             /* ignored */
6655             rn = "MVPConf0";
6656             break;
6657         case 3:
6658             CP0_CHECK(ctx->insn_flags & ASE_MT);
6659             /* ignored */
6660             rn = "MVPConf1";
6661             break;
6662         case 4:
6663             CP0_CHECK(ctx->vp);
6664             /* ignored */
6665             rn = "VPControl";
6666             break;
6667         default:
6668             goto cp0_unimplemented;
6669         }
6670         break;
6671     case 1:
6672         switch (sel) {
6673         case 0:
6674             /* ignored */
6675             rn = "Random";
6676             break;
6677         case 1:
6678             CP0_CHECK(ctx->insn_flags & ASE_MT);
6679             gen_helper_mtc0_vpecontrol(cpu_env, arg);
6680             rn = "VPEControl";
6681             break;
6682         case 2:
6683             CP0_CHECK(ctx->insn_flags & ASE_MT);
6684             gen_helper_mtc0_vpeconf0(cpu_env, arg);
6685             rn = "VPEConf0";
6686             break;
6687         case 3:
6688             CP0_CHECK(ctx->insn_flags & ASE_MT);
6689             gen_helper_mtc0_vpeconf1(cpu_env, arg);
6690             rn = "VPEConf1";
6691             break;
6692         case 4:
6693             CP0_CHECK(ctx->insn_flags & ASE_MT);
6694             gen_helper_mtc0_yqmask(cpu_env, arg);
6695             rn = "YQMask";
6696             break;
6697         case 5:
6698             CP0_CHECK(ctx->insn_flags & ASE_MT);
6699             tcg_gen_st_tl(arg, cpu_env,
6700                           offsetof(CPUMIPSState, CP0_VPESchedule));
6701             rn = "VPESchedule";
6702             break;
6703         case 6:
6704             CP0_CHECK(ctx->insn_flags & ASE_MT);
6705             tcg_gen_st_tl(arg, cpu_env,
6706                           offsetof(CPUMIPSState, CP0_VPEScheFBack));
6707             rn = "VPEScheFBack";
6708             break;
6709         case 7:
6710             CP0_CHECK(ctx->insn_flags & ASE_MT);
6711             gen_helper_mtc0_vpeopt(cpu_env, arg);
6712             rn = "VPEOpt";
6713             break;
6714         default:
6715             goto cp0_unimplemented;
6716         }
6717         break;
6718     case 2:
6719         switch (sel) {
6720         case 0:
6721             gen_helper_mtc0_entrylo0(cpu_env, arg);
6722             rn = "EntryLo0";
6723             break;
6724         case 1:
6725             CP0_CHECK(ctx->insn_flags & ASE_MT);
6726             gen_helper_mtc0_tcstatus(cpu_env, arg);
6727             rn = "TCStatus";
6728             break;
6729         case 2:
6730             CP0_CHECK(ctx->insn_flags & ASE_MT);
6731             gen_helper_mtc0_tcbind(cpu_env, arg);
6732             rn = "TCBind";
6733             break;
6734         case 3:
6735             CP0_CHECK(ctx->insn_flags & ASE_MT);
6736             gen_helper_mtc0_tcrestart(cpu_env, arg);
6737             rn = "TCRestart";
6738             break;
6739         case 4:
6740             CP0_CHECK(ctx->insn_flags & ASE_MT);
6741             gen_helper_mtc0_tchalt(cpu_env, arg);
6742             rn = "TCHalt";
6743             break;
6744         case 5:
6745             CP0_CHECK(ctx->insn_flags & ASE_MT);
6746             gen_helper_mtc0_tccontext(cpu_env, arg);
6747             rn = "TCContext";
6748             break;
6749         case 6:
6750             CP0_CHECK(ctx->insn_flags & ASE_MT);
6751             gen_helper_mtc0_tcschedule(cpu_env, arg);
6752             rn = "TCSchedule";
6753             break;
6754         case 7:
6755             CP0_CHECK(ctx->insn_flags & ASE_MT);
6756             gen_helper_mtc0_tcschefback(cpu_env, arg);
6757             rn = "TCScheFBack";
6758             break;
6759         default:
6760             goto cp0_unimplemented;
6761         }
6762         break;
6763     case 3:
6764         switch (sel) {
6765         case 0:
6766             gen_helper_mtc0_entrylo1(cpu_env, arg);
6767             rn = "EntryLo1";
6768             break;
6769         case 1:
6770             CP0_CHECK(ctx->vp);
6771             /* ignored */
6772             rn = "GlobalNumber";
6773             break;
6774         default:
6775             goto cp0_unimplemented;
6776         }
6777         break;
6778     case 4:
6779         switch (sel) {
6780         case 0:
6781             gen_helper_mtc0_context(cpu_env, arg);
6782             rn = "Context";
6783             break;
6784         case 1:
6785 //            gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
6786             rn = "ContextConfig";
6787             goto cp0_unimplemented;
6788         case 2:
6789             CP0_CHECK(ctx->ulri);
6790             tcg_gen_st_tl(arg, cpu_env,
6791                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6792             rn = "UserLocal";
6793             break;
6794         default:
6795             goto cp0_unimplemented;
6796         }
6797         break;
6798     case 5:
6799         switch (sel) {
6800         case 0:
6801             gen_helper_mtc0_pagemask(cpu_env, arg);
6802             rn = "PageMask";
6803             break;
6804         case 1:
6805             check_insn(ctx, ISA_MIPS32R2);
6806             gen_helper_mtc0_pagegrain(cpu_env, arg);
6807             rn = "PageGrain";
6808             ctx->base.is_jmp = DISAS_STOP;
6809             break;
6810         case 2:
6811             CP0_CHECK(ctx->sc);
6812             gen_helper_mtc0_segctl0(cpu_env, arg);
6813             rn = "SegCtl0";
6814             break;
6815         case 3:
6816             CP0_CHECK(ctx->sc);
6817             gen_helper_mtc0_segctl1(cpu_env, arg);
6818             rn = "SegCtl1";
6819             break;
6820         case 4:
6821             CP0_CHECK(ctx->sc);
6822             gen_helper_mtc0_segctl2(cpu_env, arg);
6823             rn = "SegCtl2";
6824             break;
6825         case 5:
6826             check_pw(ctx);
6827             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6828             rn = "PWBase";
6829             break;
6830         case 6:
6831             check_pw(ctx);
6832             gen_helper_mtc0_pwfield(cpu_env, arg);
6833             rn = "PWField";
6834             break;
6835         case 7:
6836             check_pw(ctx);
6837             gen_helper_mtc0_pwsize(cpu_env, arg);
6838             rn = "PWSize";
6839             break;
6840         default:
6841             goto cp0_unimplemented;
6842         }
6843         break;
6844     case 6:
6845         switch (sel) {
6846         case 0:
6847             gen_helper_mtc0_wired(cpu_env, arg);
6848             rn = "Wired";
6849             break;
6850         case 1:
6851             check_insn(ctx, ISA_MIPS32R2);
6852             gen_helper_mtc0_srsconf0(cpu_env, arg);
6853             rn = "SRSConf0";
6854             break;
6855         case 2:
6856             check_insn(ctx, ISA_MIPS32R2);
6857             gen_helper_mtc0_srsconf1(cpu_env, arg);
6858             rn = "SRSConf1";
6859             break;
6860         case 3:
6861             check_insn(ctx, ISA_MIPS32R2);
6862             gen_helper_mtc0_srsconf2(cpu_env, arg);
6863             rn = "SRSConf2";
6864             break;
6865         case 4:
6866             check_insn(ctx, ISA_MIPS32R2);
6867             gen_helper_mtc0_srsconf3(cpu_env, arg);
6868             rn = "SRSConf3";
6869             break;
6870         case 5:
6871             check_insn(ctx, ISA_MIPS32R2);
6872             gen_helper_mtc0_srsconf4(cpu_env, arg);
6873             rn = "SRSConf4";
6874             break;
6875         case 6:
6876             check_pw(ctx);
6877             gen_helper_mtc0_pwctl(cpu_env, arg);
6878             rn = "PWCtl";
6879             break;
6880         default:
6881             goto cp0_unimplemented;
6882         }
6883         break;
6884     case 7:
6885         switch (sel) {
6886         case 0:
6887             check_insn(ctx, ISA_MIPS32R2);
6888             gen_helper_mtc0_hwrena(cpu_env, arg);
6889             ctx->base.is_jmp = DISAS_STOP;
6890             rn = "HWREna";
6891             break;
6892         default:
6893             goto cp0_unimplemented;
6894         }
6895         break;
6896     case 8:
6897         switch (sel) {
6898         case 0:
6899             /* ignored */
6900             rn = "BadVAddr";
6901             break;
6902         case 1:
6903             /* ignored */
6904             rn = "BadInstr";
6905             break;
6906         case 2:
6907             /* ignored */
6908             rn = "BadInstrP";
6909             break;
6910         case 3:
6911             /* ignored */
6912             rn = "BadInstrX";
6913             break;
6914         default:
6915             goto cp0_unimplemented;
6916         }
6917         break;
6918     case 9:
6919         switch (sel) {
6920         case 0:
6921             gen_helper_mtc0_count(cpu_env, arg);
6922             rn = "Count";
6923             break;
6924         /* 6,7 are implementation dependent */
6925         default:
6926             goto cp0_unimplemented;
6927         }
6928         break;
6929     case 10:
6930         switch (sel) {
6931         case 0:
6932             gen_helper_mtc0_entryhi(cpu_env, arg);
6933             rn = "EntryHi";
6934             break;
6935         default:
6936             goto cp0_unimplemented;
6937         }
6938         break;
6939     case 11:
6940         switch (sel) {
6941         case 0:
6942             gen_helper_mtc0_compare(cpu_env, arg);
6943             rn = "Compare";
6944             break;
6945         /* 6,7 are implementation dependent */
6946         default:
6947             goto cp0_unimplemented;
6948         }
6949         break;
6950     case 12:
6951         switch (sel) {
6952         case 0:
6953             save_cpu_state(ctx, 1);
6954             gen_helper_mtc0_status(cpu_env, arg);
6955             /* DISAS_STOP isn't good enough here, hflags may have changed. */
6956             gen_save_pc(ctx->base.pc_next + 4);
6957             ctx->base.is_jmp = DISAS_EXIT;
6958             rn = "Status";
6959             break;
6960         case 1:
6961             check_insn(ctx, ISA_MIPS32R2);
6962             gen_helper_mtc0_intctl(cpu_env, arg);
6963             /* Stop translation as we may have switched the execution mode */
6964             ctx->base.is_jmp = DISAS_STOP;
6965             rn = "IntCtl";
6966             break;
6967         case 2:
6968             check_insn(ctx, ISA_MIPS32R2);
6969             gen_helper_mtc0_srsctl(cpu_env, arg);
6970             /* Stop translation as we may have switched the execution mode */
6971             ctx->base.is_jmp = DISAS_STOP;
6972             rn = "SRSCtl";
6973             break;
6974         case 3:
6975             check_insn(ctx, ISA_MIPS32R2);
6976             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6977             /* Stop translation as we may have switched the execution mode */
6978             ctx->base.is_jmp = DISAS_STOP;
6979             rn = "SRSMap";
6980             break;
6981         default:
6982             goto cp0_unimplemented;
6983         }
6984         break;
6985     case 13:
6986         switch (sel) {
6987         case 0:
6988             save_cpu_state(ctx, 1);
6989             gen_helper_mtc0_cause(cpu_env, arg);
6990             /* Stop translation as we may have triggered an interrupt.
6991              * DISAS_STOP isn't sufficient, we need to ensure we break out of
6992              * translated code to check for pending interrupts.  */
6993             gen_save_pc(ctx->base.pc_next + 4);
6994             ctx->base.is_jmp = DISAS_EXIT;
6995             rn = "Cause";
6996             break;
6997         default:
6998             goto cp0_unimplemented;
6999         }
7000         break;
7001     case 14:
7002         switch (sel) {
7003         case 0:
7004             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7005             rn = "EPC";
7006             break;
7007         default:
7008             goto cp0_unimplemented;
7009         }
7010         break;
7011     case 15:
7012         switch (sel) {
7013         case 0:
7014             /* ignored */
7015             rn = "PRid";
7016             break;
7017         case 1:
7018             check_insn(ctx, ISA_MIPS32R2);
7019             gen_helper_mtc0_ebase(cpu_env, arg);
7020             rn = "EBase";
7021             break;
7022         default:
7023             goto cp0_unimplemented;
7024         }
7025         break;
7026     case 16:
7027         switch (sel) {
7028         case 0:
7029             gen_helper_mtc0_config0(cpu_env, arg);
7030             rn = "Config";
7031             /* Stop translation as we may have switched the execution mode */
7032             ctx->base.is_jmp = DISAS_STOP;
7033             break;
7034         case 1:
7035             /* ignored, read only */
7036             rn = "Config1";
7037             break;
7038         case 2:
7039             gen_helper_mtc0_config2(cpu_env, arg);
7040             rn = "Config2";
7041             /* Stop translation as we may have switched the execution mode */
7042             ctx->base.is_jmp = DISAS_STOP;
7043             break;
7044         case 3:
7045             gen_helper_mtc0_config3(cpu_env, arg);
7046             rn = "Config3";
7047             /* Stop translation as we may have switched the execution mode */
7048             ctx->base.is_jmp = DISAS_STOP;
7049             break;
7050         case 4:
7051             gen_helper_mtc0_config4(cpu_env, arg);
7052             rn = "Config4";
7053             ctx->base.is_jmp = DISAS_STOP;
7054             break;
7055         case 5:
7056             gen_helper_mtc0_config5(cpu_env, arg);
7057             rn = "Config5";
7058             /* Stop translation as we may have switched the execution mode */
7059             ctx->base.is_jmp = DISAS_STOP;
7060             break;
7061         /* 6,7 are implementation dependent */
7062         case 6:
7063             /* ignored */
7064             rn = "Config6";
7065             break;
7066         case 7:
7067             /* ignored */
7068             rn = "Config7";
7069             break;
7070         default:
7071             rn = "Invalid config selector";
7072             goto cp0_unimplemented;
7073         }
7074         break;
7075     case 17:
7076         switch (sel) {
7077         case 0:
7078             gen_helper_mtc0_lladdr(cpu_env, arg);
7079             rn = "LLAddr";
7080             break;
7081         case 1:
7082             CP0_CHECK(ctx->mrp);
7083             gen_helper_mtc0_maar(cpu_env, arg);
7084             rn = "MAAR";
7085             break;
7086         case 2:
7087             CP0_CHECK(ctx->mrp);
7088             gen_helper_mtc0_maari(cpu_env, arg);
7089             rn = "MAARI";
7090             break;
7091         default:
7092             goto cp0_unimplemented;
7093         }
7094         break;
7095     case 18:
7096         switch (sel) {
7097         case 0:
7098         case 1:
7099         case 2:
7100         case 3:
7101         case 4:
7102         case 5:
7103         case 6:
7104         case 7:
7105             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7106             gen_helper_0e1i(mtc0_watchlo, arg, sel);
7107             rn = "WatchLo";
7108             break;
7109         default:
7110             goto cp0_unimplemented;
7111         }
7112         break;
7113     case 19:
7114         switch (sel) {
7115         case 0:
7116         case 1:
7117         case 2:
7118         case 3:
7119         case 4:
7120         case 5:
7121         case 6:
7122         case 7:
7123             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7124             gen_helper_0e1i(mtc0_watchhi, arg, sel);
7125             rn = "WatchHi";
7126             break;
7127         default:
7128             goto cp0_unimplemented;
7129         }
7130         break;
7131     case 20:
7132         switch (sel) {
7133         case 0:
7134 #if defined(TARGET_MIPS64)
7135             check_insn(ctx, ISA_MIPS3);
7136             gen_helper_mtc0_xcontext(cpu_env, arg);
7137             rn = "XContext";
7138             break;
7139 #endif
7140         default:
7141             goto cp0_unimplemented;
7142         }
7143         break;
7144     case 21:
7145        /* Officially reserved, but sel 0 is used for R1x000 framemask */
7146         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7147         switch (sel) {
7148         case 0:
7149             gen_helper_mtc0_framemask(cpu_env, arg);
7150             rn = "Framemask";
7151             break;
7152         default:
7153             goto cp0_unimplemented;
7154         }
7155         break;
7156     case 22:
7157         /* ignored */
7158         rn = "Diagnostic"; /* implementation dependent */
7159         break;
7160     case 23:
7161         switch (sel) {
7162         case 0:
7163             gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
7164             /* DISAS_STOP isn't good enough here, hflags may have changed. */
7165             gen_save_pc(ctx->base.pc_next + 4);
7166             ctx->base.is_jmp = DISAS_EXIT;
7167             rn = "Debug";
7168             break;
7169         case 1:
7170 //            gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
7171             rn = "TraceControl";
7172             /* Stop translation as we may have switched the execution mode */
7173             ctx->base.is_jmp = DISAS_STOP;
7174             goto cp0_unimplemented;
7175         case 2:
7176 //            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
7177             rn = "TraceControl2";
7178             /* Stop translation as we may have switched the execution mode */
7179             ctx->base.is_jmp = DISAS_STOP;
7180             goto cp0_unimplemented;
7181         case 3:
7182             /* Stop translation as we may have switched the execution mode */
7183             ctx->base.is_jmp = DISAS_STOP;
7184 //            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
7185             rn = "UserTraceData";
7186             /* Stop translation as we may have switched the execution mode */
7187             ctx->base.is_jmp = DISAS_STOP;
7188             goto cp0_unimplemented;
7189         case 4:
7190 //            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
7191             /* Stop translation as we may have switched the execution mode */
7192             ctx->base.is_jmp = DISAS_STOP;
7193             rn = "TraceBPC";
7194             goto cp0_unimplemented;
7195         default:
7196             goto cp0_unimplemented;
7197         }
7198         break;
7199     case 24:
7200         switch (sel) {
7201         case 0:
7202             /* EJTAG support */
7203             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7204             rn = "DEPC";
7205             break;
7206         default:
7207             goto cp0_unimplemented;
7208         }
7209         break;
7210     case 25:
7211         switch (sel) {
7212         case 0:
7213             gen_helper_mtc0_performance0(cpu_env, arg);
7214             rn = "Performance0";
7215             break;
7216         case 1:
7217 //            gen_helper_mtc0_performance1(arg);
7218             rn = "Performance1";
7219             goto cp0_unimplemented;
7220         case 2:
7221 //            gen_helper_mtc0_performance2(arg);
7222             rn = "Performance2";
7223             goto cp0_unimplemented;
7224         case 3:
7225 //            gen_helper_mtc0_performance3(arg);
7226             rn = "Performance3";
7227             goto cp0_unimplemented;
7228         case 4:
7229 //            gen_helper_mtc0_performance4(arg);
7230             rn = "Performance4";
7231             goto cp0_unimplemented;
7232         case 5:
7233 //            gen_helper_mtc0_performance5(arg);
7234             rn = "Performance5";
7235             goto cp0_unimplemented;
7236         case 6:
7237 //            gen_helper_mtc0_performance6(arg);
7238             rn = "Performance6";
7239             goto cp0_unimplemented;
7240         case 7:
7241 //            gen_helper_mtc0_performance7(arg);
7242             rn = "Performance7";
7243             goto cp0_unimplemented;
7244         default:
7245             goto cp0_unimplemented;
7246         }
7247        break;
7248     case 26:
7249         switch (sel) {
7250         case 0:
7251             gen_helper_mtc0_errctl(cpu_env, arg);
7252             ctx->base.is_jmp = DISAS_STOP;
7253             rn = "ErrCtl";
7254             break;
7255         default:
7256             goto cp0_unimplemented;
7257         }
7258         break;
7259     case 27:
7260         switch (sel) {
7261         case 0:
7262         case 1:
7263         case 2:
7264         case 3:
7265             /* ignored */
7266             rn = "CacheErr";
7267             break;
7268         default:
7269             goto cp0_unimplemented;
7270         }
7271        break;
7272     case 28:
7273         switch (sel) {
7274         case 0:
7275         case 2:
7276         case 4:
7277         case 6:
7278             gen_helper_mtc0_taglo(cpu_env, arg);
7279             rn = "TagLo";
7280             break;
7281         case 1:
7282         case 3:
7283         case 5:
7284         case 7:
7285             gen_helper_mtc0_datalo(cpu_env, arg);
7286             rn = "DataLo";
7287             break;
7288         default:
7289             goto cp0_unimplemented;
7290         }
7291         break;
7292     case 29:
7293         switch (sel) {
7294         case 0:
7295         case 2:
7296         case 4:
7297         case 6:
7298             gen_helper_mtc0_taghi(cpu_env, arg);
7299             rn = "TagHi";
7300             break;
7301         case 1:
7302         case 3:
7303         case 5:
7304         case 7:
7305             gen_helper_mtc0_datahi(cpu_env, arg);
7306             rn = "DataHi";
7307             break;
7308         default:
7309             rn = "invalid sel";
7310             goto cp0_unimplemented;
7311         }
7312        break;
7313     case 30:
7314         switch (sel) {
7315         case 0:
7316             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7317             rn = "ErrorEPC";
7318             break;
7319         default:
7320             goto cp0_unimplemented;
7321         }
7322         break;
7323     case 31:
7324         switch (sel) {
7325         case 0:
7326             /* EJTAG support */
7327             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7328             rn = "DESAVE";
7329             break;
7330         case 2:
7331         case 3:
7332         case 4:
7333         case 5:
7334         case 6:
7335         case 7:
7336             CP0_CHECK(ctx->kscrexist & (1 << sel));
7337             tcg_gen_st_tl(arg, cpu_env,
7338                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7339             rn = "KScratch";
7340             break;
7341         default:
7342             goto cp0_unimplemented;
7343         }
7344         break;
7345     default:
7346        goto cp0_unimplemented;
7347     }
7348     trace_mips_translate_c0("mtc0", rn, reg, sel);
7349
7350     /* For simplicity assume that all writes can cause interrupts.  */
7351     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7352         gen_io_end();
7353         /* DISAS_STOP isn't sufficient, we need to ensure we break out of
7354          * translated code to check for pending interrupts.  */
7355         gen_save_pc(ctx->base.pc_next + 4);
7356         ctx->base.is_jmp = DISAS_EXIT;
7357     }
7358     return;
7359
7360 cp0_unimplemented:
7361     qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
7362 }
7363
7364 #if defined(TARGET_MIPS64)
7365 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7366 {
7367     const char *rn = "invalid";
7368
7369     if (sel != 0)
7370         check_insn(ctx, ISA_MIPS64);
7371
7372     switch (reg) {
7373     case 0:
7374         switch (sel) {
7375         case 0:
7376             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7377             rn = "Index";
7378             break;
7379         case 1:
7380             CP0_CHECK(ctx->insn_flags & ASE_MT);
7381             gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7382             rn = "MVPControl";
7383             break;
7384         case 2:
7385             CP0_CHECK(ctx->insn_flags & ASE_MT);
7386             gen_helper_mfc0_mvpconf0(arg, cpu_env);
7387             rn = "MVPConf0";
7388             break;
7389         case 3:
7390             CP0_CHECK(ctx->insn_flags & ASE_MT);
7391             gen_helper_mfc0_mvpconf1(arg, cpu_env);
7392             rn = "MVPConf1";
7393             break;
7394         case 4:
7395             CP0_CHECK(ctx->vp);
7396             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
7397             rn = "VPControl";
7398             break;
7399         default:
7400             goto cp0_unimplemented;
7401         }
7402         break;
7403     case 1:
7404         switch (sel) {
7405         case 0:
7406             CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7407             gen_helper_mfc0_random(arg, cpu_env);
7408             rn = "Random";
7409             break;
7410         case 1:
7411             CP0_CHECK(ctx->insn_flags & ASE_MT);
7412             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7413             rn = "VPEControl";
7414             break;
7415         case 2:
7416             CP0_CHECK(ctx->insn_flags & ASE_MT);
7417             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7418             rn = "VPEConf0";
7419             break;
7420         case 3:
7421             CP0_CHECK(ctx->insn_flags & ASE_MT);
7422             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7423             rn = "VPEConf1";
7424             break;
7425         case 4:
7426             CP0_CHECK(ctx->insn_flags & ASE_MT);
7427             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
7428             rn = "YQMask";
7429             break;
7430         case 5:
7431             CP0_CHECK(ctx->insn_flags & ASE_MT);
7432             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
7433             rn = "VPESchedule";
7434             break;
7435         case 6:
7436             CP0_CHECK(ctx->insn_flags & ASE_MT);
7437             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7438             rn = "VPEScheFBack";
7439             break;
7440         case 7:
7441             CP0_CHECK(ctx->insn_flags & ASE_MT);
7442             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7443             rn = "VPEOpt";
7444             break;
7445         default:
7446             goto cp0_unimplemented;
7447         }
7448         break;
7449     case 2:
7450         switch (sel) {
7451         case 0:
7452             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
7453             rn = "EntryLo0";
7454             break;
7455         case 1:
7456             CP0_CHECK(ctx->insn_flags & ASE_MT);
7457             gen_helper_mfc0_tcstatus(arg, cpu_env);
7458             rn = "TCStatus";
7459             break;
7460         case 2:
7461             CP0_CHECK(ctx->insn_flags & ASE_MT);
7462             gen_helper_mfc0_tcbind(arg, cpu_env);
7463             rn = "TCBind";
7464             break;
7465         case 3:
7466             CP0_CHECK(ctx->insn_flags & ASE_MT);
7467             gen_helper_dmfc0_tcrestart(arg, cpu_env);
7468             rn = "TCRestart";
7469             break;
7470         case 4:
7471             CP0_CHECK(ctx->insn_flags & ASE_MT);
7472             gen_helper_dmfc0_tchalt(arg, cpu_env);
7473             rn = "TCHalt";
7474             break;
7475         case 5:
7476             CP0_CHECK(ctx->insn_flags & ASE_MT);
7477             gen_helper_dmfc0_tccontext(arg, cpu_env);
7478             rn = "TCContext";
7479             break;
7480         case 6:
7481             CP0_CHECK(ctx->insn_flags & ASE_MT);
7482             gen_helper_dmfc0_tcschedule(arg, cpu_env);
7483             rn = "TCSchedule";
7484             break;
7485         case 7:
7486             CP0_CHECK(ctx->insn_flags & ASE_MT);
7487             gen_helper_dmfc0_tcschefback(arg, cpu_env);
7488             rn = "TCScheFBack";
7489             break;
7490         default:
7491             goto cp0_unimplemented;
7492         }
7493         break;
7494     case 3:
7495         switch (sel) {
7496         case 0:
7497             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
7498             rn = "EntryLo1";
7499             break;
7500         case 1:
7501             CP0_CHECK(ctx->vp);
7502             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
7503             rn = "GlobalNumber";
7504             break;
7505         default:
7506             goto cp0_unimplemented;
7507         }
7508         break;
7509     case 4:
7510         switch (sel) {
7511         case 0:
7512             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
7513             rn = "Context";
7514             break;
7515         case 1:
7516 //            gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
7517             rn = "ContextConfig";
7518             goto cp0_unimplemented;
7519         case 2:
7520             CP0_CHECK(ctx->ulri);
7521             tcg_gen_ld_tl(arg, cpu_env,
7522                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7523             rn = "UserLocal";
7524             break;
7525         default:
7526             goto cp0_unimplemented;
7527         }
7528         break;
7529     case 5:
7530         switch (sel) {
7531         case 0:
7532             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
7533             rn = "PageMask";
7534             break;
7535         case 1:
7536             check_insn(ctx, ISA_MIPS32R2);
7537             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
7538             rn = "PageGrain";
7539             break;
7540         case 2:
7541             CP0_CHECK(ctx->sc);
7542             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
7543             rn = "SegCtl0";
7544             break;
7545         case 3:
7546             CP0_CHECK(ctx->sc);
7547             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
7548             rn = "SegCtl1";
7549             break;
7550         case 4:
7551             CP0_CHECK(ctx->sc);
7552             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
7553             rn = "SegCtl2";
7554             break;
7555         case 5:
7556             check_pw(ctx);
7557             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
7558             rn = "PWBase";
7559             break;
7560         case 6:
7561             check_pw(ctx);
7562             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
7563             rn = "PWField";
7564             break;
7565         case 7:
7566             check_pw(ctx);
7567             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
7568             rn = "PWSize";
7569             break;
7570         default:
7571             goto cp0_unimplemented;
7572         }
7573         break;
7574     case 6:
7575         switch (sel) {
7576         case 0:
7577             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
7578             rn = "Wired";
7579             break;
7580         case 1:
7581             check_insn(ctx, ISA_MIPS32R2);
7582             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
7583             rn = "SRSConf0";
7584             break;
7585         case 2:
7586             check_insn(ctx, ISA_MIPS32R2);
7587             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
7588             rn = "SRSConf1";
7589             break;
7590         case 3:
7591             check_insn(ctx, ISA_MIPS32R2);
7592             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
7593             rn = "SRSConf2";
7594             break;
7595         case 4:
7596             check_insn(ctx, ISA_MIPS32R2);
7597             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
7598             rn = "SRSConf3";
7599             break;
7600         case 5:
7601             check_insn(ctx, ISA_MIPS32R2);
7602             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
7603             rn = "SRSConf4";
7604             break;
7605         case 6:
7606             check_pw(ctx);
7607             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
7608             rn = "PWCtl";
7609             break;
7610         default:
7611             goto cp0_unimplemented;
7612         }
7613         break;
7614     case 7:
7615         switch (sel) {
7616         case 0:
7617             check_insn(ctx, ISA_MIPS32R2);
7618             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
7619             rn = "HWREna";
7620             break;
7621         default:
7622             goto cp0_unimplemented;
7623         }
7624         break;
7625     case 8:
7626         switch (sel) {
7627         case 0:
7628             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
7629             rn = "BadVAddr";
7630             break;
7631         case 1:
7632             CP0_CHECK(ctx->bi);
7633             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
7634             rn = "BadInstr";
7635             break;
7636         case 2:
7637             CP0_CHECK(ctx->bp);
7638             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
7639             rn = "BadInstrP";
7640             break;
7641         case 3:
7642             CP0_CHECK(ctx->bi);
7643             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
7644             tcg_gen_andi_tl(arg, arg, ~0xffff);
7645             rn = "BadInstrX";
7646             break;
7647         default:
7648             goto cp0_unimplemented;
7649         }
7650         break;
7651     case 9:
7652         switch (sel) {
7653         case 0:
7654             /* Mark as an IO operation because we read the time.  */
7655             if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7656                 gen_io_start();
7657             }
7658             gen_helper_mfc0_count(arg, cpu_env);
7659             if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7660                 gen_io_end();
7661             }
7662             /* Break the TB to be able to take timer interrupts immediately
7663                after reading count. DISAS_STOP isn't sufficient, we need to
7664                ensure we break completely out of translated code.  */
7665             gen_save_pc(ctx->base.pc_next + 4);
7666             ctx->base.is_jmp = DISAS_EXIT;
7667             rn = "Count";
7668             break;
7669         /* 6,7 are implementation dependent */
7670         default:
7671             goto cp0_unimplemented;
7672         }
7673         break;
7674     case 10:
7675         switch (sel) {
7676         case 0:
7677             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
7678             rn = "EntryHi";
7679             break;
7680         default:
7681             goto cp0_unimplemented;
7682         }
7683         break;
7684     case 11:
7685         switch (sel) {
7686         case 0:
7687             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
7688             rn = "Compare";
7689             break;
7690         /* 6,7 are implementation dependent */
7691         default:
7692             goto cp0_unimplemented;
7693         }
7694         break;
7695     case 12:
7696         switch (sel) {
7697         case 0:
7698             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
7699             rn = "Status";
7700             break;
7701         case 1:
7702             check_insn(ctx, ISA_MIPS32R2);
7703             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
7704             rn = "IntCtl";
7705             break;
7706         case 2:
7707             check_insn(ctx, ISA_MIPS32R2);
7708             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
7709             rn = "SRSCtl";
7710             break;
7711         case 3:
7712             check_insn(ctx, ISA_MIPS32R2);
7713             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7714             rn = "SRSMap";
7715             break;
7716         default:
7717             goto cp0_unimplemented;
7718         }
7719         break;
7720     case 13:
7721         switch (sel) {
7722         case 0:
7723             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
7724             rn = "Cause";
7725             break;
7726         default:
7727             goto cp0_unimplemented;
7728         }
7729         break;
7730     case 14:
7731         switch (sel) {
7732         case 0:
7733             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7734             rn = "EPC";
7735             break;
7736         default:
7737             goto cp0_unimplemented;
7738         }
7739         break;
7740     case 15:
7741         switch (sel) {
7742         case 0:
7743             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
7744             rn = "PRid";
7745             break;
7746         case 1:
7747             check_insn(ctx, ISA_MIPS32R2);
7748             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
7749             rn = "EBase";
7750             break;
7751         case 3:
7752             check_insn(ctx, ISA_MIPS32R2);
7753             CP0_CHECK(ctx->cmgcr);
7754             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7755             rn = "CMGCRBase";
7756             break;
7757         default:
7758             goto cp0_unimplemented;
7759         }
7760         break;
7761     case 16:
7762         switch (sel) {
7763         case 0:
7764             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
7765             rn = "Config";
7766             break;
7767         case 1:
7768             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
7769             rn = "Config1";
7770             break;
7771         case 2:
7772             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7773             rn = "Config2";
7774             break;
7775         case 3:
7776             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7777             rn = "Config3";
7778             break;
7779         case 4:
7780             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7781             rn = "Config4";
7782             break;
7783         case 5:
7784             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7785             rn = "Config5";
7786             break;
7787        /* 6,7 are implementation dependent */
7788         case 6:
7789             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
7790             rn = "Config6";
7791             break;
7792         case 7:
7793             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
7794             rn = "Config7";
7795             break;
7796         default:
7797             goto cp0_unimplemented;
7798         }
7799         break;
7800     case 17:
7801         switch (sel) {
7802         case 0:
7803             gen_helper_dmfc0_lladdr(arg, cpu_env);
7804             rn = "LLAddr";
7805             break;
7806         case 1:
7807             CP0_CHECK(ctx->mrp);
7808             gen_helper_dmfc0_maar(arg, cpu_env);
7809             rn = "MAAR";
7810             break;
7811         case 2:
7812             CP0_CHECK(ctx->mrp);
7813             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7814             rn = "MAARI";
7815             break;
7816         default:
7817             goto cp0_unimplemented;
7818         }
7819         break;
7820     case 18:
7821         switch (sel) {
7822         case 0:
7823         case 1:
7824         case 2:
7825         case 3:
7826         case 4:
7827         case 5:
7828         case 6:
7829         case 7:
7830             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7831             gen_helper_1e0i(dmfc0_watchlo, arg, sel);
7832             rn = "WatchLo";
7833             break;
7834         default:
7835             goto cp0_unimplemented;
7836         }
7837         break;
7838     case 19:
7839         switch (sel) {
7840         case 0:
7841         case 1:
7842         case 2:
7843         case 3:
7844         case 4:
7845         case 5:
7846         case 6:
7847         case 7:
7848             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7849             gen_helper_1e0i(mfc0_watchhi, arg, sel);
7850             rn = "WatchHi";
7851             break;
7852         default:
7853             goto cp0_unimplemented;
7854         }
7855         break;
7856     case 20:
7857         switch (sel) {
7858         case 0:
7859             check_insn(ctx, ISA_MIPS3);
7860             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
7861             rn = "XContext";
7862             break;
7863         default:
7864             goto cp0_unimplemented;
7865         }
7866         break;
7867     case 21:
7868        /* Officially reserved, but sel 0 is used for R1x000 framemask */
7869         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7870         switch (sel) {
7871         case 0:
7872             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
7873             rn = "Framemask";
7874             break;
7875         default:
7876             goto cp0_unimplemented;
7877         }
7878         break;
7879     case 22:
7880         tcg_gen_movi_tl(arg, 0); /* unimplemented */
7881         rn = "'Diagnostic"; /* implementation dependent */
7882         break;
7883     case 23:
7884         switch (sel) {
7885         case 0:
7886             gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
7887             rn = "Debug";
7888             break;
7889         case 1:
7890 //            gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
7891             rn = "TraceControl";
7892             goto cp0_unimplemented;
7893         case 2:
7894 //            gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
7895             rn = "TraceControl2";
7896             goto cp0_unimplemented;
7897         case 3:
7898 //            gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
7899             rn = "UserTraceData";
7900             goto cp0_unimplemented;
7901         case 4:
7902 //            gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
7903             rn = "TraceBPC";
7904             goto cp0_unimplemented;
7905         default:
7906             goto cp0_unimplemented;
7907         }
7908         break;
7909     case 24:
7910         switch (sel) {
7911         case 0:
7912             /* EJTAG support */
7913             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7914             rn = "DEPC";
7915             break;
7916         default:
7917             goto cp0_unimplemented;
7918         }
7919         break;
7920     case 25:
7921         switch (sel) {
7922         case 0:
7923             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
7924             rn = "Performance0";
7925             break;
7926         case 1:
7927 //            gen_helper_dmfc0_performance1(arg);
7928             rn = "Performance1";
7929             goto cp0_unimplemented;
7930         case 2:
7931 //            gen_helper_dmfc0_performance2(arg);
7932             rn = "Performance2";
7933             goto cp0_unimplemented;
7934         case 3:
7935 //            gen_helper_dmfc0_performance3(arg);
7936             rn = "Performance3";
7937             goto cp0_unimplemented;
7938         case 4:
7939 //            gen_helper_dmfc0_performance4(arg);
7940             rn = "Performance4";
7941             goto cp0_unimplemented;
7942         case 5:
7943 //            gen_helper_dmfc0_performance5(arg);
7944             rn = "Performance5";
7945             goto cp0_unimplemented;
7946         case 6:
7947 //            gen_helper_dmfc0_performance6(arg);
7948             rn = "Performance6";
7949             goto cp0_unimplemented;
7950         case 7:
7951 //            gen_helper_dmfc0_performance7(arg);
7952             rn = "Performance7";
7953             goto cp0_unimplemented;
7954         default:
7955             goto cp0_unimplemented;
7956         }
7957         break;
7958     case 26:
7959         switch (sel) {
7960         case 0:
7961             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7962             rn = "ErrCtl";
7963             break;
7964         default:
7965             goto cp0_unimplemented;
7966         }
7967         break;
7968     case 27:
7969         switch (sel) {
7970         /* ignored */
7971         case 0:
7972         case 1:
7973         case 2:
7974         case 3:
7975             tcg_gen_movi_tl(arg, 0); /* unimplemented */
7976             rn = "CacheErr";
7977             break;
7978         default:
7979             goto cp0_unimplemented;
7980         }
7981         break;
7982     case 28:
7983         switch (sel) {
7984         case 0:
7985         case 2:
7986         case 4:
7987         case 6:
7988             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
7989             rn = "TagLo";
7990             break;
7991         case 1:
7992         case 3:
7993         case 5:
7994         case 7:
7995             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
7996             rn = "DataLo";
7997             break;
7998         default:
7999             goto cp0_unimplemented;
8000         }
8001         break;
8002     case 29:
8003         switch (sel) {
8004         case 0:
8005         case 2:
8006         case 4:
8007         case 6:
8008             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
8009             rn = "TagHi";
8010             break;
8011         case 1:
8012         case 3:
8013         case 5:
8014         case 7:
8015             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
8016             rn = "DataHi";
8017             break;
8018         default:
8019             goto cp0_unimplemented;
8020         }
8021         break;
8022     case 30:
8023         switch (sel) {
8024         case 0:
8025             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8026             rn = "ErrorEPC";
8027             break;
8028         default:
8029             goto cp0_unimplemented;
8030         }
8031         break;
8032     case 31:
8033         switch (sel) {
8034         case 0:
8035             /* EJTAG support */
8036             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8037             rn = "DESAVE";
8038             break;
8039         case 2:
8040         case 3:
8041         case 4:
8042         case 5:
8043         case 6:
8044         case 7:
8045             CP0_CHECK(ctx->kscrexist & (1 << sel));
8046             tcg_gen_ld_tl(arg, cpu_env,
8047                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8048             rn = "KScratch";
8049             break;
8050         default:
8051             goto cp0_unimplemented;
8052         }
8053         break;
8054     default:
8055         goto cp0_unimplemented;
8056     }
8057     trace_mips_translate_c0("dmfc0", rn, reg, sel);
8058     return;
8059
8060 cp0_unimplemented:
8061     qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
8062     gen_mfc0_unimplemented(ctx, arg);
8063 }
8064
8065 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8066 {
8067     const char *rn = "invalid";
8068
8069     if (sel != 0)
8070         check_insn(ctx, ISA_MIPS64);
8071
8072     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8073         gen_io_start();
8074     }
8075
8076     switch (reg) {
8077     case 0:
8078         switch (sel) {
8079         case 0:
8080             gen_helper_mtc0_index(cpu_env, arg);
8081             rn = "Index";
8082             break;
8083         case 1:
8084             CP0_CHECK(ctx->insn_flags & ASE_MT);
8085             gen_helper_mtc0_mvpcontrol(cpu_env, arg);
8086             rn = "MVPControl";
8087             break;
8088         case 2:
8089             CP0_CHECK(ctx->insn_flags & ASE_MT);
8090             /* ignored */
8091             rn = "MVPConf0";
8092             break;
8093         case 3:
8094             CP0_CHECK(ctx->insn_flags & ASE_MT);
8095             /* ignored */
8096             rn = "MVPConf1";
8097             break;
8098         case 4:
8099             CP0_CHECK(ctx->vp);
8100             /* ignored */
8101             rn = "VPControl";
8102             break;
8103         default:
8104             goto cp0_unimplemented;
8105         }
8106         break;
8107     case 1:
8108         switch (sel) {
8109         case 0:
8110             /* ignored */
8111             rn = "Random";
8112             break;
8113         case 1:
8114             CP0_CHECK(ctx->insn_flags & ASE_MT);
8115             gen_helper_mtc0_vpecontrol(cpu_env, arg);
8116             rn = "VPEControl";
8117             break;
8118         case 2:
8119             CP0_CHECK(ctx->insn_flags & ASE_MT);
8120             gen_helper_mtc0_vpeconf0(cpu_env, arg);
8121             rn = "VPEConf0";
8122             break;
8123         case 3:
8124             CP0_CHECK(ctx->insn_flags & ASE_MT);
8125             gen_helper_mtc0_vpeconf1(cpu_env, arg);
8126             rn = "VPEConf1";
8127             break;
8128         case 4:
8129             CP0_CHECK(ctx->insn_flags & ASE_MT);
8130             gen_helper_mtc0_yqmask(cpu_env, arg);
8131             rn = "YQMask";
8132             break;
8133         case 5:
8134             CP0_CHECK(ctx->insn_flags & ASE_MT);
8135             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
8136             rn = "VPESchedule";
8137             break;
8138         case 6:
8139             CP0_CHECK(ctx->insn_flags & ASE_MT);
8140             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
8141             rn = "VPEScheFBack";
8142             break;
8143         case 7:
8144             CP0_CHECK(ctx->insn_flags & ASE_MT);
8145             gen_helper_mtc0_vpeopt(cpu_env, arg);
8146             rn = "VPEOpt";
8147             break;
8148         default:
8149             goto cp0_unimplemented;
8150         }
8151         break;
8152     case 2:
8153         switch (sel) {
8154         case 0:
8155             gen_helper_dmtc0_entrylo0(cpu_env, arg);
8156             rn = "EntryLo0";
8157             break;
8158         case 1:
8159             CP0_CHECK(ctx->insn_flags & ASE_MT);
8160             gen_helper_mtc0_tcstatus(cpu_env, arg);
8161             rn = "TCStatus";
8162             break;
8163         case 2:
8164             CP0_CHECK(ctx->insn_flags & ASE_MT);
8165             gen_helper_mtc0_tcbind(cpu_env, arg);
8166             rn = "TCBind";
8167             break;
8168         case 3:
8169             CP0_CHECK(ctx->insn_flags & ASE_MT);
8170             gen_helper_mtc0_tcrestart(cpu_env, arg);
8171             rn = "TCRestart";
8172             break;
8173         case 4:
8174             CP0_CHECK(ctx->insn_flags & ASE_MT);
8175             gen_helper_mtc0_tchalt(cpu_env, arg);
8176             rn = "TCHalt";
8177             break;
8178         case 5:
8179             CP0_CHECK(ctx->insn_flags & ASE_MT);
8180             gen_helper_mtc0_tccontext(cpu_env, arg);
8181             rn = "TCContext";
8182             break;
8183         case 6:
8184             CP0_CHECK(ctx->insn_flags & ASE_MT);
8185             gen_helper_mtc0_tcschedule(cpu_env, arg);
8186             rn = "TCSchedule";
8187             break;
8188         case 7:
8189             CP0_CHECK(ctx->insn_flags & ASE_MT);
8190             gen_helper_mtc0_tcschefback(cpu_env, arg);
8191             rn = "TCScheFBack";
8192             break;
8193         default:
8194             goto cp0_unimplemented;
8195         }
8196         break;
8197     case 3:
8198         switch (sel) {
8199         case 0:
8200             gen_helper_dmtc0_entrylo1(cpu_env, arg);
8201             rn = "EntryLo1";
8202             break;
8203         case 1:
8204             CP0_CHECK(ctx->vp);
8205             /* ignored */
8206             rn = "GlobalNumber";
8207             break;
8208         default:
8209             goto cp0_unimplemented;
8210         }
8211         break;
8212     case 4:
8213         switch (sel) {
8214         case 0:
8215             gen_helper_mtc0_context(cpu_env, arg);
8216             rn = "Context";
8217             break;
8218         case 1:
8219 //           gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
8220             rn = "ContextConfig";
8221             goto cp0_unimplemented;
8222         case 2:
8223             CP0_CHECK(ctx->ulri);
8224             tcg_gen_st_tl(arg, cpu_env,
8225                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8226             rn = "UserLocal";
8227             break;
8228         default:
8229             goto cp0_unimplemented;
8230         }
8231         break;
8232     case 5:
8233         switch (sel) {
8234         case 0:
8235             gen_helper_mtc0_pagemask(cpu_env, arg);
8236             rn = "PageMask";
8237             break;
8238         case 1:
8239             check_insn(ctx, ISA_MIPS32R2);
8240             gen_helper_mtc0_pagegrain(cpu_env, arg);
8241             rn = "PageGrain";
8242             break;
8243         case 2:
8244             CP0_CHECK(ctx->sc);
8245             gen_helper_mtc0_segctl0(cpu_env, arg);
8246             rn = "SegCtl0";
8247             break;
8248         case 3:
8249             CP0_CHECK(ctx->sc);
8250             gen_helper_mtc0_segctl1(cpu_env, arg);
8251             rn = "SegCtl1";
8252             break;
8253         case 4:
8254             CP0_CHECK(ctx->sc);
8255             gen_helper_mtc0_segctl2(cpu_env, arg);
8256             rn = "SegCtl2";
8257             break;
8258         case 5:
8259             check_pw(ctx);
8260             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8261             rn = "PWBase";
8262             break;
8263         case 6:
8264             check_pw(ctx);
8265             gen_helper_mtc0_pwfield(cpu_env, arg);
8266             rn = "PWField";
8267             break;
8268         case 7:
8269             check_pw(ctx);
8270             gen_helper_mtc0_pwsize(cpu_env, arg);
8271             rn = "PWSize";
8272             break;
8273         default:
8274             goto cp0_unimplemented;
8275         }
8276         break;
8277     case 6:
8278         switch (sel) {
8279         case 0:
8280             gen_helper_mtc0_wired(cpu_env, arg);
8281             rn = "Wired";
8282             break;
8283         case 1:
8284             check_insn(ctx, ISA_MIPS32R2);
8285             gen_helper_mtc0_srsconf0(cpu_env, arg);
8286             rn = "SRSConf0";
8287             break;
8288         case 2:
8289             check_insn(ctx, ISA_MIPS32R2);
8290             gen_helper_mtc0_srsconf1(cpu_env, arg);
8291             rn = "SRSConf1";
8292             break;
8293         case 3:
8294             check_insn(ctx, ISA_MIPS32R2);
8295             gen_helper_mtc0_srsconf2(cpu_env, arg);
8296             rn = "SRSConf2";
8297             break;
8298         case 4:
8299             check_insn(ctx, ISA_MIPS32R2);
8300             gen_helper_mtc0_srsconf3(cpu_env, arg);
8301             rn = "SRSConf3";
8302             break;
8303         case 5:
8304             check_insn(ctx, ISA_MIPS32R2);
8305             gen_helper_mtc0_srsconf4(cpu_env, arg);
8306             rn = "SRSConf4";
8307             break;
8308         case 6:
8309             check_pw(ctx);
8310             gen_helper_mtc0_pwctl(cpu_env, arg);
8311             rn = "PWCtl";
8312             break;
8313         default:
8314             goto cp0_unimplemented;
8315         }
8316         break;
8317     case 7:
8318         switch (sel) {
8319         case 0:
8320             check_insn(ctx, ISA_MIPS32R2);
8321             gen_helper_mtc0_hwrena(cpu_env, arg);
8322             ctx->base.is_jmp = DISAS_STOP;
8323             rn = "HWREna";
8324             break;
8325         default:
8326             goto cp0_unimplemented;
8327         }
8328         break;
8329     case 8:
8330         switch (sel) {
8331         case 0:
8332             /* ignored */
8333             rn = "BadVAddr";
8334             break;
8335         case 1:
8336             /* ignored */
8337             rn = "BadInstr";
8338             break;
8339         case 2:
8340             /* ignored */
8341             rn = "BadInstrP";
8342             break;
8343         case 3:
8344             /* ignored */
8345             rn = "BadInstrX";
8346             break;
8347         default:
8348             goto cp0_unimplemented;
8349         }
8350         break;
8351     case 9:
8352         switch (sel) {
8353         case 0:
8354             gen_helper_mtc0_count(cpu_env, arg);
8355             rn = "Count";
8356             break;
8357         /* 6,7 are implementation dependent */
8358         default:
8359             goto cp0_unimplemented;
8360         }
8361         /* Stop translation as we may have switched the execution mode */
8362         ctx->base.is_jmp = DISAS_STOP;
8363         break;
8364     case 10:
8365         switch (sel) {
8366         case 0:
8367             gen_helper_mtc0_entryhi(cpu_env, arg);
8368             rn = "EntryHi";
8369             break;
8370         default:
8371             goto cp0_unimplemented;
8372         }
8373         break;
8374     case 11:
8375         switch (sel) {
8376         case 0:
8377             gen_helper_mtc0_compare(cpu_env, arg);
8378             rn = "Compare";
8379             break;
8380         /* 6,7 are implementation dependent */
8381         default:
8382             goto cp0_unimplemented;
8383         }
8384         /* Stop translation as we may have switched the execution mode */
8385         ctx->base.is_jmp = DISAS_STOP;
8386         break;
8387     case 12:
8388         switch (sel) {
8389         case 0:
8390             save_cpu_state(ctx, 1);
8391             gen_helper_mtc0_status(cpu_env, arg);
8392             /* DISAS_STOP isn't good enough here, hflags may have changed. */
8393             gen_save_pc(ctx->base.pc_next + 4);
8394             ctx->base.is_jmp = DISAS_EXIT;
8395             rn = "Status";
8396             break;
8397         case 1:
8398             check_insn(ctx, ISA_MIPS32R2);
8399             gen_helper_mtc0_intctl(cpu_env, arg);
8400             /* Stop translation as we may have switched the execution mode */
8401             ctx->base.is_jmp = DISAS_STOP;
8402             rn = "IntCtl";
8403             break;
8404         case 2:
8405             check_insn(ctx, ISA_MIPS32R2);
8406             gen_helper_mtc0_srsctl(cpu_env, arg);
8407             /* Stop translation as we may have switched the execution mode */
8408             ctx->base.is_jmp = DISAS_STOP;
8409             rn = "SRSCtl";
8410             break;
8411         case 3:
8412             check_insn(ctx, ISA_MIPS32R2);
8413             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8414             /* Stop translation as we may have switched the execution mode */
8415             ctx->base.is_jmp = DISAS_STOP;
8416             rn = "SRSMap";
8417             break;
8418         default:
8419             goto cp0_unimplemented;
8420         }
8421         break;
8422     case 13:
8423         switch (sel) {
8424         case 0:
8425             save_cpu_state(ctx, 1);
8426             gen_helper_mtc0_cause(cpu_env, arg);
8427             /* Stop translation as we may have triggered an interrupt.
8428              * DISAS_STOP isn't sufficient, we need to ensure we break out of
8429              * translated code to check for pending interrupts.  */
8430             gen_save_pc(ctx->base.pc_next + 4);
8431             ctx->base.is_jmp = DISAS_EXIT;
8432             rn = "Cause";
8433             break;
8434         default:
8435             goto cp0_unimplemented;
8436         }
8437         break;
8438     case 14:
8439         switch (sel) {
8440         case 0:
8441             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
8442             rn = "EPC";
8443             break;
8444         default:
8445             goto cp0_unimplemented;
8446         }
8447         break;
8448     case 15:
8449         switch (sel) {
8450         case 0:
8451             /* ignored */
8452             rn = "PRid";
8453             break;
8454         case 1:
8455             check_insn(ctx, ISA_MIPS32R2);
8456             gen_helper_mtc0_ebase(cpu_env, arg);
8457             rn = "EBase";
8458             break;
8459         default:
8460             goto cp0_unimplemented;
8461         }
8462         break;
8463     case 16:
8464         switch (sel) {
8465         case 0:
8466             gen_helper_mtc0_config0(cpu_env, arg);
8467             rn = "Config";
8468             /* Stop translation as we may have switched the execution mode */
8469             ctx->base.is_jmp = DISAS_STOP;
8470             break;
8471         case 1:
8472             /* ignored, read only */
8473             rn = "Config1";
8474             break;
8475         case 2:
8476             gen_helper_mtc0_config2(cpu_env, arg);
8477             rn = "Config2";
8478             /* Stop translation as we may have switched the execution mode */
8479             ctx->base.is_jmp = DISAS_STOP;
8480             break;
8481         case 3:
8482             gen_helper_mtc0_config3(cpu_env, arg);
8483             rn = "Config3";
8484             /* Stop translation as we may have switched the execution mode */
8485             ctx->base.is_jmp = DISAS_STOP;
8486             break;
8487         case 4:
8488             /* currently ignored */
8489             rn = "Config4";
8490             break;
8491         case 5:
8492             gen_helper_mtc0_config5(cpu_env, arg);
8493             rn = "Config5";
8494             /* Stop translation as we may have switched the execution mode */
8495             ctx->base.is_jmp = DISAS_STOP;
8496             break;
8497         /* 6,7 are implementation dependent */
8498         default:
8499             rn = "Invalid config selector";
8500             goto cp0_unimplemented;
8501         }
8502         break;
8503     case 17:
8504         switch (sel) {
8505         case 0:
8506             gen_helper_mtc0_lladdr(cpu_env, arg);
8507             rn = "LLAddr";
8508             break;
8509         case 1:
8510             CP0_CHECK(ctx->mrp);
8511             gen_helper_mtc0_maar(cpu_env, arg);
8512             rn = "MAAR";
8513             break;
8514         case 2:
8515             CP0_CHECK(ctx->mrp);
8516             gen_helper_mtc0_maari(cpu_env, arg);
8517             rn = "MAARI";
8518             break;
8519         default:
8520             goto cp0_unimplemented;
8521         }
8522         break;
8523     case 18:
8524         switch (sel) {
8525         case 0:
8526         case 1:
8527         case 2:
8528         case 3:
8529         case 4:
8530         case 5:
8531         case 6:
8532         case 7:
8533             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8534             gen_helper_0e1i(mtc0_watchlo, arg, sel);
8535             rn = "WatchLo";
8536             break;
8537         default:
8538             goto cp0_unimplemented;
8539         }
8540         break;
8541     case 19:
8542         switch (sel) {
8543         case 0:
8544         case 1:
8545         case 2:
8546         case 3:
8547         case 4:
8548         case 5:
8549         case 6:
8550         case 7:
8551             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8552             gen_helper_0e1i(mtc0_watchhi, arg, sel);
8553             rn = "WatchHi";
8554             break;
8555         default:
8556             goto cp0_unimplemented;
8557         }
8558         break;
8559     case 20:
8560         switch (sel) {
8561         case 0:
8562             check_insn(ctx, ISA_MIPS3);
8563             gen_helper_mtc0_xcontext(cpu_env, arg);
8564             rn = "XContext";
8565             break;
8566         default:
8567             goto cp0_unimplemented;
8568         }
8569         break;
8570     case 21:
8571        /* Officially reserved, but sel 0 is used for R1x000 framemask */
8572         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8573         switch (sel) {
8574         case 0:
8575             gen_helper_mtc0_framemask(cpu_env, arg);
8576             rn = "Framemask";
8577             break;
8578         default:
8579             goto cp0_unimplemented;
8580         }
8581         break;
8582     case 22:
8583         /* ignored */
8584         rn = "Diagnostic"; /* implementation dependent */
8585         break;
8586     case 23:
8587         switch (sel) {
8588         case 0:
8589             gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8590             /* DISAS_STOP isn't good enough here, hflags may have changed. */
8591             gen_save_pc(ctx->base.pc_next + 4);
8592             ctx->base.is_jmp = DISAS_EXIT;
8593             rn = "Debug";
8594             break;
8595         case 1:
8596 //            gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8597             /* Stop translation as we may have switched the execution mode */
8598             ctx->base.is_jmp = DISAS_STOP;
8599             rn = "TraceControl";
8600             goto cp0_unimplemented;
8601         case 2:
8602 //            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8603             /* Stop translation as we may have switched the execution mode */
8604             ctx->base.is_jmp = DISAS_STOP;
8605             rn = "TraceControl2";
8606             goto cp0_unimplemented;
8607         case 3:
8608 //            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8609             /* Stop translation as we may have switched the execution mode */
8610             ctx->base.is_jmp = DISAS_STOP;
8611             rn = "UserTraceData";
8612             goto cp0_unimplemented;
8613         case 4:
8614 //            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8615             /* Stop translation as we may have switched the execution mode */
8616             ctx->base.is_jmp = DISAS_STOP;
8617             rn = "TraceBPC";
8618             goto cp0_unimplemented;
8619         default:
8620             goto cp0_unimplemented;
8621         }
8622         break;
8623     case 24:
8624         switch (sel) {
8625         case 0:
8626             /* EJTAG support */
8627             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8628             rn = "DEPC";
8629             break;
8630         default:
8631             goto cp0_unimplemented;
8632         }
8633         break;
8634     case 25:
8635         switch (sel) {
8636         case 0:
8637             gen_helper_mtc0_performance0(cpu_env, arg);
8638             rn = "Performance0";
8639             break;
8640         case 1:
8641 //            gen_helper_mtc0_performance1(cpu_env, arg);
8642             rn = "Performance1";
8643             goto cp0_unimplemented;
8644         case 2:
8645 //            gen_helper_mtc0_performance2(cpu_env, arg);
8646             rn = "Performance2";
8647             goto cp0_unimplemented;
8648         case 3:
8649 //            gen_helper_mtc0_performance3(cpu_env, arg);
8650             rn = "Performance3";
8651             goto cp0_unimplemented;
8652         case 4:
8653 //            gen_helper_mtc0_performance4(cpu_env, arg);
8654             rn = "Performance4";
8655             goto cp0_unimplemented;
8656         case 5:
8657 //            gen_helper_mtc0_performance5(cpu_env, arg);
8658             rn = "Performance5";
8659             goto cp0_unimplemented;
8660         case 6:
8661 //            gen_helper_mtc0_performance6(cpu_env, arg);
8662             rn = "Performance6";
8663             goto cp0_unimplemented;
8664         case 7:
8665 //            gen_helper_mtc0_performance7(cpu_env, arg);
8666             rn = "Performance7";
8667             goto cp0_unimplemented;
8668         default:
8669             goto cp0_unimplemented;
8670         }
8671         break;
8672     case 26:
8673         switch (sel) {
8674         case 0:
8675             gen_helper_mtc0_errctl(cpu_env, arg);
8676             ctx->base.is_jmp = DISAS_STOP;
8677             rn = "ErrCtl";
8678             break;
8679         default:
8680             goto cp0_unimplemented;
8681         }
8682         break;
8683     case 27:
8684         switch (sel) {
8685         case 0:
8686         case 1:
8687         case 2:
8688         case 3:
8689             /* ignored */
8690             rn = "CacheErr";
8691             break;
8692         default:
8693             goto cp0_unimplemented;
8694         }
8695         break;
8696     case 28:
8697         switch (sel) {
8698         case 0:
8699         case 2:
8700         case 4:
8701         case 6:
8702             gen_helper_mtc0_taglo(cpu_env, arg);
8703             rn = "TagLo";
8704             break;
8705         case 1:
8706         case 3:
8707         case 5:
8708         case 7:
8709             gen_helper_mtc0_datalo(cpu_env, arg);
8710             rn = "DataLo";
8711             break;
8712         default:
8713             goto cp0_unimplemented;
8714         }
8715         break;
8716     case 29:
8717         switch (sel) {
8718         case 0:
8719         case 2:
8720         case 4:
8721         case 6:
8722             gen_helper_mtc0_taghi(cpu_env, arg);
8723             rn = "TagHi";
8724             break;
8725         case 1:
8726         case 3:
8727         case 5:
8728         case 7:
8729             gen_helper_mtc0_datahi(cpu_env, arg);
8730             rn = "DataHi";
8731             break;
8732         default:
8733             rn = "invalid sel";
8734             goto cp0_unimplemented;
8735         }
8736         break;
8737     case 30:
8738         switch (sel) {
8739         case 0:
8740             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8741             rn = "ErrorEPC";
8742             break;
8743         default:
8744             goto cp0_unimplemented;
8745         }
8746         break;
8747     case 31:
8748         switch (sel) {
8749         case 0:
8750             /* EJTAG support */
8751             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8752             rn = "DESAVE";
8753             break;
8754         case 2:
8755         case 3:
8756         case 4:
8757         case 5:
8758         case 6:
8759         case 7:
8760             CP0_CHECK(ctx->kscrexist & (1 << sel));
8761             tcg_gen_st_tl(arg, cpu_env,
8762                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8763             rn = "KScratch";
8764             break;
8765         default:
8766             goto cp0_unimplemented;
8767         }
8768         break;
8769     default:
8770         goto cp0_unimplemented;
8771     }
8772     trace_mips_translate_c0("dmtc0", rn, reg, sel);
8773
8774     /* For simplicity assume that all writes can cause interrupts.  */
8775     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8776         gen_io_end();
8777         /* DISAS_STOP isn't sufficient, we need to ensure we break out of
8778          * translated code to check for pending interrupts.  */
8779         gen_save_pc(ctx->base.pc_next + 4);
8780         ctx->base.is_jmp = DISAS_EXIT;
8781     }
8782     return;
8783
8784 cp0_unimplemented:
8785     qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8786 }
8787 #endif /* TARGET_MIPS64 */
8788
8789 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
8790                      int u, int sel, int h)
8791 {
8792     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
8793     TCGv t0 = tcg_temp_local_new();
8794
8795     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
8796         ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8797          (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
8798         tcg_gen_movi_tl(t0, -1);
8799     else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8800              (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
8801         tcg_gen_movi_tl(t0, -1);
8802     else if (u == 0) {
8803         switch (rt) {
8804         case 1:
8805             switch (sel) {
8806             case 1:
8807                 gen_helper_mftc0_vpecontrol(t0, cpu_env);
8808                 break;
8809             case 2:
8810                 gen_helper_mftc0_vpeconf0(t0, cpu_env);
8811                 break;
8812             default:
8813                 goto die;
8814                 break;
8815             }
8816             break;
8817         case 2:
8818             switch (sel) {
8819             case 1:
8820                 gen_helper_mftc0_tcstatus(t0, cpu_env);
8821                 break;
8822             case 2:
8823                 gen_helper_mftc0_tcbind(t0, cpu_env);
8824                 break;
8825             case 3:
8826                 gen_helper_mftc0_tcrestart(t0, cpu_env);
8827                 break;
8828             case 4:
8829                 gen_helper_mftc0_tchalt(t0, cpu_env);
8830                 break;
8831             case 5:
8832                 gen_helper_mftc0_tccontext(t0, cpu_env);
8833                 break;
8834             case 6:
8835                 gen_helper_mftc0_tcschedule(t0, cpu_env);
8836                 break;
8837             case 7:
8838                 gen_helper_mftc0_tcschefback(t0, cpu_env);
8839                 break;
8840             default:
8841                 gen_mfc0(ctx, t0, rt, sel);
8842                 break;
8843             }
8844             break;
8845         case 10:
8846             switch (sel) {
8847             case 0:
8848                 gen_helper_mftc0_entryhi(t0, cpu_env);
8849                 break;
8850             default:
8851                 gen_mfc0(ctx, t0, rt, sel);
8852                 break;
8853             }
8854         case 12:
8855             switch (sel) {
8856             case 0:
8857                 gen_helper_mftc0_status(t0, cpu_env);
8858                 break;
8859             default:
8860                 gen_mfc0(ctx, t0, rt, sel);
8861                 break;
8862             }
8863         case 13:
8864             switch (sel) {
8865             case 0:
8866                 gen_helper_mftc0_cause(t0, cpu_env);
8867                 break;
8868             default:
8869                 goto die;
8870                 break;
8871             }
8872             break;
8873         case 14:
8874             switch (sel) {
8875             case 0:
8876                 gen_helper_mftc0_epc(t0, cpu_env);
8877                 break;
8878             default:
8879                 goto die;
8880                 break;
8881             }
8882             break;
8883         case 15:
8884             switch (sel) {
8885             case 1:
8886                 gen_helper_mftc0_ebase(t0, cpu_env);
8887                 break;
8888             default:
8889                 goto die;
8890                 break;
8891             }
8892             break;
8893         case 16:
8894             switch (sel) {
8895             case 0:
8896             case 1:
8897             case 2:
8898             case 3:
8899             case 4:
8900             case 5:
8901             case 6:
8902             case 7:
8903                 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
8904                 break;
8905             default:
8906                 goto die;
8907                 break;
8908             }
8909             break;
8910         case 23:
8911             switch (sel) {
8912             case 0:
8913                 gen_helper_mftc0_debug(t0, cpu_env);
8914                 break;
8915             default:
8916                 gen_mfc0(ctx, t0, rt, sel);
8917                 break;
8918             }
8919             break;
8920         default:
8921             gen_mfc0(ctx, t0, rt, sel);
8922         }
8923     } else switch (sel) {
8924     /* GPR registers. */
8925     case 0:
8926         gen_helper_1e0i(mftgpr, t0, rt);
8927         break;
8928     /* Auxiliary CPU registers */
8929     case 1:
8930         switch (rt) {
8931         case 0:
8932             gen_helper_1e0i(mftlo, t0, 0);
8933             break;
8934         case 1:
8935             gen_helper_1e0i(mfthi, t0, 0);
8936             break;
8937         case 2:
8938             gen_helper_1e0i(mftacx, t0, 0);
8939             break;
8940         case 4:
8941             gen_helper_1e0i(mftlo, t0, 1);
8942             break;
8943         case 5:
8944             gen_helper_1e0i(mfthi, t0, 1);
8945             break;
8946         case 6:
8947             gen_helper_1e0i(mftacx, t0, 1);
8948             break;
8949         case 8:
8950             gen_helper_1e0i(mftlo, t0, 2);
8951             break;
8952         case 9:
8953             gen_helper_1e0i(mfthi, t0, 2);
8954             break;
8955         case 10:
8956             gen_helper_1e0i(mftacx, t0, 2);
8957             break;
8958         case 12:
8959             gen_helper_1e0i(mftlo, t0, 3);
8960             break;
8961         case 13:
8962             gen_helper_1e0i(mfthi, t0, 3);
8963             break;
8964         case 14:
8965             gen_helper_1e0i(mftacx, t0, 3);
8966             break;
8967         case 16:
8968             gen_helper_mftdsp(t0, cpu_env);
8969             break;
8970         default:
8971             goto die;
8972         }
8973         break;
8974     /* Floating point (COP1). */
8975     case 2:
8976         /* XXX: For now we support only a single FPU context. */
8977         if (h == 0) {
8978             TCGv_i32 fp0 = tcg_temp_new_i32();
8979
8980             gen_load_fpr32(ctx, fp0, rt);
8981             tcg_gen_ext_i32_tl(t0, fp0);
8982             tcg_temp_free_i32(fp0);
8983         } else {
8984             TCGv_i32 fp0 = tcg_temp_new_i32();
8985
8986             gen_load_fpr32h(ctx, fp0, rt);
8987             tcg_gen_ext_i32_tl(t0, fp0);
8988             tcg_temp_free_i32(fp0);
8989         }
8990         break;
8991     case 3:
8992         /* XXX: For now we support only a single FPU context. */
8993         gen_helper_1e0i(cfc1, t0, rt);
8994         break;
8995     /* COP2: Not implemented. */
8996     case 4:
8997     case 5:
8998         /* fall through */
8999     default:
9000         goto die;
9001     }
9002     trace_mips_translate_tr("mftr", rt, u, sel, h);
9003     gen_store_gpr(t0, rd);
9004     tcg_temp_free(t0);
9005     return;
9006
9007 die:
9008     tcg_temp_free(t0);
9009     LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
9010     generate_exception_end(ctx, EXCP_RI);
9011 }
9012
9013 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
9014                      int u, int sel, int h)
9015 {
9016     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9017     TCGv t0 = tcg_temp_local_new();
9018
9019     gen_load_gpr(t0, rt);
9020     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9021         ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9022          (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
9023         /* NOP */ ;
9024     else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9025              (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
9026         /* NOP */ ;
9027     else if (u == 0) {
9028         switch (rd) {
9029         case 1:
9030             switch (sel) {
9031             case 1:
9032                 gen_helper_mttc0_vpecontrol(cpu_env, t0);
9033                 break;
9034             case 2:
9035                 gen_helper_mttc0_vpeconf0(cpu_env, t0);
9036                 break;
9037             default:
9038                 goto die;
9039                 break;
9040             }
9041             break;
9042         case 2:
9043             switch (sel) {
9044             case 1:
9045                 gen_helper_mttc0_tcstatus(cpu_env, t0);
9046                 break;
9047             case 2:
9048                 gen_helper_mttc0_tcbind(cpu_env, t0);
9049                 break;
9050             case 3:
9051                 gen_helper_mttc0_tcrestart(cpu_env, t0);
9052                 break;
9053             case 4:
9054                 gen_helper_mttc0_tchalt(cpu_env, t0);
9055                 break;
9056             case 5:
9057                 gen_helper_mttc0_tccontext(cpu_env, t0);
9058                 break;
9059             case 6:
9060                 gen_helper_mttc0_tcschedule(cpu_env, t0);
9061                 break;
9062             case 7:
9063                 gen_helper_mttc0_tcschefback(cpu_env, t0);
9064                 break;
9065             default:
9066                 gen_mtc0(ctx, t0, rd, sel);
9067                 break;
9068             }
9069             break;
9070         case 10:
9071             switch (sel) {
9072             case 0:
9073                 gen_helper_mttc0_entryhi(cpu_env, t0);
9074                 break;
9075             default:
9076                 gen_mtc0(ctx, t0, rd, sel);
9077                 break;
9078             }
9079         case 12:
9080             switch (sel) {
9081             case 0:
9082                 gen_helper_mttc0_status(cpu_env, t0);
9083                 break;
9084             default:
9085                 gen_mtc0(ctx, t0, rd, sel);
9086                 break;
9087             }
9088         case 13:
9089             switch (sel) {
9090             case 0:
9091                 gen_helper_mttc0_cause(cpu_env, t0);
9092                 break;
9093             default:
9094                 goto die;
9095                 break;
9096             }
9097             break;
9098         case 15:
9099             switch (sel) {
9100             case 1:
9101                 gen_helper_mttc0_ebase(cpu_env, t0);
9102                 break;
9103             default:
9104                 goto die;
9105                 break;
9106             }
9107             break;
9108         case 23:
9109             switch (sel) {
9110             case 0:
9111                 gen_helper_mttc0_debug(cpu_env, t0);
9112                 break;
9113             default:
9114                 gen_mtc0(ctx, t0, rd, sel);
9115                 break;
9116             }
9117             break;
9118         default:
9119             gen_mtc0(ctx, t0, rd, sel);
9120         }
9121     } else switch (sel) {
9122     /* GPR registers. */
9123     case 0:
9124         gen_helper_0e1i(mttgpr, t0, rd);
9125         break;
9126     /* Auxiliary CPU registers */
9127     case 1:
9128         switch (rd) {
9129         case 0:
9130             gen_helper_0e1i(mttlo, t0, 0);
9131             break;
9132         case 1:
9133             gen_helper_0e1i(mtthi, t0, 0);
9134             break;
9135         case 2:
9136             gen_helper_0e1i(mttacx, t0, 0);
9137             break;
9138         case 4:
9139             gen_helper_0e1i(mttlo, t0, 1);
9140             break;
9141         case 5:
9142             gen_helper_0e1i(mtthi, t0, 1);
9143             break;
9144         case 6:
9145             gen_helper_0e1i(mttacx, t0, 1);
9146             break;
9147         case 8:
9148             gen_helper_0e1i(mttlo, t0, 2);
9149             break;
9150         case 9:
9151             gen_helper_0e1i(mtthi, t0, 2);
9152             break;
9153         case 10:
9154             gen_helper_0e1i(mttacx, t0, 2);
9155             break;
9156         case 12:
9157             gen_helper_0e1i(mttlo, t0, 3);
9158             break;
9159         case 13:
9160             gen_helper_0e1i(mtthi, t0, 3);
9161             break;
9162         case 14:
9163             gen_helper_0e1i(mttacx, t0, 3);
9164             break;
9165         case 16:
9166             gen_helper_mttdsp(cpu_env, t0);
9167             break;
9168         default:
9169             goto die;
9170         }
9171         break;
9172     /* Floating point (COP1). */
9173     case 2:
9174         /* XXX: For now we support only a single FPU context. */
9175         if (h == 0) {
9176             TCGv_i32 fp0 = tcg_temp_new_i32();
9177
9178             tcg_gen_trunc_tl_i32(fp0, t0);
9179             gen_store_fpr32(ctx, fp0, rd);
9180             tcg_temp_free_i32(fp0);
9181         } else {
9182             TCGv_i32 fp0 = tcg_temp_new_i32();
9183
9184             tcg_gen_trunc_tl_i32(fp0, t0);
9185             gen_store_fpr32h(ctx, fp0, rd);
9186             tcg_temp_free_i32(fp0);
9187         }
9188         break;
9189     case 3:
9190         /* XXX: For now we support only a single FPU context. */
9191         {
9192             TCGv_i32 fs_tmp = tcg_const_i32(rd);
9193
9194             gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
9195             tcg_temp_free_i32(fs_tmp);
9196         }
9197         /* Stop translation as we may have changed hflags */
9198         ctx->base.is_jmp = DISAS_STOP;
9199         break;
9200     /* COP2: Not implemented. */
9201     case 4:
9202     case 5:
9203         /* fall through */
9204     default:
9205         goto die;
9206     }
9207     trace_mips_translate_tr("mttr", rd, u, sel, h);
9208     tcg_temp_free(t0);
9209     return;
9210
9211 die:
9212     tcg_temp_free(t0);
9213     LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
9214     generate_exception_end(ctx, EXCP_RI);
9215 }
9216
9217 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
9218 {
9219     const char *opn = "ldst";
9220
9221     check_cp0_enabled(ctx);
9222     switch (opc) {
9223     case OPC_MFC0:
9224         if (rt == 0) {
9225             /* Treat as NOP. */
9226             return;
9227         }
9228         gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9229         opn = "mfc0";
9230         break;
9231     case OPC_MTC0:
9232         {
9233             TCGv t0 = tcg_temp_new();
9234
9235             gen_load_gpr(t0, rt);
9236             gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
9237             tcg_temp_free(t0);
9238         }
9239         opn = "mtc0";
9240         break;
9241 #if defined(TARGET_MIPS64)
9242     case OPC_DMFC0:
9243         check_insn(ctx, ISA_MIPS3);
9244         if (rt == 0) {
9245             /* Treat as NOP. */
9246             return;
9247         }
9248         gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9249         opn = "dmfc0";
9250         break;
9251     case OPC_DMTC0:
9252         check_insn(ctx, ISA_MIPS3);
9253         {
9254             TCGv t0 = tcg_temp_new();
9255
9256             gen_load_gpr(t0, rt);
9257             gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
9258             tcg_temp_free(t0);
9259         }
9260         opn = "dmtc0";
9261         break;
9262 #endif
9263     case OPC_MFHC0:
9264         check_mvh(ctx);
9265         if (rt == 0) {
9266             /* Treat as NOP. */
9267             return;
9268         }
9269         gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9270         opn = "mfhc0";
9271         break;
9272     case OPC_MTHC0:
9273         check_mvh(ctx);
9274         {
9275             TCGv t0 = tcg_temp_new();
9276             gen_load_gpr(t0, rt);
9277             gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
9278             tcg_temp_free(t0);
9279         }
9280         opn = "mthc0";
9281         break;
9282     case OPC_MFTR:
9283         check_cp0_enabled(ctx);
9284         if (rd == 0) {
9285             /* Treat as NOP. */
9286             return;
9287         }
9288         gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
9289                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9290         opn = "mftr";
9291         break;
9292     case OPC_MTTR:
9293         check_cp0_enabled(ctx);
9294         gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
9295                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9296         opn = "mttr";
9297         break;
9298     case OPC_TLBWI:
9299         opn = "tlbwi";
9300         if (!env->tlb->helper_tlbwi)
9301             goto die;
9302         gen_helper_tlbwi(cpu_env);
9303         break;
9304     case OPC_TLBINV:
9305         opn = "tlbinv";
9306         if (ctx->ie >= 2) {
9307             if (!env->tlb->helper_tlbinv) {
9308                 goto die;
9309             }
9310             gen_helper_tlbinv(cpu_env);
9311         } /* treat as nop if TLBINV not supported */
9312         break;
9313     case OPC_TLBINVF:
9314         opn = "tlbinvf";
9315         if (ctx->ie >= 2) {
9316             if (!env->tlb->helper_tlbinvf) {
9317                 goto die;
9318             }
9319             gen_helper_tlbinvf(cpu_env);
9320         } /* treat as nop if TLBINV not supported */
9321         break;
9322     case OPC_TLBWR:
9323         opn = "tlbwr";
9324         if (!env->tlb->helper_tlbwr)
9325             goto die;
9326         gen_helper_tlbwr(cpu_env);
9327         break;
9328     case OPC_TLBP:
9329         opn = "tlbp";
9330         if (!env->tlb->helper_tlbp)
9331             goto die;
9332         gen_helper_tlbp(cpu_env);
9333         break;
9334     case OPC_TLBR:
9335         opn = "tlbr";
9336         if (!env->tlb->helper_tlbr)
9337             goto die;
9338         gen_helper_tlbr(cpu_env);
9339         break;
9340     case OPC_ERET: /* OPC_ERETNC */
9341         if ((ctx->insn_flags & ISA_MIPS32R6) &&
9342             (ctx->hflags & MIPS_HFLAG_BMASK)) {
9343             goto die;
9344         } else {
9345             int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
9346             if (ctx->opcode & (1 << bit_shift)) {
9347                 /* OPC_ERETNC */
9348                 opn = "eretnc";
9349                 check_insn(ctx, ISA_MIPS32R5);
9350                 gen_helper_eretnc(cpu_env);
9351             } else {
9352                 /* OPC_ERET */
9353                 opn = "eret";
9354                 check_insn(ctx, ISA_MIPS2);
9355                 gen_helper_eret(cpu_env);
9356             }
9357             ctx->base.is_jmp = DISAS_EXIT;
9358         }
9359         break;
9360     case OPC_DERET:
9361         opn = "deret";
9362         check_insn(ctx, ISA_MIPS32);
9363         if ((ctx->insn_flags & ISA_MIPS32R6) &&
9364             (ctx->hflags & MIPS_HFLAG_BMASK)) {
9365             goto die;
9366         }
9367         if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9368             MIPS_INVAL(opn);
9369             generate_exception_end(ctx, EXCP_RI);
9370         } else {
9371             gen_helper_deret(cpu_env);
9372             ctx->base.is_jmp = DISAS_EXIT;
9373         }
9374         break;
9375     case OPC_WAIT:
9376         opn = "wait";
9377         check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
9378         if ((ctx->insn_flags & ISA_MIPS32R6) &&
9379             (ctx->hflags & MIPS_HFLAG_BMASK)) {
9380             goto die;
9381         }
9382         /* If we get an exception, we want to restart at next instruction */
9383         ctx->base.pc_next += 4;
9384         save_cpu_state(ctx, 1);
9385         ctx->base.pc_next -= 4;
9386         gen_helper_wait(cpu_env);
9387         ctx->base.is_jmp = DISAS_NORETURN;
9388         break;
9389     default:
9390  die:
9391         MIPS_INVAL(opn);
9392         generate_exception_end(ctx, EXCP_RI);
9393         return;
9394     }
9395     (void)opn; /* avoid a compiler warning */
9396 }
9397 #endif /* !CONFIG_USER_ONLY */
9398
9399 /* CP1 Branches (before delay slot) */
9400 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
9401                                 int32_t cc, int32_t offset)
9402 {
9403     target_ulong btarget;
9404     TCGv_i32 t0 = tcg_temp_new_i32();
9405
9406     if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9407         generate_exception_end(ctx, EXCP_RI);
9408         goto out;
9409     }
9410
9411     if (cc != 0)
9412         check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
9413
9414     btarget = ctx->base.pc_next + 4 + offset;
9415
9416     switch (op) {
9417     case OPC_BC1F:
9418         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9419         tcg_gen_not_i32(t0, t0);
9420         tcg_gen_andi_i32(t0, t0, 1);
9421         tcg_gen_extu_i32_tl(bcond, t0);
9422         goto not_likely;
9423     case OPC_BC1FL:
9424         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9425         tcg_gen_not_i32(t0, t0);
9426         tcg_gen_andi_i32(t0, t0, 1);
9427         tcg_gen_extu_i32_tl(bcond, t0);
9428         goto likely;
9429     case OPC_BC1T:
9430         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9431         tcg_gen_andi_i32(t0, t0, 1);
9432         tcg_gen_extu_i32_tl(bcond, t0);
9433         goto not_likely;
9434     case OPC_BC1TL:
9435         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9436         tcg_gen_andi_i32(t0, t0, 1);
9437         tcg_gen_extu_i32_tl(bcond, t0);
9438     likely:
9439         ctx->hflags |= MIPS_HFLAG_BL;
9440         break;
9441     case OPC_BC1FANY2:
9442         {
9443             TCGv_i32 t1 = tcg_temp_new_i32();
9444             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9445             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
9446             tcg_gen_nand_i32(t0, t0, t1);
9447             tcg_temp_free_i32(t1);
9448             tcg_gen_andi_i32(t0, t0, 1);
9449             tcg_gen_extu_i32_tl(bcond, t0);
9450         }
9451         goto not_likely;
9452     case OPC_BC1TANY2:
9453         {
9454             TCGv_i32 t1 = tcg_temp_new_i32();
9455             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9456             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
9457             tcg_gen_or_i32(t0, t0, t1);
9458             tcg_temp_free_i32(t1);
9459             tcg_gen_andi_i32(t0, t0, 1);
9460             tcg_gen_extu_i32_tl(bcond, t0);
9461         }
9462         goto not_likely;
9463     case OPC_BC1FANY4:
9464         {
9465             TCGv_i32 t1 = tcg_temp_new_i32();
9466             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9467             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
9468             tcg_gen_and_i32(t0, t0, t1);
9469             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
9470             tcg_gen_and_i32(t0, t0, t1);
9471             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
9472             tcg_gen_nand_i32(t0, t0, t1);
9473             tcg_temp_free_i32(t1);
9474             tcg_gen_andi_i32(t0, t0, 1);
9475             tcg_gen_extu_i32_tl(bcond, t0);
9476         }
9477         goto not_likely;
9478     case OPC_BC1TANY4:
9479         {
9480             TCGv_i32 t1 = tcg_temp_new_i32();
9481             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9482             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
9483             tcg_gen_or_i32(t0, t0, t1);
9484             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
9485             tcg_gen_or_i32(t0, t0, t1);
9486             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
9487             tcg_gen_or_i32(t0, t0, t1);
9488             tcg_temp_free_i32(t1);
9489             tcg_gen_andi_i32(t0, t0, 1);
9490             tcg_gen_extu_i32_tl(bcond, t0);
9491         }
9492     not_likely:
9493         ctx->hflags |= MIPS_HFLAG_BC;
9494         break;
9495     default:
9496         MIPS_INVAL("cp1 cond branch");
9497         generate_exception_end(ctx, EXCP_RI);
9498         goto out;
9499     }
9500     ctx->btarget = btarget;
9501     ctx->hflags |= MIPS_HFLAG_BDS32;
9502  out:
9503     tcg_temp_free_i32(t0);
9504 }
9505
9506 /* R6 CP1 Branches */
9507 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
9508                                    int32_t ft, int32_t offset,
9509                                    int delayslot_size)
9510 {
9511     target_ulong btarget;
9512     TCGv_i64 t0 = tcg_temp_new_i64();
9513
9514     if (ctx->hflags & MIPS_HFLAG_BMASK) {
9515 #ifdef MIPS_DEBUG_DISAS
9516         LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
9517                   "\n", ctx->base.pc_next);
9518 #endif
9519         generate_exception_end(ctx, EXCP_RI);
9520         goto out;
9521     }
9522
9523     gen_load_fpr64(ctx, t0, ft);
9524     tcg_gen_andi_i64(t0, t0, 1);
9525
9526     btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
9527
9528     switch (op) {
9529     case OPC_BC1EQZ:
9530         tcg_gen_xori_i64(t0, t0, 1);
9531         ctx->hflags |= MIPS_HFLAG_BC;
9532         break;
9533     case OPC_BC1NEZ:
9534         /* t0 already set */
9535         ctx->hflags |= MIPS_HFLAG_BC;
9536         break;
9537     default:
9538         MIPS_INVAL("cp1 cond branch");
9539         generate_exception_end(ctx, EXCP_RI);
9540         goto out;
9541     }
9542
9543     tcg_gen_trunc_i64_tl(bcond, t0);
9544
9545     ctx->btarget = btarget;
9546
9547     switch (delayslot_size) {
9548     case 2:
9549         ctx->hflags |= MIPS_HFLAG_BDS16;
9550         break;
9551     case 4:
9552         ctx->hflags |= MIPS_HFLAG_BDS32;
9553         break;
9554     }
9555
9556 out:
9557     tcg_temp_free_i64(t0);
9558 }
9559
9560 /* Coprocessor 1 (FPU) */
9561
9562 #define FOP(func, fmt) (((fmt) << 21) | (func))
9563
9564 enum fopcode {
9565     OPC_ADD_S = FOP(0, FMT_S),
9566     OPC_SUB_S = FOP(1, FMT_S),
9567     OPC_MUL_S = FOP(2, FMT_S),
9568     OPC_DIV_S = FOP(3, FMT_S),
9569     OPC_SQRT_S = FOP(4, FMT_S),
9570     OPC_ABS_S = FOP(5, FMT_S),
9571     OPC_MOV_S = FOP(6, FMT_S),
9572     OPC_NEG_S = FOP(7, FMT_S),
9573     OPC_ROUND_L_S = FOP(8, FMT_S),
9574     OPC_TRUNC_L_S = FOP(9, FMT_S),
9575     OPC_CEIL_L_S = FOP(10, FMT_S),
9576     OPC_FLOOR_L_S = FOP(11, FMT_S),
9577     OPC_ROUND_W_S = FOP(12, FMT_S),
9578     OPC_TRUNC_W_S = FOP(13, FMT_S),
9579     OPC_CEIL_W_S = FOP(14, FMT_S),
9580     OPC_FLOOR_W_S = FOP(15, FMT_S),
9581     OPC_SEL_S = FOP(16, FMT_S),
9582     OPC_MOVCF_S = FOP(17, FMT_S),
9583     OPC_MOVZ_S = FOP(18, FMT_S),
9584     OPC_MOVN_S = FOP(19, FMT_S),
9585     OPC_SELEQZ_S = FOP(20, FMT_S),
9586     OPC_RECIP_S = FOP(21, FMT_S),
9587     OPC_RSQRT_S = FOP(22, FMT_S),
9588     OPC_SELNEZ_S = FOP(23, FMT_S),
9589     OPC_MADDF_S = FOP(24, FMT_S),
9590     OPC_MSUBF_S = FOP(25, FMT_S),
9591     OPC_RINT_S = FOP(26, FMT_S),
9592     OPC_CLASS_S = FOP(27, FMT_S),
9593     OPC_MIN_S = FOP(28, FMT_S),
9594     OPC_RECIP2_S = FOP(28, FMT_S),
9595     OPC_MINA_S = FOP(29, FMT_S),
9596     OPC_RECIP1_S = FOP(29, FMT_S),
9597     OPC_MAX_S = FOP(30, FMT_S),
9598     OPC_RSQRT1_S = FOP(30, FMT_S),
9599     OPC_MAXA_S = FOP(31, FMT_S),
9600     OPC_RSQRT2_S = FOP(31, FMT_S),
9601     OPC_CVT_D_S = FOP(33, FMT_S),
9602     OPC_CVT_W_S = FOP(36, FMT_S),
9603     OPC_CVT_L_S = FOP(37, FMT_S),
9604     OPC_CVT_PS_S = FOP(38, FMT_S),
9605     OPC_CMP_F_S = FOP (48, FMT_S),
9606     OPC_CMP_UN_S = FOP (49, FMT_S),
9607     OPC_CMP_EQ_S = FOP (50, FMT_S),
9608     OPC_CMP_UEQ_S = FOP (51, FMT_S),
9609     OPC_CMP_OLT_S = FOP (52, FMT_S),
9610     OPC_CMP_ULT_S = FOP (53, FMT_S),
9611     OPC_CMP_OLE_S = FOP (54, FMT_S),
9612     OPC_CMP_ULE_S = FOP (55, FMT_S),
9613     OPC_CMP_SF_S = FOP (56, FMT_S),
9614     OPC_CMP_NGLE_S = FOP (57, FMT_S),
9615     OPC_CMP_SEQ_S = FOP (58, FMT_S),
9616     OPC_CMP_NGL_S = FOP (59, FMT_S),
9617     OPC_CMP_LT_S = FOP (60, FMT_S),
9618     OPC_CMP_NGE_S = FOP (61, FMT_S),
9619     OPC_CMP_LE_S = FOP (62, FMT_S),
9620     OPC_CMP_NGT_S = FOP (63, FMT_S),
9621
9622     OPC_ADD_D = FOP(0, FMT_D),
9623     OPC_SUB_D = FOP(1, FMT_D),
9624     OPC_MUL_D = FOP(2, FMT_D),
9625     OPC_DIV_D = FOP(3, FMT_D),
9626     OPC_SQRT_D = FOP(4, FMT_D),
9627     OPC_ABS_D = FOP(5, FMT_D),
9628     OPC_MOV_D = FOP(6, FMT_D),
9629     OPC_NEG_D = FOP(7, FMT_D),
9630     OPC_ROUND_L_D = FOP(8, FMT_D),
9631     OPC_TRUNC_L_D = FOP(9, FMT_D),
9632     OPC_CEIL_L_D = FOP(10, FMT_D),
9633     OPC_FLOOR_L_D = FOP(11, FMT_D),
9634     OPC_ROUND_W_D = FOP(12, FMT_D),
9635     OPC_TRUNC_W_D = FOP(13, FMT_D),
9636     OPC_CEIL_W_D = FOP(14, FMT_D),
9637     OPC_FLOOR_W_D = FOP(15, FMT_D),
9638     OPC_SEL_D = FOP(16, FMT_D),
9639     OPC_MOVCF_D = FOP(17, FMT_D),
9640     OPC_MOVZ_D = FOP(18, FMT_D),
9641     OPC_MOVN_D = FOP(19, FMT_D),
9642     OPC_SELEQZ_D = FOP(20, FMT_D),
9643     OPC_RECIP_D = FOP(21, FMT_D),
9644     OPC_RSQRT_D = FOP(22, FMT_D),
9645     OPC_SELNEZ_D = FOP(23, FMT_D),
9646     OPC_MADDF_D = FOP(24, FMT_D),
9647     OPC_MSUBF_D = FOP(25, FMT_D),
9648     OPC_RINT_D = FOP(26, FMT_D),
9649     OPC_CLASS_D = FOP(27, FMT_D),
9650     OPC_MIN_D = FOP(28, FMT_D),
9651     OPC_RECIP2_D = FOP(28, FMT_D),
9652     OPC_MINA_D = FOP(29, FMT_D),
9653     OPC_RECIP1_D = FOP(29, FMT_D),
9654     OPC_MAX_D = FOP(30, FMT_D),
9655     OPC_RSQRT1_D = FOP(30, FMT_D),
9656     OPC_MAXA_D = FOP(31, FMT_D),
9657     OPC_RSQRT2_D = FOP(31, FMT_D),
9658     OPC_CVT_S_D = FOP(32, FMT_D),
9659     OPC_CVT_W_D = FOP(36, FMT_D),
9660     OPC_CVT_L_D = FOP(37, FMT_D),
9661     OPC_CMP_F_D = FOP (48, FMT_D),
9662     OPC_CMP_UN_D = FOP (49, FMT_D),
9663     OPC_CMP_EQ_D = FOP (50, FMT_D),
9664     OPC_CMP_UEQ_D = FOP (51, FMT_D),
9665     OPC_CMP_OLT_D = FOP (52, FMT_D),
9666     OPC_CMP_ULT_D = FOP (53, FMT_D),
9667     OPC_CMP_OLE_D = FOP (54, FMT_D),
9668     OPC_CMP_ULE_D = FOP (55, FMT_D),
9669     OPC_CMP_SF_D = FOP (56, FMT_D),
9670     OPC_CMP_NGLE_D = FOP (57, FMT_D),
9671     OPC_CMP_SEQ_D = FOP (58, FMT_D),
9672     OPC_CMP_NGL_D = FOP (59, FMT_D),
9673     OPC_CMP_LT_D = FOP (60, FMT_D),
9674     OPC_CMP_NGE_D = FOP (61, FMT_D),
9675     OPC_CMP_LE_D = FOP (62, FMT_D),
9676     OPC_CMP_NGT_D = FOP (63, FMT_D),
9677
9678     OPC_CVT_S_W = FOP(32, FMT_W),
9679     OPC_CVT_D_W = FOP(33, FMT_W),
9680     OPC_CVT_S_L = FOP(32, FMT_L),
9681     OPC_CVT_D_L = FOP(33, FMT_L),
9682     OPC_CVT_PS_PW = FOP(38, FMT_W),
9683
9684     OPC_ADD_PS = FOP(0, FMT_PS),
9685     OPC_SUB_PS = FOP(1, FMT_PS),
9686     OPC_MUL_PS = FOP(2, FMT_PS),
9687     OPC_DIV_PS = FOP(3, FMT_PS),
9688     OPC_ABS_PS = FOP(5, FMT_PS),
9689     OPC_MOV_PS = FOP(6, FMT_PS),
9690     OPC_NEG_PS = FOP(7, FMT_PS),
9691     OPC_MOVCF_PS = FOP(17, FMT_PS),
9692     OPC_MOVZ_PS = FOP(18, FMT_PS),
9693     OPC_MOVN_PS = FOP(19, FMT_PS),
9694     OPC_ADDR_PS = FOP(24, FMT_PS),
9695     OPC_MULR_PS = FOP(26, FMT_PS),
9696     OPC_RECIP2_PS = FOP(28, FMT_PS),
9697     OPC_RECIP1_PS = FOP(29, FMT_PS),
9698     OPC_RSQRT1_PS = FOP(30, FMT_PS),
9699     OPC_RSQRT2_PS = FOP(31, FMT_PS),
9700
9701     OPC_CVT_S_PU = FOP(32, FMT_PS),
9702     OPC_CVT_PW_PS = FOP(36, FMT_PS),
9703     OPC_CVT_S_PL = FOP(40, FMT_PS),
9704     OPC_PLL_PS = FOP(44, FMT_PS),
9705     OPC_PLU_PS = FOP(45, FMT_PS),
9706     OPC_PUL_PS = FOP(46, FMT_PS),
9707     OPC_PUU_PS = FOP(47, FMT_PS),
9708     OPC_CMP_F_PS = FOP (48, FMT_PS),
9709     OPC_CMP_UN_PS = FOP (49, FMT_PS),
9710     OPC_CMP_EQ_PS = FOP (50, FMT_PS),
9711     OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
9712     OPC_CMP_OLT_PS = FOP (52, FMT_PS),
9713     OPC_CMP_ULT_PS = FOP (53, FMT_PS),
9714     OPC_CMP_OLE_PS = FOP (54, FMT_PS),
9715     OPC_CMP_ULE_PS = FOP (55, FMT_PS),
9716     OPC_CMP_SF_PS = FOP (56, FMT_PS),
9717     OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
9718     OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
9719     OPC_CMP_NGL_PS = FOP (59, FMT_PS),
9720     OPC_CMP_LT_PS = FOP (60, FMT_PS),
9721     OPC_CMP_NGE_PS = FOP (61, FMT_PS),
9722     OPC_CMP_LE_PS = FOP (62, FMT_PS),
9723     OPC_CMP_NGT_PS = FOP (63, FMT_PS),
9724 };
9725
9726 enum r6_f_cmp_op {
9727     R6_OPC_CMP_AF_S   = FOP(0, FMT_W),
9728     R6_OPC_CMP_UN_S   = FOP(1, FMT_W),
9729     R6_OPC_CMP_EQ_S   = FOP(2, FMT_W),
9730     R6_OPC_CMP_UEQ_S  = FOP(3, FMT_W),
9731     R6_OPC_CMP_LT_S   = FOP(4, FMT_W),
9732     R6_OPC_CMP_ULT_S  = FOP(5, FMT_W),
9733     R6_OPC_CMP_LE_S   = FOP(6, FMT_W),
9734     R6_OPC_CMP_ULE_S  = FOP(7, FMT_W),
9735     R6_OPC_CMP_SAF_S  = FOP(8, FMT_W),
9736     R6_OPC_CMP_SUN_S  = FOP(9, FMT_W),
9737     R6_OPC_CMP_SEQ_S  = FOP(10, FMT_W),
9738     R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
9739     R6_OPC_CMP_SLT_S  = FOP(12, FMT_W),
9740     R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
9741     R6_OPC_CMP_SLE_S  = FOP(14, FMT_W),
9742     R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
9743     R6_OPC_CMP_OR_S   = FOP(17, FMT_W),
9744     R6_OPC_CMP_UNE_S  = FOP(18, FMT_W),
9745     R6_OPC_CMP_NE_S   = FOP(19, FMT_W),
9746     R6_OPC_CMP_SOR_S  = FOP(25, FMT_W),
9747     R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
9748     R6_OPC_CMP_SNE_S  = FOP(27, FMT_W),
9749
9750     R6_OPC_CMP_AF_D   = FOP(0, FMT_L),
9751     R6_OPC_CMP_UN_D   = FOP(1, FMT_L),
9752     R6_OPC_CMP_EQ_D   = FOP(2, FMT_L),
9753     R6_OPC_CMP_UEQ_D  = FOP(3, FMT_L),
9754     R6_OPC_CMP_LT_D   = FOP(4, FMT_L),
9755     R6_OPC_CMP_ULT_D  = FOP(5, FMT_L),
9756     R6_OPC_CMP_LE_D   = FOP(6, FMT_L),
9757     R6_OPC_CMP_ULE_D  = FOP(7, FMT_L),
9758     R6_OPC_CMP_SAF_D  = FOP(8, FMT_L),
9759     R6_OPC_CMP_SUN_D  = FOP(9, FMT_L),
9760     R6_OPC_CMP_SEQ_D  = FOP(10, FMT_L),
9761     R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
9762     R6_OPC_CMP_SLT_D  = FOP(12, FMT_L),
9763     R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
9764     R6_OPC_CMP_SLE_D  = FOP(14, FMT_L),
9765     R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
9766     R6_OPC_CMP_OR_D   = FOP(17, FMT_L),
9767     R6_OPC_CMP_UNE_D  = FOP(18, FMT_L),
9768     R6_OPC_CMP_NE_D   = FOP(19, FMT_L),
9769     R6_OPC_CMP_SOR_D  = FOP(25, FMT_L),
9770     R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
9771     R6_OPC_CMP_SNE_D  = FOP(27, FMT_L),
9772 };
9773 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
9774 {
9775     TCGv t0 = tcg_temp_new();
9776
9777     switch (opc) {
9778     case OPC_MFC1:
9779         {
9780             TCGv_i32 fp0 = tcg_temp_new_i32();
9781
9782             gen_load_fpr32(ctx, fp0, fs);
9783             tcg_gen_ext_i32_tl(t0, fp0);
9784             tcg_temp_free_i32(fp0);
9785         }
9786         gen_store_gpr(t0, rt);
9787         break;
9788     case OPC_MTC1:
9789         gen_load_gpr(t0, rt);
9790         {
9791             TCGv_i32 fp0 = tcg_temp_new_i32();
9792
9793             tcg_gen_trunc_tl_i32(fp0, t0);
9794             gen_store_fpr32(ctx, fp0, fs);
9795             tcg_temp_free_i32(fp0);
9796         }
9797         break;
9798     case OPC_CFC1:
9799         gen_helper_1e0i(cfc1, t0, fs);
9800         gen_store_gpr(t0, rt);
9801         break;
9802     case OPC_CTC1:
9803         gen_load_gpr(t0, rt);
9804         save_cpu_state(ctx, 0);
9805         {
9806             TCGv_i32 fs_tmp = tcg_const_i32(fs);
9807
9808             gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
9809             tcg_temp_free_i32(fs_tmp);
9810         }
9811         /* Stop translation as we may have changed hflags */
9812         ctx->base.is_jmp = DISAS_STOP;
9813         break;
9814 #if defined(TARGET_MIPS64)
9815     case OPC_DMFC1:
9816         gen_load_fpr64(ctx, t0, fs);
9817         gen_store_gpr(t0, rt);
9818         break;
9819     case OPC_DMTC1:
9820         gen_load_gpr(t0, rt);
9821         gen_store_fpr64(ctx, t0, fs);
9822         break;
9823 #endif
9824     case OPC_MFHC1:
9825         {
9826             TCGv_i32 fp0 = tcg_temp_new_i32();
9827
9828             gen_load_fpr32h(ctx, fp0, fs);
9829             tcg_gen_ext_i32_tl(t0, fp0);
9830             tcg_temp_free_i32(fp0);
9831         }
9832         gen_store_gpr(t0, rt);
9833         break;
9834     case OPC_MTHC1:
9835         gen_load_gpr(t0, rt);
9836         {
9837             TCGv_i32 fp0 = tcg_temp_new_i32();
9838
9839             tcg_gen_trunc_tl_i32(fp0, t0);
9840             gen_store_fpr32h(ctx, fp0, fs);
9841             tcg_temp_free_i32(fp0);
9842         }
9843         break;
9844     default:
9845         MIPS_INVAL("cp1 move");
9846         generate_exception_end(ctx, EXCP_RI);
9847         goto out;
9848     }
9849
9850  out:
9851     tcg_temp_free(t0);
9852 }
9853
9854 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
9855 {
9856     TCGLabel *l1;
9857     TCGCond cond;
9858     TCGv_i32 t0;
9859
9860     if (rd == 0) {
9861         /* Treat as NOP. */
9862         return;
9863     }
9864
9865     if (tf)
9866         cond = TCG_COND_EQ;
9867     else
9868         cond = TCG_COND_NE;
9869
9870     l1 = gen_new_label();
9871     t0 = tcg_temp_new_i32();
9872     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9873     tcg_gen_brcondi_i32(cond, t0, 0, l1);
9874     tcg_temp_free_i32(t0);
9875     if (rs == 0) {
9876         tcg_gen_movi_tl(cpu_gpr[rd], 0);
9877     } else {
9878         tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
9879     }
9880     gen_set_label(l1);
9881 }
9882
9883 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
9884                                int tf)
9885 {
9886     int cond;
9887     TCGv_i32 t0 = tcg_temp_new_i32();
9888     TCGLabel *l1 = gen_new_label();
9889
9890     if (tf)
9891         cond = TCG_COND_EQ;
9892     else
9893         cond = TCG_COND_NE;
9894
9895     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9896     tcg_gen_brcondi_i32(cond, t0, 0, l1);
9897     gen_load_fpr32(ctx, t0, fs);
9898     gen_store_fpr32(ctx, t0, fd);
9899     gen_set_label(l1);
9900     tcg_temp_free_i32(t0);
9901 }
9902
9903 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
9904 {
9905     int cond;
9906     TCGv_i32 t0 = tcg_temp_new_i32();
9907     TCGv_i64 fp0;
9908     TCGLabel *l1 = gen_new_label();
9909
9910     if (tf)
9911         cond = TCG_COND_EQ;
9912     else
9913         cond = TCG_COND_NE;
9914
9915     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9916     tcg_gen_brcondi_i32(cond, t0, 0, l1);
9917     tcg_temp_free_i32(t0);
9918     fp0 = tcg_temp_new_i64();
9919     gen_load_fpr64(ctx, fp0, fs);
9920     gen_store_fpr64(ctx, fp0, fd);
9921     tcg_temp_free_i64(fp0);
9922     gen_set_label(l1);
9923 }
9924
9925 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
9926                                 int cc, int tf)
9927 {
9928     int cond;
9929     TCGv_i32 t0 = tcg_temp_new_i32();
9930     TCGLabel *l1 = gen_new_label();
9931     TCGLabel *l2 = gen_new_label();
9932
9933     if (tf)
9934         cond = TCG_COND_EQ;
9935     else
9936         cond = TCG_COND_NE;
9937
9938     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9939     tcg_gen_brcondi_i32(cond, t0, 0, l1);
9940     gen_load_fpr32(ctx, t0, fs);
9941     gen_store_fpr32(ctx, t0, fd);
9942     gen_set_label(l1);
9943
9944     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
9945     tcg_gen_brcondi_i32(cond, t0, 0, l2);
9946     gen_load_fpr32h(ctx, t0, fs);
9947     gen_store_fpr32h(ctx, t0, fd);
9948     tcg_temp_free_i32(t0);
9949     gen_set_label(l2);
9950 }
9951
9952 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9953                       int fs)
9954 {
9955     TCGv_i32 t1 = tcg_const_i32(0);
9956     TCGv_i32 fp0 = tcg_temp_new_i32();
9957     TCGv_i32 fp1 = tcg_temp_new_i32();
9958     TCGv_i32 fp2 = tcg_temp_new_i32();
9959     gen_load_fpr32(ctx, fp0, fd);
9960     gen_load_fpr32(ctx, fp1, ft);
9961     gen_load_fpr32(ctx, fp2, fs);
9962
9963     switch (op1) {
9964     case OPC_SEL_S:
9965         tcg_gen_andi_i32(fp0, fp0, 1);
9966         tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9967         break;
9968     case OPC_SELEQZ_S:
9969         tcg_gen_andi_i32(fp1, fp1, 1);
9970         tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9971         break;
9972     case OPC_SELNEZ_S:
9973         tcg_gen_andi_i32(fp1, fp1, 1);
9974         tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9975         break;
9976     default:
9977         MIPS_INVAL("gen_sel_s");
9978         generate_exception_end(ctx, EXCP_RI);
9979         break;
9980     }
9981
9982     gen_store_fpr32(ctx, fp0, fd);
9983     tcg_temp_free_i32(fp2);
9984     tcg_temp_free_i32(fp1);
9985     tcg_temp_free_i32(fp0);
9986     tcg_temp_free_i32(t1);
9987 }
9988
9989 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9990                       int fs)
9991 {
9992     TCGv_i64 t1 = tcg_const_i64(0);
9993     TCGv_i64 fp0 = tcg_temp_new_i64();
9994     TCGv_i64 fp1 = tcg_temp_new_i64();
9995     TCGv_i64 fp2 = tcg_temp_new_i64();
9996     gen_load_fpr64(ctx, fp0, fd);
9997     gen_load_fpr64(ctx, fp1, ft);
9998     gen_load_fpr64(ctx, fp2, fs);
9999
10000     switch (op1) {
10001     case OPC_SEL_D:
10002         tcg_gen_andi_i64(fp0, fp0, 1);
10003         tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10004         break;
10005     case OPC_SELEQZ_D:
10006         tcg_gen_andi_i64(fp1, fp1, 1);
10007         tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10008         break;
10009     case OPC_SELNEZ_D:
10010         tcg_gen_andi_i64(fp1, fp1, 1);
10011         tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10012         break;
10013     default:
10014         MIPS_INVAL("gen_sel_d");
10015         generate_exception_end(ctx, EXCP_RI);
10016         break;
10017     }
10018
10019     gen_store_fpr64(ctx, fp0, fd);
10020     tcg_temp_free_i64(fp2);
10021     tcg_temp_free_i64(fp1);
10022     tcg_temp_free_i64(fp0);
10023     tcg_temp_free_i64(t1);
10024 }
10025
10026 static void gen_farith (DisasContext *ctx, enum fopcode op1,
10027                         int ft, int fs, int fd, int cc)
10028 {
10029     uint32_t func = ctx->opcode & 0x3f;
10030     switch (op1) {
10031     case OPC_ADD_S:
10032         {
10033             TCGv_i32 fp0 = tcg_temp_new_i32();
10034             TCGv_i32 fp1 = tcg_temp_new_i32();
10035
10036             gen_load_fpr32(ctx, fp0, fs);
10037             gen_load_fpr32(ctx, fp1, ft);
10038             gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
10039             tcg_temp_free_i32(fp1);
10040             gen_store_fpr32(ctx, fp0, fd);
10041             tcg_temp_free_i32(fp0);
10042         }
10043         break;
10044     case OPC_SUB_S:
10045         {
10046             TCGv_i32 fp0 = tcg_temp_new_i32();
10047             TCGv_i32 fp1 = tcg_temp_new_i32();
10048
10049             gen_load_fpr32(ctx, fp0, fs);
10050             gen_load_fpr32(ctx, fp1, ft);
10051             gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
10052             tcg_temp_free_i32(fp1);
10053             gen_store_fpr32(ctx, fp0, fd);
10054             tcg_temp_free_i32(fp0);
10055         }
10056         break;
10057     case OPC_MUL_S:
10058         {
10059             TCGv_i32 fp0 = tcg_temp_new_i32();
10060             TCGv_i32 fp1 = tcg_temp_new_i32();
10061
10062             gen_load_fpr32(ctx, fp0, fs);
10063             gen_load_fpr32(ctx, fp1, ft);
10064             gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
10065             tcg_temp_free_i32(fp1);
10066             gen_store_fpr32(ctx, fp0, fd);
10067             tcg_temp_free_i32(fp0);
10068         }
10069         break;
10070     case OPC_DIV_S:
10071         {
10072             TCGv_i32 fp0 = tcg_temp_new_i32();
10073             TCGv_i32 fp1 = tcg_temp_new_i32();
10074
10075             gen_load_fpr32(ctx, fp0, fs);
10076             gen_load_fpr32(ctx, fp1, ft);
10077             gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
10078             tcg_temp_free_i32(fp1);
10079             gen_store_fpr32(ctx, fp0, fd);
10080             tcg_temp_free_i32(fp0);
10081         }
10082         break;
10083     case OPC_SQRT_S:
10084         {
10085             TCGv_i32 fp0 = tcg_temp_new_i32();
10086
10087             gen_load_fpr32(ctx, fp0, fs);
10088             gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
10089             gen_store_fpr32(ctx, fp0, fd);
10090             tcg_temp_free_i32(fp0);
10091         }
10092         break;
10093     case OPC_ABS_S:
10094         {
10095             TCGv_i32 fp0 = tcg_temp_new_i32();
10096
10097             gen_load_fpr32(ctx, fp0, fs);
10098             if (ctx->abs2008) {
10099                 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
10100             } else {
10101                 gen_helper_float_abs_s(fp0, fp0);
10102             }
10103             gen_store_fpr32(ctx, fp0, fd);
10104             tcg_temp_free_i32(fp0);
10105         }
10106         break;
10107     case OPC_MOV_S:
10108         {
10109             TCGv_i32 fp0 = tcg_temp_new_i32();
10110
10111             gen_load_fpr32(ctx, fp0, fs);
10112             gen_store_fpr32(ctx, fp0, fd);
10113             tcg_temp_free_i32(fp0);
10114         }
10115         break;
10116     case OPC_NEG_S:
10117         {
10118             TCGv_i32 fp0 = tcg_temp_new_i32();
10119
10120             gen_load_fpr32(ctx, fp0, fs);
10121             if (ctx->abs2008) {
10122                 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
10123             } else {
10124                 gen_helper_float_chs_s(fp0, fp0);
10125             }
10126             gen_store_fpr32(ctx, fp0, fd);
10127             tcg_temp_free_i32(fp0);
10128         }
10129         break;
10130     case OPC_ROUND_L_S:
10131         check_cp1_64bitmode(ctx);
10132         {
10133             TCGv_i32 fp32 = tcg_temp_new_i32();
10134             TCGv_i64 fp64 = tcg_temp_new_i64();
10135
10136             gen_load_fpr32(ctx, fp32, fs);
10137             if (ctx->nan2008) {
10138                 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
10139             } else {
10140                 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
10141             }
10142             tcg_temp_free_i32(fp32);
10143             gen_store_fpr64(ctx, fp64, fd);
10144             tcg_temp_free_i64(fp64);
10145         }
10146         break;
10147     case OPC_TRUNC_L_S:
10148         check_cp1_64bitmode(ctx);
10149         {
10150             TCGv_i32 fp32 = tcg_temp_new_i32();
10151             TCGv_i64 fp64 = tcg_temp_new_i64();
10152
10153             gen_load_fpr32(ctx, fp32, fs);
10154             if (ctx->nan2008) {
10155                 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
10156             } else {
10157                 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
10158             }
10159             tcg_temp_free_i32(fp32);
10160             gen_store_fpr64(ctx, fp64, fd);
10161             tcg_temp_free_i64(fp64);
10162         }
10163         break;
10164     case OPC_CEIL_L_S:
10165         check_cp1_64bitmode(ctx);
10166         {
10167             TCGv_i32 fp32 = tcg_temp_new_i32();
10168             TCGv_i64 fp64 = tcg_temp_new_i64();
10169
10170             gen_load_fpr32(ctx, fp32, fs);
10171             if (ctx->nan2008) {
10172                 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
10173             } else {
10174                 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
10175             }
10176             tcg_temp_free_i32(fp32);
10177             gen_store_fpr64(ctx, fp64, fd);
10178             tcg_temp_free_i64(fp64);
10179         }
10180         break;
10181     case OPC_FLOOR_L_S:
10182         check_cp1_64bitmode(ctx);
10183         {
10184             TCGv_i32 fp32 = tcg_temp_new_i32();
10185             TCGv_i64 fp64 = tcg_temp_new_i64();
10186
10187             gen_load_fpr32(ctx, fp32, fs);
10188             if (ctx->nan2008) {
10189                 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
10190             } else {
10191                 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
10192             }
10193             tcg_temp_free_i32(fp32);
10194             gen_store_fpr64(ctx, fp64, fd);
10195             tcg_temp_free_i64(fp64);
10196         }
10197         break;
10198     case OPC_ROUND_W_S:
10199         {
10200             TCGv_i32 fp0 = tcg_temp_new_i32();
10201
10202             gen_load_fpr32(ctx, fp0, fs);
10203             if (ctx->nan2008) {
10204                 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
10205             } else {
10206                 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
10207             }
10208             gen_store_fpr32(ctx, fp0, fd);
10209             tcg_temp_free_i32(fp0);
10210         }
10211         break;
10212     case OPC_TRUNC_W_S:
10213         {
10214             TCGv_i32 fp0 = tcg_temp_new_i32();
10215
10216             gen_load_fpr32(ctx, fp0, fs);
10217             if (ctx->nan2008) {
10218                 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
10219             } else {
10220                 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
10221             }
10222             gen_store_fpr32(ctx, fp0, fd);
10223             tcg_temp_free_i32(fp0);
10224         }
10225         break;
10226     case OPC_CEIL_W_S:
10227         {
10228             TCGv_i32 fp0 = tcg_temp_new_i32();
10229
10230             gen_load_fpr32(ctx, fp0, fs);
10231             if (ctx->nan2008) {
10232                 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
10233             } else {
10234                 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
10235             }
10236             gen_store_fpr32(ctx, fp0, fd);
10237             tcg_temp_free_i32(fp0);
10238         }
10239         break;
10240     case OPC_FLOOR_W_S:
10241         {
10242             TCGv_i32 fp0 = tcg_temp_new_i32();
10243
10244             gen_load_fpr32(ctx, fp0, fs);
10245             if (ctx->nan2008) {
10246                 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
10247             } else {
10248                 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
10249             }
10250             gen_store_fpr32(ctx, fp0, fd);
10251             tcg_temp_free_i32(fp0);
10252         }
10253         break;
10254     case OPC_SEL_S:
10255         check_insn(ctx, ISA_MIPS32R6);
10256         gen_sel_s(ctx, op1, fd, ft, fs);
10257         break;
10258     case OPC_SELEQZ_S:
10259         check_insn(ctx, ISA_MIPS32R6);
10260         gen_sel_s(ctx, op1, fd, ft, fs);
10261         break;
10262     case OPC_SELNEZ_S:
10263         check_insn(ctx, ISA_MIPS32R6);
10264         gen_sel_s(ctx, op1, fd, ft, fs);
10265         break;
10266     case OPC_MOVCF_S:
10267         check_insn_opc_removed(ctx, ISA_MIPS32R6);
10268         gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10269         break;
10270     case OPC_MOVZ_S:
10271         check_insn_opc_removed(ctx, ISA_MIPS32R6);
10272         {
10273             TCGLabel *l1 = gen_new_label();
10274             TCGv_i32 fp0;
10275
10276             if (ft != 0) {
10277                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10278             }
10279             fp0 = tcg_temp_new_i32();
10280             gen_load_fpr32(ctx, fp0, fs);
10281             gen_store_fpr32(ctx, fp0, fd);
10282             tcg_temp_free_i32(fp0);
10283             gen_set_label(l1);
10284         }
10285         break;
10286     case OPC_MOVN_S:
10287         check_insn_opc_removed(ctx, ISA_MIPS32R6);
10288         {
10289             TCGLabel *l1 = gen_new_label();
10290             TCGv_i32 fp0;
10291
10292             if (ft != 0) {
10293                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10294                 fp0 = tcg_temp_new_i32();
10295                 gen_load_fpr32(ctx, fp0, fs);
10296                 gen_store_fpr32(ctx, fp0, fd);
10297                 tcg_temp_free_i32(fp0);
10298                 gen_set_label(l1);
10299             }
10300         }
10301         break;
10302     case OPC_RECIP_S:
10303         {
10304             TCGv_i32 fp0 = tcg_temp_new_i32();
10305
10306             gen_load_fpr32(ctx, fp0, fs);
10307             gen_helper_float_recip_s(fp0, cpu_env, fp0);
10308             gen_store_fpr32(ctx, fp0, fd);
10309             tcg_temp_free_i32(fp0);
10310         }
10311         break;
10312     case OPC_RSQRT_S:
10313         {
10314             TCGv_i32 fp0 = tcg_temp_new_i32();
10315
10316             gen_load_fpr32(ctx, fp0, fs);
10317             gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
10318             gen_store_fpr32(ctx, fp0, fd);
10319             tcg_temp_free_i32(fp0);
10320         }
10321         break;
10322     case OPC_MADDF_S:
10323         check_insn(ctx, ISA_MIPS32R6);
10324         {
10325             TCGv_i32 fp0 = tcg_temp_new_i32();
10326             TCGv_i32 fp1 = tcg_temp_new_i32();
10327             TCGv_i32 fp2 = tcg_temp_new_i32();
10328             gen_load_fpr32(ctx, fp0, fs);
10329             gen_load_fpr32(ctx, fp1, ft);
10330             gen_load_fpr32(ctx, fp2, fd);
10331             gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
10332             gen_store_fpr32(ctx, fp2, fd);
10333             tcg_temp_free_i32(fp2);
10334             tcg_temp_free_i32(fp1);
10335             tcg_temp_free_i32(fp0);
10336         }
10337         break;
10338     case OPC_MSUBF_S:
10339         check_insn(ctx, ISA_MIPS32R6);
10340         {
10341             TCGv_i32 fp0 = tcg_temp_new_i32();
10342             TCGv_i32 fp1 = tcg_temp_new_i32();
10343             TCGv_i32 fp2 = tcg_temp_new_i32();
10344             gen_load_fpr32(ctx, fp0, fs);
10345             gen_load_fpr32(ctx, fp1, ft);
10346             gen_load_fpr32(ctx, fp2, fd);
10347             gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
10348             gen_store_fpr32(ctx, fp2, fd);
10349             tcg_temp_free_i32(fp2);
10350             tcg_temp_free_i32(fp1);
10351             tcg_temp_free_i32(fp0);
10352         }
10353         break;
10354     case OPC_RINT_S:
10355         check_insn(ctx, ISA_MIPS32R6);
10356         {
10357             TCGv_i32 fp0 = tcg_temp_new_i32();
10358             gen_load_fpr32(ctx, fp0, fs);
10359             gen_helper_float_rint_s(fp0, cpu_env, fp0);
10360             gen_store_fpr32(ctx, fp0, fd);
10361             tcg_temp_free_i32(fp0);
10362         }
10363         break;
10364     case OPC_CLASS_S:
10365         check_insn(ctx, ISA_MIPS32R6);
10366         {
10367             TCGv_i32 fp0 = tcg_temp_new_i32();
10368             gen_load_fpr32(ctx, fp0, fs);
10369             gen_helper_float_class_s(fp0, cpu_env, fp0);
10370             gen_store_fpr32(ctx, fp0, fd);
10371             tcg_temp_free_i32(fp0);
10372         }
10373         break;
10374     case OPC_MIN_S: /* OPC_RECIP2_S */
10375         if (ctx->insn_flags & ISA_MIPS32R6) {
10376             /* OPC_MIN_S */
10377             TCGv_i32 fp0 = tcg_temp_new_i32();
10378             TCGv_i32 fp1 = tcg_temp_new_i32();
10379             TCGv_i32 fp2 = tcg_temp_new_i32();
10380             gen_load_fpr32(ctx, fp0, fs);
10381             gen_load_fpr32(ctx, fp1, ft);
10382             gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
10383             gen_store_fpr32(ctx, fp2, fd);
10384             tcg_temp_free_i32(fp2);
10385             tcg_temp_free_i32(fp1);
10386             tcg_temp_free_i32(fp0);
10387         } else {
10388             /* OPC_RECIP2_S */
10389             check_cp1_64bitmode(ctx);
10390             {
10391                 TCGv_i32 fp0 = tcg_temp_new_i32();
10392                 TCGv_i32 fp1 = tcg_temp_new_i32();
10393
10394                 gen_load_fpr32(ctx, fp0, fs);
10395                 gen_load_fpr32(ctx, fp1, ft);
10396                 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
10397                 tcg_temp_free_i32(fp1);
10398                 gen_store_fpr32(ctx, fp0, fd);
10399                 tcg_temp_free_i32(fp0);
10400             }
10401         }
10402         break;
10403     case OPC_MINA_S: /* OPC_RECIP1_S */
10404         if (ctx->insn_flags & ISA_MIPS32R6) {
10405             /* OPC_MINA_S */
10406             TCGv_i32 fp0 = tcg_temp_new_i32();
10407             TCGv_i32 fp1 = tcg_temp_new_i32();
10408             TCGv_i32 fp2 = tcg_temp_new_i32();
10409             gen_load_fpr32(ctx, fp0, fs);
10410             gen_load_fpr32(ctx, fp1, ft);
10411             gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
10412             gen_store_fpr32(ctx, fp2, fd);
10413             tcg_temp_free_i32(fp2);
10414             tcg_temp_free_i32(fp1);
10415             tcg_temp_free_i32(fp0);
10416         } else {
10417             /* OPC_RECIP1_S */
10418             check_cp1_64bitmode(ctx);
10419             {
10420                 TCGv_i32 fp0 = tcg_temp_new_i32();
10421
10422                 gen_load_fpr32(ctx, fp0, fs);
10423                 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
10424                 gen_store_fpr32(ctx, fp0, fd);
10425                 tcg_temp_free_i32(fp0);
10426             }
10427         }
10428         break;
10429     case OPC_MAX_S: /* OPC_RSQRT1_S */
10430         if (ctx->insn_flags & ISA_MIPS32R6) {
10431             /* OPC_MAX_S */
10432             TCGv_i32 fp0 = tcg_temp_new_i32();
10433             TCGv_i32 fp1 = tcg_temp_new_i32();
10434             gen_load_fpr32(ctx, fp0, fs);
10435             gen_load_fpr32(ctx, fp1, ft);
10436             gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
10437             gen_store_fpr32(ctx, fp1, fd);
10438             tcg_temp_free_i32(fp1);
10439             tcg_temp_free_i32(fp0);
10440         } else {
10441             /* OPC_RSQRT1_S */
10442             check_cp1_64bitmode(ctx);
10443             {
10444                 TCGv_i32 fp0 = tcg_temp_new_i32();
10445
10446                 gen_load_fpr32(ctx, fp0, fs);
10447                 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
10448                 gen_store_fpr32(ctx, fp0, fd);
10449                 tcg_temp_free_i32(fp0);
10450             }
10451         }
10452         break;
10453     case OPC_MAXA_S: /* OPC_RSQRT2_S */
10454         if (ctx->insn_flags & ISA_MIPS32R6) {
10455             /* OPC_MAXA_S */
10456             TCGv_i32 fp0 = tcg_temp_new_i32();
10457             TCGv_i32 fp1 = tcg_temp_new_i32();
10458             gen_load_fpr32(ctx, fp0, fs);
10459             gen_load_fpr32(ctx, fp1, ft);
10460             gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
10461             gen_store_fpr32(ctx, fp1, fd);
10462             tcg_temp_free_i32(fp1);
10463             tcg_temp_free_i32(fp0);
10464         } else {
10465             /* OPC_RSQRT2_S */
10466             check_cp1_64bitmode(ctx);
10467             {
10468                 TCGv_i32 fp0 = tcg_temp_new_i32();
10469                 TCGv_i32 fp1 = tcg_temp_new_i32();
10470
10471                 gen_load_fpr32(ctx, fp0, fs);
10472                 gen_load_fpr32(ctx, fp1, ft);
10473                 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
10474                 tcg_temp_free_i32(fp1);
10475                 gen_store_fpr32(ctx, fp0, fd);
10476                 tcg_temp_free_i32(fp0);
10477             }
10478         }
10479         break;
10480     case OPC_CVT_D_S:
10481         check_cp1_registers(ctx, fd);
10482         {
10483             TCGv_i32 fp32 = tcg_temp_new_i32();
10484             TCGv_i64 fp64 = tcg_temp_new_i64();
10485
10486             gen_load_fpr32(ctx, fp32, fs);
10487             gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
10488             tcg_temp_free_i32(fp32);
10489             gen_store_fpr64(ctx, fp64, fd);
10490             tcg_temp_free_i64(fp64);
10491         }
10492         break;
10493     case OPC_CVT_W_S:
10494         {
10495             TCGv_i32 fp0 = tcg_temp_new_i32();
10496
10497             gen_load_fpr32(ctx, fp0, fs);
10498             if (ctx->nan2008) {
10499                 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
10500             } else {
10501                 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
10502             }
10503             gen_store_fpr32(ctx, fp0, fd);
10504             tcg_temp_free_i32(fp0);
10505         }
10506         break;
10507     case OPC_CVT_L_S:
10508         check_cp1_64bitmode(ctx);
10509         {
10510             TCGv_i32 fp32 = tcg_temp_new_i32();
10511             TCGv_i64 fp64 = tcg_temp_new_i64();
10512
10513             gen_load_fpr32(ctx, fp32, fs);
10514             if (ctx->nan2008) {
10515                 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
10516             } else {
10517                 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
10518             }
10519             tcg_temp_free_i32(fp32);
10520             gen_store_fpr64(ctx, fp64, fd);
10521             tcg_temp_free_i64(fp64);
10522         }
10523         break;
10524     case OPC_CVT_PS_S:
10525         check_ps(ctx);
10526         {
10527             TCGv_i64 fp64 = tcg_temp_new_i64();
10528             TCGv_i32 fp32_0 = tcg_temp_new_i32();
10529             TCGv_i32 fp32_1 = tcg_temp_new_i32();
10530
10531             gen_load_fpr32(ctx, fp32_0, fs);
10532             gen_load_fpr32(ctx, fp32_1, ft);
10533             tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
10534             tcg_temp_free_i32(fp32_1);
10535             tcg_temp_free_i32(fp32_0);
10536             gen_store_fpr64(ctx, fp64, fd);
10537             tcg_temp_free_i64(fp64);
10538         }
10539         break;
10540     case OPC_CMP_F_S:
10541     case OPC_CMP_UN_S:
10542     case OPC_CMP_EQ_S:
10543     case OPC_CMP_UEQ_S:
10544     case OPC_CMP_OLT_S:
10545     case OPC_CMP_ULT_S:
10546     case OPC_CMP_OLE_S:
10547     case OPC_CMP_ULE_S:
10548     case OPC_CMP_SF_S:
10549     case OPC_CMP_NGLE_S:
10550     case OPC_CMP_SEQ_S:
10551     case OPC_CMP_NGL_S:
10552     case OPC_CMP_LT_S:
10553     case OPC_CMP_NGE_S:
10554     case OPC_CMP_LE_S:
10555     case OPC_CMP_NGT_S:
10556         check_insn_opc_removed(ctx, ISA_MIPS32R6);
10557         if (ctx->opcode & (1 << 6)) {
10558             gen_cmpabs_s(ctx, func-48, ft, fs, cc);
10559         } else {
10560             gen_cmp_s(ctx, func-48, ft, fs, cc);
10561         }
10562         break;
10563     case OPC_ADD_D:
10564         check_cp1_registers(ctx, fs | ft | fd);
10565         {
10566             TCGv_i64 fp0 = tcg_temp_new_i64();
10567             TCGv_i64 fp1 = tcg_temp_new_i64();
10568
10569             gen_load_fpr64(ctx, fp0, fs);
10570             gen_load_fpr64(ctx, fp1, ft);
10571             gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
10572             tcg_temp_free_i64(fp1);
10573             gen_store_fpr64(ctx, fp0, fd);
10574             tcg_temp_free_i64(fp0);
10575         }
10576         break;
10577     case OPC_SUB_D:
10578         check_cp1_registers(ctx, fs | ft | fd);
10579         {
10580             TCGv_i64 fp0 = tcg_temp_new_i64();
10581             TCGv_i64 fp1 = tcg_temp_new_i64();
10582
10583             gen_load_fpr64(ctx, fp0, fs);
10584             gen_load_fpr64(ctx, fp1, ft);
10585             gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
10586             tcg_temp_free_i64(fp1);
10587             gen_store_fpr64(ctx, fp0, fd);
10588             tcg_temp_free_i64(fp0);
10589         }
10590         break;
10591     case OPC_MUL_D:
10592         check_cp1_registers(ctx, fs | ft | fd);
10593         {
10594             TCGv_i64 fp0 = tcg_temp_new_i64();
10595             TCGv_i64 fp1 = tcg_temp_new_i64();
10596
10597             gen_load_fpr64(ctx, fp0, fs);
10598             gen_load_fpr64(ctx, fp1, ft);
10599             gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
10600             tcg_temp_free_i64(fp1);
10601             gen_store_fpr64(ctx, fp0, fd);
10602             tcg_temp_free_i64(fp0);
10603         }
10604         break;
10605     case OPC_DIV_D:
10606         check_cp1_registers(ctx, fs | ft | fd);
10607         {
10608             TCGv_i64 fp0 = tcg_temp_new_i64();
10609             TCGv_i64 fp1 = tcg_temp_new_i64();
10610
10611             gen_load_fpr64(ctx, fp0, fs);
10612             gen_load_fpr64(ctx, fp1, ft);
10613             gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
10614             tcg_temp_free_i64(fp1);
10615             gen_store_fpr64(ctx, fp0, fd);
10616             tcg_temp_free_i64(fp0);
10617         }
10618         break;
10619     case OPC_SQRT_D:
10620         check_cp1_registers(ctx, fs | fd);
10621         {
10622             TCGv_i64 fp0 = tcg_temp_new_i64();
10623
10624             gen_load_fpr64(ctx, fp0, fs);
10625             gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
10626             gen_store_fpr64(ctx, fp0, fd);
10627             tcg_temp_free_i64(fp0);
10628         }
10629         break;
10630     case OPC_ABS_D:
10631         check_cp1_registers(ctx, fs | fd);
10632         {
10633             TCGv_i64 fp0 = tcg_temp_new_i64();
10634
10635             gen_load_fpr64(ctx, fp0, fs);
10636             if (ctx->abs2008) {
10637                 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
10638             } else {
10639                 gen_helper_float_abs_d(fp0, fp0);
10640             }
10641             gen_store_fpr64(ctx, fp0, fd);
10642             tcg_temp_free_i64(fp0);
10643         }
10644         break;
10645     case OPC_MOV_D:
10646         check_cp1_registers(ctx, fs | fd);
10647         {
10648             TCGv_i64 fp0 = tcg_temp_new_i64();
10649
10650             gen_load_fpr64(ctx, fp0, fs);
10651             gen_store_fpr64(ctx, fp0, fd);
10652             tcg_temp_free_i64(fp0);
10653         }
10654         break;
10655     case OPC_NEG_D:
10656         check_cp1_registers(ctx, fs | fd);
10657         {
10658             TCGv_i64 fp0 = tcg_temp_new_i64();
10659
10660             gen_load_fpr64(ctx, fp0, fs);
10661             if (ctx->abs2008) {
10662                 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
10663             } else {
10664                 gen_helper_float_chs_d(fp0, fp0);
10665             }
10666             gen_store_fpr64(ctx, fp0, fd);
10667             tcg_temp_free_i64(fp0);
10668         }
10669         break;
10670     case OPC_ROUND_L_D:
10671         check_cp1_64bitmode(ctx);
10672         {
10673             TCGv_i64 fp0 = tcg_temp_new_i64();
10674
10675             gen_load_fpr64(ctx, fp0, fs);
10676             if (ctx->nan2008) {
10677                 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
10678             } else {
10679                 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
10680             }
10681             gen_store_fpr64(ctx, fp0, fd);
10682             tcg_temp_free_i64(fp0);
10683         }
10684         break;
10685     case OPC_TRUNC_L_D:
10686         check_cp1_64bitmode(ctx);
10687         {
10688             TCGv_i64 fp0 = tcg_temp_new_i64();
10689
10690             gen_load_fpr64(ctx, fp0, fs);
10691             if (ctx->nan2008) {
10692                 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
10693             } else {
10694                 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
10695             }
10696             gen_store_fpr64(ctx, fp0, fd);
10697             tcg_temp_free_i64(fp0);
10698         }
10699         break;
10700     case OPC_CEIL_L_D:
10701         check_cp1_64bitmode(ctx);
10702         {
10703             TCGv_i64 fp0 = tcg_temp_new_i64();
10704
10705             gen_load_fpr64(ctx, fp0, fs);
10706             if (ctx->nan2008) {
10707                 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
10708             } else {
10709                 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
10710             }
10711             gen_store_fpr64(ctx, fp0, fd);
10712             tcg_temp_free_i64(fp0);
10713         }
10714         break;
10715     case OPC_FLOOR_L_D:
10716         check_cp1_64bitmode(ctx);
10717         {
10718             TCGv_i64 fp0 = tcg_temp_new_i64();
10719
10720             gen_load_fpr64(ctx, fp0, fs);
10721             if (ctx->nan2008) {
10722                 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
10723             } else {
10724                 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
10725             }
10726             gen_store_fpr64(ctx, fp0, fd);
10727             tcg_temp_free_i64(fp0);
10728         }
10729         break;
10730     case OPC_ROUND_W_D:
10731         check_cp1_registers(ctx, fs);
10732         {
10733             TCGv_i32 fp32 = tcg_temp_new_i32();
10734             TCGv_i64 fp64 = tcg_temp_new_i64();
10735
10736             gen_load_fpr64(ctx, fp64, fs);
10737             if (ctx->nan2008) {
10738                 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
10739             } else {
10740                 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
10741             }
10742             tcg_temp_free_i64(fp64);
10743             gen_store_fpr32(ctx, fp32, fd);
10744             tcg_temp_free_i32(fp32);
10745         }
10746         break;
10747     case OPC_TRUNC_W_D:
10748         check_cp1_registers(ctx, fs);
10749         {
10750             TCGv_i32 fp32 = tcg_temp_new_i32();
10751             TCGv_i64 fp64 = tcg_temp_new_i64();
10752
10753             gen_load_fpr64(ctx, fp64, fs);
10754             if (ctx->nan2008) {
10755                 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
10756             } else {
10757                 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
10758             }
10759             tcg_temp_free_i64(fp64);
10760             gen_store_fpr32(ctx, fp32, fd);
10761             tcg_temp_free_i32(fp32);
10762         }
10763         break;
10764     case OPC_CEIL_W_D:
10765         check_cp1_registers(ctx, fs);
10766         {
10767             TCGv_i32 fp32 = tcg_temp_new_i32();
10768             TCGv_i64 fp64 = tcg_temp_new_i64();
10769
10770             gen_load_fpr64(ctx, fp64, fs);
10771             if (ctx->nan2008) {
10772                 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
10773             } else {
10774                 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
10775             }
10776             tcg_temp_free_i64(fp64);
10777             gen_store_fpr32(ctx, fp32, fd);
10778             tcg_temp_free_i32(fp32);
10779         }
10780         break;
10781     case OPC_FLOOR_W_D:
10782         check_cp1_registers(ctx, fs);
10783         {
10784             TCGv_i32 fp32 = tcg_temp_new_i32();
10785             TCGv_i64 fp64 = tcg_temp_new_i64();
10786
10787             gen_load_fpr64(ctx, fp64, fs);
10788             if (ctx->nan2008) {
10789                 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
10790             } else {
10791                 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
10792             }
10793             tcg_temp_free_i64(fp64);
10794             gen_store_fpr32(ctx, fp32, fd);
10795             tcg_temp_free_i32(fp32);
10796         }
10797         break;
10798     case OPC_SEL_D:
10799         check_insn(ctx, ISA_MIPS32R6);
10800         gen_sel_d(ctx, op1, fd, ft, fs);
10801         break;
10802     case OPC_SELEQZ_D:
10803         check_insn(ctx, ISA_MIPS32R6);
10804         gen_sel_d(ctx, op1, fd, ft, fs);
10805         break;
10806     case OPC_SELNEZ_D:
10807         check_insn(ctx, ISA_MIPS32R6);
10808         gen_sel_d(ctx, op1, fd, ft, fs);
10809         break;
10810     case OPC_MOVCF_D:
10811         check_insn_opc_removed(ctx, ISA_MIPS32R6);
10812         gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10813         break;
10814     case OPC_MOVZ_D:
10815         check_insn_opc_removed(ctx, ISA_MIPS32R6);
10816         {
10817             TCGLabel *l1 = gen_new_label();
10818             TCGv_i64 fp0;
10819
10820             if (ft != 0) {
10821                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10822             }
10823             fp0 = tcg_temp_new_i64();
10824             gen_load_fpr64(ctx, fp0, fs);
10825             gen_store_fpr64(ctx, fp0, fd);
10826             tcg_temp_free_i64(fp0);
10827             gen_set_label(l1);
10828         }
10829         break;
10830     case OPC_MOVN_D:
10831         check_insn_opc_removed(ctx, ISA_MIPS32R6);
10832         {
10833             TCGLabel *l1 = gen_new_label();
10834             TCGv_i64 fp0;
10835
10836             if (ft != 0) {
10837                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10838                 fp0 = tcg_temp_new_i64();
10839                 gen_load_fpr64(ctx, fp0, fs);
10840                 gen_store_fpr64(ctx, fp0, fd);
10841                 tcg_temp_free_i64(fp0);
10842                 gen_set_label(l1);
10843             }
10844         }
10845         break;
10846     case OPC_RECIP_D:
10847         check_cp1_registers(ctx, fs | fd);
10848         {
10849             TCGv_i64 fp0 = tcg_temp_new_i64();
10850
10851             gen_load_fpr64(ctx, fp0, fs);
10852             gen_helper_float_recip_d(fp0, cpu_env, fp0);
10853             gen_store_fpr64(ctx, fp0, fd);
10854             tcg_temp_free_i64(fp0);
10855         }
10856         break;
10857     case OPC_RSQRT_D:
10858         check_cp1_registers(ctx, fs | fd);
10859         {
10860             TCGv_i64 fp0 = tcg_temp_new_i64();
10861
10862             gen_load_fpr64(ctx, fp0, fs);
10863             gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
10864             gen_store_fpr64(ctx, fp0, fd);
10865             tcg_temp_free_i64(fp0);
10866         }
10867         break;
10868     case OPC_MADDF_D:
10869         check_insn(ctx, ISA_MIPS32R6);
10870         {
10871             TCGv_i64 fp0 = tcg_temp_new_i64();
10872             TCGv_i64 fp1 = tcg_temp_new_i64();
10873             TCGv_i64 fp2 = tcg_temp_new_i64();
10874             gen_load_fpr64(ctx, fp0, fs);
10875             gen_load_fpr64(ctx, fp1, ft);
10876             gen_load_fpr64(ctx, fp2, fd);
10877             gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
10878             gen_store_fpr64(ctx, fp2, fd);
10879             tcg_temp_free_i64(fp2);
10880             tcg_temp_free_i64(fp1);
10881             tcg_temp_free_i64(fp0);
10882         }
10883         break;
10884     case OPC_MSUBF_D:
10885         check_insn(ctx, ISA_MIPS32R6);
10886         {
10887             TCGv_i64 fp0 = tcg_temp_new_i64();
10888             TCGv_i64 fp1 = tcg_temp_new_i64();
10889             TCGv_i64 fp2 = tcg_temp_new_i64();
10890             gen_load_fpr64(ctx, fp0, fs);
10891             gen_load_fpr64(ctx, fp1, ft);
10892             gen_load_fpr64(ctx, fp2, fd);
10893             gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
10894             gen_store_fpr64(ctx, fp2, fd);
10895             tcg_temp_free_i64(fp2);
10896             tcg_temp_free_i64(fp1);
10897             tcg_temp_free_i64(fp0);
10898         }
10899         break;
10900     case OPC_RINT_D:
10901         check_insn(ctx, ISA_MIPS32R6);
10902         {
10903             TCGv_i64 fp0 = tcg_temp_new_i64();
10904             gen_load_fpr64(ctx, fp0, fs);
10905             gen_helper_float_rint_d(fp0, cpu_env, fp0);
10906             gen_store_fpr64(ctx, fp0, fd);
10907             tcg_temp_free_i64(fp0);
10908         }
10909         break;
10910     case OPC_CLASS_D:
10911         check_insn(ctx, ISA_MIPS32R6);
10912         {
10913             TCGv_i64 fp0 = tcg_temp_new_i64();
10914             gen_load_fpr64(ctx, fp0, fs);
10915             gen_helper_float_class_d(fp0, cpu_env, fp0);
10916             gen_store_fpr64(ctx, fp0, fd);
10917             tcg_temp_free_i64(fp0);
10918         }
10919         break;
10920     case OPC_MIN_D: /* OPC_RECIP2_D */
10921         if (ctx->insn_flags & ISA_MIPS32R6) {
10922             /* OPC_MIN_D */
10923             TCGv_i64 fp0 = tcg_temp_new_i64();
10924             TCGv_i64 fp1 = tcg_temp_new_i64();
10925             gen_load_fpr64(ctx, fp0, fs);
10926             gen_load_fpr64(ctx, fp1, ft);
10927             gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
10928             gen_store_fpr64(ctx, fp1, fd);
10929             tcg_temp_free_i64(fp1);
10930             tcg_temp_free_i64(fp0);
10931         } else {
10932             /* OPC_RECIP2_D */
10933             check_cp1_64bitmode(ctx);
10934             {
10935                 TCGv_i64 fp0 = tcg_temp_new_i64();
10936                 TCGv_i64 fp1 = tcg_temp_new_i64();
10937
10938                 gen_load_fpr64(ctx, fp0, fs);
10939                 gen_load_fpr64(ctx, fp1, ft);
10940                 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
10941                 tcg_temp_free_i64(fp1);
10942                 gen_store_fpr64(ctx, fp0, fd);
10943                 tcg_temp_free_i64(fp0);
10944             }
10945         }
10946         break;
10947     case OPC_MINA_D: /* OPC_RECIP1_D */
10948         if (ctx->insn_flags & ISA_MIPS32R6) {
10949             /* OPC_MINA_D */
10950             TCGv_i64 fp0 = tcg_temp_new_i64();
10951             TCGv_i64 fp1 = tcg_temp_new_i64();
10952             gen_load_fpr64(ctx, fp0, fs);
10953             gen_load_fpr64(ctx, fp1, ft);
10954             gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
10955             gen_store_fpr64(ctx, fp1, fd);
10956             tcg_temp_free_i64(fp1);
10957             tcg_temp_free_i64(fp0);
10958         } else {
10959             /* OPC_RECIP1_D */
10960             check_cp1_64bitmode(ctx);
10961             {
10962                 TCGv_i64 fp0 = tcg_temp_new_i64();
10963
10964                 gen_load_fpr64(ctx, fp0, fs);
10965                 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
10966                 gen_store_fpr64(ctx, fp0, fd);
10967                 tcg_temp_free_i64(fp0);
10968             }
10969         }
10970         break;
10971     case OPC_MAX_D: /*  OPC_RSQRT1_D */
10972         if (ctx->insn_flags & ISA_MIPS32R6) {
10973             /* OPC_MAX_D */
10974             TCGv_i64 fp0 = tcg_temp_new_i64();
10975             TCGv_i64 fp1 = tcg_temp_new_i64();
10976             gen_load_fpr64(ctx, fp0, fs);
10977             gen_load_fpr64(ctx, fp1, ft);
10978             gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
10979             gen_store_fpr64(ctx, fp1, fd);
10980             tcg_temp_free_i64(fp1);
10981             tcg_temp_free_i64(fp0);
10982         } else {
10983             /* OPC_RSQRT1_D */
10984             check_cp1_64bitmode(ctx);
10985             {
10986                 TCGv_i64 fp0 = tcg_temp_new_i64();
10987
10988                 gen_load_fpr64(ctx, fp0, fs);
10989                 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
10990                 gen_store_fpr64(ctx, fp0, fd);
10991                 tcg_temp_free_i64(fp0);
10992             }
10993         }
10994         break;
10995     case OPC_MAXA_D: /* OPC_RSQRT2_D */
10996         if (ctx->insn_flags & ISA_MIPS32R6) {
10997             /* OPC_MAXA_D */
10998             TCGv_i64 fp0 = tcg_temp_new_i64();
10999             TCGv_i64 fp1 = tcg_temp_new_i64();
11000             gen_load_fpr64(ctx, fp0, fs);
11001             gen_load_fpr64(ctx, fp1, ft);
11002             gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
11003             gen_store_fpr64(ctx, fp1, fd);
11004             tcg_temp_free_i64(fp1);
11005             tcg_temp_free_i64(fp0);
11006         } else {
11007             /* OPC_RSQRT2_D */
11008             check_cp1_64bitmode(ctx);
11009             {
11010                 TCGv_i64 fp0 = tcg_temp_new_i64();
11011                 TCGv_i64 fp1 = tcg_temp_new_i64();
11012
11013                 gen_load_fpr64(ctx, fp0, fs);
11014                 gen_load_fpr64(ctx, fp1, ft);
11015                 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
11016                 tcg_temp_free_i64(fp1);
11017                 gen_store_fpr64(ctx, fp0, fd);
11018                 tcg_temp_free_i64(fp0);
11019             }
11020         }
11021         break;
11022     case OPC_CMP_F_D:
11023     case OPC_CMP_UN_D:
11024     case OPC_CMP_EQ_D:
11025     case OPC_CMP_UEQ_D:
11026     case OPC_CMP_OLT_D:
11027     case OPC_CMP_ULT_D:
11028     case OPC_CMP_OLE_D:
11029     case OPC_CMP_ULE_D:
11030     case OPC_CMP_SF_D:
11031     case OPC_CMP_NGLE_D:
11032     case OPC_CMP_SEQ_D:
11033     case OPC_CMP_NGL_D:
11034     case OPC_CMP_LT_D:
11035     case OPC_CMP_NGE_D:
11036     case OPC_CMP_LE_D:
11037     case OPC_CMP_NGT_D:
11038         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11039         if (ctx->opcode & (1 << 6)) {
11040             gen_cmpabs_d(ctx, func-48, ft, fs, cc);
11041         } else {
11042             gen_cmp_d(ctx, func-48, ft, fs, cc);
11043         }
11044         break;
11045     case OPC_CVT_S_D:
11046         check_cp1_registers(ctx, fs);
11047         {
11048             TCGv_i32 fp32 = tcg_temp_new_i32();
11049             TCGv_i64 fp64 = tcg_temp_new_i64();
11050
11051             gen_load_fpr64(ctx, fp64, fs);
11052             gen_helper_float_cvts_d(fp32, cpu_env, fp64);
11053             tcg_temp_free_i64(fp64);
11054             gen_store_fpr32(ctx, fp32, fd);
11055             tcg_temp_free_i32(fp32);
11056         }
11057         break;
11058     case OPC_CVT_W_D:
11059         check_cp1_registers(ctx, fs);
11060         {
11061             TCGv_i32 fp32 = tcg_temp_new_i32();
11062             TCGv_i64 fp64 = tcg_temp_new_i64();
11063
11064             gen_load_fpr64(ctx, fp64, fs);
11065             if (ctx->nan2008) {
11066                 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
11067             } else {
11068                 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
11069             }
11070             tcg_temp_free_i64(fp64);
11071             gen_store_fpr32(ctx, fp32, fd);
11072             tcg_temp_free_i32(fp32);
11073         }
11074         break;
11075     case OPC_CVT_L_D:
11076         check_cp1_64bitmode(ctx);
11077         {
11078             TCGv_i64 fp0 = tcg_temp_new_i64();
11079
11080             gen_load_fpr64(ctx, fp0, fs);
11081             if (ctx->nan2008) {
11082                 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
11083             } else {
11084                 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
11085             }
11086             gen_store_fpr64(ctx, fp0, fd);
11087             tcg_temp_free_i64(fp0);
11088         }
11089         break;
11090     case OPC_CVT_S_W:
11091         {
11092             TCGv_i32 fp0 = tcg_temp_new_i32();
11093
11094             gen_load_fpr32(ctx, fp0, fs);
11095             gen_helper_float_cvts_w(fp0, cpu_env, fp0);
11096             gen_store_fpr32(ctx, fp0, fd);
11097             tcg_temp_free_i32(fp0);
11098         }
11099         break;
11100     case OPC_CVT_D_W:
11101         check_cp1_registers(ctx, fd);
11102         {
11103             TCGv_i32 fp32 = tcg_temp_new_i32();
11104             TCGv_i64 fp64 = tcg_temp_new_i64();
11105
11106             gen_load_fpr32(ctx, fp32, fs);
11107             gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
11108             tcg_temp_free_i32(fp32);
11109             gen_store_fpr64(ctx, fp64, fd);
11110             tcg_temp_free_i64(fp64);
11111         }
11112         break;
11113     case OPC_CVT_S_L:
11114         check_cp1_64bitmode(ctx);
11115         {
11116             TCGv_i32 fp32 = tcg_temp_new_i32();
11117             TCGv_i64 fp64 = tcg_temp_new_i64();
11118
11119             gen_load_fpr64(ctx, fp64, fs);
11120             gen_helper_float_cvts_l(fp32, cpu_env, fp64);
11121             tcg_temp_free_i64(fp64);
11122             gen_store_fpr32(ctx, fp32, fd);
11123             tcg_temp_free_i32(fp32);
11124         }
11125         break;
11126     case OPC_CVT_D_L:
11127         check_cp1_64bitmode(ctx);
11128         {
11129             TCGv_i64 fp0 = tcg_temp_new_i64();
11130
11131             gen_load_fpr64(ctx, fp0, fs);
11132             gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
11133             gen_store_fpr64(ctx, fp0, fd);
11134             tcg_temp_free_i64(fp0);
11135         }
11136         break;
11137     case OPC_CVT_PS_PW:
11138         check_ps(ctx);
11139         {
11140             TCGv_i64 fp0 = tcg_temp_new_i64();
11141
11142             gen_load_fpr64(ctx, fp0, fs);
11143             gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
11144             gen_store_fpr64(ctx, fp0, fd);
11145             tcg_temp_free_i64(fp0);
11146         }
11147         break;
11148     case OPC_ADD_PS:
11149         check_ps(ctx);
11150         {
11151             TCGv_i64 fp0 = tcg_temp_new_i64();
11152             TCGv_i64 fp1 = tcg_temp_new_i64();
11153
11154             gen_load_fpr64(ctx, fp0, fs);
11155             gen_load_fpr64(ctx, fp1, ft);
11156             gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
11157             tcg_temp_free_i64(fp1);
11158             gen_store_fpr64(ctx, fp0, fd);
11159             tcg_temp_free_i64(fp0);
11160         }
11161         break;
11162     case OPC_SUB_PS:
11163         check_ps(ctx);
11164         {
11165             TCGv_i64 fp0 = tcg_temp_new_i64();
11166             TCGv_i64 fp1 = tcg_temp_new_i64();
11167
11168             gen_load_fpr64(ctx, fp0, fs);
11169             gen_load_fpr64(ctx, fp1, ft);
11170             gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
11171             tcg_temp_free_i64(fp1);
11172             gen_store_fpr64(ctx, fp0, fd);
11173             tcg_temp_free_i64(fp0);
11174         }
11175         break;
11176     case OPC_MUL_PS:
11177         check_ps(ctx);
11178         {
11179             TCGv_i64 fp0 = tcg_temp_new_i64();
11180             TCGv_i64 fp1 = tcg_temp_new_i64();
11181
11182             gen_load_fpr64(ctx, fp0, fs);
11183             gen_load_fpr64(ctx, fp1, ft);
11184             gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
11185             tcg_temp_free_i64(fp1);
11186             gen_store_fpr64(ctx, fp0, fd);
11187             tcg_temp_free_i64(fp0);
11188         }
11189         break;
11190     case OPC_ABS_PS:
11191         check_ps(ctx);
11192         {
11193             TCGv_i64 fp0 = tcg_temp_new_i64();
11194
11195             gen_load_fpr64(ctx, fp0, fs);
11196             gen_helper_float_abs_ps(fp0, fp0);
11197             gen_store_fpr64(ctx, fp0, fd);
11198             tcg_temp_free_i64(fp0);
11199         }
11200         break;
11201     case OPC_MOV_PS:
11202         check_ps(ctx);
11203         {
11204             TCGv_i64 fp0 = tcg_temp_new_i64();
11205
11206             gen_load_fpr64(ctx, fp0, fs);
11207             gen_store_fpr64(ctx, fp0, fd);
11208             tcg_temp_free_i64(fp0);
11209         }
11210         break;
11211     case OPC_NEG_PS:
11212         check_ps(ctx);
11213         {
11214             TCGv_i64 fp0 = tcg_temp_new_i64();
11215
11216             gen_load_fpr64(ctx, fp0, fs);
11217             gen_helper_float_chs_ps(fp0, fp0);
11218             gen_store_fpr64(ctx, fp0, fd);
11219             tcg_temp_free_i64(fp0);
11220         }
11221         break;
11222     case OPC_MOVCF_PS:
11223         check_ps(ctx);
11224         gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11225         break;
11226     case OPC_MOVZ_PS:
11227         check_ps(ctx);
11228         {
11229             TCGLabel *l1 = gen_new_label();
11230             TCGv_i64 fp0;
11231
11232             if (ft != 0)
11233                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11234             fp0 = tcg_temp_new_i64();
11235             gen_load_fpr64(ctx, fp0, fs);
11236             gen_store_fpr64(ctx, fp0, fd);
11237             tcg_temp_free_i64(fp0);
11238             gen_set_label(l1);
11239         }
11240         break;
11241     case OPC_MOVN_PS:
11242         check_ps(ctx);
11243         {
11244             TCGLabel *l1 = gen_new_label();
11245             TCGv_i64 fp0;
11246
11247             if (ft != 0) {
11248                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11249                 fp0 = tcg_temp_new_i64();
11250                 gen_load_fpr64(ctx, fp0, fs);
11251                 gen_store_fpr64(ctx, fp0, fd);
11252                 tcg_temp_free_i64(fp0);
11253                 gen_set_label(l1);
11254             }
11255         }
11256         break;
11257     case OPC_ADDR_PS:
11258         check_ps(ctx);
11259         {
11260             TCGv_i64 fp0 = tcg_temp_new_i64();
11261             TCGv_i64 fp1 = tcg_temp_new_i64();
11262
11263             gen_load_fpr64(ctx, fp0, ft);
11264             gen_load_fpr64(ctx, fp1, fs);
11265             gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
11266             tcg_temp_free_i64(fp1);
11267             gen_store_fpr64(ctx, fp0, fd);
11268             tcg_temp_free_i64(fp0);
11269         }
11270         break;
11271     case OPC_MULR_PS:
11272         check_ps(ctx);
11273         {
11274             TCGv_i64 fp0 = tcg_temp_new_i64();
11275             TCGv_i64 fp1 = tcg_temp_new_i64();
11276
11277             gen_load_fpr64(ctx, fp0, ft);
11278             gen_load_fpr64(ctx, fp1, fs);
11279             gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
11280             tcg_temp_free_i64(fp1);
11281             gen_store_fpr64(ctx, fp0, fd);
11282             tcg_temp_free_i64(fp0);
11283         }
11284         break;
11285     case OPC_RECIP2_PS:
11286         check_ps(ctx);
11287         {
11288             TCGv_i64 fp0 = tcg_temp_new_i64();
11289             TCGv_i64 fp1 = tcg_temp_new_i64();
11290
11291             gen_load_fpr64(ctx, fp0, fs);
11292             gen_load_fpr64(ctx, fp1, ft);
11293             gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
11294             tcg_temp_free_i64(fp1);
11295             gen_store_fpr64(ctx, fp0, fd);
11296             tcg_temp_free_i64(fp0);
11297         }
11298         break;
11299     case OPC_RECIP1_PS:
11300         check_ps(ctx);
11301         {
11302             TCGv_i64 fp0 = tcg_temp_new_i64();
11303
11304             gen_load_fpr64(ctx, fp0, fs);
11305             gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
11306             gen_store_fpr64(ctx, fp0, fd);
11307             tcg_temp_free_i64(fp0);
11308         }
11309         break;
11310     case OPC_RSQRT1_PS:
11311         check_ps(ctx);
11312         {
11313             TCGv_i64 fp0 = tcg_temp_new_i64();
11314
11315             gen_load_fpr64(ctx, fp0, fs);
11316             gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
11317             gen_store_fpr64(ctx, fp0, fd);
11318             tcg_temp_free_i64(fp0);
11319         }
11320         break;
11321     case OPC_RSQRT2_PS:
11322         check_ps(ctx);
11323         {
11324             TCGv_i64 fp0 = tcg_temp_new_i64();
11325             TCGv_i64 fp1 = tcg_temp_new_i64();
11326
11327             gen_load_fpr64(ctx, fp0, fs);
11328             gen_load_fpr64(ctx, fp1, ft);
11329             gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
11330             tcg_temp_free_i64(fp1);
11331             gen_store_fpr64(ctx, fp0, fd);
11332             tcg_temp_free_i64(fp0);
11333         }
11334         break;
11335     case OPC_CVT_S_PU:
11336         check_cp1_64bitmode(ctx);
11337         {
11338             TCGv_i32 fp0 = tcg_temp_new_i32();
11339
11340             gen_load_fpr32h(ctx, fp0, fs);
11341             gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
11342             gen_store_fpr32(ctx, fp0, fd);
11343             tcg_temp_free_i32(fp0);
11344         }
11345         break;
11346     case OPC_CVT_PW_PS:
11347         check_ps(ctx);
11348         {
11349             TCGv_i64 fp0 = tcg_temp_new_i64();
11350
11351             gen_load_fpr64(ctx, fp0, fs);
11352             gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
11353             gen_store_fpr64(ctx, fp0, fd);
11354             tcg_temp_free_i64(fp0);
11355         }
11356         break;
11357     case OPC_CVT_S_PL:
11358         check_cp1_64bitmode(ctx);
11359         {
11360             TCGv_i32 fp0 = tcg_temp_new_i32();
11361
11362             gen_load_fpr32(ctx, fp0, fs);
11363             gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
11364             gen_store_fpr32(ctx, fp0, fd);
11365             tcg_temp_free_i32(fp0);
11366         }
11367         break;
11368     case OPC_PLL_PS:
11369         check_ps(ctx);
11370         {
11371             TCGv_i32 fp0 = tcg_temp_new_i32();
11372             TCGv_i32 fp1 = tcg_temp_new_i32();
11373
11374             gen_load_fpr32(ctx, fp0, fs);
11375             gen_load_fpr32(ctx, fp1, ft);
11376             gen_store_fpr32h(ctx, fp0, fd);
11377             gen_store_fpr32(ctx, fp1, fd);
11378             tcg_temp_free_i32(fp0);
11379             tcg_temp_free_i32(fp1);
11380         }
11381         break;
11382     case OPC_PLU_PS:
11383         check_ps(ctx);
11384         {
11385             TCGv_i32 fp0 = tcg_temp_new_i32();
11386             TCGv_i32 fp1 = tcg_temp_new_i32();
11387
11388             gen_load_fpr32(ctx, fp0, fs);
11389             gen_load_fpr32h(ctx, fp1, ft);
11390             gen_store_fpr32(ctx, fp1, fd);
11391             gen_store_fpr32h(ctx, fp0, fd);
11392             tcg_temp_free_i32(fp0);
11393             tcg_temp_free_i32(fp1);
11394         }
11395         break;
11396     case OPC_PUL_PS:
11397         check_ps(ctx);
11398         {
11399             TCGv_i32 fp0 = tcg_temp_new_i32();
11400             TCGv_i32 fp1 = tcg_temp_new_i32();
11401
11402             gen_load_fpr32h(ctx, fp0, fs);
11403             gen_load_fpr32(ctx, fp1, ft);
11404             gen_store_fpr32(ctx, fp1, fd);
11405             gen_store_fpr32h(ctx, fp0, fd);
11406             tcg_temp_free_i32(fp0);
11407             tcg_temp_free_i32(fp1);
11408         }
11409         break;
11410     case OPC_PUU_PS:
11411         check_ps(ctx);
11412         {
11413             TCGv_i32 fp0 = tcg_temp_new_i32();
11414             TCGv_i32 fp1 = tcg_temp_new_i32();
11415
11416             gen_load_fpr32h(ctx, fp0, fs);
11417             gen_load_fpr32h(ctx, fp1, ft);
11418             gen_store_fpr32(ctx, fp1, fd);
11419             gen_store_fpr32h(ctx, fp0, fd);
11420             tcg_temp_free_i32(fp0);
11421             tcg_temp_free_i32(fp1);
11422         }
11423         break;
11424     case OPC_CMP_F_PS:
11425     case OPC_CMP_UN_PS:
11426     case OPC_CMP_EQ_PS:
11427     case OPC_CMP_UEQ_PS:
11428     case OPC_CMP_OLT_PS:
11429     case OPC_CMP_ULT_PS:
11430     case OPC_CMP_OLE_PS:
11431     case OPC_CMP_ULE_PS:
11432     case OPC_CMP_SF_PS:
11433     case OPC_CMP_NGLE_PS:
11434     case OPC_CMP_SEQ_PS:
11435     case OPC_CMP_NGL_PS:
11436     case OPC_CMP_LT_PS:
11437     case OPC_CMP_NGE_PS:
11438     case OPC_CMP_LE_PS:
11439     case OPC_CMP_NGT_PS:
11440         if (ctx->opcode & (1 << 6)) {
11441             gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
11442         } else {
11443             gen_cmp_ps(ctx, func-48, ft, fs, cc);
11444         }
11445         break;
11446     default:
11447         MIPS_INVAL("farith");
11448         generate_exception_end(ctx, EXCP_RI);
11449         return;
11450     }
11451 }
11452
11453 /* Coprocessor 3 (FPU) */
11454 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
11455                            int fd, int fs, int base, int index)
11456 {
11457     TCGv t0 = tcg_temp_new();
11458
11459     if (base == 0) {
11460         gen_load_gpr(t0, index);
11461     } else if (index == 0) {
11462         gen_load_gpr(t0, base);
11463     } else {
11464         gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
11465     }
11466     /* Don't do NOP if destination is zero: we must perform the actual
11467        memory access. */
11468     switch (opc) {
11469     case OPC_LWXC1:
11470         check_cop1x(ctx);
11471         {
11472             TCGv_i32 fp0 = tcg_temp_new_i32();
11473
11474             tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
11475             tcg_gen_trunc_tl_i32(fp0, t0);
11476             gen_store_fpr32(ctx, fp0, fd);
11477             tcg_temp_free_i32(fp0);
11478         }
11479         break;
11480     case OPC_LDXC1:
11481         check_cop1x(ctx);
11482         check_cp1_registers(ctx, fd);
11483         {
11484             TCGv_i64 fp0 = tcg_temp_new_i64();
11485             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11486             gen_store_fpr64(ctx, fp0, fd);
11487             tcg_temp_free_i64(fp0);
11488         }
11489         break;
11490     case OPC_LUXC1:
11491         check_cp1_64bitmode(ctx);
11492         tcg_gen_andi_tl(t0, t0, ~0x7);
11493         {
11494             TCGv_i64 fp0 = tcg_temp_new_i64();
11495
11496             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11497             gen_store_fpr64(ctx, fp0, fd);
11498             tcg_temp_free_i64(fp0);
11499         }
11500         break;
11501     case OPC_SWXC1:
11502         check_cop1x(ctx);
11503         {
11504             TCGv_i32 fp0 = tcg_temp_new_i32();
11505             gen_load_fpr32(ctx, fp0, fs);
11506             tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
11507             tcg_temp_free_i32(fp0);
11508         }
11509         break;
11510     case OPC_SDXC1:
11511         check_cop1x(ctx);
11512         check_cp1_registers(ctx, fs);
11513         {
11514             TCGv_i64 fp0 = tcg_temp_new_i64();
11515             gen_load_fpr64(ctx, fp0, fs);
11516             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11517             tcg_temp_free_i64(fp0);
11518         }
11519         break;
11520     case OPC_SUXC1:
11521         check_cp1_64bitmode(ctx);
11522         tcg_gen_andi_tl(t0, t0, ~0x7);
11523         {
11524             TCGv_i64 fp0 = tcg_temp_new_i64();
11525             gen_load_fpr64(ctx, fp0, fs);
11526             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11527             tcg_temp_free_i64(fp0);
11528         }
11529         break;
11530     }
11531     tcg_temp_free(t0);
11532 }
11533
11534 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
11535                             int fd, int fr, int fs, int ft)
11536 {
11537     switch (opc) {
11538     case OPC_ALNV_PS:
11539         check_ps(ctx);
11540         {
11541             TCGv t0 = tcg_temp_local_new();
11542             TCGv_i32 fp = tcg_temp_new_i32();
11543             TCGv_i32 fph = tcg_temp_new_i32();
11544             TCGLabel *l1 = gen_new_label();
11545             TCGLabel *l2 = gen_new_label();
11546
11547             gen_load_gpr(t0, fr);
11548             tcg_gen_andi_tl(t0, t0, 0x7);
11549
11550             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
11551             gen_load_fpr32(ctx, fp, fs);
11552             gen_load_fpr32h(ctx, fph, fs);
11553             gen_store_fpr32(ctx, fp, fd);
11554             gen_store_fpr32h(ctx, fph, fd);
11555             tcg_gen_br(l2);
11556             gen_set_label(l1);
11557             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
11558             tcg_temp_free(t0);
11559 #ifdef TARGET_WORDS_BIGENDIAN
11560             gen_load_fpr32(ctx, fp, fs);
11561             gen_load_fpr32h(ctx, fph, ft);
11562             gen_store_fpr32h(ctx, fp, fd);
11563             gen_store_fpr32(ctx, fph, fd);
11564 #else
11565             gen_load_fpr32h(ctx, fph, fs);
11566             gen_load_fpr32(ctx, fp, ft);
11567             gen_store_fpr32(ctx, fph, fd);
11568             gen_store_fpr32h(ctx, fp, fd);
11569 #endif
11570             gen_set_label(l2);
11571             tcg_temp_free_i32(fp);
11572             tcg_temp_free_i32(fph);
11573         }
11574         break;
11575     case OPC_MADD_S:
11576         check_cop1x(ctx);
11577         {
11578             TCGv_i32 fp0 = tcg_temp_new_i32();
11579             TCGv_i32 fp1 = tcg_temp_new_i32();
11580             TCGv_i32 fp2 = tcg_temp_new_i32();
11581
11582             gen_load_fpr32(ctx, fp0, fs);
11583             gen_load_fpr32(ctx, fp1, ft);
11584             gen_load_fpr32(ctx, fp2, fr);
11585             gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
11586             tcg_temp_free_i32(fp0);
11587             tcg_temp_free_i32(fp1);
11588             gen_store_fpr32(ctx, fp2, fd);
11589             tcg_temp_free_i32(fp2);
11590         }
11591         break;
11592     case OPC_MADD_D:
11593         check_cop1x(ctx);
11594         check_cp1_registers(ctx, fd | fs | ft | fr);
11595         {
11596             TCGv_i64 fp0 = tcg_temp_new_i64();
11597             TCGv_i64 fp1 = tcg_temp_new_i64();
11598             TCGv_i64 fp2 = tcg_temp_new_i64();
11599
11600             gen_load_fpr64(ctx, fp0, fs);
11601             gen_load_fpr64(ctx, fp1, ft);
11602             gen_load_fpr64(ctx, fp2, fr);
11603             gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
11604             tcg_temp_free_i64(fp0);
11605             tcg_temp_free_i64(fp1);
11606             gen_store_fpr64(ctx, fp2, fd);
11607             tcg_temp_free_i64(fp2);
11608         }
11609         break;
11610     case OPC_MADD_PS:
11611         check_ps(ctx);
11612         {
11613             TCGv_i64 fp0 = tcg_temp_new_i64();
11614             TCGv_i64 fp1 = tcg_temp_new_i64();
11615             TCGv_i64 fp2 = tcg_temp_new_i64();
11616
11617             gen_load_fpr64(ctx, fp0, fs);
11618             gen_load_fpr64(ctx, fp1, ft);
11619             gen_load_fpr64(ctx, fp2, fr);
11620             gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
11621             tcg_temp_free_i64(fp0);
11622             tcg_temp_free_i64(fp1);
11623             gen_store_fpr64(ctx, fp2, fd);
11624             tcg_temp_free_i64(fp2);
11625         }
11626         break;
11627     case OPC_MSUB_S:
11628         check_cop1x(ctx);
11629         {
11630             TCGv_i32 fp0 = tcg_temp_new_i32();
11631             TCGv_i32 fp1 = tcg_temp_new_i32();
11632             TCGv_i32 fp2 = tcg_temp_new_i32();
11633
11634             gen_load_fpr32(ctx, fp0, fs);
11635             gen_load_fpr32(ctx, fp1, ft);
11636             gen_load_fpr32(ctx, fp2, fr);
11637             gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
11638             tcg_temp_free_i32(fp0);
11639             tcg_temp_free_i32(fp1);
11640             gen_store_fpr32(ctx, fp2, fd);
11641             tcg_temp_free_i32(fp2);
11642         }
11643         break;
11644     case OPC_MSUB_D:
11645         check_cop1x(ctx);
11646         check_cp1_registers(ctx, fd | fs | ft | fr);
11647         {
11648             TCGv_i64 fp0 = tcg_temp_new_i64();
11649             TCGv_i64 fp1 = tcg_temp_new_i64();
11650             TCGv_i64 fp2 = tcg_temp_new_i64();
11651
11652             gen_load_fpr64(ctx, fp0, fs);
11653             gen_load_fpr64(ctx, fp1, ft);
11654             gen_load_fpr64(ctx, fp2, fr);
11655             gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
11656             tcg_temp_free_i64(fp0);
11657             tcg_temp_free_i64(fp1);
11658             gen_store_fpr64(ctx, fp2, fd);
11659             tcg_temp_free_i64(fp2);
11660         }
11661         break;
11662     case OPC_MSUB_PS:
11663         check_ps(ctx);
11664         {
11665             TCGv_i64 fp0 = tcg_temp_new_i64();
11666             TCGv_i64 fp1 = tcg_temp_new_i64();
11667             TCGv_i64 fp2 = tcg_temp_new_i64();
11668
11669             gen_load_fpr64(ctx, fp0, fs);
11670             gen_load_fpr64(ctx, fp1, ft);
11671             gen_load_fpr64(ctx, fp2, fr);
11672             gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
11673             tcg_temp_free_i64(fp0);
11674             tcg_temp_free_i64(fp1);
11675             gen_store_fpr64(ctx, fp2, fd);
11676             tcg_temp_free_i64(fp2);
11677         }
11678         break;
11679     case OPC_NMADD_S:
11680         check_cop1x(ctx);
11681         {
11682             TCGv_i32 fp0 = tcg_temp_new_i32();
11683             TCGv_i32 fp1 = tcg_temp_new_i32();
11684             TCGv_i32 fp2 = tcg_temp_new_i32();
11685
11686             gen_load_fpr32(ctx, fp0, fs);
11687             gen_load_fpr32(ctx, fp1, ft);
11688             gen_load_fpr32(ctx, fp2, fr);
11689             gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
11690             tcg_temp_free_i32(fp0);
11691             tcg_temp_free_i32(fp1);
11692             gen_store_fpr32(ctx, fp2, fd);
11693             tcg_temp_free_i32(fp2);
11694         }
11695         break;
11696     case OPC_NMADD_D:
11697         check_cop1x(ctx);
11698         check_cp1_registers(ctx, fd | fs | ft | fr);
11699         {
11700             TCGv_i64 fp0 = tcg_temp_new_i64();
11701             TCGv_i64 fp1 = tcg_temp_new_i64();
11702             TCGv_i64 fp2 = tcg_temp_new_i64();
11703
11704             gen_load_fpr64(ctx, fp0, fs);
11705             gen_load_fpr64(ctx, fp1, ft);
11706             gen_load_fpr64(ctx, fp2, fr);
11707             gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
11708             tcg_temp_free_i64(fp0);
11709             tcg_temp_free_i64(fp1);
11710             gen_store_fpr64(ctx, fp2, fd);
11711             tcg_temp_free_i64(fp2);
11712         }
11713         break;
11714     case OPC_NMADD_PS:
11715         check_ps(ctx);
11716         {
11717             TCGv_i64 fp0 = tcg_temp_new_i64();
11718             TCGv_i64 fp1 = tcg_temp_new_i64();
11719             TCGv_i64 fp2 = tcg_temp_new_i64();
11720
11721             gen_load_fpr64(ctx, fp0, fs);
11722             gen_load_fpr64(ctx, fp1, ft);
11723             gen_load_fpr64(ctx, fp2, fr);
11724             gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
11725             tcg_temp_free_i64(fp0);
11726             tcg_temp_free_i64(fp1);
11727             gen_store_fpr64(ctx, fp2, fd);
11728             tcg_temp_free_i64(fp2);
11729         }
11730         break;
11731     case OPC_NMSUB_S:
11732         check_cop1x(ctx);
11733         {
11734             TCGv_i32 fp0 = tcg_temp_new_i32();
11735             TCGv_i32 fp1 = tcg_temp_new_i32();
11736             TCGv_i32 fp2 = tcg_temp_new_i32();
11737
11738             gen_load_fpr32(ctx, fp0, fs);
11739             gen_load_fpr32(ctx, fp1, ft);
11740             gen_load_fpr32(ctx, fp2, fr);
11741             gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
11742             tcg_temp_free_i32(fp0);
11743             tcg_temp_free_i32(fp1);
11744             gen_store_fpr32(ctx, fp2, fd);
11745             tcg_temp_free_i32(fp2);
11746         }
11747         break;
11748     case OPC_NMSUB_D:
11749         check_cop1x(ctx);
11750         check_cp1_registers(ctx, fd | fs | ft | fr);
11751         {
11752             TCGv_i64 fp0 = tcg_temp_new_i64();
11753             TCGv_i64 fp1 = tcg_temp_new_i64();
11754             TCGv_i64 fp2 = tcg_temp_new_i64();
11755
11756             gen_load_fpr64(ctx, fp0, fs);
11757             gen_load_fpr64(ctx, fp1, ft);
11758             gen_load_fpr64(ctx, fp2, fr);
11759             gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
11760             tcg_temp_free_i64(fp0);
11761             tcg_temp_free_i64(fp1);
11762             gen_store_fpr64(ctx, fp2, fd);
11763             tcg_temp_free_i64(fp2);
11764         }
11765         break;
11766     case OPC_NMSUB_PS:
11767         check_ps(ctx);
11768         {
11769             TCGv_i64 fp0 = tcg_temp_new_i64();
11770             TCGv_i64 fp1 = tcg_temp_new_i64();
11771             TCGv_i64 fp2 = tcg_temp_new_i64();
11772
11773             gen_load_fpr64(ctx, fp0, fs);
11774             gen_load_fpr64(ctx, fp1, ft);
11775             gen_load_fpr64(ctx, fp2, fr);
11776             gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
11777             tcg_temp_free_i64(fp0);
11778             tcg_temp_free_i64(fp1);
11779             gen_store_fpr64(ctx, fp2, fd);
11780             tcg_temp_free_i64(fp2);
11781         }
11782         break;
11783     default:
11784         MIPS_INVAL("flt3_arith");
11785         generate_exception_end(ctx, EXCP_RI);
11786         return;
11787     }
11788 }
11789
11790 static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
11791 {
11792     TCGv t0;
11793
11794 #if !defined(CONFIG_USER_ONLY)
11795     /* The Linux kernel will emulate rdhwr if it's not supported natively.
11796        Therefore only check the ISA in system mode.  */
11797     check_insn(ctx, ISA_MIPS32R2);
11798 #endif
11799     t0 = tcg_temp_new();
11800
11801     switch (rd) {
11802     case 0:
11803         gen_helper_rdhwr_cpunum(t0, cpu_env);
11804         gen_store_gpr(t0, rt);
11805         break;
11806     case 1:
11807         gen_helper_rdhwr_synci_step(t0, cpu_env);
11808         gen_store_gpr(t0, rt);
11809         break;
11810     case 2:
11811         if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
11812             gen_io_start();
11813         }
11814         gen_helper_rdhwr_cc(t0, cpu_env);
11815         if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
11816             gen_io_end();
11817         }
11818         gen_store_gpr(t0, rt);
11819         /* Break the TB to be able to take timer interrupts immediately
11820            after reading count. DISAS_STOP isn't sufficient, we need to ensure
11821            we break completely out of translated code.  */
11822         gen_save_pc(ctx->base.pc_next + 4);
11823         ctx->base.is_jmp = DISAS_EXIT;
11824         break;
11825     case 3:
11826         gen_helper_rdhwr_ccres(t0, cpu_env);
11827         gen_store_gpr(t0, rt);
11828         break;
11829     case 4:
11830         check_insn(ctx, ISA_MIPS32R6);
11831         if (sel != 0) {
11832             /* Performance counter registers are not implemented other than
11833              * control register 0.
11834              */
11835             generate_exception(ctx, EXCP_RI);
11836         }
11837         gen_helper_rdhwr_performance(t0, cpu_env);
11838         gen_store_gpr(t0, rt);
11839         break;
11840     case 5:
11841         check_insn(ctx, ISA_MIPS32R6);
11842         gen_helper_rdhwr_xnp(t0, cpu_env);
11843         gen_store_gpr(t0, rt);
11844         break;
11845     case 29:
11846 #if defined(CONFIG_USER_ONLY)
11847         tcg_gen_ld_tl(t0, cpu_env,
11848                       offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
11849         gen_store_gpr(t0, rt);
11850         break;
11851 #else
11852         if ((ctx->hflags & MIPS_HFLAG_CP0) ||
11853             (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
11854             tcg_gen_ld_tl(t0, cpu_env,
11855                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
11856             gen_store_gpr(t0, rt);
11857         } else {
11858             generate_exception_end(ctx, EXCP_RI);
11859         }
11860         break;
11861 #endif
11862     default:            /* Invalid */
11863         MIPS_INVAL("rdhwr");
11864         generate_exception_end(ctx, EXCP_RI);
11865         break;
11866     }
11867     tcg_temp_free(t0);
11868 }
11869
11870 static inline void clear_branch_hflags(DisasContext *ctx)
11871 {
11872     ctx->hflags &= ~MIPS_HFLAG_BMASK;
11873     if (ctx->base.is_jmp == DISAS_NEXT) {
11874         save_cpu_state(ctx, 0);
11875     } else {
11876         /* it is not safe to save ctx->hflags as hflags may be changed
11877            in execution time by the instruction in delay / forbidden slot. */
11878         tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
11879     }
11880 }
11881
11882 static void gen_branch(DisasContext *ctx, int insn_bytes)
11883 {
11884     if (ctx->hflags & MIPS_HFLAG_BMASK) {
11885         int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
11886         /* Branches completion */
11887         clear_branch_hflags(ctx);
11888         ctx->base.is_jmp = DISAS_NORETURN;
11889         /* FIXME: Need to clear can_do_io.  */
11890         switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
11891         case MIPS_HFLAG_FBNSLOT:
11892             gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
11893             break;
11894         case MIPS_HFLAG_B:
11895             /* unconditional branch */
11896             if (proc_hflags & MIPS_HFLAG_BX) {
11897                 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
11898             }
11899             gen_goto_tb(ctx, 0, ctx->btarget);
11900             break;
11901         case MIPS_HFLAG_BL:
11902             /* blikely taken case */
11903             gen_goto_tb(ctx, 0, ctx->btarget);
11904             break;
11905         case MIPS_HFLAG_BC:
11906             /* Conditional branch */
11907             {
11908                 TCGLabel *l1 = gen_new_label();
11909
11910                 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
11911                 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
11912                 gen_set_label(l1);
11913                 gen_goto_tb(ctx, 0, ctx->btarget);
11914             }
11915             break;
11916         case MIPS_HFLAG_BR:
11917             /* unconditional branch to register */
11918             if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
11919                 TCGv t0 = tcg_temp_new();
11920                 TCGv_i32 t1 = tcg_temp_new_i32();
11921
11922                 tcg_gen_andi_tl(t0, btarget, 0x1);
11923                 tcg_gen_trunc_tl_i32(t1, t0);
11924                 tcg_temp_free(t0);
11925                 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
11926                 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
11927                 tcg_gen_or_i32(hflags, hflags, t1);
11928                 tcg_temp_free_i32(t1);
11929
11930                 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
11931             } else {
11932                 tcg_gen_mov_tl(cpu_PC, btarget);
11933             }
11934             if (ctx->base.singlestep_enabled) {
11935                 save_cpu_state(ctx, 0);
11936                 gen_helper_raise_exception_debug(cpu_env);
11937             }
11938             tcg_gen_lookup_and_goto_ptr();
11939             break;
11940         default:
11941             fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
11942             abort();
11943         }
11944     }
11945 }
11946
11947 /* Compact Branches */
11948 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
11949                                        int rs, int rt, int32_t offset)
11950 {
11951     int bcond_compute = 0;
11952     TCGv t0 = tcg_temp_new();
11953     TCGv t1 = tcg_temp_new();
11954     int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
11955
11956     if (ctx->hflags & MIPS_HFLAG_BMASK) {
11957 #ifdef MIPS_DEBUG_DISAS
11958         LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
11959                   "\n", ctx->base.pc_next);
11960 #endif
11961         generate_exception_end(ctx, EXCP_RI);
11962         goto out;
11963     }
11964
11965     /* Load needed operands and calculate btarget */
11966     switch (opc) {
11967     /* compact branch */
11968     case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11969     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11970         gen_load_gpr(t0, rs);
11971         gen_load_gpr(t1, rt);
11972         bcond_compute = 1;
11973         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11974         if (rs <= rt && rs == 0) {
11975             /* OPC_BEQZALC, OPC_BNEZALC */
11976             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11977         }
11978         break;
11979     case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11980     case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11981         gen_load_gpr(t0, rs);
11982         gen_load_gpr(t1, rt);
11983         bcond_compute = 1;
11984         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11985         break;
11986     case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11987     case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11988         if (rs == 0 || rs == rt) {
11989             /* OPC_BLEZALC, OPC_BGEZALC */
11990             /* OPC_BGTZALC, OPC_BLTZALC */
11991             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11992         }
11993         gen_load_gpr(t0, rs);
11994         gen_load_gpr(t1, rt);
11995         bcond_compute = 1;
11996         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11997         break;
11998     case OPC_BC:
11999     case OPC_BALC:
12000         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12001         break;
12002     case OPC_BEQZC:
12003     case OPC_BNEZC:
12004         if (rs != 0) {
12005             /* OPC_BEQZC, OPC_BNEZC */
12006             gen_load_gpr(t0, rs);
12007             bcond_compute = 1;
12008             ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12009         } else {
12010             /* OPC_JIC, OPC_JIALC */
12011             TCGv tbase = tcg_temp_new();
12012             TCGv toffset = tcg_temp_new();
12013
12014             gen_load_gpr(tbase, rt);
12015             tcg_gen_movi_tl(toffset, offset);
12016             gen_op_addr_add(ctx, btarget, tbase, toffset);
12017             tcg_temp_free(tbase);
12018             tcg_temp_free(toffset);
12019         }
12020         break;
12021     default:
12022         MIPS_INVAL("Compact branch/jump");
12023         generate_exception_end(ctx, EXCP_RI);
12024         goto out;
12025     }
12026
12027     if (bcond_compute == 0) {
12028         /* Uncoditional compact branch */
12029         switch (opc) {
12030         case OPC_JIALC:
12031             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12032             /* Fallthrough */
12033         case OPC_JIC:
12034             ctx->hflags |= MIPS_HFLAG_BR;
12035             break;
12036         case OPC_BALC:
12037             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12038             /* Fallthrough */
12039         case OPC_BC:
12040             ctx->hflags |= MIPS_HFLAG_B;
12041             break;
12042         default:
12043             MIPS_INVAL("Compact branch/jump");
12044             generate_exception_end(ctx, EXCP_RI);
12045             goto out;
12046         }
12047
12048         /* Generating branch here as compact branches don't have delay slot */
12049         gen_branch(ctx, 4);
12050     } else {
12051         /* Conditional compact branch */
12052         TCGLabel *fs = gen_new_label();
12053         save_cpu_state(ctx, 0);
12054
12055         switch (opc) {
12056         case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12057             if (rs == 0 && rt != 0) {
12058                 /* OPC_BLEZALC */
12059                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12060             } else if (rs != 0 && rt != 0 && rs == rt) {
12061                 /* OPC_BGEZALC */
12062                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12063             } else {
12064                 /* OPC_BGEUC */
12065                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
12066             }
12067             break;
12068         case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12069             if (rs == 0 && rt != 0) {
12070                 /* OPC_BGTZALC */
12071                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12072             } else if (rs != 0 && rt != 0 && rs == rt) {
12073                 /* OPC_BLTZALC */
12074                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12075             } else {
12076                 /* OPC_BLTUC */
12077                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
12078             }
12079             break;
12080         case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12081             if (rs == 0 && rt != 0) {
12082                 /* OPC_BLEZC */
12083                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12084             } else if (rs != 0 && rt != 0 && rs == rt) {
12085                 /* OPC_BGEZC */
12086                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12087             } else {
12088                 /* OPC_BGEC */
12089                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
12090             }
12091             break;
12092         case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12093             if (rs == 0 && rt != 0) {
12094                 /* OPC_BGTZC */
12095                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12096             } else if (rs != 0 && rt != 0 && rs == rt) {
12097                 /* OPC_BLTZC */
12098                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12099             } else {
12100                 /* OPC_BLTC */
12101                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
12102             }
12103             break;
12104         case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12105         case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12106             if (rs >= rt) {
12107                 /* OPC_BOVC, OPC_BNVC */
12108                 TCGv t2 = tcg_temp_new();
12109                 TCGv t3 = tcg_temp_new();
12110                 TCGv t4 = tcg_temp_new();
12111                 TCGv input_overflow = tcg_temp_new();
12112
12113                 gen_load_gpr(t0, rs);
12114                 gen_load_gpr(t1, rt);
12115                 tcg_gen_ext32s_tl(t2, t0);
12116                 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
12117                 tcg_gen_ext32s_tl(t3, t1);
12118                 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
12119                 tcg_gen_or_tl(input_overflow, input_overflow, t4);
12120
12121                 tcg_gen_add_tl(t4, t2, t3);
12122                 tcg_gen_ext32s_tl(t4, t4);
12123                 tcg_gen_xor_tl(t2, t2, t3);
12124                 tcg_gen_xor_tl(t3, t4, t3);
12125                 tcg_gen_andc_tl(t2, t3, t2);
12126                 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
12127                 tcg_gen_or_tl(t4, t4, input_overflow);
12128                 if (opc == OPC_BOVC) {
12129                     /* OPC_BOVC */
12130                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
12131                 } else {
12132                     /* OPC_BNVC */
12133                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
12134                 }
12135                 tcg_temp_free(input_overflow);
12136                 tcg_temp_free(t4);
12137                 tcg_temp_free(t3);
12138                 tcg_temp_free(t2);
12139             } else if (rs < rt && rs == 0) {
12140                 /* OPC_BEQZALC, OPC_BNEZALC */
12141                 if (opc == OPC_BEQZALC) {
12142                     /* OPC_BEQZALC */
12143                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
12144                 } else {
12145                     /* OPC_BNEZALC */
12146                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
12147                 }
12148             } else {
12149                 /* OPC_BEQC, OPC_BNEC */
12150                 if (opc == OPC_BEQC) {
12151                     /* OPC_BEQC */
12152                     tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
12153                 } else {
12154                     /* OPC_BNEC */
12155                     tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
12156                 }
12157             }
12158             break;
12159         case OPC_BEQZC:
12160             tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
12161             break;
12162         case OPC_BNEZC:
12163             tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
12164             break;
12165         default:
12166             MIPS_INVAL("Compact conditional branch/jump");
12167             generate_exception_end(ctx, EXCP_RI);
12168             goto out;
12169         }
12170
12171         /* Generating branch here as compact branches don't have delay slot */
12172         gen_goto_tb(ctx, 1, ctx->btarget);
12173         gen_set_label(fs);
12174
12175         ctx->hflags |= MIPS_HFLAG_FBNSLOT;
12176     }
12177
12178 out:
12179     tcg_temp_free(t0);
12180     tcg_temp_free(t1);
12181 }
12182
12183 /* ISA extensions (ASEs) */
12184 /* MIPS16 extension to MIPS32 */
12185
12186 /* MIPS16 major opcodes */
12187 enum {
12188   M16_OPC_ADDIUSP = 0x00,
12189   M16_OPC_ADDIUPC = 0x01,
12190   M16_OPC_B = 0x02,
12191   M16_OPC_JAL = 0x03,
12192   M16_OPC_BEQZ = 0x04,
12193   M16_OPC_BNEQZ = 0x05,
12194   M16_OPC_SHIFT = 0x06,
12195   M16_OPC_LD = 0x07,
12196   M16_OPC_RRIA = 0x08,
12197   M16_OPC_ADDIU8 = 0x09,
12198   M16_OPC_SLTI = 0x0a,
12199   M16_OPC_SLTIU = 0x0b,
12200   M16_OPC_I8 = 0x0c,
12201   M16_OPC_LI = 0x0d,
12202   M16_OPC_CMPI = 0x0e,
12203   M16_OPC_SD = 0x0f,
12204   M16_OPC_LB = 0x10,
12205   M16_OPC_LH = 0x11,
12206   M16_OPC_LWSP = 0x12,
12207   M16_OPC_LW = 0x13,
12208   M16_OPC_LBU = 0x14,
12209   M16_OPC_LHU = 0x15,
12210   M16_OPC_LWPC = 0x16,
12211   M16_OPC_LWU = 0x17,
12212   M16_OPC_SB = 0x18,
12213   M16_OPC_SH = 0x19,
12214   M16_OPC_SWSP = 0x1a,
12215   M16_OPC_SW = 0x1b,
12216   M16_OPC_RRR = 0x1c,
12217   M16_OPC_RR = 0x1d,
12218   M16_OPC_EXTEND = 0x1e,
12219   M16_OPC_I64 = 0x1f
12220 };
12221
12222 /* I8 funct field */
12223 enum {
12224   I8_BTEQZ = 0x0,
12225   I8_BTNEZ = 0x1,
12226   I8_SWRASP = 0x2,
12227   I8_ADJSP = 0x3,
12228   I8_SVRS = 0x4,
12229   I8_MOV32R = 0x5,
12230   I8_MOVR32 = 0x7
12231 };
12232
12233 /* RRR f field */
12234 enum {
12235   RRR_DADDU = 0x0,
12236   RRR_ADDU = 0x1,
12237   RRR_DSUBU = 0x2,
12238   RRR_SUBU = 0x3
12239 };
12240
12241 /* RR funct field */
12242 enum {
12243   RR_JR = 0x00,
12244   RR_SDBBP = 0x01,
12245   RR_SLT = 0x02,
12246   RR_SLTU = 0x03,
12247   RR_SLLV = 0x04,
12248   RR_BREAK = 0x05,
12249   RR_SRLV = 0x06,
12250   RR_SRAV = 0x07,
12251   RR_DSRL = 0x08,
12252   RR_CMP = 0x0a,
12253   RR_NEG = 0x0b,
12254   RR_AND = 0x0c,
12255   RR_OR = 0x0d,
12256   RR_XOR = 0x0e,
12257   RR_NOT = 0x0f,
12258   RR_MFHI = 0x10,
12259   RR_CNVT = 0x11,
12260   RR_MFLO = 0x12,
12261   RR_DSRA = 0x13,
12262   RR_DSLLV = 0x14,
12263   RR_DSRLV = 0x16,
12264   RR_DSRAV = 0x17,
12265   RR_MULT = 0x18,
12266   RR_MULTU = 0x19,
12267   RR_DIV = 0x1a,
12268   RR_DIVU = 0x1b,
12269   RR_DMULT = 0x1c,
12270   RR_DMULTU = 0x1d,
12271   RR_DDIV = 0x1e,
12272   RR_DDIVU = 0x1f
12273 };
12274
12275 /* I64 funct field */
12276 enum {
12277   I64_LDSP = 0x0,
12278   I64_SDSP = 0x1,
12279   I64_SDRASP = 0x2,
12280   I64_DADJSP = 0x3,
12281   I64_LDPC = 0x4,
12282   I64_DADDIU5 = 0x5,
12283   I64_DADDIUPC = 0x6,
12284   I64_DADDIUSP = 0x7
12285 };
12286
12287 /* RR ry field for CNVT */
12288 enum {
12289   RR_RY_CNVT_ZEB = 0x0,
12290   RR_RY_CNVT_ZEH = 0x1,
12291   RR_RY_CNVT_ZEW = 0x2,
12292   RR_RY_CNVT_SEB = 0x4,
12293   RR_RY_CNVT_SEH = 0x5,
12294   RR_RY_CNVT_SEW = 0x6,
12295 };
12296
12297 static int xlat (int r)
12298 {
12299   static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12300
12301   return map[r];
12302 }
12303
12304 static void gen_mips16_save (DisasContext *ctx,
12305                              int xsregs, int aregs,
12306                              int do_ra, int do_s0, int do_s1,
12307                              int framesize)
12308 {
12309     TCGv t0 = tcg_temp_new();
12310     TCGv t1 = tcg_temp_new();
12311     TCGv t2 = tcg_temp_new();
12312     int args, astatic;
12313
12314     switch (aregs) {
12315     case 0:
12316     case 1:
12317     case 2:
12318     case 3:
12319     case 11:
12320         args = 0;
12321         break;
12322     case 4:
12323     case 5:
12324     case 6:
12325     case 7:
12326         args = 1;
12327         break;
12328     case 8:
12329     case 9:
12330     case 10:
12331         args = 2;
12332         break;
12333     case 12:
12334     case 13:
12335         args = 3;
12336         break;
12337     case 14:
12338         args = 4;
12339         break;
12340     default:
12341         generate_exception_end(ctx, EXCP_RI);
12342         return;
12343     }
12344
12345     switch (args) {
12346     case 4:
12347         gen_base_offset_addr(ctx, t0, 29, 12);
12348         gen_load_gpr(t1, 7);
12349         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12350         /* Fall through */
12351     case 3:
12352         gen_base_offset_addr(ctx, t0, 29, 8);
12353         gen_load_gpr(t1, 6);
12354         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12355         /* Fall through */
12356     case 2:
12357         gen_base_offset_addr(ctx, t0, 29, 4);
12358         gen_load_gpr(t1, 5);
12359         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12360         /* Fall through */
12361     case 1:
12362         gen_base_offset_addr(ctx, t0, 29, 0);
12363         gen_load_gpr(t1, 4);
12364         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12365     }
12366
12367     gen_load_gpr(t0, 29);
12368
12369 #define DECR_AND_STORE(reg) do {                                 \
12370         tcg_gen_movi_tl(t2, -4);                                 \
12371         gen_op_addr_add(ctx, t0, t0, t2);                        \
12372         gen_load_gpr(t1, reg);                                   \
12373         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
12374     } while (0)
12375
12376     if (do_ra) {
12377         DECR_AND_STORE(31);
12378     }
12379
12380     switch (xsregs) {
12381     case 7:
12382         DECR_AND_STORE(30);
12383         /* Fall through */
12384     case 6:
12385         DECR_AND_STORE(23);
12386         /* Fall through */
12387     case 5:
12388         DECR_AND_STORE(22);
12389         /* Fall through */
12390     case 4:
12391         DECR_AND_STORE(21);
12392         /* Fall through */
12393     case 3:
12394         DECR_AND_STORE(20);
12395         /* Fall through */
12396     case 2:
12397         DECR_AND_STORE(19);
12398         /* Fall through */
12399     case 1:
12400         DECR_AND_STORE(18);
12401     }
12402
12403     if (do_s1) {
12404         DECR_AND_STORE(17);
12405     }
12406     if (do_s0) {
12407         DECR_AND_STORE(16);
12408     }
12409
12410     switch (aregs) {
12411     case 0:
12412     case 4:
12413     case 8:
12414     case 12:
12415     case 14:
12416         astatic = 0;
12417         break;
12418     case 1:
12419     case 5:
12420     case 9:
12421     case 13:
12422         astatic = 1;
12423         break;
12424     case 2:
12425     case 6:
12426     case 10:
12427         astatic = 2;
12428         break;
12429     case 3:
12430     case 7:
12431         astatic = 3;
12432         break;
12433     case 11:
12434         astatic = 4;
12435         break;
12436     default:
12437         generate_exception_end(ctx, EXCP_RI);
12438         return;
12439     }
12440
12441     if (astatic > 0) {
12442         DECR_AND_STORE(7);
12443         if (astatic > 1) {
12444             DECR_AND_STORE(6);
12445             if (astatic > 2) {
12446                 DECR_AND_STORE(5);
12447                 if (astatic > 3) {
12448                     DECR_AND_STORE(4);
12449                 }
12450             }
12451         }
12452     }
12453 #undef DECR_AND_STORE
12454
12455     tcg_gen_movi_tl(t2, -framesize);
12456     gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
12457     tcg_temp_free(t0);
12458     tcg_temp_free(t1);
12459     tcg_temp_free(t2);
12460 }
12461
12462 static void gen_mips16_restore (DisasContext *ctx,
12463                                 int xsregs, int aregs,
12464                                 int do_ra, int do_s0, int do_s1,
12465                                 int framesize)
12466 {
12467     int astatic;
12468     TCGv t0 = tcg_temp_new();
12469     TCGv t1 = tcg_temp_new();
12470     TCGv t2 = tcg_temp_new();
12471
12472     tcg_gen_movi_tl(t2, framesize);
12473     gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
12474
12475 #define DECR_AND_LOAD(reg) do {                            \
12476         tcg_gen_movi_tl(t2, -4);                           \
12477         gen_op_addr_add(ctx, t0, t0, t2);                  \
12478         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
12479         gen_store_gpr(t1, reg);                            \
12480     } while (0)
12481
12482     if (do_ra) {
12483         DECR_AND_LOAD(31);
12484     }
12485
12486     switch (xsregs) {
12487     case 7:
12488         DECR_AND_LOAD(30);
12489         /* Fall through */
12490     case 6:
12491         DECR_AND_LOAD(23);
12492         /* Fall through */
12493     case 5:
12494         DECR_AND_LOAD(22);
12495         /* Fall through */
12496     case 4:
12497         DECR_AND_LOAD(21);
12498         /* Fall through */
12499     case 3:
12500         DECR_AND_LOAD(20);
12501         /* Fall through */
12502     case 2:
12503         DECR_AND_LOAD(19);
12504         /* Fall through */
12505     case 1:
12506         DECR_AND_LOAD(18);
12507     }
12508
12509     if (do_s1) {
12510         DECR_AND_LOAD(17);
12511     }
12512     if (do_s0) {
12513         DECR_AND_LOAD(16);
12514     }
12515
12516     switch (aregs) {
12517     case 0:
12518     case 4:
12519     case 8:
12520     case 12:
12521     case 14:
12522         astatic = 0;
12523         break;
12524     case 1:
12525     case 5:
12526     case 9:
12527     case 13:
12528         astatic = 1;
12529         break;
12530     case 2:
12531     case 6:
12532     case 10:
12533         astatic = 2;
12534         break;
12535     case 3:
12536     case 7:
12537         astatic = 3;
12538         break;
12539     case 11:
12540         astatic = 4;
12541         break;
12542     default:
12543         generate_exception_end(ctx, EXCP_RI);
12544         return;
12545     }
12546
12547     if (astatic > 0) {
12548         DECR_AND_LOAD(7);
12549         if (astatic > 1) {
12550             DECR_AND_LOAD(6);
12551             if (astatic > 2) {
12552                 DECR_AND_LOAD(5);
12553                 if (astatic > 3) {
12554                     DECR_AND_LOAD(4);
12555                 }
12556             }
12557         }
12558     }
12559 #undef DECR_AND_LOAD
12560
12561     tcg_gen_movi_tl(t2, framesize);
12562     gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
12563     tcg_temp_free(t0);
12564     tcg_temp_free(t1);
12565     tcg_temp_free(t2);
12566 }
12567
12568 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
12569                          int is_64_bit, int extended)
12570 {
12571     TCGv t0;
12572
12573     if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
12574         generate_exception_end(ctx, EXCP_RI);
12575         return;
12576     }
12577
12578     t0 = tcg_temp_new();
12579
12580     tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
12581     tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
12582     if (!is_64_bit) {
12583         tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12584     }
12585
12586     tcg_temp_free(t0);
12587 }
12588
12589 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
12590                                 int16_t offset)
12591 {
12592     TCGv_i32 t0 = tcg_const_i32(op);
12593     TCGv t1 = tcg_temp_new();
12594     gen_base_offset_addr(ctx, t1, base, offset);
12595     gen_helper_cache(cpu_env, t1, t0);
12596 }
12597
12598 #if defined(TARGET_MIPS64)
12599 static void decode_i64_mips16 (DisasContext *ctx,
12600                                int ry, int funct, int16_t offset,
12601                                int extended)
12602 {
12603     switch (funct) {
12604     case I64_LDSP:
12605         check_insn(ctx, ISA_MIPS3);
12606         check_mips_64(ctx);
12607         offset = extended ? offset : offset << 3;
12608         gen_ld(ctx, OPC_LD, ry, 29, offset);
12609         break;
12610     case I64_SDSP:
12611         check_insn(ctx, ISA_MIPS3);
12612         check_mips_64(ctx);
12613         offset = extended ? offset : offset << 3;
12614         gen_st(ctx, OPC_SD, ry, 29, offset);
12615         break;
12616     case I64_SDRASP:
12617         check_insn(ctx, ISA_MIPS3);
12618         check_mips_64(ctx);
12619         offset = extended ? offset : (ctx->opcode & 0xff) << 3;
12620         gen_st(ctx, OPC_SD, 31, 29, offset);
12621         break;
12622     case I64_DADJSP:
12623         check_insn(ctx, ISA_MIPS3);
12624         check_mips_64(ctx);
12625         offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
12626         gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
12627         break;
12628     case I64_LDPC:
12629         check_insn(ctx, ISA_MIPS3);
12630         check_mips_64(ctx);
12631         if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
12632             generate_exception_end(ctx, EXCP_RI);
12633         } else {
12634             offset = extended ? offset : offset << 3;
12635             gen_ld(ctx, OPC_LDPC, ry, 0, offset);
12636         }
12637         break;
12638     case I64_DADDIU5:
12639         check_insn(ctx, ISA_MIPS3);
12640         check_mips_64(ctx);
12641         offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
12642         gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
12643         break;
12644     case I64_DADDIUPC:
12645         check_insn(ctx, ISA_MIPS3);
12646         check_mips_64(ctx);
12647         offset = extended ? offset : offset << 2;
12648         gen_addiupc(ctx, ry, offset, 1, extended);
12649         break;
12650     case I64_DADDIUSP:
12651         check_insn(ctx, ISA_MIPS3);
12652         check_mips_64(ctx);
12653         offset = extended ? offset : offset << 2;
12654         gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
12655         break;
12656     }
12657 }
12658 #endif
12659
12660 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
12661 {
12662     int extend = cpu_lduw_code(env, ctx->base.pc_next + 2);
12663     int op, rx, ry, funct, sa;
12664     int16_t imm, offset;
12665
12666     ctx->opcode = (ctx->opcode << 16) | extend;
12667     op = (ctx->opcode >> 11) & 0x1f;
12668     sa = (ctx->opcode >> 22) & 0x1f;
12669     funct = (ctx->opcode >> 8) & 0x7;
12670     rx = xlat((ctx->opcode >> 8) & 0x7);
12671     ry = xlat((ctx->opcode >> 5) & 0x7);
12672     offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
12673                               | ((ctx->opcode >> 21) & 0x3f) << 5
12674                               | (ctx->opcode & 0x1f));
12675
12676     /* The extended opcodes cleverly reuse the opcodes from their 16-bit
12677        counterparts.  */
12678     switch (op) {
12679     case M16_OPC_ADDIUSP:
12680         gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
12681         break;
12682     case M16_OPC_ADDIUPC:
12683         gen_addiupc(ctx, rx, imm, 0, 1);
12684         break;
12685     case M16_OPC_B:
12686         gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
12687         /* No delay slot, so just process as a normal instruction */
12688         break;
12689     case M16_OPC_BEQZ:
12690         gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
12691         /* No delay slot, so just process as a normal instruction */
12692         break;
12693     case M16_OPC_BNEQZ:
12694         gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
12695         /* No delay slot, so just process as a normal instruction */
12696         break;
12697     case M16_OPC_SHIFT:
12698         switch (ctx->opcode & 0x3) {
12699         case 0x0:
12700             gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
12701             break;
12702         case 0x1:
12703 #if defined(TARGET_MIPS64)
12704             check_mips_64(ctx);
12705             gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
12706 #else
12707             generate_exception_end(ctx, EXCP_RI);
12708 #endif
12709             break;
12710         case 0x2:
12711             gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
12712             break;
12713         case 0x3:
12714             gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
12715             break;
12716         }
12717         break;
12718 #if defined(TARGET_MIPS64)
12719     case M16_OPC_LD:
12720         check_insn(ctx, ISA_MIPS3);
12721         check_mips_64(ctx);
12722         gen_ld(ctx, OPC_LD, ry, rx, offset);
12723         break;
12724 #endif
12725     case M16_OPC_RRIA:
12726         imm = ctx->opcode & 0xf;
12727         imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
12728         imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
12729         imm = (int16_t) (imm << 1) >> 1;
12730         if ((ctx->opcode >> 4) & 0x1) {
12731 #if defined(TARGET_MIPS64)
12732             check_mips_64(ctx);
12733             gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
12734 #else
12735             generate_exception_end(ctx, EXCP_RI);
12736 #endif
12737         } else {
12738             gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
12739         }
12740         break;
12741     case M16_OPC_ADDIU8:
12742         gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
12743         break;
12744     case M16_OPC_SLTI:
12745         gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
12746         break;
12747     case M16_OPC_SLTIU:
12748         gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
12749         break;
12750     case M16_OPC_I8:
12751         switch (funct) {
12752         case I8_BTEQZ:
12753             gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
12754             break;
12755         case I8_BTNEZ:
12756             gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
12757             break;
12758         case I8_SWRASP:
12759             gen_st(ctx, OPC_SW, 31, 29, imm);
12760             break;
12761         case I8_ADJSP:
12762             gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
12763             break;
12764         case I8_SVRS:
12765             check_insn(ctx, ISA_MIPS32);
12766             {
12767                 int xsregs = (ctx->opcode >> 24) & 0x7;
12768                 int aregs = (ctx->opcode >> 16) & 0xf;
12769                 int do_ra = (ctx->opcode >> 6) & 0x1;
12770                 int do_s0 = (ctx->opcode >> 5) & 0x1;
12771                 int do_s1 = (ctx->opcode >> 4) & 0x1;
12772                 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
12773                                  | (ctx->opcode & 0xf)) << 3;
12774
12775                 if (ctx->opcode & (1 << 7)) {
12776                     gen_mips16_save(ctx, xsregs, aregs,
12777                                     do_ra, do_s0, do_s1,
12778                                     framesize);
12779                 } else {
12780                     gen_mips16_restore(ctx, xsregs, aregs,
12781                                        do_ra, do_s0, do_s1,
12782                                        framesize);
12783                 }
12784             }
12785             break;
12786         default:
12787             generate_exception_end(ctx, EXCP_RI);
12788             break;
12789         }
12790         break;
12791     case M16_OPC_LI:
12792         tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
12793         break;
12794     case M16_OPC_CMPI:
12795         tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
12796         break;
12797 #if defined(TARGET_MIPS64)
12798     case M16_OPC_SD:
12799         check_insn(ctx, ISA_MIPS3);
12800         check_mips_64(ctx);
12801         gen_st(ctx, OPC_SD, ry, rx, offset);
12802         break;
12803 #endif
12804     case M16_OPC_LB:
12805         gen_ld(ctx, OPC_LB, ry, rx, offset);
12806         break;
12807     case M16_OPC_LH:
12808         gen_ld(ctx, OPC_LH, ry, rx, offset);
12809         break;
12810     case M16_OPC_LWSP:
12811         gen_ld(ctx, OPC_LW, rx, 29, offset);
12812         break;
12813     case M16_OPC_LW:
12814         gen_ld(ctx, OPC_LW, ry, rx, offset);
12815         break;
12816     case M16_OPC_LBU:
12817         gen_ld(ctx, OPC_LBU, ry, rx, offset);
12818         break;
12819     case M16_OPC_LHU:
12820         gen_ld(ctx, OPC_LHU, ry, rx, offset);
12821         break;
12822     case M16_OPC_LWPC:
12823         gen_ld(ctx, OPC_LWPC, rx, 0, offset);
12824         break;
12825 #if defined(TARGET_MIPS64)
12826     case M16_OPC_LWU:
12827         check_insn(ctx, ISA_MIPS3);
12828         check_mips_64(ctx);
12829         gen_ld(ctx, OPC_LWU, ry, rx, offset);
12830         break;
12831 #endif
12832     case M16_OPC_SB:
12833         gen_st(ctx, OPC_SB, ry, rx, offset);
12834         break;
12835     case M16_OPC_SH:
12836         gen_st(ctx, OPC_SH, ry, rx, offset);
12837         break;
12838     case M16_OPC_SWSP:
12839         gen_st(ctx, OPC_SW, rx, 29, offset);
12840         break;
12841     case M16_OPC_SW:
12842         gen_st(ctx, OPC_SW, ry, rx, offset);
12843         break;
12844 #if defined(TARGET_MIPS64)
12845     case M16_OPC_I64:
12846         decode_i64_mips16(ctx, ry, funct, offset, 1);
12847         break;
12848 #endif
12849     default:
12850         generate_exception_end(ctx, EXCP_RI);
12851         break;
12852     }
12853
12854     return 4;
12855 }
12856
12857 static inline bool is_uhi(int sdbbp_code)
12858 {
12859 #ifdef CONFIG_USER_ONLY
12860     return false;
12861 #else
12862     return semihosting_enabled() && sdbbp_code == 1;
12863 #endif
12864 }
12865
12866 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
12867 {
12868     int rx, ry;
12869     int sa;
12870     int op, cnvt_op, op1, offset;
12871     int funct;
12872     int n_bytes;
12873
12874     op = (ctx->opcode >> 11) & 0x1f;
12875     sa = (ctx->opcode >> 2) & 0x7;
12876     sa = sa == 0 ? 8 : sa;
12877     rx = xlat((ctx->opcode >> 8) & 0x7);
12878     cnvt_op = (ctx->opcode >> 5) & 0x7;
12879     ry = xlat((ctx->opcode >> 5) & 0x7);
12880     op1 = offset = ctx->opcode & 0x1f;
12881
12882     n_bytes = 2;
12883
12884     switch (op) {
12885     case M16_OPC_ADDIUSP:
12886         {
12887             int16_t imm = ((uint8_t) ctx->opcode) << 2;
12888
12889             gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
12890         }
12891         break;
12892     case M16_OPC_ADDIUPC:
12893         gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
12894         break;
12895     case M16_OPC_B:
12896         offset = (ctx->opcode & 0x7ff) << 1;
12897         offset = (int16_t)(offset << 4) >> 4;
12898         gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
12899         /* No delay slot, so just process as a normal instruction */
12900         break;
12901     case M16_OPC_JAL:
12902         offset = cpu_lduw_code(env, ctx->base.pc_next + 2);
12903         offset = (((ctx->opcode & 0x1f) << 21)
12904                   | ((ctx->opcode >> 5) & 0x1f) << 16
12905                   | offset) << 2;
12906         op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
12907         gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
12908         n_bytes = 4;
12909         break;
12910     case M16_OPC_BEQZ:
12911         gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
12912                            ((int8_t)ctx->opcode) << 1, 0);
12913         /* No delay slot, so just process as a normal instruction */
12914         break;
12915     case M16_OPC_BNEQZ:
12916         gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
12917                            ((int8_t)ctx->opcode) << 1, 0);
12918         /* No delay slot, so just process as a normal instruction */
12919         break;
12920     case M16_OPC_SHIFT:
12921         switch (ctx->opcode & 0x3) {
12922         case 0x0:
12923             gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
12924             break;
12925         case 0x1:
12926 #if defined(TARGET_MIPS64)
12927             check_insn(ctx, ISA_MIPS3);
12928             check_mips_64(ctx);
12929             gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
12930 #else
12931             generate_exception_end(ctx, EXCP_RI);
12932 #endif
12933             break;
12934         case 0x2:
12935             gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
12936             break;
12937         case 0x3:
12938             gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
12939             break;
12940         }
12941         break;
12942 #if defined(TARGET_MIPS64)
12943     case M16_OPC_LD:
12944         check_insn(ctx, ISA_MIPS3);
12945         check_mips_64(ctx);
12946         gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
12947         break;
12948 #endif
12949     case M16_OPC_RRIA:
12950         {
12951             int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
12952
12953             if ((ctx->opcode >> 4) & 1) {
12954 #if defined(TARGET_MIPS64)
12955                 check_insn(ctx, ISA_MIPS3);
12956                 check_mips_64(ctx);
12957                 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
12958 #else
12959                 generate_exception_end(ctx, EXCP_RI);
12960 #endif
12961             } else {
12962                 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
12963             }
12964         }
12965         break;
12966     case M16_OPC_ADDIU8:
12967         {
12968             int16_t imm = (int8_t) ctx->opcode;
12969
12970             gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
12971         }
12972         break;
12973     case M16_OPC_SLTI:
12974         {
12975             int16_t imm = (uint8_t) ctx->opcode;
12976             gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
12977         }
12978         break;
12979     case M16_OPC_SLTIU:
12980         {
12981             int16_t imm = (uint8_t) ctx->opcode;
12982             gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
12983         }
12984         break;
12985     case M16_OPC_I8:
12986         {
12987             int reg32;
12988
12989             funct = (ctx->opcode >> 8) & 0x7;
12990             switch (funct) {
12991             case I8_BTEQZ:
12992                 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
12993                                    ((int8_t)ctx->opcode) << 1, 0);
12994                 break;
12995             case I8_BTNEZ:
12996                 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
12997                                    ((int8_t)ctx->opcode) << 1, 0);
12998                 break;
12999             case I8_SWRASP:
13000                 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
13001                 break;
13002             case I8_ADJSP:
13003                 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
13004                               ((int8_t)ctx->opcode) << 3);
13005                 break;
13006             case I8_SVRS:
13007                 check_insn(ctx, ISA_MIPS32);
13008                 {
13009                     int do_ra = ctx->opcode & (1 << 6);
13010                     int do_s0 = ctx->opcode & (1 << 5);
13011                     int do_s1 = ctx->opcode & (1 << 4);
13012                     int framesize = ctx->opcode & 0xf;
13013
13014                     if (framesize == 0) {
13015                         framesize = 128;
13016                     } else {
13017                         framesize = framesize << 3;
13018                     }
13019
13020                     if (ctx->opcode & (1 << 7)) {
13021                         gen_mips16_save(ctx, 0, 0,
13022                                         do_ra, do_s0, do_s1, framesize);
13023                     } else {
13024                         gen_mips16_restore(ctx, 0, 0,
13025                                            do_ra, do_s0, do_s1, framesize);
13026                     }
13027                 }
13028                 break;
13029             case I8_MOV32R:
13030                 {
13031                     int rz = xlat(ctx->opcode & 0x7);
13032
13033                     reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
13034                         ((ctx->opcode >> 5) & 0x7);
13035                     gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
13036                 }
13037                 break;
13038             case I8_MOVR32:
13039                 reg32 = ctx->opcode & 0x1f;
13040                 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
13041                 break;
13042             default:
13043                 generate_exception_end(ctx, EXCP_RI);
13044                 break;
13045             }
13046         }
13047         break;
13048     case M16_OPC_LI:
13049         {
13050             int16_t imm = (uint8_t) ctx->opcode;
13051
13052             gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
13053         }
13054         break;
13055     case M16_OPC_CMPI:
13056         {
13057             int16_t imm = (uint8_t) ctx->opcode;
13058             gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
13059         }
13060         break;
13061 #if defined(TARGET_MIPS64)
13062     case M16_OPC_SD:
13063         check_insn(ctx, ISA_MIPS3);
13064         check_mips_64(ctx);
13065         gen_st(ctx, OPC_SD, ry, rx, offset << 3);
13066         break;
13067 #endif
13068     case M16_OPC_LB:
13069         gen_ld(ctx, OPC_LB, ry, rx, offset);
13070         break;
13071     case M16_OPC_LH:
13072         gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
13073         break;
13074     case M16_OPC_LWSP:
13075         gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
13076         break;
13077     case M16_OPC_LW:
13078         gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
13079         break;
13080     case M16_OPC_LBU:
13081         gen_ld(ctx, OPC_LBU, ry, rx, offset);
13082         break;
13083     case M16_OPC_LHU:
13084         gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
13085         break;
13086     case M16_OPC_LWPC:
13087         gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
13088         break;
13089 #if defined (TARGET_MIPS64)
13090     case M16_OPC_LWU:
13091         check_insn(ctx, ISA_MIPS3);
13092         check_mips_64(ctx);
13093         gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
13094         break;
13095 #endif
13096     case M16_OPC_SB:
13097         gen_st(ctx, OPC_SB, ry, rx, offset);
13098         break;
13099     case M16_OPC_SH:
13100         gen_st(ctx, OPC_SH, ry, rx, offset << 1);
13101         break;
13102     case M16_OPC_SWSP:
13103         gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
13104         break;
13105     case M16_OPC_SW:
13106         gen_st(ctx, OPC_SW, ry, rx, offset << 2);
13107         break;
13108     case M16_OPC_RRR:
13109         {
13110             int rz = xlat((ctx->opcode >> 2) & 0x7);
13111             int mips32_op;
13112
13113             switch (ctx->opcode & 0x3) {
13114             case RRR_ADDU:
13115                 mips32_op = OPC_ADDU;
13116                 break;
13117             case RRR_SUBU:
13118                 mips32_op = OPC_SUBU;
13119                 break;
13120 #if defined(TARGET_MIPS64)
13121             case RRR_DADDU:
13122                 mips32_op = OPC_DADDU;
13123                 check_insn(ctx, ISA_MIPS3);
13124                 check_mips_64(ctx);
13125                 break;
13126             case RRR_DSUBU:
13127                 mips32_op = OPC_DSUBU;
13128                 check_insn(ctx, ISA_MIPS3);
13129                 check_mips_64(ctx);
13130                 break;
13131 #endif
13132             default:
13133                 generate_exception_end(ctx, EXCP_RI);
13134                 goto done;
13135             }
13136
13137             gen_arith(ctx, mips32_op, rz, rx, ry);
13138         done:
13139             ;
13140         }
13141         break;
13142     case M16_OPC_RR:
13143         switch (op1) {
13144         case RR_JR:
13145             {
13146                 int nd = (ctx->opcode >> 7) & 0x1;
13147                 int link = (ctx->opcode >> 6) & 0x1;
13148                 int ra = (ctx->opcode >> 5) & 0x1;
13149
13150                 if (nd) {
13151                     check_insn(ctx, ISA_MIPS32);
13152                 }
13153
13154                 if (link) {
13155                     op = OPC_JALR;
13156                 } else {
13157                     op = OPC_JR;
13158                 }
13159
13160                 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
13161                                    (nd ? 0 : 2));
13162             }
13163             break;
13164         case RR_SDBBP:
13165             if (is_uhi(extract32(ctx->opcode, 5, 6))) {
13166                 gen_helper_do_semihosting(cpu_env);
13167             } else {
13168                 /* XXX: not clear which exception should be raised
13169                  *      when in debug mode...
13170                  */
13171                 check_insn(ctx, ISA_MIPS32);
13172                 generate_exception_end(ctx, EXCP_DBp);
13173             }
13174             break;
13175         case RR_SLT:
13176             gen_slt(ctx, OPC_SLT, 24, rx, ry);
13177             break;
13178         case RR_SLTU:
13179             gen_slt(ctx, OPC_SLTU, 24, rx, ry);
13180             break;
13181         case RR_BREAK:
13182             generate_exception_end(ctx, EXCP_BREAK);
13183             break;
13184         case RR_SLLV:
13185             gen_shift(ctx, OPC_SLLV, ry, rx, ry);
13186             break;
13187         case RR_SRLV:
13188             gen_shift(ctx, OPC_SRLV, ry, rx, ry);
13189             break;
13190         case RR_SRAV:
13191             gen_shift(ctx, OPC_SRAV, ry, rx, ry);
13192             break;
13193 #if defined (TARGET_MIPS64)
13194         case RR_DSRL:
13195             check_insn(ctx, ISA_MIPS3);
13196             check_mips_64(ctx);
13197             gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
13198             break;
13199 #endif
13200         case RR_CMP:
13201             gen_logic(ctx, OPC_XOR, 24, rx, ry);
13202             break;
13203         case RR_NEG:
13204             gen_arith(ctx, OPC_SUBU, rx, 0, ry);
13205             break;
13206         case RR_AND:
13207             gen_logic(ctx, OPC_AND, rx, rx, ry);
13208             break;
13209         case RR_OR:
13210             gen_logic(ctx, OPC_OR, rx, rx, ry);
13211             break;
13212         case RR_XOR:
13213             gen_logic(ctx, OPC_XOR, rx, rx, ry);
13214             break;
13215         case RR_NOT:
13216             gen_logic(ctx, OPC_NOR, rx, ry, 0);
13217             break;
13218         case RR_MFHI:
13219             gen_HILO(ctx, OPC_MFHI, 0, rx);
13220             break;
13221         case RR_CNVT:
13222             check_insn(ctx, ISA_MIPS32);
13223             switch (cnvt_op) {
13224             case RR_RY_CNVT_ZEB:
13225                 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13226                 break;
13227             case RR_RY_CNVT_ZEH:
13228                 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13229                 break;
13230             case RR_RY_CNVT_SEB:
13231                 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13232                 break;
13233             case RR_RY_CNVT_SEH:
13234                 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13235                 break;
13236 #if defined (TARGET_MIPS64)
13237             case RR_RY_CNVT_ZEW:
13238                 check_insn(ctx, ISA_MIPS64);
13239                 check_mips_64(ctx);
13240                 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13241                 break;
13242             case RR_RY_CNVT_SEW:
13243                 check_insn(ctx, ISA_MIPS64);
13244                 check_mips_64(ctx);
13245                 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13246                 break;
13247 #endif
13248             default:
13249                 generate_exception_end(ctx, EXCP_RI);
13250                 break;
13251             }
13252             break;
13253         case RR_MFLO:
13254             gen_HILO(ctx, OPC_MFLO, 0, rx);
13255             break;
13256 #if defined (TARGET_MIPS64)
13257         case RR_DSRA:
13258             check_insn(ctx, ISA_MIPS3);
13259             check_mips_64(ctx);
13260             gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
13261             break;
13262         case RR_DSLLV:
13263             check_insn(ctx, ISA_MIPS3);
13264             check_mips_64(ctx);
13265             gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
13266             break;
13267         case RR_DSRLV:
13268             check_insn(ctx, ISA_MIPS3);
13269             check_mips_64(ctx);
13270             gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
13271             break;
13272         case RR_DSRAV:
13273             check_insn(ctx, ISA_MIPS3);
13274             check_mips_64(ctx);
13275             gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
13276             break;
13277 #endif
13278         case RR_MULT:
13279             gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
13280             break;
13281         case RR_MULTU:
13282             gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
13283             break;
13284         case RR_DIV:
13285             gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
13286             break;
13287         case RR_DIVU:
13288             gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
13289             break;
13290 #if defined (TARGET_MIPS64)
13291         case RR_DMULT:
13292             check_insn(ctx, ISA_MIPS3);
13293             check_mips_64(ctx);
13294             gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
13295             break;
13296         case RR_DMULTU:
13297             check_insn(ctx, ISA_MIPS3);
13298             check_mips_64(ctx);
13299             gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
13300             break;
13301         case RR_DDIV:
13302             check_insn(ctx, ISA_MIPS3);
13303             check_mips_64(ctx);
13304             gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
13305             break;
13306         case RR_DDIVU:
13307             check_insn(ctx, ISA_MIPS3);
13308             check_mips_64(ctx);
13309             gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
13310             break;
13311 #endif
13312         default:
13313             generate_exception_end(ctx, EXCP_RI);
13314             break;
13315         }
13316         break;
13317     case M16_OPC_EXTEND:
13318         decode_extended_mips16_opc(env, ctx);
13319         n_bytes = 4;
13320         break;
13321 #if defined(TARGET_MIPS64)
13322     case M16_OPC_I64:
13323         funct = (ctx->opcode >> 8) & 0x7;
13324         decode_i64_mips16(ctx, ry, funct, offset, 0);
13325         break;
13326 #endif
13327     default:
13328         generate_exception_end(ctx, EXCP_RI);
13329         break;
13330     }
13331
13332     return n_bytes;
13333 }
13334
13335 /* microMIPS extension to MIPS32/MIPS64 */
13336
13337 /*
13338  * microMIPS32/microMIPS64 major opcodes
13339  *
13340  * 1. MIPS Architecture for Programmers Volume II-B:
13341  *      The microMIPS32 Instruction Set (Revision 3.05)
13342  *
13343  *    Table 6.2 microMIPS32 Encoding of Major Opcode Field
13344  *
13345  * 2. MIPS Architecture For Programmers Volume II-A:
13346  *      The MIPS64 Instruction Set (Revision 3.51)
13347  */
13348
13349 enum {
13350     POOL32A = 0x00,
13351     POOL16A = 0x01,
13352     LBU16 = 0x02,
13353     MOVE16 = 0x03,
13354     ADDI32 = 0x04,
13355     R6_LUI = 0x04,
13356     AUI = 0x04,
13357     LBU32 = 0x05,
13358     SB32 = 0x06,
13359     LB32 = 0x07,
13360
13361     POOL32B = 0x08,
13362     POOL16B = 0x09,
13363     LHU16 = 0x0a,
13364     ANDI16 = 0x0b,
13365     ADDIU32 = 0x0c,
13366     LHU32 = 0x0d,
13367     SH32 = 0x0e,
13368     LH32 = 0x0f,
13369
13370     POOL32I = 0x10,
13371     POOL16C = 0x11,
13372     LWSP16 = 0x12,
13373     POOL16D = 0x13,
13374     ORI32 = 0x14,
13375     POOL32F = 0x15,
13376     POOL32S = 0x16,  /* MIPS64 */
13377     DADDIU32 = 0x17, /* MIPS64 */
13378
13379     POOL32C = 0x18,
13380     LWGP16 = 0x19,
13381     LW16 = 0x1a,
13382     POOL16E = 0x1b,
13383     XORI32 = 0x1c,
13384     JALS32 = 0x1d,
13385     BOVC = 0x1d,
13386     BEQC = 0x1d,
13387     BEQZALC = 0x1d,
13388     ADDIUPC = 0x1e,
13389     PCREL = 0x1e,
13390     BNVC = 0x1f,
13391     BNEC = 0x1f,
13392     BNEZALC = 0x1f,
13393
13394     R6_BEQZC = 0x20,
13395     JIC = 0x20,
13396     POOL16F = 0x21,
13397     SB16 = 0x22,
13398     BEQZ16 = 0x23,
13399     BEQZC16 = 0x23,
13400     SLTI32 = 0x24,
13401     BEQ32 = 0x25,
13402     BC = 0x25,
13403     SWC132 = 0x26,
13404     LWC132 = 0x27,
13405
13406     /* 0x29 is reserved */
13407     RES_29 = 0x29,
13408     R6_BNEZC = 0x28,
13409     JIALC = 0x28,
13410     SH16 = 0x2a,
13411     BNEZ16 = 0x2b,
13412     BNEZC16 = 0x2b,
13413     SLTIU32 = 0x2c,
13414     BNE32 = 0x2d,
13415     BALC = 0x2d,
13416     SDC132 = 0x2e,
13417     LDC132 = 0x2f,
13418
13419     /* 0x31 is reserved */
13420     RES_31 = 0x31,
13421     BLEZALC = 0x30,
13422     BGEZALC = 0x30,
13423     BGEUC = 0x30,
13424     SWSP16 = 0x32,
13425     B16 = 0x33,
13426     BC16 = 0x33,
13427     ANDI32 = 0x34,
13428     J32 = 0x35,
13429     BGTZC = 0x35,
13430     BLTZC = 0x35,
13431     BLTC = 0x35,
13432     SD32 = 0x36, /* MIPS64 */
13433     LD32 = 0x37, /* MIPS64 */
13434
13435     /* 0x39 is reserved */
13436     RES_39 = 0x39,
13437     BGTZALC = 0x38,
13438     BLTZALC = 0x38,
13439     BLTUC = 0x38,
13440     SW16 = 0x3a,
13441     LI16 = 0x3b,
13442     JALX32 = 0x3c,
13443     JAL32 = 0x3d,
13444     BLEZC = 0x3d,
13445     BGEZC = 0x3d,
13446     BGEC = 0x3d,
13447     SW32 = 0x3e,
13448     LW32 = 0x3f
13449 };
13450
13451 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
13452 enum {
13453     ADDIUPC_00 = 0x00,
13454     ADDIUPC_01 = 0x01,
13455     ADDIUPC_02 = 0x02,
13456     ADDIUPC_03 = 0x03,
13457     ADDIUPC_04 = 0x04,
13458     ADDIUPC_05 = 0x05,
13459     ADDIUPC_06 = 0x06,
13460     ADDIUPC_07 = 0x07,
13461     AUIPC = 0x1e,
13462     ALUIPC = 0x1f,
13463     LWPC_08 = 0x08,
13464     LWPC_09 = 0x09,
13465     LWPC_0A = 0x0A,
13466     LWPC_0B = 0x0B,
13467     LWPC_0C = 0x0C,
13468     LWPC_0D = 0x0D,
13469     LWPC_0E = 0x0E,
13470     LWPC_0F = 0x0F,
13471 };
13472
13473 /* POOL32A encoding of minor opcode field */
13474
13475 enum {
13476     /* These opcodes are distinguished only by bits 9..6; those bits are
13477      * what are recorded below. */
13478     SLL32 = 0x0,
13479     SRL32 = 0x1,
13480     SRA = 0x2,
13481     ROTR = 0x3,
13482     SELEQZ = 0x5,
13483     SELNEZ = 0x6,
13484     R6_RDHWR = 0x7,
13485
13486     SLLV = 0x0,
13487     SRLV = 0x1,
13488     SRAV = 0x2,
13489     ROTRV = 0x3,
13490     ADD = 0x4,
13491     ADDU32 = 0x5,
13492     SUB = 0x6,
13493     SUBU32 = 0x7,
13494     MUL = 0x8,
13495     AND = 0x9,
13496     OR32 = 0xa,
13497     NOR = 0xb,
13498     XOR32 = 0xc,
13499     SLT = 0xd,
13500     SLTU = 0xe,
13501
13502     MOVN = 0x0,
13503     R6_MUL  = 0x0,
13504     MOVZ = 0x1,
13505     MUH  = 0x1,
13506     MULU = 0x2,
13507     MUHU = 0x3,
13508     LWXS = 0x4,
13509     R6_DIV  = 0x4,
13510     MOD  = 0x5,
13511     R6_DIVU = 0x6,
13512     MODU = 0x7,
13513
13514     /* The following can be distinguished by their lower 6 bits. */
13515     BREAK32 = 0x07,
13516     INS = 0x0c,
13517     LSA = 0x0f,
13518     ALIGN = 0x1f,
13519     EXT = 0x2c,
13520     POOL32AXF = 0x3c,
13521     SIGRIE = 0x3f
13522 };
13523
13524 /* POOL32AXF encoding of minor opcode field extension */
13525
13526 /*
13527  * 1. MIPS Architecture for Programmers Volume II-B:
13528  *      The microMIPS32 Instruction Set (Revision 3.05)
13529  *
13530  *    Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
13531  *
13532  * 2. MIPS Architecture for Programmers VolumeIV-e:
13533  *      The MIPS DSP Application-Specific Extension
13534  *        to the microMIPS32 Architecture (Revision 2.34)
13535  *
13536  *    Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
13537  */
13538
13539 enum {
13540     /* bits 11..6 */
13541     TEQ = 0x00,
13542     TGE = 0x08,
13543     TGEU = 0x10,
13544     TLT = 0x20,
13545     TLTU = 0x28,
13546     TNE = 0x30,
13547
13548     MFC0 = 0x03,
13549     MTC0 = 0x0b,
13550
13551     /* begin of microMIPS32 DSP */
13552
13553     /* bits 13..12 for 0x01 */
13554     MFHI_ACC = 0x0,
13555     MFLO_ACC = 0x1,
13556     MTHI_ACC = 0x2,
13557     MTLO_ACC = 0x3,
13558
13559     /* bits 13..12 for 0x2a */
13560     MADD_ACC = 0x0,
13561     MADDU_ACC = 0x1,
13562     MSUB_ACC = 0x2,
13563     MSUBU_ACC = 0x3,
13564
13565     /* bits 13..12 for 0x32 */
13566     MULT_ACC = 0x0,
13567     MULTU_ACC = 0x1,
13568
13569     /* end of microMIPS32 DSP */
13570
13571     /* bits 15..12 for 0x2c */
13572     BITSWAP = 0x0,
13573     SEB = 0x2,
13574     SEH = 0x3,
13575     CLO = 0x4,
13576     CLZ = 0x5,
13577     RDHWR = 0x6,
13578     WSBH = 0x7,
13579     MULT = 0x8,
13580     MULTU = 0x9,
13581     DIV = 0xa,
13582     DIVU = 0xb,
13583     MADD = 0xc,
13584     MADDU = 0xd,
13585     MSUB = 0xe,
13586     MSUBU = 0xf,
13587
13588     /* bits 15..12 for 0x34 */
13589     MFC2 = 0x4,
13590     MTC2 = 0x5,
13591     MFHC2 = 0x8,
13592     MTHC2 = 0x9,
13593     CFC2 = 0xc,
13594     CTC2 = 0xd,
13595
13596     /* bits 15..12 for 0x3c */
13597     JALR = 0x0,
13598     JR = 0x0,                   /* alias */
13599     JALRC = 0x0,
13600     JRC = 0x0,
13601     JALR_HB = 0x1,
13602     JALRC_HB = 0x1,
13603     JALRS = 0x4,
13604     JALRS_HB = 0x5,
13605
13606     /* bits 15..12 for 0x05 */
13607     RDPGPR = 0xe,
13608     WRPGPR = 0xf,
13609
13610     /* bits 15..12 for 0x0d */
13611     TLBP = 0x0,
13612     TLBR = 0x1,
13613     TLBWI = 0x2,
13614     TLBWR = 0x3,
13615     TLBINV = 0x4,
13616     TLBINVF = 0x5,
13617     WAIT = 0x9,
13618     IRET = 0xd,
13619     DERET = 0xe,
13620     ERET = 0xf,
13621
13622     /* bits 15..12 for 0x15 */
13623     DMT = 0x0,
13624     DVPE = 0x1,
13625     EMT = 0x2,
13626     EVPE = 0x3,
13627
13628     /* bits 15..12 for 0x1d */
13629     DI = 0x4,
13630     EI = 0x5,
13631
13632     /* bits 15..12 for 0x2d */
13633     SYNC = 0x6,
13634     SYSCALL = 0x8,
13635     SDBBP = 0xd,
13636
13637     /* bits 15..12 for 0x35 */
13638     MFHI32 = 0x0,
13639     MFLO32 = 0x1,
13640     MTHI32 = 0x2,
13641     MTLO32 = 0x3,
13642 };
13643
13644 /* POOL32B encoding of minor opcode field (bits 15..12) */
13645
13646 enum {
13647     LWC2 = 0x0,
13648     LWP = 0x1,
13649     LDP = 0x4,
13650     LWM32 = 0x5,
13651     CACHE = 0x6,
13652     LDM = 0x7,
13653     SWC2 = 0x8,
13654     SWP = 0x9,
13655     SDP = 0xc,
13656     SWM32 = 0xd,
13657     SDM = 0xf
13658 };
13659
13660 /* POOL32C encoding of minor opcode field (bits 15..12) */
13661
13662 enum {
13663     LWL = 0x0,
13664     SWL = 0x8,
13665     LWR = 0x1,
13666     SWR = 0x9,
13667     PREF = 0x2,
13668     ST_EVA = 0xa,
13669     LL = 0x3,
13670     SC = 0xb,
13671     LDL = 0x4,
13672     SDL = 0xc,
13673     LDR = 0x5,
13674     SDR = 0xd,
13675     LD_EVA = 0x6,
13676     LWU = 0xe,
13677     LLD = 0x7,
13678     SCD = 0xf
13679 };
13680
13681 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
13682
13683 enum {
13684     LBUE = 0x0,
13685     LHUE = 0x1,
13686     LWLE = 0x2,
13687     LWRE = 0x3,
13688     LBE = 0x4,
13689     LHE = 0x5,
13690     LLE = 0x6,
13691     LWE = 0x7,
13692 };
13693
13694 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
13695
13696 enum {
13697     SWLE = 0x0,
13698     SWRE = 0x1,
13699     PREFE = 0x2,
13700     CACHEE = 0x3,
13701     SBE = 0x4,
13702     SHE = 0x5,
13703     SCE = 0x6,
13704     SWE = 0x7,
13705 };
13706
13707 /* POOL32F encoding of minor opcode field (bits 5..0) */
13708
13709 enum {
13710     /* These are the bit 7..6 values */
13711     ADD_FMT = 0x0,
13712
13713     SUB_FMT = 0x1,
13714
13715     MUL_FMT = 0x2,
13716
13717     DIV_FMT = 0x3,
13718
13719     /* These are the bit 8..6 values */
13720     MOVN_FMT = 0x0,
13721     RSQRT2_FMT = 0x0,
13722     MOVF_FMT = 0x0,
13723     RINT_FMT = 0x0,
13724     SELNEZ_FMT = 0x0,
13725
13726     MOVZ_FMT = 0x1,
13727     LWXC1 = 0x1,
13728     MOVT_FMT = 0x1,
13729     CLASS_FMT = 0x1,
13730     SELEQZ_FMT = 0x1,
13731
13732     PLL_PS = 0x2,
13733     SWXC1 = 0x2,
13734     SEL_FMT = 0x2,
13735
13736     PLU_PS = 0x3,
13737     LDXC1 = 0x3,
13738
13739     MOVN_FMT_04 = 0x4,
13740     PUL_PS = 0x4,
13741     SDXC1 = 0x4,
13742     RECIP2_FMT = 0x4,
13743
13744     MOVZ_FMT_05 = 0x05,
13745     PUU_PS = 0x5,
13746     LUXC1 = 0x5,
13747
13748     CVT_PS_S = 0x6,
13749     SUXC1 = 0x6,
13750     ADDR_PS = 0x6,
13751     PREFX = 0x6,
13752     MADDF_FMT = 0x6,
13753
13754     MULR_PS = 0x7,
13755     MSUBF_FMT = 0x7,
13756
13757     MADD_S = 0x01,
13758     MADD_D = 0x09,
13759     MADD_PS = 0x11,
13760     ALNV_PS = 0x19,
13761     MSUB_S = 0x21,
13762     MSUB_D = 0x29,
13763     MSUB_PS = 0x31,
13764
13765     NMADD_S = 0x02,
13766     NMADD_D = 0x0a,
13767     NMADD_PS = 0x12,
13768     NMSUB_S = 0x22,
13769     NMSUB_D = 0x2a,
13770     NMSUB_PS = 0x32,
13771
13772     MIN_FMT = 0x3,
13773     MAX_FMT = 0xb,
13774     MINA_FMT = 0x23,
13775     MAXA_FMT = 0x2b,
13776     POOL32FXF = 0x3b,
13777
13778     CABS_COND_FMT = 0x1c,              /* MIPS3D */
13779     C_COND_FMT = 0x3c,
13780
13781     CMP_CONDN_S = 0x5,
13782     CMP_CONDN_D = 0x15
13783 };
13784
13785 /* POOL32Fxf encoding of minor opcode extension field */
13786
13787 enum {
13788     CVT_L = 0x04,
13789     RSQRT_FMT = 0x08,
13790     FLOOR_L = 0x0c,
13791     CVT_PW_PS = 0x1c,
13792     CVT_W = 0x24,
13793     SQRT_FMT = 0x28,
13794     FLOOR_W = 0x2c,
13795     CVT_PS_PW = 0x3c,
13796     CFC1 = 0x40,
13797     RECIP_FMT = 0x48,
13798     CEIL_L = 0x4c,
13799     CTC1 = 0x60,
13800     CEIL_W = 0x6c,
13801     MFC1 = 0x80,
13802     CVT_S_PL = 0x84,
13803     TRUNC_L = 0x8c,
13804     MTC1 = 0xa0,
13805     CVT_S_PU = 0xa4,
13806     TRUNC_W = 0xac,
13807     MFHC1 = 0xc0,
13808     ROUND_L = 0xcc,
13809     MTHC1 = 0xe0,
13810     ROUND_W = 0xec,
13811
13812     MOV_FMT = 0x01,
13813     MOVF = 0x05,
13814     ABS_FMT = 0x0d,
13815     RSQRT1_FMT = 0x1d,
13816     MOVT = 0x25,
13817     NEG_FMT = 0x2d,
13818     CVT_D = 0x4d,
13819     RECIP1_FMT = 0x5d,
13820     CVT_S = 0x6d
13821 };
13822
13823 /* POOL32I encoding of minor opcode field (bits 25..21) */
13824
13825 enum {
13826     BLTZ = 0x00,
13827     BLTZAL = 0x01,
13828     BGEZ = 0x02,
13829     BGEZAL = 0x03,
13830     BLEZ = 0x04,
13831     BNEZC = 0x05,
13832     BGTZ = 0x06,
13833     BEQZC = 0x07,
13834     TLTI = 0x08,
13835     BC1EQZC = 0x08,
13836     TGEI = 0x09,
13837     BC1NEZC = 0x09,
13838     TLTIU = 0x0a,
13839     BC2EQZC = 0x0a,
13840     TGEIU = 0x0b,
13841     BC2NEZC = 0x0a,
13842     TNEI = 0x0c,
13843     R6_SYNCI = 0x0c,
13844     LUI = 0x0d,
13845     TEQI = 0x0e,
13846     SYNCI = 0x10,
13847     BLTZALS = 0x11,
13848     BGEZALS = 0x13,
13849     BC2F = 0x14,
13850     BC2T = 0x15,
13851     BPOSGE64 = 0x1a,
13852     BPOSGE32 = 0x1b,
13853     /* These overlap and are distinguished by bit16 of the instruction */
13854     BC1F = 0x1c,
13855     BC1T = 0x1d,
13856     BC1ANY2F = 0x1c,
13857     BC1ANY2T = 0x1d,
13858     BC1ANY4F = 0x1e,
13859     BC1ANY4T = 0x1f
13860 };
13861
13862 /* POOL16A encoding of minor opcode field */
13863
13864 enum {
13865     ADDU16 = 0x0,
13866     SUBU16 = 0x1
13867 };
13868
13869 /* POOL16B encoding of minor opcode field */
13870
13871 enum {
13872     SLL16 = 0x0,
13873     SRL16 = 0x1
13874 };
13875
13876 /* POOL16C encoding of minor opcode field */
13877
13878 enum {
13879     NOT16 = 0x00,
13880     XOR16 = 0x04,
13881     AND16 = 0x08,
13882     OR16 = 0x0c,
13883     LWM16 = 0x10,
13884     SWM16 = 0x14,
13885     JR16 = 0x18,
13886     JRC16 = 0x1a,
13887     JALR16 = 0x1c,
13888     JALR16S = 0x1e,
13889     MFHI16 = 0x20,
13890     MFLO16 = 0x24,
13891     BREAK16 = 0x28,
13892     SDBBP16 = 0x2c,
13893     JRADDIUSP = 0x30
13894 };
13895
13896 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
13897
13898 enum {
13899     R6_NOT16    = 0x00,
13900     R6_AND16    = 0x01,
13901     R6_LWM16    = 0x02,
13902     R6_JRC16    = 0x03,
13903     MOVEP       = 0x04,
13904     MOVEP_05    = 0x05,
13905     MOVEP_06    = 0x06,
13906     MOVEP_07    = 0x07,
13907     R6_XOR16    = 0x08,
13908     R6_OR16     = 0x09,
13909     R6_SWM16    = 0x0a,
13910     JALRC16     = 0x0b,
13911     MOVEP_0C    = 0x0c,
13912     MOVEP_0D    = 0x0d,
13913     MOVEP_0E    = 0x0e,
13914     MOVEP_0F    = 0x0f,
13915     JRCADDIUSP  = 0x13,
13916     R6_BREAK16  = 0x1b,
13917     R6_SDBBP16  = 0x3b
13918 };
13919
13920 /* POOL16D encoding of minor opcode field */
13921
13922 enum {
13923     ADDIUS5 = 0x0,
13924     ADDIUSP = 0x1
13925 };
13926
13927 /* POOL16E encoding of minor opcode field */
13928
13929 enum {
13930     ADDIUR2 = 0x0,
13931     ADDIUR1SP = 0x1
13932 };
13933
13934 static int mmreg (int r)
13935 {
13936     static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13937
13938     return map[r];
13939 }
13940
13941 /* Used for 16-bit store instructions.  */
13942 static int mmreg2 (int r)
13943 {
13944     static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
13945
13946     return map[r];
13947 }
13948
13949 #define uMIPS_RD(op) ((op >> 7) & 0x7)
13950 #define uMIPS_RS(op) ((op >> 4) & 0x7)
13951 #define uMIPS_RS2(op) uMIPS_RS(op)
13952 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
13953 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
13954 #define uMIPS_RS5(op) (op & 0x1f)
13955
13956 /* Signed immediate */
13957 #define SIMM(op, start, width)                                          \
13958     ((int32_t)(((op >> start) & ((~0U) >> (32-width)))                 \
13959                << (32-width))                                           \
13960      >> (32-width))
13961 /* Zero-extended immediate */
13962 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
13963
13964 static void gen_addiur1sp(DisasContext *ctx)
13965 {
13966     int rd = mmreg(uMIPS_RD(ctx->opcode));
13967
13968     gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
13969 }
13970
13971 static void gen_addiur2(DisasContext *ctx)
13972 {
13973     static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
13974     int rd = mmreg(uMIPS_RD(ctx->opcode));
13975     int rs = mmreg(uMIPS_RS(ctx->opcode));
13976
13977     gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
13978 }
13979
13980 static void gen_addiusp(DisasContext *ctx)
13981 {
13982     int encoded = ZIMM(ctx->opcode, 1, 9);
13983     int decoded;
13984
13985     if (encoded <= 1) {
13986         decoded = 256 + encoded;
13987     } else if (encoded <= 255) {
13988         decoded = encoded;
13989     } else if (encoded <= 509) {
13990         decoded = encoded - 512;
13991     } else {
13992         decoded = encoded - 768;
13993     }
13994
13995     gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
13996 }
13997
13998 static void gen_addius5(DisasContext *ctx)
13999 {
14000     int imm = SIMM(ctx->opcode, 1, 4);
14001     int rd = (ctx->opcode >> 5) & 0x1f;
14002
14003     gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
14004 }
14005
14006 static void gen_andi16(DisasContext *ctx)
14007 {
14008     static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
14009                                  31, 32, 63, 64, 255, 32768, 65535 };
14010     int rd = mmreg(uMIPS_RD(ctx->opcode));
14011     int rs = mmreg(uMIPS_RS(ctx->opcode));
14012     int encoded = ZIMM(ctx->opcode, 0, 4);
14013
14014     gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
14015 }
14016
14017 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
14018                                int base, int16_t offset)
14019 {
14020     TCGv t0, t1;
14021     TCGv_i32 t2;
14022
14023     if (ctx->hflags & MIPS_HFLAG_BMASK) {
14024         generate_exception_end(ctx, EXCP_RI);
14025         return;
14026     }
14027
14028     t0 = tcg_temp_new();
14029
14030     gen_base_offset_addr(ctx, t0, base, offset);
14031
14032     t1 = tcg_const_tl(reglist);
14033     t2 = tcg_const_i32(ctx->mem_idx);
14034
14035     save_cpu_state(ctx, 1);
14036     switch (opc) {
14037     case LWM32:
14038         gen_helper_lwm(cpu_env, t0, t1, t2);
14039         break;
14040     case SWM32:
14041         gen_helper_swm(cpu_env, t0, t1, t2);
14042         break;
14043 #ifdef TARGET_MIPS64
14044     case LDM:
14045         gen_helper_ldm(cpu_env, t0, t1, t2);
14046         break;
14047     case SDM:
14048         gen_helper_sdm(cpu_env, t0, t1, t2);
14049         break;
14050 #endif
14051     }
14052     tcg_temp_free(t0);
14053     tcg_temp_free(t1);
14054     tcg_temp_free_i32(t2);
14055 }
14056
14057
14058 static void gen_pool16c_insn(DisasContext *ctx)
14059 {
14060     int rd = mmreg((ctx->opcode >> 3) & 0x7);
14061     int rs = mmreg(ctx->opcode & 0x7);
14062
14063     switch (((ctx->opcode) >> 4) & 0x3f) {
14064     case NOT16 + 0:
14065     case NOT16 + 1:
14066     case NOT16 + 2:
14067     case NOT16 + 3:
14068         gen_logic(ctx, OPC_NOR, rd, rs, 0);
14069         break;
14070     case XOR16 + 0:
14071     case XOR16 + 1:
14072     case XOR16 + 2:
14073     case XOR16 + 3:
14074         gen_logic(ctx, OPC_XOR, rd, rd, rs);
14075         break;
14076     case AND16 + 0:
14077     case AND16 + 1:
14078     case AND16 + 2:
14079     case AND16 + 3:
14080         gen_logic(ctx, OPC_AND, rd, rd, rs);
14081         break;
14082     case OR16 + 0:
14083     case OR16 + 1:
14084     case OR16 + 2:
14085     case OR16 + 3:
14086         gen_logic(ctx, OPC_OR, rd, rd, rs);
14087         break;
14088     case LWM16 + 0:
14089     case LWM16 + 1:
14090     case LWM16 + 2:
14091     case LWM16 + 3:
14092         {
14093             static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14094             int offset = ZIMM(ctx->opcode, 0, 4);
14095
14096             gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
14097                               29, offset << 2);
14098         }
14099         break;
14100     case SWM16 + 0:
14101     case SWM16 + 1:
14102     case SWM16 + 2:
14103     case SWM16 + 3:
14104         {
14105             static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14106             int offset = ZIMM(ctx->opcode, 0, 4);
14107
14108             gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
14109                               29, offset << 2);
14110         }
14111         break;
14112     case JR16 + 0:
14113     case JR16 + 1:
14114         {
14115             int reg = ctx->opcode & 0x1f;
14116
14117             gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
14118         }
14119         break;
14120     case JRC16 + 0:
14121     case JRC16 + 1:
14122         {
14123             int reg = ctx->opcode & 0x1f;
14124             gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
14125             /* Let normal delay slot handling in our caller take us
14126                to the branch target.  */
14127         }
14128         break;
14129     case JALR16 + 0:
14130     case JALR16 + 1:
14131         gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
14132         ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14133         break;
14134     case JALR16S + 0:
14135     case JALR16S + 1:
14136         gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
14137         ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14138         break;
14139     case MFHI16 + 0:
14140     case MFHI16 + 1:
14141         gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
14142         break;
14143     case MFLO16 + 0:
14144     case MFLO16 + 1:
14145         gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
14146         break;
14147     case BREAK16:
14148         generate_exception_end(ctx, EXCP_BREAK);
14149         break;
14150     case SDBBP16:
14151         if (is_uhi(extract32(ctx->opcode, 0, 4))) {
14152             gen_helper_do_semihosting(cpu_env);
14153         } else {
14154             /* XXX: not clear which exception should be raised
14155              *      when in debug mode...
14156              */
14157             check_insn(ctx, ISA_MIPS32);
14158             generate_exception_end(ctx, EXCP_DBp);
14159         }
14160         break;
14161     case JRADDIUSP + 0:
14162     case JRADDIUSP + 1:
14163         {
14164             int imm = ZIMM(ctx->opcode, 0, 5);
14165             gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
14166             gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
14167             /* Let normal delay slot handling in our caller take us
14168                to the branch target.  */
14169         }
14170         break;
14171     default:
14172         generate_exception_end(ctx, EXCP_RI);
14173         break;
14174     }
14175 }
14176
14177 static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
14178                              int enc_rs)
14179 {
14180     int rd, rs, re, rt;
14181     static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
14182     static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
14183     static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
14184     rd = rd_enc[enc_dest];
14185     re = re_enc[enc_dest];
14186     rs = rs_rt_enc[enc_rs];
14187     rt = rs_rt_enc[enc_rt];
14188     if (rs) {
14189         tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
14190     } else {
14191         tcg_gen_movi_tl(cpu_gpr[rd], 0);
14192     }
14193     if (rt) {
14194         tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
14195     } else {
14196         tcg_gen_movi_tl(cpu_gpr[re], 0);
14197     }
14198 }
14199
14200 static void gen_pool16c_r6_insn(DisasContext *ctx)
14201 {
14202     int rt = mmreg((ctx->opcode >> 7) & 0x7);
14203     int rs = mmreg((ctx->opcode >> 4) & 0x7);
14204
14205     switch (ctx->opcode & 0xf) {
14206     case R6_NOT16:
14207         gen_logic(ctx, OPC_NOR, rt, rs, 0);
14208         break;
14209     case R6_AND16:
14210         gen_logic(ctx, OPC_AND, rt, rt, rs);
14211         break;
14212     case R6_LWM16:
14213         {
14214             int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
14215             int offset = extract32(ctx->opcode, 4, 4);
14216             gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
14217         }
14218         break;
14219     case R6_JRC16: /* JRCADDIUSP */
14220         if ((ctx->opcode >> 4) & 1) {
14221             /* JRCADDIUSP */
14222             int imm = extract32(ctx->opcode, 5, 5);
14223             gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
14224             gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
14225         } else {
14226             /* JRC16 */
14227             rs = extract32(ctx->opcode, 5, 5);
14228             gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
14229         }
14230         break;
14231     case MOVEP:
14232     case MOVEP_05:
14233     case MOVEP_06:
14234     case MOVEP_07:
14235     case MOVEP_0C:
14236     case MOVEP_0D:
14237     case MOVEP_0E:
14238     case MOVEP_0F:
14239         {
14240             int enc_dest = uMIPS_RD(ctx->opcode);
14241             int enc_rt = uMIPS_RS2(ctx->opcode);
14242             int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
14243             gen_movep(ctx, enc_dest, enc_rt, enc_rs);
14244         }
14245         break;
14246     case R6_XOR16:
14247         gen_logic(ctx, OPC_XOR, rt, rt, rs);
14248         break;
14249     case R6_OR16:
14250         gen_logic(ctx, OPC_OR, rt, rt, rs);
14251         break;
14252     case R6_SWM16:
14253         {
14254             int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
14255             int offset = extract32(ctx->opcode, 4, 4);
14256             gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
14257         }
14258         break;
14259     case JALRC16: /* BREAK16, SDBBP16 */
14260         switch (ctx->opcode & 0x3f) {
14261         case JALRC16:
14262         case JALRC16 + 0x20:
14263             /* JALRC16 */
14264             gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
14265                                31, 0, 0);
14266             break;
14267         case R6_BREAK16:
14268             /* BREAK16 */
14269             generate_exception(ctx, EXCP_BREAK);
14270             break;
14271         case R6_SDBBP16:
14272             /* SDBBP16 */
14273             if (is_uhi(extract32(ctx->opcode, 6, 4))) {
14274                 gen_helper_do_semihosting(cpu_env);
14275             } else {
14276                 if (ctx->hflags & MIPS_HFLAG_SBRI) {
14277                     generate_exception(ctx, EXCP_RI);
14278                 } else {
14279                     generate_exception(ctx, EXCP_DBp);
14280                 }
14281             }
14282             break;
14283         }
14284         break;
14285     default:
14286         generate_exception(ctx, EXCP_RI);
14287         break;
14288     }
14289 }
14290
14291 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
14292 {
14293     TCGv t0 = tcg_temp_new();
14294     TCGv t1 = tcg_temp_new();
14295
14296     gen_load_gpr(t0, base);
14297
14298     if (index != 0) {
14299         gen_load_gpr(t1, index);
14300         tcg_gen_shli_tl(t1, t1, 2);
14301         gen_op_addr_add(ctx, t0, t1, t0);
14302     }
14303
14304     tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
14305     gen_store_gpr(t1, rd);
14306
14307     tcg_temp_free(t0);
14308     tcg_temp_free(t1);
14309 }
14310
14311 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
14312                            int base, int16_t offset)
14313 {
14314     TCGv t0, t1;
14315
14316     if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
14317         generate_exception_end(ctx, EXCP_RI);
14318         return;
14319     }
14320
14321     t0 = tcg_temp_new();
14322     t1 = tcg_temp_new();
14323
14324     gen_base_offset_addr(ctx, t0, base, offset);
14325
14326     switch (opc) {
14327     case LWP:
14328         if (rd == base) {
14329             generate_exception_end(ctx, EXCP_RI);
14330             return;
14331         }
14332         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
14333         gen_store_gpr(t1, rd);
14334         tcg_gen_movi_tl(t1, 4);
14335         gen_op_addr_add(ctx, t0, t0, t1);
14336         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
14337         gen_store_gpr(t1, rd+1);
14338         break;
14339     case SWP:
14340         gen_load_gpr(t1, rd);
14341         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
14342         tcg_gen_movi_tl(t1, 4);
14343         gen_op_addr_add(ctx, t0, t0, t1);
14344         gen_load_gpr(t1, rd+1);
14345         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
14346         break;
14347 #ifdef TARGET_MIPS64
14348     case LDP:
14349         if (rd == base) {
14350             generate_exception_end(ctx, EXCP_RI);
14351             return;
14352         }
14353         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14354         gen_store_gpr(t1, rd);
14355         tcg_gen_movi_tl(t1, 8);
14356         gen_op_addr_add(ctx, t0, t0, t1);
14357         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14358         gen_store_gpr(t1, rd+1);
14359         break;
14360     case SDP:
14361         gen_load_gpr(t1, rd);
14362         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14363         tcg_gen_movi_tl(t1, 8);
14364         gen_op_addr_add(ctx, t0, t0, t1);
14365         gen_load_gpr(t1, rd+1);
14366         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14367         break;
14368 #endif
14369     }
14370     tcg_temp_free(t0);
14371     tcg_temp_free(t1);
14372 }
14373
14374 static void gen_sync(int stype)
14375 {
14376     TCGBar tcg_mo = TCG_BAR_SC;
14377
14378     switch (stype) {
14379     case 0x4: /* SYNC_WMB */
14380         tcg_mo |= TCG_MO_ST_ST;
14381         break;
14382     case 0x10: /* SYNC_MB */
14383         tcg_mo |= TCG_MO_ALL;
14384         break;
14385     case 0x11: /* SYNC_ACQUIRE */
14386         tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
14387         break;
14388     case 0x12: /* SYNC_RELEASE */
14389         tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
14390         break;
14391     case 0x13: /* SYNC_RMB */
14392         tcg_mo |= TCG_MO_LD_LD;
14393         break;
14394     default:
14395         tcg_mo |= TCG_MO_ALL;
14396         break;
14397     }
14398
14399     tcg_gen_mb(tcg_mo);
14400 }
14401
14402 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
14403 {
14404     int extension = (ctx->opcode >> 6) & 0x3f;
14405     int minor = (ctx->opcode >> 12) & 0xf;
14406     uint32_t mips32_op;
14407
14408     switch (extension) {
14409     case TEQ:
14410         mips32_op = OPC_TEQ;
14411         goto do_trap;
14412     case TGE:
14413         mips32_op = OPC_TGE;
14414         goto do_trap;
14415     case TGEU:
14416         mips32_op = OPC_TGEU;
14417         goto do_trap;
14418     case TLT:
14419         mips32_op = OPC_TLT;
14420         goto do_trap;
14421     case TLTU:
14422         mips32_op = OPC_TLTU;
14423         goto do_trap;
14424     case TNE:
14425         mips32_op = OPC_TNE;
14426     do_trap:
14427         gen_trap(ctx, mips32_op, rs, rt, -1);
14428         break;
14429 #ifndef CONFIG_USER_ONLY
14430     case MFC0:
14431     case MFC0 + 32:
14432         check_cp0_enabled(ctx);
14433         if (rt == 0) {
14434             /* Treat as NOP. */
14435             break;
14436         }
14437         gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
14438         break;
14439     case MTC0:
14440     case MTC0 + 32:
14441         check_cp0_enabled(ctx);
14442         {
14443             TCGv t0 = tcg_temp_new();
14444
14445             gen_load_gpr(t0, rt);
14446             gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
14447             tcg_temp_free(t0);
14448         }
14449         break;
14450 #endif
14451     case 0x2a:
14452         switch (minor & 3) {
14453         case MADD_ACC:
14454             gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
14455             break;
14456         case MADDU_ACC:
14457             gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
14458             break;
14459         case MSUB_ACC:
14460             gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
14461             break;
14462         case MSUBU_ACC:
14463             gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
14464             break;
14465         default:
14466             goto pool32axf_invalid;
14467         }
14468         break;
14469     case 0x32:
14470         switch (minor & 3) {
14471         case MULT_ACC:
14472             gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
14473             break;
14474         case MULTU_ACC:
14475             gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
14476             break;
14477         default:
14478             goto pool32axf_invalid;
14479         }
14480         break;
14481     case 0x2c:
14482         switch (minor) {
14483         case BITSWAP:
14484             check_insn(ctx, ISA_MIPS32R6);
14485             gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
14486             break;
14487         case SEB:
14488             gen_bshfl(ctx, OPC_SEB, rs, rt);
14489             break;
14490         case SEH:
14491             gen_bshfl(ctx, OPC_SEH, rs, rt);
14492             break;
14493         case CLO:
14494             mips32_op = OPC_CLO;
14495             goto do_cl;
14496         case CLZ:
14497             mips32_op = OPC_CLZ;
14498         do_cl:
14499             check_insn(ctx, ISA_MIPS32);
14500             gen_cl(ctx, mips32_op, rt, rs);
14501             break;
14502         case RDHWR:
14503             check_insn_opc_removed(ctx, ISA_MIPS32R6);
14504             gen_rdhwr(ctx, rt, rs, 0);
14505             break;
14506         case WSBH:
14507             gen_bshfl(ctx, OPC_WSBH, rs, rt);
14508             break;
14509         case MULT:
14510             check_insn_opc_removed(ctx, ISA_MIPS32R6);
14511             mips32_op = OPC_MULT;
14512             goto do_mul;
14513         case MULTU:
14514             check_insn_opc_removed(ctx, ISA_MIPS32R6);
14515             mips32_op = OPC_MULTU;
14516             goto do_mul;
14517         case DIV:
14518             check_insn_opc_removed(ctx, ISA_MIPS32R6);
14519             mips32_op = OPC_DIV;
14520             goto do_div;
14521         case DIVU:
14522             check_insn_opc_removed(ctx, ISA_MIPS32R6);
14523             mips32_op = OPC_DIVU;
14524             goto do_div;
14525         do_div:
14526             check_insn(ctx, ISA_MIPS32);
14527             gen_muldiv(ctx, mips32_op, 0, rs, rt);
14528             break;
14529         case MADD:
14530             check_insn_opc_removed(ctx, ISA_MIPS32R6);
14531             mips32_op = OPC_MADD;
14532             goto do_mul;
14533         case MADDU:
14534             check_insn_opc_removed(ctx, ISA_MIPS32R6);
14535             mips32_op = OPC_MADDU;
14536             goto do_mul;
14537         case MSUB:
14538             check_insn_opc_removed(ctx, ISA_MIPS32R6);
14539             mips32_op = OPC_MSUB;
14540             goto do_mul;
14541         case MSUBU:
14542             check_insn_opc_removed(ctx, ISA_MIPS32R6);
14543             mips32_op = OPC_MSUBU;
14544         do_mul:
14545             check_insn(ctx, ISA_MIPS32);
14546             gen_muldiv(ctx, mips32_op, 0, rs, rt);
14547             break;
14548         default:
14549             goto pool32axf_invalid;
14550         }
14551         break;
14552     case 0x34:
14553         switch (minor) {
14554         case MFC2:
14555         case MTC2:
14556         case MFHC2:
14557         case MTHC2:
14558         case CFC2:
14559         case CTC2:
14560             generate_exception_err(ctx, EXCP_CpU, 2);
14561             break;
14562         default:
14563             goto pool32axf_invalid;
14564         }
14565         break;
14566     case 0x3c:
14567         switch (minor) {
14568         case JALR:    /* JALRC */
14569         case JALR_HB: /* JALRC_HB */
14570             if (ctx->insn_flags & ISA_MIPS32R6) {
14571                 /* JALRC, JALRC_HB */
14572                 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
14573             } else {
14574                 /* JALR, JALR_HB */
14575                 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
14576                 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14577             }
14578             break;
14579         case JALRS:
14580         case JALRS_HB:
14581             check_insn_opc_removed(ctx, ISA_MIPS32R6);
14582             gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
14583             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14584             break;
14585         default:
14586             goto pool32axf_invalid;
14587         }
14588         break;
14589     case 0x05:
14590         switch (minor) {
14591         case RDPGPR:
14592             check_cp0_enabled(ctx);
14593             check_insn(ctx, ISA_MIPS32R2);
14594             gen_load_srsgpr(rs, rt);
14595             break;
14596         case WRPGPR:
14597             check_cp0_enabled(ctx);
14598             check_insn(ctx, ISA_MIPS32R2);
14599             gen_store_srsgpr(rs, rt);
14600             break;
14601         default:
14602             goto pool32axf_invalid;
14603         }
14604         break;
14605 #ifndef CONFIG_USER_ONLY
14606     case 0x0d:
14607         switch (minor) {
14608         case TLBP:
14609             mips32_op = OPC_TLBP;
14610             goto do_cp0;
14611         case TLBR:
14612             mips32_op = OPC_TLBR;
14613             goto do_cp0;
14614         case TLBWI:
14615             mips32_op = OPC_TLBWI;
14616             goto do_cp0;
14617         case TLBWR:
14618             mips32_op = OPC_TLBWR;
14619             goto do_cp0;
14620         case TLBINV:
14621             mips32_op = OPC_TLBINV;
14622             goto do_cp0;
14623         case TLBINVF:
14624             mips32_op = OPC_TLBINVF;
14625             goto do_cp0;
14626         case WAIT:
14627             mips32_op = OPC_WAIT;
14628             goto do_cp0;
14629         case DERET:
14630             mips32_op = OPC_DERET;
14631             goto do_cp0;
14632         case ERET:
14633             mips32_op = OPC_ERET;
14634         do_cp0:
14635             gen_cp0(env, ctx, mips32_op, rt, rs);
14636             break;
14637         default:
14638             goto pool32axf_invalid;
14639         }
14640         break;
14641     case 0x1d:
14642         switch (minor) {
14643         case DI:
14644             check_cp0_enabled(ctx);
14645             {
14646                 TCGv t0 = tcg_temp_new();
14647
14648                 save_cpu_state(ctx, 1);
14649                 gen_helper_di(t0, cpu_env);
14650                 gen_store_gpr(t0, rs);
14651                 /* Stop translation as we may have switched the execution mode */
14652                 ctx->base.is_jmp = DISAS_STOP;
14653                 tcg_temp_free(t0);
14654             }
14655             break;
14656         case EI:
14657             check_cp0_enabled(ctx);
14658             {
14659                 TCGv t0 = tcg_temp_new();
14660
14661                 save_cpu_state(ctx, 1);
14662                 gen_helper_ei(t0, cpu_env);
14663                 gen_store_gpr(t0, rs);
14664                 /* DISAS_STOP isn't sufficient, we need to ensure we break out
14665                    of translated code to check for pending interrupts.  */
14666                 gen_save_pc(ctx->base.pc_next + 4);
14667                 ctx->base.is_jmp = DISAS_EXIT;
14668                 tcg_temp_free(t0);
14669             }
14670             break;
14671         default:
14672             goto pool32axf_invalid;
14673         }
14674         break;
14675 #endif
14676     case 0x2d:
14677         switch (minor) {
14678         case SYNC:
14679             gen_sync(extract32(ctx->opcode, 16, 5));
14680             break;
14681         case SYSCALL:
14682             generate_exception_end(ctx, EXCP_SYSCALL);
14683             break;
14684         case SDBBP:
14685             if (is_uhi(extract32(ctx->opcode, 16, 10))) {
14686                 gen_helper_do_semihosting(cpu_env);
14687             } else {
14688                 check_insn(ctx, ISA_MIPS32);
14689                 if (ctx->hflags & MIPS_HFLAG_SBRI) {
14690                     generate_exception_end(ctx, EXCP_RI);
14691                 } else {
14692                     generate_exception_end(ctx, EXCP_DBp);
14693                 }
14694             }
14695             break;
14696         default:
14697             goto pool32axf_invalid;
14698         }
14699         break;
14700     case 0x01:
14701         switch (minor & 3) {
14702         case MFHI_ACC:
14703             gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
14704             break;
14705         case MFLO_ACC:
14706             gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
14707             break;
14708         case MTHI_ACC:
14709             gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
14710             break;
14711         case MTLO_ACC:
14712             gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
14713             break;
14714         default:
14715             goto pool32axf_invalid;
14716         }
14717         break;
14718     case 0x35:
14719         check_insn_opc_removed(ctx, ISA_MIPS32R6);
14720         switch (minor) {
14721         case MFHI32:
14722             gen_HILO(ctx, OPC_MFHI, 0, rs);
14723             break;
14724         case MFLO32:
14725             gen_HILO(ctx, OPC_MFLO, 0, rs);
14726             break;
14727         case MTHI32:
14728             gen_HILO(ctx, OPC_MTHI, 0, rs);
14729             break;
14730         case MTLO32:
14731             gen_HILO(ctx, OPC_MTLO, 0, rs);
14732             break;
14733         default:
14734             goto pool32axf_invalid;
14735         }
14736         break;
14737     default:
14738     pool32axf_invalid:
14739         MIPS_INVAL("pool32axf");
14740         generate_exception_end(ctx, EXCP_RI);
14741         break;
14742     }
14743 }
14744
14745 /* Values for microMIPS fmt field.  Variable-width, depending on which
14746    formats the instruction supports.  */
14747
14748 enum {
14749     FMT_SD_S = 0,
14750     FMT_SD_D = 1,
14751
14752     FMT_SDPS_S = 0,
14753     FMT_SDPS_D = 1,
14754     FMT_SDPS_PS = 2,
14755
14756     FMT_SWL_S = 0,
14757     FMT_SWL_W = 1,
14758     FMT_SWL_L = 2,
14759
14760     FMT_DWL_D = 0,
14761     FMT_DWL_W = 1,
14762     FMT_DWL_L = 2
14763 };
14764
14765 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
14766 {
14767     int extension = (ctx->opcode >> 6) & 0x3ff;
14768     uint32_t mips32_op;
14769
14770 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
14771 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
14772 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
14773
14774     switch (extension) {
14775     case FLOAT_1BIT_FMT(CFC1, 0):
14776         mips32_op = OPC_CFC1;
14777         goto do_cp1;
14778     case FLOAT_1BIT_FMT(CTC1, 0):
14779         mips32_op = OPC_CTC1;
14780         goto do_cp1;
14781     case FLOAT_1BIT_FMT(MFC1, 0):
14782         mips32_op = OPC_MFC1;
14783         goto do_cp1;
14784     case FLOAT_1BIT_FMT(MTC1, 0):
14785         mips32_op = OPC_MTC1;
14786         goto do_cp1;
14787     case FLOAT_1BIT_FMT(MFHC1, 0):
14788         mips32_op = OPC_MFHC1;
14789         goto do_cp1;
14790     case FLOAT_1BIT_FMT(MTHC1, 0):
14791         mips32_op = OPC_MTHC1;
14792     do_cp1:
14793         gen_cp1(ctx, mips32_op, rt, rs);
14794         break;
14795
14796         /* Reciprocal square root */
14797     case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
14798         mips32_op = OPC_RSQRT_S;
14799         goto do_unaryfp;
14800     case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
14801         mips32_op = OPC_RSQRT_D;
14802         goto do_unaryfp;
14803
14804         /* Square root */
14805     case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
14806         mips32_op = OPC_SQRT_S;
14807         goto do_unaryfp;
14808     case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
14809         mips32_op = OPC_SQRT_D;
14810         goto do_unaryfp;
14811
14812         /* Reciprocal */
14813     case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
14814         mips32_op = OPC_RECIP_S;
14815         goto do_unaryfp;
14816     case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
14817         mips32_op = OPC_RECIP_D;
14818         goto do_unaryfp;
14819
14820         /* Floor */
14821     case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
14822         mips32_op = OPC_FLOOR_L_S;
14823         goto do_unaryfp;
14824     case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
14825         mips32_op = OPC_FLOOR_L_D;
14826         goto do_unaryfp;
14827     case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
14828         mips32_op = OPC_FLOOR_W_S;
14829         goto do_unaryfp;
14830     case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
14831         mips32_op = OPC_FLOOR_W_D;
14832         goto do_unaryfp;
14833
14834         /* Ceiling */
14835     case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
14836         mips32_op = OPC_CEIL_L_S;
14837         goto do_unaryfp;
14838     case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
14839         mips32_op = OPC_CEIL_L_D;
14840         goto do_unaryfp;
14841     case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
14842         mips32_op = OPC_CEIL_W_S;
14843         goto do_unaryfp;
14844     case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
14845         mips32_op = OPC_CEIL_W_D;
14846         goto do_unaryfp;
14847
14848         /* Truncation */
14849     case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
14850         mips32_op = OPC_TRUNC_L_S;
14851         goto do_unaryfp;
14852     case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
14853         mips32_op = OPC_TRUNC_L_D;
14854         goto do_unaryfp;
14855     case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
14856         mips32_op = OPC_TRUNC_W_S;
14857         goto do_unaryfp;
14858     case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
14859         mips32_op = OPC_TRUNC_W_D;
14860         goto do_unaryfp;
14861
14862         /* Round */
14863     case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
14864         mips32_op = OPC_ROUND_L_S;
14865         goto do_unaryfp;
14866     case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
14867         mips32_op = OPC_ROUND_L_D;
14868         goto do_unaryfp;
14869     case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
14870         mips32_op = OPC_ROUND_W_S;
14871         goto do_unaryfp;
14872     case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
14873         mips32_op = OPC_ROUND_W_D;
14874         goto do_unaryfp;
14875
14876         /* Integer to floating-point conversion */
14877     case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
14878         mips32_op = OPC_CVT_L_S;
14879         goto do_unaryfp;
14880     case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
14881         mips32_op = OPC_CVT_L_D;
14882         goto do_unaryfp;
14883     case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
14884         mips32_op = OPC_CVT_W_S;
14885         goto do_unaryfp;
14886     case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
14887         mips32_op = OPC_CVT_W_D;
14888         goto do_unaryfp;
14889
14890         /* Paired-foo conversions */
14891     case FLOAT_1BIT_FMT(CVT_S_PL, 0):
14892         mips32_op = OPC_CVT_S_PL;
14893         goto do_unaryfp;
14894     case FLOAT_1BIT_FMT(CVT_S_PU, 0):
14895         mips32_op = OPC_CVT_S_PU;
14896         goto do_unaryfp;
14897     case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
14898         mips32_op = OPC_CVT_PW_PS;
14899         goto do_unaryfp;
14900     case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
14901         mips32_op = OPC_CVT_PS_PW;
14902         goto do_unaryfp;
14903
14904         /* Floating-point moves */
14905     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
14906         mips32_op = OPC_MOV_S;
14907         goto do_unaryfp;
14908     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
14909         mips32_op = OPC_MOV_D;
14910         goto do_unaryfp;
14911     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
14912         mips32_op = OPC_MOV_PS;
14913         goto do_unaryfp;
14914
14915         /* Absolute value */
14916     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
14917         mips32_op = OPC_ABS_S;
14918         goto do_unaryfp;
14919     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
14920         mips32_op = OPC_ABS_D;
14921         goto do_unaryfp;
14922     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
14923         mips32_op = OPC_ABS_PS;
14924         goto do_unaryfp;
14925
14926         /* Negation */
14927     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
14928         mips32_op = OPC_NEG_S;
14929         goto do_unaryfp;
14930     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
14931         mips32_op = OPC_NEG_D;
14932         goto do_unaryfp;
14933     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
14934         mips32_op = OPC_NEG_PS;
14935         goto do_unaryfp;
14936
14937         /* Reciprocal square root step */
14938     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
14939         mips32_op = OPC_RSQRT1_S;
14940         goto do_unaryfp;
14941     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
14942         mips32_op = OPC_RSQRT1_D;
14943         goto do_unaryfp;
14944     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
14945         mips32_op = OPC_RSQRT1_PS;
14946         goto do_unaryfp;
14947
14948         /* Reciprocal step */
14949     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
14950         mips32_op = OPC_RECIP1_S;
14951         goto do_unaryfp;
14952     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
14953         mips32_op = OPC_RECIP1_S;
14954         goto do_unaryfp;
14955     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
14956         mips32_op = OPC_RECIP1_PS;
14957         goto do_unaryfp;
14958
14959         /* Conversions from double */
14960     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
14961         mips32_op = OPC_CVT_D_S;
14962         goto do_unaryfp;
14963     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
14964         mips32_op = OPC_CVT_D_W;
14965         goto do_unaryfp;
14966     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
14967         mips32_op = OPC_CVT_D_L;
14968         goto do_unaryfp;
14969
14970         /* Conversions from single */
14971     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
14972         mips32_op = OPC_CVT_S_D;
14973         goto do_unaryfp;
14974     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
14975         mips32_op = OPC_CVT_S_W;
14976         goto do_unaryfp;
14977     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
14978         mips32_op = OPC_CVT_S_L;
14979     do_unaryfp:
14980         gen_farith(ctx, mips32_op, -1, rs, rt, 0);
14981         break;
14982
14983         /* Conditional moves on floating-point codes */
14984     case COND_FLOAT_MOV(MOVT, 0):
14985     case COND_FLOAT_MOV(MOVT, 1):
14986     case COND_FLOAT_MOV(MOVT, 2):
14987     case COND_FLOAT_MOV(MOVT, 3):
14988     case COND_FLOAT_MOV(MOVT, 4):
14989     case COND_FLOAT_MOV(MOVT, 5):
14990     case COND_FLOAT_MOV(MOVT, 6):
14991     case COND_FLOAT_MOV(MOVT, 7):
14992         check_insn_opc_removed(ctx, ISA_MIPS32R6);
14993         gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
14994         break;
14995     case COND_FLOAT_MOV(MOVF, 0):
14996     case COND_FLOAT_MOV(MOVF, 1):
14997     case COND_FLOAT_MOV(MOVF, 2):
14998     case COND_FLOAT_MOV(MOVF, 3):
14999     case COND_FLOAT_MOV(MOVF, 4):
15000     case COND_FLOAT_MOV(MOVF, 5):
15001     case COND_FLOAT_MOV(MOVF, 6):
15002     case COND_FLOAT_MOV(MOVF, 7):
15003         check_insn_opc_removed(ctx, ISA_MIPS32R6);
15004         gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
15005         break;
15006     default:
15007         MIPS_INVAL("pool32fxf");
15008         generate_exception_end(ctx, EXCP_RI);
15009         break;
15010     }
15011 }
15012
15013 static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
15014 {
15015     int32_t offset;
15016     uint16_t insn;
15017     int rt, rs, rd, rr;
15018     int16_t imm;
15019     uint32_t op, minor, minor2, mips32_op;
15020     uint32_t cond, fmt, cc;
15021
15022     insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
15023     ctx->opcode = (ctx->opcode << 16) | insn;
15024
15025     rt = (ctx->opcode >> 21) & 0x1f;
15026     rs = (ctx->opcode >> 16) & 0x1f;
15027     rd = (ctx->opcode >> 11) & 0x1f;
15028     rr = (ctx->opcode >> 6) & 0x1f;
15029     imm = (int16_t) ctx->opcode;
15030
15031     op = (ctx->opcode >> 26) & 0x3f;
15032     switch (op) {
15033     case POOL32A:
15034         minor = ctx->opcode & 0x3f;
15035         switch (minor) {
15036         case 0x00:
15037             minor = (ctx->opcode >> 6) & 0xf;
15038             switch (minor) {
15039             case SLL32:
15040                 mips32_op = OPC_SLL;
15041                 goto do_shifti;
15042             case SRA:
15043                 mips32_op = OPC_SRA;
15044                 goto do_shifti;
15045             case SRL32:
15046                 mips32_op = OPC_SRL;
15047                 goto do_shifti;
15048             case ROTR:
15049                 mips32_op = OPC_ROTR;
15050             do_shifti:
15051                 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
15052                 break;
15053             case SELEQZ:
15054                 check_insn(ctx, ISA_MIPS32R6);
15055                 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
15056                 break;
15057             case SELNEZ:
15058                 check_insn(ctx, ISA_MIPS32R6);
15059                 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
15060                 break;
15061             case R6_RDHWR:
15062                 check_insn(ctx, ISA_MIPS32R6);
15063                 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
15064                 break;
15065             default:
15066                 goto pool32a_invalid;
15067             }
15068             break;
15069         case 0x10:
15070             minor = (ctx->opcode >> 6) & 0xf;
15071             switch (minor) {
15072                 /* Arithmetic */
15073             case ADD:
15074                 mips32_op = OPC_ADD;
15075                 goto do_arith;
15076             case ADDU32:
15077                 mips32_op = OPC_ADDU;
15078                 goto do_arith;
15079             case SUB:
15080                 mips32_op = OPC_SUB;
15081                 goto do_arith;
15082             case SUBU32:
15083                 mips32_op = OPC_SUBU;
15084                 goto do_arith;
15085             case MUL:
15086                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15087                 mips32_op = OPC_MUL;
15088             do_arith:
15089                 gen_arith(ctx, mips32_op, rd, rs, rt);
15090                 break;
15091                 /* Shifts */
15092             case SLLV:
15093                 mips32_op = OPC_SLLV;
15094                 goto do_shift;
15095             case SRLV:
15096                 mips32_op = OPC_SRLV;
15097                 goto do_shift;
15098             case SRAV:
15099                 mips32_op = OPC_SRAV;
15100                 goto do_shift;
15101             case ROTRV:
15102                 mips32_op = OPC_ROTRV;
15103             do_shift:
15104                 gen_shift(ctx, mips32_op, rd, rs, rt);
15105                 break;
15106                 /* Logical operations */
15107             case AND:
15108                 mips32_op = OPC_AND;
15109                 goto do_logic;
15110             case OR32:
15111                 mips32_op = OPC_OR;
15112                 goto do_logic;
15113             case NOR:
15114                 mips32_op = OPC_NOR;
15115                 goto do_logic;
15116             case XOR32:
15117                 mips32_op = OPC_XOR;
15118             do_logic:
15119                 gen_logic(ctx, mips32_op, rd, rs, rt);
15120                 break;
15121                 /* Set less than */
15122             case SLT:
15123                 mips32_op = OPC_SLT;
15124                 goto do_slt;
15125             case SLTU:
15126                 mips32_op = OPC_SLTU;
15127             do_slt:
15128                 gen_slt(ctx, mips32_op, rd, rs, rt);
15129                 break;
15130             default:
15131                 goto pool32a_invalid;
15132             }
15133             break;
15134         case 0x18:
15135             minor = (ctx->opcode >> 6) & 0xf;
15136             switch (minor) {
15137                 /* Conditional moves */
15138             case MOVN: /* MUL */
15139                 if (ctx->insn_flags & ISA_MIPS32R6) {
15140                     /* MUL */
15141                     gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
15142                 } else {
15143                     /* MOVN */
15144                     gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
15145                 }
15146                 break;
15147             case MOVZ: /* MUH */
15148                 if (ctx->insn_flags & ISA_MIPS32R6) {
15149                     /* MUH */
15150                     gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
15151                 } else {
15152                     /* MOVZ */
15153                     gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
15154                 }
15155                 break;
15156             case MULU:
15157                 check_insn(ctx, ISA_MIPS32R6);
15158                 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
15159                 break;
15160             case MUHU:
15161                 check_insn(ctx, ISA_MIPS32R6);
15162                 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
15163                 break;
15164             case LWXS: /* DIV */
15165                 if (ctx->insn_flags & ISA_MIPS32R6) {
15166                     /* DIV */
15167                     gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
15168                 } else {
15169                     /* LWXS */
15170                     gen_ldxs(ctx, rs, rt, rd);
15171                 }
15172                 break;
15173             case MOD:
15174                 check_insn(ctx, ISA_MIPS32R6);
15175                 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
15176                 break;
15177             case R6_DIVU:
15178                 check_insn(ctx, ISA_MIPS32R6);
15179                 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
15180                 break;
15181             case MODU:
15182                 check_insn(ctx, ISA_MIPS32R6);
15183                 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
15184                 break;
15185             default:
15186                 goto pool32a_invalid;
15187             }
15188             break;
15189         case INS:
15190             gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
15191             return;
15192         case LSA:
15193             check_insn(ctx, ISA_MIPS32R6);
15194             gen_lsa(ctx, OPC_LSA, rd, rs, rt,
15195                     extract32(ctx->opcode, 9, 2));
15196             break;
15197         case ALIGN:
15198             check_insn(ctx, ISA_MIPS32R6);
15199             gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2));
15200             break;
15201         case EXT:
15202             gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
15203             return;
15204         case POOL32AXF:
15205             gen_pool32axf(env, ctx, rt, rs);
15206             break;
15207         case BREAK32:
15208             generate_exception_end(ctx, EXCP_BREAK);
15209             break;
15210         case SIGRIE:
15211             check_insn(ctx, ISA_MIPS32R6);
15212             generate_exception_end(ctx, EXCP_RI);
15213             break;
15214         default:
15215         pool32a_invalid:
15216                 MIPS_INVAL("pool32a");
15217                 generate_exception_end(ctx, EXCP_RI);
15218                 break;
15219         }
15220         break;
15221     case POOL32B:
15222         minor = (ctx->opcode >> 12) & 0xf;
15223         switch (minor) {
15224         case CACHE:
15225             check_cp0_enabled(ctx);
15226             if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15227                 gen_cache_operation(ctx, rt, rs, imm);
15228             }
15229             break;
15230         case LWC2:
15231         case SWC2:
15232             /* COP2: Not implemented. */
15233             generate_exception_err(ctx, EXCP_CpU, 2);
15234             break;
15235 #ifdef TARGET_MIPS64
15236         case LDP:
15237         case SDP:
15238             check_insn(ctx, ISA_MIPS3);
15239             check_mips_64(ctx);
15240 #endif
15241             /* fall through */
15242         case LWP:
15243         case SWP:
15244             gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
15245             break;
15246 #ifdef TARGET_MIPS64
15247         case LDM:
15248         case SDM:
15249             check_insn(ctx, ISA_MIPS3);
15250             check_mips_64(ctx);
15251 #endif
15252             /* fall through */
15253         case LWM32:
15254         case SWM32:
15255             gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
15256             break;
15257         default:
15258             MIPS_INVAL("pool32b");
15259             generate_exception_end(ctx, EXCP_RI);
15260             break;
15261         }
15262         break;
15263     case POOL32F:
15264         if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
15265             minor = ctx->opcode & 0x3f;
15266             check_cp1_enabled(ctx);
15267             switch (minor) {
15268             case ALNV_PS:
15269                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15270                 mips32_op = OPC_ALNV_PS;
15271                 goto do_madd;
15272             case MADD_S:
15273                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15274                 mips32_op = OPC_MADD_S;
15275                 goto do_madd;
15276             case MADD_D:
15277                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15278                 mips32_op = OPC_MADD_D;
15279                 goto do_madd;
15280             case MADD_PS:
15281                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15282                 mips32_op = OPC_MADD_PS;
15283                 goto do_madd;
15284             case MSUB_S:
15285                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15286                 mips32_op = OPC_MSUB_S;
15287                 goto do_madd;
15288             case MSUB_D:
15289                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15290                 mips32_op = OPC_MSUB_D;
15291                 goto do_madd;
15292             case MSUB_PS:
15293                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15294                 mips32_op = OPC_MSUB_PS;
15295                 goto do_madd;
15296             case NMADD_S:
15297                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15298                 mips32_op = OPC_NMADD_S;
15299                 goto do_madd;
15300             case NMADD_D:
15301                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15302                 mips32_op = OPC_NMADD_D;
15303                 goto do_madd;
15304             case NMADD_PS:
15305                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15306                 mips32_op = OPC_NMADD_PS;
15307                 goto do_madd;
15308             case NMSUB_S:
15309                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15310                 mips32_op = OPC_NMSUB_S;
15311                 goto do_madd;
15312             case NMSUB_D:
15313                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15314                 mips32_op = OPC_NMSUB_D;
15315                 goto do_madd;
15316             case NMSUB_PS:
15317                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15318                 mips32_op = OPC_NMSUB_PS;
15319             do_madd:
15320                 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
15321                 break;
15322             case CABS_COND_FMT:
15323                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15324                 cond = (ctx->opcode >> 6) & 0xf;
15325                 cc = (ctx->opcode >> 13) & 0x7;
15326                 fmt = (ctx->opcode >> 10) & 0x3;
15327                 switch (fmt) {
15328                 case 0x0:
15329                     gen_cmpabs_s(ctx, cond, rt, rs, cc);
15330                     break;
15331                 case 0x1:
15332                     gen_cmpabs_d(ctx, cond, rt, rs, cc);
15333                     break;
15334                 case 0x2:
15335                     gen_cmpabs_ps(ctx, cond, rt, rs, cc);
15336                     break;
15337                 default:
15338                     goto pool32f_invalid;
15339                 }
15340                 break;
15341             case C_COND_FMT:
15342                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15343                 cond = (ctx->opcode >> 6) & 0xf;
15344                 cc = (ctx->opcode >> 13) & 0x7;
15345                 fmt = (ctx->opcode >> 10) & 0x3;
15346                 switch (fmt) {
15347                 case 0x0:
15348                     gen_cmp_s(ctx, cond, rt, rs, cc);
15349                     break;
15350                 case 0x1:
15351                     gen_cmp_d(ctx, cond, rt, rs, cc);
15352                     break;
15353                 case 0x2:
15354                     gen_cmp_ps(ctx, cond, rt, rs, cc);
15355                     break;
15356                 default:
15357                     goto pool32f_invalid;
15358                 }
15359                 break;
15360             case CMP_CONDN_S:
15361                 check_insn(ctx, ISA_MIPS32R6);
15362                 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
15363                 break;
15364             case CMP_CONDN_D:
15365                 check_insn(ctx, ISA_MIPS32R6);
15366                 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
15367                 break;
15368             case POOL32FXF:
15369                 gen_pool32fxf(ctx, rt, rs);
15370                 break;
15371             case 0x00:
15372                 /* PLL foo */
15373                 switch ((ctx->opcode >> 6) & 0x7) {
15374                 case PLL_PS:
15375                     mips32_op = OPC_PLL_PS;
15376                     goto do_ps;
15377                 case PLU_PS:
15378                     mips32_op = OPC_PLU_PS;
15379                     goto do_ps;
15380                 case PUL_PS:
15381                     mips32_op = OPC_PUL_PS;
15382                     goto do_ps;
15383                 case PUU_PS:
15384                     mips32_op = OPC_PUU_PS;
15385                     goto do_ps;
15386                 case CVT_PS_S:
15387                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
15388                     mips32_op = OPC_CVT_PS_S;
15389                 do_ps:
15390                     gen_farith(ctx, mips32_op, rt, rs, rd, 0);
15391                     break;
15392                 default:
15393                     goto pool32f_invalid;
15394                 }
15395                 break;
15396             case MIN_FMT:
15397                 check_insn(ctx, ISA_MIPS32R6);
15398                 switch ((ctx->opcode >> 9) & 0x3) {
15399                 case FMT_SDPS_S:
15400                     gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
15401                     break;
15402                 case FMT_SDPS_D:
15403                     gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
15404                     break;
15405                 default:
15406                     goto pool32f_invalid;
15407                 }
15408                 break;
15409             case 0x08:
15410                 /* [LS][WDU]XC1 */
15411                 switch ((ctx->opcode >> 6) & 0x7) {
15412                 case LWXC1:
15413                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
15414                     mips32_op = OPC_LWXC1;
15415                     goto do_ldst_cp1;
15416                 case SWXC1:
15417                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
15418                     mips32_op = OPC_SWXC1;
15419                     goto do_ldst_cp1;
15420                 case LDXC1:
15421                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
15422                     mips32_op = OPC_LDXC1;
15423                     goto do_ldst_cp1;
15424                 case SDXC1:
15425                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
15426                     mips32_op = OPC_SDXC1;
15427                     goto do_ldst_cp1;
15428                 case LUXC1:
15429                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
15430                     mips32_op = OPC_LUXC1;
15431                     goto do_ldst_cp1;
15432                 case SUXC1:
15433                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
15434                     mips32_op = OPC_SUXC1;
15435                 do_ldst_cp1:
15436                     gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
15437                     break;
15438                 default:
15439                     goto pool32f_invalid;
15440                 }
15441                 break;
15442             case MAX_FMT:
15443                 check_insn(ctx, ISA_MIPS32R6);
15444                 switch ((ctx->opcode >> 9) & 0x3) {
15445                 case FMT_SDPS_S:
15446                     gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
15447                     break;
15448                 case FMT_SDPS_D:
15449                     gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
15450                     break;
15451                 default:
15452                     goto pool32f_invalid;
15453                 }
15454                 break;
15455             case 0x18:
15456                 /* 3D insns */
15457                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15458                 fmt = (ctx->opcode >> 9) & 0x3;
15459                 switch ((ctx->opcode >> 6) & 0x7) {
15460                 case RSQRT2_FMT:
15461                     switch (fmt) {
15462                     case FMT_SDPS_S:
15463                         mips32_op = OPC_RSQRT2_S;
15464                         goto do_3d;
15465                     case FMT_SDPS_D:
15466                         mips32_op = OPC_RSQRT2_D;
15467                         goto do_3d;
15468                     case FMT_SDPS_PS:
15469                         mips32_op = OPC_RSQRT2_PS;
15470                         goto do_3d;
15471                     default:
15472                         goto pool32f_invalid;
15473                     }
15474                     break;
15475                 case RECIP2_FMT:
15476                     switch (fmt) {
15477                     case FMT_SDPS_S:
15478                         mips32_op = OPC_RECIP2_S;
15479                         goto do_3d;
15480                     case FMT_SDPS_D:
15481                         mips32_op = OPC_RECIP2_D;
15482                         goto do_3d;
15483                     case FMT_SDPS_PS:
15484                         mips32_op = OPC_RECIP2_PS;
15485                         goto do_3d;
15486                     default:
15487                         goto pool32f_invalid;
15488                     }
15489                     break;
15490                 case ADDR_PS:
15491                     mips32_op = OPC_ADDR_PS;
15492                     goto do_3d;
15493                 case MULR_PS:
15494                     mips32_op = OPC_MULR_PS;
15495                 do_3d:
15496                     gen_farith(ctx, mips32_op, rt, rs, rd, 0);
15497                     break;
15498                 default:
15499                     goto pool32f_invalid;
15500                 }
15501                 break;
15502             case 0x20:
15503                 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
15504                 cc = (ctx->opcode >> 13) & 0x7;
15505                 fmt = (ctx->opcode >> 9) & 0x3;
15506                 switch ((ctx->opcode >> 6) & 0x7) {
15507                 case MOVF_FMT: /* RINT_FMT */
15508                     if (ctx->insn_flags & ISA_MIPS32R6) {
15509                         /* RINT_FMT */
15510                         switch (fmt) {
15511                         case FMT_SDPS_S:
15512                             gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
15513                             break;
15514                         case FMT_SDPS_D:
15515                             gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
15516                             break;
15517                         default:
15518                             goto pool32f_invalid;
15519                         }
15520                     } else {
15521                         /* MOVF_FMT */
15522                         switch (fmt) {
15523                         case FMT_SDPS_S:
15524                             gen_movcf_s(ctx, rs, rt, cc, 0);
15525                             break;
15526                         case FMT_SDPS_D:
15527                             gen_movcf_d(ctx, rs, rt, cc, 0);
15528                             break;
15529                         case FMT_SDPS_PS:
15530                             check_ps(ctx);
15531                             gen_movcf_ps(ctx, rs, rt, cc, 0);
15532                             break;
15533                         default:
15534                             goto pool32f_invalid;
15535                         }
15536                     }
15537                     break;
15538                 case MOVT_FMT: /* CLASS_FMT */
15539                     if (ctx->insn_flags & ISA_MIPS32R6) {
15540                         /* CLASS_FMT */
15541                         switch (fmt) {
15542                         case FMT_SDPS_S:
15543                             gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
15544                             break;
15545                         case FMT_SDPS_D:
15546                             gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
15547                             break;
15548                         default:
15549                             goto pool32f_invalid;
15550                         }
15551                     } else {
15552                         /* MOVT_FMT */
15553                         switch (fmt) {
15554                         case FMT_SDPS_S:
15555                             gen_movcf_s(ctx, rs, rt, cc, 1);
15556                             break;
15557                         case FMT_SDPS_D:
15558                             gen_movcf_d(ctx, rs, rt, cc, 1);
15559                             break;
15560                         case FMT_SDPS_PS:
15561                             check_ps(ctx);
15562                             gen_movcf_ps(ctx, rs, rt, cc, 1);
15563                             break;
15564                         default:
15565                             goto pool32f_invalid;
15566                         }
15567                     }
15568                     break;
15569                 case PREFX:
15570                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
15571                     break;
15572                 default:
15573                     goto pool32f_invalid;
15574                 }
15575                 break;
15576 #define FINSN_3ARG_SDPS(prfx)                           \
15577                 switch ((ctx->opcode >> 8) & 0x3) {     \
15578                 case FMT_SDPS_S:                        \
15579                     mips32_op = OPC_##prfx##_S;         \
15580                     goto do_fpop;                       \
15581                 case FMT_SDPS_D:                        \
15582                     mips32_op = OPC_##prfx##_D;         \
15583                     goto do_fpop;                       \
15584                 case FMT_SDPS_PS:                       \
15585                     check_ps(ctx);                      \
15586                     mips32_op = OPC_##prfx##_PS;        \
15587                     goto do_fpop;                       \
15588                 default:                                \
15589                     goto pool32f_invalid;               \
15590                 }
15591             case MINA_FMT:
15592                 check_insn(ctx, ISA_MIPS32R6);
15593                 switch ((ctx->opcode >> 9) & 0x3) {
15594                 case FMT_SDPS_S:
15595                     gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
15596                     break;
15597                 case FMT_SDPS_D:
15598                     gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
15599                     break;
15600                 default:
15601                     goto pool32f_invalid;
15602                 }
15603                 break;
15604             case MAXA_FMT:
15605                 check_insn(ctx, ISA_MIPS32R6);
15606                 switch ((ctx->opcode >> 9) & 0x3) {
15607                 case FMT_SDPS_S:
15608                     gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
15609                     break;
15610                 case FMT_SDPS_D:
15611                     gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
15612                     break;
15613                 default:
15614                     goto pool32f_invalid;
15615                 }
15616                 break;
15617             case 0x30:
15618                 /* regular FP ops */
15619                 switch ((ctx->opcode >> 6) & 0x3) {
15620                 case ADD_FMT:
15621                     FINSN_3ARG_SDPS(ADD);
15622                     break;
15623                 case SUB_FMT:
15624                     FINSN_3ARG_SDPS(SUB);
15625                     break;
15626                 case MUL_FMT:
15627                     FINSN_3ARG_SDPS(MUL);
15628                     break;
15629                 case DIV_FMT:
15630                     fmt = (ctx->opcode >> 8) & 0x3;
15631                     if (fmt == 1) {
15632                         mips32_op = OPC_DIV_D;
15633                     } else if (fmt == 0) {
15634                         mips32_op = OPC_DIV_S;
15635                     } else {
15636                         goto pool32f_invalid;
15637                     }
15638                     goto do_fpop;
15639                 default:
15640                     goto pool32f_invalid;
15641                 }
15642                 break;
15643             case 0x38:
15644                 /* cmovs */
15645                 switch ((ctx->opcode >> 6) & 0x7) {
15646                 case MOVN_FMT: /* SELEQZ_FMT */
15647                     if (ctx->insn_flags & ISA_MIPS32R6) {
15648                         /* SELEQZ_FMT */
15649                         switch ((ctx->opcode >> 9) & 0x3) {
15650                         case FMT_SDPS_S:
15651                             gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
15652                             break;
15653                         case FMT_SDPS_D:
15654                             gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
15655                             break;
15656                         default:
15657                             goto pool32f_invalid;
15658                         }
15659                     } else {
15660                         /* MOVN_FMT */
15661                         FINSN_3ARG_SDPS(MOVN);
15662                     }
15663                     break;
15664                 case MOVN_FMT_04:
15665                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
15666                     FINSN_3ARG_SDPS(MOVN);
15667                     break;
15668                 case MOVZ_FMT: /* SELNEZ_FMT */
15669                     if (ctx->insn_flags & ISA_MIPS32R6) {
15670                         /* SELNEZ_FMT */
15671                         switch ((ctx->opcode >> 9) & 0x3) {
15672                         case FMT_SDPS_S:
15673                             gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
15674                             break;
15675                         case FMT_SDPS_D:
15676                             gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
15677                             break;
15678                         default:
15679                             goto pool32f_invalid;
15680                         }
15681                     } else {
15682                         /* MOVZ_FMT */
15683                         FINSN_3ARG_SDPS(MOVZ);
15684                     }
15685                     break;
15686                 case MOVZ_FMT_05:
15687                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
15688                     FINSN_3ARG_SDPS(MOVZ);
15689                     break;
15690                 case SEL_FMT:
15691                     check_insn(ctx, ISA_MIPS32R6);
15692                     switch ((ctx->opcode >> 9) & 0x3) {
15693                     case FMT_SDPS_S:
15694                         gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
15695                         break;
15696                     case FMT_SDPS_D:
15697                         gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
15698                         break;
15699                     default:
15700                         goto pool32f_invalid;
15701                     }
15702                     break;
15703                 case MADDF_FMT:
15704                     check_insn(ctx, ISA_MIPS32R6);
15705                     switch ((ctx->opcode >> 9) & 0x3) {
15706                     case FMT_SDPS_S:
15707                         mips32_op = OPC_MADDF_S;
15708                         goto do_fpop;
15709                     case FMT_SDPS_D:
15710                         mips32_op = OPC_MADDF_D;
15711                         goto do_fpop;
15712                     default:
15713                         goto pool32f_invalid;
15714                     }
15715                     break;
15716                 case MSUBF_FMT:
15717                     check_insn(ctx, ISA_MIPS32R6);
15718                     switch ((ctx->opcode >> 9) & 0x3) {
15719                     case FMT_SDPS_S:
15720                         mips32_op = OPC_MSUBF_S;
15721                         goto do_fpop;
15722                     case FMT_SDPS_D:
15723                         mips32_op = OPC_MSUBF_D;
15724                         goto do_fpop;
15725                     default:
15726                         goto pool32f_invalid;
15727                     }
15728                     break;
15729                 default:
15730                     goto pool32f_invalid;
15731                 }
15732                 break;
15733             do_fpop:
15734                 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
15735                 break;
15736             default:
15737             pool32f_invalid:
15738                 MIPS_INVAL("pool32f");
15739                 generate_exception_end(ctx, EXCP_RI);
15740                 break;
15741             }
15742         } else {
15743             generate_exception_err(ctx, EXCP_CpU, 1);
15744         }
15745         break;
15746     case POOL32I:
15747         minor = (ctx->opcode >> 21) & 0x1f;
15748         switch (minor) {
15749         case BLTZ:
15750             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15751             gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
15752             break;
15753         case BLTZAL:
15754             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15755             gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
15756             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15757             break;
15758         case BLTZALS:
15759             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15760             gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
15761             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15762             break;
15763         case BGEZ:
15764             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15765             gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
15766             break;
15767         case BGEZAL:
15768             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15769             gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
15770             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15771             break;
15772         case BGEZALS:
15773             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15774             gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
15775             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15776             break;
15777         case BLEZ:
15778             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15779             gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
15780             break;
15781         case BGTZ:
15782             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15783             gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
15784             break;
15785
15786             /* Traps */
15787         case TLTI: /* BC1EQZC */
15788             if (ctx->insn_flags & ISA_MIPS32R6) {
15789                 /* BC1EQZC */
15790                 check_cp1_enabled(ctx);
15791                 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
15792             } else {
15793                 /* TLTI */
15794                 mips32_op = OPC_TLTI;
15795                 goto do_trapi;
15796             }
15797             break;
15798         case TGEI: /* BC1NEZC */
15799             if (ctx->insn_flags & ISA_MIPS32R6) {
15800                 /* BC1NEZC */
15801                 check_cp1_enabled(ctx);
15802                 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
15803             } else {
15804                 /* TGEI */
15805                 mips32_op = OPC_TGEI;
15806                 goto do_trapi;
15807             }
15808             break;
15809         case TLTIU:
15810             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15811             mips32_op = OPC_TLTIU;
15812             goto do_trapi;
15813         case TGEIU:
15814             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15815             mips32_op = OPC_TGEIU;
15816             goto do_trapi;
15817         case TNEI: /* SYNCI */
15818             if (ctx->insn_flags & ISA_MIPS32R6) {
15819                 /* SYNCI */
15820                 /* Break the TB to be able to sync copied instructions
15821                    immediately */
15822                 ctx->base.is_jmp = DISAS_STOP;
15823             } else {
15824                 /* TNEI */
15825                 mips32_op = OPC_TNEI;
15826                 goto do_trapi;
15827             }
15828             break;
15829         case TEQI:
15830             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15831             mips32_op = OPC_TEQI;
15832         do_trapi:
15833             gen_trap(ctx, mips32_op, rs, -1, imm);
15834             break;
15835
15836         case BNEZC:
15837         case BEQZC:
15838             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15839             gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
15840                                4, rs, 0, imm << 1, 0);
15841             /* Compact branches don't have a delay slot, so just let
15842                the normal delay slot handling take us to the branch
15843                target. */
15844             break;
15845         case LUI:
15846             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15847             gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
15848             break;
15849         case SYNCI:
15850             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15851             /* Break the TB to be able to sync copied instructions
15852                immediately */
15853             ctx->base.is_jmp = DISAS_STOP;
15854             break;
15855         case BC2F:
15856         case BC2T:
15857             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15858             /* COP2: Not implemented. */
15859             generate_exception_err(ctx, EXCP_CpU, 2);
15860             break;
15861         case BC1F:
15862             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15863             mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
15864             goto do_cp1branch;
15865         case BC1T:
15866             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15867             mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
15868             goto do_cp1branch;
15869         case BC1ANY4F:
15870             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15871             mips32_op = OPC_BC1FANY4;
15872             goto do_cp1mips3d;
15873         case BC1ANY4T:
15874             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15875             mips32_op = OPC_BC1TANY4;
15876         do_cp1mips3d:
15877             check_cop1x(ctx);
15878             check_insn(ctx, ASE_MIPS3D);
15879             /* Fall through */
15880         do_cp1branch:
15881             if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15882                 check_cp1_enabled(ctx);
15883                 gen_compute_branch1(ctx, mips32_op,
15884                                     (ctx->opcode >> 18) & 0x7, imm << 1);
15885             } else {
15886                 generate_exception_err(ctx, EXCP_CpU, 1);
15887             }
15888             break;
15889         case BPOSGE64:
15890         case BPOSGE32:
15891             /* MIPS DSP: not implemented */
15892             /* Fall through */
15893         default:
15894             MIPS_INVAL("pool32i");
15895             generate_exception_end(ctx, EXCP_RI);
15896             break;
15897         }
15898         break;
15899     case POOL32C:
15900         minor = (ctx->opcode >> 12) & 0xf;
15901         offset = sextract32(ctx->opcode, 0,
15902                             (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
15903         switch (minor) {
15904         case LWL:
15905             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15906             mips32_op = OPC_LWL;
15907             goto do_ld_lr;
15908         case SWL:
15909             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15910             mips32_op = OPC_SWL;
15911             goto do_st_lr;
15912         case LWR:
15913             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15914             mips32_op = OPC_LWR;
15915             goto do_ld_lr;
15916         case SWR:
15917             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15918             mips32_op = OPC_SWR;
15919             goto do_st_lr;
15920 #if defined(TARGET_MIPS64)
15921         case LDL:
15922             check_insn(ctx, ISA_MIPS3);
15923             check_mips_64(ctx);
15924             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15925             mips32_op = OPC_LDL;
15926             goto do_ld_lr;
15927         case SDL:
15928             check_insn(ctx, ISA_MIPS3);
15929             check_mips_64(ctx);
15930             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15931             mips32_op = OPC_SDL;
15932             goto do_st_lr;
15933         case LDR:
15934             check_insn(ctx, ISA_MIPS3);
15935             check_mips_64(ctx);
15936             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15937             mips32_op = OPC_LDR;
15938             goto do_ld_lr;
15939         case SDR:
15940             check_insn(ctx, ISA_MIPS3);
15941             check_mips_64(ctx);
15942             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15943             mips32_op = OPC_SDR;
15944             goto do_st_lr;
15945         case LWU:
15946             check_insn(ctx, ISA_MIPS3);
15947             check_mips_64(ctx);
15948             mips32_op = OPC_LWU;
15949             goto do_ld_lr;
15950         case LLD:
15951             check_insn(ctx, ISA_MIPS3);
15952             check_mips_64(ctx);
15953             mips32_op = OPC_LLD;
15954             goto do_ld_lr;
15955 #endif
15956         case LL:
15957             mips32_op = OPC_LL;
15958             goto do_ld_lr;
15959         do_ld_lr:
15960             gen_ld(ctx, mips32_op, rt, rs, offset);
15961             break;
15962         do_st_lr:
15963             gen_st(ctx, mips32_op, rt, rs, offset);
15964             break;
15965         case SC:
15966             gen_st_cond(ctx, OPC_SC, rt, rs, offset);
15967             break;
15968 #if defined(TARGET_MIPS64)
15969         case SCD:
15970             check_insn(ctx, ISA_MIPS3);
15971             check_mips_64(ctx);
15972             gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
15973             break;
15974 #endif
15975         case LD_EVA:
15976             if (!ctx->eva) {
15977                 MIPS_INVAL("pool32c ld-eva");
15978                 generate_exception_end(ctx, EXCP_RI);
15979                 break;
15980             }
15981             check_cp0_enabled(ctx);
15982
15983             minor2 = (ctx->opcode >> 9) & 0x7;
15984             offset = sextract32(ctx->opcode, 0, 9);
15985             switch (minor2) {
15986             case LBUE:
15987                 mips32_op = OPC_LBUE;
15988                 goto do_ld_lr;
15989             case LHUE:
15990                 mips32_op = OPC_LHUE;
15991                 goto do_ld_lr;
15992             case LWLE:
15993                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15994                 mips32_op = OPC_LWLE;
15995                 goto do_ld_lr;
15996             case LWRE:
15997                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15998                 mips32_op = OPC_LWRE;
15999                 goto do_ld_lr;
16000             case LBE:
16001                 mips32_op = OPC_LBE;
16002                 goto do_ld_lr;
16003             case LHE:
16004                 mips32_op = OPC_LHE;
16005                 goto do_ld_lr;
16006             case LLE:
16007                 mips32_op = OPC_LLE;
16008                 goto do_ld_lr;
16009             case LWE:
16010                 mips32_op = OPC_LWE;
16011                 goto do_ld_lr;
16012             };
16013             break;
16014         case ST_EVA:
16015             if (!ctx->eva) {
16016                 MIPS_INVAL("pool32c st-eva");
16017                 generate_exception_end(ctx, EXCP_RI);
16018                 break;
16019             }
16020             check_cp0_enabled(ctx);
16021
16022             minor2 = (ctx->opcode >> 9) & 0x7;
16023             offset = sextract32(ctx->opcode, 0, 9);
16024             switch (minor2) {
16025             case SWLE:
16026                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16027                 mips32_op = OPC_SWLE;
16028                 goto do_st_lr;
16029             case SWRE:
16030                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16031                 mips32_op = OPC_SWRE;
16032                 goto do_st_lr;
16033             case PREFE:
16034                 /* Treat as no-op */
16035                 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16036                     /* hint codes 24-31 are reserved and signal RI */
16037                     generate_exception(ctx, EXCP_RI);
16038                 }
16039                 break;
16040             case CACHEE:
16041                 /* Treat as no-op */
16042                 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
16043                     gen_cache_operation(ctx, rt, rs, offset);
16044                 }
16045                 break;
16046             case SBE:
16047                 mips32_op = OPC_SBE;
16048                 goto do_st_lr;
16049             case SHE:
16050                 mips32_op = OPC_SHE;
16051                 goto do_st_lr;
16052             case SCE:
16053                 gen_st_cond(ctx, OPC_SCE, rt, rs, offset);
16054                 break;
16055             case SWE:
16056                 mips32_op = OPC_SWE;
16057                 goto do_st_lr;
16058             };
16059             break;
16060         case PREF:
16061             /* Treat as no-op */
16062             if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16063                 /* hint codes 24-31 are reserved and signal RI */
16064                 generate_exception(ctx, EXCP_RI);
16065             }
16066             break;
16067         default:
16068             MIPS_INVAL("pool32c");
16069             generate_exception_end(ctx, EXCP_RI);
16070             break;
16071         }
16072         break;
16073     case ADDI32: /* AUI, LUI */
16074         if (ctx->insn_flags & ISA_MIPS32R6) {
16075             /* AUI, LUI */
16076             gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
16077         } else {
16078             /* ADDI32 */
16079             mips32_op = OPC_ADDI;
16080             goto do_addi;
16081         }
16082         break;
16083     case ADDIU32:
16084         mips32_op = OPC_ADDIU;
16085     do_addi:
16086         gen_arith_imm(ctx, mips32_op, rt, rs, imm);
16087         break;
16088
16089         /* Logical operations */
16090     case ORI32:
16091         mips32_op = OPC_ORI;
16092         goto do_logici;
16093     case XORI32:
16094         mips32_op = OPC_XORI;
16095         goto do_logici;
16096     case ANDI32:
16097         mips32_op = OPC_ANDI;
16098     do_logici:
16099         gen_logic_imm(ctx, mips32_op, rt, rs, imm);
16100         break;
16101
16102         /* Set less than immediate */
16103     case SLTI32:
16104         mips32_op = OPC_SLTI;
16105         goto do_slti;
16106     case SLTIU32:
16107         mips32_op = OPC_SLTIU;
16108     do_slti:
16109         gen_slt_imm(ctx, mips32_op, rt, rs, imm);
16110         break;
16111     case JALX32:
16112         check_insn_opc_removed(ctx, ISA_MIPS32R6);
16113         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
16114         gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
16115         ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16116         break;
16117     case JALS32: /* BOVC, BEQC, BEQZALC */
16118         if (ctx->insn_flags & ISA_MIPS32R6) {
16119             if (rs >= rt) {
16120                 /* BOVC */
16121                 mips32_op = OPC_BOVC;
16122             } else if (rs < rt && rs == 0) {
16123                 /* BEQZALC */
16124                 mips32_op = OPC_BEQZALC;
16125             } else {
16126                 /* BEQC */
16127                 mips32_op = OPC_BEQC;
16128             }
16129             gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16130         } else {
16131             /* JALS32 */
16132             offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
16133             gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
16134             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16135         }
16136         break;
16137     case BEQ32: /* BC */
16138         if (ctx->insn_flags & ISA_MIPS32R6) {
16139             /* BC */
16140             gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
16141                                        sextract32(ctx->opcode << 1, 0, 27));
16142         } else {
16143             /* BEQ32 */
16144             gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
16145         }
16146         break;
16147     case BNE32: /* BALC */
16148         if (ctx->insn_flags & ISA_MIPS32R6) {
16149             /* BALC */
16150             gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
16151                                        sextract32(ctx->opcode << 1, 0, 27));
16152         } else {
16153             /* BNE32 */
16154             gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
16155         }
16156         break;
16157     case J32: /* BGTZC, BLTZC, BLTC */
16158         if (ctx->insn_flags & ISA_MIPS32R6) {
16159             if (rs == 0 && rt != 0) {
16160                 /* BGTZC */
16161                 mips32_op = OPC_BGTZC;
16162             } else if (rs != 0 && rt != 0 && rs == rt) {
16163                 /* BLTZC */
16164                 mips32_op = OPC_BLTZC;
16165             } else {
16166                 /* BLTC */
16167                 mips32_op = OPC_BLTC;
16168             }
16169             gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16170         } else {
16171             /* J32 */
16172             gen_compute_branch(ctx, OPC_J, 4, rt, rs,
16173                                (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
16174         }
16175         break;
16176     case JAL32: /* BLEZC, BGEZC, BGEC */
16177         if (ctx->insn_flags & ISA_MIPS32R6) {
16178             if (rs == 0 && rt != 0) {
16179                 /* BLEZC */
16180                 mips32_op = OPC_BLEZC;
16181             } else if (rs != 0 && rt != 0 && rs == rt) {
16182                 /* BGEZC */
16183                 mips32_op = OPC_BGEZC;
16184             } else {
16185                 /* BGEC */
16186                 mips32_op = OPC_BGEC;
16187             }
16188             gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16189         } else {
16190             /* JAL32 */
16191             gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
16192                                (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
16193             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16194         }
16195         break;
16196         /* Floating point (COP1) */
16197     case LWC132:
16198         mips32_op = OPC_LWC1;
16199         goto do_cop1;
16200     case LDC132:
16201         mips32_op = OPC_LDC1;
16202         goto do_cop1;
16203     case SWC132:
16204         mips32_op = OPC_SWC1;
16205         goto do_cop1;
16206     case SDC132:
16207         mips32_op = OPC_SDC1;
16208     do_cop1:
16209         gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
16210         break;
16211     case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16212         if (ctx->insn_flags & ISA_MIPS32R6) {
16213             /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16214             switch ((ctx->opcode >> 16) & 0x1f) {
16215             case ADDIUPC_00:
16216             case ADDIUPC_01:
16217             case ADDIUPC_02:
16218             case ADDIUPC_03:
16219             case ADDIUPC_04:
16220             case ADDIUPC_05:
16221             case ADDIUPC_06:
16222             case ADDIUPC_07:
16223                 gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
16224                 break;
16225             case AUIPC:
16226                 gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
16227                 break;
16228             case ALUIPC:
16229                 gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
16230                 break;
16231             case LWPC_08:
16232             case LWPC_09:
16233             case LWPC_0A:
16234             case LWPC_0B:
16235             case LWPC_0C:
16236             case LWPC_0D:
16237             case LWPC_0E:
16238             case LWPC_0F:
16239                 gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
16240                 break;
16241             default:
16242                 generate_exception(ctx, EXCP_RI);
16243                 break;
16244             }
16245         } else {
16246             /* ADDIUPC */
16247             int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
16248             offset = SIMM(ctx->opcode, 0, 23) << 2;
16249
16250             gen_addiupc(ctx, reg, offset, 0, 0);
16251         }
16252         break;
16253     case BNVC: /* BNEC, BNEZALC */
16254         check_insn(ctx, ISA_MIPS32R6);
16255         if (rs >= rt) {
16256             /* BNVC */
16257             mips32_op = OPC_BNVC;
16258         } else if (rs < rt && rs == 0) {
16259             /* BNEZALC */
16260             mips32_op = OPC_BNEZALC;
16261         } else {
16262             /* BNEC */
16263             mips32_op = OPC_BNEC;
16264         }
16265         gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16266         break;
16267     case R6_BNEZC: /* JIALC */
16268         check_insn(ctx, ISA_MIPS32R6);
16269         if (rt != 0) {
16270             /* BNEZC */
16271             gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
16272                                        sextract32(ctx->opcode << 1, 0, 22));
16273         } else {
16274             /* JIALC */
16275             gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
16276         }
16277         break;
16278     case R6_BEQZC: /* JIC */
16279         check_insn(ctx, ISA_MIPS32R6);
16280         if (rt != 0) {
16281             /* BEQZC */
16282             gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
16283                                        sextract32(ctx->opcode << 1, 0, 22));
16284         } else {
16285             /* JIC */
16286             gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
16287         }
16288         break;
16289     case BLEZALC: /* BGEZALC, BGEUC */
16290         check_insn(ctx, ISA_MIPS32R6);
16291         if (rs == 0 && rt != 0) {
16292             /* BLEZALC */
16293             mips32_op = OPC_BLEZALC;
16294         } else if (rs != 0 && rt != 0 && rs == rt) {
16295             /* BGEZALC */
16296             mips32_op = OPC_BGEZALC;
16297         } else {
16298             /* BGEUC */
16299             mips32_op = OPC_BGEUC;
16300         }
16301         gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16302         break;
16303     case BGTZALC: /* BLTZALC, BLTUC */
16304         check_insn(ctx, ISA_MIPS32R6);
16305         if (rs == 0 && rt != 0) {
16306             /* BGTZALC */
16307             mips32_op = OPC_BGTZALC;
16308         } else if (rs != 0 && rt != 0 && rs == rt) {
16309             /* BLTZALC */
16310             mips32_op = OPC_BLTZALC;
16311         } else {
16312             /* BLTUC */
16313             mips32_op = OPC_BLTUC;
16314         }
16315         gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16316         break;
16317         /* Loads and stores */
16318     case LB32:
16319         mips32_op = OPC_LB;
16320         goto do_ld;
16321     case LBU32:
16322         mips32_op = OPC_LBU;
16323         goto do_ld;
16324     case LH32:
16325         mips32_op = OPC_LH;
16326         goto do_ld;
16327     case LHU32:
16328         mips32_op = OPC_LHU;
16329         goto do_ld;
16330     case LW32:
16331         mips32_op = OPC_LW;
16332         goto do_ld;
16333 #ifdef TARGET_MIPS64
16334     case LD32:
16335         check_insn(ctx, ISA_MIPS3);
16336         check_mips_64(ctx);
16337         mips32_op = OPC_LD;
16338         goto do_ld;
16339     case SD32:
16340         check_insn(ctx, ISA_MIPS3);
16341         check_mips_64(ctx);
16342         mips32_op = OPC_SD;
16343         goto do_st;
16344 #endif
16345     case SB32:
16346         mips32_op = OPC_SB;
16347         goto do_st;
16348     case SH32:
16349         mips32_op = OPC_SH;
16350         goto do_st;
16351     case SW32:
16352         mips32_op = OPC_SW;
16353         goto do_st;
16354     do_ld:
16355         gen_ld(ctx, mips32_op, rt, rs, imm);
16356         break;
16357     do_st:
16358         gen_st(ctx, mips32_op, rt, rs, imm);
16359         break;
16360     default:
16361         generate_exception_end(ctx, EXCP_RI);
16362         break;
16363     }
16364 }
16365
16366 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
16367 {
16368     uint32_t op;
16369
16370     /* make sure instructions are on a halfword boundary */
16371     if (ctx->base.pc_next & 0x1) {
16372         env->CP0_BadVAddr = ctx->base.pc_next;
16373         generate_exception_end(ctx, EXCP_AdEL);
16374         return 2;
16375     }
16376
16377     op = (ctx->opcode >> 10) & 0x3f;
16378     /* Enforce properly-sized instructions in a delay slot */
16379     if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
16380         switch (op & 0x7) { /* MSB-3..MSB-5 */
16381         case 0:
16382         /* POOL32A, POOL32B, POOL32I, POOL32C */
16383         case 4:
16384         /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
16385         case 5:
16386         /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
16387         case 6:
16388         /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
16389         case 7:
16390         /* LB32, LH32, LWC132, LDC132, LW32 */
16391             if (ctx->hflags & MIPS_HFLAG_BDS16) {
16392                 generate_exception_end(ctx, EXCP_RI);
16393                 return 2;
16394             }
16395             break;
16396         case 1:
16397         /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
16398         case 2:
16399         /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
16400         case 3:
16401         /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
16402             if (ctx->hflags & MIPS_HFLAG_BDS32) {
16403                 generate_exception_end(ctx, EXCP_RI);
16404                 return 2;
16405             }
16406             break;
16407         }
16408     }
16409
16410     switch (op) {
16411     case POOL16A:
16412         {
16413             int rd = mmreg(uMIPS_RD(ctx->opcode));
16414             int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
16415             int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
16416             uint32_t opc = 0;
16417
16418             switch (ctx->opcode & 0x1) {
16419             case ADDU16:
16420                 opc = OPC_ADDU;
16421                 break;
16422             case SUBU16:
16423                 opc = OPC_SUBU;
16424                 break;
16425             }
16426             if (ctx->insn_flags & ISA_MIPS32R6) {
16427                 /* In the Release 6 the register number location in
16428                  * the instruction encoding has changed.
16429                  */
16430                 gen_arith(ctx, opc, rs1, rd, rs2);
16431             } else {
16432                 gen_arith(ctx, opc, rd, rs1, rs2);
16433             }
16434         }
16435         break;
16436     case POOL16B:
16437         {
16438             int rd = mmreg(uMIPS_RD(ctx->opcode));
16439             int rs = mmreg(uMIPS_RS(ctx->opcode));
16440             int amount = (ctx->opcode >> 1) & 0x7;
16441             uint32_t opc = 0;
16442             amount = amount == 0 ? 8 : amount;
16443
16444             switch (ctx->opcode & 0x1) {
16445             case SLL16:
16446                 opc = OPC_SLL;
16447                 break;
16448             case SRL16:
16449                 opc = OPC_SRL;
16450                 break;
16451             }
16452
16453             gen_shift_imm(ctx, opc, rd, rs, amount);
16454         }
16455         break;
16456     case POOL16C:
16457         if (ctx->insn_flags & ISA_MIPS32R6) {
16458             gen_pool16c_r6_insn(ctx);
16459         } else {
16460             gen_pool16c_insn(ctx);
16461         }
16462         break;
16463     case LWGP16:
16464         {
16465             int rd = mmreg(uMIPS_RD(ctx->opcode));
16466             int rb = 28;            /* GP */
16467             int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
16468
16469             gen_ld(ctx, OPC_LW, rd, rb, offset);
16470         }
16471         break;
16472     case POOL16F:
16473         check_insn_opc_removed(ctx, ISA_MIPS32R6);
16474         if (ctx->opcode & 1) {
16475             generate_exception_end(ctx, EXCP_RI);
16476         } else {
16477             /* MOVEP */
16478             int enc_dest = uMIPS_RD(ctx->opcode);
16479             int enc_rt = uMIPS_RS2(ctx->opcode);
16480             int enc_rs = uMIPS_RS1(ctx->opcode);
16481             gen_movep(ctx, enc_dest, enc_rt, enc_rs);
16482         }
16483         break;
16484     case LBU16:
16485         {
16486             int rd = mmreg(uMIPS_RD(ctx->opcode));
16487             int rb = mmreg(uMIPS_RS(ctx->opcode));
16488             int16_t offset = ZIMM(ctx->opcode, 0, 4);
16489             offset = (offset == 0xf ? -1 : offset);
16490
16491             gen_ld(ctx, OPC_LBU, rd, rb, offset);
16492         }
16493         break;
16494     case LHU16:
16495         {
16496             int rd = mmreg(uMIPS_RD(ctx->opcode));
16497             int rb = mmreg(uMIPS_RS(ctx->opcode));
16498             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
16499
16500             gen_ld(ctx, OPC_LHU, rd, rb, offset);
16501         }
16502         break;
16503     case LWSP16:
16504         {
16505             int rd = (ctx->opcode >> 5) & 0x1f;
16506             int rb = 29;            /* SP */
16507             int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
16508
16509             gen_ld(ctx, OPC_LW, rd, rb, offset);
16510         }
16511         break;
16512     case LW16:
16513         {
16514             int rd = mmreg(uMIPS_RD(ctx->opcode));
16515             int rb = mmreg(uMIPS_RS(ctx->opcode));
16516             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
16517
16518             gen_ld(ctx, OPC_LW, rd, rb, offset);
16519         }
16520         break;
16521     case SB16:
16522         {
16523             int rd = mmreg2(uMIPS_RD(ctx->opcode));
16524             int rb = mmreg(uMIPS_RS(ctx->opcode));
16525             int16_t offset = ZIMM(ctx->opcode, 0, 4);
16526
16527             gen_st(ctx, OPC_SB, rd, rb, offset);
16528         }
16529         break;
16530     case SH16:
16531         {
16532             int rd = mmreg2(uMIPS_RD(ctx->opcode));
16533             int rb = mmreg(uMIPS_RS(ctx->opcode));
16534             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
16535
16536             gen_st(ctx, OPC_SH, rd, rb, offset);
16537         }
16538         break;
16539     case SWSP16:
16540         {
16541             int rd = (ctx->opcode >> 5) & 0x1f;
16542             int rb = 29;            /* SP */
16543             int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
16544
16545             gen_st(ctx, OPC_SW, rd, rb, offset);
16546         }
16547         break;
16548     case SW16:
16549         {
16550             int rd = mmreg2(uMIPS_RD(ctx->opcode));
16551             int rb = mmreg(uMIPS_RS(ctx->opcode));
16552             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
16553
16554             gen_st(ctx, OPC_SW, rd, rb, offset);
16555         }
16556         break;
16557     case MOVE16:
16558         {
16559             int rd = uMIPS_RD5(ctx->opcode);
16560             int rs = uMIPS_RS5(ctx->opcode);
16561
16562             gen_arith(ctx, OPC_ADDU, rd, rs, 0);
16563         }
16564         break;
16565     case ANDI16:
16566         gen_andi16(ctx);
16567         break;
16568     case POOL16D:
16569         switch (ctx->opcode & 0x1) {
16570         case ADDIUS5:
16571             gen_addius5(ctx);
16572             break;
16573         case ADDIUSP:
16574             gen_addiusp(ctx);
16575             break;
16576         }
16577         break;
16578     case POOL16E:
16579         switch (ctx->opcode & 0x1) {
16580         case ADDIUR2:
16581             gen_addiur2(ctx);
16582             break;
16583         case ADDIUR1SP:
16584             gen_addiur1sp(ctx);
16585             break;
16586         }
16587         break;
16588     case B16: /* BC16 */
16589         gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
16590                            sextract32(ctx->opcode, 0, 10) << 1,
16591                            (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
16592         break;
16593     case BNEZ16: /* BNEZC16 */
16594     case BEQZ16: /* BEQZC16 */
16595         gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
16596                            mmreg(uMIPS_RD(ctx->opcode)),
16597                            0, sextract32(ctx->opcode, 0, 7) << 1,
16598                            (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
16599
16600         break;
16601     case LI16:
16602         {
16603             int reg = mmreg(uMIPS_RD(ctx->opcode));
16604             int imm = ZIMM(ctx->opcode, 0, 7);
16605
16606             imm = (imm == 0x7f ? -1 : imm);
16607             tcg_gen_movi_tl(cpu_gpr[reg], imm);
16608         }
16609         break;
16610     case RES_29:
16611     case RES_31:
16612     case RES_39:
16613         generate_exception_end(ctx, EXCP_RI);
16614         break;
16615     default:
16616         decode_micromips32_opc(env, ctx);
16617         return 4;
16618     }
16619
16620     return 2;
16621 }
16622
16623 /*
16624  *
16625  * nanoMIPS opcodes
16626  *
16627  */
16628
16629 /* MAJOR, P16, and P32 pools opcodes */
16630 enum {
16631     NM_P_ADDIU      = 0x00,
16632     NM_ADDIUPC      = 0x01,
16633     NM_MOVE_BALC    = 0x02,
16634     NM_P16_MV       = 0x04,
16635     NM_LW16         = 0x05,
16636     NM_BC16         = 0x06,
16637     NM_P16_SR       = 0x07,
16638
16639     NM_POOL32A      = 0x08,
16640     NM_P_BAL        = 0x0a,
16641     NM_P16_SHIFT    = 0x0c,
16642     NM_LWSP16       = 0x0d,
16643     NM_BALC16       = 0x0e,
16644     NM_P16_4X4      = 0x0f,
16645
16646     NM_P_GP_W       = 0x10,
16647     NM_P_GP_BH      = 0x11,
16648     NM_P_J          = 0x12,
16649     NM_P16C         = 0x14,
16650     NM_LWGP16       = 0x15,
16651     NM_P16_LB       = 0x17,
16652
16653     NM_P48I         = 0x18,
16654     NM_P16_A1       = 0x1c,
16655     NM_LW4X4        = 0x1d,
16656     NM_P16_LH       = 0x1f,
16657
16658     NM_P_U12        = 0x20,
16659     NM_P_LS_U12     = 0x21,
16660     NM_P_BR1        = 0x22,
16661     NM_P16_A2       = 0x24,
16662     NM_SW16         = 0x25,
16663     NM_BEQZC16      = 0x26,
16664
16665     NM_POOL32F      = 0x28,
16666     NM_P_LS_S9      = 0x29,
16667     NM_P_BR2        = 0x2a,
16668
16669     NM_P16_ADDU     = 0x2c,
16670     NM_SWSP16       = 0x2d,
16671     NM_BNEZC16      = 0x2e,
16672     NM_MOVEP        = 0x2f,
16673
16674     NM_POOL32S      = 0x30,
16675     NM_P_BRI        = 0x32,
16676     NM_LI16         = 0x34,
16677     NM_SWGP16       = 0x35,
16678     NM_P16_BR       = 0x36,
16679
16680     NM_P_LUI        = 0x38,
16681     NM_ANDI16       = 0x3c,
16682     NM_SW4X4        = 0x3d,
16683     NM_MOVEPREV     = 0x3f,
16684 };
16685
16686 /* POOL32A instruction pool */
16687 enum {
16688     NM_POOL32A0    = 0x00,
16689     NM_SPECIAL2    = 0x01,
16690     NM_COP2_1      = 0x02,
16691     NM_UDI         = 0x03,
16692     NM_POOL32A5    = 0x05,
16693     NM_POOL32A7    = 0x07,
16694 };
16695
16696 /* P.GP.W instruction pool */
16697 enum {
16698     NM_ADDIUGP_W = 0x00,
16699     NM_LWGP      = 0x02,
16700     NM_SWGP      = 0x03,
16701 };
16702
16703 /* P48I instruction pool */
16704 enum {
16705     NM_LI48        = 0x00,
16706     NM_ADDIU48     = 0x01,
16707     NM_ADDIUGP48   = 0x02,
16708     NM_ADDIUPC48   = 0x03,
16709     NM_LWPC48      = 0x0b,
16710     NM_SWPC48      = 0x0f,
16711 };
16712
16713 /* P.U12 instruction pool */
16714 enum {
16715     NM_ORI      = 0x00,
16716     NM_XORI     = 0x01,
16717     NM_ANDI     = 0x02,
16718     NM_P_SR     = 0x03,
16719     NM_SLTI     = 0x04,
16720     NM_SLTIU    = 0x05,
16721     NM_SEQI     = 0x06,
16722     NM_ADDIUNEG = 0x08,
16723     NM_P_SHIFT  = 0x0c,
16724     NM_P_ROTX   = 0x0d,
16725     NM_P_INS    = 0x0e,
16726     NM_P_EXT    = 0x0f,
16727 };
16728
16729 /* POOL32F instruction pool */
16730 enum {
16731     NM_POOL32F_0   = 0x00,
16732     NM_POOL32F_3   = 0x03,
16733     NM_POOL32F_5   = 0x05,
16734 };
16735
16736 /* POOL32S instruction pool */
16737 enum {
16738     NM_POOL32S_0   = 0x00,
16739     NM_POOL32S_4   = 0x04,
16740 };
16741
16742 /* P.LUI instruction pool */
16743 enum {
16744     NM_LUI      = 0x00,
16745     NM_ALUIPC   = 0x01,
16746 };
16747
16748 /* P.GP.BH instruction pool */
16749 enum {
16750     NM_LBGP      = 0x00,
16751     NM_SBGP      = 0x01,
16752     NM_LBUGP     = 0x02,
16753     NM_ADDIUGP_B = 0x03,
16754     NM_P_GP_LH   = 0x04,
16755     NM_P_GP_SH   = 0x05,
16756     NM_P_GP_CP1  = 0x06,
16757 };
16758
16759 /* P.LS.U12 instruction pool */
16760 enum {
16761     NM_LB        = 0x00,
16762     NM_SB        = 0x01,
16763     NM_LBU       = 0x02,
16764     NM_P_PREFU12 = 0x03,
16765     NM_LH        = 0x04,
16766     NM_SH        = 0x05,
16767     NM_LHU       = 0x06,
16768     NM_LWU       = 0x07,
16769     NM_LW        = 0x08,
16770     NM_SW        = 0x09,
16771     NM_LWC1      = 0x0a,
16772     NM_SWC1      = 0x0b,
16773     NM_LDC1      = 0x0e,
16774     NM_SDC1      = 0x0f,
16775 };
16776
16777 /* P.LS.S9 instruction pool */
16778 enum {
16779     NM_P_LS_S0         = 0x00,
16780     NM_P_LS_S1         = 0x01,
16781     NM_P_LS_E0         = 0x02,
16782     NM_P_LS_WM         = 0x04,
16783     NM_P_LS_UAWM       = 0x05,
16784 };
16785
16786 /* P.BAL instruction pool */
16787 enum {
16788     NM_BC       = 0x00,
16789     NM_BALC     = 0x01,
16790 };
16791
16792 /* P.J instruction pool */
16793 enum {
16794     NM_JALRC    = 0x00,
16795     NM_JALRC_HB = 0x01,
16796     NM_P_BALRSC = 0x08,
16797 };
16798
16799 /* P.BR1 instruction pool */
16800 enum {
16801     NM_BEQC     = 0x00,
16802     NM_P_BR3A   = 0x01,
16803     NM_BGEC     = 0x02,
16804     NM_BGEUC    = 0x03,
16805 };
16806
16807 /* P.BR2 instruction pool */
16808 enum {
16809     NM_BNEC     = 0x00,
16810     NM_BLTC     = 0x02,
16811     NM_BLTUC    = 0x03,
16812 };
16813
16814 /* P.BRI instruction pool */
16815 enum {
16816     NM_BEQIC    = 0x00,
16817     NM_BBEQZC   = 0x01,
16818     NM_BGEIC    = 0x02,
16819     NM_BGEIUC   = 0x03,
16820     NM_BNEIC    = 0x04,
16821     NM_BBNEZC   = 0x05,
16822     NM_BLTIC    = 0x06,
16823     NM_BLTIUC   = 0x07,
16824 };
16825
16826 /* P16.SHIFT instruction pool */
16827 enum {
16828     NM_SLL16    = 0x00,
16829     NM_SRL16    = 0x01,
16830 };
16831
16832 /* POOL16C instruction pool */
16833 enum {
16834     NM_POOL16C_0  = 0x00,
16835     NM_LWXS16     = 0x01,
16836 };
16837
16838 /* P16.A1 instruction pool */
16839 enum {
16840     NM_ADDIUR1SP = 0x01,
16841 };
16842
16843 /* P16.A2 instruction pool */
16844 enum {
16845     NM_ADDIUR2  = 0x00,
16846     NM_P_ADDIURS5  = 0x01,
16847 };
16848
16849 /* P16.ADDU instruction pool */
16850 enum {
16851     NM_ADDU16     = 0x00,
16852     NM_SUBU16     = 0x01,
16853 };
16854
16855 /* P16.SR instruction pool */
16856 enum {
16857     NM_SAVE16        = 0x00,
16858     NM_RESTORE_JRC16 = 0x01,
16859 };
16860
16861 /* P16.4X4 instruction pool */
16862 enum {
16863     NM_ADDU4X4      = 0x00,
16864     NM_MUL4X4       = 0x01,
16865 };
16866
16867 /* P16.LB instruction pool */
16868 enum {
16869     NM_LB16       = 0x00,
16870     NM_SB16       = 0x01,
16871     NM_LBU16      = 0x02,
16872 };
16873
16874 /* P16.LH  instruction pool */
16875 enum {
16876     NM_LH16     = 0x00,
16877     NM_SH16     = 0x01,
16878     NM_LHU16    = 0x02,
16879 };
16880
16881 /* P.RI instruction pool */
16882 enum {
16883     NM_SIGRIE       = 0x00,
16884     NM_P_SYSCALL    = 0x01,
16885     NM_BREAK        = 0x02,
16886     NM_SDBBP        = 0x03,
16887 };
16888
16889 /* POOL32A0 instruction pool */
16890 enum {
16891     NM_P_TRAP   = 0x00,
16892     NM_SEB      = 0x01,
16893     NM_SLLV     = 0x02,
16894     NM_MUL      = 0x03,
16895     NM_MFC0     = 0x06,
16896     NM_MFHC0    = 0x07,
16897     NM_SEH      = 0x09,
16898     NM_SRLV     = 0x0a,
16899     NM_MUH      = 0x0b,
16900     NM_MTC0     = 0x0e,
16901     NM_MTHC0    = 0x0f,
16902     NM_SRAV     = 0x12,
16903     NM_MULU     = 0x13,
16904     NM_ROTRV    = 0x1a,
16905     NM_MUHU     = 0x1b,
16906     NM_ADD      = 0x22,
16907     NM_DIV      = 0x23,
16908     NM_ADDU     = 0x2a,
16909     NM_MOD      = 0x2b,
16910     NM_SUB      = 0x32,
16911     NM_DIVU     = 0x33,
16912     NM_RDHWR    = 0x38,
16913     NM_SUBU     = 0x3a,
16914     NM_MODU     = 0x3b,
16915     NM_P_CMOVE  = 0x42,
16916     NM_FORK     = 0x45,
16917     NM_MFTR     = 0x46,
16918     NM_MFHTR    = 0x47,
16919     NM_AND      = 0x4a,
16920     NM_YIELD    = 0x4d,
16921     NM_MTTR     = 0x4e,
16922     NM_MTHTR    = 0x4f,
16923     NM_OR       = 0x52,
16924     NM_D_E_MT_VPE = 0x56,
16925     NM_NOR      = 0x5a,
16926     NM_XOR      = 0x62,
16927     NM_SLT      = 0x6a,
16928     NM_P_SLTU   = 0x72,
16929     NM_SOV      = 0x7a,
16930 };
16931
16932 /* POOL32A5 instruction pool */
16933 enum {
16934     NM_CMP_EQ_PH        = 0x00,
16935     NM_CMP_LT_PH        = 0x08,
16936     NM_CMP_LE_PH        = 0x10,
16937     NM_CMPGU_EQ_QB      = 0x18,
16938     NM_CMPGU_LT_QB      = 0x20,
16939     NM_CMPGU_LE_QB      = 0x28,
16940     NM_CMPGDU_EQ_QB     = 0x30,
16941     NM_CMPGDU_LT_QB     = 0x38,
16942     NM_CMPGDU_LE_QB     = 0x40,
16943     NM_CMPU_EQ_QB       = 0x48,
16944     NM_CMPU_LT_QB       = 0x50,
16945     NM_CMPU_LE_QB       = 0x58,
16946     NM_ADDQ_S_W         = 0x60,
16947     NM_SUBQ_S_W         = 0x68,
16948     NM_ADDSC            = 0x70,
16949     NM_ADDWC            = 0x78,
16950
16951     NM_ADDQ_S_PH   = 0x01,
16952     NM_ADDQH_R_PH  = 0x09,
16953     NM_ADDQH_R_W   = 0x11,
16954     NM_ADDU_S_QB   = 0x19,
16955     NM_ADDU_S_PH   = 0x21,
16956     NM_ADDUH_R_QB  = 0x29,
16957     NM_SHRAV_R_PH  = 0x31,
16958     NM_SHRAV_R_QB  = 0x39,
16959     NM_SUBQ_S_PH   = 0x41,
16960     NM_SUBQH_R_PH  = 0x49,
16961     NM_SUBQH_R_W   = 0x51,
16962     NM_SUBU_S_QB   = 0x59,
16963     NM_SUBU_S_PH   = 0x61,
16964     NM_SUBUH_R_QB  = 0x69,
16965     NM_SHLLV_S_PH  = 0x71,
16966     NM_PRECR_SRA_R_PH_W = 0x79,
16967
16968     NM_MULEU_S_PH_QBL   = 0x12,
16969     NM_MULEU_S_PH_QBR   = 0x1a,
16970     NM_MULQ_RS_PH       = 0x22,
16971     NM_MULQ_S_PH        = 0x2a,
16972     NM_MULQ_RS_W        = 0x32,
16973     NM_MULQ_S_W         = 0x3a,
16974     NM_APPEND           = 0x42,
16975     NM_MODSUB           = 0x52,
16976     NM_SHRAV_R_W        = 0x5a,
16977     NM_SHRLV_PH         = 0x62,
16978     NM_SHRLV_QB         = 0x6a,
16979     NM_SHLLV_QB         = 0x72,
16980     NM_SHLLV_S_W        = 0x7a,
16981
16982     NM_SHILO            = 0x03,
16983
16984     NM_MULEQ_S_W_PHL    = 0x04,
16985     NM_MULEQ_S_W_PHR    = 0x0c,
16986
16987     NM_MUL_S_PH         = 0x05,
16988     NM_PRECR_QB_PH      = 0x0d,
16989     NM_PRECRQ_QB_PH     = 0x15,
16990     NM_PRECRQ_PH_W      = 0x1d,
16991     NM_PRECRQ_RS_PH_W   = 0x25,
16992     NM_PRECRQU_S_QB_PH  = 0x2d,
16993     NM_PACKRL_PH        = 0x35,
16994     NM_PICK_QB          = 0x3d,
16995     NM_PICK_PH          = 0x45,
16996
16997     NM_SHRA_R_W         = 0x5e,
16998     NM_SHRA_R_PH        = 0x66,
16999     NM_SHLL_S_PH        = 0x76,
17000     NM_SHLL_S_W         = 0x7e,
17001
17002     NM_REPL_PH          = 0x07
17003 };
17004
17005 /* POOL32A7 instruction pool */
17006 enum {
17007     NM_P_LSX        = 0x00,
17008     NM_LSA          = 0x01,
17009     NM_EXTW         = 0x03,
17010     NM_POOL32AXF    = 0x07,
17011 };
17012
17013 /* P.SR instruction pool */
17014 enum {
17015     NM_PP_SR           = 0x00,
17016     NM_P_SR_F          = 0x01,
17017 };
17018
17019 /* P.SHIFT instruction pool */
17020 enum {
17021     NM_P_SLL        = 0x00,
17022     NM_SRL          = 0x02,
17023     NM_SRA          = 0x04,
17024     NM_ROTR         = 0x06,
17025 };
17026
17027 /* P.ROTX instruction pool */
17028 enum {
17029     NM_ROTX         = 0x00,
17030 };
17031
17032 /* P.INS instruction pool */
17033 enum {
17034     NM_INS          = 0x00,
17035 };
17036
17037 /* P.EXT instruction pool */
17038 enum {
17039     NM_EXT          = 0x00,
17040 };
17041
17042 /* POOL32F_0 (fmt) instruction pool */
17043 enum {
17044     NM_RINT_S              = 0x04,
17045     NM_RINT_D              = 0x44,
17046     NM_ADD_S               = 0x06,
17047     NM_SELEQZ_S            = 0x07,
17048     NM_SELEQZ_D            = 0x47,
17049     NM_CLASS_S             = 0x0c,
17050     NM_CLASS_D             = 0x4c,
17051     NM_SUB_S               = 0x0e,
17052     NM_SELNEZ_S            = 0x0f,
17053     NM_SELNEZ_D            = 0x4f,
17054     NM_MUL_S               = 0x16,
17055     NM_SEL_S               = 0x17,
17056     NM_SEL_D               = 0x57,
17057     NM_DIV_S               = 0x1e,
17058     NM_ADD_D               = 0x26,
17059     NM_SUB_D               = 0x2e,
17060     NM_MUL_D               = 0x36,
17061     NM_MADDF_S             = 0x37,
17062     NM_MADDF_D             = 0x77,
17063     NM_DIV_D               = 0x3e,
17064     NM_MSUBF_S             = 0x3f,
17065     NM_MSUBF_D             = 0x7f,
17066 };
17067
17068 /* POOL32F_3  instruction pool */
17069 enum {
17070     NM_MIN_FMT         = 0x00,
17071     NM_MAX_FMT         = 0x01,
17072     NM_MINA_FMT        = 0x04,
17073     NM_MAXA_FMT        = 0x05,
17074     NM_POOL32FXF       = 0x07,
17075 };
17076
17077 /* POOL32F_5  instruction pool */
17078 enum {
17079     NM_CMP_CONDN_S     = 0x00,
17080     NM_CMP_CONDN_D     = 0x02,
17081 };
17082
17083 /* P.GP.LH instruction pool */
17084 enum {
17085     NM_LHGP    = 0x00,
17086     NM_LHUGP   = 0x01,
17087 };
17088
17089 /* P.GP.SH instruction pool */
17090 enum {
17091     NM_SHGP    = 0x00,
17092 };
17093
17094 /* P.GP.CP1 instruction pool */
17095 enum {
17096     NM_LWC1GP       = 0x00,
17097     NM_SWC1GP       = 0x01,
17098     NM_LDC1GP       = 0x02,
17099     NM_SDC1GP       = 0x03,
17100 };
17101
17102 /* P.LS.S0 instruction pool */
17103 enum {
17104     NM_LBS9     = 0x00,
17105     NM_LHS9     = 0x04,
17106     NM_LWS9     = 0x08,
17107     NM_LDS9     = 0x0c,
17108
17109     NM_SBS9     = 0x01,
17110     NM_SHS9     = 0x05,
17111     NM_SWS9     = 0x09,
17112     NM_SDS9     = 0x0d,
17113
17114     NM_LBUS9    = 0x02,
17115     NM_LHUS9    = 0x06,
17116     NM_LWC1S9   = 0x0a,
17117     NM_LDC1S9   = 0x0e,
17118
17119     NM_P_PREFS9 = 0x03,
17120     NM_LWUS9    = 0x07,
17121     NM_SWC1S9   = 0x0b,
17122     NM_SDC1S9   = 0x0f,
17123 };
17124
17125 /* P.LS.S1 instruction pool */
17126 enum {
17127     NM_ASET_ACLR = 0x02,
17128     NM_UALH      = 0x04,
17129     NM_UASH      = 0x05,
17130     NM_CACHE     = 0x07,
17131     NM_P_LL      = 0x0a,
17132     NM_P_SC      = 0x0b,
17133 };
17134
17135 /* P.LS.E0 instruction pool */
17136 enum {
17137     NM_LBE      = 0x00,
17138     NM_SBE      = 0x01,
17139     NM_LBUE     = 0x02,
17140     NM_P_PREFE  = 0x03,
17141     NM_LHE      = 0x04,
17142     NM_SHE      = 0x05,
17143     NM_LHUE     = 0x06,
17144     NM_CACHEE   = 0x07,
17145     NM_LWE      = 0x08,
17146     NM_SWE      = 0x09,
17147     NM_P_LLE    = 0x0a,
17148     NM_P_SCE    = 0x0b,
17149 };
17150
17151 /* P.PREFE instruction pool */
17152 enum {
17153     NM_SYNCIE   = 0x00,
17154     NM_PREFE    = 0x01,
17155 };
17156
17157 /* P.LLE instruction pool */
17158 enum {
17159     NM_LLE      = 0x00,
17160     NM_LLWPE    = 0x01,
17161 };
17162
17163 /* P.SCE instruction pool */
17164 enum {
17165     NM_SCE      = 0x00,
17166     NM_SCWPE    = 0x01,
17167 };
17168
17169 /* P.LS.WM instruction pool */
17170 enum {
17171     NM_LWM       = 0x00,
17172     NM_SWM       = 0x01,
17173 };
17174
17175 /* P.LS.UAWM instruction pool */
17176 enum {
17177     NM_UALWM       = 0x00,
17178     NM_UASWM       = 0x01,
17179 };
17180
17181 /* P.BR3A instruction pool */
17182 enum {
17183     NM_BC1EQZC          = 0x00,
17184     NM_BC1NEZC          = 0x01,
17185     NM_BC2EQZC          = 0x02,
17186     NM_BC2NEZC          = 0x03,
17187     NM_BPOSGE32C        = 0x04,
17188 };
17189
17190 /* P16.RI instruction pool */
17191 enum {
17192     NM_P16_SYSCALL  = 0x01,
17193     NM_BREAK16      = 0x02,
17194     NM_SDBBP16      = 0x03,
17195 };
17196
17197 /* POOL16C_0 instruction pool */
17198 enum {
17199     NM_POOL16C_00      = 0x00,
17200 };
17201
17202 /* P16.JRC instruction pool */
17203 enum {
17204     NM_JRC          = 0x00,
17205     NM_JALRC16      = 0x01,
17206 };
17207
17208 /* P.SYSCALL instruction pool */
17209 enum {
17210     NM_SYSCALL      = 0x00,
17211     NM_HYPCALL      = 0x01,
17212 };
17213
17214 /* P.TRAP instruction pool */
17215 enum {
17216     NM_TEQ          = 0x00,
17217     NM_TNE          = 0x01,
17218 };
17219
17220 /* P.CMOVE instruction pool */
17221 enum {
17222     NM_MOVZ            = 0x00,
17223     NM_MOVN            = 0x01,
17224 };
17225
17226 /* POOL32Axf instruction pool */
17227 enum {
17228     NM_POOL32AXF_1 = 0x01,
17229     NM_POOL32AXF_2 = 0x02,
17230     NM_POOL32AXF_4 = 0x04,
17231     NM_POOL32AXF_5 = 0x05,
17232     NM_POOL32AXF_7 = 0x07,
17233 };
17234
17235 /* POOL32Axf_1 instruction pool */
17236 enum {
17237     NM_POOL32AXF_1_0 = 0x00,
17238     NM_POOL32AXF_1_1 = 0x01,
17239     NM_POOL32AXF_1_3 = 0x03,
17240     NM_POOL32AXF_1_4 = 0x04,
17241     NM_POOL32AXF_1_5 = 0x05,
17242     NM_POOL32AXF_1_7 = 0x07,
17243 };
17244
17245 /* POOL32Axf_2 instruction pool */
17246 enum {
17247     NM_POOL32AXF_2_0_7     = 0x00,
17248     NM_POOL32AXF_2_8_15    = 0x01,
17249     NM_POOL32AXF_2_16_23   = 0x02,
17250     NM_POOL32AXF_2_24_31   = 0x03,
17251 };
17252
17253 /* POOL32Axf_7 instruction pool */
17254 enum {
17255     NM_SHRA_R_QB    = 0x0,
17256     NM_SHRL_PH      = 0x1,
17257     NM_REPL_QB      = 0x2,
17258 };
17259
17260 /* POOL32Axf_1_0 instruction pool */
17261 enum {
17262     NM_MFHI = 0x0,
17263     NM_MFLO = 0x1,
17264     NM_MTHI = 0x2,
17265     NM_MTLO = 0x3,
17266 };
17267
17268 /* POOL32Axf_1_1 instruction pool */
17269 enum {
17270     NM_MTHLIP = 0x0,
17271     NM_SHILOV = 0x1,
17272 };
17273
17274 /* POOL32Axf_1_3 instruction pool */
17275 enum {
17276     NM_RDDSP    = 0x0,
17277     NM_WRDSP    = 0x1,
17278     NM_EXTP     = 0x2,
17279     NM_EXTPDP   = 0x3,
17280 };
17281
17282 /* POOL32Axf_1_4 instruction pool */
17283 enum {
17284     NM_SHLL_QB  = 0x0,
17285     NM_SHRL_QB  = 0x1,
17286 };
17287
17288 /* POOL32Axf_1_5 instruction pool */
17289 enum {
17290     NM_MAQ_S_W_PHR   = 0x0,
17291     NM_MAQ_S_W_PHL   = 0x1,
17292     NM_MAQ_SA_W_PHR  = 0x2,
17293     NM_MAQ_SA_W_PHL  = 0x3,
17294 };
17295
17296 /* POOL32Axf_1_7 instruction pool */
17297 enum {
17298     NM_EXTR_W       = 0x0,
17299     NM_EXTR_R_W     = 0x1,
17300     NM_EXTR_RS_W    = 0x2,
17301     NM_EXTR_S_H     = 0x3,
17302 };
17303
17304 /* POOL32Axf_2_0_7 instruction pool */
17305 enum {
17306     NM_DPA_W_PH     = 0x0,
17307     NM_DPAQ_S_W_PH  = 0x1,
17308     NM_DPS_W_PH     = 0x2,
17309     NM_DPSQ_S_W_PH  = 0x3,
17310     NM_BALIGN       = 0x4,
17311     NM_MADD         = 0x5,
17312     NM_MULT         = 0x6,
17313     NM_EXTRV_W      = 0x7,
17314 };
17315
17316 /* POOL32Axf_2_8_15 instruction pool */
17317 enum {
17318     NM_DPAX_W_PH    = 0x0,
17319     NM_DPAQ_SA_L_W  = 0x1,
17320     NM_DPSX_W_PH    = 0x2,
17321     NM_DPSQ_SA_L_W  = 0x3,
17322     NM_MADDU        = 0x5,
17323     NM_MULTU        = 0x6,
17324     NM_EXTRV_R_W    = 0x7,
17325 };
17326
17327 /* POOL32Axf_2_16_23 instruction pool */
17328 enum {
17329     NM_DPAU_H_QBL       = 0x0,
17330     NM_DPAQX_S_W_PH     = 0x1,
17331     NM_DPSU_H_QBL       = 0x2,
17332     NM_DPSQX_S_W_PH     = 0x3,
17333     NM_EXTPV            = 0x4,
17334     NM_MSUB             = 0x5,
17335     NM_MULSA_W_PH       = 0x6,
17336     NM_EXTRV_RS_W       = 0x7,
17337 };
17338
17339 /* POOL32Axf_2_24_31 instruction pool */
17340 enum {
17341     NM_DPAU_H_QBR       = 0x0,
17342     NM_DPAQX_SA_W_PH    = 0x1,
17343     NM_DPSU_H_QBR       = 0x2,
17344     NM_DPSQX_SA_W_PH    = 0x3,
17345     NM_EXTPDPV          = 0x4,
17346     NM_MSUBU            = 0x5,
17347     NM_MULSAQ_S_W_PH    = 0x6,
17348     NM_EXTRV_S_H        = 0x7,
17349 };
17350
17351 /* POOL32Axf_{4, 5} instruction pool */
17352 enum {
17353     NM_CLO      = 0x25,
17354     NM_CLZ      = 0x2d,
17355
17356     NM_TLBP     = 0x01,
17357     NM_TLBR     = 0x09,
17358     NM_TLBWI    = 0x11,
17359     NM_TLBWR    = 0x19,
17360     NM_TLBINV   = 0x03,
17361     NM_TLBINVF  = 0x0b,
17362     NM_DI       = 0x23,
17363     NM_EI       = 0x2b,
17364     NM_RDPGPR   = 0x70,
17365     NM_WRPGPR   = 0x78,
17366     NM_WAIT     = 0x61,
17367     NM_DERET    = 0x71,
17368     NM_ERETX    = 0x79,
17369
17370     /* nanoMIPS DSP instructions */
17371     NM_ABSQ_S_QB        = 0x00,
17372     NM_ABSQ_S_PH        = 0x08,
17373     NM_ABSQ_S_W         = 0x10,
17374     NM_PRECEQ_W_PHL     = 0x28,
17375     NM_PRECEQ_W_PHR     = 0x30,
17376     NM_PRECEQU_PH_QBL   = 0x38,
17377     NM_PRECEQU_PH_QBR   = 0x48,
17378     NM_PRECEU_PH_QBL    = 0x58,
17379     NM_PRECEU_PH_QBR    = 0x68,
17380     NM_PRECEQU_PH_QBLA  = 0x39,
17381     NM_PRECEQU_PH_QBRA  = 0x49,
17382     NM_PRECEU_PH_QBLA   = 0x59,
17383     NM_PRECEU_PH_QBRA   = 0x69,
17384     NM_REPLV_PH         = 0x01,
17385     NM_REPLV_QB         = 0x09,
17386     NM_BITREV           = 0x18,
17387     NM_INSV             = 0x20,
17388     NM_RADDU_W_QB       = 0x78,
17389
17390     NM_BITSWAP          = 0x05,
17391     NM_WSBH             = 0x3d,
17392 };
17393
17394 /* PP.SR instruction pool */
17395 enum {
17396     NM_SAVE         = 0x00,
17397     NM_RESTORE      = 0x02,
17398     NM_RESTORE_JRC  = 0x03,
17399 };
17400
17401 /* P.SR.F instruction pool */
17402 enum {
17403     NM_SAVEF        = 0x00,
17404     NM_RESTOREF     = 0x01,
17405 };
17406
17407 /* P16.SYSCALL  instruction pool */
17408 enum {
17409     NM_SYSCALL16     = 0x00,
17410     NM_HYPCALL16     = 0x01,
17411 };
17412
17413 /* POOL16C_00 instruction pool */
17414 enum {
17415     NM_NOT16           = 0x00,
17416     NM_XOR16           = 0x01,
17417     NM_AND16           = 0x02,
17418     NM_OR16            = 0x03,
17419 };
17420
17421 /* PP.LSX and PP.LSXS instruction pool */
17422 enum {
17423     NM_LBX      = 0x00,
17424     NM_LHX      = 0x04,
17425     NM_LWX      = 0x08,
17426     NM_LDX      = 0x0c,
17427
17428     NM_SBX      = 0x01,
17429     NM_SHX      = 0x05,
17430     NM_SWX      = 0x09,
17431     NM_SDX      = 0x0d,
17432
17433     NM_LBUX     = 0x02,
17434     NM_LHUX     = 0x06,
17435     NM_LWC1X    = 0x0a,
17436     NM_LDC1X    = 0x0e,
17437
17438     NM_LWUX     = 0x07,
17439     NM_SWC1X    = 0x0b,
17440     NM_SDC1X    = 0x0f,
17441
17442     NM_LHXS     = 0x04,
17443     NM_LWXS     = 0x08,
17444     NM_LDXS     = 0x0c,
17445
17446     NM_SHXS     = 0x05,
17447     NM_SWXS     = 0x09,
17448     NM_SDXS     = 0x0d,
17449
17450     NM_LHUXS    = 0x06,
17451     NM_LWC1XS   = 0x0a,
17452     NM_LDC1XS   = 0x0e,
17453
17454     NM_LWUXS    = 0x07,
17455     NM_SWC1XS   = 0x0b,
17456     NM_SDC1XS   = 0x0f,
17457 };
17458
17459 /* ERETx instruction pool */
17460 enum {
17461     NM_ERET     = 0x00,
17462     NM_ERETNC   = 0x01,
17463 };
17464
17465 /* POOL32FxF_{0, 1} insturction pool */
17466 enum {
17467     NM_CFC1     = 0x40,
17468     NM_CTC1     = 0x60,
17469     NM_MFC1     = 0x80,
17470     NM_MTC1     = 0xa0,
17471     NM_MFHC1    = 0xc0,
17472     NM_MTHC1    = 0xe0,
17473
17474     NM_CVT_S_PL = 0x84,
17475     NM_CVT_S_PU = 0xa4,
17476
17477     NM_CVT_L_S     = 0x004,
17478     NM_CVT_L_D     = 0x104,
17479     NM_CVT_W_S     = 0x024,
17480     NM_CVT_W_D     = 0x124,
17481
17482     NM_RSQRT_S     = 0x008,
17483     NM_RSQRT_D     = 0x108,
17484
17485     NM_SQRT_S      = 0x028,
17486     NM_SQRT_D      = 0x128,
17487
17488     NM_RECIP_S     = 0x048,
17489     NM_RECIP_D     = 0x148,
17490
17491     NM_FLOOR_L_S   = 0x00c,
17492     NM_FLOOR_L_D   = 0x10c,
17493
17494     NM_FLOOR_W_S   = 0x02c,
17495     NM_FLOOR_W_D   = 0x12c,
17496
17497     NM_CEIL_L_S    = 0x04c,
17498     NM_CEIL_L_D    = 0x14c,
17499     NM_CEIL_W_S    = 0x06c,
17500     NM_CEIL_W_D    = 0x16c,
17501     NM_TRUNC_L_S   = 0x08c,
17502     NM_TRUNC_L_D   = 0x18c,
17503     NM_TRUNC_W_S   = 0x0ac,
17504     NM_TRUNC_W_D   = 0x1ac,
17505     NM_ROUND_L_S   = 0x0cc,
17506     NM_ROUND_L_D   = 0x1cc,
17507     NM_ROUND_W_S   = 0x0ec,
17508     NM_ROUND_W_D   = 0x1ec,
17509
17510     NM_MOV_S       = 0x01,
17511     NM_MOV_D       = 0x81,
17512     NM_ABS_S       = 0x0d,
17513     NM_ABS_D       = 0x8d,
17514     NM_NEG_S       = 0x2d,
17515     NM_NEG_D       = 0xad,
17516     NM_CVT_D_S     = 0x04d,
17517     NM_CVT_D_W     = 0x0cd,
17518     NM_CVT_D_L     = 0x14d,
17519     NM_CVT_S_D     = 0x06d,
17520     NM_CVT_S_W     = 0x0ed,
17521     NM_CVT_S_L     = 0x16d,
17522 };
17523
17524 /* P.LL instruction pool */
17525 enum {
17526     NM_LL       = 0x00,
17527     NM_LLWP     = 0x01,
17528 };
17529
17530 /* P.SC instruction pool */
17531 enum {
17532     NM_SC       = 0x00,
17533     NM_SCWP     = 0x01,
17534 };
17535
17536 /* P.DVP instruction pool */
17537 enum {
17538     NM_DVP      = 0x00,
17539     NM_EVP      = 0x01,
17540 };
17541
17542
17543 /*
17544  *
17545  * nanoMIPS decoding engine
17546  *
17547  */
17548
17549
17550 /* extraction utilities */
17551
17552 #define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
17553 #define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
17554 #define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
17555 #define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
17556 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
17557 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
17558
17559 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
17560 static inline int decode_gpr_gpr3(int r)
17561 {
17562     static const int map[] = { 16, 17, 18, 19,  4,  5,  6,  7 };
17563
17564     return map[r & 0x7];
17565 }
17566
17567 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
17568 static inline int decode_gpr_gpr3_src_store(int r)
17569 {
17570     static const int map[] = {  0, 17, 18, 19,  4,  5,  6,  7 };
17571
17572     return map[r & 0x7];
17573 }
17574
17575 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
17576 static inline int decode_gpr_gpr4(int r)
17577 {
17578     static const int map[] = {  8,  9, 10, 11,  4,  5,  6,  7,
17579                                16, 17, 18, 19, 20, 21, 22, 23 };
17580
17581     return map[r & 0xf];
17582 }
17583
17584 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
17585 static inline int decode_gpr_gpr4_zero(int r)
17586 {
17587     static const int map[] = {  8,  9, 10,  0,  4,  5,  6,  7,
17588                                16, 17, 18, 19, 20, 21, 22, 23 };
17589
17590     return map[r & 0xf];
17591 }
17592
17593
17594 /* extraction utilities */
17595
17596 #define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
17597 #define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
17598 #define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
17599 #define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
17600 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
17601 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
17602
17603
17604 static void gen_adjust_sp(DisasContext *ctx, int u)
17605 {
17606     gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u);
17607 }
17608
17609 static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count,
17610                      uint8_t gp, uint16_t u)
17611 {
17612     int counter = 0;
17613     TCGv va = tcg_temp_new();
17614     TCGv t0 = tcg_temp_new();
17615
17616     while (counter != count) {
17617         bool use_gp = gp && (counter == count - 1);
17618         int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
17619         int this_offset = -((counter + 1) << 2);
17620         gen_base_offset_addr(ctx, va, 29, this_offset);
17621         gen_load_gpr(t0, this_rt);
17622         tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx,
17623                            (MO_TEUL | ctx->default_tcg_memop_mask));
17624         counter++;
17625     }
17626
17627     /* adjust stack pointer */
17628     gen_adjust_sp(ctx, -u);
17629
17630     tcg_temp_free(t0);
17631     tcg_temp_free(va);
17632 }
17633
17634 static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count,
17635                         uint8_t gp, uint16_t u)
17636 {
17637     int counter = 0;
17638     TCGv va = tcg_temp_new();
17639     TCGv t0 = tcg_temp_new();
17640
17641     while (counter != count) {
17642         bool use_gp = gp && (counter == count - 1);
17643         int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
17644         int this_offset = u - ((counter + 1) << 2);
17645         gen_base_offset_addr(ctx, va, 29, this_offset);
17646         tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL |
17647                         ctx->default_tcg_memop_mask);
17648         tcg_gen_ext32s_tl(t0, t0);
17649         gen_store_gpr(t0, this_rt);
17650         counter++;
17651     }
17652
17653     /* adjust stack pointer */
17654     gen_adjust_sp(ctx, u);
17655
17656     tcg_temp_free(t0);
17657     tcg_temp_free(va);
17658 }
17659
17660 static void gen_pool16c_nanomips_insn(DisasContext *ctx)
17661 {
17662     int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
17663     int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
17664
17665     switch (extract32(ctx->opcode, 2, 2)) {
17666     case NM_NOT16:
17667         gen_logic(ctx, OPC_NOR, rt, rs, 0);
17668         break;
17669     case NM_AND16:
17670         gen_logic(ctx, OPC_AND, rt, rt, rs);
17671         break;
17672     case NM_XOR16:
17673         gen_logic(ctx, OPC_XOR, rt, rt, rs);
17674         break;
17675     case NM_OR16:
17676         gen_logic(ctx, OPC_OR, rt, rt, rs);
17677         break;
17678     }
17679 }
17680
17681 static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
17682 {
17683     int rt = extract32(ctx->opcode, 21, 5);
17684     int rs = extract32(ctx->opcode, 16, 5);
17685     int rd = extract32(ctx->opcode, 11, 5);
17686
17687     switch (extract32(ctx->opcode, 3, 7)) {
17688     case NM_P_TRAP:
17689         switch (extract32(ctx->opcode, 10, 1)) {
17690         case NM_TEQ:
17691             check_nms(ctx);
17692             gen_trap(ctx, OPC_TEQ, rs, rt, -1);
17693             break;
17694         case NM_TNE:
17695             check_nms(ctx);
17696             gen_trap(ctx, OPC_TNE, rs, rt, -1);
17697             break;
17698         }
17699         break;
17700     case NM_RDHWR:
17701         check_nms(ctx);
17702         gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
17703         break;
17704     case NM_SEB:
17705         check_nms(ctx);
17706         gen_bshfl(ctx, OPC_SEB, rs, rt);
17707         break;
17708     case NM_SEH:
17709         gen_bshfl(ctx, OPC_SEH, rs, rt);
17710         break;
17711     case NM_SLLV:
17712         gen_shift(ctx, OPC_SLLV, rd, rt, rs);
17713         break;
17714     case NM_SRLV:
17715         gen_shift(ctx, OPC_SRLV, rd, rt, rs);
17716         break;
17717     case NM_SRAV:
17718         gen_shift(ctx, OPC_SRAV, rd, rt, rs);
17719         break;
17720     case NM_ROTRV:
17721         gen_shift(ctx, OPC_ROTRV, rd, rt, rs);
17722         break;
17723     case NM_ADD:
17724         gen_arith(ctx, OPC_ADD, rd, rs, rt);
17725         break;
17726     case NM_ADDU:
17727         gen_arith(ctx, OPC_ADDU, rd, rs, rt);
17728         break;
17729     case NM_SUB:
17730         check_nms(ctx);
17731         gen_arith(ctx, OPC_SUB, rd, rs, rt);
17732         break;
17733     case NM_SUBU:
17734         gen_arith(ctx, OPC_SUBU, rd, rs, rt);
17735         break;
17736     case NM_P_CMOVE:
17737         switch (extract32(ctx->opcode, 10, 1)) {
17738         case NM_MOVZ:
17739             gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
17740             break;
17741         case NM_MOVN:
17742             gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
17743             break;
17744         }
17745         break;
17746     case NM_AND:
17747         gen_logic(ctx, OPC_AND, rd, rs, rt);
17748         break;
17749     case NM_OR:
17750         gen_logic(ctx, OPC_OR, rd, rs, rt);
17751         break;
17752     case NM_NOR:
17753         gen_logic(ctx, OPC_NOR, rd, rs, rt);
17754         break;
17755     case NM_XOR:
17756         gen_logic(ctx, OPC_XOR, rd, rs, rt);
17757         break;
17758     case NM_SLT:
17759         gen_slt(ctx, OPC_SLT, rd, rs, rt);
17760         break;
17761     case NM_P_SLTU:
17762         if (rd == 0) {
17763             /* P_DVP */
17764 #ifndef CONFIG_USER_ONLY
17765             TCGv t0 = tcg_temp_new();
17766             switch (extract32(ctx->opcode, 10, 1)) {
17767             case NM_DVP:
17768                 if (ctx->vp) {
17769                     check_cp0_enabled(ctx);
17770                     gen_helper_dvp(t0, cpu_env);
17771                     gen_store_gpr(t0, rt);
17772                 }
17773                 break;
17774             case NM_EVP:
17775                 if (ctx->vp) {
17776                     check_cp0_enabled(ctx);
17777                     gen_helper_evp(t0, cpu_env);
17778                     gen_store_gpr(t0, rt);
17779                 }
17780                 break;
17781             }
17782             tcg_temp_free(t0);
17783 #endif
17784         } else {
17785             gen_slt(ctx, OPC_SLTU, rd, rs, rt);
17786         }
17787         break;
17788     case NM_SOV:
17789         {
17790             TCGv t0 = tcg_temp_new();
17791             TCGv t1 = tcg_temp_new();
17792             TCGv t2 = tcg_temp_new();
17793
17794             gen_load_gpr(t1, rs);
17795             gen_load_gpr(t2, rt);
17796             tcg_gen_add_tl(t0, t1, t2);
17797             tcg_gen_ext32s_tl(t0, t0);
17798             tcg_gen_xor_tl(t1, t1, t2);
17799             tcg_gen_xor_tl(t2, t0, t2);
17800             tcg_gen_andc_tl(t1, t2, t1);
17801
17802             /* operands of same sign, result different sign */
17803             tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0);
17804             gen_store_gpr(t0, rd);
17805
17806             tcg_temp_free(t0);
17807             tcg_temp_free(t1);
17808             tcg_temp_free(t2);
17809         }
17810         break;
17811     case NM_MUL:
17812         gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
17813         break;
17814     case NM_MUH:
17815         gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
17816         break;
17817     case NM_MULU:
17818         gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
17819         break;
17820     case NM_MUHU:
17821         gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
17822         break;
17823     case NM_DIV:
17824         gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
17825         break;
17826     case NM_MOD:
17827         gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
17828         break;
17829     case NM_DIVU:
17830         gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
17831         break;
17832     case NM_MODU:
17833         gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
17834         break;
17835 #ifndef CONFIG_USER_ONLY
17836     case NM_MFC0:
17837         check_cp0_enabled(ctx);
17838         if (rt == 0) {
17839             /* Treat as NOP. */
17840             break;
17841         }
17842         gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3));
17843         break;
17844     case NM_MTC0:
17845         check_cp0_enabled(ctx);
17846         {
17847             TCGv t0 = tcg_temp_new();
17848
17849             gen_load_gpr(t0, rt);
17850             gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3));
17851             tcg_temp_free(t0);
17852         }
17853         break;
17854     case NM_D_E_MT_VPE:
17855         {
17856             uint8_t sc = extract32(ctx->opcode, 10, 1);
17857             TCGv t0 = tcg_temp_new();
17858
17859             switch (sc) {
17860             case 0:
17861                 if (rs == 1) {
17862                     /* DMT */
17863                     check_cp0_mt(ctx);
17864                     gen_helper_dmt(t0);
17865                     gen_store_gpr(t0, rt);
17866                 } else if (rs == 0) {
17867                     /* DVPE */
17868                     check_cp0_mt(ctx);
17869                     gen_helper_dvpe(t0, cpu_env);
17870                     gen_store_gpr(t0, rt);
17871                 } else {
17872                     generate_exception_end(ctx, EXCP_RI);
17873                 }
17874                 break;
17875             case 1:
17876                 if (rs == 1) {
17877                     /* EMT */
17878                     check_cp0_mt(ctx);
17879                     gen_helper_emt(t0);
17880                     gen_store_gpr(t0, rt);
17881                 } else if (rs == 0) {
17882                     /* EVPE */
17883                     check_cp0_mt(ctx);
17884                     gen_helper_evpe(t0, cpu_env);
17885                     gen_store_gpr(t0, rt);
17886                 } else {
17887                     generate_exception_end(ctx, EXCP_RI);
17888                 }
17889                 break;
17890             }
17891
17892             tcg_temp_free(t0);
17893         }
17894         break;
17895     case NM_FORK:
17896         check_mt(ctx);
17897         {
17898             TCGv t0 = tcg_temp_new();
17899             TCGv t1 = tcg_temp_new();
17900
17901             gen_load_gpr(t0, rt);
17902             gen_load_gpr(t1, rs);
17903             gen_helper_fork(t0, t1);
17904             tcg_temp_free(t0);
17905             tcg_temp_free(t1);
17906         }
17907         break;
17908     case NM_MFTR:
17909     case NM_MFHTR:
17910         check_cp0_enabled(ctx);
17911         if (rd == 0) {
17912             /* Treat as NOP. */
17913             return;
17914         }
17915         gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
17916                  extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
17917         break;
17918     case NM_MTTR:
17919     case NM_MTHTR:
17920         check_cp0_enabled(ctx);
17921         gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
17922                  extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
17923         break;
17924     case NM_YIELD:
17925         check_mt(ctx);
17926         {
17927             TCGv t0 = tcg_temp_new();
17928
17929             gen_load_gpr(t0, rs);
17930             gen_helper_yield(t0, cpu_env, t0);
17931             gen_store_gpr(t0, rt);
17932             tcg_temp_free(t0);
17933         }
17934         break;
17935 #endif
17936     default:
17937         generate_exception_end(ctx, EXCP_RI);
17938         break;
17939     }
17940 }
17941
17942 /* dsp */
17943 static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc,
17944                                             int ret, int v1, int v2)
17945 {
17946     TCGv_i32 t0;
17947     TCGv v0_t;
17948     TCGv v1_t;
17949
17950     t0 = tcg_temp_new_i32();
17951
17952     v0_t = tcg_temp_new();
17953     v1_t = tcg_temp_new();
17954
17955     tcg_gen_movi_i32(t0, v2 >> 3);
17956
17957     gen_load_gpr(v0_t, ret);
17958     gen_load_gpr(v1_t, v1);
17959
17960     switch (opc) {
17961     case NM_MAQ_S_W_PHR:
17962         check_dsp(ctx);
17963         gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env);
17964         break;
17965     case NM_MAQ_S_W_PHL:
17966         check_dsp(ctx);
17967         gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env);
17968         break;
17969     case NM_MAQ_SA_W_PHR:
17970         check_dsp(ctx);
17971         gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env);
17972         break;
17973     case NM_MAQ_SA_W_PHL:
17974         check_dsp(ctx);
17975         gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env);
17976         break;
17977     default:
17978         generate_exception_end(ctx, EXCP_RI);
17979         break;
17980     }
17981
17982     tcg_temp_free_i32(t0);
17983
17984     tcg_temp_free(v0_t);
17985     tcg_temp_free(v1_t);
17986 }
17987
17988
17989 static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc,
17990                                     int ret, int v1, int v2)
17991 {
17992     int16_t imm;
17993     TCGv t0 = tcg_temp_new();
17994     TCGv t1 = tcg_temp_new();
17995     TCGv v0_t = tcg_temp_new();
17996
17997     gen_load_gpr(v0_t, v1);
17998
17999     switch (opc) {
18000     case NM_POOL32AXF_1_0:
18001         check_dsp(ctx);
18002         switch (extract32(ctx->opcode, 12, 2)) {
18003         case NM_MFHI:
18004             gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret);
18005             break;
18006         case NM_MFLO:
18007             gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret);
18008             break;
18009         case NM_MTHI:
18010             gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1);
18011             break;
18012         case NM_MTLO:
18013             gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1);
18014             break;
18015         }
18016         break;
18017     case NM_POOL32AXF_1_1:
18018         check_dsp(ctx);
18019         switch (extract32(ctx->opcode, 12, 2)) {
18020         case NM_MTHLIP:
18021             tcg_gen_movi_tl(t0, v2);
18022             gen_helper_mthlip(t0, v0_t, cpu_env);
18023             break;
18024         case NM_SHILOV:
18025             tcg_gen_movi_tl(t0, v2 >> 3);
18026             gen_helper_shilo(t0, v0_t, cpu_env);
18027             break;
18028         default:
18029             generate_exception_end(ctx, EXCP_RI);
18030             break;
18031         }
18032         break;
18033     case NM_POOL32AXF_1_3:
18034         check_dsp(ctx);
18035         imm = extract32(ctx->opcode, 14, 7);
18036         switch (extract32(ctx->opcode, 12, 2)) {
18037         case NM_RDDSP:
18038             tcg_gen_movi_tl(t0, imm);
18039             gen_helper_rddsp(t0, t0, cpu_env);
18040             gen_store_gpr(t0, ret);
18041             break;
18042         case NM_WRDSP:
18043             gen_load_gpr(t0, ret);
18044             tcg_gen_movi_tl(t1, imm);
18045             gen_helper_wrdsp(t0, t1, cpu_env);
18046             break;
18047         case NM_EXTP:
18048             tcg_gen_movi_tl(t0, v2 >> 3);
18049             tcg_gen_movi_tl(t1, v1);
18050             gen_helper_extp(t0, t0, t1, cpu_env);
18051             gen_store_gpr(t0, ret);
18052             break;
18053         case NM_EXTPDP:
18054             tcg_gen_movi_tl(t0, v2 >> 3);
18055             tcg_gen_movi_tl(t1, v1);
18056             gen_helper_extpdp(t0, t0, t1, cpu_env);
18057             gen_store_gpr(t0, ret);
18058             break;
18059         }
18060         break;
18061     case NM_POOL32AXF_1_4:
18062         check_dsp(ctx);
18063         tcg_gen_movi_tl(t0, v2 >> 2);
18064         switch (extract32(ctx->opcode, 12, 1)) {
18065         case NM_SHLL_QB:
18066             gen_helper_shll_qb(t0, t0, v0_t, cpu_env);
18067             gen_store_gpr(t0, ret);
18068             break;
18069         case NM_SHRL_QB:
18070             gen_helper_shrl_qb(t0, t0, v0_t);
18071             gen_store_gpr(t0, ret);
18072             break;
18073         }
18074         break;
18075     case NM_POOL32AXF_1_5:
18076         opc = extract32(ctx->opcode, 12, 2);
18077         gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2);
18078         break;
18079     case NM_POOL32AXF_1_7:
18080         check_dsp(ctx);
18081         tcg_gen_movi_tl(t0, v2 >> 3);
18082         tcg_gen_movi_tl(t1, v1);
18083         switch (extract32(ctx->opcode, 12, 2)) {
18084         case NM_EXTR_W:
18085             gen_helper_extr_w(t0, t0, t1, cpu_env);
18086             gen_store_gpr(t0, ret);
18087             break;
18088         case NM_EXTR_R_W:
18089             gen_helper_extr_r_w(t0, t0, t1, cpu_env);
18090             gen_store_gpr(t0, ret);
18091             break;
18092         case NM_EXTR_RS_W:
18093             gen_helper_extr_rs_w(t0, t0, t1, cpu_env);
18094             gen_store_gpr(t0, ret);
18095             break;
18096         case NM_EXTR_S_H:
18097             gen_helper_extr_s_h(t0, t0, t1, cpu_env);
18098             gen_store_gpr(t0, ret);
18099             break;
18100         }
18101         break;
18102     default:
18103         generate_exception_end(ctx, EXCP_RI);
18104         break;
18105     }
18106
18107     tcg_temp_free(t0);
18108     tcg_temp_free(t1);
18109     tcg_temp_free(v0_t);
18110 }
18111
18112 static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc,
18113                                     TCGv v0, TCGv v1, int rd)
18114 {
18115     TCGv_i32 t0;
18116
18117     t0 = tcg_temp_new_i32();
18118
18119     tcg_gen_movi_i32(t0, rd >> 3);
18120
18121     switch (opc) {
18122     case NM_POOL32AXF_2_0_7:
18123         switch (extract32(ctx->opcode, 9, 3)) {
18124         case NM_DPA_W_PH:
18125             check_dsp_r2(ctx);
18126             gen_helper_dpa_w_ph(t0, v1, v0, cpu_env);
18127             break;
18128         case NM_DPAQ_S_W_PH:
18129             check_dsp(ctx);
18130             gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env);
18131             break;
18132         case NM_DPS_W_PH:
18133             check_dsp_r2(ctx);
18134             gen_helper_dps_w_ph(t0, v1, v0, cpu_env);
18135             break;
18136         case NM_DPSQ_S_W_PH:
18137             check_dsp(ctx);
18138             gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env);
18139             break;
18140         default:
18141             generate_exception_end(ctx, EXCP_RI);
18142             break;
18143         }
18144         break;
18145     case NM_POOL32AXF_2_8_15:
18146         switch (extract32(ctx->opcode, 9, 3)) {
18147         case NM_DPAX_W_PH:
18148             check_dsp_r2(ctx);
18149             gen_helper_dpax_w_ph(t0, v0, v1, cpu_env);
18150             break;
18151         case NM_DPAQ_SA_L_W:
18152             check_dsp(ctx);
18153             gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env);
18154             break;
18155         case NM_DPSX_W_PH:
18156             check_dsp_r2(ctx);
18157             gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env);
18158             break;
18159         case NM_DPSQ_SA_L_W:
18160             check_dsp(ctx);
18161             gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env);
18162             break;
18163         default:
18164             generate_exception_end(ctx, EXCP_RI);
18165             break;
18166         }
18167         break;
18168     case NM_POOL32AXF_2_16_23:
18169         switch (extract32(ctx->opcode, 9, 3)) {
18170         case NM_DPAU_H_QBL:
18171             check_dsp(ctx);
18172             gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env);
18173             break;
18174         case NM_DPAQX_S_W_PH:
18175             check_dsp_r2(ctx);
18176             gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env);
18177             break;
18178         case NM_DPSU_H_QBL:
18179             check_dsp(ctx);
18180             gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env);
18181             break;
18182         case NM_DPSQX_S_W_PH:
18183             check_dsp_r2(ctx);
18184             gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env);
18185             break;
18186         case NM_MULSA_W_PH:
18187             check_dsp_r2(ctx);
18188             gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env);
18189             break;
18190         default:
18191             generate_exception_end(ctx, EXCP_RI);
18192             break;
18193         }
18194         break;
18195     case NM_POOL32AXF_2_24_31:
18196         switch (extract32(ctx->opcode, 9, 3)) {
18197         case NM_DPAU_H_QBR:
18198             check_dsp(ctx);
18199             gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env);
18200             break;
18201         case NM_DPAQX_SA_W_PH:
18202             check_dsp_r2(ctx);
18203             gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env);
18204             break;
18205         case NM_DPSU_H_QBR:
18206             check_dsp(ctx);
18207             gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env);
18208             break;
18209         case NM_DPSQX_SA_W_PH:
18210             check_dsp_r2(ctx);
18211             gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env);
18212             break;
18213         case NM_MULSAQ_S_W_PH:
18214             check_dsp(ctx);
18215             gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env);
18216             break;
18217         default:
18218             generate_exception_end(ctx, EXCP_RI);
18219             break;
18220         }
18221         break;
18222     default:
18223         generate_exception_end(ctx, EXCP_RI);
18224         break;
18225     }
18226
18227     tcg_temp_free_i32(t0);
18228 }
18229
18230 static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc,
18231                                           int rt, int rs, int rd)
18232 {
18233     int ret = rt;
18234     TCGv t0 = tcg_temp_new();
18235     TCGv t1 = tcg_temp_new();
18236     TCGv v0_t = tcg_temp_new();
18237     TCGv v1_t = tcg_temp_new();
18238
18239     gen_load_gpr(v0_t, rt);
18240     gen_load_gpr(v1_t, rs);
18241
18242     switch (opc) {
18243     case NM_POOL32AXF_2_0_7:
18244         switch (extract32(ctx->opcode, 9, 3)) {
18245         case NM_DPA_W_PH:
18246         case NM_DPAQ_S_W_PH:
18247         case NM_DPS_W_PH:
18248         case NM_DPSQ_S_W_PH:
18249             gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18250             break;
18251         case NM_BALIGN:
18252             check_dsp_r2(ctx);
18253             if (rt != 0) {
18254                 gen_load_gpr(t0, rs);
18255                 rd &= 3;
18256                 if (rd != 0 && rd != 2) {
18257                     tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd);
18258                     tcg_gen_ext32u_tl(t0, t0);
18259                     tcg_gen_shri_tl(t0, t0, 8 * (4 - rd));
18260                     tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
18261                 }
18262                 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
18263             }
18264             break;
18265         case NM_MADD:
18266             check_dsp(ctx);
18267             {
18268                 int acc = extract32(ctx->opcode, 14, 2);
18269                 TCGv_i64 t2 = tcg_temp_new_i64();
18270                 TCGv_i64 t3 = tcg_temp_new_i64();
18271
18272                 gen_load_gpr(t0, rt);
18273                 gen_load_gpr(t1, rs);
18274                 tcg_gen_ext_tl_i64(t2, t0);
18275                 tcg_gen_ext_tl_i64(t3, t1);
18276                 tcg_gen_mul_i64(t2, t2, t3);
18277                 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18278                 tcg_gen_add_i64(t2, t2, t3);
18279                 tcg_temp_free_i64(t3);
18280                 gen_move_low32(cpu_LO[acc], t2);
18281                 gen_move_high32(cpu_HI[acc], t2);
18282                 tcg_temp_free_i64(t2);
18283             }
18284             break;
18285         case NM_MULT:
18286             check_dsp(ctx);
18287             {
18288                 int acc = extract32(ctx->opcode, 14, 2);
18289                 TCGv_i32 t2 = tcg_temp_new_i32();
18290                 TCGv_i32 t3 = tcg_temp_new_i32();
18291
18292                 gen_load_gpr(t0, rs);
18293                 gen_load_gpr(t1, rt);
18294                 tcg_gen_trunc_tl_i32(t2, t0);
18295                 tcg_gen_trunc_tl_i32(t3, t1);
18296                 tcg_gen_muls2_i32(t2, t3, t2, t3);
18297                 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
18298                 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
18299                 tcg_temp_free_i32(t2);
18300                 tcg_temp_free_i32(t3);
18301             }
18302             break;
18303         case NM_EXTRV_W:
18304             check_dsp(ctx);
18305             gen_load_gpr(v1_t, rs);
18306             tcg_gen_movi_tl(t0, rd >> 3);
18307             gen_helper_extr_w(t0, t0, v1_t, cpu_env);
18308             gen_store_gpr(t0, ret);
18309             break;
18310         }
18311         break;
18312     case NM_POOL32AXF_2_8_15:
18313         switch (extract32(ctx->opcode, 9, 3)) {
18314         case NM_DPAX_W_PH:
18315         case NM_DPAQ_SA_L_W:
18316         case NM_DPSX_W_PH:
18317         case NM_DPSQ_SA_L_W:
18318             gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18319             break;
18320         case NM_MADDU:
18321             check_dsp(ctx);
18322             {
18323                 int acc = extract32(ctx->opcode, 14, 2);
18324                 TCGv_i64 t2 = tcg_temp_new_i64();
18325                 TCGv_i64 t3 = tcg_temp_new_i64();
18326
18327                 gen_load_gpr(t0, rs);
18328                 gen_load_gpr(t1, rt);
18329                 tcg_gen_ext32u_tl(t0, t0);
18330                 tcg_gen_ext32u_tl(t1, t1);
18331                 tcg_gen_extu_tl_i64(t2, t0);
18332                 tcg_gen_extu_tl_i64(t3, t1);
18333                 tcg_gen_mul_i64(t2, t2, t3);
18334                 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18335                 tcg_gen_add_i64(t2, t2, t3);
18336                 tcg_temp_free_i64(t3);
18337                 gen_move_low32(cpu_LO[acc], t2);
18338                 gen_move_high32(cpu_HI[acc], t2);
18339                 tcg_temp_free_i64(t2);
18340             }
18341             break;
18342         case NM_MULTU:
18343             check_dsp(ctx);
18344             {
18345                 int acc = extract32(ctx->opcode, 14, 2);
18346                 TCGv_i32 t2 = tcg_temp_new_i32();
18347                 TCGv_i32 t3 = tcg_temp_new_i32();
18348
18349                 gen_load_gpr(t0, rs);
18350                 gen_load_gpr(t1, rt);
18351                 tcg_gen_trunc_tl_i32(t2, t0);
18352                 tcg_gen_trunc_tl_i32(t3, t1);
18353                 tcg_gen_mulu2_i32(t2, t3, t2, t3);
18354                 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
18355                 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
18356                 tcg_temp_free_i32(t2);
18357                 tcg_temp_free_i32(t3);
18358             }
18359             break;
18360         case NM_EXTRV_R_W:
18361             check_dsp(ctx);
18362             tcg_gen_movi_tl(t0, rd >> 3);
18363             gen_helper_extr_r_w(t0, t0, v1_t, cpu_env);
18364             gen_store_gpr(t0, ret);
18365             break;
18366         default:
18367             generate_exception_end(ctx, EXCP_RI);
18368             break;
18369         }
18370         break;
18371     case NM_POOL32AXF_2_16_23:
18372         switch (extract32(ctx->opcode, 9, 3)) {
18373         case NM_DPAU_H_QBL:
18374         case NM_DPAQX_S_W_PH:
18375         case NM_DPSU_H_QBL:
18376         case NM_DPSQX_S_W_PH:
18377         case NM_MULSA_W_PH:
18378             gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18379             break;
18380         case NM_EXTPV:
18381             check_dsp(ctx);
18382             tcg_gen_movi_tl(t0, rd >> 3);
18383             gen_helper_extp(t0, t0, v1_t, cpu_env);
18384             gen_store_gpr(t0, ret);
18385             break;
18386         case NM_MSUB:
18387             check_dsp(ctx);
18388             {
18389                 int acc = extract32(ctx->opcode, 14, 2);
18390                 TCGv_i64 t2 = tcg_temp_new_i64();
18391                 TCGv_i64 t3 = tcg_temp_new_i64();
18392
18393                 gen_load_gpr(t0, rs);
18394                 gen_load_gpr(t1, rt);
18395                 tcg_gen_ext_tl_i64(t2, t0);
18396                 tcg_gen_ext_tl_i64(t3, t1);
18397                 tcg_gen_mul_i64(t2, t2, t3);
18398                 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18399                 tcg_gen_sub_i64(t2, t3, t2);
18400                 tcg_temp_free_i64(t3);
18401                 gen_move_low32(cpu_LO[acc], t2);
18402                 gen_move_high32(cpu_HI[acc], t2);
18403                 tcg_temp_free_i64(t2);
18404             }
18405             break;
18406         case NM_EXTRV_RS_W:
18407             check_dsp(ctx);
18408             tcg_gen_movi_tl(t0, rd >> 3);
18409             gen_helper_extr_rs_w(t0, t0, v1_t, cpu_env);
18410             gen_store_gpr(t0, ret);
18411             break;
18412         }
18413         break;
18414     case NM_POOL32AXF_2_24_31:
18415         switch (extract32(ctx->opcode, 9, 3)) {
18416         case NM_DPAU_H_QBR:
18417         case NM_DPAQX_SA_W_PH:
18418         case NM_DPSU_H_QBR:
18419         case NM_DPSQX_SA_W_PH:
18420         case NM_MULSAQ_S_W_PH:
18421             gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18422             break;
18423         case NM_EXTPDPV:
18424             check_dsp(ctx);
18425             tcg_gen_movi_tl(t0, rd >> 3);
18426             gen_helper_extpdp(t0, t0, v1_t, cpu_env);
18427             gen_store_gpr(t0, ret);
18428             break;
18429         case NM_MSUBU:
18430             check_dsp(ctx);
18431             {
18432                 int acc = extract32(ctx->opcode, 14, 2);
18433                 TCGv_i64 t2 = tcg_temp_new_i64();
18434                 TCGv_i64 t3 = tcg_temp_new_i64();
18435
18436                 gen_load_gpr(t0, rs);
18437                 gen_load_gpr(t1, rt);
18438                 tcg_gen_ext32u_tl(t0, t0);
18439                 tcg_gen_ext32u_tl(t1, t1);
18440                 tcg_gen_extu_tl_i64(t2, t0);
18441                 tcg_gen_extu_tl_i64(t3, t1);
18442                 tcg_gen_mul_i64(t2, t2, t3);
18443                 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18444                 tcg_gen_sub_i64(t2, t3, t2);
18445                 tcg_temp_free_i64(t3);
18446                 gen_move_low32(cpu_LO[acc], t2);
18447                 gen_move_high32(cpu_HI[acc], t2);
18448                 tcg_temp_free_i64(t2);
18449             }
18450             break;
18451         case NM_EXTRV_S_H:
18452             check_dsp(ctx);
18453             tcg_gen_movi_tl(t0, rd >> 3);
18454             gen_helper_extr_s_h(t0, t0, v0_t, cpu_env);
18455             gen_store_gpr(t0, ret);
18456             break;
18457         }
18458         break;
18459     default:
18460         generate_exception_end(ctx, EXCP_RI);
18461         break;
18462     }
18463
18464     tcg_temp_free(t0);
18465     tcg_temp_free(t1);
18466
18467     tcg_temp_free(v0_t);
18468     tcg_temp_free(v1_t);
18469 }
18470
18471 static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc,
18472                                           int rt, int rs)
18473 {
18474     int ret = rt;
18475     TCGv t0 = tcg_temp_new();
18476     TCGv v0_t = tcg_temp_new();
18477
18478     gen_load_gpr(v0_t, rs);
18479
18480     switch (opc) {
18481     case NM_ABSQ_S_QB:
18482         check_dsp_r2(ctx);
18483         gen_helper_absq_s_qb(v0_t, v0_t, cpu_env);
18484         gen_store_gpr(v0_t, ret);
18485         break;
18486     case NM_ABSQ_S_PH:
18487         check_dsp(ctx);
18488         gen_helper_absq_s_ph(v0_t, v0_t, cpu_env);
18489         gen_store_gpr(v0_t, ret);
18490         break;
18491     case NM_ABSQ_S_W:
18492         check_dsp(ctx);
18493         gen_helper_absq_s_w(v0_t, v0_t, cpu_env);
18494         gen_store_gpr(v0_t, ret);
18495         break;
18496     case NM_PRECEQ_W_PHL:
18497         check_dsp(ctx);
18498         tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000);
18499         tcg_gen_ext32s_tl(v0_t, v0_t);
18500         gen_store_gpr(v0_t, ret);
18501         break;
18502     case NM_PRECEQ_W_PHR:
18503         check_dsp(ctx);
18504         tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF);
18505         tcg_gen_shli_tl(v0_t, v0_t, 16);
18506         tcg_gen_ext32s_tl(v0_t, v0_t);
18507         gen_store_gpr(v0_t, ret);
18508         break;
18509     case NM_PRECEQU_PH_QBL:
18510         check_dsp(ctx);
18511         gen_helper_precequ_ph_qbl(v0_t, v0_t);
18512         gen_store_gpr(v0_t, ret);
18513         break;
18514     case NM_PRECEQU_PH_QBR:
18515         check_dsp(ctx);
18516         gen_helper_precequ_ph_qbr(v0_t, v0_t);
18517         gen_store_gpr(v0_t, ret);
18518         break;
18519     case NM_PRECEQU_PH_QBLA:
18520         check_dsp(ctx);
18521         gen_helper_precequ_ph_qbla(v0_t, v0_t);
18522         gen_store_gpr(v0_t, ret);
18523         break;
18524     case NM_PRECEQU_PH_QBRA:
18525         check_dsp(ctx);
18526         gen_helper_precequ_ph_qbra(v0_t, v0_t);
18527         gen_store_gpr(v0_t, ret);
18528         break;
18529     case NM_PRECEU_PH_QBL:
18530         check_dsp(ctx);
18531         gen_helper_preceu_ph_qbl(v0_t, v0_t);
18532         gen_store_gpr(v0_t, ret);
18533         break;
18534     case NM_PRECEU_PH_QBR:
18535         check_dsp(ctx);
18536         gen_helper_preceu_ph_qbr(v0_t, v0_t);
18537         gen_store_gpr(v0_t, ret);
18538         break;
18539     case NM_PRECEU_PH_QBLA:
18540         check_dsp(ctx);
18541         gen_helper_preceu_ph_qbla(v0_t, v0_t);
18542         gen_store_gpr(v0_t, ret);
18543         break;
18544     case NM_PRECEU_PH_QBRA:
18545         check_dsp(ctx);
18546         gen_helper_preceu_ph_qbra(v0_t, v0_t);
18547         gen_store_gpr(v0_t, ret);
18548         break;
18549     case NM_REPLV_PH:
18550         check_dsp(ctx);
18551         tcg_gen_ext16u_tl(v0_t, v0_t);
18552         tcg_gen_shli_tl(t0, v0_t, 16);
18553         tcg_gen_or_tl(v0_t, v0_t, t0);
18554         tcg_gen_ext32s_tl(v0_t, v0_t);
18555         gen_store_gpr(v0_t, ret);
18556         break;
18557     case NM_REPLV_QB:
18558         check_dsp(ctx);
18559         tcg_gen_ext8u_tl(v0_t, v0_t);
18560         tcg_gen_shli_tl(t0, v0_t, 8);
18561         tcg_gen_or_tl(v0_t, v0_t, t0);
18562         tcg_gen_shli_tl(t0, v0_t, 16);
18563         tcg_gen_or_tl(v0_t, v0_t, t0);
18564         tcg_gen_ext32s_tl(v0_t, v0_t);
18565         gen_store_gpr(v0_t, ret);
18566         break;
18567     case NM_BITREV:
18568         check_dsp(ctx);
18569         gen_helper_bitrev(v0_t, v0_t);
18570         gen_store_gpr(v0_t, ret);
18571         break;
18572     case NM_INSV:
18573         check_dsp(ctx);
18574         {
18575             TCGv tv0 = tcg_temp_new();
18576
18577             gen_load_gpr(tv0, rt);
18578             gen_helper_insv(v0_t, cpu_env, v0_t, tv0);
18579             gen_store_gpr(v0_t, ret);
18580             tcg_temp_free(tv0);
18581         }
18582         break;
18583     case NM_RADDU_W_QB:
18584         check_dsp(ctx);
18585         gen_helper_raddu_w_qb(v0_t, v0_t);
18586         gen_store_gpr(v0_t, ret);
18587         break;
18588     case NM_BITSWAP:
18589         gen_bitswap(ctx, OPC_BITSWAP, ret, rs);
18590         break;
18591     case NM_CLO:
18592         check_nms(ctx);
18593         gen_cl(ctx, OPC_CLO, ret, rs);
18594         break;
18595     case NM_CLZ:
18596         check_nms(ctx);
18597         gen_cl(ctx, OPC_CLZ, ret, rs);
18598         break;
18599     case NM_WSBH:
18600         gen_bshfl(ctx, OPC_WSBH, ret, rs);
18601         break;
18602     default:
18603         generate_exception_end(ctx, EXCP_RI);
18604         break;
18605     }
18606
18607     tcg_temp_free(v0_t);
18608     tcg_temp_free(t0);
18609 }
18610
18611 static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc,
18612                                           int rt, int rs, int rd)
18613 {
18614     TCGv t0 = tcg_temp_new();
18615     TCGv rs_t = tcg_temp_new();
18616
18617     gen_load_gpr(rs_t, rs);
18618
18619     switch (opc) {
18620     case NM_SHRA_R_QB:
18621         check_dsp_r2(ctx);
18622         tcg_gen_movi_tl(t0, rd >> 2);
18623         switch (extract32(ctx->opcode, 12, 1)) {
18624         case 0:
18625             /* NM_SHRA_QB */
18626             gen_helper_shra_qb(t0, t0, rs_t);
18627             gen_store_gpr(t0, rt);
18628             break;
18629         case 1:
18630             /* NM_SHRA_R_QB */
18631             gen_helper_shra_r_qb(t0, t0, rs_t);
18632             gen_store_gpr(t0, rt);
18633             break;
18634         }
18635         break;
18636     case NM_SHRL_PH:
18637         check_dsp_r2(ctx);
18638         tcg_gen_movi_tl(t0, rd >> 1);
18639         gen_helper_shrl_ph(t0, t0, rs_t);
18640         gen_store_gpr(t0, rt);
18641         break;
18642     case NM_REPL_QB:
18643         check_dsp(ctx);
18644         {
18645             int16_t imm;
18646             target_long result;
18647             imm = extract32(ctx->opcode, 13, 8);
18648             result = (uint32_t)imm << 24 |
18649                      (uint32_t)imm << 16 |
18650                      (uint32_t)imm << 8  |
18651                      (uint32_t)imm;
18652             result = (int32_t)result;
18653             tcg_gen_movi_tl(t0, result);
18654             gen_store_gpr(t0, rt);
18655         }
18656         break;
18657     default:
18658         generate_exception_end(ctx, EXCP_RI);
18659         break;
18660     }
18661     tcg_temp_free(t0);
18662     tcg_temp_free(rs_t);
18663 }
18664
18665
18666 static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
18667 {
18668     int rt = extract32(ctx->opcode, 21, 5);
18669     int rs = extract32(ctx->opcode, 16, 5);
18670     int rd = extract32(ctx->opcode, 11, 5);
18671
18672     switch (extract32(ctx->opcode, 6, 3)) {
18673     case NM_POOL32AXF_1:
18674         {
18675             int32_t op1 = extract32(ctx->opcode, 9, 3);
18676             gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd);
18677         }
18678         break;
18679     case NM_POOL32AXF_2:
18680         {
18681             int32_t op1 = extract32(ctx->opcode, 12, 2);
18682             gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd);
18683         }
18684         break;
18685     case NM_POOL32AXF_4:
18686         {
18687             int32_t op1 = extract32(ctx->opcode, 9, 7);
18688             gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs);
18689         }
18690         break;
18691     case NM_POOL32AXF_5:
18692         switch (extract32(ctx->opcode, 9, 7)) {
18693 #ifndef CONFIG_USER_ONLY
18694         case NM_TLBP:
18695             gen_cp0(env, ctx, OPC_TLBP, 0, 0);
18696             break;
18697         case NM_TLBR:
18698             gen_cp0(env, ctx, OPC_TLBR, 0, 0);
18699             break;
18700         case NM_TLBWI:
18701             gen_cp0(env, ctx, OPC_TLBWI, 0, 0);
18702             break;
18703         case NM_TLBWR:
18704             gen_cp0(env, ctx, OPC_TLBWR, 0, 0);
18705             break;
18706         case NM_TLBINV:
18707             gen_cp0(env, ctx, OPC_TLBINV, 0, 0);
18708             break;
18709         case NM_TLBINVF:
18710             gen_cp0(env, ctx, OPC_TLBINVF, 0, 0);
18711             break;
18712         case NM_DI:
18713             check_cp0_enabled(ctx);
18714             {
18715                 TCGv t0 = tcg_temp_new();
18716
18717                 save_cpu_state(ctx, 1);
18718                 gen_helper_di(t0, cpu_env);
18719                 gen_store_gpr(t0, rt);
18720             /* Stop translation as we may have switched the execution mode */
18721                 ctx->base.is_jmp = DISAS_STOP;
18722                 tcg_temp_free(t0);
18723             }
18724             break;
18725         case NM_EI:
18726             check_cp0_enabled(ctx);
18727             {
18728                 TCGv t0 = tcg_temp_new();
18729
18730                 save_cpu_state(ctx, 1);
18731                 gen_helper_ei(t0, cpu_env);
18732                 gen_store_gpr(t0, rt);
18733             /* Stop translation as we may have switched the execution mode */
18734                 ctx->base.is_jmp = DISAS_STOP;
18735                 tcg_temp_free(t0);
18736             }
18737             break;
18738         case NM_RDPGPR:
18739             gen_load_srsgpr(rs, rt);
18740             break;
18741         case NM_WRPGPR:
18742             gen_store_srsgpr(rs, rt);
18743             break;
18744         case NM_WAIT:
18745             gen_cp0(env, ctx, OPC_WAIT, 0, 0);
18746             break;
18747         case NM_DERET:
18748             gen_cp0(env, ctx, OPC_DERET, 0, 0);
18749             break;
18750         case NM_ERETX:
18751             gen_cp0(env, ctx, OPC_ERET, 0, 0);
18752             break;
18753 #endif
18754         default:
18755             generate_exception_end(ctx, EXCP_RI);
18756             break;
18757         }
18758         break;
18759     case NM_POOL32AXF_7:
18760         {
18761             int32_t op1 = extract32(ctx->opcode, 9, 3);
18762             gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd);
18763         }
18764         break;
18765     default:
18766         generate_exception_end(ctx, EXCP_RI);
18767         break;
18768     }
18769 }
18770
18771 /* Immediate Value Compact Branches */
18772 static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc,
18773                                    int rt, int32_t imm, int32_t offset)
18774 {
18775     TCGCond cond;
18776     int bcond_compute = 0;
18777     TCGv t0 = tcg_temp_new();
18778     TCGv t1 = tcg_temp_new();
18779
18780     gen_load_gpr(t0, rt);
18781     tcg_gen_movi_tl(t1, imm);
18782     ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
18783
18784     /* Load needed operands and calculate btarget */
18785     switch (opc) {
18786     case NM_BEQIC:
18787         if (rt == 0 && imm == 0) {
18788             /* Unconditional branch */
18789         } else if (rt == 0 && imm != 0) {
18790             /* Treat as NOP */
18791             goto out;
18792         } else {
18793             bcond_compute = 1;
18794             cond = TCG_COND_EQ;
18795         }
18796         break;
18797     case NM_BBEQZC:
18798     case NM_BBNEZC:
18799         check_nms(ctx);
18800         if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) {
18801             generate_exception_end(ctx, EXCP_RI);
18802             goto out;
18803         } else if (rt == 0 && opc == NM_BBEQZC) {
18804             /* Unconditional branch */
18805         } else if (rt == 0 && opc == NM_BBNEZC) {
18806             /* Treat as NOP */
18807             goto out;
18808         } else {
18809             tcg_gen_shri_tl(t0, t0, imm);
18810             tcg_gen_andi_tl(t0, t0, 1);
18811             tcg_gen_movi_tl(t1, 0);
18812             bcond_compute = 1;
18813             if (opc == NM_BBEQZC) {
18814                 cond = TCG_COND_EQ;
18815             } else {
18816                 cond = TCG_COND_NE;
18817             }
18818         }
18819         break;
18820     case NM_BNEIC:
18821         if (rt == 0 && imm == 0) {
18822             /* Treat as NOP */
18823             goto out;
18824         } else if (rt == 0 && imm != 0) {
18825             /* Unconditional branch */
18826         } else {
18827             bcond_compute = 1;
18828             cond = TCG_COND_NE;
18829         }
18830         break;
18831     case NM_BGEIC:
18832         if (rt == 0 && imm == 0) {
18833             /* Unconditional branch */
18834         } else  {
18835             bcond_compute = 1;
18836             cond = TCG_COND_GE;
18837         }
18838         break;
18839     case NM_BLTIC:
18840         bcond_compute = 1;
18841         cond = TCG_COND_LT;
18842         break;
18843     case NM_BGEIUC:
18844         if (rt == 0 && imm == 0) {
18845             /* Unconditional branch */
18846         } else  {
18847             bcond_compute = 1;
18848             cond = TCG_COND_GEU;
18849         }
18850         break;
18851     case NM_BLTIUC:
18852         bcond_compute = 1;
18853         cond = TCG_COND_LTU;
18854         break;
18855     default:
18856         MIPS_INVAL("Immediate Value Compact branch");
18857         generate_exception_end(ctx, EXCP_RI);
18858         goto out;
18859     }
18860
18861     if (bcond_compute == 0) {
18862         /* Uncoditional compact branch */
18863         gen_goto_tb(ctx, 0, ctx->btarget);
18864     } else {
18865         /* Conditional compact branch */
18866         TCGLabel *fs = gen_new_label();
18867
18868         tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs);
18869
18870         gen_goto_tb(ctx, 1, ctx->btarget);
18871         gen_set_label(fs);
18872
18873         gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
18874     }
18875
18876 out:
18877     tcg_temp_free(t0);
18878     tcg_temp_free(t1);
18879 }
18880
18881 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
18882 static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs,
18883                                                 int rt)
18884 {
18885     TCGv t0 = tcg_temp_new();
18886     TCGv t1 = tcg_temp_new();
18887
18888     /* load rs */
18889     gen_load_gpr(t0, rs);
18890
18891     /* link */
18892     if (rt != 0) {
18893         tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4);
18894     }
18895
18896     /* calculate btarget */
18897     tcg_gen_shli_tl(t0, t0, 1);
18898     tcg_gen_movi_tl(t1, ctx->base.pc_next + 4);
18899     gen_op_addr_add(ctx, btarget, t1, t0);
18900
18901     /* unconditional branch to register */
18902     tcg_gen_mov_tl(cpu_PC, btarget);
18903     tcg_gen_lookup_and_goto_ptr();
18904
18905     tcg_temp_free(t0);
18906     tcg_temp_free(t1);
18907 }
18908
18909 /* nanoMIPS Branches */
18910 static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc,
18911                                        int rs, int rt, int32_t offset)
18912 {
18913     int bcond_compute = 0;
18914     TCGv t0 = tcg_temp_new();
18915     TCGv t1 = tcg_temp_new();
18916
18917     /* Load needed operands and calculate btarget */
18918     switch (opc) {
18919     /* compact branch */
18920     case OPC_BGEC:
18921     case OPC_BLTC:
18922         gen_load_gpr(t0, rs);
18923         gen_load_gpr(t1, rt);
18924         bcond_compute = 1;
18925         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
18926         break;
18927     case OPC_BGEUC:
18928     case OPC_BLTUC:
18929         if (rs == 0 || rs == rt) {
18930             /* OPC_BLEZALC, OPC_BGEZALC */
18931             /* OPC_BGTZALC, OPC_BLTZALC */
18932             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4);
18933         }
18934         gen_load_gpr(t0, rs);
18935         gen_load_gpr(t1, rt);
18936         bcond_compute = 1;
18937         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
18938         break;
18939     case OPC_BC:
18940         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
18941         break;
18942     case OPC_BEQZC:
18943         if (rs != 0) {
18944             /* OPC_BEQZC, OPC_BNEZC */
18945             gen_load_gpr(t0, rs);
18946             bcond_compute = 1;
18947             ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
18948         } else {
18949             /* OPC_JIC, OPC_JIALC */
18950             TCGv tbase = tcg_temp_new();
18951             TCGv toffset = tcg_temp_new();
18952
18953             gen_load_gpr(tbase, rt);
18954             tcg_gen_movi_tl(toffset, offset);
18955             gen_op_addr_add(ctx, btarget, tbase, toffset);
18956             tcg_temp_free(tbase);
18957             tcg_temp_free(toffset);
18958         }
18959         break;
18960     default:
18961         MIPS_INVAL("Compact branch/jump");
18962         generate_exception_end(ctx, EXCP_RI);
18963         goto out;
18964     }
18965
18966     if (bcond_compute == 0) {
18967         /* Uncoditional compact branch */
18968         switch (opc) {
18969         case OPC_BC:
18970             gen_goto_tb(ctx, 0, ctx->btarget);
18971             break;
18972         default:
18973             MIPS_INVAL("Compact branch/jump");
18974             generate_exception_end(ctx, EXCP_RI);
18975             goto out;
18976         }
18977     } else {
18978         /* Conditional compact branch */
18979         TCGLabel *fs = gen_new_label();
18980
18981         switch (opc) {
18982         case OPC_BGEUC:
18983             if (rs == 0 && rt != 0) {
18984                 /* OPC_BLEZALC */
18985                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
18986             } else if (rs != 0 && rt != 0 && rs == rt) {
18987                 /* OPC_BGEZALC */
18988                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
18989             } else {
18990                 /* OPC_BGEUC */
18991                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
18992             }
18993             break;
18994         case OPC_BLTUC:
18995             if (rs == 0 && rt != 0) {
18996                 /* OPC_BGTZALC */
18997                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
18998             } else if (rs != 0 && rt != 0 && rs == rt) {
18999                 /* OPC_BLTZALC */
19000                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19001             } else {
19002                 /* OPC_BLTUC */
19003                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
19004             }
19005             break;
19006         case OPC_BGEC:
19007             if (rs == 0 && rt != 0) {
19008                 /* OPC_BLEZC */
19009                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19010             } else if (rs != 0 && rt != 0 && rs == rt) {
19011                 /* OPC_BGEZC */
19012                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19013             } else {
19014                 /* OPC_BGEC */
19015                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
19016             }
19017             break;
19018         case OPC_BLTC:
19019             if (rs == 0 && rt != 0) {
19020                 /* OPC_BGTZC */
19021                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19022             } else if (rs != 0 && rt != 0 && rs == rt) {
19023                 /* OPC_BLTZC */
19024                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19025             } else {
19026                 /* OPC_BLTC */
19027                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
19028             }
19029             break;
19030         case OPC_BEQZC:
19031             tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
19032             break;
19033         default:
19034             MIPS_INVAL("Compact conditional branch/jump");
19035             generate_exception_end(ctx, EXCP_RI);
19036             goto out;
19037         }
19038
19039         /* Generating branch here as compact branches don't have delay slot */
19040         gen_goto_tb(ctx, 1, ctx->btarget);
19041         gen_set_label(fs);
19042
19043         gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19044     }
19045
19046 out:
19047     tcg_temp_free(t0);
19048     tcg_temp_free(t1);
19049 }
19050
19051
19052 /* nanoMIPS CP1 Branches */
19053 static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op,
19054                                    int32_t ft, int32_t offset)
19055 {
19056     target_ulong btarget;
19057     TCGv_i64 t0 = tcg_temp_new_i64();
19058
19059     gen_load_fpr64(ctx, t0, ft);
19060     tcg_gen_andi_i64(t0, t0, 1);
19061
19062     btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19063
19064     switch (op) {
19065     case NM_BC1EQZC:
19066         tcg_gen_xori_i64(t0, t0, 1);
19067         ctx->hflags |= MIPS_HFLAG_BC;
19068         break;
19069     case NM_BC1NEZC:
19070         /* t0 already set */
19071         ctx->hflags |= MIPS_HFLAG_BC;
19072         break;
19073     default:
19074         MIPS_INVAL("cp1 cond branch");
19075         generate_exception_end(ctx, EXCP_RI);
19076         goto out;
19077     }
19078
19079     tcg_gen_trunc_i64_tl(bcond, t0);
19080
19081     ctx->btarget = btarget;
19082
19083 out:
19084     tcg_temp_free_i64(t0);
19085 }
19086
19087
19088 static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt)
19089 {
19090     TCGv t0, t1;
19091     t0 = tcg_temp_new();
19092     t1 = tcg_temp_new();
19093
19094     gen_load_gpr(t0, rs);
19095     gen_load_gpr(t1, rt);
19096
19097     if ((extract32(ctx->opcode, 6, 1)) == 1) {
19098         /* PP.LSXS instructions require shifting */
19099         switch (extract32(ctx->opcode, 7, 4)) {
19100         case NM_SHXS:
19101             check_nms(ctx);
19102         case NM_LHXS:
19103         case NM_LHUXS:
19104             tcg_gen_shli_tl(t0, t0, 1);
19105             break;
19106         case NM_SWXS:
19107             check_nms(ctx);
19108         case NM_LWXS:
19109         case NM_LWC1XS:
19110         case NM_SWC1XS:
19111             tcg_gen_shli_tl(t0, t0, 2);
19112             break;
19113         case NM_LDC1XS:
19114         case NM_SDC1XS:
19115             tcg_gen_shli_tl(t0, t0, 3);
19116             break;
19117         }
19118     }
19119     gen_op_addr_add(ctx, t0, t0, t1);
19120
19121     switch (extract32(ctx->opcode, 7, 4)) {
19122     case NM_LBX:
19123         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19124                            MO_SB);
19125         gen_store_gpr(t0, rd);
19126         break;
19127     case NM_LHX:
19128     /*case NM_LHXS:*/
19129         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19130                            MO_TESW);
19131         gen_store_gpr(t0, rd);
19132         break;
19133     case NM_LWX:
19134     /*case NM_LWXS:*/
19135         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19136                            MO_TESL);
19137         gen_store_gpr(t0, rd);
19138         break;
19139     case NM_LBUX:
19140         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19141                            MO_UB);
19142         gen_store_gpr(t0, rd);
19143         break;
19144     case NM_LHUX:
19145     /*case NM_LHUXS:*/
19146         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19147                            MO_TEUW);
19148         gen_store_gpr(t0, rd);
19149         break;
19150     case NM_SBX:
19151         check_nms(ctx);
19152         gen_load_gpr(t1, rd);
19153         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19154                            MO_8);
19155         break;
19156     case NM_SHX:
19157     /*case NM_SHXS:*/
19158         check_nms(ctx);
19159         gen_load_gpr(t1, rd);
19160         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19161                            MO_TEUW);
19162         break;
19163     case NM_SWX:
19164     /*case NM_SWXS:*/
19165         check_nms(ctx);
19166         gen_load_gpr(t1, rd);
19167         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19168                            MO_TEUL);
19169         break;
19170     case NM_LWC1X:
19171     /*case NM_LWC1XS:*/
19172     case NM_LDC1X:
19173     /*case NM_LDC1XS:*/
19174     case NM_SWC1X:
19175     /*case NM_SWC1XS:*/
19176     case NM_SDC1X:
19177     /*case NM_SDC1XS:*/
19178         if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
19179             check_cp1_enabled(ctx);
19180             switch (extract32(ctx->opcode, 7, 4)) {
19181             case NM_LWC1X:
19182             /*case NM_LWC1XS:*/
19183                 gen_flt_ldst(ctx, OPC_LWC1, rd, t0);
19184                 break;
19185             case NM_LDC1X:
19186             /*case NM_LDC1XS:*/
19187                 gen_flt_ldst(ctx, OPC_LDC1, rd, t0);
19188                 break;
19189             case NM_SWC1X:
19190             /*case NM_SWC1XS:*/
19191                 gen_flt_ldst(ctx, OPC_SWC1, rd, t0);
19192                 break;
19193             case NM_SDC1X:
19194             /*case NM_SDC1XS:*/
19195                 gen_flt_ldst(ctx, OPC_SDC1, rd, t0);
19196                 break;
19197             }
19198         } else {
19199             generate_exception_err(ctx, EXCP_CpU, 1);
19200         }
19201         break;
19202     default:
19203         generate_exception_end(ctx, EXCP_RI);
19204         break;
19205     }
19206
19207     tcg_temp_free(t0);
19208     tcg_temp_free(t1);
19209 }
19210
19211 static void gen_pool32f_nanomips_insn(DisasContext *ctx)
19212 {
19213     int rt, rs, rd;
19214
19215     rt = extract32(ctx->opcode, 21, 5);
19216     rs = extract32(ctx->opcode, 16, 5);
19217     rd = extract32(ctx->opcode, 11, 5);
19218
19219     if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) {
19220         generate_exception_end(ctx, EXCP_RI);
19221         return;
19222     }
19223     check_cp1_enabled(ctx);
19224     switch (extract32(ctx->opcode, 0, 3)) {
19225     case NM_POOL32F_0:
19226         switch (extract32(ctx->opcode, 3, 7)) {
19227         case NM_RINT_S:
19228             gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
19229             break;
19230         case NM_RINT_D:
19231             gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
19232             break;
19233         case NM_CLASS_S:
19234             gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
19235             break;
19236         case NM_CLASS_D:
19237             gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
19238             break;
19239         case NM_ADD_S:
19240             gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0);
19241             break;
19242         case NM_ADD_D:
19243             gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0);
19244             break;
19245         case NM_SUB_S:
19246             gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0);
19247             break;
19248         case NM_SUB_D:
19249             gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0);
19250             break;
19251         case NM_MUL_S:
19252             gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0);
19253             break;
19254         case NM_MUL_D:
19255             gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0);
19256             break;
19257         case NM_DIV_S:
19258             gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0);
19259             break;
19260         case NM_DIV_D:
19261             gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0);
19262             break;
19263         case NM_SELEQZ_S:
19264             gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
19265             break;
19266         case NM_SELEQZ_D:
19267             gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
19268             break;
19269         case NM_SELNEZ_S:
19270             gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
19271             break;
19272         case NM_SELNEZ_D:
19273             gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
19274             break;
19275         case NM_SEL_S:
19276             gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
19277             break;
19278         case NM_SEL_D:
19279             gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
19280             break;
19281         case NM_MADDF_S:
19282             gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0);
19283             break;
19284         case NM_MADDF_D:
19285             gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0);
19286             break;
19287         case NM_MSUBF_S:
19288             gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0);
19289             break;
19290         case NM_MSUBF_D:
19291             gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0);
19292             break;
19293         default:
19294             generate_exception_end(ctx, EXCP_RI);
19295             break;
19296         }
19297         break;
19298     case NM_POOL32F_3:
19299         switch (extract32(ctx->opcode, 3, 3)) {
19300         case NM_MIN_FMT:
19301             switch (extract32(ctx->opcode, 9, 1)) {
19302             case FMT_SDPS_S:
19303                 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
19304                 break;
19305             case FMT_SDPS_D:
19306                 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
19307                 break;
19308             }
19309             break;
19310         case NM_MAX_FMT:
19311             switch (extract32(ctx->opcode, 9, 1)) {
19312             case FMT_SDPS_S:
19313                 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
19314                 break;
19315             case FMT_SDPS_D:
19316                 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
19317                 break;
19318             }
19319             break;
19320         case NM_MINA_FMT:
19321             switch (extract32(ctx->opcode, 9, 1)) {
19322             case FMT_SDPS_S:
19323                 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
19324                 break;
19325             case FMT_SDPS_D:
19326                 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
19327                 break;
19328             }
19329             break;
19330         case NM_MAXA_FMT:
19331             switch (extract32(ctx->opcode, 9, 1)) {
19332             case FMT_SDPS_S:
19333                 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
19334                 break;
19335             case FMT_SDPS_D:
19336                 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
19337                 break;
19338             }
19339             break;
19340         case NM_POOL32FXF:
19341             switch (extract32(ctx->opcode, 6, 8)) {
19342             case NM_CFC1:
19343                 gen_cp1(ctx, OPC_CFC1, rt, rs);
19344                 break;
19345             case NM_CTC1:
19346                 gen_cp1(ctx, OPC_CTC1, rt, rs);
19347                 break;
19348             case NM_MFC1:
19349                 gen_cp1(ctx, OPC_MFC1, rt, rs);
19350                 break;
19351             case NM_MTC1:
19352                 gen_cp1(ctx, OPC_MTC1, rt, rs);
19353                 break;
19354             case NM_MFHC1:
19355                 gen_cp1(ctx, OPC_MFHC1, rt, rs);
19356                 break;
19357             case NM_MTHC1:
19358                 gen_cp1(ctx, OPC_MTHC1, rt, rs);
19359                 break;
19360             case NM_CVT_S_PL:
19361                 gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0);
19362                 break;
19363             case NM_CVT_S_PU:
19364                 gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0);
19365                 break;
19366             default:
19367                 switch (extract32(ctx->opcode, 6, 9)) {
19368                 case NM_CVT_L_S:
19369                     gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0);
19370                     break;
19371                 case NM_CVT_L_D:
19372                     gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0);
19373                     break;
19374                 case NM_CVT_W_S:
19375                     gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0);
19376                     break;
19377                 case NM_CVT_W_D:
19378                     gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0);
19379                     break;
19380                 case NM_RSQRT_S:
19381                     gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0);
19382                     break;
19383                 case NM_RSQRT_D:
19384                     gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0);
19385                     break;
19386                 case NM_SQRT_S:
19387                     gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0);
19388                     break;
19389                 case NM_SQRT_D:
19390                     gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0);
19391                     break;
19392                 case NM_RECIP_S:
19393                     gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0);
19394                     break;
19395                 case NM_RECIP_D:
19396                     gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0);
19397                     break;
19398                 case NM_FLOOR_L_S:
19399                     gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0);
19400                     break;
19401                 case NM_FLOOR_L_D:
19402                     gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0);
19403                     break;
19404                 case NM_FLOOR_W_S:
19405                     gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0);
19406                     break;
19407                 case NM_FLOOR_W_D:
19408                     gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0);
19409                     break;
19410                 case NM_CEIL_L_S:
19411                     gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0);
19412                     break;
19413                 case NM_CEIL_L_D:
19414                     gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0);
19415                     break;
19416                 case NM_CEIL_W_S:
19417                     gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0);
19418                     break;
19419                 case NM_CEIL_W_D:
19420                     gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0);
19421                     break;
19422                 case NM_TRUNC_L_S:
19423                     gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0);
19424                     break;
19425                 case NM_TRUNC_L_D:
19426                     gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0);
19427                     break;
19428                 case NM_TRUNC_W_S:
19429                     gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0);
19430                     break;
19431                 case NM_TRUNC_W_D:
19432                     gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0);
19433                     break;
19434                 case NM_ROUND_L_S:
19435                     gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0);
19436                     break;
19437                 case NM_ROUND_L_D:
19438                     gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0);
19439                     break;
19440                 case NM_ROUND_W_S:
19441                     gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0);
19442                     break;
19443                 case NM_ROUND_W_D:
19444                     gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0);
19445                     break;
19446                 case NM_MOV_S:
19447                     gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0);
19448                     break;
19449                 case NM_MOV_D:
19450                     gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0);
19451                     break;
19452                 case NM_ABS_S:
19453                     gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0);
19454                     break;
19455                 case NM_ABS_D:
19456                     gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0);
19457                     break;
19458                 case NM_NEG_S:
19459                     gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0);
19460                     break;
19461                 case NM_NEG_D:
19462                     gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0);
19463                     break;
19464                 case NM_CVT_D_S:
19465                     gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0);
19466                     break;
19467                 case NM_CVT_D_W:
19468                     gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0);
19469                     break;
19470                 case NM_CVT_D_L:
19471                     gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0);
19472                     break;
19473                 case NM_CVT_S_D:
19474                     gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0);
19475                     break;
19476                 case NM_CVT_S_W:
19477                     gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0);
19478                     break;
19479                 case NM_CVT_S_L:
19480                     gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0);
19481                     break;
19482                 default:
19483                     generate_exception_end(ctx, EXCP_RI);
19484                     break;
19485                 }
19486                 break;
19487             }
19488             break;
19489         }
19490         break;
19491     case NM_POOL32F_5:
19492         switch (extract32(ctx->opcode, 3, 3)) {
19493         case NM_CMP_CONDN_S:
19494             gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
19495             break;
19496         case NM_CMP_CONDN_D:
19497             gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
19498             break;
19499         default:
19500             generate_exception_end(ctx, EXCP_RI);
19501             break;
19502         }
19503         break;
19504     default:
19505         generate_exception_end(ctx, EXCP_RI);
19506         break;
19507     }
19508 }
19509
19510 static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc,
19511                                        int rd, int rs, int rt)
19512 {
19513     int ret = rd;
19514     TCGv t0 = tcg_temp_new();
19515     TCGv v1_t = tcg_temp_new();
19516     TCGv v2_t = tcg_temp_new();
19517
19518     gen_load_gpr(v1_t, rs);
19519     gen_load_gpr(v2_t, rt);
19520
19521     switch (opc) {
19522     case NM_CMP_EQ_PH:
19523         check_dsp(ctx);
19524         gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
19525         break;
19526     case NM_CMP_LT_PH:
19527         check_dsp(ctx);
19528         gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
19529         break;
19530     case NM_CMP_LE_PH:
19531         check_dsp(ctx);
19532         gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
19533         break;
19534     case NM_CMPU_EQ_QB:
19535         check_dsp(ctx);
19536         gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
19537         break;
19538     case NM_CMPU_LT_QB:
19539         check_dsp(ctx);
19540         gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
19541         break;
19542     case NM_CMPU_LE_QB:
19543         check_dsp(ctx);
19544         gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
19545         break;
19546     case NM_CMPGU_EQ_QB:
19547         check_dsp(ctx);
19548         gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
19549         gen_store_gpr(v1_t, ret);
19550         break;
19551     case NM_CMPGU_LT_QB:
19552         check_dsp(ctx);
19553         gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
19554         gen_store_gpr(v1_t, ret);
19555         break;
19556     case NM_CMPGU_LE_QB:
19557         check_dsp(ctx);
19558         gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
19559         gen_store_gpr(v1_t, ret);
19560         break;
19561     case NM_CMPGDU_EQ_QB:
19562         check_dsp_r2(ctx);
19563         gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
19564         tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
19565         gen_store_gpr(v1_t, ret);
19566         break;
19567     case NM_CMPGDU_LT_QB:
19568         check_dsp_r2(ctx);
19569         gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
19570         tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
19571         gen_store_gpr(v1_t, ret);
19572         break;
19573     case NM_CMPGDU_LE_QB:
19574         check_dsp_r2(ctx);
19575         gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
19576         tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
19577         gen_store_gpr(v1_t, ret);
19578         break;
19579     case NM_PACKRL_PH:
19580         check_dsp(ctx);
19581         gen_helper_packrl_ph(v1_t, v1_t, v2_t);
19582         gen_store_gpr(v1_t, ret);
19583         break;
19584     case NM_PICK_QB:
19585         check_dsp(ctx);
19586         gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env);
19587         gen_store_gpr(v1_t, ret);
19588         break;
19589     case NM_PICK_PH:
19590         check_dsp(ctx);
19591         gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env);
19592         gen_store_gpr(v1_t, ret);
19593         break;
19594     case NM_ADDQ_S_W:
19595         check_dsp(ctx);
19596         gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env);
19597         gen_store_gpr(v1_t, ret);
19598         break;
19599     case NM_SUBQ_S_W:
19600         check_dsp(ctx);
19601         gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env);
19602         gen_store_gpr(v1_t, ret);
19603         break;
19604     case NM_ADDSC:
19605         check_dsp(ctx);
19606         gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env);
19607         gen_store_gpr(v1_t, ret);
19608         break;
19609     case NM_ADDWC:
19610         check_dsp(ctx);
19611         gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env);
19612         gen_store_gpr(v1_t, ret);
19613         break;
19614     case NM_ADDQ_S_PH:
19615         check_dsp(ctx);
19616         switch (extract32(ctx->opcode, 10, 1)) {
19617         case 0:
19618             /* ADDQ_PH */
19619             gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env);
19620             gen_store_gpr(v1_t, ret);
19621             break;
19622         case 1:
19623             /* ADDQ_S_PH */
19624             gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env);
19625             gen_store_gpr(v1_t, ret);
19626             break;
19627         }
19628         break;
19629     case NM_ADDQH_R_PH:
19630         check_dsp_r2(ctx);
19631         switch (extract32(ctx->opcode, 10, 1)) {
19632         case 0:
19633             /* ADDQH_PH */
19634             gen_helper_addqh_ph(v1_t, v1_t, v2_t);
19635             gen_store_gpr(v1_t, ret);
19636             break;
19637         case 1:
19638             /* ADDQH_R_PH */
19639             gen_helper_addqh_r_ph(v1_t, v1_t, v2_t);
19640             gen_store_gpr(v1_t, ret);
19641             break;
19642         }
19643         break;
19644     case NM_ADDQH_R_W:
19645         check_dsp_r2(ctx);
19646         switch (extract32(ctx->opcode, 10, 1)) {
19647         case 0:
19648             /* ADDQH_W */
19649             gen_helper_addqh_w(v1_t, v1_t, v2_t);
19650             gen_store_gpr(v1_t, ret);
19651             break;
19652         case 1:
19653             /* ADDQH_R_W */
19654             gen_helper_addqh_r_w(v1_t, v1_t, v2_t);
19655             gen_store_gpr(v1_t, ret);
19656             break;
19657         }
19658         break;
19659     case NM_ADDU_S_QB:
19660         check_dsp(ctx);
19661         switch (extract32(ctx->opcode, 10, 1)) {
19662         case 0:
19663             /* ADDU_QB */
19664             gen_helper_addu_qb(v1_t, v1_t, v2_t, cpu_env);
19665             gen_store_gpr(v1_t, ret);
19666             break;
19667         case 1:
19668             /* ADDU_S_QB */
19669             gen_helper_addu_s_qb(v1_t, v1_t, v2_t, cpu_env);
19670             gen_store_gpr(v1_t, ret);
19671             break;
19672         }
19673         break;
19674     case NM_ADDU_S_PH:
19675         check_dsp_r2(ctx);
19676         switch (extract32(ctx->opcode, 10, 1)) {
19677         case 0:
19678             /* ADDU_PH */
19679             gen_helper_addu_ph(v1_t, v1_t, v2_t, cpu_env);
19680             gen_store_gpr(v1_t, ret);
19681             break;
19682         case 1:
19683             /* ADDU_S_PH */
19684             gen_helper_addu_s_ph(v1_t, v1_t, v2_t, cpu_env);
19685             gen_store_gpr(v1_t, ret);
19686             break;
19687         }
19688         break;
19689     case NM_ADDUH_R_QB:
19690         check_dsp_r2(ctx);
19691         switch (extract32(ctx->opcode, 10, 1)) {
19692         case 0:
19693             /* ADDUH_QB */
19694             gen_helper_adduh_qb(v1_t, v1_t, v2_t);
19695             gen_store_gpr(v1_t, ret);
19696             break;
19697         case 1:
19698             /* ADDUH_R_QB */
19699             gen_helper_adduh_r_qb(v1_t, v1_t, v2_t);
19700             gen_store_gpr(v1_t, ret);
19701             break;
19702         }
19703         break;
19704     case NM_SHRAV_R_PH:
19705         check_dsp(ctx);
19706         switch (extract32(ctx->opcode, 10, 1)) {
19707         case 0:
19708             /* SHRAV_PH */
19709             gen_helper_shra_ph(v1_t, v1_t, v2_t);
19710             gen_store_gpr(v1_t, ret);
19711             break;
19712         case 1:
19713             /* SHRAV_R_PH */
19714             gen_helper_shra_r_ph(v1_t, v1_t, v2_t);
19715             gen_store_gpr(v1_t, ret);
19716             break;
19717         }
19718         break;
19719     case NM_SHRAV_R_QB:
19720         check_dsp_r2(ctx);
19721         switch (extract32(ctx->opcode, 10, 1)) {
19722         case 0:
19723             /* SHRAV_QB */
19724             gen_helper_shra_qb(v1_t, v1_t, v2_t);
19725             gen_store_gpr(v1_t, ret);
19726             break;
19727         case 1:
19728             /* SHRAV_R_QB */
19729             gen_helper_shra_r_qb(v1_t, v1_t, v2_t);
19730             gen_store_gpr(v1_t, ret);
19731             break;
19732         }
19733         break;
19734     case NM_SUBQ_S_PH:
19735         check_dsp(ctx);
19736         switch (extract32(ctx->opcode, 10, 1)) {
19737         case 0:
19738             /* SUBQ_PH */
19739             gen_helper_subq_ph(v1_t, v1_t, v2_t, cpu_env);
19740             gen_store_gpr(v1_t, ret);
19741             break;
19742         case 1:
19743             /* SUBQ_S_PH */
19744             gen_helper_subq_s_ph(v1_t, v1_t, v2_t, cpu_env);
19745             gen_store_gpr(v1_t, ret);
19746             break;
19747         }
19748         break;
19749     case NM_SUBQH_R_PH:
19750         check_dsp_r2(ctx);
19751         switch (extract32(ctx->opcode, 10, 1)) {
19752         case 0:
19753             /* SUBQH_PH */
19754             gen_helper_subqh_ph(v1_t, v1_t, v2_t);
19755             gen_store_gpr(v1_t, ret);
19756             break;
19757         case 1:
19758             /* SUBQH_R_PH */
19759             gen_helper_subqh_r_ph(v1_t, v1_t, v2_t);
19760             gen_store_gpr(v1_t, ret);
19761             break;
19762         }
19763         break;
19764     case NM_SUBQH_R_W:
19765         check_dsp_r2(ctx);
19766         switch (extract32(ctx->opcode, 10, 1)) {
19767         case 0:
19768             /* SUBQH_W */
19769             gen_helper_subqh_w(v1_t, v1_t, v2_t);
19770             gen_store_gpr(v1_t, ret);
19771             break;
19772         case 1:
19773             /* SUBQH_R_W */
19774             gen_helper_subqh_r_w(v1_t, v1_t, v2_t);
19775             gen_store_gpr(v1_t, ret);
19776             break;
19777         }
19778         break;
19779     case NM_SUBU_S_QB:
19780         check_dsp(ctx);
19781         switch (extract32(ctx->opcode, 10, 1)) {
19782         case 0:
19783             /* SUBU_QB */
19784             gen_helper_subu_qb(v1_t, v1_t, v2_t, cpu_env);
19785             gen_store_gpr(v1_t, ret);
19786             break;
19787         case 1:
19788             /* SUBU_S_QB */
19789             gen_helper_subu_s_qb(v1_t, v1_t, v2_t, cpu_env);
19790             gen_store_gpr(v1_t, ret);
19791             break;
19792         }
19793         break;
19794     case NM_SUBU_S_PH:
19795         check_dsp_r2(ctx);
19796         switch (extract32(ctx->opcode, 10, 1)) {
19797         case 0:
19798             /* SUBU_PH */
19799             gen_helper_subu_ph(v1_t, v1_t, v2_t, cpu_env);
19800             gen_store_gpr(v1_t, ret);
19801             break;
19802         case 1:
19803             /* SUBU_S_PH */
19804             gen_helper_subu_s_ph(v1_t, v1_t, v2_t, cpu_env);
19805             gen_store_gpr(v1_t, ret);
19806             break;
19807         }
19808         break;
19809     case NM_SUBUH_R_QB:
19810         check_dsp_r2(ctx);
19811         switch (extract32(ctx->opcode, 10, 1)) {
19812         case 0:
19813             /* SUBUH_QB */
19814             gen_helper_subuh_qb(v1_t, v1_t, v2_t);
19815             gen_store_gpr(v1_t, ret);
19816             break;
19817         case 1:
19818             /* SUBUH_R_QB */
19819             gen_helper_subuh_r_qb(v1_t, v1_t, v2_t);
19820             gen_store_gpr(v1_t, ret);
19821             break;
19822         }
19823         break;
19824     case NM_SHLLV_S_PH:
19825         check_dsp(ctx);
19826         switch (extract32(ctx->opcode, 10, 1)) {
19827         case 0:
19828             /* SHLLV_PH */
19829             gen_helper_shll_ph(v1_t, v1_t, v2_t, cpu_env);
19830             gen_store_gpr(v1_t, ret);
19831             break;
19832         case 1:
19833             /* SHLLV_S_PH */
19834             gen_helper_shll_s_ph(v1_t, v1_t, v2_t, cpu_env);
19835             gen_store_gpr(v1_t, ret);
19836             break;
19837         }
19838         break;
19839     case NM_PRECR_SRA_R_PH_W:
19840         check_dsp_r2(ctx);
19841         switch (extract32(ctx->opcode, 10, 1)) {
19842         case 0:
19843             /* PRECR_SRA_PH_W */
19844             {
19845                 TCGv_i32 sa_t = tcg_const_i32(rd);
19846                 gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t,
19847                                           cpu_gpr[rt]);
19848                 gen_store_gpr(v1_t, rt);
19849                 tcg_temp_free_i32(sa_t);
19850             }
19851             break;
19852         case 1:
19853             /* PRECR_SRA_R_PH_W */
19854             {
19855                 TCGv_i32 sa_t = tcg_const_i32(rd);
19856                 gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t,
19857                                             cpu_gpr[rt]);
19858                 gen_store_gpr(v1_t, rt);
19859                 tcg_temp_free_i32(sa_t);
19860             }
19861             break;
19862        }
19863         break;
19864     case NM_MULEU_S_PH_QBL:
19865         check_dsp(ctx);
19866         gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, cpu_env);
19867         gen_store_gpr(v1_t, ret);
19868         break;
19869     case NM_MULEU_S_PH_QBR:
19870         check_dsp(ctx);
19871         gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, cpu_env);
19872         gen_store_gpr(v1_t, ret);
19873         break;
19874     case NM_MULQ_RS_PH:
19875         check_dsp(ctx);
19876         gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, cpu_env);
19877         gen_store_gpr(v1_t, ret);
19878         break;
19879     case NM_MULQ_S_PH:
19880         check_dsp_r2(ctx);
19881         gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, cpu_env);
19882         gen_store_gpr(v1_t, ret);
19883         break;
19884     case NM_MULQ_RS_W:
19885         check_dsp_r2(ctx);
19886         gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, cpu_env);
19887         gen_store_gpr(v1_t, ret);
19888         break;
19889     case NM_MULQ_S_W:
19890         check_dsp_r2(ctx);
19891         gen_helper_mulq_s_w(v1_t, v1_t, v2_t, cpu_env);
19892         gen_store_gpr(v1_t, ret);
19893         break;
19894     case NM_APPEND:
19895         check_dsp_r2(ctx);
19896         gen_load_gpr(t0, rs);
19897         if (rd != 0) {
19898             tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd);
19899         }
19900         tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
19901         break;
19902     case NM_MODSUB:
19903         check_dsp(ctx);
19904         gen_helper_modsub(v1_t, v1_t, v2_t);
19905         gen_store_gpr(v1_t, ret);
19906         break;
19907     case NM_SHRAV_R_W:
19908         check_dsp(ctx);
19909         gen_helper_shra_r_w(v1_t, v1_t, v2_t);
19910         gen_store_gpr(v1_t, ret);
19911         break;
19912     case NM_SHRLV_PH:
19913         check_dsp_r2(ctx);
19914         gen_helper_shrl_ph(v1_t, v1_t, v2_t);
19915         gen_store_gpr(v1_t, ret);
19916         break;
19917     case NM_SHRLV_QB:
19918         check_dsp(ctx);
19919         gen_helper_shrl_qb(v1_t, v1_t, v2_t);
19920         gen_store_gpr(v1_t, ret);
19921         break;
19922     case NM_SHLLV_QB:
19923         check_dsp(ctx);
19924         gen_helper_shll_qb(v1_t, v1_t, v2_t, cpu_env);
19925         gen_store_gpr(v1_t, ret);
19926         break;
19927     case NM_SHLLV_S_W:
19928         check_dsp(ctx);
19929         gen_helper_shll_s_w(v1_t, v1_t, v2_t, cpu_env);
19930         gen_store_gpr(v1_t, ret);
19931         break;
19932     case NM_SHILO:
19933         check_dsp(ctx);
19934         {
19935             TCGv tv0 = tcg_temp_new();
19936             TCGv tv1 = tcg_temp_new();
19937             int16_t imm = extract32(ctx->opcode, 16, 7);
19938
19939             tcg_gen_movi_tl(tv0, rd >> 3);
19940             tcg_gen_movi_tl(tv1, imm);
19941             gen_helper_shilo(tv0, tv1, cpu_env);
19942         }
19943         break;
19944     case NM_MULEQ_S_W_PHL:
19945         check_dsp(ctx);
19946         gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, cpu_env);
19947         gen_store_gpr(v1_t, ret);
19948         break;
19949     case NM_MULEQ_S_W_PHR:
19950         check_dsp(ctx);
19951         gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, cpu_env);
19952         gen_store_gpr(v1_t, ret);
19953         break;
19954     case NM_MUL_S_PH:
19955         check_dsp_r2(ctx);
19956         switch (extract32(ctx->opcode, 10, 1)) {
19957         case 0:
19958             /* MUL_PH */
19959             gen_helper_mul_ph(v1_t, v1_t, v2_t, cpu_env);
19960             gen_store_gpr(v1_t, ret);
19961             break;
19962         case 1:
19963             /* MUL_S_PH */
19964             gen_helper_mul_s_ph(v1_t, v1_t, v2_t, cpu_env);
19965             gen_store_gpr(v1_t, ret);
19966             break;
19967         }
19968         break;
19969     case NM_PRECR_QB_PH:
19970         check_dsp_r2(ctx);
19971         gen_helper_precr_qb_ph(v1_t, v1_t, v2_t);
19972         gen_store_gpr(v1_t, ret);
19973         break;
19974     case NM_PRECRQ_QB_PH:
19975         check_dsp(ctx);
19976         gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t);
19977         gen_store_gpr(v1_t, ret);
19978         break;
19979     case NM_PRECRQ_PH_W:
19980         check_dsp(ctx);
19981         gen_helper_precrq_ph_w(v1_t, v1_t, v2_t);
19982         gen_store_gpr(v1_t, ret);
19983         break;
19984     case NM_PRECRQ_RS_PH_W:
19985         check_dsp(ctx);
19986         gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, cpu_env);
19987         gen_store_gpr(v1_t, ret);
19988         break;
19989     case NM_PRECRQU_S_QB_PH:
19990         check_dsp(ctx);
19991         gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, cpu_env);
19992         gen_store_gpr(v1_t, ret);
19993         break;
19994     case NM_SHRA_R_W:
19995         check_dsp(ctx);
19996         tcg_gen_movi_tl(t0, rd);
19997         gen_helper_shra_r_w(v1_t, t0, v1_t);
19998         gen_store_gpr(v1_t, rt);
19999         break;
20000     case NM_SHRA_R_PH:
20001         check_dsp(ctx);
20002         tcg_gen_movi_tl(t0, rd >> 1);
20003         switch (extract32(ctx->opcode, 10, 1)) {
20004         case 0:
20005             /* SHRA_PH */
20006             gen_helper_shra_ph(v1_t, t0, v1_t);
20007             gen_store_gpr(v1_t, rt);
20008             break;
20009         case 1:
20010             /* SHRA_R_PH */
20011             gen_helper_shra_r_ph(v1_t, t0, v1_t);
20012             gen_store_gpr(v1_t, rt);
20013             break;
20014         }
20015         break;
20016     case NM_SHLL_S_PH:
20017         check_dsp(ctx);
20018         tcg_gen_movi_tl(t0, rd >> 1);
20019         switch (extract32(ctx->opcode, 10, 2)) {
20020         case 0:
20021             /* SHLL_PH */
20022             gen_helper_shll_ph(v1_t, t0, v1_t, cpu_env);
20023             gen_store_gpr(v1_t, rt);
20024             break;
20025         case 2:
20026             /* SHLL_S_PH */
20027             gen_helper_shll_s_ph(v1_t, t0, v1_t, cpu_env);
20028             gen_store_gpr(v1_t, rt);
20029             break;
20030         default:
20031             generate_exception_end(ctx, EXCP_RI);
20032             break;
20033         }
20034         break;
20035     case NM_SHLL_S_W:
20036         check_dsp(ctx);
20037         tcg_gen_movi_tl(t0, rd);
20038         gen_helper_shll_s_w(v1_t, t0, v1_t, cpu_env);
20039         gen_store_gpr(v1_t, rt);
20040         break;
20041     case NM_REPL_PH:
20042         check_dsp(ctx);
20043         {
20044             int16_t imm;
20045             imm = sextract32(ctx->opcode, 11, 11);
20046             imm = (int16_t)(imm << 6) >> 6;
20047             if (rt != 0) {
20048                 tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm));
20049             }
20050         }
20051         break;
20052     default:
20053         generate_exception_end(ctx, EXCP_RI);
20054         break;
20055     }
20056 }
20057
20058 static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
20059 {
20060     uint16_t insn;
20061     uint32_t op;
20062     int rt, rs, rd;
20063     int offset;
20064     int imm;
20065
20066     insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
20067     ctx->opcode = (ctx->opcode << 16) | insn;
20068
20069     rt = extract32(ctx->opcode, 21, 5);
20070     rs = extract32(ctx->opcode, 16, 5);
20071     rd = extract32(ctx->opcode, 11, 5);
20072
20073     op = extract32(ctx->opcode, 26, 6);
20074     switch (op) {
20075     case NM_P_ADDIU:
20076         if (rt == 0) {
20077             /* P.RI */
20078             switch (extract32(ctx->opcode, 19, 2)) {
20079             case NM_SIGRIE:
20080             default:
20081                 generate_exception_end(ctx, EXCP_RI);
20082                 break;
20083             case NM_P_SYSCALL:
20084                 if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) {
20085                     generate_exception_end(ctx, EXCP_SYSCALL);
20086                 } else {
20087                     generate_exception_end(ctx, EXCP_RI);
20088                 }
20089                 break;
20090             case NM_BREAK:
20091                 generate_exception_end(ctx, EXCP_BREAK);
20092                 break;
20093             case NM_SDBBP:
20094                 if (is_uhi(extract32(ctx->opcode, 0, 19))) {
20095                     gen_helper_do_semihosting(cpu_env);
20096                 } else {
20097                     if (ctx->hflags & MIPS_HFLAG_SBRI) {
20098                         generate_exception_end(ctx, EXCP_RI);
20099                     } else {
20100                         generate_exception_end(ctx, EXCP_DBp);
20101                     }
20102                 }
20103                 break;
20104             }
20105         } else {
20106             /* NM_ADDIU */
20107             imm = extract32(ctx->opcode, 0, 16);
20108             if (rs != 0) {
20109                 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm);
20110             } else {
20111                 tcg_gen_movi_tl(cpu_gpr[rt], imm);
20112             }
20113             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20114         }
20115         break;
20116     case NM_ADDIUPC:
20117         if (rt != 0) {
20118             offset = sextract32(ctx->opcode, 0, 1) << 21 |
20119                      extract32(ctx->opcode, 1, 20) << 1;
20120             target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset);
20121             tcg_gen_movi_tl(cpu_gpr[rt], addr);
20122         }
20123         break;
20124     case NM_POOL32A:
20125         switch (ctx->opcode & 0x07) {
20126         case NM_POOL32A0:
20127             gen_pool32a0_nanomips_insn(env, ctx);
20128             break;
20129         case NM_POOL32A5:
20130             {
20131                 int32_t op1 = extract32(ctx->opcode, 3, 7);
20132                 gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt);
20133             }
20134             break;
20135         case NM_POOL32A7:
20136             switch (extract32(ctx->opcode, 3, 3)) {
20137             case NM_P_LSX:
20138                 gen_p_lsx(ctx, rd, rs, rt);
20139                 break;
20140             case NM_LSA:
20141                 /* In nanoMIPS, the shift field directly encodes the shift
20142                  * amount, meaning that the supported shift values are in
20143                  * the range 0 to 3 (instead of 1 to 4 in MIPSR6). */
20144                 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
20145                         extract32(ctx->opcode, 9, 2) - 1);
20146                 break;
20147             case NM_EXTW:
20148                 gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5));
20149                 break;
20150             case NM_POOL32AXF:
20151                 gen_pool32axf_nanomips_insn(env, ctx);
20152                 break;
20153             default:
20154                 generate_exception_end(ctx, EXCP_RI);
20155                 break;
20156             }
20157             break;
20158         default:
20159             generate_exception_end(ctx, EXCP_RI);
20160             break;
20161         }
20162         break;
20163     case NM_P_GP_W:
20164         switch (ctx->opcode & 0x03) {
20165         case NM_ADDIUGP_W:
20166             if (rt != 0) {
20167                 offset = extract32(ctx->opcode, 0, 21);
20168                 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset);
20169             }
20170             break;
20171         case NM_LWGP:
20172             gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
20173             break;
20174         case NM_SWGP:
20175             gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
20176             break;
20177         default:
20178             generate_exception_end(ctx, EXCP_RI);
20179             break;
20180         }
20181         break;
20182     case NM_P48I:
20183         {
20184             insn = cpu_lduw_code(env, ctx->base.pc_next + 4);
20185             target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16;
20186             switch (extract32(ctx->opcode, 16, 5)) {
20187             case NM_LI48:
20188                 check_nms(ctx);
20189                 if (rt != 0) {
20190                     tcg_gen_movi_tl(cpu_gpr[rt], addr_off);
20191                 }
20192                 break;
20193             case NM_ADDIU48:
20194                 check_nms(ctx);
20195                 if (rt != 0) {
20196                     tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off);
20197                     tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20198                 }
20199                 break;
20200             case NM_ADDIUGP48:
20201                 check_nms(ctx);
20202                 if (rt != 0) {
20203                     gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_off);
20204                 }
20205                 break;
20206             case NM_ADDIUPC48:
20207                 check_nms(ctx);
20208                 if (rt != 0) {
20209                     target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20210                                                 addr_off);
20211
20212                     tcg_gen_movi_tl(cpu_gpr[rt], addr);
20213                 }
20214                 break;
20215             case NM_LWPC48:
20216                 check_nms(ctx);
20217                 if (rt != 0) {
20218                     TCGv t0;
20219                     t0 = tcg_temp_new();
20220
20221                     target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20222                                                 addr_off);
20223
20224                     tcg_gen_movi_tl(t0, addr);
20225                     tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_TESL);
20226                     tcg_temp_free(t0);
20227                 }
20228                 break;
20229             case NM_SWPC48:
20230                 check_nms(ctx);
20231                 {
20232                     TCGv t0, t1;
20233                     t0 = tcg_temp_new();
20234                     t1 = tcg_temp_new();
20235
20236                     target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20237                                                 addr_off);
20238
20239                     tcg_gen_movi_tl(t0, addr);
20240                     gen_load_gpr(t1, rt);
20241
20242                     tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
20243
20244                     tcg_temp_free(t0);
20245                     tcg_temp_free(t1);
20246                 }
20247                 break;
20248             default:
20249                 generate_exception_end(ctx, EXCP_RI);
20250                 break;
20251             }
20252             return 6;
20253         }
20254     case NM_P_U12:
20255         switch (extract32(ctx->opcode, 12, 4)) {
20256         case NM_ORI:
20257             gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12));
20258             break;
20259         case NM_XORI:
20260             gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12));
20261             break;
20262         case NM_ANDI:
20263             gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12));
20264             break;
20265         case NM_P_SR:
20266             switch (extract32(ctx->opcode, 20, 1)) {
20267             case NM_PP_SR:
20268                 switch (ctx->opcode & 3) {
20269                 case NM_SAVE:
20270                     gen_save(ctx, rt, extract32(ctx->opcode, 16, 4),
20271                              extract32(ctx->opcode, 2, 1),
20272                              extract32(ctx->opcode, 3, 9) << 3);
20273                     break;
20274                 case NM_RESTORE:
20275                 case NM_RESTORE_JRC:
20276                     gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4),
20277                                 extract32(ctx->opcode, 2, 1),
20278                                 extract32(ctx->opcode, 3, 9) << 3);
20279                     if ((ctx->opcode & 3) == NM_RESTORE_JRC) {
20280                         gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
20281                     }
20282                     break;
20283                 default:
20284                     generate_exception_end(ctx, EXCP_RI);
20285                     break;
20286                 }
20287                 break;
20288             case NM_P_SR_F:
20289                 generate_exception_end(ctx, EXCP_RI);
20290                 break;
20291             }
20292             break;
20293         case NM_SLTI:
20294             gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12));
20295             break;
20296         case NM_SLTIU:
20297             gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12));
20298             break;
20299         case NM_SEQI:
20300             {
20301                 TCGv t0 = tcg_temp_new();
20302
20303                 imm = extract32(ctx->opcode, 0, 12);
20304                 gen_load_gpr(t0, rs);
20305                 tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm);
20306                 gen_store_gpr(t0, rt);
20307
20308                 tcg_temp_free(t0);
20309             }
20310             break;
20311         case NM_ADDIUNEG:
20312             imm = (int16_t) extract32(ctx->opcode, 0, 12);
20313             gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm);
20314             break;
20315         case NM_P_SHIFT:
20316             {
20317                 int shift = extract32(ctx->opcode, 0, 5);
20318                 switch (extract32(ctx->opcode, 5, 4)) {
20319                 case NM_P_SLL:
20320                     if (rt == 0 && shift == 0) {
20321                         /* NOP */
20322                     } else if (rt == 0 && shift == 3) {
20323                         /* EHB - treat as NOP */
20324                     } else if (rt == 0 && shift == 5) {
20325                         /* PAUSE - treat as NOP */
20326                     } else if (rt == 0 && shift == 6) {
20327                         /* SYNC */
20328                         gen_sync(extract32(ctx->opcode, 16, 5));
20329                     } else {
20330                         /* SLL */
20331                         gen_shift_imm(ctx, OPC_SLL, rt, rs,
20332                                       extract32(ctx->opcode, 0, 5));
20333                     }
20334                     break;
20335                 case NM_SRL:
20336                     gen_shift_imm(ctx, OPC_SRL, rt, rs,
20337                                   extract32(ctx->opcode, 0, 5));
20338                     break;
20339                 case NM_SRA:
20340                     gen_shift_imm(ctx, OPC_SRA, rt, rs,
20341                                   extract32(ctx->opcode, 0, 5));
20342                     break;
20343                 case NM_ROTR:
20344                     gen_shift_imm(ctx, OPC_ROTR, rt, rs,
20345                                   extract32(ctx->opcode, 0, 5));
20346                     break;
20347                 }
20348             }
20349             break;
20350         case NM_P_ROTX:
20351             check_nms(ctx);
20352             if (rt != 0) {
20353                 TCGv t0 = tcg_temp_new();
20354                 TCGv_i32 shift = tcg_const_i32(extract32(ctx->opcode, 0, 5));
20355                 TCGv_i32 shiftx = tcg_const_i32(extract32(ctx->opcode, 7, 4)
20356                                                 << 1);
20357                 TCGv_i32 stripe = tcg_const_i32(extract32(ctx->opcode, 6, 1));
20358
20359                 gen_load_gpr(t0, rs);
20360                 gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe);
20361                 tcg_temp_free(t0);
20362
20363                 tcg_temp_free_i32(shift);
20364                 tcg_temp_free_i32(shiftx);
20365                 tcg_temp_free_i32(stripe);
20366             }
20367             break;
20368         case NM_P_INS:
20369             switch (((ctx->opcode >> 10) & 2) |
20370                     (extract32(ctx->opcode, 5, 1))) {
20371             case NM_INS:
20372                 check_nms(ctx);
20373                 gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5),
20374                            extract32(ctx->opcode, 6, 5));
20375                 break;
20376             default:
20377                 generate_exception_end(ctx, EXCP_RI);
20378                 break;
20379             }
20380             break;
20381         case NM_P_EXT:
20382             switch (((ctx->opcode >> 10) & 2) |
20383                     (extract32(ctx->opcode, 5, 1))) {
20384             case NM_EXT:
20385                 check_nms(ctx);
20386                 gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5),
20387                            extract32(ctx->opcode, 6, 5));
20388                 break;
20389             default:
20390                 generate_exception_end(ctx, EXCP_RI);
20391                 break;
20392             }
20393             break;
20394         default:
20395             generate_exception_end(ctx, EXCP_RI);
20396             break;
20397         }
20398         break;
20399     case NM_POOL32F:
20400         gen_pool32f_nanomips_insn(ctx);
20401         break;
20402     case NM_POOL32S:
20403         break;
20404     case NM_P_LUI:
20405         switch (extract32(ctx->opcode, 1, 1)) {
20406         case NM_LUI:
20407             if (rt != 0) {
20408                 tcg_gen_movi_tl(cpu_gpr[rt],
20409                                 sextract32(ctx->opcode, 0, 1) << 31 |
20410                                 extract32(ctx->opcode, 2, 10) << 21 |
20411                                 extract32(ctx->opcode, 12, 9) << 12);
20412             }
20413             break;
20414         case NM_ALUIPC:
20415             if (rt != 0) {
20416                 offset = sextract32(ctx->opcode, 0, 1) << 31 |
20417                          extract32(ctx->opcode, 2, 10) << 21 |
20418                          extract32(ctx->opcode, 12, 9) << 12;
20419                 target_long addr;
20420                 addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset);
20421                 tcg_gen_movi_tl(cpu_gpr[rt], addr);
20422             }
20423             break;
20424         }
20425         break;
20426     case NM_P_GP_BH:
20427         {
20428             uint32_t u = extract32(ctx->opcode, 0, 18);
20429
20430             switch (extract32(ctx->opcode, 18, 3)) {
20431             case NM_LBGP:
20432                 gen_ld(ctx, OPC_LB, rt, 28, u);
20433                 break;
20434             case NM_SBGP:
20435                 gen_st(ctx, OPC_SB, rt, 28, u);
20436                 break;
20437             case NM_LBUGP:
20438                 gen_ld(ctx, OPC_LBU, rt, 28, u);
20439                 break;
20440             case NM_ADDIUGP_B:
20441                 if (rt != 0) {
20442                     gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u);
20443                 }
20444                 break;
20445             case NM_P_GP_LH:
20446                 u &= ~1;
20447                 switch (ctx->opcode & 1) {
20448                 case NM_LHGP:
20449                     gen_ld(ctx, OPC_LH, rt, 28, u);
20450                     break;
20451                 case NM_LHUGP:
20452                     gen_ld(ctx, OPC_LHU, rt, 28, u);
20453                     break;
20454                 }
20455                 break;
20456             case NM_P_GP_SH:
20457                 u &= ~1;
20458                 switch (ctx->opcode & 1) {
20459                 case NM_SHGP:
20460                     gen_st(ctx, OPC_SH, rt, 28, u);
20461                     break;
20462                 default:
20463                     generate_exception_end(ctx, EXCP_RI);
20464                     break;
20465                 }
20466                 break;
20467             case NM_P_GP_CP1:
20468                 u &= ~0x3;
20469                 switch (ctx->opcode & 0x3) {
20470                 case NM_LWC1GP:
20471                     gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u);
20472                     break;
20473                 case NM_LDC1GP:
20474                     gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u);
20475                     break;
20476                 case NM_SWC1GP:
20477                     gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u);
20478                     break;
20479                 case NM_SDC1GP:
20480                     gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u);
20481                     break;
20482                 }
20483                 break;
20484             default:
20485                 generate_exception_end(ctx, EXCP_RI);
20486                 break;
20487             }
20488         }
20489         break;
20490     case NM_P_LS_U12:
20491         {
20492             uint32_t u = extract32(ctx->opcode, 0, 12);
20493
20494             switch (extract32(ctx->opcode, 12, 4)) {
20495             case NM_P_PREFU12:
20496                 if (rt == 31) {
20497                     /* SYNCI */
20498                     /* Break the TB to be able to sync copied instructions
20499                        immediately */
20500                     ctx->base.is_jmp = DISAS_STOP;
20501                 } else {
20502                     /* PREF */
20503                     /* Treat as NOP. */
20504                 }
20505                 break;
20506             case NM_LB:
20507                 gen_ld(ctx, OPC_LB, rt, rs, u);
20508                 break;
20509             case NM_LH:
20510                 gen_ld(ctx, OPC_LH, rt, rs, u);
20511                 break;
20512             case NM_LW:
20513                 gen_ld(ctx, OPC_LW, rt, rs, u);
20514                 break;
20515             case NM_LBU:
20516                 gen_ld(ctx, OPC_LBU, rt, rs, u);
20517                 break;
20518             case NM_LHU:
20519                 gen_ld(ctx, OPC_LHU, rt, rs, u);
20520                 break;
20521             case NM_SB:
20522                 gen_st(ctx, OPC_SB, rt, rs, u);
20523                 break;
20524             case NM_SH:
20525                 gen_st(ctx, OPC_SH, rt, rs, u);
20526                 break;
20527             case NM_SW:
20528                 gen_st(ctx, OPC_SW, rt, rs, u);
20529                 break;
20530             case NM_LWC1:
20531                 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u);
20532                 break;
20533             case NM_LDC1:
20534                 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u);
20535                 break;
20536             case NM_SWC1:
20537                 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u);
20538                 break;
20539             case NM_SDC1:
20540                 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u);
20541                 break;
20542             default:
20543                 generate_exception_end(ctx, EXCP_RI);
20544                 break;
20545             }
20546         }
20547         break;
20548     case NM_P_LS_S9:
20549         {
20550             int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) |
20551                         extract32(ctx->opcode, 0, 8);
20552
20553             switch (extract32(ctx->opcode, 8, 3)) {
20554             case NM_P_LS_S0:
20555                 switch (extract32(ctx->opcode, 11, 4)) {
20556                 case NM_LBS9:
20557                     gen_ld(ctx, OPC_LB, rt, rs, s);
20558                     break;
20559                 case NM_LHS9:
20560                     gen_ld(ctx, OPC_LH, rt, rs, s);
20561                     break;
20562                 case NM_LWS9:
20563                     gen_ld(ctx, OPC_LW, rt, rs, s);
20564                     break;
20565                 case NM_LBUS9:
20566                     gen_ld(ctx, OPC_LBU, rt, rs, s);
20567                     break;
20568                 case NM_LHUS9:
20569                     gen_ld(ctx, OPC_LHU, rt, rs, s);
20570                     break;
20571                 case NM_SBS9:
20572                     gen_st(ctx, OPC_SB, rt, rs, s);
20573                     break;
20574                 case NM_SHS9:
20575                     gen_st(ctx, OPC_SH, rt, rs, s);
20576                     break;
20577                 case NM_SWS9:
20578                     gen_st(ctx, OPC_SW, rt, rs, s);
20579                     break;
20580                 case NM_LWC1S9:
20581                     gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s);
20582                     break;
20583                 case NM_LDC1S9:
20584                     gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s);
20585                     break;
20586                 case NM_SWC1S9:
20587                     gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s);
20588                     break;
20589                 case NM_SDC1S9:
20590                     gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s);
20591                     break;
20592                 case NM_P_PREFS9:
20593                     if (rt == 31) {
20594                         /* SYNCI */
20595                         /* Break the TB to be able to sync copied instructions
20596                            immediately */
20597                         ctx->base.is_jmp = DISAS_STOP;
20598                     } else {
20599                         /* PREF */
20600                         /* Treat as NOP. */
20601                     }
20602                     break;
20603                 default:
20604                     generate_exception_end(ctx, EXCP_RI);
20605                     break;
20606                 }
20607                 break;
20608             case NM_P_LS_S1:
20609                 switch (extract32(ctx->opcode, 11, 4)) {
20610                 case NM_UALH:
20611                 case NM_UASH:
20612                     check_nms(ctx);
20613                     {
20614                         TCGv t0 = tcg_temp_new();
20615                         TCGv t1 = tcg_temp_new();
20616
20617                         gen_base_offset_addr(ctx, t0, rs, s);
20618
20619                         switch (extract32(ctx->opcode, 11, 4)) {
20620                         case NM_UALH:
20621                             tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
20622                                                MO_UNALN);
20623                             gen_store_gpr(t0, rt);
20624                             break;
20625                         case NM_UASH:
20626                             gen_load_gpr(t1, rt);
20627                             tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
20628                                                MO_UNALN);
20629                             break;
20630                         }
20631                         tcg_temp_free(t0);
20632                         tcg_temp_free(t1);
20633                     }
20634                     break;
20635                 case NM_P_LL:
20636                     switch (ctx->opcode & 0x03) {
20637                     case NM_LL:
20638                         gen_ld(ctx, OPC_LL, rt, rs, s);
20639                         break;
20640                     case NM_LLWP:
20641                         check_xnp(ctx);
20642                         gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
20643                         break;
20644                     }
20645                     break;
20646                 case NM_P_SC:
20647                     switch (ctx->opcode & 0x03) {
20648                     case NM_SC:
20649                         gen_st_cond(ctx, OPC_SC, rt, rs, s);
20650                         break;
20651                     case NM_SCWP:
20652                         check_xnp(ctx);
20653                         gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
20654                         break;
20655                     }
20656                     break;
20657                 case NM_CACHE:
20658                     check_cp0_enabled(ctx);
20659                     if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
20660                         gen_cache_operation(ctx, rt, rs, s);
20661                     }
20662                     break;
20663                 }
20664                 break;
20665             case NM_P_LS_WM:
20666             case NM_P_LS_UAWM:
20667                 check_nms(ctx);
20668                 {
20669                     int count = extract32(ctx->opcode, 12, 3);
20670                     int counter = 0;
20671
20672                     offset = sextract32(ctx->opcode, 15, 1) << 8 |
20673                              extract32(ctx->opcode, 0, 8);
20674                     TCGv va = tcg_temp_new();
20675                     TCGv t1 = tcg_temp_new();
20676                     TCGMemOp memop = (extract32(ctx->opcode, 8, 3)) ==
20677                                       NM_P_LS_UAWM ? MO_UNALN : 0;
20678
20679                     count = (count == 0) ? 8 : count;
20680                     while (counter != count) {
20681                         int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10);
20682                         int this_offset = offset + (counter << 2);
20683
20684                         gen_base_offset_addr(ctx, va, rs, this_offset);
20685
20686                         switch (extract32(ctx->opcode, 11, 1)) {
20687                         case NM_LWM:
20688                             tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx,
20689                                                memop | MO_TESL);
20690                             gen_store_gpr(t1, this_rt);
20691                             if ((this_rt == rs) &&
20692                                 (counter != (count - 1))) {
20693                                 /* UNPREDICTABLE */
20694                             }
20695                             break;
20696                         case NM_SWM:
20697                             this_rt = (rt == 0) ? 0 : this_rt;
20698                             gen_load_gpr(t1, this_rt);
20699                             tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx,
20700                                                memop | MO_TEUL);
20701                             break;
20702                         }
20703                         counter++;
20704                     }
20705                     tcg_temp_free(va);
20706                     tcg_temp_free(t1);
20707                 }
20708                 break;
20709             default:
20710                 generate_exception_end(ctx, EXCP_RI);
20711                 break;
20712             }
20713         }
20714         break;
20715     case NM_MOVE_BALC:
20716         check_nms(ctx);
20717         {
20718             TCGv t0 = tcg_temp_new();
20719             int32_t s = sextract32(ctx->opcode, 0, 1) << 21 |
20720                         extract32(ctx->opcode, 1, 20) << 1;
20721             rd = (extract32(ctx->opcode, 24, 1)) == 0 ? 4 : 5;
20722             rt = decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3 |
20723                             extract32(ctx->opcode, 21, 3));
20724             gen_load_gpr(t0, rt);
20725             tcg_gen_mov_tl(cpu_gpr[rd], t0);
20726             gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
20727             tcg_temp_free(t0);
20728         }
20729         break;
20730     case NM_P_BAL:
20731         {
20732             int32_t s = sextract32(ctx->opcode, 0, 1) << 25 |
20733                         extract32(ctx->opcode, 1, 24) << 1;
20734
20735             if ((extract32(ctx->opcode, 25, 1)) == 0) {
20736                 /* BC */
20737                 gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s);
20738             } else {
20739                 /* BALC */
20740                 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
20741             }
20742         }
20743         break;
20744     case NM_P_J:
20745         switch (extract32(ctx->opcode, 12, 4)) {
20746         case NM_JALRC:
20747         case NM_JALRC_HB:
20748             gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0);
20749             break;
20750         case NM_P_BALRSC:
20751             gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt);
20752             break;
20753         default:
20754             generate_exception_end(ctx, EXCP_RI);
20755             break;
20756         }
20757         break;
20758     case NM_P_BR1:
20759         {
20760             int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
20761                         extract32(ctx->opcode, 1, 13) << 1;
20762             switch (extract32(ctx->opcode, 14, 2)) {
20763             case NM_BEQC:
20764                 check_nms(ctx);
20765                 gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s);
20766                 break;
20767             case NM_P_BR3A:
20768                 s = sextract32(ctx->opcode, 0, 1) << 14 |
20769                     extract32(ctx->opcode, 1, 13) << 1;
20770                 check_cp1_enabled(ctx);
20771                 switch (extract32(ctx->opcode, 16, 5)) {
20772                 case NM_BC1EQZC:
20773                     gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s);
20774                     break;
20775                 case NM_BC1NEZC:
20776                     gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s);
20777                     break;
20778                 case NM_BPOSGE32C:
20779                     check_dsp_r3(ctx);
20780                     {
20781                         int32_t imm = extract32(ctx->opcode, 1, 13) |
20782                                       extract32(ctx->opcode, 0, 1) << 13;
20783
20784                         gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2,
20785                                               imm);
20786                     }
20787                     break;
20788                 default:
20789                     generate_exception_end(ctx, EXCP_RI);
20790                     break;
20791                 }
20792                 break;
20793             case NM_BGEC:
20794                 if (rs == rt) {
20795                     gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s);
20796                 } else {
20797                     gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s);
20798                 }
20799                 break;
20800             case NM_BGEUC:
20801                 if (rs == rt || rt == 0) {
20802                     gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s);
20803                 } else if (rs == 0) {
20804                     gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s);
20805                 } else {
20806                     gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, s);
20807                 }
20808                 break;
20809             }
20810         }
20811         break;
20812     case NM_P_BR2:
20813         {
20814             int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
20815                         extract32(ctx->opcode, 1, 13) << 1;
20816             switch (extract32(ctx->opcode, 14, 2)) {
20817             case NM_BNEC:
20818                 check_nms(ctx);
20819                 gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s);
20820                 break;
20821             case NM_BLTC:
20822                 if (rs != 0 && rt != 0 && rs == rt) {
20823                     /* NOP */
20824                     ctx->hflags |= MIPS_HFLAG_FBNSLOT;
20825                 } else {
20826                     gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s);
20827                 }
20828                 break;
20829             case NM_BLTUC:
20830                 if (rs == 0 || rs == rt) {
20831                     /* NOP */
20832                     ctx->hflags |= MIPS_HFLAG_FBNSLOT;
20833                 } else {
20834                     gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, s);
20835                 }
20836                 break;
20837             default:
20838                 generate_exception_end(ctx, EXCP_RI);
20839                 break;
20840             }
20841         }
20842         break;
20843     case NM_P_BRI:
20844         {
20845             int32_t s = sextract32(ctx->opcode, 0, 1) << 11 |
20846                         extract32(ctx->opcode, 1, 10) << 1;
20847             uint32_t u = extract32(ctx->opcode, 11, 7);
20848
20849             gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3),
20850                                    rt, u, s);
20851         }
20852         break;
20853     default:
20854         generate_exception_end(ctx, EXCP_RI);
20855         break;
20856     }
20857     return 4;
20858 }
20859
20860 static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
20861 {
20862     uint32_t op;
20863     int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
20864     int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
20865     int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS1(ctx->opcode));
20866     int offset;
20867     int imm;
20868
20869     /* make sure instructions are on a halfword boundary */
20870     if (ctx->base.pc_next & 0x1) {
20871         TCGv tmp = tcg_const_tl(ctx->base.pc_next);
20872         tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
20873         tcg_temp_free(tmp);
20874         generate_exception_end(ctx, EXCP_AdEL);
20875         return 2;
20876     }
20877
20878     op = extract32(ctx->opcode, 10, 6);
20879     switch (op) {
20880     case NM_P16_MV:
20881         rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
20882         if (rt != 0) {
20883             /* MOVE */
20884             rs = NANOMIPS_EXTRACT_RS5(ctx->opcode);
20885             gen_arith(ctx, OPC_ADDU, rt, rs, 0);
20886         } else {
20887             /* P16.RI */
20888             switch (extract32(ctx->opcode, 3, 2)) {
20889             case NM_P16_SYSCALL:
20890                 if (extract32(ctx->opcode, 2, 1) == 0) {
20891                     generate_exception_end(ctx, EXCP_SYSCALL);
20892                 } else {
20893                     generate_exception_end(ctx, EXCP_RI);
20894                 }
20895                 break;
20896             case NM_BREAK16:
20897                 generate_exception_end(ctx, EXCP_BREAK);
20898                 break;
20899             case NM_SDBBP16:
20900                 if (is_uhi(extract32(ctx->opcode, 0, 3))) {
20901                     gen_helper_do_semihosting(cpu_env);
20902                 } else {
20903                     if (ctx->hflags & MIPS_HFLAG_SBRI) {
20904                         generate_exception_end(ctx, EXCP_RI);
20905                     } else {
20906                         generate_exception_end(ctx, EXCP_DBp);
20907                     }
20908                 }
20909                 break;
20910             default:
20911                 generate_exception_end(ctx, EXCP_RI);
20912                 break;
20913             }
20914         }
20915         break;
20916     case NM_P16_SHIFT:
20917         {
20918             int shift = extract32(ctx->opcode, 0, 3);
20919             uint32_t opc = 0;
20920             shift = (shift == 0) ? 8 : shift;
20921
20922             switch (extract32(ctx->opcode, 3, 1)) {
20923             case NM_SLL16:
20924                 opc = OPC_SLL;
20925                 break;
20926             case NM_SRL16:
20927                 opc = OPC_SRL;
20928                 break;
20929             }
20930             gen_shift_imm(ctx, opc, rt, rs, shift);
20931         }
20932         break;
20933     case NM_P16C:
20934         switch (ctx->opcode & 1) {
20935         case NM_POOL16C_0:
20936             gen_pool16c_nanomips_insn(ctx);
20937             break;
20938         case NM_LWXS16:
20939             gen_ldxs(ctx, rt, rs, rd);
20940             break;
20941         }
20942         break;
20943     case NM_P16_A1:
20944         switch (extract32(ctx->opcode, 6, 1)) {
20945         case NM_ADDIUR1SP:
20946             imm = extract32(ctx->opcode, 0, 6) << 2;
20947             gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm);
20948             break;
20949         default:
20950             generate_exception_end(ctx, EXCP_RI);
20951             break;
20952         }
20953         break;
20954     case NM_P16_A2:
20955         switch (extract32(ctx->opcode, 3, 1)) {
20956         case NM_ADDIUR2:
20957             imm = extract32(ctx->opcode, 0, 3) << 2;
20958             gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm);
20959             break;
20960         case NM_P_ADDIURS5:
20961             rt = extract32(ctx->opcode, 5, 5);
20962             if (rt != 0) {
20963                 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
20964                 imm = (sextract32(ctx->opcode, 4, 1) << 3) |
20965                       (extract32(ctx->opcode, 0, 3));
20966                 gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm);
20967             }
20968             break;
20969         }
20970         break;
20971     case NM_P16_ADDU:
20972         switch (ctx->opcode & 0x1) {
20973         case NM_ADDU16:
20974             gen_arith(ctx, OPC_ADDU, rd, rs, rt);
20975             break;
20976         case NM_SUBU16:
20977             gen_arith(ctx, OPC_SUBU, rd, rs, rt);
20978             break;
20979         }
20980         break;
20981     case NM_P16_4X4:
20982         rt = (extract32(ctx->opcode, 9, 1) << 3) |
20983               extract32(ctx->opcode, 5, 3);
20984         rs = (extract32(ctx->opcode, 4, 1) << 3) |
20985               extract32(ctx->opcode, 0, 3);
20986         rt = decode_gpr_gpr4(rt);
20987         rs = decode_gpr_gpr4(rs);
20988         switch ((extract32(ctx->opcode, 7, 2) & 0x2) |
20989                 (extract32(ctx->opcode, 3, 1))) {
20990         case NM_ADDU4X4:
20991             check_nms(ctx);
20992             gen_arith(ctx, OPC_ADDU, rt, rs, rt);
20993             break;
20994         case NM_MUL4X4:
20995             check_nms(ctx);
20996             gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt);
20997             break;
20998         default:
20999             generate_exception_end(ctx, EXCP_RI);
21000             break;
21001         }
21002         break;
21003     case NM_LI16:
21004         {
21005             int imm = extract32(ctx->opcode, 0, 7);
21006             imm = (imm == 0x7f ? -1 : imm);
21007             if (rt != 0) {
21008                 tcg_gen_movi_tl(cpu_gpr[rt], imm);
21009             }
21010         }
21011         break;
21012     case NM_ANDI16:
21013         {
21014             uint32_t u = extract32(ctx->opcode, 0, 4);
21015             u = (u == 12) ? 0xff :
21016                 (u == 13) ? 0xffff : u;
21017             gen_logic_imm(ctx, OPC_ANDI, rt, rs, u);
21018         }
21019         break;
21020     case NM_P16_LB:
21021         offset = extract32(ctx->opcode, 0, 2);
21022         switch (extract32(ctx->opcode, 2, 2)) {
21023         case NM_LB16:
21024             gen_ld(ctx, OPC_LB, rt, rs, offset);
21025             break;
21026         case NM_SB16:
21027             rt = decode_gpr_gpr3_src_store(
21028                      NANOMIPS_EXTRACT_RD(ctx->opcode));
21029             gen_st(ctx, OPC_SB, rt, rs, offset);
21030             break;
21031         case NM_LBU16:
21032             gen_ld(ctx, OPC_LBU, rt, rs, offset);
21033             break;
21034         default:
21035             generate_exception_end(ctx, EXCP_RI);
21036             break;
21037         }
21038         break;
21039     case NM_P16_LH:
21040         offset = extract32(ctx->opcode, 1, 2) << 1;
21041         switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) {
21042         case NM_LH16:
21043             gen_ld(ctx, OPC_LH, rt, rs, offset);
21044             break;
21045         case NM_SH16:
21046             rt = decode_gpr_gpr3_src_store(
21047                      NANOMIPS_EXTRACT_RD(ctx->opcode));
21048             gen_st(ctx, OPC_SH, rt, rs, offset);
21049             break;
21050         case NM_LHU16:
21051             gen_ld(ctx, OPC_LHU, rt, rs, offset);
21052             break;
21053         default:
21054             generate_exception_end(ctx, EXCP_RI);
21055             break;
21056         }
21057         break;
21058     case NM_LW16:
21059         offset = extract32(ctx->opcode, 0, 4) << 2;
21060         gen_ld(ctx, OPC_LW, rt, rs, offset);
21061         break;
21062     case NM_LWSP16:
21063         rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21064         offset = extract32(ctx->opcode, 0, 5) << 2;
21065         gen_ld(ctx, OPC_LW, rt, 29, offset);
21066         break;
21067     case NM_LW4X4:
21068         check_nms(ctx);
21069         rt = (extract32(ctx->opcode, 9, 1) << 3) |
21070              extract32(ctx->opcode, 5, 3);
21071         rs = (extract32(ctx->opcode, 4, 1) << 3) |
21072              extract32(ctx->opcode, 0, 3);
21073         offset = (extract32(ctx->opcode, 3, 1) << 3) |
21074                  (extract32(ctx->opcode, 8, 1) << 2);
21075         rt = decode_gpr_gpr4(rt);
21076         rs = decode_gpr_gpr4(rs);
21077         gen_ld(ctx, OPC_LW, rt, rs, offset);
21078         break;
21079     case NM_SW4X4:
21080         check_nms(ctx);
21081         rt = (extract32(ctx->opcode, 9, 1) << 3) |
21082              extract32(ctx->opcode, 5, 3);
21083         rs = (extract32(ctx->opcode, 4, 1) << 3) |
21084              extract32(ctx->opcode, 0, 3);
21085         offset = (extract32(ctx->opcode, 3, 1) << 3) |
21086                  (extract32(ctx->opcode, 8, 1) << 2);
21087         rt = decode_gpr_gpr4_zero(rt);
21088         rs = decode_gpr_gpr4(rs);
21089         gen_st(ctx, OPC_SW, rt, rs, offset);
21090         break;
21091     case NM_LWGP16:
21092         offset = extract32(ctx->opcode, 0, 7) << 2;
21093         gen_ld(ctx, OPC_LW, rt, 28, offset);
21094         break;
21095     case NM_SWSP16:
21096         rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21097         offset = extract32(ctx->opcode, 0, 5) << 2;
21098         gen_st(ctx, OPC_SW, rt, 29, offset);
21099         break;
21100     case NM_SW16:
21101         rt = decode_gpr_gpr3_src_store(
21102                  NANOMIPS_EXTRACT_RD(ctx->opcode));
21103         rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
21104         offset = extract32(ctx->opcode, 0, 4) << 2;
21105         gen_st(ctx, OPC_SW, rt, rs, offset);
21106         break;
21107     case NM_SWGP16:
21108         rt = decode_gpr_gpr3_src_store(
21109                  NANOMIPS_EXTRACT_RD(ctx->opcode));
21110         offset = extract32(ctx->opcode, 0, 7) << 2;
21111         gen_st(ctx, OPC_SW, rt, 28, offset);
21112         break;
21113     case NM_BC16:
21114         gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0,
21115                            (sextract32(ctx->opcode, 0, 1) << 10) |
21116                            (extract32(ctx->opcode, 1, 9) << 1));
21117         break;
21118     case NM_BALC16:
21119         gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0,
21120                            (sextract32(ctx->opcode, 0, 1) << 10) |
21121                            (extract32(ctx->opcode, 1, 9) << 1));
21122         break;
21123     case NM_BEQZC16:
21124         gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0,
21125                            (sextract32(ctx->opcode, 0, 1) << 7) |
21126                            (extract32(ctx->opcode, 1, 6) << 1));
21127         break;
21128     case NM_BNEZC16:
21129         gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0,
21130                            (sextract32(ctx->opcode, 0, 1) << 7) |
21131                            (extract32(ctx->opcode, 1, 6) << 1));
21132         break;
21133     case NM_P16_BR:
21134         switch (ctx->opcode & 0xf) {
21135         case 0:
21136             /* P16.JRC */
21137             switch (extract32(ctx->opcode, 4, 1)) {
21138             case NM_JRC:
21139                 gen_compute_branch_nm(ctx, OPC_JR, 2,
21140                                    extract32(ctx->opcode, 5, 5), 0, 0);
21141                 break;
21142             case NM_JALRC16:
21143                 gen_compute_branch_nm(ctx, OPC_JALR, 2,
21144                                    extract32(ctx->opcode, 5, 5), 31, 0);
21145                 break;
21146             }
21147             break;
21148         default:
21149             {
21150                 /* P16.BRI */
21151                 uint32_t opc = extract32(ctx->opcode, 4, 3) <
21152                                extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE;
21153                 gen_compute_branch_nm(ctx, opc, 2, rs, rt,
21154                                    extract32(ctx->opcode, 0, 4) << 1);
21155             }
21156             break;
21157         }
21158         break;
21159     case NM_P16_SR:
21160         {
21161             int count = extract32(ctx->opcode, 0, 4);
21162             int u = extract32(ctx->opcode, 4, 4) << 4;
21163
21164             rt = 30 + extract32(ctx->opcode, 9, 1);
21165             switch (extract32(ctx->opcode, 8, 1)) {
21166             case NM_SAVE16:
21167                 gen_save(ctx, rt, count, 0, u);
21168                 break;
21169             case NM_RESTORE_JRC16:
21170                 gen_restore(ctx, rt, count, 0, u);
21171                 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
21172                 break;
21173             }
21174         }
21175         break;
21176     case NM_MOVEP:
21177     case NM_MOVEPREV:
21178         check_nms(ctx);
21179         {
21180             static const int gpr2reg1[] = {4, 5, 6, 7};
21181             static const int gpr2reg2[] = {5, 6, 7, 8};
21182             int re;
21183             int rd2 = extract32(ctx->opcode, 3, 1) << 1 |
21184                       extract32(ctx->opcode, 8, 1);
21185             int r1 = gpr2reg1[rd2];
21186             int r2 = gpr2reg2[rd2];
21187             int r3 = extract32(ctx->opcode, 4, 1) << 3 |
21188                      extract32(ctx->opcode, 0, 3);
21189             int r4 = extract32(ctx->opcode, 9, 1) << 3 |
21190                      extract32(ctx->opcode, 5, 3);
21191             TCGv t0 = tcg_temp_new();
21192             TCGv t1 = tcg_temp_new();
21193             if (op == NM_MOVEP) {
21194                 rd = r1;
21195                 re = r2;
21196                 rs = decode_gpr_gpr4_zero(r3);
21197                 rt = decode_gpr_gpr4_zero(r4);
21198             } else {
21199                 rd = decode_gpr_gpr4(r3);
21200                 re = decode_gpr_gpr4(r4);
21201                 rs = r1;
21202                 rt = r2;
21203             }
21204             gen_load_gpr(t0, rs);
21205             gen_load_gpr(t1, rt);
21206             tcg_gen_mov_tl(cpu_gpr[rd], t0);
21207             tcg_gen_mov_tl(cpu_gpr[re], t1);
21208             tcg_temp_free(t0);
21209             tcg_temp_free(t1);
21210         }
21211         break;
21212     default:
21213         return decode_nanomips_32_48_opc(env, ctx);
21214     }
21215
21216     return 2;
21217 }
21218
21219
21220 /* SmartMIPS extension to MIPS32 */
21221
21222 #if defined(TARGET_MIPS64)
21223
21224 /* MDMX extension to MIPS64 */
21225
21226 #endif
21227
21228 /* MIPSDSP functions. */
21229 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
21230                            int rd, int base, int offset)
21231 {
21232     TCGv t0;
21233
21234     check_dsp(ctx);
21235     t0 = tcg_temp_new();
21236
21237     if (base == 0) {
21238         gen_load_gpr(t0, offset);
21239     } else if (offset == 0) {
21240         gen_load_gpr(t0, base);
21241     } else {
21242         gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
21243     }
21244
21245     switch (opc) {
21246     case OPC_LBUX:
21247         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
21248         gen_store_gpr(t0, rd);
21249         break;
21250     case OPC_LHX:
21251         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
21252         gen_store_gpr(t0, rd);
21253         break;
21254     case OPC_LWX:
21255         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
21256         gen_store_gpr(t0, rd);
21257         break;
21258 #if defined(TARGET_MIPS64)
21259     case OPC_LDX:
21260         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
21261         gen_store_gpr(t0, rd);
21262         break;
21263 #endif
21264     }
21265     tcg_temp_free(t0);
21266 }
21267
21268 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
21269                               int ret, int v1, int v2)
21270 {
21271     TCGv v1_t;
21272     TCGv v2_t;
21273
21274     if (ret == 0) {
21275         /* Treat as NOP. */
21276         return;
21277     }
21278
21279     v1_t = tcg_temp_new();
21280     v2_t = tcg_temp_new();
21281
21282     gen_load_gpr(v1_t, v1);
21283     gen_load_gpr(v2_t, v2);
21284
21285     switch (op1) {
21286     /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
21287     case OPC_MULT_G_2E:
21288         check_dsp_r2(ctx);
21289         switch (op2) {
21290         case OPC_ADDUH_QB:
21291             gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
21292             break;
21293         case OPC_ADDUH_R_QB:
21294             gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
21295             break;
21296         case OPC_ADDQH_PH:
21297             gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
21298             break;
21299         case OPC_ADDQH_R_PH:
21300             gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
21301             break;
21302         case OPC_ADDQH_W:
21303             gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
21304             break;
21305         case OPC_ADDQH_R_W:
21306             gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
21307             break;
21308         case OPC_SUBUH_QB:
21309             gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
21310             break;
21311         case OPC_SUBUH_R_QB:
21312             gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
21313             break;
21314         case OPC_SUBQH_PH:
21315             gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
21316             break;
21317         case OPC_SUBQH_R_PH:
21318             gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
21319             break;
21320         case OPC_SUBQH_W:
21321             gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
21322             break;
21323         case OPC_SUBQH_R_W:
21324             gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
21325             break;
21326         }
21327         break;
21328     case OPC_ABSQ_S_PH_DSP:
21329         switch (op2) {
21330         case OPC_ABSQ_S_QB:
21331             check_dsp_r2(ctx);
21332             gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
21333             break;
21334         case OPC_ABSQ_S_PH:
21335             check_dsp(ctx);
21336             gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
21337             break;
21338         case OPC_ABSQ_S_W:
21339             check_dsp(ctx);
21340             gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
21341             break;
21342         case OPC_PRECEQ_W_PHL:
21343             check_dsp(ctx);
21344             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
21345             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
21346             break;
21347         case OPC_PRECEQ_W_PHR:
21348             check_dsp(ctx);
21349             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
21350             tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
21351             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
21352             break;
21353         case OPC_PRECEQU_PH_QBL:
21354             check_dsp(ctx);
21355             gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
21356             break;
21357         case OPC_PRECEQU_PH_QBR:
21358             check_dsp(ctx);
21359             gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
21360             break;
21361         case OPC_PRECEQU_PH_QBLA:
21362             check_dsp(ctx);
21363             gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
21364             break;
21365         case OPC_PRECEQU_PH_QBRA:
21366             check_dsp(ctx);
21367             gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
21368             break;
21369         case OPC_PRECEU_PH_QBL:
21370             check_dsp(ctx);
21371             gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
21372             break;
21373         case OPC_PRECEU_PH_QBR:
21374             check_dsp(ctx);
21375             gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
21376             break;
21377         case OPC_PRECEU_PH_QBLA:
21378             check_dsp(ctx);
21379             gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
21380             break;
21381         case OPC_PRECEU_PH_QBRA:
21382             check_dsp(ctx);
21383             gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
21384             break;
21385         }
21386         break;
21387     case OPC_ADDU_QB_DSP:
21388         switch (op2) {
21389         case OPC_ADDQ_PH:
21390             check_dsp(ctx);
21391             gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21392             break;
21393         case OPC_ADDQ_S_PH:
21394             check_dsp(ctx);
21395             gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21396             break;
21397         case OPC_ADDQ_S_W:
21398             check_dsp(ctx);
21399             gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21400             break;
21401         case OPC_ADDU_QB:
21402             check_dsp(ctx);
21403             gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21404             break;
21405         case OPC_ADDU_S_QB:
21406             check_dsp(ctx);
21407             gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21408             break;
21409         case OPC_ADDU_PH:
21410             check_dsp_r2(ctx);
21411             gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21412             break;
21413         case OPC_ADDU_S_PH:
21414             check_dsp_r2(ctx);
21415             gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21416             break;
21417         case OPC_SUBQ_PH:
21418             check_dsp(ctx);
21419             gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21420             break;
21421         case OPC_SUBQ_S_PH:
21422             check_dsp(ctx);
21423             gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21424             break;
21425         case OPC_SUBQ_S_W:
21426             check_dsp(ctx);
21427             gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21428             break;
21429         case OPC_SUBU_QB:
21430             check_dsp(ctx);
21431             gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21432             break;
21433         case OPC_SUBU_S_QB:
21434             check_dsp(ctx);
21435             gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21436             break;
21437         case OPC_SUBU_PH:
21438             check_dsp_r2(ctx);
21439             gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21440             break;
21441         case OPC_SUBU_S_PH:
21442             check_dsp_r2(ctx);
21443             gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21444             break;
21445         case OPC_ADDSC:
21446             check_dsp(ctx);
21447             gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21448             break;
21449         case OPC_ADDWC:
21450             check_dsp(ctx);
21451             gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21452             break;
21453         case OPC_MODSUB:
21454             check_dsp(ctx);
21455             gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
21456             break;
21457         case OPC_RADDU_W_QB:
21458             check_dsp(ctx);
21459             gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
21460             break;
21461         }
21462         break;
21463     case OPC_CMPU_EQ_QB_DSP:
21464         switch (op2) {
21465         case OPC_PRECR_QB_PH:
21466             check_dsp_r2(ctx);
21467             gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
21468             break;
21469         case OPC_PRECRQ_QB_PH:
21470             check_dsp(ctx);
21471             gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
21472             break;
21473         case OPC_PRECR_SRA_PH_W:
21474             check_dsp_r2(ctx);
21475             {
21476                 TCGv_i32 sa_t = tcg_const_i32(v2);
21477                 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
21478                                           cpu_gpr[ret]);
21479                 tcg_temp_free_i32(sa_t);
21480                 break;
21481             }
21482         case OPC_PRECR_SRA_R_PH_W:
21483             check_dsp_r2(ctx);
21484             {
21485                 TCGv_i32 sa_t = tcg_const_i32(v2);
21486                 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
21487                                             cpu_gpr[ret]);
21488                 tcg_temp_free_i32(sa_t);
21489                 break;
21490             }
21491         case OPC_PRECRQ_PH_W:
21492             check_dsp(ctx);
21493             gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
21494             break;
21495         case OPC_PRECRQ_RS_PH_W:
21496             check_dsp(ctx);
21497             gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21498             break;
21499         case OPC_PRECRQU_S_QB_PH:
21500             check_dsp(ctx);
21501             gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21502             break;
21503         }
21504         break;
21505 #ifdef TARGET_MIPS64
21506     case OPC_ABSQ_S_QH_DSP:
21507         switch (op2) {
21508         case OPC_PRECEQ_L_PWL:
21509             check_dsp(ctx);
21510             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
21511             break;
21512         case OPC_PRECEQ_L_PWR:
21513             check_dsp(ctx);
21514             tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
21515             break;
21516         case OPC_PRECEQ_PW_QHL:
21517             check_dsp(ctx);
21518             gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
21519             break;
21520         case OPC_PRECEQ_PW_QHR:
21521             check_dsp(ctx);
21522             gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
21523             break;
21524         case OPC_PRECEQ_PW_QHLA:
21525             check_dsp(ctx);
21526             gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
21527             break;
21528         case OPC_PRECEQ_PW_QHRA:
21529             check_dsp(ctx);
21530             gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
21531             break;
21532         case OPC_PRECEQU_QH_OBL:
21533             check_dsp(ctx);
21534             gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
21535             break;
21536         case OPC_PRECEQU_QH_OBR:
21537             check_dsp(ctx);
21538             gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
21539             break;
21540         case OPC_PRECEQU_QH_OBLA:
21541             check_dsp(ctx);
21542             gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
21543             break;
21544         case OPC_PRECEQU_QH_OBRA:
21545             check_dsp(ctx);
21546             gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
21547             break;
21548         case OPC_PRECEU_QH_OBL:
21549             check_dsp(ctx);
21550             gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
21551             break;
21552         case OPC_PRECEU_QH_OBR:
21553             check_dsp(ctx);
21554             gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
21555             break;
21556         case OPC_PRECEU_QH_OBLA:
21557             check_dsp(ctx);
21558             gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
21559             break;
21560         case OPC_PRECEU_QH_OBRA:
21561             check_dsp(ctx);
21562             gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
21563             break;
21564         case OPC_ABSQ_S_OB:
21565             check_dsp_r2(ctx);
21566             gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
21567             break;
21568         case OPC_ABSQ_S_PW:
21569             check_dsp(ctx);
21570             gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
21571             break;
21572         case OPC_ABSQ_S_QH:
21573             check_dsp(ctx);
21574             gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
21575             break;
21576         }
21577         break;
21578     case OPC_ADDU_OB_DSP:
21579         switch (op2) {
21580         case OPC_RADDU_L_OB:
21581             check_dsp(ctx);
21582             gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
21583             break;
21584         case OPC_SUBQ_PW:
21585             check_dsp(ctx);
21586             gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21587             break;
21588         case OPC_SUBQ_S_PW:
21589             check_dsp(ctx);
21590             gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21591             break;
21592         case OPC_SUBQ_QH:
21593             check_dsp(ctx);
21594             gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21595             break;
21596         case OPC_SUBQ_S_QH:
21597             check_dsp(ctx);
21598             gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21599             break;
21600         case OPC_SUBU_OB:
21601             check_dsp(ctx);
21602             gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21603             break;
21604         case OPC_SUBU_S_OB:
21605             check_dsp(ctx);
21606             gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21607             break;
21608         case OPC_SUBU_QH:
21609             check_dsp_r2(ctx);
21610             gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21611             break;
21612         case OPC_SUBU_S_QH:
21613             check_dsp_r2(ctx);
21614             gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21615             break;
21616         case OPC_SUBUH_OB:
21617             check_dsp_r2(ctx);
21618             gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
21619             break;
21620         case OPC_SUBUH_R_OB:
21621             check_dsp_r2(ctx);
21622             gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
21623             break;
21624         case OPC_ADDQ_PW:
21625             check_dsp(ctx);
21626             gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21627             break;
21628         case OPC_ADDQ_S_PW:
21629             check_dsp(ctx);
21630             gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21631             break;
21632         case OPC_ADDQ_QH:
21633             check_dsp(ctx);
21634             gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21635             break;
21636         case OPC_ADDQ_S_QH:
21637             check_dsp(ctx);
21638             gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21639             break;
21640         case OPC_ADDU_OB:
21641             check_dsp(ctx);
21642             gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21643             break;
21644         case OPC_ADDU_S_OB:
21645             check_dsp(ctx);
21646             gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21647             break;
21648         case OPC_ADDU_QH:
21649             check_dsp_r2(ctx);
21650             gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21651             break;
21652         case OPC_ADDU_S_QH:
21653             check_dsp_r2(ctx);
21654             gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21655             break;
21656         case OPC_ADDUH_OB:
21657             check_dsp_r2(ctx);
21658             gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
21659             break;
21660         case OPC_ADDUH_R_OB:
21661             check_dsp_r2(ctx);
21662             gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
21663             break;
21664         }
21665         break;
21666     case OPC_CMPU_EQ_OB_DSP:
21667         switch (op2) {
21668         case OPC_PRECR_OB_QH:
21669             check_dsp_r2(ctx);
21670             gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
21671             break;
21672         case OPC_PRECR_SRA_QH_PW:
21673             check_dsp_r2(ctx);
21674             {
21675                 TCGv_i32 ret_t = tcg_const_i32(ret);
21676                 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
21677                 tcg_temp_free_i32(ret_t);
21678                 break;
21679             }
21680         case OPC_PRECR_SRA_R_QH_PW:
21681             check_dsp_r2(ctx);
21682             {
21683                 TCGv_i32 sa_v = tcg_const_i32(ret);
21684                 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
21685                 tcg_temp_free_i32(sa_v);
21686                 break;
21687             }
21688         case OPC_PRECRQ_OB_QH:
21689             check_dsp(ctx);
21690             gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
21691             break;
21692         case OPC_PRECRQ_PW_L:
21693             check_dsp(ctx);
21694             gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
21695             break;
21696         case OPC_PRECRQ_QH_PW:
21697             check_dsp(ctx);
21698             gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
21699             break;
21700         case OPC_PRECRQ_RS_QH_PW:
21701             check_dsp(ctx);
21702             gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21703             break;
21704         case OPC_PRECRQU_S_OB_QH:
21705             check_dsp(ctx);
21706             gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21707             break;
21708         }
21709         break;
21710 #endif
21711     }
21712
21713     tcg_temp_free(v1_t);
21714     tcg_temp_free(v2_t);
21715 }
21716
21717 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
21718                               int ret, int v1, int v2)
21719 {
21720     uint32_t op2;
21721     TCGv t0;
21722     TCGv v1_t;
21723     TCGv v2_t;
21724
21725     if (ret == 0) {
21726         /* Treat as NOP. */
21727         return;
21728     }
21729
21730     t0 = tcg_temp_new();
21731     v1_t = tcg_temp_new();
21732     v2_t = tcg_temp_new();
21733
21734     tcg_gen_movi_tl(t0, v1);
21735     gen_load_gpr(v1_t, v1);
21736     gen_load_gpr(v2_t, v2);
21737
21738     switch (opc) {
21739     case OPC_SHLL_QB_DSP:
21740         {
21741             op2 = MASK_SHLL_QB(ctx->opcode);
21742             switch (op2) {
21743             case OPC_SHLL_QB:
21744                 check_dsp(ctx);
21745                 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
21746                 break;
21747             case OPC_SHLLV_QB:
21748                 check_dsp(ctx);
21749                 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21750                 break;
21751             case OPC_SHLL_PH:
21752                 check_dsp(ctx);
21753                 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
21754                 break;
21755             case OPC_SHLLV_PH:
21756                 check_dsp(ctx);
21757                 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21758                 break;
21759             case OPC_SHLL_S_PH:
21760                 check_dsp(ctx);
21761                 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
21762                 break;
21763             case OPC_SHLLV_S_PH:
21764                 check_dsp(ctx);
21765                 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21766                 break;
21767             case OPC_SHLL_S_W:
21768                 check_dsp(ctx);
21769                 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
21770                 break;
21771             case OPC_SHLLV_S_W:
21772                 check_dsp(ctx);
21773                 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21774                 break;
21775             case OPC_SHRL_QB:
21776                 check_dsp(ctx);
21777                 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
21778                 break;
21779             case OPC_SHRLV_QB:
21780                 check_dsp(ctx);
21781                 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
21782                 break;
21783             case OPC_SHRL_PH:
21784                 check_dsp_r2(ctx);
21785                 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
21786                 break;
21787             case OPC_SHRLV_PH:
21788                 check_dsp_r2(ctx);
21789                 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
21790                 break;
21791             case OPC_SHRA_QB:
21792                 check_dsp_r2(ctx);
21793                 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
21794                 break;
21795             case OPC_SHRA_R_QB:
21796                 check_dsp_r2(ctx);
21797                 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
21798                 break;
21799             case OPC_SHRAV_QB:
21800                 check_dsp_r2(ctx);
21801                 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
21802                 break;
21803             case OPC_SHRAV_R_QB:
21804                 check_dsp_r2(ctx);
21805                 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
21806                 break;
21807             case OPC_SHRA_PH:
21808                 check_dsp(ctx);
21809                 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
21810                 break;
21811             case OPC_SHRA_R_PH:
21812                 check_dsp(ctx);
21813                 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
21814                 break;
21815             case OPC_SHRAV_PH:
21816                 check_dsp(ctx);
21817                 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
21818                 break;
21819             case OPC_SHRAV_R_PH:
21820                 check_dsp(ctx);
21821                 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
21822                 break;
21823             case OPC_SHRA_R_W:
21824                 check_dsp(ctx);
21825                 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
21826                 break;
21827             case OPC_SHRAV_R_W:
21828                 check_dsp(ctx);
21829                 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
21830                 break;
21831             default:            /* Invalid */
21832                 MIPS_INVAL("MASK SHLL.QB");
21833                 generate_exception_end(ctx, EXCP_RI);
21834                 break;
21835             }
21836             break;
21837         }
21838 #ifdef TARGET_MIPS64
21839     case OPC_SHLL_OB_DSP:
21840         op2 = MASK_SHLL_OB(ctx->opcode);
21841         switch (op2) {
21842         case OPC_SHLL_PW:
21843             check_dsp(ctx);
21844             gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
21845             break;
21846         case OPC_SHLLV_PW:
21847             check_dsp(ctx);
21848             gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
21849             break;
21850         case OPC_SHLL_S_PW:
21851             check_dsp(ctx);
21852             gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
21853             break;
21854         case OPC_SHLLV_S_PW:
21855             check_dsp(ctx);
21856             gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
21857             break;
21858         case OPC_SHLL_OB:
21859             check_dsp(ctx);
21860             gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
21861             break;
21862         case OPC_SHLLV_OB:
21863             check_dsp(ctx);
21864             gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
21865             break;
21866         case OPC_SHLL_QH:
21867             check_dsp(ctx);
21868             gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
21869             break;
21870         case OPC_SHLLV_QH:
21871             check_dsp(ctx);
21872             gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
21873             break;
21874         case OPC_SHLL_S_QH:
21875             check_dsp(ctx);
21876             gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
21877             break;
21878         case OPC_SHLLV_S_QH:
21879             check_dsp(ctx);
21880             gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
21881             break;
21882         case OPC_SHRA_OB:
21883             check_dsp_r2(ctx);
21884             gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
21885             break;
21886         case OPC_SHRAV_OB:
21887             check_dsp_r2(ctx);
21888             gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
21889             break;
21890         case OPC_SHRA_R_OB:
21891             check_dsp_r2(ctx);
21892             gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
21893             break;
21894         case OPC_SHRAV_R_OB:
21895             check_dsp_r2(ctx);
21896             gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
21897             break;
21898         case OPC_SHRA_PW:
21899             check_dsp(ctx);
21900             gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
21901             break;
21902         case OPC_SHRAV_PW:
21903             check_dsp(ctx);
21904             gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
21905             break;
21906         case OPC_SHRA_R_PW:
21907             check_dsp(ctx);
21908             gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
21909             break;
21910         case OPC_SHRAV_R_PW:
21911             check_dsp(ctx);
21912             gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
21913             break;
21914         case OPC_SHRA_QH:
21915             check_dsp(ctx);
21916             gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
21917             break;
21918         case OPC_SHRAV_QH:
21919             check_dsp(ctx);
21920             gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
21921             break;
21922         case OPC_SHRA_R_QH:
21923             check_dsp(ctx);
21924             gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
21925             break;
21926         case OPC_SHRAV_R_QH:
21927             check_dsp(ctx);
21928             gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
21929             break;
21930         case OPC_SHRL_OB:
21931             check_dsp(ctx);
21932             gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
21933             break;
21934         case OPC_SHRLV_OB:
21935             check_dsp(ctx);
21936             gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
21937             break;
21938         case OPC_SHRL_QH:
21939             check_dsp_r2(ctx);
21940             gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
21941             break;
21942         case OPC_SHRLV_QH:
21943             check_dsp_r2(ctx);
21944             gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
21945             break;
21946         default:            /* Invalid */
21947             MIPS_INVAL("MASK SHLL.OB");
21948             generate_exception_end(ctx, EXCP_RI);
21949             break;
21950         }
21951         break;
21952 #endif
21953     }
21954
21955     tcg_temp_free(t0);
21956     tcg_temp_free(v1_t);
21957     tcg_temp_free(v2_t);
21958 }
21959
21960 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
21961                                  int ret, int v1, int v2, int check_ret)
21962 {
21963     TCGv_i32 t0;
21964     TCGv v1_t;
21965     TCGv v2_t;
21966
21967     if ((ret == 0) && (check_ret == 1)) {
21968         /* Treat as NOP. */
21969         return;
21970     }
21971
21972     t0 = tcg_temp_new_i32();
21973     v1_t = tcg_temp_new();
21974     v2_t = tcg_temp_new();
21975
21976     tcg_gen_movi_i32(t0, ret);
21977     gen_load_gpr(v1_t, v1);
21978     gen_load_gpr(v2_t, v2);
21979
21980     switch (op1) {
21981     /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
21982      * the same mask and op1. */
21983     case OPC_MULT_G_2E:
21984         check_dsp_r2(ctx);
21985         switch (op2) {
21986         case  OPC_MUL_PH:
21987             gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21988             break;
21989         case  OPC_MUL_S_PH:
21990             gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21991             break;
21992         case OPC_MULQ_S_W:
21993             gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21994             break;
21995         case OPC_MULQ_RS_W:
21996             gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21997             break;
21998         }
21999         break;
22000     case OPC_DPA_W_PH_DSP:
22001         switch (op2) {
22002         case OPC_DPAU_H_QBL:
22003             check_dsp(ctx);
22004             gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
22005             break;
22006         case OPC_DPAU_H_QBR:
22007             check_dsp(ctx);
22008             gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
22009             break;
22010         case OPC_DPSU_H_QBL:
22011             check_dsp(ctx);
22012             gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
22013             break;
22014         case OPC_DPSU_H_QBR:
22015             check_dsp(ctx);
22016             gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
22017             break;
22018         case OPC_DPA_W_PH:
22019             check_dsp_r2(ctx);
22020             gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
22021             break;
22022         case OPC_DPAX_W_PH:
22023             check_dsp_r2(ctx);
22024             gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
22025             break;
22026         case OPC_DPAQ_S_W_PH:
22027             check_dsp(ctx);
22028             gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22029             break;
22030         case OPC_DPAQX_S_W_PH:
22031             check_dsp_r2(ctx);
22032             gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
22033             break;
22034         case OPC_DPAQX_SA_W_PH:
22035             check_dsp_r2(ctx);
22036             gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
22037             break;
22038         case OPC_DPS_W_PH:
22039             check_dsp_r2(ctx);
22040             gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
22041             break;
22042         case OPC_DPSX_W_PH:
22043             check_dsp_r2(ctx);
22044             gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
22045             break;
22046         case OPC_DPSQ_S_W_PH:
22047             check_dsp(ctx);
22048             gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22049             break;
22050         case OPC_DPSQX_S_W_PH:
22051             check_dsp_r2(ctx);
22052             gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
22053             break;
22054         case OPC_DPSQX_SA_W_PH:
22055             check_dsp_r2(ctx);
22056             gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
22057             break;
22058         case OPC_MULSAQ_S_W_PH:
22059             check_dsp(ctx);
22060             gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22061             break;
22062         case OPC_DPAQ_SA_L_W:
22063             check_dsp(ctx);
22064             gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
22065             break;
22066         case OPC_DPSQ_SA_L_W:
22067             check_dsp(ctx);
22068             gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
22069             break;
22070         case OPC_MAQ_S_W_PHL:
22071             check_dsp(ctx);
22072             gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
22073             break;
22074         case OPC_MAQ_S_W_PHR:
22075             check_dsp(ctx);
22076             gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
22077             break;
22078         case OPC_MAQ_SA_W_PHL:
22079             check_dsp(ctx);
22080             gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
22081             break;
22082         case OPC_MAQ_SA_W_PHR:
22083             check_dsp(ctx);
22084             gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
22085             break;
22086         case OPC_MULSA_W_PH:
22087             check_dsp_r2(ctx);
22088             gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
22089             break;
22090         }
22091         break;
22092 #ifdef TARGET_MIPS64
22093     case OPC_DPAQ_W_QH_DSP:
22094         {
22095             int ac = ret & 0x03;
22096             tcg_gen_movi_i32(t0, ac);
22097
22098             switch (op2) {
22099             case OPC_DMADD:
22100                 check_dsp(ctx);
22101                 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
22102                 break;
22103             case OPC_DMADDU:
22104                 check_dsp(ctx);
22105                 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
22106                 break;
22107             case OPC_DMSUB:
22108                 check_dsp(ctx);
22109                 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
22110                 break;
22111             case OPC_DMSUBU:
22112                 check_dsp(ctx);
22113                 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
22114                 break;
22115             case OPC_DPA_W_QH:
22116                 check_dsp_r2(ctx);
22117                 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
22118                 break;
22119             case OPC_DPAQ_S_W_QH:
22120                 check_dsp(ctx);
22121                 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22122                 break;
22123             case OPC_DPAQ_SA_L_PW:
22124                 check_dsp(ctx);
22125                 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
22126                 break;
22127             case OPC_DPAU_H_OBL:
22128                 check_dsp(ctx);
22129                 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
22130                 break;
22131             case OPC_DPAU_H_OBR:
22132                 check_dsp(ctx);
22133                 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
22134                 break;
22135             case OPC_DPS_W_QH:
22136                 check_dsp_r2(ctx);
22137                 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
22138                 break;
22139             case OPC_DPSQ_S_W_QH:
22140                 check_dsp(ctx);
22141                 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22142                 break;
22143             case OPC_DPSQ_SA_L_PW:
22144                 check_dsp(ctx);
22145                 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
22146                 break;
22147             case OPC_DPSU_H_OBL:
22148                 check_dsp(ctx);
22149                 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
22150                 break;
22151             case OPC_DPSU_H_OBR:
22152                 check_dsp(ctx);
22153                 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
22154                 break;
22155             case OPC_MAQ_S_L_PWL:
22156                 check_dsp(ctx);
22157                 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
22158                 break;
22159             case OPC_MAQ_S_L_PWR:
22160                 check_dsp(ctx);
22161                 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
22162                 break;
22163             case OPC_MAQ_S_W_QHLL:
22164                 check_dsp(ctx);
22165                 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
22166                 break;
22167             case OPC_MAQ_SA_W_QHLL:
22168                 check_dsp(ctx);
22169                 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
22170                 break;
22171             case OPC_MAQ_S_W_QHLR:
22172                 check_dsp(ctx);
22173                 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
22174                 break;
22175             case OPC_MAQ_SA_W_QHLR:
22176                 check_dsp(ctx);
22177                 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
22178                 break;
22179             case OPC_MAQ_S_W_QHRL:
22180                 check_dsp(ctx);
22181                 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
22182                 break;
22183             case OPC_MAQ_SA_W_QHRL:
22184                 check_dsp(ctx);
22185                 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
22186                 break;
22187             case OPC_MAQ_S_W_QHRR:
22188                 check_dsp(ctx);
22189                 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
22190                 break;
22191             case OPC_MAQ_SA_W_QHRR:
22192                 check_dsp(ctx);
22193                 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
22194                 break;
22195             case OPC_MULSAQ_S_L_PW:
22196                 check_dsp(ctx);
22197                 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
22198                 break;
22199             case OPC_MULSAQ_S_W_QH:
22200                 check_dsp(ctx);
22201                 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22202                 break;
22203             }
22204         }
22205         break;
22206 #endif
22207     case OPC_ADDU_QB_DSP:
22208         switch (op2) {
22209         case OPC_MULEU_S_PH_QBL:
22210             check_dsp(ctx);
22211             gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22212             break;
22213         case OPC_MULEU_S_PH_QBR:
22214             check_dsp(ctx);
22215             gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22216             break;
22217         case OPC_MULQ_RS_PH:
22218             check_dsp(ctx);
22219             gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22220             break;
22221         case OPC_MULEQ_S_W_PHL:
22222             check_dsp(ctx);
22223             gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22224             break;
22225         case OPC_MULEQ_S_W_PHR:
22226             check_dsp(ctx);
22227             gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22228             break;
22229         case OPC_MULQ_S_PH:
22230             check_dsp_r2(ctx);
22231             gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22232             break;
22233         }
22234         break;
22235 #ifdef TARGET_MIPS64
22236     case OPC_ADDU_OB_DSP:
22237         switch (op2) {
22238         case OPC_MULEQ_S_PW_QHL:
22239             check_dsp(ctx);
22240             gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22241             break;
22242         case OPC_MULEQ_S_PW_QHR:
22243             check_dsp(ctx);
22244             gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22245             break;
22246         case OPC_MULEU_S_QH_OBL:
22247             check_dsp(ctx);
22248             gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22249             break;
22250         case OPC_MULEU_S_QH_OBR:
22251             check_dsp(ctx);
22252             gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22253             break;
22254         case OPC_MULQ_RS_QH:
22255             check_dsp(ctx);
22256             gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22257             break;
22258         }
22259         break;
22260 #endif
22261     }
22262
22263     tcg_temp_free_i32(t0);
22264     tcg_temp_free(v1_t);
22265     tcg_temp_free(v2_t);
22266 }
22267
22268 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
22269                                 int ret, int val)
22270 {
22271     int16_t imm;
22272     TCGv t0;
22273     TCGv val_t;
22274
22275     if (ret == 0) {
22276         /* Treat as NOP. */
22277         return;
22278     }
22279
22280     t0 = tcg_temp_new();
22281     val_t = tcg_temp_new();
22282     gen_load_gpr(val_t, val);
22283
22284     switch (op1) {
22285     case OPC_ABSQ_S_PH_DSP:
22286         switch (op2) {
22287         case OPC_BITREV:
22288             check_dsp(ctx);
22289             gen_helper_bitrev(cpu_gpr[ret], val_t);
22290             break;
22291         case OPC_REPL_QB:
22292             check_dsp(ctx);
22293             {
22294                 target_long result;
22295                 imm = (ctx->opcode >> 16) & 0xFF;
22296                 result = (uint32_t)imm << 24 |
22297                          (uint32_t)imm << 16 |
22298                          (uint32_t)imm << 8  |
22299                          (uint32_t)imm;
22300                 result = (int32_t)result;
22301                 tcg_gen_movi_tl(cpu_gpr[ret], result);
22302             }
22303             break;
22304         case OPC_REPLV_QB:
22305             check_dsp(ctx);
22306             tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
22307             tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
22308             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22309             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
22310             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22311             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22312             break;
22313         case OPC_REPL_PH:
22314             check_dsp(ctx);
22315             {
22316                 imm = (ctx->opcode >> 16) & 0x03FF;
22317                 imm = (int16_t)(imm << 6) >> 6;
22318                 tcg_gen_movi_tl(cpu_gpr[ret], \
22319                                 (target_long)((int32_t)imm << 16 | \
22320                                 (uint16_t)imm));
22321             }
22322             break;
22323         case OPC_REPLV_PH:
22324             check_dsp(ctx);
22325             tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
22326             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
22327             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22328             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22329             break;
22330         }
22331         break;
22332 #ifdef TARGET_MIPS64
22333     case OPC_ABSQ_S_QH_DSP:
22334         switch (op2) {
22335         case OPC_REPL_OB:
22336             check_dsp(ctx);
22337             {
22338                 target_long temp;
22339
22340                 imm = (ctx->opcode >> 16) & 0xFF;
22341                 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
22342                 temp = (temp << 16) | temp;
22343                 temp = (temp << 32) | temp;
22344                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
22345                 break;
22346             }
22347         case OPC_REPL_PW:
22348             check_dsp(ctx);
22349             {
22350                 target_long temp;
22351
22352                 imm = (ctx->opcode >> 16) & 0x03FF;
22353                 imm = (int16_t)(imm << 6) >> 6;
22354                 temp = ((target_long)imm << 32) \
22355                        | ((target_long)imm & 0xFFFFFFFF);
22356                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
22357                 break;
22358             }
22359         case OPC_REPL_QH:
22360             check_dsp(ctx);
22361             {
22362                 target_long temp;
22363
22364                 imm = (ctx->opcode >> 16) & 0x03FF;
22365                 imm = (int16_t)(imm << 6) >> 6;
22366
22367                 temp = ((uint64_t)(uint16_t)imm << 48) |
22368                        ((uint64_t)(uint16_t)imm << 32) |
22369                        ((uint64_t)(uint16_t)imm << 16) |
22370                        (uint64_t)(uint16_t)imm;
22371                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
22372                 break;
22373             }
22374         case OPC_REPLV_OB:
22375             check_dsp(ctx);
22376             tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
22377             tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
22378             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22379             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
22380             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22381             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
22382             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22383             break;
22384         case OPC_REPLV_PW:
22385             check_dsp(ctx);
22386             tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
22387             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
22388             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22389             break;
22390         case OPC_REPLV_QH:
22391             check_dsp(ctx);
22392             tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
22393             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
22394             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22395             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
22396             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22397             break;
22398         }
22399         break;
22400 #endif
22401     }
22402     tcg_temp_free(t0);
22403     tcg_temp_free(val_t);
22404 }
22405
22406 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
22407                                      uint32_t op1, uint32_t op2,
22408                                      int ret, int v1, int v2, int check_ret)
22409 {
22410     TCGv t1;
22411     TCGv v1_t;
22412     TCGv v2_t;
22413
22414     if ((ret == 0) && (check_ret == 1)) {
22415         /* Treat as NOP. */
22416         return;
22417     }
22418
22419     t1 = tcg_temp_new();
22420     v1_t = tcg_temp_new();
22421     v2_t = tcg_temp_new();
22422
22423     gen_load_gpr(v1_t, v1);
22424     gen_load_gpr(v2_t, v2);
22425
22426     switch (op1) {
22427     case OPC_CMPU_EQ_QB_DSP:
22428         switch (op2) {
22429         case OPC_CMPU_EQ_QB:
22430             check_dsp(ctx);
22431             gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
22432             break;
22433         case OPC_CMPU_LT_QB:
22434             check_dsp(ctx);
22435             gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
22436             break;
22437         case OPC_CMPU_LE_QB:
22438             check_dsp(ctx);
22439             gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
22440             break;
22441         case OPC_CMPGU_EQ_QB:
22442             check_dsp(ctx);
22443             gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
22444             break;
22445         case OPC_CMPGU_LT_QB:
22446             check_dsp(ctx);
22447             gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
22448             break;
22449         case OPC_CMPGU_LE_QB:
22450             check_dsp(ctx);
22451             gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
22452             break;
22453         case OPC_CMPGDU_EQ_QB:
22454             check_dsp_r2(ctx);
22455             gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
22456             tcg_gen_mov_tl(cpu_gpr[ret], t1);
22457             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
22458             tcg_gen_shli_tl(t1, t1, 24);
22459             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
22460             break;
22461         case OPC_CMPGDU_LT_QB:
22462             check_dsp_r2(ctx);
22463             gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
22464             tcg_gen_mov_tl(cpu_gpr[ret], t1);
22465             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
22466             tcg_gen_shli_tl(t1, t1, 24);
22467             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
22468             break;
22469         case OPC_CMPGDU_LE_QB:
22470             check_dsp_r2(ctx);
22471             gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
22472             tcg_gen_mov_tl(cpu_gpr[ret], t1);
22473             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
22474             tcg_gen_shli_tl(t1, t1, 24);
22475             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
22476             break;
22477         case OPC_CMP_EQ_PH:
22478             check_dsp(ctx);
22479             gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
22480             break;
22481         case OPC_CMP_LT_PH:
22482             check_dsp(ctx);
22483             gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
22484             break;
22485         case OPC_CMP_LE_PH:
22486             check_dsp(ctx);
22487             gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
22488             break;
22489         case OPC_PICK_QB:
22490             check_dsp(ctx);
22491             gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22492             break;
22493         case OPC_PICK_PH:
22494             check_dsp(ctx);
22495             gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22496             break;
22497         case OPC_PACKRL_PH:
22498             check_dsp(ctx);
22499             gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
22500             break;
22501         }
22502         break;
22503 #ifdef TARGET_MIPS64
22504     case OPC_CMPU_EQ_OB_DSP:
22505         switch (op2) {
22506         case OPC_CMP_EQ_PW:
22507             check_dsp(ctx);
22508             gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
22509             break;
22510         case OPC_CMP_LT_PW:
22511             check_dsp(ctx);
22512             gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
22513             break;
22514         case OPC_CMP_LE_PW:
22515             check_dsp(ctx);
22516             gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
22517             break;
22518         case OPC_CMP_EQ_QH:
22519             check_dsp(ctx);
22520             gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
22521             break;
22522         case OPC_CMP_LT_QH:
22523             check_dsp(ctx);
22524             gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
22525             break;
22526         case OPC_CMP_LE_QH:
22527             check_dsp(ctx);
22528             gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
22529             break;
22530         case OPC_CMPGDU_EQ_OB:
22531             check_dsp_r2(ctx);
22532             gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22533             break;
22534         case OPC_CMPGDU_LT_OB:
22535             check_dsp_r2(ctx);
22536             gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22537             break;
22538         case OPC_CMPGDU_LE_OB:
22539             check_dsp_r2(ctx);
22540             gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22541             break;
22542         case OPC_CMPGU_EQ_OB:
22543             check_dsp(ctx);
22544             gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
22545             break;
22546         case OPC_CMPGU_LT_OB:
22547             check_dsp(ctx);
22548             gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
22549             break;
22550         case OPC_CMPGU_LE_OB:
22551             check_dsp(ctx);
22552             gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
22553             break;
22554         case OPC_CMPU_EQ_OB:
22555             check_dsp(ctx);
22556             gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
22557             break;
22558         case OPC_CMPU_LT_OB:
22559             check_dsp(ctx);
22560             gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
22561             break;
22562         case OPC_CMPU_LE_OB:
22563             check_dsp(ctx);
22564             gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
22565             break;
22566         case OPC_PACKRL_PW:
22567             check_dsp(ctx);
22568             gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
22569             break;
22570         case OPC_PICK_OB:
22571             check_dsp(ctx);
22572             gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22573             break;
22574         case OPC_PICK_PW:
22575             check_dsp(ctx);
22576             gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22577             break;
22578         case OPC_PICK_QH:
22579             check_dsp(ctx);
22580             gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22581             break;
22582         }
22583         break;
22584 #endif
22585     }
22586
22587     tcg_temp_free(t1);
22588     tcg_temp_free(v1_t);
22589     tcg_temp_free(v2_t);
22590 }
22591
22592 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
22593                                uint32_t op1, int rt, int rs, int sa)
22594 {
22595     TCGv t0;
22596
22597     check_dsp_r2(ctx);
22598
22599     if (rt == 0) {
22600         /* Treat as NOP. */
22601         return;
22602     }
22603
22604     t0 = tcg_temp_new();
22605     gen_load_gpr(t0, rs);
22606
22607     switch (op1) {
22608     case OPC_APPEND_DSP:
22609         switch (MASK_APPEND(ctx->opcode)) {
22610         case OPC_APPEND:
22611             if (sa != 0) {
22612                 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
22613             }
22614             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
22615             break;
22616         case OPC_PREPEND:
22617             if (sa != 0) {
22618                 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
22619                 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
22620                 tcg_gen_shli_tl(t0, t0, 32 - sa);
22621                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
22622             }
22623             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
22624             break;
22625         case OPC_BALIGN:
22626             sa &= 3;
22627             if (sa != 0 && sa != 2) {
22628                 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
22629                 tcg_gen_ext32u_tl(t0, t0);
22630                 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
22631                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
22632             }
22633             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
22634             break;
22635         default:            /* Invalid */
22636             MIPS_INVAL("MASK APPEND");
22637             generate_exception_end(ctx, EXCP_RI);
22638             break;
22639         }
22640         break;
22641 #ifdef TARGET_MIPS64
22642     case OPC_DAPPEND_DSP:
22643         switch (MASK_DAPPEND(ctx->opcode)) {
22644         case OPC_DAPPEND:
22645             if (sa != 0) {
22646                 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
22647             }
22648             break;
22649         case OPC_PREPENDD:
22650             tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
22651             tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
22652             tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
22653             break;
22654         case OPC_PREPENDW:
22655             if (sa != 0) {
22656                 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
22657                 tcg_gen_shli_tl(t0, t0, 64 - sa);
22658                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
22659             }
22660             break;
22661         case OPC_DBALIGN:
22662             sa &= 7;
22663             if (sa != 0 && sa != 2 && sa != 4) {
22664                 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
22665                 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
22666                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
22667             }
22668             break;
22669         default:            /* Invalid */
22670             MIPS_INVAL("MASK DAPPEND");
22671             generate_exception_end(ctx, EXCP_RI);
22672             break;
22673         }
22674         break;
22675 #endif
22676     }
22677     tcg_temp_free(t0);
22678 }
22679
22680 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
22681                                 int ret, int v1, int v2, int check_ret)
22682
22683 {
22684     TCGv t0;
22685     TCGv t1;
22686     TCGv v1_t;
22687     TCGv v2_t;
22688     int16_t imm;
22689
22690     if ((ret == 0) && (check_ret == 1)) {
22691         /* Treat as NOP. */
22692         return;
22693     }
22694
22695     t0 = tcg_temp_new();
22696     t1 = tcg_temp_new();
22697     v1_t = tcg_temp_new();
22698     v2_t = tcg_temp_new();
22699
22700     gen_load_gpr(v1_t, v1);
22701     gen_load_gpr(v2_t, v2);
22702
22703     switch (op1) {
22704     case OPC_EXTR_W_DSP:
22705         check_dsp(ctx);
22706         switch (op2) {
22707         case OPC_EXTR_W:
22708             tcg_gen_movi_tl(t0, v2);
22709             tcg_gen_movi_tl(t1, v1);
22710             gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
22711             break;
22712         case OPC_EXTR_R_W:
22713             tcg_gen_movi_tl(t0, v2);
22714             tcg_gen_movi_tl(t1, v1);
22715             gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
22716             break;
22717         case OPC_EXTR_RS_W:
22718             tcg_gen_movi_tl(t0, v2);
22719             tcg_gen_movi_tl(t1, v1);
22720             gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
22721             break;
22722         case OPC_EXTR_S_H:
22723             tcg_gen_movi_tl(t0, v2);
22724             tcg_gen_movi_tl(t1, v1);
22725             gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
22726             break;
22727         case OPC_EXTRV_S_H:
22728             tcg_gen_movi_tl(t0, v2);
22729             gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
22730             break;
22731         case OPC_EXTRV_W:
22732             tcg_gen_movi_tl(t0, v2);
22733             gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
22734             break;
22735         case OPC_EXTRV_R_W:
22736             tcg_gen_movi_tl(t0, v2);
22737             gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
22738             break;
22739         case OPC_EXTRV_RS_W:
22740             tcg_gen_movi_tl(t0, v2);
22741             gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
22742             break;
22743         case OPC_EXTP:
22744             tcg_gen_movi_tl(t0, v2);
22745             tcg_gen_movi_tl(t1, v1);
22746             gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
22747             break;
22748         case OPC_EXTPV:
22749             tcg_gen_movi_tl(t0, v2);
22750             gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
22751             break;
22752         case OPC_EXTPDP:
22753             tcg_gen_movi_tl(t0, v2);
22754             tcg_gen_movi_tl(t1, v1);
22755             gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
22756             break;
22757         case OPC_EXTPDPV:
22758             tcg_gen_movi_tl(t0, v2);
22759             gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
22760             break;
22761         case OPC_SHILO:
22762             imm = (ctx->opcode >> 20) & 0x3F;
22763             tcg_gen_movi_tl(t0, ret);
22764             tcg_gen_movi_tl(t1, imm);
22765             gen_helper_shilo(t0, t1, cpu_env);
22766             break;
22767         case OPC_SHILOV:
22768             tcg_gen_movi_tl(t0, ret);
22769             gen_helper_shilo(t0, v1_t, cpu_env);
22770             break;
22771         case OPC_MTHLIP:
22772             tcg_gen_movi_tl(t0, ret);
22773             gen_helper_mthlip(t0, v1_t, cpu_env);
22774             break;
22775         case OPC_WRDSP:
22776             imm = (ctx->opcode >> 11) & 0x3FF;
22777             tcg_gen_movi_tl(t0, imm);
22778             gen_helper_wrdsp(v1_t, t0, cpu_env);
22779             break;
22780         case OPC_RDDSP:
22781             imm = (ctx->opcode >> 16) & 0x03FF;
22782             tcg_gen_movi_tl(t0, imm);
22783             gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
22784             break;
22785         }
22786         break;
22787 #ifdef TARGET_MIPS64
22788     case OPC_DEXTR_W_DSP:
22789         check_dsp(ctx);
22790         switch (op2) {
22791         case OPC_DMTHLIP:
22792             tcg_gen_movi_tl(t0, ret);
22793             gen_helper_dmthlip(v1_t, t0, cpu_env);
22794             break;
22795         case OPC_DSHILO:
22796             {
22797                 int shift = (ctx->opcode >> 19) & 0x7F;
22798                 int ac = (ctx->opcode >> 11) & 0x03;
22799                 tcg_gen_movi_tl(t0, shift);
22800                 tcg_gen_movi_tl(t1, ac);
22801                 gen_helper_dshilo(t0, t1, cpu_env);
22802                 break;
22803             }
22804         case OPC_DSHILOV:
22805             {
22806                 int ac = (ctx->opcode >> 11) & 0x03;
22807                 tcg_gen_movi_tl(t0, ac);
22808                 gen_helper_dshilo(v1_t, t0, cpu_env);
22809                 break;
22810             }
22811         case OPC_DEXTP:
22812             tcg_gen_movi_tl(t0, v2);
22813             tcg_gen_movi_tl(t1, v1);
22814
22815             gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
22816             break;
22817         case OPC_DEXTPV:
22818             tcg_gen_movi_tl(t0, v2);
22819             gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
22820             break;
22821         case OPC_DEXTPDP:
22822             tcg_gen_movi_tl(t0, v2);
22823             tcg_gen_movi_tl(t1, v1);
22824             gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
22825             break;
22826         case OPC_DEXTPDPV:
22827             tcg_gen_movi_tl(t0, v2);
22828             gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
22829             break;
22830         case OPC_DEXTR_L:
22831             tcg_gen_movi_tl(t0, v2);
22832             tcg_gen_movi_tl(t1, v1);
22833             gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
22834             break;
22835         case OPC_DEXTR_R_L:
22836             tcg_gen_movi_tl(t0, v2);
22837             tcg_gen_movi_tl(t1, v1);
22838             gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
22839             break;
22840         case OPC_DEXTR_RS_L:
22841             tcg_gen_movi_tl(t0, v2);
22842             tcg_gen_movi_tl(t1, v1);
22843             gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
22844             break;
22845         case OPC_DEXTR_W:
22846             tcg_gen_movi_tl(t0, v2);
22847             tcg_gen_movi_tl(t1, v1);
22848             gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
22849             break;
22850         case OPC_DEXTR_R_W:
22851             tcg_gen_movi_tl(t0, v2);
22852             tcg_gen_movi_tl(t1, v1);
22853             gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
22854             break;
22855         case OPC_DEXTR_RS_W:
22856             tcg_gen_movi_tl(t0, v2);
22857             tcg_gen_movi_tl(t1, v1);
22858             gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
22859             break;
22860         case OPC_DEXTR_S_H:
22861             tcg_gen_movi_tl(t0, v2);
22862             tcg_gen_movi_tl(t1, v1);
22863             gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
22864             break;
22865         case OPC_DEXTRV_S_H:
22866             tcg_gen_movi_tl(t0, v2);
22867             tcg_gen_movi_tl(t1, v1);
22868             gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
22869             break;
22870         case OPC_DEXTRV_L:
22871             tcg_gen_movi_tl(t0, v2);
22872             gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
22873             break;
22874         case OPC_DEXTRV_R_L:
22875             tcg_gen_movi_tl(t0, v2);
22876             gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
22877             break;
22878         case OPC_DEXTRV_RS_L:
22879             tcg_gen_movi_tl(t0, v2);
22880             gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
22881             break;
22882         case OPC_DEXTRV_W:
22883             tcg_gen_movi_tl(t0, v2);
22884             gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
22885             break;
22886         case OPC_DEXTRV_R_W:
22887             tcg_gen_movi_tl(t0, v2);
22888             gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
22889             break;
22890         case OPC_DEXTRV_RS_W:
22891             tcg_gen_movi_tl(t0, v2);
22892             gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
22893             break;
22894         }
22895         break;
22896 #endif
22897     }
22898
22899     tcg_temp_free(t0);
22900     tcg_temp_free(t1);
22901     tcg_temp_free(v1_t);
22902     tcg_temp_free(v2_t);
22903 }
22904
22905 /* End MIPSDSP functions. */
22906
22907 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
22908 {
22909     int rs, rt, rd, sa;
22910     uint32_t op1, op2;
22911
22912     rs = (ctx->opcode >> 21) & 0x1f;
22913     rt = (ctx->opcode >> 16) & 0x1f;
22914     rd = (ctx->opcode >> 11) & 0x1f;
22915     sa = (ctx->opcode >> 6) & 0x1f;
22916
22917     op1 = MASK_SPECIAL(ctx->opcode);
22918     switch (op1) {
22919     case OPC_LSA:
22920         gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
22921         break;
22922     case OPC_MULT:
22923     case OPC_MULTU:
22924     case OPC_DIV:
22925     case OPC_DIVU:
22926         op2 = MASK_R6_MULDIV(ctx->opcode);
22927         switch (op2) {
22928         case R6_OPC_MUL:
22929         case R6_OPC_MUH:
22930         case R6_OPC_MULU:
22931         case R6_OPC_MUHU:
22932         case R6_OPC_DIV:
22933         case R6_OPC_MOD:
22934         case R6_OPC_DIVU:
22935         case R6_OPC_MODU:
22936             gen_r6_muldiv(ctx, op2, rd, rs, rt);
22937             break;
22938         default:
22939             MIPS_INVAL("special_r6 muldiv");
22940             generate_exception_end(ctx, EXCP_RI);
22941             break;
22942         }
22943         break;
22944     case OPC_SELEQZ:
22945     case OPC_SELNEZ:
22946         gen_cond_move(ctx, op1, rd, rs, rt);
22947         break;
22948     case R6_OPC_CLO:
22949     case R6_OPC_CLZ:
22950         if (rt == 0 && sa == 1) {
22951             /* Major opcode and function field is shared with preR6 MFHI/MTHI.
22952                We need additionally to check other fields */
22953             gen_cl(ctx, op1, rd, rs);
22954         } else {
22955             generate_exception_end(ctx, EXCP_RI);
22956         }
22957         break;
22958     case R6_OPC_SDBBP:
22959         if (is_uhi(extract32(ctx->opcode, 6, 20))) {
22960             gen_helper_do_semihosting(cpu_env);
22961         } else {
22962             if (ctx->hflags & MIPS_HFLAG_SBRI) {
22963                 generate_exception_end(ctx, EXCP_RI);
22964             } else {
22965                 generate_exception_end(ctx, EXCP_DBp);
22966             }
22967         }
22968         break;
22969 #if defined(TARGET_MIPS64)
22970     case OPC_DLSA:
22971         check_mips_64(ctx);
22972         gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
22973         break;
22974     case R6_OPC_DCLO:
22975     case R6_OPC_DCLZ:
22976         if (rt == 0 && sa == 1) {
22977             /* Major opcode and function field is shared with preR6 MFHI/MTHI.
22978                We need additionally to check other fields */
22979             check_mips_64(ctx);
22980             gen_cl(ctx, op1, rd, rs);
22981         } else {
22982             generate_exception_end(ctx, EXCP_RI);
22983         }
22984         break;
22985     case OPC_DMULT:
22986     case OPC_DMULTU:
22987     case OPC_DDIV:
22988     case OPC_DDIVU:
22989
22990         op2 = MASK_R6_MULDIV(ctx->opcode);
22991         switch (op2) {
22992         case R6_OPC_DMUL:
22993         case R6_OPC_DMUH:
22994         case R6_OPC_DMULU:
22995         case R6_OPC_DMUHU:
22996         case R6_OPC_DDIV:
22997         case R6_OPC_DMOD:
22998         case R6_OPC_DDIVU:
22999         case R6_OPC_DMODU:
23000             check_mips_64(ctx);
23001             gen_r6_muldiv(ctx, op2, rd, rs, rt);
23002             break;
23003         default:
23004             MIPS_INVAL("special_r6 muldiv");
23005             generate_exception_end(ctx, EXCP_RI);
23006             break;
23007         }
23008         break;
23009 #endif
23010     default:            /* Invalid */
23011         MIPS_INVAL("special_r6");
23012         generate_exception_end(ctx, EXCP_RI);
23013         break;
23014     }
23015 }
23016
23017 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
23018 {
23019     int rs, rt, rd, sa;
23020     uint32_t op1;
23021
23022     rs = (ctx->opcode >> 21) & 0x1f;
23023     rt = (ctx->opcode >> 16) & 0x1f;
23024     rd = (ctx->opcode >> 11) & 0x1f;
23025     sa = (ctx->opcode >> 6) & 0x1f;
23026
23027     op1 = MASK_SPECIAL(ctx->opcode);
23028     switch (op1) {
23029     case OPC_MOVN:         /* Conditional move */
23030     case OPC_MOVZ:
23031         check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
23032                    INSN_LOONGSON2E | INSN_LOONGSON2F);
23033         gen_cond_move(ctx, op1, rd, rs, rt);
23034         break;
23035     case OPC_MFHI:          /* Move from HI/LO */
23036     case OPC_MFLO:
23037         gen_HILO(ctx, op1, rs & 3, rd);
23038         break;
23039     case OPC_MTHI:
23040     case OPC_MTLO:          /* Move to HI/LO */
23041         gen_HILO(ctx, op1, rd & 3, rs);
23042         break;
23043     case OPC_MOVCI:
23044         check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
23045         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
23046             check_cp1_enabled(ctx);
23047             gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
23048                       (ctx->opcode >> 16) & 1);
23049         } else {
23050             generate_exception_err(ctx, EXCP_CpU, 1);
23051         }
23052         break;
23053     case OPC_MULT:
23054     case OPC_MULTU:
23055         if (sa) {
23056             check_insn(ctx, INSN_VR54XX);
23057             op1 = MASK_MUL_VR54XX(ctx->opcode);
23058             gen_mul_vr54xx(ctx, op1, rd, rs, rt);
23059         } else {
23060             gen_muldiv(ctx, op1, rd & 3, rs, rt);
23061         }
23062         break;
23063     case OPC_DIV:
23064     case OPC_DIVU:
23065         gen_muldiv(ctx, op1, 0, rs, rt);
23066         break;
23067 #if defined(TARGET_MIPS64)
23068     case OPC_DMULT:
23069     case OPC_DMULTU:
23070     case OPC_DDIV:
23071     case OPC_DDIVU:
23072         check_insn(ctx, ISA_MIPS3);
23073         check_mips_64(ctx);
23074         gen_muldiv(ctx, op1, 0, rs, rt);
23075         break;
23076 #endif
23077     case OPC_JR:
23078         gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
23079         break;
23080     case OPC_SPIM:
23081 #ifdef MIPS_STRICT_STANDARD
23082         MIPS_INVAL("SPIM");
23083         generate_exception_end(ctx, EXCP_RI);
23084 #else
23085         /* Implemented as RI exception for now. */
23086         MIPS_INVAL("spim (unofficial)");
23087         generate_exception_end(ctx, EXCP_RI);
23088 #endif
23089         break;
23090     default:            /* Invalid */
23091         MIPS_INVAL("special_legacy");
23092         generate_exception_end(ctx, EXCP_RI);
23093         break;
23094     }
23095 }
23096
23097 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
23098 {
23099     int rs, rt, rd, sa;
23100     uint32_t op1;
23101
23102     rs = (ctx->opcode >> 21) & 0x1f;
23103     rt = (ctx->opcode >> 16) & 0x1f;
23104     rd = (ctx->opcode >> 11) & 0x1f;
23105     sa = (ctx->opcode >> 6) & 0x1f;
23106
23107     op1 = MASK_SPECIAL(ctx->opcode);
23108     switch (op1) {
23109     case OPC_SLL:          /* Shift with immediate */
23110         if (sa == 5 && rd == 0 &&
23111             rs == 0 && rt == 0) { /* PAUSE */
23112             if ((ctx->insn_flags & ISA_MIPS32R6) &&
23113                 (ctx->hflags & MIPS_HFLAG_BMASK)) {
23114                 generate_exception_end(ctx, EXCP_RI);
23115                 break;
23116             }
23117         }
23118         /* Fallthrough */
23119     case OPC_SRA:
23120         gen_shift_imm(ctx, op1, rd, rt, sa);
23121         break;
23122     case OPC_SRL:
23123         switch ((ctx->opcode >> 21) & 0x1f) {
23124         case 1:
23125             /* rotr is decoded as srl on non-R2 CPUs */
23126             if (ctx->insn_flags & ISA_MIPS32R2) {
23127                 op1 = OPC_ROTR;
23128             }
23129             /* Fallthrough */
23130         case 0:
23131             gen_shift_imm(ctx, op1, rd, rt, sa);
23132             break;
23133         default:
23134             generate_exception_end(ctx, EXCP_RI);
23135             break;
23136         }
23137         break;
23138     case OPC_ADD:
23139     case OPC_ADDU:
23140     case OPC_SUB:
23141     case OPC_SUBU:
23142         gen_arith(ctx, op1, rd, rs, rt);
23143         break;
23144     case OPC_SLLV:         /* Shifts */
23145     case OPC_SRAV:
23146         gen_shift(ctx, op1, rd, rs, rt);
23147         break;
23148     case OPC_SRLV:
23149         switch ((ctx->opcode >> 6) & 0x1f) {
23150         case 1:
23151             /* rotrv is decoded as srlv on non-R2 CPUs */
23152             if (ctx->insn_flags & ISA_MIPS32R2) {
23153                 op1 = OPC_ROTRV;
23154             }
23155             /* Fallthrough */
23156         case 0:
23157             gen_shift(ctx, op1, rd, rs, rt);
23158             break;
23159         default:
23160             generate_exception_end(ctx, EXCP_RI);
23161             break;
23162         }
23163         break;
23164     case OPC_SLT:          /* Set on less than */
23165     case OPC_SLTU:
23166         gen_slt(ctx, op1, rd, rs, rt);
23167         break;
23168     case OPC_AND:          /* Logic*/
23169     case OPC_OR:
23170     case OPC_NOR:
23171     case OPC_XOR:
23172         gen_logic(ctx, op1, rd, rs, rt);
23173         break;
23174     case OPC_JALR:
23175         gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
23176         break;
23177     case OPC_TGE: /* Traps */
23178     case OPC_TGEU:
23179     case OPC_TLT:
23180     case OPC_TLTU:
23181     case OPC_TEQ:
23182     case OPC_TNE:
23183         check_insn(ctx, ISA_MIPS2);
23184         gen_trap(ctx, op1, rs, rt, -1);
23185         break;
23186     case OPC_LSA: /* OPC_PMON */
23187         if ((ctx->insn_flags & ISA_MIPS32R6) ||
23188             (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
23189             decode_opc_special_r6(env, ctx);
23190         } else {
23191             /* Pmon entry point, also R4010 selsl */
23192 #ifdef MIPS_STRICT_STANDARD
23193             MIPS_INVAL("PMON / selsl");
23194             generate_exception_end(ctx, EXCP_RI);
23195 #else
23196             gen_helper_0e0i(pmon, sa);
23197 #endif
23198         }
23199         break;
23200     case OPC_SYSCALL:
23201         generate_exception_end(ctx, EXCP_SYSCALL);
23202         break;
23203     case OPC_BREAK:
23204         generate_exception_end(ctx, EXCP_BREAK);
23205         break;
23206     case OPC_SYNC:
23207         check_insn(ctx, ISA_MIPS2);
23208         gen_sync(extract32(ctx->opcode, 6, 5));
23209         break;
23210
23211 #if defined(TARGET_MIPS64)
23212         /* MIPS64 specific opcodes */
23213     case OPC_DSLL:
23214     case OPC_DSRA:
23215     case OPC_DSLL32:
23216     case OPC_DSRA32:
23217         check_insn(ctx, ISA_MIPS3);
23218         check_mips_64(ctx);
23219         gen_shift_imm(ctx, op1, rd, rt, sa);
23220         break;
23221     case OPC_DSRL:
23222         switch ((ctx->opcode >> 21) & 0x1f) {
23223         case 1:
23224             /* drotr is decoded as dsrl on non-R2 CPUs */
23225             if (ctx->insn_flags & ISA_MIPS32R2) {
23226                 op1 = OPC_DROTR;
23227             }
23228             /* Fallthrough */
23229         case 0:
23230             check_insn(ctx, ISA_MIPS3);
23231             check_mips_64(ctx);
23232             gen_shift_imm(ctx, op1, rd, rt, sa);
23233             break;
23234         default:
23235             generate_exception_end(ctx, EXCP_RI);
23236             break;
23237         }
23238         break;
23239     case OPC_DSRL32:
23240         switch ((ctx->opcode >> 21) & 0x1f) {
23241         case 1:
23242             /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
23243             if (ctx->insn_flags & ISA_MIPS32R2) {
23244                 op1 = OPC_DROTR32;
23245             }
23246             /* Fallthrough */
23247         case 0:
23248             check_insn(ctx, ISA_MIPS3);
23249             check_mips_64(ctx);
23250             gen_shift_imm(ctx, op1, rd, rt, sa);
23251             break;
23252         default:
23253             generate_exception_end(ctx, EXCP_RI);
23254             break;
23255         }
23256         break;
23257     case OPC_DADD:
23258     case OPC_DADDU:
23259     case OPC_DSUB:
23260     case OPC_DSUBU:
23261         check_insn(ctx, ISA_MIPS3);
23262         check_mips_64(ctx);
23263         gen_arith(ctx, op1, rd, rs, rt);
23264         break;
23265     case OPC_DSLLV:
23266     case OPC_DSRAV:
23267         check_insn(ctx, ISA_MIPS3);
23268         check_mips_64(ctx);
23269         gen_shift(ctx, op1, rd, rs, rt);
23270         break;
23271     case OPC_DSRLV:
23272         switch ((ctx->opcode >> 6) & 0x1f) {
23273         case 1:
23274             /* drotrv is decoded as dsrlv on non-R2 CPUs */
23275             if (ctx->insn_flags & ISA_MIPS32R2) {
23276                 op1 = OPC_DROTRV;
23277             }
23278             /* Fallthrough */
23279         case 0:
23280             check_insn(ctx, ISA_MIPS3);
23281             check_mips_64(ctx);
23282             gen_shift(ctx, op1, rd, rs, rt);
23283             break;
23284         default:
23285             generate_exception_end(ctx, EXCP_RI);
23286             break;
23287         }
23288         break;
23289     case OPC_DLSA:
23290         if ((ctx->insn_flags & ISA_MIPS32R6) ||
23291             (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
23292             decode_opc_special_r6(env, ctx);
23293         }
23294         break;
23295 #endif
23296     default:
23297         if (ctx->insn_flags & ISA_MIPS32R6) {
23298             decode_opc_special_r6(env, ctx);
23299         } else {
23300             decode_opc_special_legacy(env, ctx);
23301         }
23302     }
23303 }
23304
23305 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
23306 {
23307     int rs, rt, rd;
23308     uint32_t op1;
23309
23310     check_insn_opc_removed(ctx, ISA_MIPS32R6);
23311
23312     rs = (ctx->opcode >> 21) & 0x1f;
23313     rt = (ctx->opcode >> 16) & 0x1f;
23314     rd = (ctx->opcode >> 11) & 0x1f;
23315
23316     op1 = MASK_SPECIAL2(ctx->opcode);
23317     switch (op1) {
23318     case OPC_MADD: /* Multiply and add/sub */
23319     case OPC_MADDU:
23320     case OPC_MSUB:
23321     case OPC_MSUBU:
23322         check_insn(ctx, ISA_MIPS32);
23323         gen_muldiv(ctx, op1, rd & 3, rs, rt);
23324         break;
23325     case OPC_MUL:
23326         gen_arith(ctx, op1, rd, rs, rt);
23327         break;
23328     case OPC_DIV_G_2F:
23329     case OPC_DIVU_G_2F:
23330     case OPC_MULT_G_2F:
23331     case OPC_MULTU_G_2F:
23332     case OPC_MOD_G_2F:
23333     case OPC_MODU_G_2F:
23334         check_insn(ctx, INSN_LOONGSON2F);
23335         gen_loongson_integer(ctx, op1, rd, rs, rt);
23336         break;
23337     case OPC_CLO:
23338     case OPC_CLZ:
23339         check_insn(ctx, ISA_MIPS32);
23340         gen_cl(ctx, op1, rd, rs);
23341         break;
23342     case OPC_SDBBP:
23343         if (is_uhi(extract32(ctx->opcode, 6, 20))) {
23344             gen_helper_do_semihosting(cpu_env);
23345         } else {
23346             /* XXX: not clear which exception should be raised
23347              *      when in debug mode...
23348              */
23349             check_insn(ctx, ISA_MIPS32);
23350             generate_exception_end(ctx, EXCP_DBp);
23351         }
23352         break;
23353 #if defined(TARGET_MIPS64)
23354     case OPC_DCLO:
23355     case OPC_DCLZ:
23356         check_insn(ctx, ISA_MIPS64);
23357         check_mips_64(ctx);
23358         gen_cl(ctx, op1, rd, rs);
23359         break;
23360     case OPC_DMULT_G_2F:
23361     case OPC_DMULTU_G_2F:
23362     case OPC_DDIV_G_2F:
23363     case OPC_DDIVU_G_2F:
23364     case OPC_DMOD_G_2F:
23365     case OPC_DMODU_G_2F:
23366         check_insn(ctx, INSN_LOONGSON2F);
23367         gen_loongson_integer(ctx, op1, rd, rs, rt);
23368         break;
23369 #endif
23370     default:            /* Invalid */
23371         MIPS_INVAL("special2_legacy");
23372         generate_exception_end(ctx, EXCP_RI);
23373         break;
23374     }
23375 }
23376
23377 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
23378 {
23379     int rs, rt, rd, sa;
23380     uint32_t op1, op2;
23381     int16_t imm;
23382
23383     rs = (ctx->opcode >> 21) & 0x1f;
23384     rt = (ctx->opcode >> 16) & 0x1f;
23385     rd = (ctx->opcode >> 11) & 0x1f;
23386     sa = (ctx->opcode >> 6) & 0x1f;
23387     imm = (int16_t)ctx->opcode >> 7;
23388
23389     op1 = MASK_SPECIAL3(ctx->opcode);
23390     switch (op1) {
23391     case R6_OPC_PREF:
23392         if (rt >= 24) {
23393             /* hint codes 24-31 are reserved and signal RI */
23394             generate_exception_end(ctx, EXCP_RI);
23395         }
23396         /* Treat as NOP. */
23397         break;
23398     case R6_OPC_CACHE:
23399         check_cp0_enabled(ctx);
23400         if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
23401             gen_cache_operation(ctx, rt, rs, imm);
23402         }
23403         break;
23404     case R6_OPC_SC:
23405         gen_st_cond(ctx, op1, rt, rs, imm);
23406         break;
23407     case R6_OPC_LL:
23408         gen_ld(ctx, op1, rt, rs, imm);
23409         break;
23410     case OPC_BSHFL:
23411         {
23412             if (rd == 0) {
23413                 /* Treat as NOP. */
23414                 break;
23415             }
23416             op2 = MASK_BSHFL(ctx->opcode);
23417             switch (op2) {
23418             case OPC_ALIGN:
23419             case OPC_ALIGN_END:
23420                 gen_align(ctx, 32, rd, rs, rt, sa & 3);
23421                 break;
23422             case OPC_BITSWAP:
23423                 gen_bitswap(ctx, op2, rd, rt);
23424                 break;
23425             }
23426         }
23427         break;
23428 #if defined(TARGET_MIPS64)
23429     case R6_OPC_SCD:
23430         gen_st_cond(ctx, op1, rt, rs, imm);
23431         break;
23432     case R6_OPC_LLD:
23433         gen_ld(ctx, op1, rt, rs, imm);
23434         break;
23435     case OPC_DBSHFL:
23436         check_mips_64(ctx);
23437         {
23438             if (rd == 0) {
23439                 /* Treat as NOP. */
23440                 break;
23441             }
23442             op2 = MASK_DBSHFL(ctx->opcode);
23443             switch (op2) {
23444             case OPC_DALIGN:
23445             case OPC_DALIGN_END:
23446                 gen_align(ctx, 64, rd, rs, rt, sa & 7);
23447                 break;
23448             case OPC_DBITSWAP:
23449                 gen_bitswap(ctx, op2, rd, rt);
23450                 break;
23451             }
23452
23453         }
23454         break;
23455 #endif
23456     default:            /* Invalid */
23457         MIPS_INVAL("special3_r6");
23458         generate_exception_end(ctx, EXCP_RI);
23459         break;
23460     }
23461 }
23462
23463 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
23464 {
23465     int rs, rt, rd;
23466     uint32_t op1, op2;
23467
23468     rs = (ctx->opcode >> 21) & 0x1f;
23469     rt = (ctx->opcode >> 16) & 0x1f;
23470     rd = (ctx->opcode >> 11) & 0x1f;
23471
23472     op1 = MASK_SPECIAL3(ctx->opcode);
23473     switch (op1) {
23474     case OPC_DIV_G_2E:
23475     case OPC_DIVU_G_2E:
23476     case OPC_MOD_G_2E:
23477     case OPC_MODU_G_2E:
23478     case OPC_MULT_G_2E:
23479     case OPC_MULTU_G_2E:
23480         /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
23481          * the same mask and op1. */
23482         if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
23483             op2 = MASK_ADDUH_QB(ctx->opcode);
23484             switch (op2) {
23485             case OPC_ADDUH_QB:
23486             case OPC_ADDUH_R_QB:
23487             case OPC_ADDQH_PH:
23488             case OPC_ADDQH_R_PH:
23489             case OPC_ADDQH_W:
23490             case OPC_ADDQH_R_W:
23491             case OPC_SUBUH_QB:
23492             case OPC_SUBUH_R_QB:
23493             case OPC_SUBQH_PH:
23494             case OPC_SUBQH_R_PH:
23495             case OPC_SUBQH_W:
23496             case OPC_SUBQH_R_W:
23497                 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23498                 break;
23499             case OPC_MUL_PH:
23500             case OPC_MUL_S_PH:
23501             case OPC_MULQ_S_W:
23502             case OPC_MULQ_RS_W:
23503                 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
23504                 break;
23505             default:
23506                 MIPS_INVAL("MASK ADDUH.QB");
23507                 generate_exception_end(ctx, EXCP_RI);
23508                 break;
23509             }
23510         } else if (ctx->insn_flags & INSN_LOONGSON2E) {
23511             gen_loongson_integer(ctx, op1, rd, rs, rt);
23512         } else {
23513             generate_exception_end(ctx, EXCP_RI);
23514         }
23515         break;
23516     case OPC_LX_DSP:
23517         op2 = MASK_LX(ctx->opcode);
23518         switch (op2) {
23519 #if defined(TARGET_MIPS64)
23520         case OPC_LDX:
23521 #endif
23522         case OPC_LBUX:
23523         case OPC_LHX:
23524         case OPC_LWX:
23525             gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
23526             break;
23527         default:            /* Invalid */
23528             MIPS_INVAL("MASK LX");
23529             generate_exception_end(ctx, EXCP_RI);
23530             break;
23531         }
23532         break;
23533     case OPC_ABSQ_S_PH_DSP:
23534         op2 = MASK_ABSQ_S_PH(ctx->opcode);
23535         switch (op2) {
23536         case OPC_ABSQ_S_QB:
23537         case OPC_ABSQ_S_PH:
23538         case OPC_ABSQ_S_W:
23539         case OPC_PRECEQ_W_PHL:
23540         case OPC_PRECEQ_W_PHR:
23541         case OPC_PRECEQU_PH_QBL:
23542         case OPC_PRECEQU_PH_QBR:
23543         case OPC_PRECEQU_PH_QBLA:
23544         case OPC_PRECEQU_PH_QBRA:
23545         case OPC_PRECEU_PH_QBL:
23546         case OPC_PRECEU_PH_QBR:
23547         case OPC_PRECEU_PH_QBLA:
23548         case OPC_PRECEU_PH_QBRA:
23549             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23550             break;
23551         case OPC_BITREV:
23552         case OPC_REPL_QB:
23553         case OPC_REPLV_QB:
23554         case OPC_REPL_PH:
23555         case OPC_REPLV_PH:
23556             gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
23557             break;
23558         default:
23559             MIPS_INVAL("MASK ABSQ_S.PH");
23560             generate_exception_end(ctx, EXCP_RI);
23561             break;
23562         }
23563         break;
23564     case OPC_ADDU_QB_DSP:
23565         op2 = MASK_ADDU_QB(ctx->opcode);
23566         switch (op2) {
23567         case OPC_ADDQ_PH:
23568         case OPC_ADDQ_S_PH:
23569         case OPC_ADDQ_S_W:
23570         case OPC_ADDU_QB:
23571         case OPC_ADDU_S_QB:
23572         case OPC_ADDU_PH:
23573         case OPC_ADDU_S_PH:
23574         case OPC_SUBQ_PH:
23575         case OPC_SUBQ_S_PH:
23576         case OPC_SUBQ_S_W:
23577         case OPC_SUBU_QB:
23578         case OPC_SUBU_S_QB:
23579         case OPC_SUBU_PH:
23580         case OPC_SUBU_S_PH:
23581         case OPC_ADDSC:
23582         case OPC_ADDWC:
23583         case OPC_MODSUB:
23584         case OPC_RADDU_W_QB:
23585             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23586             break;
23587         case OPC_MULEU_S_PH_QBL:
23588         case OPC_MULEU_S_PH_QBR:
23589         case OPC_MULQ_RS_PH:
23590         case OPC_MULEQ_S_W_PHL:
23591         case OPC_MULEQ_S_W_PHR:
23592         case OPC_MULQ_S_PH:
23593             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
23594             break;
23595         default:            /* Invalid */
23596             MIPS_INVAL("MASK ADDU.QB");
23597             generate_exception_end(ctx, EXCP_RI);
23598             break;
23599
23600         }
23601         break;
23602     case OPC_CMPU_EQ_QB_DSP:
23603         op2 = MASK_CMPU_EQ_QB(ctx->opcode);
23604         switch (op2) {
23605         case OPC_PRECR_SRA_PH_W:
23606         case OPC_PRECR_SRA_R_PH_W:
23607             gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
23608             break;
23609         case OPC_PRECR_QB_PH:
23610         case OPC_PRECRQ_QB_PH:
23611         case OPC_PRECRQ_PH_W:
23612         case OPC_PRECRQ_RS_PH_W:
23613         case OPC_PRECRQU_S_QB_PH:
23614             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23615             break;
23616         case OPC_CMPU_EQ_QB:
23617         case OPC_CMPU_LT_QB:
23618         case OPC_CMPU_LE_QB:
23619         case OPC_CMP_EQ_PH:
23620         case OPC_CMP_LT_PH:
23621         case OPC_CMP_LE_PH:
23622             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
23623             break;
23624         case OPC_CMPGU_EQ_QB:
23625         case OPC_CMPGU_LT_QB:
23626         case OPC_CMPGU_LE_QB:
23627         case OPC_CMPGDU_EQ_QB:
23628         case OPC_CMPGDU_LT_QB:
23629         case OPC_CMPGDU_LE_QB:
23630         case OPC_PICK_QB:
23631         case OPC_PICK_PH:
23632         case OPC_PACKRL_PH:
23633             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
23634             break;
23635         default:            /* Invalid */
23636             MIPS_INVAL("MASK CMPU.EQ.QB");
23637             generate_exception_end(ctx, EXCP_RI);
23638             break;
23639         }
23640         break;
23641     case OPC_SHLL_QB_DSP:
23642         gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
23643         break;
23644     case OPC_DPA_W_PH_DSP:
23645         op2 = MASK_DPA_W_PH(ctx->opcode);
23646         switch (op2) {
23647         case OPC_DPAU_H_QBL:
23648         case OPC_DPAU_H_QBR:
23649         case OPC_DPSU_H_QBL:
23650         case OPC_DPSU_H_QBR:
23651         case OPC_DPA_W_PH:
23652         case OPC_DPAX_W_PH:
23653         case OPC_DPAQ_S_W_PH:
23654         case OPC_DPAQX_S_W_PH:
23655         case OPC_DPAQX_SA_W_PH:
23656         case OPC_DPS_W_PH:
23657         case OPC_DPSX_W_PH:
23658         case OPC_DPSQ_S_W_PH:
23659         case OPC_DPSQX_S_W_PH:
23660         case OPC_DPSQX_SA_W_PH:
23661         case OPC_MULSAQ_S_W_PH:
23662         case OPC_DPAQ_SA_L_W:
23663         case OPC_DPSQ_SA_L_W:
23664         case OPC_MAQ_S_W_PHL:
23665         case OPC_MAQ_S_W_PHR:
23666         case OPC_MAQ_SA_W_PHL:
23667         case OPC_MAQ_SA_W_PHR:
23668         case OPC_MULSA_W_PH:
23669             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
23670             break;
23671         default:            /* Invalid */
23672             MIPS_INVAL("MASK DPAW.PH");
23673             generate_exception_end(ctx, EXCP_RI);
23674             break;
23675         }
23676         break;
23677     case OPC_INSV_DSP:
23678         op2 = MASK_INSV(ctx->opcode);
23679         switch (op2) {
23680         case OPC_INSV:
23681             check_dsp(ctx);
23682             {
23683                 TCGv t0, t1;
23684
23685                 if (rt == 0) {
23686                     break;
23687                 }
23688
23689                 t0 = tcg_temp_new();
23690                 t1 = tcg_temp_new();
23691
23692                 gen_load_gpr(t0, rt);
23693                 gen_load_gpr(t1, rs);
23694
23695                 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
23696
23697                 tcg_temp_free(t0);
23698                 tcg_temp_free(t1);
23699                 break;
23700             }
23701         default:            /* Invalid */
23702             MIPS_INVAL("MASK INSV");
23703             generate_exception_end(ctx, EXCP_RI);
23704             break;
23705         }
23706         break;
23707     case OPC_APPEND_DSP:
23708         gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
23709         break;
23710     case OPC_EXTR_W_DSP:
23711         op2 = MASK_EXTR_W(ctx->opcode);
23712         switch (op2) {
23713         case OPC_EXTR_W:
23714         case OPC_EXTR_R_W:
23715         case OPC_EXTR_RS_W:
23716         case OPC_EXTR_S_H:
23717         case OPC_EXTRV_S_H:
23718         case OPC_EXTRV_W:
23719         case OPC_EXTRV_R_W:
23720         case OPC_EXTRV_RS_W:
23721         case OPC_EXTP:
23722         case OPC_EXTPV:
23723         case OPC_EXTPDP:
23724         case OPC_EXTPDPV:
23725             gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
23726             break;
23727         case OPC_RDDSP:
23728             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
23729             break;
23730         case OPC_SHILO:
23731         case OPC_SHILOV:
23732         case OPC_MTHLIP:
23733         case OPC_WRDSP:
23734             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
23735             break;
23736         default:            /* Invalid */
23737             MIPS_INVAL("MASK EXTR.W");
23738             generate_exception_end(ctx, EXCP_RI);
23739             break;
23740         }
23741         break;
23742 #if defined(TARGET_MIPS64)
23743     case OPC_DDIV_G_2E:
23744     case OPC_DDIVU_G_2E:
23745     case OPC_DMULT_G_2E:
23746     case OPC_DMULTU_G_2E:
23747     case OPC_DMOD_G_2E:
23748     case OPC_DMODU_G_2E:
23749         check_insn(ctx, INSN_LOONGSON2E);
23750         gen_loongson_integer(ctx, op1, rd, rs, rt);
23751         break;
23752     case OPC_ABSQ_S_QH_DSP:
23753         op2 = MASK_ABSQ_S_QH(ctx->opcode);
23754         switch (op2) {
23755         case OPC_PRECEQ_L_PWL:
23756         case OPC_PRECEQ_L_PWR:
23757         case OPC_PRECEQ_PW_QHL:
23758         case OPC_PRECEQ_PW_QHR:
23759         case OPC_PRECEQ_PW_QHLA:
23760         case OPC_PRECEQ_PW_QHRA:
23761         case OPC_PRECEQU_QH_OBL:
23762         case OPC_PRECEQU_QH_OBR:
23763         case OPC_PRECEQU_QH_OBLA:
23764         case OPC_PRECEQU_QH_OBRA:
23765         case OPC_PRECEU_QH_OBL:
23766         case OPC_PRECEU_QH_OBR:
23767         case OPC_PRECEU_QH_OBLA:
23768         case OPC_PRECEU_QH_OBRA:
23769         case OPC_ABSQ_S_OB:
23770         case OPC_ABSQ_S_PW:
23771         case OPC_ABSQ_S_QH:
23772             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23773             break;
23774         case OPC_REPL_OB:
23775         case OPC_REPL_PW:
23776         case OPC_REPL_QH:
23777         case OPC_REPLV_OB:
23778         case OPC_REPLV_PW:
23779         case OPC_REPLV_QH:
23780             gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
23781             break;
23782         default:            /* Invalid */
23783             MIPS_INVAL("MASK ABSQ_S.QH");
23784             generate_exception_end(ctx, EXCP_RI);
23785             break;
23786         }
23787         break;
23788     case OPC_ADDU_OB_DSP:
23789         op2 = MASK_ADDU_OB(ctx->opcode);
23790         switch (op2) {
23791         case OPC_RADDU_L_OB:
23792         case OPC_SUBQ_PW:
23793         case OPC_SUBQ_S_PW:
23794         case OPC_SUBQ_QH:
23795         case OPC_SUBQ_S_QH:
23796         case OPC_SUBU_OB:
23797         case OPC_SUBU_S_OB:
23798         case OPC_SUBU_QH:
23799         case OPC_SUBU_S_QH:
23800         case OPC_SUBUH_OB:
23801         case OPC_SUBUH_R_OB:
23802         case OPC_ADDQ_PW:
23803         case OPC_ADDQ_S_PW:
23804         case OPC_ADDQ_QH:
23805         case OPC_ADDQ_S_QH:
23806         case OPC_ADDU_OB:
23807         case OPC_ADDU_S_OB:
23808         case OPC_ADDU_QH:
23809         case OPC_ADDU_S_QH:
23810         case OPC_ADDUH_OB:
23811         case OPC_ADDUH_R_OB:
23812             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23813             break;
23814         case OPC_MULEQ_S_PW_QHL:
23815         case OPC_MULEQ_S_PW_QHR:
23816         case OPC_MULEU_S_QH_OBL:
23817         case OPC_MULEU_S_QH_OBR:
23818         case OPC_MULQ_RS_QH:
23819             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
23820             break;
23821         default:            /* Invalid */
23822             MIPS_INVAL("MASK ADDU.OB");
23823             generate_exception_end(ctx, EXCP_RI);
23824             break;
23825         }
23826         break;
23827     case OPC_CMPU_EQ_OB_DSP:
23828         op2 = MASK_CMPU_EQ_OB(ctx->opcode);
23829         switch (op2) {
23830         case OPC_PRECR_SRA_QH_PW:
23831         case OPC_PRECR_SRA_R_QH_PW:
23832             /* Return value is rt. */
23833             gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
23834             break;
23835         case OPC_PRECR_OB_QH:
23836         case OPC_PRECRQ_OB_QH:
23837         case OPC_PRECRQ_PW_L:
23838         case OPC_PRECRQ_QH_PW:
23839         case OPC_PRECRQ_RS_QH_PW:
23840         case OPC_PRECRQU_S_OB_QH:
23841             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23842             break;
23843         case OPC_CMPU_EQ_OB:
23844         case OPC_CMPU_LT_OB:
23845         case OPC_CMPU_LE_OB:
23846         case OPC_CMP_EQ_QH:
23847         case OPC_CMP_LT_QH:
23848         case OPC_CMP_LE_QH:
23849         case OPC_CMP_EQ_PW:
23850         case OPC_CMP_LT_PW:
23851         case OPC_CMP_LE_PW:
23852             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
23853             break;
23854         case OPC_CMPGDU_EQ_OB:
23855         case OPC_CMPGDU_LT_OB:
23856         case OPC_CMPGDU_LE_OB:
23857         case OPC_CMPGU_EQ_OB:
23858         case OPC_CMPGU_LT_OB:
23859         case OPC_CMPGU_LE_OB:
23860         case OPC_PACKRL_PW:
23861         case OPC_PICK_OB:
23862         case OPC_PICK_PW:
23863         case OPC_PICK_QH:
23864             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
23865             break;
23866         default:            /* Invalid */
23867             MIPS_INVAL("MASK CMPU_EQ.OB");
23868             generate_exception_end(ctx, EXCP_RI);
23869             break;
23870         }
23871         break;
23872     case OPC_DAPPEND_DSP:
23873         gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
23874         break;
23875     case OPC_DEXTR_W_DSP:
23876         op2 = MASK_DEXTR_W(ctx->opcode);
23877         switch (op2) {
23878         case OPC_DEXTP:
23879         case OPC_DEXTPDP:
23880         case OPC_DEXTPDPV:
23881         case OPC_DEXTPV:
23882         case OPC_DEXTR_L:
23883         case OPC_DEXTR_R_L:
23884         case OPC_DEXTR_RS_L:
23885         case OPC_DEXTR_W:
23886         case OPC_DEXTR_R_W:
23887         case OPC_DEXTR_RS_W:
23888         case OPC_DEXTR_S_H:
23889         case OPC_DEXTRV_L:
23890         case OPC_DEXTRV_R_L:
23891         case OPC_DEXTRV_RS_L:
23892         case OPC_DEXTRV_S_H:
23893         case OPC_DEXTRV_W:
23894         case OPC_DEXTRV_R_W:
23895         case OPC_DEXTRV_RS_W:
23896             gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
23897             break;
23898         case OPC_DMTHLIP:
23899         case OPC_DSHILO:
23900         case OPC_DSHILOV:
23901             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
23902             break;
23903         default:            /* Invalid */
23904             MIPS_INVAL("MASK EXTR.W");
23905             generate_exception_end(ctx, EXCP_RI);
23906             break;
23907         }
23908         break;
23909     case OPC_DPAQ_W_QH_DSP:
23910         op2 = MASK_DPAQ_W_QH(ctx->opcode);
23911         switch (op2) {
23912         case OPC_DPAU_H_OBL:
23913         case OPC_DPAU_H_OBR:
23914         case OPC_DPSU_H_OBL:
23915         case OPC_DPSU_H_OBR:
23916         case OPC_DPA_W_QH:
23917         case OPC_DPAQ_S_W_QH:
23918         case OPC_DPS_W_QH:
23919         case OPC_DPSQ_S_W_QH:
23920         case OPC_MULSAQ_S_W_QH:
23921         case OPC_DPAQ_SA_L_PW:
23922         case OPC_DPSQ_SA_L_PW:
23923         case OPC_MULSAQ_S_L_PW:
23924             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
23925             break;
23926         case OPC_MAQ_S_W_QHLL:
23927         case OPC_MAQ_S_W_QHLR:
23928         case OPC_MAQ_S_W_QHRL:
23929         case OPC_MAQ_S_W_QHRR:
23930         case OPC_MAQ_SA_W_QHLL:
23931         case OPC_MAQ_SA_W_QHLR:
23932         case OPC_MAQ_SA_W_QHRL:
23933         case OPC_MAQ_SA_W_QHRR:
23934         case OPC_MAQ_S_L_PWL:
23935         case OPC_MAQ_S_L_PWR:
23936         case OPC_DMADD:
23937         case OPC_DMADDU:
23938         case OPC_DMSUB:
23939         case OPC_DMSUBU:
23940             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
23941             break;
23942         default:            /* Invalid */
23943             MIPS_INVAL("MASK DPAQ.W.QH");
23944             generate_exception_end(ctx, EXCP_RI);
23945             break;
23946         }
23947         break;
23948     case OPC_DINSV_DSP:
23949         op2 = MASK_INSV(ctx->opcode);
23950         switch (op2) {
23951         case OPC_DINSV:
23952         {
23953             TCGv t0, t1;
23954
23955             if (rt == 0) {
23956                 break;
23957             }
23958             check_dsp(ctx);
23959
23960             t0 = tcg_temp_new();
23961             t1 = tcg_temp_new();
23962
23963             gen_load_gpr(t0, rt);
23964             gen_load_gpr(t1, rs);
23965
23966             gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
23967
23968             tcg_temp_free(t0);
23969             tcg_temp_free(t1);
23970             break;
23971         }
23972         default:            /* Invalid */
23973             MIPS_INVAL("MASK DINSV");
23974             generate_exception_end(ctx, EXCP_RI);
23975             break;
23976         }
23977         break;
23978     case OPC_SHLL_OB_DSP:
23979         gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
23980         break;
23981 #endif
23982     default:            /* Invalid */
23983         MIPS_INVAL("special3_legacy");
23984         generate_exception_end(ctx, EXCP_RI);
23985         break;
23986     }
23987 }
23988
23989 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
23990 {
23991     int rs, rt, rd, sa;
23992     uint32_t op1, op2;
23993     int16_t imm;
23994
23995     rs = (ctx->opcode >> 21) & 0x1f;
23996     rt = (ctx->opcode >> 16) & 0x1f;
23997     rd = (ctx->opcode >> 11) & 0x1f;
23998     sa = (ctx->opcode >> 6) & 0x1f;
23999     imm = sextract32(ctx->opcode, 7, 9);
24000
24001     op1 = MASK_SPECIAL3(ctx->opcode);
24002
24003     /*
24004      * EVA loads and stores overlap Loongson 2E instructions decoded by
24005      * decode_opc_special3_legacy(), so be careful to allow their decoding when
24006      * EVA is absent.
24007      */
24008     if (ctx->eva) {
24009         switch (op1) {
24010         case OPC_LWLE:
24011         case OPC_LWRE:
24012             check_insn_opc_removed(ctx, ISA_MIPS32R6);
24013             /* fall through */
24014         case OPC_LBUE:
24015         case OPC_LHUE:
24016         case OPC_LBE:
24017         case OPC_LHE:
24018         case OPC_LLE:
24019         case OPC_LWE:
24020             check_cp0_enabled(ctx);
24021             gen_ld(ctx, op1, rt, rs, imm);
24022             return;
24023         case OPC_SWLE:
24024         case OPC_SWRE:
24025             check_insn_opc_removed(ctx, ISA_MIPS32R6);
24026             /* fall through */
24027         case OPC_SBE:
24028         case OPC_SHE:
24029         case OPC_SWE:
24030             check_cp0_enabled(ctx);
24031             gen_st(ctx, op1, rt, rs, imm);
24032             return;
24033         case OPC_SCE:
24034             check_cp0_enabled(ctx);
24035             gen_st_cond(ctx, op1, rt, rs, imm);
24036             return;
24037         case OPC_CACHEE:
24038             check_cp0_enabled(ctx);
24039             if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
24040                 gen_cache_operation(ctx, rt, rs, imm);
24041             }
24042             /* Treat as NOP. */
24043             return;
24044         case OPC_PREFE:
24045             check_cp0_enabled(ctx);
24046             /* Treat as NOP. */
24047             return;
24048         }
24049     }
24050
24051     switch (op1) {
24052     case OPC_EXT:
24053     case OPC_INS:
24054         check_insn(ctx, ISA_MIPS32R2);
24055         gen_bitops(ctx, op1, rt, rs, sa, rd);
24056         break;
24057     case OPC_BSHFL:
24058         op2 = MASK_BSHFL(ctx->opcode);
24059         switch (op2) {
24060         case OPC_ALIGN:
24061         case OPC_ALIGN_END:
24062         case OPC_BITSWAP:
24063             check_insn(ctx, ISA_MIPS32R6);
24064             decode_opc_special3_r6(env, ctx);
24065             break;
24066         default:
24067             check_insn(ctx, ISA_MIPS32R2);
24068             gen_bshfl(ctx, op2, rt, rd);
24069             break;
24070         }
24071         break;
24072 #if defined(TARGET_MIPS64)
24073     case OPC_DEXTM:
24074     case OPC_DEXTU:
24075     case OPC_DEXT:
24076     case OPC_DINSM:
24077     case OPC_DINSU:
24078     case OPC_DINS:
24079         check_insn(ctx, ISA_MIPS64R2);
24080         check_mips_64(ctx);
24081         gen_bitops(ctx, op1, rt, rs, sa, rd);
24082         break;
24083     case OPC_DBSHFL:
24084         op2 = MASK_DBSHFL(ctx->opcode);
24085         switch (op2) {
24086         case OPC_DALIGN:
24087         case OPC_DALIGN_END:
24088         case OPC_DBITSWAP:
24089             check_insn(ctx, ISA_MIPS32R6);
24090             decode_opc_special3_r6(env, ctx);
24091             break;
24092         default:
24093             check_insn(ctx, ISA_MIPS64R2);
24094             check_mips_64(ctx);
24095             op2 = MASK_DBSHFL(ctx->opcode);
24096             gen_bshfl(ctx, op2, rt, rd);
24097             break;
24098         }
24099         break;
24100 #endif
24101     case OPC_RDHWR:
24102         gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
24103         break;
24104     case OPC_FORK:
24105         check_mt(ctx);
24106         {
24107             TCGv t0 = tcg_temp_new();
24108             TCGv t1 = tcg_temp_new();
24109
24110             gen_load_gpr(t0, rt);
24111             gen_load_gpr(t1, rs);
24112             gen_helper_fork(t0, t1);
24113             tcg_temp_free(t0);
24114             tcg_temp_free(t1);
24115         }
24116         break;
24117     case OPC_YIELD:
24118         check_mt(ctx);
24119         {
24120             TCGv t0 = tcg_temp_new();
24121
24122             gen_load_gpr(t0, rs);
24123             gen_helper_yield(t0, cpu_env, t0);
24124             gen_store_gpr(t0, rd);
24125             tcg_temp_free(t0);
24126         }
24127         break;
24128     default:
24129         if (ctx->insn_flags & ISA_MIPS32R6) {
24130             decode_opc_special3_r6(env, ctx);
24131         } else {
24132             decode_opc_special3_legacy(env, ctx);
24133         }
24134     }
24135 }
24136
24137 /* MIPS SIMD Architecture (MSA)  */
24138 static inline int check_msa_access(DisasContext *ctx)
24139 {
24140     if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
24141                  !(ctx->hflags & MIPS_HFLAG_F64))) {
24142         generate_exception_end(ctx, EXCP_RI);
24143         return 0;
24144     }
24145
24146     if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
24147         if (ctx->insn_flags & ASE_MSA) {
24148             generate_exception_end(ctx, EXCP_MSADIS);
24149             return 0;
24150         } else {
24151             generate_exception_end(ctx, EXCP_RI);
24152             return 0;
24153         }
24154     }
24155     return 1;
24156 }
24157
24158 static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
24159 {
24160     /* generates tcg ops to check if any element is 0 */
24161     /* Note this function only works with MSA_WRLEN = 128 */
24162     uint64_t eval_zero_or_big = 0;
24163     uint64_t eval_big = 0;
24164     TCGv_i64 t0 = tcg_temp_new_i64();
24165     TCGv_i64 t1 = tcg_temp_new_i64();
24166     switch (df) {
24167     case DF_BYTE:
24168         eval_zero_or_big = 0x0101010101010101ULL;
24169         eval_big = 0x8080808080808080ULL;
24170         break;
24171     case DF_HALF:
24172         eval_zero_or_big = 0x0001000100010001ULL;
24173         eval_big = 0x8000800080008000ULL;
24174         break;
24175     case DF_WORD:
24176         eval_zero_or_big = 0x0000000100000001ULL;
24177         eval_big = 0x8000000080000000ULL;
24178         break;
24179     case DF_DOUBLE:
24180         eval_zero_or_big = 0x0000000000000001ULL;
24181         eval_big = 0x8000000000000000ULL;
24182         break;
24183     }
24184     tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
24185     tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
24186     tcg_gen_andi_i64(t0, t0, eval_big);
24187     tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
24188     tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
24189     tcg_gen_andi_i64(t1, t1, eval_big);
24190     tcg_gen_or_i64(t0, t0, t1);
24191     /* if all bits are zero then all elements are not zero */
24192     /* if some bit is non-zero then some element is zero */
24193     tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
24194     tcg_gen_trunc_i64_tl(tresult, t0);
24195     tcg_temp_free_i64(t0);
24196     tcg_temp_free_i64(t1);
24197 }
24198
24199 static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
24200 {
24201     uint8_t df = (ctx->opcode >> 21) & 0x3;
24202     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
24203     int64_t s16 = (int16_t)ctx->opcode;
24204
24205     check_msa_access(ctx);
24206
24207     if (ctx->hflags & MIPS_HFLAG_BMASK) {
24208         generate_exception_end(ctx, EXCP_RI);
24209         return;
24210     }
24211     switch (op1) {
24212     case OPC_BZ_V:
24213     case OPC_BNZ_V:
24214         {
24215             TCGv_i64 t0 = tcg_temp_new_i64();
24216             tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
24217             tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
24218                     TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
24219             tcg_gen_trunc_i64_tl(bcond, t0);
24220             tcg_temp_free_i64(t0);
24221         }
24222         break;
24223     case OPC_BZ_B:
24224     case OPC_BZ_H:
24225     case OPC_BZ_W:
24226     case OPC_BZ_D:
24227         gen_check_zero_element(bcond, df, wt);
24228         break;
24229     case OPC_BNZ_B:
24230     case OPC_BNZ_H:
24231     case OPC_BNZ_W:
24232     case OPC_BNZ_D:
24233         gen_check_zero_element(bcond, df, wt);
24234         tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
24235         break;
24236     }
24237
24238     ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
24239
24240     ctx->hflags |= MIPS_HFLAG_BC;
24241     ctx->hflags |= MIPS_HFLAG_BDS32;
24242 }
24243
24244 static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
24245 {
24246 #define MASK_MSA_I8(op)    (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
24247     uint8_t i8 = (ctx->opcode >> 16) & 0xff;
24248     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24249     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24250
24251     TCGv_i32 twd = tcg_const_i32(wd);
24252     TCGv_i32 tws = tcg_const_i32(ws);
24253     TCGv_i32 ti8 = tcg_const_i32(i8);
24254
24255     switch (MASK_MSA_I8(ctx->opcode)) {
24256     case OPC_ANDI_B:
24257         gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
24258         break;
24259     case OPC_ORI_B:
24260         gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
24261         break;
24262     case OPC_NORI_B:
24263         gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
24264         break;
24265     case OPC_XORI_B:
24266         gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
24267         break;
24268     case OPC_BMNZI_B:
24269         gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
24270         break;
24271     case OPC_BMZI_B:
24272         gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
24273         break;
24274     case OPC_BSELI_B:
24275         gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
24276         break;
24277     case OPC_SHF_B:
24278     case OPC_SHF_H:
24279     case OPC_SHF_W:
24280         {
24281             uint8_t df = (ctx->opcode >> 24) & 0x3;
24282             if (df == DF_DOUBLE) {
24283                 generate_exception_end(ctx, EXCP_RI);
24284             } else {
24285                 TCGv_i32 tdf = tcg_const_i32(df);
24286                 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
24287                 tcg_temp_free_i32(tdf);
24288             }
24289         }
24290         break;
24291     default:
24292         MIPS_INVAL("MSA instruction");
24293         generate_exception_end(ctx, EXCP_RI);
24294         break;
24295     }
24296
24297     tcg_temp_free_i32(twd);
24298     tcg_temp_free_i32(tws);
24299     tcg_temp_free_i32(ti8);
24300 }
24301
24302 static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
24303 {
24304 #define MASK_MSA_I5(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
24305     uint8_t df = (ctx->opcode >> 21) & 0x3;
24306     int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
24307     uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
24308     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24309     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24310
24311     TCGv_i32 tdf = tcg_const_i32(df);
24312     TCGv_i32 twd = tcg_const_i32(wd);
24313     TCGv_i32 tws = tcg_const_i32(ws);
24314     TCGv_i32 timm = tcg_temp_new_i32();
24315     tcg_gen_movi_i32(timm, u5);
24316
24317     switch (MASK_MSA_I5(ctx->opcode)) {
24318     case OPC_ADDVI_df:
24319         gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
24320         break;
24321     case OPC_SUBVI_df:
24322         gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
24323         break;
24324     case OPC_MAXI_S_df:
24325         tcg_gen_movi_i32(timm, s5);
24326         gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
24327         break;
24328     case OPC_MAXI_U_df:
24329         gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
24330         break;
24331     case OPC_MINI_S_df:
24332         tcg_gen_movi_i32(timm, s5);
24333         gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
24334         break;
24335     case OPC_MINI_U_df:
24336         gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
24337         break;
24338     case OPC_CEQI_df:
24339         tcg_gen_movi_i32(timm, s5);
24340         gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
24341         break;
24342     case OPC_CLTI_S_df:
24343         tcg_gen_movi_i32(timm, s5);
24344         gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
24345         break;
24346     case OPC_CLTI_U_df:
24347         gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
24348         break;
24349     case OPC_CLEI_S_df:
24350         tcg_gen_movi_i32(timm, s5);
24351         gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
24352         break;
24353     case OPC_CLEI_U_df:
24354         gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
24355         break;
24356     case OPC_LDI_df:
24357         {
24358             int32_t s10 = sextract32(ctx->opcode, 11, 10);
24359             tcg_gen_movi_i32(timm, s10);
24360             gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
24361         }
24362         break;
24363     default:
24364         MIPS_INVAL("MSA instruction");
24365         generate_exception_end(ctx, EXCP_RI);
24366         break;
24367     }
24368
24369     tcg_temp_free_i32(tdf);
24370     tcg_temp_free_i32(twd);
24371     tcg_temp_free_i32(tws);
24372     tcg_temp_free_i32(timm);
24373 }
24374
24375 static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
24376 {
24377 #define MASK_MSA_BIT(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
24378     uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
24379     uint32_t df = 0, m = 0;
24380     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24381     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24382
24383     TCGv_i32 tdf;
24384     TCGv_i32 tm;
24385     TCGv_i32 twd;
24386     TCGv_i32 tws;
24387
24388     if ((dfm & 0x40) == 0x00) {
24389         m = dfm & 0x3f;
24390         df = DF_DOUBLE;
24391     } else if ((dfm & 0x60) == 0x40) {
24392         m = dfm & 0x1f;
24393         df = DF_WORD;
24394     } else if ((dfm & 0x70) == 0x60) {
24395         m = dfm & 0x0f;
24396         df = DF_HALF;
24397     } else if ((dfm & 0x78) == 0x70) {
24398         m = dfm & 0x7;
24399         df = DF_BYTE;
24400     } else {
24401         generate_exception_end(ctx, EXCP_RI);
24402         return;
24403     }
24404
24405     tdf = tcg_const_i32(df);
24406     tm  = tcg_const_i32(m);
24407     twd = tcg_const_i32(wd);
24408     tws = tcg_const_i32(ws);
24409
24410     switch (MASK_MSA_BIT(ctx->opcode)) {
24411     case OPC_SLLI_df:
24412         gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
24413         break;
24414     case OPC_SRAI_df:
24415         gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
24416         break;
24417     case OPC_SRLI_df:
24418         gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
24419         break;
24420     case OPC_BCLRI_df:
24421         gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
24422         break;
24423     case OPC_BSETI_df:
24424         gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
24425         break;
24426     case OPC_BNEGI_df:
24427         gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
24428         break;
24429     case OPC_BINSLI_df:
24430         gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
24431         break;
24432     case OPC_BINSRI_df:
24433         gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
24434         break;
24435     case OPC_SAT_S_df:
24436         gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
24437         break;
24438     case OPC_SAT_U_df:
24439         gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
24440         break;
24441     case OPC_SRARI_df:
24442         gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
24443         break;
24444     case OPC_SRLRI_df:
24445         gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
24446         break;
24447     default:
24448         MIPS_INVAL("MSA instruction");
24449         generate_exception_end(ctx, EXCP_RI);
24450         break;
24451     }
24452
24453     tcg_temp_free_i32(tdf);
24454     tcg_temp_free_i32(tm);
24455     tcg_temp_free_i32(twd);
24456     tcg_temp_free_i32(tws);
24457 }
24458
24459 static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
24460 {
24461 #define MASK_MSA_3R(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
24462     uint8_t df = (ctx->opcode >> 21) & 0x3;
24463     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
24464     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24465     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24466
24467     TCGv_i32 tdf = tcg_const_i32(df);
24468     TCGv_i32 twd = tcg_const_i32(wd);
24469     TCGv_i32 tws = tcg_const_i32(ws);
24470     TCGv_i32 twt = tcg_const_i32(wt);
24471
24472     switch (MASK_MSA_3R(ctx->opcode)) {
24473     case OPC_SLL_df:
24474         gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
24475         break;
24476     case OPC_ADDV_df:
24477         gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
24478         break;
24479     case OPC_CEQ_df:
24480         gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
24481         break;
24482     case OPC_ADD_A_df:
24483         gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
24484         break;
24485     case OPC_SUBS_S_df:
24486         gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
24487         break;
24488     case OPC_MULV_df:
24489         gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
24490         break;
24491     case OPC_SLD_df:
24492         gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
24493         break;
24494     case OPC_VSHF_df:
24495         gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
24496         break;
24497     case OPC_SRA_df:
24498         gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
24499         break;
24500     case OPC_SUBV_df:
24501         gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
24502         break;
24503     case OPC_ADDS_A_df:
24504         gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
24505         break;
24506     case OPC_SUBS_U_df:
24507         gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
24508         break;
24509     case OPC_MADDV_df:
24510         gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
24511         break;
24512     case OPC_SPLAT_df:
24513         gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
24514         break;
24515     case OPC_SRAR_df:
24516         gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
24517         break;
24518     case OPC_SRL_df:
24519         gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
24520         break;
24521     case OPC_MAX_S_df:
24522         gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
24523         break;
24524     case OPC_CLT_S_df:
24525         gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
24526         break;
24527     case OPC_ADDS_S_df:
24528         gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
24529         break;
24530     case OPC_SUBSUS_U_df:
24531         gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
24532         break;
24533     case OPC_MSUBV_df:
24534         gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
24535         break;
24536     case OPC_PCKEV_df:
24537         gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
24538         break;
24539     case OPC_SRLR_df:
24540         gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
24541         break;
24542     case OPC_BCLR_df:
24543         gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
24544         break;
24545     case OPC_MAX_U_df:
24546         gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
24547         break;
24548     case OPC_CLT_U_df:
24549         gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
24550         break;
24551     case OPC_ADDS_U_df:
24552         gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
24553         break;
24554     case OPC_SUBSUU_S_df:
24555         gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
24556         break;
24557     case OPC_PCKOD_df:
24558         gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
24559         break;
24560     case OPC_BSET_df:
24561         gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
24562         break;
24563     case OPC_MIN_S_df:
24564         gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
24565         break;
24566     case OPC_CLE_S_df:
24567         gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
24568         break;
24569     case OPC_AVE_S_df:
24570         gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
24571         break;
24572     case OPC_ASUB_S_df:
24573         gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
24574         break;
24575     case OPC_DIV_S_df:
24576         gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
24577         break;
24578     case OPC_ILVL_df:
24579         gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
24580         break;
24581     case OPC_BNEG_df:
24582         gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
24583         break;
24584     case OPC_MIN_U_df:
24585         gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
24586         break;
24587     case OPC_CLE_U_df:
24588         gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
24589         break;
24590     case OPC_AVE_U_df:
24591         gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
24592         break;
24593     case OPC_ASUB_U_df:
24594         gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
24595         break;
24596     case OPC_DIV_U_df:
24597         gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
24598         break;
24599     case OPC_ILVR_df:
24600         gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
24601         break;
24602     case OPC_BINSL_df:
24603         gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
24604         break;
24605     case OPC_MAX_A_df:
24606         gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
24607         break;
24608     case OPC_AVER_S_df:
24609         gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
24610         break;
24611     case OPC_MOD_S_df:
24612         gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
24613         break;
24614     case OPC_ILVEV_df:
24615         gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
24616         break;
24617     case OPC_BINSR_df:
24618         gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
24619         break;
24620     case OPC_MIN_A_df:
24621         gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
24622         break;
24623     case OPC_AVER_U_df:
24624         gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
24625         break;
24626     case OPC_MOD_U_df:
24627         gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
24628         break;
24629     case OPC_ILVOD_df:
24630         gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
24631         break;
24632
24633     case OPC_DOTP_S_df:
24634     case OPC_DOTP_U_df:
24635     case OPC_DPADD_S_df:
24636     case OPC_DPADD_U_df:
24637     case OPC_DPSUB_S_df:
24638     case OPC_HADD_S_df:
24639     case OPC_DPSUB_U_df:
24640     case OPC_HADD_U_df:
24641     case OPC_HSUB_S_df:
24642     case OPC_HSUB_U_df:
24643         if (df == DF_BYTE) {
24644             generate_exception_end(ctx, EXCP_RI);
24645             break;
24646         }
24647         switch (MASK_MSA_3R(ctx->opcode)) {
24648         case OPC_DOTP_S_df:
24649             gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
24650             break;
24651         case OPC_DOTP_U_df:
24652             gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
24653             break;
24654         case OPC_DPADD_S_df:
24655             gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
24656             break;
24657         case OPC_DPADD_U_df:
24658             gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
24659             break;
24660         case OPC_DPSUB_S_df:
24661             gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
24662             break;
24663         case OPC_HADD_S_df:
24664             gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
24665             break;
24666         case OPC_DPSUB_U_df:
24667             gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
24668             break;
24669         case OPC_HADD_U_df:
24670             gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
24671             break;
24672         case OPC_HSUB_S_df:
24673             gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
24674             break;
24675         case OPC_HSUB_U_df:
24676             gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
24677             break;
24678         }
24679         break;
24680     default:
24681         MIPS_INVAL("MSA instruction");
24682         generate_exception_end(ctx, EXCP_RI);
24683         break;
24684     }
24685     tcg_temp_free_i32(twd);
24686     tcg_temp_free_i32(tws);
24687     tcg_temp_free_i32(twt);
24688     tcg_temp_free_i32(tdf);
24689 }
24690
24691 static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
24692 {
24693 #define MASK_MSA_ELM_DF3E(op)   (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
24694     uint8_t source = (ctx->opcode >> 11) & 0x1f;
24695     uint8_t dest = (ctx->opcode >> 6) & 0x1f;
24696     TCGv telm = tcg_temp_new();
24697     TCGv_i32 tsr = tcg_const_i32(source);
24698     TCGv_i32 tdt = tcg_const_i32(dest);
24699
24700     switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
24701     case OPC_CTCMSA:
24702         gen_load_gpr(telm, source);
24703         gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
24704         break;
24705     case OPC_CFCMSA:
24706         gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
24707         gen_store_gpr(telm, dest);
24708         break;
24709     case OPC_MOVE_V:
24710         gen_helper_msa_move_v(cpu_env, tdt, tsr);
24711         break;
24712     default:
24713         MIPS_INVAL("MSA instruction");
24714         generate_exception_end(ctx, EXCP_RI);
24715         break;
24716     }
24717
24718     tcg_temp_free(telm);
24719     tcg_temp_free_i32(tdt);
24720     tcg_temp_free_i32(tsr);
24721 }
24722
24723 static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
24724         uint32_t n)
24725 {
24726 #define MASK_MSA_ELM(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
24727     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24728     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24729
24730     TCGv_i32 tws = tcg_const_i32(ws);
24731     TCGv_i32 twd = tcg_const_i32(wd);
24732     TCGv_i32 tn  = tcg_const_i32(n);
24733     TCGv_i32 tdf = tcg_const_i32(df);
24734
24735     switch (MASK_MSA_ELM(ctx->opcode)) {
24736     case OPC_SLDI_df:
24737         gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
24738         break;
24739     case OPC_SPLATI_df:
24740         gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
24741         break;
24742     case OPC_INSVE_df:
24743         gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
24744         break;
24745     case OPC_COPY_S_df:
24746     case OPC_COPY_U_df:
24747     case OPC_INSERT_df:
24748 #if !defined(TARGET_MIPS64)
24749         /* Double format valid only for MIPS64 */
24750         if (df == DF_DOUBLE) {
24751             generate_exception_end(ctx, EXCP_RI);
24752             break;
24753         }
24754 #endif
24755         switch (MASK_MSA_ELM(ctx->opcode)) {
24756         case OPC_COPY_S_df:
24757             if (likely(wd != 0)) {
24758                 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
24759             }
24760             break;
24761         case OPC_COPY_U_df:
24762             if (likely(wd != 0)) {
24763                 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
24764             }
24765             break;
24766         case OPC_INSERT_df:
24767             gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
24768             break;
24769         }
24770         break;
24771     default:
24772         MIPS_INVAL("MSA instruction");
24773         generate_exception_end(ctx, EXCP_RI);
24774     }
24775     tcg_temp_free_i32(twd);
24776     tcg_temp_free_i32(tws);
24777     tcg_temp_free_i32(tn);
24778     tcg_temp_free_i32(tdf);
24779 }
24780
24781 static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
24782 {
24783     uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
24784     uint32_t df = 0, n = 0;
24785
24786     if ((dfn & 0x30) == 0x00) {
24787         n = dfn & 0x0f;
24788         df = DF_BYTE;
24789     } else if ((dfn & 0x38) == 0x20) {
24790         n = dfn & 0x07;
24791         df = DF_HALF;
24792     } else if ((dfn & 0x3c) == 0x30) {
24793         n = dfn & 0x03;
24794         df = DF_WORD;
24795     } else if ((dfn & 0x3e) == 0x38) {
24796         n = dfn & 0x01;
24797         df = DF_DOUBLE;
24798     } else if (dfn == 0x3E) {
24799         /* CTCMSA, CFCMSA, MOVE.V */
24800         gen_msa_elm_3e(env, ctx);
24801         return;
24802     } else {
24803         generate_exception_end(ctx, EXCP_RI);
24804         return;
24805     }
24806
24807     gen_msa_elm_df(env, ctx, df, n);
24808 }
24809
24810 static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
24811 {
24812 #define MASK_MSA_3RF(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
24813     uint8_t df = (ctx->opcode >> 21) & 0x1;
24814     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
24815     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24816     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24817
24818     TCGv_i32 twd = tcg_const_i32(wd);
24819     TCGv_i32 tws = tcg_const_i32(ws);
24820     TCGv_i32 twt = tcg_const_i32(wt);
24821     TCGv_i32 tdf = tcg_temp_new_i32();
24822
24823     /* adjust df value for floating-point instruction */
24824     tcg_gen_movi_i32(tdf, df + 2);
24825
24826     switch (MASK_MSA_3RF(ctx->opcode)) {
24827     case OPC_FCAF_df:
24828         gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
24829         break;
24830     case OPC_FADD_df:
24831         gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
24832         break;
24833     case OPC_FCUN_df:
24834         gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
24835         break;
24836     case OPC_FSUB_df:
24837         gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
24838         break;
24839     case OPC_FCOR_df:
24840         gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
24841         break;
24842     case OPC_FCEQ_df:
24843         gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
24844         break;
24845     case OPC_FMUL_df:
24846         gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
24847         break;
24848     case OPC_FCUNE_df:
24849         gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
24850         break;
24851     case OPC_FCUEQ_df:
24852         gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
24853         break;
24854     case OPC_FDIV_df:
24855         gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
24856         break;
24857     case OPC_FCNE_df:
24858         gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
24859         break;
24860     case OPC_FCLT_df:
24861         gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
24862         break;
24863     case OPC_FMADD_df:
24864         gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
24865         break;
24866     case OPC_MUL_Q_df:
24867         tcg_gen_movi_i32(tdf, df + 1);
24868         gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
24869         break;
24870     case OPC_FCULT_df:
24871         gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
24872         break;
24873     case OPC_FMSUB_df:
24874         gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
24875         break;
24876     case OPC_MADD_Q_df:
24877         tcg_gen_movi_i32(tdf, df + 1);
24878         gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
24879         break;
24880     case OPC_FCLE_df:
24881         gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
24882         break;
24883     case OPC_MSUB_Q_df:
24884         tcg_gen_movi_i32(tdf, df + 1);
24885         gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
24886         break;
24887     case OPC_FCULE_df:
24888         gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
24889         break;
24890     case OPC_FEXP2_df:
24891         gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
24892         break;
24893     case OPC_FSAF_df:
24894         gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
24895         break;
24896     case OPC_FEXDO_df:
24897         gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
24898         break;
24899     case OPC_FSUN_df:
24900         gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
24901         break;
24902     case OPC_FSOR_df:
24903         gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
24904         break;
24905     case OPC_FSEQ_df:
24906         gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
24907         break;
24908     case OPC_FTQ_df:
24909         gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
24910         break;
24911     case OPC_FSUNE_df:
24912         gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
24913         break;
24914     case OPC_FSUEQ_df:
24915         gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
24916         break;
24917     case OPC_FSNE_df:
24918         gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
24919         break;
24920     case OPC_FSLT_df:
24921         gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
24922         break;
24923     case OPC_FMIN_df:
24924         gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
24925         break;
24926     case OPC_MULR_Q_df:
24927         tcg_gen_movi_i32(tdf, df + 1);
24928         gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
24929         break;
24930     case OPC_FSULT_df:
24931         gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
24932         break;
24933     case OPC_FMIN_A_df:
24934         gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
24935         break;
24936     case OPC_MADDR_Q_df:
24937         tcg_gen_movi_i32(tdf, df + 1);
24938         gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
24939         break;
24940     case OPC_FSLE_df:
24941         gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
24942         break;
24943     case OPC_FMAX_df:
24944         gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
24945         break;
24946     case OPC_MSUBR_Q_df:
24947         tcg_gen_movi_i32(tdf, df + 1);
24948         gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
24949         break;
24950     case OPC_FSULE_df:
24951         gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
24952         break;
24953     case OPC_FMAX_A_df:
24954         gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
24955         break;
24956     default:
24957         MIPS_INVAL("MSA instruction");
24958         generate_exception_end(ctx, EXCP_RI);
24959         break;
24960     }
24961
24962     tcg_temp_free_i32(twd);
24963     tcg_temp_free_i32(tws);
24964     tcg_temp_free_i32(twt);
24965     tcg_temp_free_i32(tdf);
24966 }
24967
24968 static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
24969 {
24970 #define MASK_MSA_2R(op)     (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
24971                             (op & (0x7 << 18)))
24972     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
24973     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24974     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24975     uint8_t df = (ctx->opcode >> 16) & 0x3;
24976     TCGv_i32 twd = tcg_const_i32(wd);
24977     TCGv_i32 tws = tcg_const_i32(ws);
24978     TCGv_i32 twt = tcg_const_i32(wt);
24979     TCGv_i32 tdf = tcg_const_i32(df);
24980
24981     switch (MASK_MSA_2R(ctx->opcode)) {
24982     case OPC_FILL_df:
24983 #if !defined(TARGET_MIPS64)
24984         /* Double format valid only for MIPS64 */
24985         if (df == DF_DOUBLE) {
24986             generate_exception_end(ctx, EXCP_RI);
24987             break;
24988         }
24989 #endif
24990         gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
24991         break;
24992     case OPC_PCNT_df:
24993         gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
24994         break;
24995     case OPC_NLOC_df:
24996         gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
24997         break;
24998     case OPC_NLZC_df:
24999         gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
25000         break;
25001     default:
25002         MIPS_INVAL("MSA instruction");
25003         generate_exception_end(ctx, EXCP_RI);
25004         break;
25005     }
25006
25007     tcg_temp_free_i32(twd);
25008     tcg_temp_free_i32(tws);
25009     tcg_temp_free_i32(twt);
25010     tcg_temp_free_i32(tdf);
25011 }
25012
25013 static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
25014 {
25015 #define MASK_MSA_2RF(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
25016                             (op & (0xf << 17)))
25017     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
25018     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
25019     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
25020     uint8_t df = (ctx->opcode >> 16) & 0x1;
25021     TCGv_i32 twd = tcg_const_i32(wd);
25022     TCGv_i32 tws = tcg_const_i32(ws);
25023     TCGv_i32 twt = tcg_const_i32(wt);
25024     /* adjust df value for floating-point instruction */
25025     TCGv_i32 tdf = tcg_const_i32(df + 2);
25026
25027     switch (MASK_MSA_2RF(ctx->opcode)) {
25028     case OPC_FCLASS_df:
25029         gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
25030         break;
25031     case OPC_FTRUNC_S_df:
25032         gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
25033         break;
25034     case OPC_FTRUNC_U_df:
25035         gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
25036         break;
25037     case OPC_FSQRT_df:
25038         gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
25039         break;
25040     case OPC_FRSQRT_df:
25041         gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
25042         break;
25043     case OPC_FRCP_df:
25044         gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
25045         break;
25046     case OPC_FRINT_df:
25047         gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
25048         break;
25049     case OPC_FLOG2_df:
25050         gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
25051         break;
25052     case OPC_FEXUPL_df:
25053         gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
25054         break;
25055     case OPC_FEXUPR_df:
25056         gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
25057         break;
25058     case OPC_FFQL_df:
25059         gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
25060         break;
25061     case OPC_FFQR_df:
25062         gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
25063         break;
25064     case OPC_FTINT_S_df:
25065         gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
25066         break;
25067     case OPC_FTINT_U_df:
25068         gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
25069         break;
25070     case OPC_FFINT_S_df:
25071         gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
25072         break;
25073     case OPC_FFINT_U_df:
25074         gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
25075         break;
25076     }
25077
25078     tcg_temp_free_i32(twd);
25079     tcg_temp_free_i32(tws);
25080     tcg_temp_free_i32(twt);
25081     tcg_temp_free_i32(tdf);
25082 }
25083
25084 static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
25085 {
25086 #define MASK_MSA_VEC(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
25087     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
25088     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
25089     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
25090     TCGv_i32 twd = tcg_const_i32(wd);
25091     TCGv_i32 tws = tcg_const_i32(ws);
25092     TCGv_i32 twt = tcg_const_i32(wt);
25093
25094     switch (MASK_MSA_VEC(ctx->opcode)) {
25095     case OPC_AND_V:
25096         gen_helper_msa_and_v(cpu_env, twd, tws, twt);
25097         break;
25098     case OPC_OR_V:
25099         gen_helper_msa_or_v(cpu_env, twd, tws, twt);
25100         break;
25101     case OPC_NOR_V:
25102         gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
25103         break;
25104     case OPC_XOR_V:
25105         gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
25106         break;
25107     case OPC_BMNZ_V:
25108         gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
25109         break;
25110     case OPC_BMZ_V:
25111         gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
25112         break;
25113     case OPC_BSEL_V:
25114         gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
25115         break;
25116     default:
25117         MIPS_INVAL("MSA instruction");
25118         generate_exception_end(ctx, EXCP_RI);
25119         break;
25120     }
25121
25122     tcg_temp_free_i32(twd);
25123     tcg_temp_free_i32(tws);
25124     tcg_temp_free_i32(twt);
25125 }
25126
25127 static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
25128 {
25129     switch (MASK_MSA_VEC(ctx->opcode)) {
25130     case OPC_AND_V:
25131     case OPC_OR_V:
25132     case OPC_NOR_V:
25133     case OPC_XOR_V:
25134     case OPC_BMNZ_V:
25135     case OPC_BMZ_V:
25136     case OPC_BSEL_V:
25137         gen_msa_vec_v(env, ctx);
25138         break;
25139     case OPC_MSA_2R:
25140         gen_msa_2r(env, ctx);
25141         break;
25142     case OPC_MSA_2RF:
25143         gen_msa_2rf(env, ctx);
25144         break;
25145     default:
25146         MIPS_INVAL("MSA instruction");
25147         generate_exception_end(ctx, EXCP_RI);
25148         break;
25149     }
25150 }
25151
25152 static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
25153 {
25154     uint32_t opcode = ctx->opcode;
25155     check_insn(ctx, ASE_MSA);
25156     check_msa_access(ctx);
25157
25158     switch (MASK_MSA_MINOR(opcode)) {
25159     case OPC_MSA_I8_00:
25160     case OPC_MSA_I8_01:
25161     case OPC_MSA_I8_02:
25162         gen_msa_i8(env, ctx);
25163         break;
25164     case OPC_MSA_I5_06:
25165     case OPC_MSA_I5_07:
25166         gen_msa_i5(env, ctx);
25167         break;
25168     case OPC_MSA_BIT_09:
25169     case OPC_MSA_BIT_0A:
25170         gen_msa_bit(env, ctx);
25171         break;
25172     case OPC_MSA_3R_0D:
25173     case OPC_MSA_3R_0E:
25174     case OPC_MSA_3R_0F:
25175     case OPC_MSA_3R_10:
25176     case OPC_MSA_3R_11:
25177     case OPC_MSA_3R_12:
25178     case OPC_MSA_3R_13:
25179     case OPC_MSA_3R_14:
25180     case OPC_MSA_3R_15:
25181         gen_msa_3r(env, ctx);
25182         break;
25183     case OPC_MSA_ELM:
25184         gen_msa_elm(env, ctx);
25185         break;
25186     case OPC_MSA_3RF_1A:
25187     case OPC_MSA_3RF_1B:
25188     case OPC_MSA_3RF_1C:
25189         gen_msa_3rf(env, ctx);
25190         break;
25191     case OPC_MSA_VEC:
25192         gen_msa_vec(env, ctx);
25193         break;
25194     case OPC_LD_B:
25195     case OPC_LD_H:
25196     case OPC_LD_W:
25197     case OPC_LD_D:
25198     case OPC_ST_B:
25199     case OPC_ST_H:
25200     case OPC_ST_W:
25201     case OPC_ST_D:
25202         {
25203             int32_t s10 = sextract32(ctx->opcode, 16, 10);
25204             uint8_t rs = (ctx->opcode >> 11) & 0x1f;
25205             uint8_t wd = (ctx->opcode >> 6) & 0x1f;
25206             uint8_t df = (ctx->opcode >> 0) & 0x3;
25207
25208             TCGv_i32 twd = tcg_const_i32(wd);
25209             TCGv taddr = tcg_temp_new();
25210             gen_base_offset_addr(ctx, taddr, rs, s10 << df);
25211
25212             switch (MASK_MSA_MINOR(opcode)) {
25213             case OPC_LD_B:
25214                 gen_helper_msa_ld_b(cpu_env, twd, taddr);
25215                 break;
25216             case OPC_LD_H:
25217                 gen_helper_msa_ld_h(cpu_env, twd, taddr);
25218                 break;
25219             case OPC_LD_W:
25220                 gen_helper_msa_ld_w(cpu_env, twd, taddr);
25221                 break;
25222             case OPC_LD_D:
25223                 gen_helper_msa_ld_d(cpu_env, twd, taddr);
25224                 break;
25225             case OPC_ST_B:
25226                 gen_helper_msa_st_b(cpu_env, twd, taddr);
25227                 break;
25228             case OPC_ST_H:
25229                 gen_helper_msa_st_h(cpu_env, twd, taddr);
25230                 break;
25231             case OPC_ST_W:
25232                 gen_helper_msa_st_w(cpu_env, twd, taddr);
25233                 break;
25234             case OPC_ST_D:
25235                 gen_helper_msa_st_d(cpu_env, twd, taddr);
25236                 break;
25237             }
25238
25239             tcg_temp_free_i32(twd);
25240             tcg_temp_free(taddr);
25241         }
25242         break;
25243     default:
25244         MIPS_INVAL("MSA instruction");
25245         generate_exception_end(ctx, EXCP_RI);
25246         break;
25247     }
25248
25249 }
25250
25251 static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
25252 {
25253     int32_t offset;
25254     int rs, rt, rd, sa;
25255     uint32_t op, op1;
25256     int16_t imm;
25257
25258     /* make sure instructions are on a word boundary */
25259     if (ctx->base.pc_next & 0x3) {
25260         env->CP0_BadVAddr = ctx->base.pc_next;
25261         generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
25262         return;
25263     }
25264
25265     /* Handle blikely not taken case */
25266     if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
25267         TCGLabel *l1 = gen_new_label();
25268
25269         tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
25270         tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
25271         gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
25272         gen_set_label(l1);
25273     }
25274
25275     op = MASK_OP_MAJOR(ctx->opcode);
25276     rs = (ctx->opcode >> 21) & 0x1f;
25277     rt = (ctx->opcode >> 16) & 0x1f;
25278     rd = (ctx->opcode >> 11) & 0x1f;
25279     sa = (ctx->opcode >> 6) & 0x1f;
25280     imm = (int16_t)ctx->opcode;
25281     switch (op) {
25282     case OPC_SPECIAL:
25283         decode_opc_special(env, ctx);
25284         break;
25285     case OPC_SPECIAL2:
25286         decode_opc_special2_legacy(env, ctx);
25287         break;
25288     case OPC_SPECIAL3:
25289         decode_opc_special3(env, ctx);
25290         break;
25291     case OPC_REGIMM:
25292         op1 = MASK_REGIMM(ctx->opcode);
25293         switch (op1) {
25294         case OPC_BLTZL: /* REGIMM branches */
25295         case OPC_BGEZL:
25296         case OPC_BLTZALL:
25297         case OPC_BGEZALL:
25298             check_insn(ctx, ISA_MIPS2);
25299             check_insn_opc_removed(ctx, ISA_MIPS32R6);
25300             /* Fallthrough */
25301         case OPC_BLTZ:
25302         case OPC_BGEZ:
25303             gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
25304             break;
25305         case OPC_BLTZAL:
25306         case OPC_BGEZAL:
25307             if (ctx->insn_flags & ISA_MIPS32R6) {
25308                 if (rs == 0) {
25309                     /* OPC_NAL, OPC_BAL */
25310                     gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
25311                 } else {
25312                     generate_exception_end(ctx, EXCP_RI);
25313                 }
25314             } else {
25315                 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
25316             }
25317             break;
25318         case OPC_TGEI: /* REGIMM traps */
25319         case OPC_TGEIU:
25320         case OPC_TLTI:
25321         case OPC_TLTIU:
25322         case OPC_TEQI:
25323
25324         case OPC_TNEI:
25325             check_insn(ctx, ISA_MIPS2);
25326             check_insn_opc_removed(ctx, ISA_MIPS32R6);
25327             gen_trap(ctx, op1, rs, -1, imm);
25328             break;
25329         case OPC_SIGRIE:
25330             check_insn(ctx, ISA_MIPS32R6);
25331             generate_exception_end(ctx, EXCP_RI);
25332             break;
25333         case OPC_SYNCI:
25334             check_insn(ctx, ISA_MIPS32R2);
25335             /* Break the TB to be able to sync copied instructions
25336                immediately */
25337             ctx->base.is_jmp = DISAS_STOP;
25338             break;
25339         case OPC_BPOSGE32:    /* MIPS DSP branch */
25340 #if defined(TARGET_MIPS64)
25341         case OPC_BPOSGE64:
25342 #endif
25343             check_dsp(ctx);
25344             gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
25345             break;
25346 #if defined(TARGET_MIPS64)
25347         case OPC_DAHI:
25348             check_insn(ctx, ISA_MIPS32R6);
25349             check_mips_64(ctx);
25350             if (rs != 0) {
25351                 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
25352             }
25353             break;
25354         case OPC_DATI:
25355             check_insn(ctx, ISA_MIPS32R6);
25356             check_mips_64(ctx);
25357             if (rs != 0) {
25358                 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
25359             }
25360             break;
25361 #endif
25362         default:            /* Invalid */
25363             MIPS_INVAL("regimm");
25364             generate_exception_end(ctx, EXCP_RI);
25365             break;
25366         }
25367         break;
25368     case OPC_CP0:
25369         check_cp0_enabled(ctx);
25370         op1 = MASK_CP0(ctx->opcode);
25371         switch (op1) {
25372         case OPC_MFC0:
25373         case OPC_MTC0:
25374         case OPC_MFTR:
25375         case OPC_MTTR:
25376         case OPC_MFHC0:
25377         case OPC_MTHC0:
25378 #if defined(TARGET_MIPS64)
25379         case OPC_DMFC0:
25380         case OPC_DMTC0:
25381 #endif
25382 #ifndef CONFIG_USER_ONLY
25383             gen_cp0(env, ctx, op1, rt, rd);
25384 #endif /* !CONFIG_USER_ONLY */
25385             break;
25386         case OPC_C0:
25387         case OPC_C0_1:
25388         case OPC_C0_2:
25389         case OPC_C0_3:
25390         case OPC_C0_4:
25391         case OPC_C0_5:
25392         case OPC_C0_6:
25393         case OPC_C0_7:
25394         case OPC_C0_8:
25395         case OPC_C0_9:
25396         case OPC_C0_A:
25397         case OPC_C0_B:
25398         case OPC_C0_C:
25399         case OPC_C0_D:
25400         case OPC_C0_E:
25401         case OPC_C0_F:
25402 #ifndef CONFIG_USER_ONLY
25403             gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
25404 #endif /* !CONFIG_USER_ONLY */
25405             break;
25406         case OPC_MFMC0:
25407 #ifndef CONFIG_USER_ONLY
25408             {
25409                 uint32_t op2;
25410                 TCGv t0 = tcg_temp_new();
25411
25412                 op2 = MASK_MFMC0(ctx->opcode);
25413                 switch (op2) {
25414                 case OPC_DMT:
25415                     check_cp0_mt(ctx);
25416                     gen_helper_dmt(t0);
25417                     gen_store_gpr(t0, rt);
25418                     break;
25419                 case OPC_EMT:
25420                     check_cp0_mt(ctx);
25421                     gen_helper_emt(t0);
25422                     gen_store_gpr(t0, rt);
25423                     break;
25424                 case OPC_DVPE:
25425                     check_cp0_mt(ctx);
25426                     gen_helper_dvpe(t0, cpu_env);
25427                     gen_store_gpr(t0, rt);
25428                     break;
25429                 case OPC_EVPE:
25430                     check_cp0_mt(ctx);
25431                     gen_helper_evpe(t0, cpu_env);
25432                     gen_store_gpr(t0, rt);
25433                     break;
25434                 case OPC_DVP:
25435                     check_insn(ctx, ISA_MIPS32R6);
25436                     if (ctx->vp) {
25437                         gen_helper_dvp(t0, cpu_env);
25438                         gen_store_gpr(t0, rt);
25439                     }
25440                     break;
25441                 case OPC_EVP:
25442                     check_insn(ctx, ISA_MIPS32R6);
25443                     if (ctx->vp) {
25444                         gen_helper_evp(t0, cpu_env);
25445                         gen_store_gpr(t0, rt);
25446                     }
25447                     break;
25448                 case OPC_DI:
25449                     check_insn(ctx, ISA_MIPS32R2);
25450                     save_cpu_state(ctx, 1);
25451                     gen_helper_di(t0, cpu_env);
25452                     gen_store_gpr(t0, rt);
25453                     /* Stop translation as we may have switched
25454                        the execution mode.  */
25455                     ctx->base.is_jmp = DISAS_STOP;
25456                     break;
25457                 case OPC_EI:
25458                     check_insn(ctx, ISA_MIPS32R2);
25459                     save_cpu_state(ctx, 1);
25460                     gen_helper_ei(t0, cpu_env);
25461                     gen_store_gpr(t0, rt);
25462                     /* DISAS_STOP isn't sufficient, we need to ensure we break
25463                        out of translated code to check for pending interrupts */
25464                     gen_save_pc(ctx->base.pc_next + 4);
25465                     ctx->base.is_jmp = DISAS_EXIT;
25466                     break;
25467                 default:            /* Invalid */
25468                     MIPS_INVAL("mfmc0");
25469                     generate_exception_end(ctx, EXCP_RI);
25470                     break;
25471                 }
25472                 tcg_temp_free(t0);
25473             }
25474 #endif /* !CONFIG_USER_ONLY */
25475             break;
25476         case OPC_RDPGPR:
25477             check_insn(ctx, ISA_MIPS32R2);
25478             gen_load_srsgpr(rt, rd);
25479             break;
25480         case OPC_WRPGPR:
25481             check_insn(ctx, ISA_MIPS32R2);
25482             gen_store_srsgpr(rt, rd);
25483             break;
25484         default:
25485             MIPS_INVAL("cp0");
25486             generate_exception_end(ctx, EXCP_RI);
25487             break;
25488         }
25489         break;
25490     case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
25491         if (ctx->insn_flags & ISA_MIPS32R6) {
25492             /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
25493             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25494         } else {
25495             /* OPC_ADDI */
25496             /* Arithmetic with immediate opcode */
25497             gen_arith_imm(ctx, op, rt, rs, imm);
25498         }
25499         break;
25500     case OPC_ADDIU:
25501          gen_arith_imm(ctx, op, rt, rs, imm);
25502          break;
25503     case OPC_SLTI: /* Set on less than with immediate opcode */
25504     case OPC_SLTIU:
25505          gen_slt_imm(ctx, op, rt, rs, imm);
25506          break;
25507     case OPC_ANDI: /* Arithmetic with immediate opcode */
25508     case OPC_LUI: /* OPC_AUI */
25509     case OPC_ORI:
25510     case OPC_XORI:
25511          gen_logic_imm(ctx, op, rt, rs, imm);
25512          break;
25513     case OPC_J: /* Jump */
25514     case OPC_JAL:
25515          offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
25516          gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
25517          break;
25518     /* Branch */
25519     case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
25520         if (ctx->insn_flags & ISA_MIPS32R6) {
25521             if (rt == 0) {
25522                 generate_exception_end(ctx, EXCP_RI);
25523                 break;
25524             }
25525             /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
25526             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25527         } else {
25528             /* OPC_BLEZL */
25529             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
25530         }
25531         break;
25532     case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
25533         if (ctx->insn_flags & ISA_MIPS32R6) {
25534             if (rt == 0) {
25535                 generate_exception_end(ctx, EXCP_RI);
25536                 break;
25537             }
25538             /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
25539             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25540         } else {
25541             /* OPC_BGTZL */
25542             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
25543         }
25544         break;
25545     case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
25546         if (rt == 0) {
25547             /* OPC_BLEZ */
25548             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
25549         } else {
25550             check_insn(ctx, ISA_MIPS32R6);
25551             /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
25552             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25553         }
25554         break;
25555     case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
25556         if (rt == 0) {
25557             /* OPC_BGTZ */
25558             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
25559         } else {
25560             check_insn(ctx, ISA_MIPS32R6);
25561             /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
25562             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25563         }
25564         break;
25565     case OPC_BEQL:
25566     case OPC_BNEL:
25567         check_insn(ctx, ISA_MIPS2);
25568          check_insn_opc_removed(ctx, ISA_MIPS32R6);
25569         /* Fallthrough */
25570     case OPC_BEQ:
25571     case OPC_BNE:
25572          gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
25573          break;
25574     case OPC_LL: /* Load and stores */
25575         check_insn(ctx, ISA_MIPS2);
25576         /* Fallthrough */
25577     case OPC_LWL:
25578     case OPC_LWR:
25579         check_insn_opc_removed(ctx, ISA_MIPS32R6);
25580          /* Fallthrough */
25581     case OPC_LB:
25582     case OPC_LH:
25583     case OPC_LW:
25584     case OPC_LWPC:
25585     case OPC_LBU:
25586     case OPC_LHU:
25587          gen_ld(ctx, op, rt, rs, imm);
25588          break;
25589     case OPC_SWL:
25590     case OPC_SWR:
25591         check_insn_opc_removed(ctx, ISA_MIPS32R6);
25592         /* fall through */
25593     case OPC_SB:
25594     case OPC_SH:
25595     case OPC_SW:
25596          gen_st(ctx, op, rt, rs, imm);
25597          break;
25598     case OPC_SC:
25599         check_insn(ctx, ISA_MIPS2);
25600          check_insn_opc_removed(ctx, ISA_MIPS32R6);
25601          gen_st_cond(ctx, op, rt, rs, imm);
25602          break;
25603     case OPC_CACHE:
25604         check_insn_opc_removed(ctx, ISA_MIPS32R6);
25605         check_cp0_enabled(ctx);
25606         check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
25607         if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
25608             gen_cache_operation(ctx, rt, rs, imm);
25609         }
25610         /* Treat as NOP. */
25611         break;
25612     case OPC_PREF:
25613         check_insn_opc_removed(ctx, ISA_MIPS32R6);
25614         check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
25615         /* Treat as NOP. */
25616         break;
25617
25618     /* Floating point (COP1). */
25619     case OPC_LWC1:
25620     case OPC_LDC1:
25621     case OPC_SWC1:
25622     case OPC_SDC1:
25623         gen_cop1_ldst(ctx, op, rt, rs, imm);
25624         break;
25625
25626     case OPC_CP1:
25627         op1 = MASK_CP1(ctx->opcode);
25628
25629         switch (op1) {
25630         case OPC_MFHC1:
25631         case OPC_MTHC1:
25632             check_cp1_enabled(ctx);
25633             check_insn(ctx, ISA_MIPS32R2);
25634             /* fall through */
25635         case OPC_MFC1:
25636         case OPC_CFC1:
25637         case OPC_MTC1:
25638         case OPC_CTC1:
25639             check_cp1_enabled(ctx);
25640             gen_cp1(ctx, op1, rt, rd);
25641             break;
25642 #if defined(TARGET_MIPS64)
25643         case OPC_DMFC1:
25644         case OPC_DMTC1:
25645             check_cp1_enabled(ctx);
25646             check_insn(ctx, ISA_MIPS3);
25647             check_mips_64(ctx);
25648             gen_cp1(ctx, op1, rt, rd);
25649             break;
25650 #endif
25651         case OPC_BC1EQZ: /* OPC_BC1ANY2 */
25652             check_cp1_enabled(ctx);
25653             if (ctx->insn_flags & ISA_MIPS32R6) {
25654                 /* OPC_BC1EQZ */
25655                 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
25656                                        rt, imm << 2, 4);
25657             } else {
25658                 /* OPC_BC1ANY2 */
25659                 check_cop1x(ctx);
25660                 check_insn(ctx, ASE_MIPS3D);
25661                 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
25662                                     (rt >> 2) & 0x7, imm << 2);
25663             }
25664             break;
25665         case OPC_BC1NEZ:
25666             check_cp1_enabled(ctx);
25667             check_insn(ctx, ISA_MIPS32R6);
25668             gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
25669                                    rt, imm << 2, 4);
25670             break;
25671         case OPC_BC1ANY4:
25672             check_cp1_enabled(ctx);
25673             check_insn_opc_removed(ctx, ISA_MIPS32R6);
25674             check_cop1x(ctx);
25675             check_insn(ctx, ASE_MIPS3D);
25676             /* fall through */
25677         case OPC_BC1:
25678             check_cp1_enabled(ctx);
25679             check_insn_opc_removed(ctx, ISA_MIPS32R6);
25680             gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
25681                                 (rt >> 2) & 0x7, imm << 2);
25682             break;
25683         case OPC_PS_FMT:
25684             check_ps(ctx);
25685             /* fall through */
25686         case OPC_S_FMT:
25687         case OPC_D_FMT:
25688             check_cp1_enabled(ctx);
25689             gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
25690                        (imm >> 8) & 0x7);
25691             break;
25692         case OPC_W_FMT:
25693         case OPC_L_FMT:
25694         {
25695             int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
25696             check_cp1_enabled(ctx);
25697             if (ctx->insn_flags & ISA_MIPS32R6) {
25698                 switch (r6_op) {
25699                 case R6_OPC_CMP_AF_S:
25700                 case R6_OPC_CMP_UN_S:
25701                 case R6_OPC_CMP_EQ_S:
25702                 case R6_OPC_CMP_UEQ_S:
25703                 case R6_OPC_CMP_LT_S:
25704                 case R6_OPC_CMP_ULT_S:
25705                 case R6_OPC_CMP_LE_S:
25706                 case R6_OPC_CMP_ULE_S:
25707                 case R6_OPC_CMP_SAF_S:
25708                 case R6_OPC_CMP_SUN_S:
25709                 case R6_OPC_CMP_SEQ_S:
25710                 case R6_OPC_CMP_SEUQ_S:
25711                 case R6_OPC_CMP_SLT_S:
25712                 case R6_OPC_CMP_SULT_S:
25713                 case R6_OPC_CMP_SLE_S:
25714                 case R6_OPC_CMP_SULE_S:
25715                 case R6_OPC_CMP_OR_S:
25716                 case R6_OPC_CMP_UNE_S:
25717                 case R6_OPC_CMP_NE_S:
25718                 case R6_OPC_CMP_SOR_S:
25719                 case R6_OPC_CMP_SUNE_S:
25720                 case R6_OPC_CMP_SNE_S:
25721                     gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
25722                     break;
25723                 case R6_OPC_CMP_AF_D:
25724                 case R6_OPC_CMP_UN_D:
25725                 case R6_OPC_CMP_EQ_D:
25726                 case R6_OPC_CMP_UEQ_D:
25727                 case R6_OPC_CMP_LT_D:
25728                 case R6_OPC_CMP_ULT_D:
25729                 case R6_OPC_CMP_LE_D:
25730                 case R6_OPC_CMP_ULE_D:
25731                 case R6_OPC_CMP_SAF_D:
25732                 case R6_OPC_CMP_SUN_D:
25733                 case R6_OPC_CMP_SEQ_D:
25734                 case R6_OPC_CMP_SEUQ_D:
25735                 case R6_OPC_CMP_SLT_D:
25736                 case R6_OPC_CMP_SULT_D:
25737                 case R6_OPC_CMP_SLE_D:
25738                 case R6_OPC_CMP_SULE_D:
25739                 case R6_OPC_CMP_OR_D:
25740                 case R6_OPC_CMP_UNE_D:
25741                 case R6_OPC_CMP_NE_D:
25742                 case R6_OPC_CMP_SOR_D:
25743                 case R6_OPC_CMP_SUNE_D:
25744                 case R6_OPC_CMP_SNE_D:
25745                     gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
25746                     break;
25747                 default:
25748                     gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
25749                                rt, rd, sa, (imm >> 8) & 0x7);
25750
25751                     break;
25752                 }
25753             } else {
25754                 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
25755                            (imm >> 8) & 0x7);
25756             }
25757             break;
25758         }
25759         case OPC_BZ_V:
25760         case OPC_BNZ_V:
25761         case OPC_BZ_B:
25762         case OPC_BZ_H:
25763         case OPC_BZ_W:
25764         case OPC_BZ_D:
25765         case OPC_BNZ_B:
25766         case OPC_BNZ_H:
25767         case OPC_BNZ_W:
25768         case OPC_BNZ_D:
25769             check_insn(ctx, ASE_MSA);
25770             gen_msa_branch(env, ctx, op1);
25771             break;
25772         default:
25773             MIPS_INVAL("cp1");
25774             generate_exception_end(ctx, EXCP_RI);
25775             break;
25776         }
25777         break;
25778
25779     /* Compact branches [R6] and COP2 [non-R6] */
25780     case OPC_BC: /* OPC_LWC2 */
25781     case OPC_BALC: /* OPC_SWC2 */
25782         if (ctx->insn_flags & ISA_MIPS32R6) {
25783             /* OPC_BC, OPC_BALC */
25784             gen_compute_compact_branch(ctx, op, 0, 0,
25785                                        sextract32(ctx->opcode << 2, 0, 28));
25786         } else {
25787             /* OPC_LWC2, OPC_SWC2 */
25788             /* COP2: Not implemented. */
25789             generate_exception_err(ctx, EXCP_CpU, 2);
25790         }
25791         break;
25792     case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
25793     case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
25794         if (ctx->insn_flags & ISA_MIPS32R6) {
25795             if (rs != 0) {
25796                 /* OPC_BEQZC, OPC_BNEZC */
25797                 gen_compute_compact_branch(ctx, op, rs, 0,
25798                                            sextract32(ctx->opcode << 2, 0, 23));
25799             } else {
25800                 /* OPC_JIC, OPC_JIALC */
25801                 gen_compute_compact_branch(ctx, op, 0, rt, imm);
25802             }
25803         } else {
25804             /* OPC_LWC2, OPC_SWC2 */
25805             /* COP2: Not implemented. */
25806             generate_exception_err(ctx, EXCP_CpU, 2);
25807         }
25808         break;
25809     case OPC_CP2:
25810         check_insn(ctx, INSN_LOONGSON2F);
25811         /* Note that these instructions use different fields.  */
25812         gen_loongson_multimedia(ctx, sa, rd, rt);
25813         break;
25814
25815     case OPC_CP3:
25816         check_insn_opc_removed(ctx, ISA_MIPS32R6);
25817         if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
25818             check_cp1_enabled(ctx);
25819             op1 = MASK_CP3(ctx->opcode);
25820             switch (op1) {
25821             case OPC_LUXC1:
25822             case OPC_SUXC1:
25823                 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
25824                 /* Fallthrough */
25825             case OPC_LWXC1:
25826             case OPC_LDXC1:
25827             case OPC_SWXC1:
25828             case OPC_SDXC1:
25829                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
25830                 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
25831                 break;
25832             case OPC_PREFX:
25833                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
25834                 /* Treat as NOP. */
25835                 break;
25836             case OPC_ALNV_PS:
25837                 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
25838                 /* Fallthrough */
25839             case OPC_MADD_S:
25840             case OPC_MADD_D:
25841             case OPC_MADD_PS:
25842             case OPC_MSUB_S:
25843             case OPC_MSUB_D:
25844             case OPC_MSUB_PS:
25845             case OPC_NMADD_S:
25846             case OPC_NMADD_D:
25847             case OPC_NMADD_PS:
25848             case OPC_NMSUB_S:
25849             case OPC_NMSUB_D:
25850             case OPC_NMSUB_PS:
25851                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
25852                 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
25853                 break;
25854             default:
25855                 MIPS_INVAL("cp3");
25856                 generate_exception_end(ctx, EXCP_RI);
25857                 break;
25858             }
25859         } else {
25860             generate_exception_err(ctx, EXCP_CpU, 1);
25861         }
25862         break;
25863
25864 #if defined(TARGET_MIPS64)
25865     /* MIPS64 opcodes */
25866     case OPC_LDL:
25867     case OPC_LDR:
25868     case OPC_LLD:
25869         check_insn_opc_removed(ctx, ISA_MIPS32R6);
25870         /* fall through */
25871     case OPC_LWU:
25872     case OPC_LD:
25873         check_insn(ctx, ISA_MIPS3);
25874         check_mips_64(ctx);
25875         gen_ld(ctx, op, rt, rs, imm);
25876         break;
25877     case OPC_SDL:
25878     case OPC_SDR:
25879         check_insn_opc_removed(ctx, ISA_MIPS32R6);
25880         /* fall through */
25881     case OPC_SD:
25882         check_insn(ctx, ISA_MIPS3);
25883         check_mips_64(ctx);
25884         gen_st(ctx, op, rt, rs, imm);
25885         break;
25886     case OPC_SCD:
25887         check_insn_opc_removed(ctx, ISA_MIPS32R6);
25888         check_insn(ctx, ISA_MIPS3);
25889         check_mips_64(ctx);
25890         gen_st_cond(ctx, op, rt, rs, imm);
25891         break;
25892     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
25893         if (ctx->insn_flags & ISA_MIPS32R6) {
25894             /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
25895             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25896         } else {
25897             /* OPC_DADDI */
25898             check_insn(ctx, ISA_MIPS3);
25899             check_mips_64(ctx);
25900             gen_arith_imm(ctx, op, rt, rs, imm);
25901         }
25902         break;
25903     case OPC_DADDIU:
25904         check_insn(ctx, ISA_MIPS3);
25905         check_mips_64(ctx);
25906         gen_arith_imm(ctx, op, rt, rs, imm);
25907         break;
25908 #else
25909     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
25910         if (ctx->insn_flags & ISA_MIPS32R6) {
25911             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25912         } else {
25913             MIPS_INVAL("major opcode");
25914             generate_exception_end(ctx, EXCP_RI);
25915         }
25916         break;
25917 #endif
25918     case OPC_DAUI: /* OPC_JALX */
25919         if (ctx->insn_flags & ISA_MIPS32R6) {
25920 #if defined(TARGET_MIPS64)
25921             /* OPC_DAUI */
25922             check_mips_64(ctx);
25923             if (rs == 0) {
25924                 generate_exception(ctx, EXCP_RI);
25925             } else if (rt != 0) {
25926                 TCGv t0 = tcg_temp_new();
25927                 gen_load_gpr(t0, rs);
25928                 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
25929                 tcg_temp_free(t0);
25930             }
25931 #else
25932             generate_exception_end(ctx, EXCP_RI);
25933             MIPS_INVAL("major opcode");
25934 #endif
25935         } else {
25936             /* OPC_JALX */
25937             check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
25938             offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
25939             gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
25940         }
25941         break;
25942     case OPC_MSA: /* OPC_MDMX */
25943         /* MDMX: Not implemented. */
25944         gen_msa(env, ctx);
25945         break;
25946     case OPC_PCREL:
25947         check_insn(ctx, ISA_MIPS32R6);
25948         gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
25949         break;
25950     default:            /* Invalid */
25951         MIPS_INVAL("major opcode");
25952         generate_exception_end(ctx, EXCP_RI);
25953         break;
25954     }
25955 }
25956
25957 static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
25958 {
25959     DisasContext *ctx = container_of(dcbase, DisasContext, base);
25960     CPUMIPSState *env = cs->env_ptr;
25961
25962     ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
25963     ctx->saved_pc = -1;
25964     ctx->insn_flags = env->insn_flags;
25965     ctx->CP0_Config1 = env->CP0_Config1;
25966     ctx->CP0_Config2 = env->CP0_Config2;
25967     ctx->CP0_Config3 = env->CP0_Config3;
25968     ctx->CP0_Config5 = env->CP0_Config5;
25969     ctx->btarget = 0;
25970     ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
25971     ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
25972     ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
25973     ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
25974     ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
25975     ctx->PAMask = env->PAMask;
25976     ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
25977     ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
25978     ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
25979     ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
25980     ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
25981     /* Restore delay slot state from the tb context.  */
25982     ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
25983     ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
25984     ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
25985              (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
25986     ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
25987     ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
25988     ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
25989     ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
25990     restore_cpu_state(env, ctx);
25991 #ifdef CONFIG_USER_ONLY
25992         ctx->mem_idx = MIPS_HFLAG_UM;
25993 #else
25994         ctx->mem_idx = hflags_mmu_index(ctx->hflags);
25995 #endif
25996     ctx->default_tcg_memop_mask = (ctx->insn_flags & ISA_MIPS32R6) ?
25997                                   MO_UNALN : MO_ALIGN;
25998
25999     LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
26000               ctx->hflags);
26001 }
26002
26003 static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
26004 {
26005 }
26006
26007 static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
26008 {
26009     DisasContext *ctx = container_of(dcbase, DisasContext, base);
26010
26011     tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
26012                        ctx->btarget);
26013 }
26014
26015 static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
26016                                      const CPUBreakpoint *bp)
26017 {
26018     DisasContext *ctx = container_of(dcbase, DisasContext, base);
26019
26020     save_cpu_state(ctx, 1);
26021     ctx->base.is_jmp = DISAS_NORETURN;
26022     gen_helper_raise_exception_debug(cpu_env);
26023     /* The address covered by the breakpoint must be included in
26024        [tb->pc, tb->pc + tb->size) in order to for it to be
26025        properly cleared -- thus we increment the PC here so that
26026        the logic setting tb->size below does the right thing.  */
26027     ctx->base.pc_next += 4;
26028     return true;
26029 }
26030
26031 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
26032 {
26033     CPUMIPSState *env = cs->env_ptr;
26034     DisasContext *ctx = container_of(dcbase, DisasContext, base);
26035     int insn_bytes;
26036     int is_slot;
26037
26038     is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
26039     if (ctx->insn_flags & ISA_NANOMIPS32) {
26040         ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
26041         insn_bytes = decode_nanomips_opc(env, ctx);
26042     } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
26043         ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
26044         insn_bytes = 4;
26045         decode_opc(env, ctx);
26046     } else if (ctx->insn_flags & ASE_MICROMIPS) {
26047         ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
26048         insn_bytes = decode_micromips_opc(env, ctx);
26049     } else if (ctx->insn_flags & ASE_MIPS16) {
26050         ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
26051         insn_bytes = decode_mips16_opc(env, ctx);
26052     } else {
26053         generate_exception_end(ctx, EXCP_RI);
26054         g_assert(ctx->base.is_jmp == DISAS_NORETURN);
26055         return;
26056     }
26057
26058     if (ctx->hflags & MIPS_HFLAG_BMASK) {
26059         if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
26060                              MIPS_HFLAG_FBNSLOT))) {
26061             /* force to generate branch as there is neither delay nor
26062                forbidden slot */
26063             is_slot = 1;
26064         }
26065         if ((ctx->hflags & MIPS_HFLAG_M16) &&
26066             (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
26067             /* Force to generate branch as microMIPS R6 doesn't restrict
26068                branches in the forbidden slot. */
26069             is_slot = 1;
26070         }
26071     }
26072     if (is_slot) {
26073         gen_branch(ctx, insn_bytes);
26074     }
26075     ctx->base.pc_next += insn_bytes;
26076
26077     if (ctx->base.is_jmp != DISAS_NEXT) {
26078         return;
26079     }
26080     /* Execute a branch and its delay slot as a single instruction.
26081        This is what GDB expects and is consistent with what the
26082        hardware does (e.g. if a delay slot instruction faults, the
26083        reported PC is the PC of the branch).  */
26084     if (ctx->base.singlestep_enabled &&
26085         (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
26086         ctx->base.is_jmp = DISAS_TOO_MANY;
26087     }
26088     if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
26089         ctx->base.is_jmp = DISAS_TOO_MANY;
26090     }
26091 }
26092
26093 static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
26094 {
26095     DisasContext *ctx = container_of(dcbase, DisasContext, base);
26096
26097     if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
26098         save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
26099         gen_helper_raise_exception_debug(cpu_env);
26100     } else {
26101         switch (ctx->base.is_jmp) {
26102         case DISAS_STOP:
26103             gen_save_pc(ctx->base.pc_next);
26104             tcg_gen_lookup_and_goto_ptr();
26105             break;
26106         case DISAS_NEXT:
26107         case DISAS_TOO_MANY:
26108             save_cpu_state(ctx, 0);
26109             gen_goto_tb(ctx, 0, ctx->base.pc_next);
26110             break;
26111         case DISAS_EXIT:
26112             tcg_gen_exit_tb(NULL, 0);
26113             break;
26114         case DISAS_NORETURN:
26115             break;
26116         default:
26117             g_assert_not_reached();
26118         }
26119     }
26120 }
26121
26122 static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
26123 {
26124     qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
26125     log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
26126 }
26127
26128 static const TranslatorOps mips_tr_ops = {
26129     .init_disas_context = mips_tr_init_disas_context,
26130     .tb_start           = mips_tr_tb_start,
26131     .insn_start         = mips_tr_insn_start,
26132     .breakpoint_check   = mips_tr_breakpoint_check,
26133     .translate_insn     = mips_tr_translate_insn,
26134     .tb_stop            = mips_tr_tb_stop,
26135     .disas_log          = mips_tr_disas_log,
26136 };
26137
26138 void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
26139 {
26140     DisasContext ctx;
26141
26142     translator_loop(&mips_tr_ops, &ctx.base, cs, tb);
26143 }
26144
26145 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
26146                            int flags)
26147 {
26148     int i;
26149     int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
26150
26151 #define printfpr(fp)                                                    \
26152     do {                                                                \
26153         if (is_fpu64)                                                   \
26154             fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
26155                         " fd:%13g fs:%13g psu: %13g\n",                 \
26156                         (fp)->w[FP_ENDIAN_IDX], (fp)->d,                \
26157                         (double)(fp)->fd,                               \
26158                         (double)(fp)->fs[FP_ENDIAN_IDX],                \
26159                         (double)(fp)->fs[!FP_ENDIAN_IDX]);              \
26160         else {                                                          \
26161             fpr_t tmp;                                                  \
26162             tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];              \
26163             tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];       \
26164             fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
26165                         " fd:%13g fs:%13g psu:%13g\n",                  \
26166                         tmp.w[FP_ENDIAN_IDX], tmp.d,                    \
26167                         (double)tmp.fd,                                 \
26168                         (double)tmp.fs[FP_ENDIAN_IDX],                  \
26169                         (double)tmp.fs[!FP_ENDIAN_IDX]);                \
26170         }                                                               \
26171     } while(0)
26172
26173
26174     fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%02x\n",
26175                 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
26176                 get_float_exception_flags(&env->active_fpu.fp_status));
26177     for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
26178         fpu_fprintf(f, "%3s: ", fregnames[i]);
26179         printfpr(&env->active_fpu.fpr[i]);
26180     }
26181
26182 #undef printfpr
26183 }
26184
26185 void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
26186                          int flags)
26187 {
26188     MIPSCPU *cpu = MIPS_CPU(cs);
26189     CPUMIPSState *env = &cpu->env;
26190     int i;
26191
26192     cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
26193                 " LO=0x" TARGET_FMT_lx " ds %04x "
26194                 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
26195                 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
26196                 env->hflags, env->btarget, env->bcond);
26197     for (i = 0; i < 32; i++) {
26198         if ((i & 3) == 0)
26199             cpu_fprintf(f, "GPR%02d:", i);
26200         cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
26201         if ((i & 3) == 3)
26202             cpu_fprintf(f, "\n");
26203     }
26204
26205     cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
26206                 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
26207     cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
26208                 PRIx64 "\n",
26209                 env->CP0_Config0, env->CP0_Config1, env->lladdr);
26210     cpu_fprintf(f, "    Config2 0x%08x Config3 0x%08x\n",
26211                 env->CP0_Config2, env->CP0_Config3);
26212     cpu_fprintf(f, "    Config4 0x%08x Config5 0x%08x\n",
26213                 env->CP0_Config4, env->CP0_Config5);
26214     if ((flags & CPU_DUMP_FPU) && (env->hflags & MIPS_HFLAG_FPU)) {
26215         fpu_dump_state(env, f, cpu_fprintf, flags);
26216     }
26217 }
26218
26219 void mips_tcg_init(void)
26220 {
26221     int i;
26222
26223     cpu_gpr[0] = NULL;
26224     for (i = 1; i < 32; i++)
26225         cpu_gpr[i] = tcg_global_mem_new(cpu_env,
26226                                         offsetof(CPUMIPSState, active_tc.gpr[i]),
26227                                         regnames[i]);
26228
26229     for (i = 0; i < 32; i++) {
26230         int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
26231         msa_wr_d[i * 2] =
26232                 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
26233         /* The scalar floating-point unit (FPU) registers are mapped on
26234          * the MSA vector registers. */
26235         fpu_f64[i] = msa_wr_d[i * 2];
26236         off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
26237         msa_wr_d[i * 2 + 1] =
26238                 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
26239     }
26240
26241     cpu_PC = tcg_global_mem_new(cpu_env,
26242                                 offsetof(CPUMIPSState, active_tc.PC), "PC");
26243     for (i = 0; i < MIPS_DSP_ACC; i++) {
26244         cpu_HI[i] = tcg_global_mem_new(cpu_env,
26245                                        offsetof(CPUMIPSState, active_tc.HI[i]),
26246                                        regnames_HI[i]);
26247         cpu_LO[i] = tcg_global_mem_new(cpu_env,
26248                                        offsetof(CPUMIPSState, active_tc.LO[i]),
26249                                        regnames_LO[i]);
26250     }
26251     cpu_dspctrl = tcg_global_mem_new(cpu_env,
26252                                      offsetof(CPUMIPSState, active_tc.DSPControl),
26253                                      "DSPControl");
26254     bcond = tcg_global_mem_new(cpu_env,
26255                                offsetof(CPUMIPSState, bcond), "bcond");
26256     btarget = tcg_global_mem_new(cpu_env,
26257                                  offsetof(CPUMIPSState, btarget), "btarget");
26258     hflags = tcg_global_mem_new_i32(cpu_env,
26259                                     offsetof(CPUMIPSState, hflags), "hflags");
26260
26261     fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
26262                                       offsetof(CPUMIPSState, active_fpu.fcr0),
26263                                       "fcr0");
26264     fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
26265                                        offsetof(CPUMIPSState, active_fpu.fcr31),
26266                                        "fcr31");
26267 }
26268
26269 #include "translate_init.inc.c"
26270
26271 void cpu_mips_realize_env(CPUMIPSState *env)
26272 {
26273     env->exception_base = (int32_t)0xBFC00000;
26274
26275 #ifndef CONFIG_USER_ONLY
26276     mmu_init(env, env->cpu_model);
26277 #endif
26278     fpu_init(env, env->cpu_model);
26279     mvp_init(env, env->cpu_model);
26280 }
26281
26282 bool cpu_supports_cps_smp(const char *cpu_type)
26283 {
26284     const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
26285     return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
26286 }
26287
26288 bool cpu_supports_isa(const char *cpu_type, unsigned int isa)
26289 {
26290     const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
26291     return (mcc->cpu_def->insn_flags & isa) != 0;
26292 }
26293
26294 void cpu_set_exception_base(int vp_index, target_ulong address)
26295 {
26296     MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
26297     vp->env.exception_base = address;
26298 }
26299
26300 void cpu_state_reset(CPUMIPSState *env)
26301 {
26302     MIPSCPU *cpu = mips_env_get_cpu(env);
26303     CPUState *cs = CPU(cpu);
26304
26305     /* Reset registers to their default values */
26306     env->CP0_PRid = env->cpu_model->CP0_PRid;
26307     env->CP0_Config0 = env->cpu_model->CP0_Config0;
26308 #ifdef TARGET_WORDS_BIGENDIAN
26309     env->CP0_Config0 |= (1 << CP0C0_BE);
26310 #endif
26311     env->CP0_Config1 = env->cpu_model->CP0_Config1;
26312     env->CP0_Config2 = env->cpu_model->CP0_Config2;
26313     env->CP0_Config3 = env->cpu_model->CP0_Config3;
26314     env->CP0_Config4 = env->cpu_model->CP0_Config4;
26315     env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
26316     env->CP0_Config5 = env->cpu_model->CP0_Config5;
26317     env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
26318     env->CP0_Config6 = env->cpu_model->CP0_Config6;
26319     env->CP0_Config7 = env->cpu_model->CP0_Config7;
26320     env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
26321                                  << env->cpu_model->CP0_LLAddr_shift;
26322     env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
26323     env->SYNCI_Step = env->cpu_model->SYNCI_Step;
26324     env->CCRes = env->cpu_model->CCRes;
26325     env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
26326     env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
26327     env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
26328     env->current_tc = 0;
26329     env->SEGBITS = env->cpu_model->SEGBITS;
26330     env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
26331 #if defined(TARGET_MIPS64)
26332     if (env->cpu_model->insn_flags & ISA_MIPS3) {
26333         env->SEGMask |= 3ULL << 62;
26334     }
26335 #endif
26336     env->PABITS = env->cpu_model->PABITS;
26337     env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
26338     env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
26339     env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
26340     env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
26341     env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
26342     env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
26343     env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
26344     env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
26345     env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
26346     env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
26347     env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
26348     env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
26349     env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
26350     env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
26351     env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
26352     env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
26353     env->msair = env->cpu_model->MSAIR;
26354     env->insn_flags = env->cpu_model->insn_flags;
26355
26356 #if defined(CONFIG_USER_ONLY)
26357     env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
26358 # ifdef TARGET_MIPS64
26359     /* Enable 64-bit register mode.  */
26360     env->CP0_Status |= (1 << CP0St_PX);
26361 # endif
26362 # ifdef TARGET_ABI_MIPSN64
26363     /* Enable 64-bit address mode.  */
26364     env->CP0_Status |= (1 << CP0St_UX);
26365 # endif
26366     /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
26367        hardware registers.  */
26368     env->CP0_HWREna |= 0x0000000F;
26369     if (env->CP0_Config1 & (1 << CP0C1_FP)) {
26370         env->CP0_Status |= (1 << CP0St_CU1);
26371     }
26372     if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
26373         env->CP0_Status |= (1 << CP0St_MX);
26374     }
26375 # if defined(TARGET_MIPS64)
26376     /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
26377     if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
26378         (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
26379         env->CP0_Status |= (1 << CP0St_FR);
26380     }
26381 # endif
26382 #else
26383     if (env->hflags & MIPS_HFLAG_BMASK) {
26384         /* If the exception was raised from a delay slot,
26385            come back to the jump.  */
26386         env->CP0_ErrorEPC = (env->active_tc.PC
26387                              - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
26388     } else {
26389         env->CP0_ErrorEPC = env->active_tc.PC;
26390     }
26391     env->active_tc.PC = env->exception_base;
26392     env->CP0_Random = env->tlb->nb_tlb - 1;
26393     env->tlb->tlb_in_use = env->tlb->nb_tlb;
26394     env->CP0_Wired = 0;
26395     env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
26396     env->CP0_EBase = (cs->cpu_index & 0x3FF);
26397     if (mips_um_ksegs_enabled()) {
26398         env->CP0_EBase |= 0x40000000;
26399     } else {
26400         env->CP0_EBase |= (int32_t)0x80000000;
26401     }
26402     if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
26403         env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
26404     }
26405     env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
26406                                  0x3ff : 0xff;
26407     env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
26408     /* vectored interrupts not implemented, timer on int 7,
26409        no performance counters. */
26410     env->CP0_IntCtl = 0xe0000000;
26411     {
26412         int i;
26413
26414         for (i = 0; i < 7; i++) {
26415             env->CP0_WatchLo[i] = 0;
26416             env->CP0_WatchHi[i] = 0x80000000;
26417         }
26418         env->CP0_WatchLo[7] = 0;
26419         env->CP0_WatchHi[7] = 0;
26420     }
26421     /* Count register increments in debug mode, EJTAG version 1 */
26422     env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
26423
26424     cpu_mips_store_count(env, 1);
26425
26426     if (env->CP0_Config3 & (1 << CP0C3_MT)) {
26427         int i;
26428
26429         /* Only TC0 on VPE 0 starts as active.  */
26430         for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
26431             env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
26432             env->tcs[i].CP0_TCHalt = 1;
26433         }
26434         env->active_tc.CP0_TCHalt = 1;
26435         cs->halted = 1;
26436
26437         if (cs->cpu_index == 0) {
26438             /* VPE0 starts up enabled.  */
26439             env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
26440             env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
26441
26442             /* TC0 starts up unhalted.  */
26443             cs->halted = 0;
26444             env->active_tc.CP0_TCHalt = 0;
26445             env->tcs[0].CP0_TCHalt = 0;
26446             /* With thread 0 active.  */
26447             env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
26448             env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
26449         }
26450     }
26451
26452     /*
26453      * Configure default legacy segmentation control. We use this regardless of
26454      * whether segmentation control is presented to the guest.
26455      */
26456     /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
26457     env->CP0_SegCtl0 =   (CP0SC_AM_MK << CP0SC_AM);
26458     /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
26459     env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
26460     /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
26461     env->CP0_SegCtl1 =   (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
26462                          (2 << CP0SC_C);
26463     /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
26464     env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
26465                          (3 << CP0SC_C)) << 16;
26466     /* USeg (seg4 0x40000000..0x7FFFFFFF) */
26467     env->CP0_SegCtl2 =   (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
26468                          (1 << CP0SC_EU) | (2 << CP0SC_C);
26469     /* USeg (seg5 0x00000000..0x3FFFFFFF) */
26470     env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
26471                          (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
26472     /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
26473     env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
26474 #endif
26475     if ((env->insn_flags & ISA_MIPS32R6) &&
26476         (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
26477         /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
26478         env->CP0_Status |= (1 << CP0St_FR);
26479     }
26480
26481     if (env->insn_flags & ISA_MIPS32R6) {
26482         /* PTW  =  1 */
26483         env->CP0_PWSize = 0x40;
26484         /* GDI  = 12 */
26485         /* UDI  = 12 */
26486         /* MDI  = 12 */
26487         /* PRI  = 12 */
26488         /* PTEI =  2 */
26489         env->CP0_PWField = 0x0C30C302;
26490     } else {
26491         /* GDI  =  0 */
26492         /* UDI  =  0 */
26493         /* MDI  =  0 */
26494         /* PRI  =  0 */
26495         /* PTEI =  2 */
26496         env->CP0_PWField = 0x02;
26497     }
26498
26499     if (env->CP0_Config3 & (1 << CP0C3_ISA) & (1 << (CP0C3_ISA + 1))) {
26500         /*  microMIPS on reset when Config3.ISA is 3 */
26501         env->hflags |= MIPS_HFLAG_M16;
26502     }
26503
26504     /* MSA */
26505     if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
26506         msa_reset(env);
26507     }
26508
26509     compute_hflags(env);
26510     restore_fp_status(env);
26511     restore_pamask(env);
26512     cs->exception_index = EXCP_NONE;
26513
26514     if (semihosting_get_argc()) {
26515         /* UHI interface can be used to obtain argc and argv */
26516         env->active_tc.gpr[4] = -1;
26517     }
26518 }
26519
26520 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
26521                           target_ulong *data)
26522 {
26523     env->active_tc.PC = data[0];
26524     env->hflags &= ~MIPS_HFLAG_BMASK;
26525     env->hflags |= data[1];
26526     switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
26527     case MIPS_HFLAG_BR:
26528         break;
26529     case MIPS_HFLAG_BC:
26530     case MIPS_HFLAG_BL:
26531     case MIPS_HFLAG_B:
26532         env->btarget = data[2];
26533         break;
26534     }
26535 }
This page took 1.462827 seconds and 4 git commands to generate.