OSDN Git Service

target/mips: Add CP0 Config2 to DisasContext
[qmiga/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 /*
2482  * This code generates a "reserved instruction" exception if the
2483  * Config3 MT bit is NOT set.
2484  */
2485 static inline void check_mt(DisasContext *ctx)
2486 {
2487     if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
2488         generate_exception_end(ctx, EXCP_RI);
2489     }
2490 }
2491
2492 #ifndef CONFIG_USER_ONLY
2493 /*
2494  * This code generates a "coprocessor unusable" exception if CP0 is not
2495  * available, and, if that is not the case, generates a "reserved instruction"
2496  * exception if the Config5 MT bit is NOT set. This is needed for availability
2497  * control of some of MT ASE instructions.
2498  */
2499 static inline void check_cp0_mt(DisasContext *ctx)
2500 {
2501     if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
2502         generate_exception_err(ctx, EXCP_CpU, 0);
2503     } else {
2504         if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
2505             generate_exception_err(ctx, EXCP_RI, 0);
2506         }
2507     }
2508 }
2509 #endif
2510
2511 /*
2512  * This code generates a "reserved instruction" exception if the
2513  * Config5 NMS bit is set.
2514  */
2515 static inline void check_nms(DisasContext *ctx)
2516 {
2517     if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
2518         generate_exception_end(ctx, EXCP_RI);
2519     }
2520 }
2521
2522
2523 /* Define small wrappers for gen_load_fpr* so that we have a uniform
2524    calling interface for 32 and 64-bit FPRs.  No sense in changing
2525    all callers for gen_load_fpr32 when we need the CTX parameter for
2526    this one use.  */
2527 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
2528 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
2529 #define FOP_CONDS(type, abs, fmt, ifmt, bits)                                 \
2530 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
2531                                                int ft, int fs, int cc)        \
2532 {                                                                             \
2533     TCGv_i##bits fp0 = tcg_temp_new_i##bits ();                               \
2534     TCGv_i##bits fp1 = tcg_temp_new_i##bits ();                               \
2535     switch (ifmt) {                                                           \
2536     case FMT_PS:                                                              \
2537         check_ps(ctx);                                                        \
2538         break;                                                                \
2539     case FMT_D:                                                               \
2540         if (abs) {                                                            \
2541             check_cop1x(ctx);                                                 \
2542         }                                                                     \
2543         check_cp1_registers(ctx, fs | ft);                                    \
2544         break;                                                                \
2545     case FMT_S:                                                               \
2546         if (abs) {                                                            \
2547             check_cop1x(ctx);                                                 \
2548         }                                                                     \
2549         break;                                                                \
2550     }                                                                         \
2551     gen_ldcmp_fpr##bits (ctx, fp0, fs);                                       \
2552     gen_ldcmp_fpr##bits (ctx, fp1, ft);                                       \
2553     switch (n) {                                                              \
2554     case  0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc);    break;\
2555     case  1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc);   break;\
2556     case  2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc);   break;\
2557     case  3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc);  break;\
2558     case  4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc);  break;\
2559     case  5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc);  break;\
2560     case  6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc);  break;\
2561     case  7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc);  break;\
2562     case  8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc);   break;\
2563     case  9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
2564     case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc);  break;\
2565     case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc);  break;\
2566     case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc);   break;\
2567     case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc);  break;\
2568     case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc);   break;\
2569     case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc);  break;\
2570     default: abort();                                                         \
2571     }                                                                         \
2572     tcg_temp_free_i##bits (fp0);                                              \
2573     tcg_temp_free_i##bits (fp1);                                              \
2574 }
2575
2576 FOP_CONDS(, 0, d, FMT_D, 64)
2577 FOP_CONDS(abs, 1, d, FMT_D, 64)
2578 FOP_CONDS(, 0, s, FMT_S, 32)
2579 FOP_CONDS(abs, 1, s, FMT_S, 32)
2580 FOP_CONDS(, 0, ps, FMT_PS, 64)
2581 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
2582 #undef FOP_CONDS
2583
2584 #define FOP_CONDNS(fmt, ifmt, bits, STORE)                              \
2585 static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n,        \
2586                                       int ft, int fs, int fd)           \
2587 {                                                                       \
2588     TCGv_i ## bits fp0 = tcg_temp_new_i ## bits();                      \
2589     TCGv_i ## bits fp1 = tcg_temp_new_i ## bits();                      \
2590     if (ifmt == FMT_D) {                                                \
2591         check_cp1_registers(ctx, fs | ft | fd);                         \
2592     }                                                                   \
2593     gen_ldcmp_fpr ## bits(ctx, fp0, fs);                                \
2594     gen_ldcmp_fpr ## bits(ctx, fp1, ft);                                \
2595     switch (n) {                                                        \
2596     case  0:                                                            \
2597         gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1);       \
2598         break;                                                          \
2599     case  1:                                                            \
2600         gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1);       \
2601         break;                                                          \
2602     case  2:                                                            \
2603         gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1);       \
2604         break;                                                          \
2605     case  3:                                                            \
2606         gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1);      \
2607         break;                                                          \
2608     case  4:                                                            \
2609         gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1);       \
2610         break;                                                          \
2611     case  5:                                                            \
2612         gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1);      \
2613         break;                                                          \
2614     case  6:                                                            \
2615         gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1);       \
2616         break;                                                          \
2617     case  7:                                                            \
2618         gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1);      \
2619         break;                                                          \
2620     case  8:                                                            \
2621         gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1);      \
2622         break;                                                          \
2623     case  9:                                                            \
2624         gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1);      \
2625         break;                                                          \
2626     case 10:                                                            \
2627         gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1);      \
2628         break;                                                          \
2629     case 11:                                                            \
2630         gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1);     \
2631         break;                                                          \
2632     case 12:                                                            \
2633         gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1);      \
2634         break;                                                          \
2635     case 13:                                                            \
2636         gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1);     \
2637         break;                                                          \
2638     case 14:                                                            \
2639         gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1);      \
2640         break;                                                          \
2641     case 15:                                                            \
2642         gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1);     \
2643         break;                                                          \
2644     case 17:                                                            \
2645         gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1);       \
2646         break;                                                          \
2647     case 18:                                                            \
2648         gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1);      \
2649         break;                                                          \
2650     case 19:                                                            \
2651         gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1);       \
2652         break;                                                          \
2653     case 25:                                                            \
2654         gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1);      \
2655         break;                                                          \
2656     case 26:                                                            \
2657         gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1);     \
2658         break;                                                          \
2659     case 27:                                                            \
2660         gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1);      \
2661         break;                                                          \
2662     default:                                                            \
2663         abort();                                                        \
2664     }                                                                   \
2665     STORE;                                                              \
2666     tcg_temp_free_i ## bits (fp0);                                      \
2667     tcg_temp_free_i ## bits (fp1);                                      \
2668 }
2669
2670 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
2671 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
2672 #undef FOP_CONDNS
2673 #undef gen_ldcmp_fpr32
2674 #undef gen_ldcmp_fpr64
2675
2676 /* load/store instructions. */
2677 #ifdef CONFIG_USER_ONLY
2678 #define OP_LD_ATOMIC(insn,fname)                                           \
2679 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
2680                                 DisasContext *ctx)                         \
2681 {                                                                          \
2682     TCGv t0 = tcg_temp_new();                                              \
2683     tcg_gen_mov_tl(t0, arg1);                                              \
2684     tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
2685     tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));                \
2686     tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval));                \
2687     tcg_temp_free(t0);                                                     \
2688 }
2689 #else
2690 #define OP_LD_ATOMIC(insn,fname)                                           \
2691 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
2692                                 DisasContext *ctx)                         \
2693 {                                                                          \
2694     gen_helper_1e1i(insn, ret, arg1, mem_idx);                             \
2695 }
2696 #endif
2697 OP_LD_ATOMIC(ll,ld32s);
2698 #if defined(TARGET_MIPS64)
2699 OP_LD_ATOMIC(lld,ld64);
2700 #endif
2701 #undef OP_LD_ATOMIC
2702
2703 #ifdef CONFIG_USER_ONLY
2704 #define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
2705 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx,   \
2706                                 DisasContext *ctx)                           \
2707 {                                                                            \
2708     TCGv t0 = tcg_temp_new();                                                \
2709     TCGLabel *l1 = gen_new_label();                                          \
2710     TCGLabel *l2 = gen_new_label();                                          \
2711                                                                              \
2712     tcg_gen_andi_tl(t0, arg2, almask);                                       \
2713     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);                              \
2714     tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));          \
2715     generate_exception(ctx, EXCP_AdES);                                      \
2716     gen_set_label(l1);                                                       \
2717     tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));                  \
2718     tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2);                            \
2719     tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20));                        \
2720     tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg));                   \
2721     tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval));              \
2722     generate_exception_end(ctx, EXCP_SC);                                    \
2723     gen_set_label(l2);                                                       \
2724     tcg_gen_movi_tl(t0, 0);                                                  \
2725     gen_store_gpr(t0, rt);                                                   \
2726     tcg_temp_free(t0);                                                       \
2727 }
2728 #else
2729 #define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
2730 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx,   \
2731                                 DisasContext *ctx)                           \
2732 {                                                                            \
2733     TCGv t0 = tcg_temp_new();                                                \
2734     gen_helper_1e2i(insn, t0, arg1, arg2, mem_idx);                          \
2735     gen_store_gpr(t0, rt);                                                   \
2736     tcg_temp_free(t0);                                                       \
2737 }
2738 #endif
2739 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
2740 #if defined(TARGET_MIPS64)
2741 OP_ST_ATOMIC(scd,st64,ld64,0x7);
2742 #endif
2743 #undef OP_ST_ATOMIC
2744
2745 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
2746                                   int base, int offset)
2747 {
2748     if (base == 0) {
2749         tcg_gen_movi_tl(addr, offset);
2750     } else if (offset == 0) {
2751         gen_load_gpr(addr, base);
2752     } else {
2753         tcg_gen_movi_tl(addr, offset);
2754         gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2755     }
2756 }
2757
2758 static target_ulong pc_relative_pc (DisasContext *ctx)
2759 {
2760     target_ulong pc = ctx->base.pc_next;
2761
2762     if (ctx->hflags & MIPS_HFLAG_BMASK) {
2763         int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2764
2765         pc -= branch_bytes;
2766     }
2767
2768     pc &= ~(target_ulong)3;
2769     return pc;
2770 }
2771
2772 /* Load */
2773 static void gen_ld(DisasContext *ctx, uint32_t opc,
2774                    int rt, int base, int offset)
2775 {
2776     TCGv t0, t1, t2;
2777     int mem_idx = ctx->mem_idx;
2778
2779     if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
2780         /* Loongson CPU uses a load to zero register for prefetch.
2781            We emulate it as a NOP. On other CPU we must perform the
2782            actual memory access. */
2783         return;
2784     }
2785
2786     t0 = tcg_temp_new();
2787     gen_base_offset_addr(ctx, t0, base, offset);
2788
2789     switch (opc) {
2790 #if defined(TARGET_MIPS64)
2791     case OPC_LWU:
2792         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
2793                            ctx->default_tcg_memop_mask);
2794         gen_store_gpr(t0, rt);
2795         break;
2796     case OPC_LD:
2797         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
2798                            ctx->default_tcg_memop_mask);
2799         gen_store_gpr(t0, rt);
2800         break;
2801     case OPC_LLD:
2802     case R6_OPC_LLD:
2803         op_ld_lld(t0, t0, mem_idx, ctx);
2804         gen_store_gpr(t0, rt);
2805         break;
2806     case OPC_LDL:
2807         t1 = tcg_temp_new();
2808         /* Do a byte access to possibly trigger a page
2809            fault with the unaligned address.  */
2810         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2811         tcg_gen_andi_tl(t1, t0, 7);
2812 #ifndef TARGET_WORDS_BIGENDIAN
2813         tcg_gen_xori_tl(t1, t1, 7);
2814 #endif
2815         tcg_gen_shli_tl(t1, t1, 3);
2816         tcg_gen_andi_tl(t0, t0, ~7);
2817         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
2818         tcg_gen_shl_tl(t0, t0, t1);
2819         t2 = tcg_const_tl(-1);
2820         tcg_gen_shl_tl(t2, t2, t1);
2821         gen_load_gpr(t1, rt);
2822         tcg_gen_andc_tl(t1, t1, t2);
2823         tcg_temp_free(t2);
2824         tcg_gen_or_tl(t0, t0, t1);
2825         tcg_temp_free(t1);
2826         gen_store_gpr(t0, rt);
2827         break;
2828     case OPC_LDR:
2829         t1 = tcg_temp_new();
2830         /* Do a byte access to possibly trigger a page
2831            fault with the unaligned address.  */
2832         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2833         tcg_gen_andi_tl(t1, t0, 7);
2834 #ifdef TARGET_WORDS_BIGENDIAN
2835         tcg_gen_xori_tl(t1, t1, 7);
2836 #endif
2837         tcg_gen_shli_tl(t1, t1, 3);
2838         tcg_gen_andi_tl(t0, t0, ~7);
2839         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
2840         tcg_gen_shr_tl(t0, t0, t1);
2841         tcg_gen_xori_tl(t1, t1, 63);
2842         t2 = tcg_const_tl(0xfffffffffffffffeull);
2843         tcg_gen_shl_tl(t2, t2, t1);
2844         gen_load_gpr(t1, rt);
2845         tcg_gen_and_tl(t1, t1, t2);
2846         tcg_temp_free(t2);
2847         tcg_gen_or_tl(t0, t0, t1);
2848         tcg_temp_free(t1);
2849         gen_store_gpr(t0, rt);
2850         break;
2851     case OPC_LDPC:
2852         t1 = tcg_const_tl(pc_relative_pc(ctx));
2853         gen_op_addr_add(ctx, t0, t0, t1);
2854         tcg_temp_free(t1);
2855         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
2856         gen_store_gpr(t0, rt);
2857         break;
2858 #endif
2859     case OPC_LWPC:
2860         t1 = tcg_const_tl(pc_relative_pc(ctx));
2861         gen_op_addr_add(ctx, t0, t0, t1);
2862         tcg_temp_free(t1);
2863         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
2864         gen_store_gpr(t0, rt);
2865         break;
2866     case OPC_LWE:
2867         mem_idx = MIPS_HFLAG_UM;
2868         /* fall through */
2869     case OPC_LW:
2870         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
2871                            ctx->default_tcg_memop_mask);
2872         gen_store_gpr(t0, rt);
2873         break;
2874     case OPC_LHE:
2875         mem_idx = MIPS_HFLAG_UM;
2876         /* fall through */
2877     case OPC_LH:
2878         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
2879                            ctx->default_tcg_memop_mask);
2880         gen_store_gpr(t0, rt);
2881         break;
2882     case OPC_LHUE:
2883         mem_idx = MIPS_HFLAG_UM;
2884         /* fall through */
2885     case OPC_LHU:
2886         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
2887                            ctx->default_tcg_memop_mask);
2888         gen_store_gpr(t0, rt);
2889         break;
2890     case OPC_LBE:
2891         mem_idx = MIPS_HFLAG_UM;
2892         /* fall through */
2893     case OPC_LB:
2894         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
2895         gen_store_gpr(t0, rt);
2896         break;
2897     case OPC_LBUE:
2898         mem_idx = MIPS_HFLAG_UM;
2899         /* fall through */
2900     case OPC_LBU:
2901         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
2902         gen_store_gpr(t0, rt);
2903         break;
2904     case OPC_LWLE:
2905         mem_idx = MIPS_HFLAG_UM;
2906         /* fall through */
2907     case OPC_LWL:
2908         t1 = tcg_temp_new();
2909         /* Do a byte access to possibly trigger a page
2910            fault with the unaligned address.  */
2911         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2912         tcg_gen_andi_tl(t1, t0, 3);
2913 #ifndef TARGET_WORDS_BIGENDIAN
2914         tcg_gen_xori_tl(t1, t1, 3);
2915 #endif
2916         tcg_gen_shli_tl(t1, t1, 3);
2917         tcg_gen_andi_tl(t0, t0, ~3);
2918         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
2919         tcg_gen_shl_tl(t0, t0, t1);
2920         t2 = tcg_const_tl(-1);
2921         tcg_gen_shl_tl(t2, t2, t1);
2922         gen_load_gpr(t1, rt);
2923         tcg_gen_andc_tl(t1, t1, t2);
2924         tcg_temp_free(t2);
2925         tcg_gen_or_tl(t0, t0, t1);
2926         tcg_temp_free(t1);
2927         tcg_gen_ext32s_tl(t0, t0);
2928         gen_store_gpr(t0, rt);
2929         break;
2930     case OPC_LWRE:
2931         mem_idx = MIPS_HFLAG_UM;
2932         /* fall through */
2933     case OPC_LWR:
2934         t1 = tcg_temp_new();
2935         /* Do a byte access to possibly trigger a page
2936            fault with the unaligned address.  */
2937         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2938         tcg_gen_andi_tl(t1, t0, 3);
2939 #ifdef TARGET_WORDS_BIGENDIAN
2940         tcg_gen_xori_tl(t1, t1, 3);
2941 #endif
2942         tcg_gen_shli_tl(t1, t1, 3);
2943         tcg_gen_andi_tl(t0, t0, ~3);
2944         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
2945         tcg_gen_shr_tl(t0, t0, t1);
2946         tcg_gen_xori_tl(t1, t1, 31);
2947         t2 = tcg_const_tl(0xfffffffeull);
2948         tcg_gen_shl_tl(t2, t2, t1);
2949         gen_load_gpr(t1, rt);
2950         tcg_gen_and_tl(t1, t1, t2);
2951         tcg_temp_free(t2);
2952         tcg_gen_or_tl(t0, t0, t1);
2953         tcg_temp_free(t1);
2954         tcg_gen_ext32s_tl(t0, t0);
2955         gen_store_gpr(t0, rt);
2956         break;
2957     case OPC_LLE:
2958         mem_idx = MIPS_HFLAG_UM;
2959         /* fall through */
2960     case OPC_LL:
2961     case R6_OPC_LL:
2962         op_ld_ll(t0, t0, mem_idx, ctx);
2963         gen_store_gpr(t0, rt);
2964         break;
2965     }
2966     tcg_temp_free(t0);
2967 }
2968
2969 static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
2970                     uint32_t reg1, uint32_t reg2)
2971 {
2972     TCGv taddr = tcg_temp_new();
2973     TCGv_i64 tval = tcg_temp_new_i64();
2974     TCGv tmp1 = tcg_temp_new();
2975     TCGv tmp2 = tcg_temp_new();
2976
2977     gen_base_offset_addr(ctx, taddr, base, offset);
2978     tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx);
2979 #ifdef TARGET_WORDS_BIGENDIAN
2980     tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
2981 #else
2982     tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
2983 #endif
2984     gen_store_gpr(tmp1, reg1);
2985     tcg_temp_free(tmp1);
2986     gen_store_gpr(tmp2, reg2);
2987     tcg_temp_free(tmp2);
2988     tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp));
2989     tcg_temp_free_i64(tval);
2990     tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr));
2991     tcg_temp_free(taddr);
2992 }
2993
2994 /* Store */
2995 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
2996                     int base, int offset)
2997 {
2998     TCGv t0 = tcg_temp_new();
2999     TCGv t1 = tcg_temp_new();
3000     int mem_idx = ctx->mem_idx;
3001
3002     gen_base_offset_addr(ctx, t0, base, offset);
3003     gen_load_gpr(t1, rt);
3004     switch (opc) {
3005 #if defined(TARGET_MIPS64)
3006     case OPC_SD:
3007         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
3008                            ctx->default_tcg_memop_mask);
3009         break;
3010     case OPC_SDL:
3011         gen_helper_0e2i(sdl, t1, t0, mem_idx);
3012         break;
3013     case OPC_SDR:
3014         gen_helper_0e2i(sdr, t1, t0, mem_idx);
3015         break;
3016 #endif
3017     case OPC_SWE:
3018         mem_idx = MIPS_HFLAG_UM;
3019         /* fall through */
3020     case OPC_SW:
3021         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
3022                            ctx->default_tcg_memop_mask);
3023         break;
3024     case OPC_SHE:
3025         mem_idx = MIPS_HFLAG_UM;
3026         /* fall through */
3027     case OPC_SH:
3028         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
3029                            ctx->default_tcg_memop_mask);
3030         break;
3031     case OPC_SBE:
3032         mem_idx = MIPS_HFLAG_UM;
3033         /* fall through */
3034     case OPC_SB:
3035         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
3036         break;
3037     case OPC_SWLE:
3038         mem_idx = MIPS_HFLAG_UM;
3039         /* fall through */
3040     case OPC_SWL:
3041         gen_helper_0e2i(swl, t1, t0, mem_idx);
3042         break;
3043     case OPC_SWRE:
3044         mem_idx = MIPS_HFLAG_UM;
3045         /* fall through */
3046     case OPC_SWR:
3047         gen_helper_0e2i(swr, t1, t0, mem_idx);
3048         break;
3049     }
3050     tcg_temp_free(t0);
3051     tcg_temp_free(t1);
3052 }
3053
3054
3055 /* Store conditional */
3056 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
3057                          int base, int16_t offset)
3058 {
3059     TCGv t0, t1;
3060     int mem_idx = ctx->mem_idx;
3061
3062 #ifdef CONFIG_USER_ONLY
3063     t0 = tcg_temp_local_new();
3064     t1 = tcg_temp_local_new();
3065 #else
3066     t0 = tcg_temp_new();
3067     t1 = tcg_temp_new();
3068 #endif
3069     gen_base_offset_addr(ctx, t0, base, offset);
3070     gen_load_gpr(t1, rt);
3071     switch (opc) {
3072 #if defined(TARGET_MIPS64)
3073     case OPC_SCD:
3074     case R6_OPC_SCD:
3075         op_st_scd(t1, t0, rt, mem_idx, ctx);
3076         break;
3077 #endif
3078     case OPC_SCE:
3079         mem_idx = MIPS_HFLAG_UM;
3080         /* fall through */
3081     case OPC_SC:
3082     case R6_OPC_SC:
3083         op_st_sc(t1, t0, rt, mem_idx, ctx);
3084         break;
3085     }
3086     tcg_temp_free(t1);
3087     tcg_temp_free(t0);
3088 }
3089
3090 static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
3091                     uint32_t reg1, uint32_t reg2)
3092 {
3093     TCGv taddr = tcg_temp_local_new();
3094     TCGv lladdr = tcg_temp_local_new();
3095     TCGv_i64 tval = tcg_temp_new_i64();
3096     TCGv_i64 llval = tcg_temp_new_i64();
3097     TCGv_i64 val = tcg_temp_new_i64();
3098     TCGv tmp1 = tcg_temp_new();
3099     TCGv tmp2 = tcg_temp_new();
3100     TCGLabel *lab_fail = gen_new_label();
3101     TCGLabel *lab_done = gen_new_label();
3102
3103     gen_base_offset_addr(ctx, taddr, base, offset);
3104
3105     tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3106     tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail);
3107
3108     gen_load_gpr(tmp1, reg1);
3109     gen_load_gpr(tmp2, reg2);
3110
3111 #ifdef TARGET_WORDS_BIGENDIAN
3112     tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
3113 #else
3114     tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
3115 #endif
3116
3117     tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3118     tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
3119                                ctx->mem_idx, MO_64);
3120     if (reg1 != 0) {
3121         tcg_gen_movi_tl(cpu_gpr[reg1], 1);
3122     }
3123     tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done);
3124
3125     gen_set_label(lab_fail);
3126
3127     if (reg1 != 0) {
3128         tcg_gen_movi_tl(cpu_gpr[reg1], 0);
3129     }
3130     gen_set_label(lab_done);
3131     tcg_gen_movi_tl(lladdr, -1);
3132     tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3133 }
3134
3135 /* Load and store */
3136 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
3137                           TCGv t0)
3138 {
3139     /* Don't do NOP if destination is zero: we must perform the actual
3140        memory access. */
3141     switch (opc) {
3142     case OPC_LWC1:
3143         {
3144             TCGv_i32 fp0 = tcg_temp_new_i32();
3145             tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
3146                                 ctx->default_tcg_memop_mask);
3147             gen_store_fpr32(ctx, fp0, ft);
3148             tcg_temp_free_i32(fp0);
3149         }
3150         break;
3151     case OPC_SWC1:
3152         {
3153             TCGv_i32 fp0 = tcg_temp_new_i32();
3154             gen_load_fpr32(ctx, fp0, ft);
3155             tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
3156                                 ctx->default_tcg_memop_mask);
3157             tcg_temp_free_i32(fp0);
3158         }
3159         break;
3160     case OPC_LDC1:
3161         {
3162             TCGv_i64 fp0 = tcg_temp_new_i64();
3163             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3164                                 ctx->default_tcg_memop_mask);
3165             gen_store_fpr64(ctx, fp0, ft);
3166             tcg_temp_free_i64(fp0);
3167         }
3168         break;
3169     case OPC_SDC1:
3170         {
3171             TCGv_i64 fp0 = tcg_temp_new_i64();
3172             gen_load_fpr64(ctx, fp0, ft);
3173             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3174                                 ctx->default_tcg_memop_mask);
3175             tcg_temp_free_i64(fp0);
3176         }
3177         break;
3178     default:
3179         MIPS_INVAL("flt_ldst");
3180         generate_exception_end(ctx, EXCP_RI);
3181         break;
3182     }
3183 }
3184
3185 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
3186                           int rs, int16_t imm)
3187 {
3188     TCGv t0 = tcg_temp_new();
3189
3190     if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3191         check_cp1_enabled(ctx);
3192         switch (op) {
3193         case OPC_LDC1:
3194         case OPC_SDC1:
3195             check_insn(ctx, ISA_MIPS2);
3196             /* Fallthrough */
3197         default:
3198             gen_base_offset_addr(ctx, t0, rs, imm);
3199             gen_flt_ldst(ctx, op, rt, t0);
3200         }
3201     } else {
3202         generate_exception_err(ctx, EXCP_CpU, 1);
3203     }
3204     tcg_temp_free(t0);
3205 }
3206
3207 /* Arithmetic with immediate operand */
3208 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
3209                           int rt, int rs, int imm)
3210 {
3211     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3212
3213     if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
3214         /* If no destination, treat it as a NOP.
3215            For addi, we must generate the overflow exception when needed. */
3216         return;
3217     }
3218     switch (opc) {
3219     case OPC_ADDI:
3220         {
3221             TCGv t0 = tcg_temp_local_new();
3222             TCGv t1 = tcg_temp_new();
3223             TCGv t2 = tcg_temp_new();
3224             TCGLabel *l1 = gen_new_label();
3225
3226             gen_load_gpr(t1, rs);
3227             tcg_gen_addi_tl(t0, t1, uimm);
3228             tcg_gen_ext32s_tl(t0, t0);
3229
3230             tcg_gen_xori_tl(t1, t1, ~uimm);
3231             tcg_gen_xori_tl(t2, t0, uimm);
3232             tcg_gen_and_tl(t1, t1, t2);
3233             tcg_temp_free(t2);
3234             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3235             tcg_temp_free(t1);
3236             /* operands of same sign, result different sign */
3237             generate_exception(ctx, EXCP_OVERFLOW);
3238             gen_set_label(l1);
3239             tcg_gen_ext32s_tl(t0, t0);
3240             gen_store_gpr(t0, rt);
3241             tcg_temp_free(t0);
3242         }
3243         break;
3244     case OPC_ADDIU:
3245         if (rs != 0) {
3246             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3247             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3248         } else {
3249             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3250         }
3251         break;
3252 #if defined(TARGET_MIPS64)
3253     case OPC_DADDI:
3254         {
3255             TCGv t0 = tcg_temp_local_new();
3256             TCGv t1 = tcg_temp_new();
3257             TCGv t2 = tcg_temp_new();
3258             TCGLabel *l1 = gen_new_label();
3259
3260             gen_load_gpr(t1, rs);
3261             tcg_gen_addi_tl(t0, t1, uimm);
3262
3263             tcg_gen_xori_tl(t1, t1, ~uimm);
3264             tcg_gen_xori_tl(t2, t0, uimm);
3265             tcg_gen_and_tl(t1, t1, t2);
3266             tcg_temp_free(t2);
3267             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3268             tcg_temp_free(t1);
3269             /* operands of same sign, result different sign */
3270             generate_exception(ctx, EXCP_OVERFLOW);
3271             gen_set_label(l1);
3272             gen_store_gpr(t0, rt);
3273             tcg_temp_free(t0);
3274         }
3275         break;
3276     case OPC_DADDIU:
3277         if (rs != 0) {
3278             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3279         } else {
3280             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3281         }
3282         break;
3283 #endif
3284     }
3285 }
3286
3287 /* Logic with immediate operand */
3288 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
3289                           int rt, int rs, int16_t imm)
3290 {
3291     target_ulong uimm;
3292
3293     if (rt == 0) {
3294         /* If no destination, treat it as a NOP. */
3295         return;
3296     }
3297     uimm = (uint16_t)imm;
3298     switch (opc) {
3299     case OPC_ANDI:
3300         if (likely(rs != 0))
3301             tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3302         else
3303             tcg_gen_movi_tl(cpu_gpr[rt], 0);
3304         break;
3305     case OPC_ORI:
3306         if (rs != 0)
3307             tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3308         else
3309             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3310         break;
3311     case OPC_XORI:
3312         if (likely(rs != 0))
3313             tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3314         else
3315             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3316         break;
3317     case OPC_LUI:
3318         if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
3319             /* OPC_AUI */
3320             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
3321             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3322         } else {
3323             tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
3324         }
3325         break;
3326
3327     default:
3328         break;
3329     }
3330 }
3331
3332 /* Set on less than with immediate operand */
3333 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
3334                         int rt, int rs, int16_t imm)
3335 {
3336     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3337     TCGv t0;
3338
3339     if (rt == 0) {
3340         /* If no destination, treat it as a NOP. */
3341         return;
3342     }
3343     t0 = tcg_temp_new();
3344     gen_load_gpr(t0, rs);
3345     switch (opc) {
3346     case OPC_SLTI:
3347         tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
3348         break;
3349     case OPC_SLTIU:
3350         tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
3351         break;
3352     }
3353     tcg_temp_free(t0);
3354 }
3355
3356 /* Shifts with immediate operand */
3357 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
3358                           int rt, int rs, int16_t imm)
3359 {
3360     target_ulong uimm = ((uint16_t)imm) & 0x1f;
3361     TCGv t0;
3362
3363     if (rt == 0) {
3364         /* If no destination, treat it as a NOP. */
3365         return;
3366     }
3367
3368     t0 = tcg_temp_new();
3369     gen_load_gpr(t0, rs);
3370     switch (opc) {
3371     case OPC_SLL:
3372         tcg_gen_shli_tl(t0, t0, uimm);
3373         tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3374         break;
3375     case OPC_SRA:
3376         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
3377         break;
3378     case OPC_SRL:
3379         if (uimm != 0) {
3380             tcg_gen_ext32u_tl(t0, t0);
3381             tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3382         } else {
3383             tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3384         }
3385         break;
3386     case OPC_ROTR:
3387         if (uimm != 0) {
3388             TCGv_i32 t1 = tcg_temp_new_i32();
3389
3390             tcg_gen_trunc_tl_i32(t1, t0);
3391             tcg_gen_rotri_i32(t1, t1, uimm);
3392             tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
3393             tcg_temp_free_i32(t1);
3394         } else {
3395             tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3396         }
3397         break;
3398 #if defined(TARGET_MIPS64)
3399     case OPC_DSLL:
3400         tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
3401         break;
3402     case OPC_DSRA:
3403         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
3404         break;
3405     case OPC_DSRL:
3406         tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3407         break;
3408     case OPC_DROTR:
3409         if (uimm != 0) {
3410             tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3411         } else {
3412             tcg_gen_mov_tl(cpu_gpr[rt], t0);
3413         }
3414         break;
3415     case OPC_DSLL32:
3416         tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
3417         break;
3418     case OPC_DSRA32:
3419         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
3420         break;
3421     case OPC_DSRL32:
3422         tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
3423         break;
3424     case OPC_DROTR32:
3425         tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
3426         break;
3427 #endif
3428     }
3429     tcg_temp_free(t0);
3430 }
3431
3432 /* Arithmetic */
3433 static void gen_arith(DisasContext *ctx, uint32_t opc,
3434                       int rd, int rs, int rt)
3435 {
3436     if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
3437        && opc != OPC_DADD && opc != OPC_DSUB) {
3438         /* If no destination, treat it as a NOP.
3439            For add & sub, we must generate the overflow exception when needed. */
3440         return;
3441     }
3442
3443     switch (opc) {
3444     case OPC_ADD:
3445         {
3446             TCGv t0 = tcg_temp_local_new();
3447             TCGv t1 = tcg_temp_new();
3448             TCGv t2 = tcg_temp_new();
3449             TCGLabel *l1 = gen_new_label();
3450
3451             gen_load_gpr(t1, rs);
3452             gen_load_gpr(t2, rt);
3453             tcg_gen_add_tl(t0, t1, t2);
3454             tcg_gen_ext32s_tl(t0, t0);
3455             tcg_gen_xor_tl(t1, t1, t2);
3456             tcg_gen_xor_tl(t2, t0, t2);
3457             tcg_gen_andc_tl(t1, t2, t1);
3458             tcg_temp_free(t2);
3459             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3460             tcg_temp_free(t1);
3461             /* operands of same sign, result different sign */
3462             generate_exception(ctx, EXCP_OVERFLOW);
3463             gen_set_label(l1);
3464             gen_store_gpr(t0, rd);
3465             tcg_temp_free(t0);
3466         }
3467         break;
3468     case OPC_ADDU:
3469         if (rs != 0 && rt != 0) {
3470             tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3471             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3472         } else if (rs == 0 && rt != 0) {
3473             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3474         } else if (rs != 0 && rt == 0) {
3475             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3476         } else {
3477             tcg_gen_movi_tl(cpu_gpr[rd], 0);
3478         }
3479         break;
3480     case OPC_SUB:
3481         {
3482             TCGv t0 = tcg_temp_local_new();
3483             TCGv t1 = tcg_temp_new();
3484             TCGv t2 = tcg_temp_new();
3485             TCGLabel *l1 = gen_new_label();
3486
3487             gen_load_gpr(t1, rs);
3488             gen_load_gpr(t2, rt);
3489             tcg_gen_sub_tl(t0, t1, t2);
3490             tcg_gen_ext32s_tl(t0, t0);
3491             tcg_gen_xor_tl(t2, t1, t2);
3492             tcg_gen_xor_tl(t1, t0, t1);
3493             tcg_gen_and_tl(t1, t1, t2);
3494             tcg_temp_free(t2);
3495             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3496             tcg_temp_free(t1);
3497             /* operands of different sign, first operand and result different sign */
3498             generate_exception(ctx, EXCP_OVERFLOW);
3499             gen_set_label(l1);
3500             gen_store_gpr(t0, rd);
3501             tcg_temp_free(t0);
3502         }
3503         break;
3504     case OPC_SUBU:
3505         if (rs != 0 && rt != 0) {
3506             tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3507             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3508         } else if (rs == 0 && rt != 0) {
3509             tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
3510             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3511         } else if (rs != 0 && rt == 0) {
3512             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3513         } else {
3514             tcg_gen_movi_tl(cpu_gpr[rd], 0);
3515         }
3516         break;
3517 #if defined(TARGET_MIPS64)
3518     case OPC_DADD:
3519         {
3520             TCGv t0 = tcg_temp_local_new();
3521             TCGv t1 = tcg_temp_new();
3522             TCGv t2 = tcg_temp_new();
3523             TCGLabel *l1 = gen_new_label();
3524
3525             gen_load_gpr(t1, rs);
3526             gen_load_gpr(t2, rt);
3527             tcg_gen_add_tl(t0, t1, t2);
3528             tcg_gen_xor_tl(t1, t1, t2);
3529             tcg_gen_xor_tl(t2, t0, t2);
3530             tcg_gen_andc_tl(t1, t2, t1);
3531             tcg_temp_free(t2);
3532             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3533             tcg_temp_free(t1);
3534             /* operands of same sign, result different sign */
3535             generate_exception(ctx, EXCP_OVERFLOW);
3536             gen_set_label(l1);
3537             gen_store_gpr(t0, rd);
3538             tcg_temp_free(t0);
3539         }
3540         break;
3541     case OPC_DADDU:
3542         if (rs != 0 && rt != 0) {
3543             tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3544         } else if (rs == 0 && rt != 0) {
3545             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3546         } else if (rs != 0 && rt == 0) {
3547             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3548         } else {
3549             tcg_gen_movi_tl(cpu_gpr[rd], 0);
3550         }
3551         break;
3552     case OPC_DSUB:
3553         {
3554             TCGv t0 = tcg_temp_local_new();
3555             TCGv t1 = tcg_temp_new();
3556             TCGv t2 = tcg_temp_new();
3557             TCGLabel *l1 = gen_new_label();
3558
3559             gen_load_gpr(t1, rs);
3560             gen_load_gpr(t2, rt);
3561             tcg_gen_sub_tl(t0, t1, t2);
3562             tcg_gen_xor_tl(t2, t1, t2);
3563             tcg_gen_xor_tl(t1, t0, t1);
3564             tcg_gen_and_tl(t1, t1, t2);
3565             tcg_temp_free(t2);
3566             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3567             tcg_temp_free(t1);
3568             /* operands of different sign, first operand and result different sign */
3569             generate_exception(ctx, EXCP_OVERFLOW);
3570             gen_set_label(l1);
3571             gen_store_gpr(t0, rd);
3572             tcg_temp_free(t0);
3573         }
3574         break;
3575     case OPC_DSUBU:
3576         if (rs != 0 && rt != 0) {
3577             tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3578         } else if (rs == 0 && rt != 0) {
3579             tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
3580         } else if (rs != 0 && rt == 0) {
3581             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3582         } else {
3583             tcg_gen_movi_tl(cpu_gpr[rd], 0);
3584         }
3585         break;
3586 #endif
3587     case OPC_MUL:
3588         if (likely(rs != 0 && rt != 0)) {
3589             tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3590             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3591         } else {
3592             tcg_gen_movi_tl(cpu_gpr[rd], 0);
3593         }
3594         break;
3595     }
3596 }
3597
3598 /* Conditional move */
3599 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
3600                           int rd, int rs, int rt)
3601 {
3602     TCGv t0, t1, t2;
3603
3604     if (rd == 0) {
3605         /* If no destination, treat it as a NOP. */
3606         return;
3607     }
3608
3609     t0 = tcg_temp_new();
3610     gen_load_gpr(t0, rt);
3611     t1 = tcg_const_tl(0);
3612     t2 = tcg_temp_new();
3613     gen_load_gpr(t2, rs);
3614     switch (opc) {
3615     case OPC_MOVN:
3616         tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
3617         break;
3618     case OPC_MOVZ:
3619         tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
3620         break;
3621     case OPC_SELNEZ:
3622         tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
3623         break;
3624     case OPC_SELEQZ:
3625         tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
3626         break;
3627     }
3628     tcg_temp_free(t2);
3629     tcg_temp_free(t1);
3630     tcg_temp_free(t0);
3631 }
3632
3633 /* Logic */
3634 static void gen_logic(DisasContext *ctx, uint32_t opc,
3635                       int rd, int rs, int rt)
3636 {
3637     if (rd == 0) {
3638         /* If no destination, treat it as a NOP. */
3639         return;
3640     }
3641
3642     switch (opc) {
3643     case OPC_AND:
3644         if (likely(rs != 0 && rt != 0)) {
3645             tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3646         } else {
3647             tcg_gen_movi_tl(cpu_gpr[rd], 0);
3648         }
3649         break;
3650     case OPC_NOR:
3651         if (rs != 0 && rt != 0) {
3652             tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3653         } else if (rs == 0 && rt != 0) {
3654             tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
3655         } else if (rs != 0 && rt == 0) {
3656             tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
3657         } else {
3658             tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
3659         }
3660         break;
3661     case OPC_OR:
3662         if (likely(rs != 0 && rt != 0)) {
3663             tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3664         } else if (rs == 0 && rt != 0) {
3665             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3666         } else if (rs != 0 && rt == 0) {
3667             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3668         } else {
3669             tcg_gen_movi_tl(cpu_gpr[rd], 0);
3670         }
3671         break;
3672     case OPC_XOR:
3673         if (likely(rs != 0 && rt != 0)) {
3674             tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3675         } else if (rs == 0 && rt != 0) {
3676             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3677         } else if (rs != 0 && rt == 0) {
3678             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3679         } else {
3680             tcg_gen_movi_tl(cpu_gpr[rd], 0);
3681         }
3682         break;
3683     }
3684 }
3685
3686 /* Set on lower than */
3687 static void gen_slt(DisasContext *ctx, uint32_t opc,
3688                     int rd, int rs, int rt)
3689 {
3690     TCGv t0, t1;
3691
3692     if (rd == 0) {
3693         /* If no destination, treat it as a NOP. */
3694         return;
3695     }
3696
3697     t0 = tcg_temp_new();
3698     t1 = tcg_temp_new();
3699     gen_load_gpr(t0, rs);
3700     gen_load_gpr(t1, rt);
3701     switch (opc) {
3702     case OPC_SLT:
3703         tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
3704         break;
3705     case OPC_SLTU:
3706         tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
3707         break;
3708     }
3709     tcg_temp_free(t0);
3710     tcg_temp_free(t1);
3711 }
3712
3713 /* Shifts */
3714 static void gen_shift(DisasContext *ctx, uint32_t opc,
3715                       int rd, int rs, int rt)
3716 {
3717     TCGv t0, t1;
3718
3719     if (rd == 0) {
3720         /* If no destination, treat it as a NOP.
3721            For add & sub, we must generate the overflow exception when needed. */
3722         return;
3723     }
3724
3725     t0 = tcg_temp_new();
3726     t1 = tcg_temp_new();
3727     gen_load_gpr(t0, rs);
3728     gen_load_gpr(t1, rt);
3729     switch (opc) {
3730     case OPC_SLLV:
3731         tcg_gen_andi_tl(t0, t0, 0x1f);
3732         tcg_gen_shl_tl(t0, t1, t0);
3733         tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3734         break;
3735     case OPC_SRAV:
3736         tcg_gen_andi_tl(t0, t0, 0x1f);
3737         tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
3738         break;
3739     case OPC_SRLV:
3740         tcg_gen_ext32u_tl(t1, t1);
3741         tcg_gen_andi_tl(t0, t0, 0x1f);
3742         tcg_gen_shr_tl(t0, t1, t0);
3743         tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3744         break;
3745     case OPC_ROTRV:
3746         {
3747             TCGv_i32 t2 = tcg_temp_new_i32();
3748             TCGv_i32 t3 = tcg_temp_new_i32();
3749
3750             tcg_gen_trunc_tl_i32(t2, t0);
3751             tcg_gen_trunc_tl_i32(t3, t1);
3752             tcg_gen_andi_i32(t2, t2, 0x1f);
3753             tcg_gen_rotr_i32(t2, t3, t2);
3754             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3755             tcg_temp_free_i32(t2);
3756             tcg_temp_free_i32(t3);
3757         }
3758         break;
3759 #if defined(TARGET_MIPS64)
3760     case OPC_DSLLV:
3761         tcg_gen_andi_tl(t0, t0, 0x3f);
3762         tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
3763         break;
3764     case OPC_DSRAV:
3765         tcg_gen_andi_tl(t0, t0, 0x3f);
3766         tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
3767         break;
3768     case OPC_DSRLV:
3769         tcg_gen_andi_tl(t0, t0, 0x3f);
3770         tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
3771         break;
3772     case OPC_DROTRV:
3773         tcg_gen_andi_tl(t0, t0, 0x3f);
3774         tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
3775         break;
3776 #endif
3777     }
3778     tcg_temp_free(t0);
3779     tcg_temp_free(t1);
3780 }
3781
3782 /* Arithmetic on HI/LO registers */
3783 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
3784 {
3785     if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
3786         /* Treat as NOP. */
3787         return;
3788     }
3789
3790     if (acc != 0) {
3791         check_dsp(ctx);
3792     }
3793
3794     switch (opc) {
3795     case OPC_MFHI:
3796 #if defined(TARGET_MIPS64)
3797         if (acc != 0) {
3798             tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
3799         } else
3800 #endif
3801         {
3802             tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3803         }
3804         break;
3805     case OPC_MFLO:
3806 #if defined(TARGET_MIPS64)
3807         if (acc != 0) {
3808             tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3809         } else
3810 #endif
3811         {
3812             tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3813         }
3814         break;
3815     case OPC_MTHI:
3816         if (reg != 0) {
3817 #if defined(TARGET_MIPS64)
3818             if (acc != 0) {
3819                 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3820             } else
3821 #endif
3822             {
3823                 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3824             }
3825         } else {
3826             tcg_gen_movi_tl(cpu_HI[acc], 0);
3827         }
3828         break;
3829     case OPC_MTLO:
3830         if (reg != 0) {
3831 #if defined(TARGET_MIPS64)
3832             if (acc != 0) {
3833                 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3834             } else
3835 #endif
3836             {
3837                 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3838             }
3839         } else {
3840             tcg_gen_movi_tl(cpu_LO[acc], 0);
3841         }
3842         break;
3843     }
3844 }
3845
3846 static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3847                              TCGMemOp memop)
3848 {
3849     TCGv t0 = tcg_const_tl(addr);
3850     tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3851     gen_store_gpr(t0, reg);
3852     tcg_temp_free(t0);
3853 }
3854
3855 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
3856                              int rs)
3857 {
3858     target_long offset;
3859     target_long addr;
3860
3861     switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
3862     case OPC_ADDIUPC:
3863         if (rs != 0) {
3864             offset = sextract32(ctx->opcode << 2, 0, 21);
3865             addr = addr_add(ctx, pc, offset);
3866             tcg_gen_movi_tl(cpu_gpr[rs], addr);
3867         }
3868         break;
3869     case R6_OPC_LWPC:
3870         offset = sextract32(ctx->opcode << 2, 0, 21);
3871         addr = addr_add(ctx, pc, offset);
3872         gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3873         break;
3874 #if defined(TARGET_MIPS64)
3875     case OPC_LWUPC:
3876         check_mips_64(ctx);
3877         offset = sextract32(ctx->opcode << 2, 0, 21);
3878         addr = addr_add(ctx, pc, offset);
3879         gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3880         break;
3881 #endif
3882     default:
3883         switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
3884         case OPC_AUIPC:
3885             if (rs != 0) {
3886                 offset = sextract32(ctx->opcode, 0, 16) << 16;
3887                 addr = addr_add(ctx, pc, offset);
3888                 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3889             }
3890             break;
3891         case OPC_ALUIPC:
3892             if (rs != 0) {
3893                 offset = sextract32(ctx->opcode, 0, 16) << 16;
3894                 addr = ~0xFFFF & addr_add(ctx, pc, offset);
3895                 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3896             }
3897             break;
3898 #if defined(TARGET_MIPS64)
3899         case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3900         case R6_OPC_LDPC + (1 << 16):
3901         case R6_OPC_LDPC + (2 << 16):
3902         case R6_OPC_LDPC + (3 << 16):
3903             check_mips_64(ctx);
3904             offset = sextract32(ctx->opcode << 3, 0, 21);
3905             addr = addr_add(ctx, (pc & ~0x7), offset);
3906             gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3907             break;
3908 #endif
3909         default:
3910             MIPS_INVAL("OPC_PCREL");
3911             generate_exception_end(ctx, EXCP_RI);
3912             break;
3913         }
3914         break;
3915     }
3916 }
3917
3918 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3919 {
3920     TCGv t0, t1;
3921
3922     if (rd == 0) {
3923         /* Treat as NOP. */
3924         return;
3925     }
3926
3927     t0 = tcg_temp_new();
3928     t1 = tcg_temp_new();
3929
3930     gen_load_gpr(t0, rs);
3931     gen_load_gpr(t1, rt);
3932
3933     switch (opc) {
3934     case R6_OPC_DIV:
3935         {
3936             TCGv t2 = tcg_temp_new();
3937             TCGv t3 = tcg_temp_new();
3938             tcg_gen_ext32s_tl(t0, t0);
3939             tcg_gen_ext32s_tl(t1, t1);
3940             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3941             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3942             tcg_gen_and_tl(t2, t2, t3);
3943             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3944             tcg_gen_or_tl(t2, t2, t3);
3945             tcg_gen_movi_tl(t3, 0);
3946             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3947             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3948             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3949             tcg_temp_free(t3);
3950             tcg_temp_free(t2);
3951         }
3952         break;
3953     case R6_OPC_MOD:
3954         {
3955             TCGv t2 = tcg_temp_new();
3956             TCGv t3 = tcg_temp_new();
3957             tcg_gen_ext32s_tl(t0, t0);
3958             tcg_gen_ext32s_tl(t1, t1);
3959             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3960             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3961             tcg_gen_and_tl(t2, t2, t3);
3962             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3963             tcg_gen_or_tl(t2, t2, t3);
3964             tcg_gen_movi_tl(t3, 0);
3965             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3966             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3967             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3968             tcg_temp_free(t3);
3969             tcg_temp_free(t2);
3970         }
3971         break;
3972     case R6_OPC_DIVU:
3973         {
3974             TCGv t2 = tcg_const_tl(0);
3975             TCGv t3 = tcg_const_tl(1);
3976             tcg_gen_ext32u_tl(t0, t0);
3977             tcg_gen_ext32u_tl(t1, t1);
3978             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3979             tcg_gen_divu_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_MODU:
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_remu_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_MUL:
3999         {
4000             TCGv_i32 t2 = tcg_temp_new_i32();
4001             TCGv_i32 t3 = tcg_temp_new_i32();
4002             tcg_gen_trunc_tl_i32(t2, t0);
4003             tcg_gen_trunc_tl_i32(t3, t1);
4004             tcg_gen_mul_i32(t2, t2, t3);
4005             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4006             tcg_temp_free_i32(t2);
4007             tcg_temp_free_i32(t3);
4008         }
4009         break;
4010     case R6_OPC_MUH:
4011         {
4012             TCGv_i32 t2 = tcg_temp_new_i32();
4013             TCGv_i32 t3 = tcg_temp_new_i32();
4014             tcg_gen_trunc_tl_i32(t2, t0);
4015             tcg_gen_trunc_tl_i32(t3, t1);
4016             tcg_gen_muls2_i32(t2, t3, t2, t3);
4017             tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4018             tcg_temp_free_i32(t2);
4019             tcg_temp_free_i32(t3);
4020         }
4021         break;
4022     case R6_OPC_MULU:
4023         {
4024             TCGv_i32 t2 = tcg_temp_new_i32();
4025             TCGv_i32 t3 = tcg_temp_new_i32();
4026             tcg_gen_trunc_tl_i32(t2, t0);
4027             tcg_gen_trunc_tl_i32(t3, t1);
4028             tcg_gen_mul_i32(t2, t2, t3);
4029             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4030             tcg_temp_free_i32(t2);
4031             tcg_temp_free_i32(t3);
4032         }
4033         break;
4034     case R6_OPC_MUHU:
4035         {
4036             TCGv_i32 t2 = tcg_temp_new_i32();
4037             TCGv_i32 t3 = tcg_temp_new_i32();
4038             tcg_gen_trunc_tl_i32(t2, t0);
4039             tcg_gen_trunc_tl_i32(t3, t1);
4040             tcg_gen_mulu2_i32(t2, t3, t2, t3);
4041             tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4042             tcg_temp_free_i32(t2);
4043             tcg_temp_free_i32(t3);
4044         }
4045         break;
4046 #if defined(TARGET_MIPS64)
4047     case R6_OPC_DDIV:
4048         {
4049             TCGv t2 = tcg_temp_new();
4050             TCGv t3 = tcg_temp_new();
4051             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4052             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4053             tcg_gen_and_tl(t2, t2, t3);
4054             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4055             tcg_gen_or_tl(t2, t2, t3);
4056             tcg_gen_movi_tl(t3, 0);
4057             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4058             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4059             tcg_temp_free(t3);
4060             tcg_temp_free(t2);
4061         }
4062         break;
4063     case R6_OPC_DMOD:
4064         {
4065             TCGv t2 = tcg_temp_new();
4066             TCGv t3 = tcg_temp_new();
4067             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4068             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4069             tcg_gen_and_tl(t2, t2, t3);
4070             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4071             tcg_gen_or_tl(t2, t2, t3);
4072             tcg_gen_movi_tl(t3, 0);
4073             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4074             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4075             tcg_temp_free(t3);
4076             tcg_temp_free(t2);
4077         }
4078         break;
4079     case R6_OPC_DDIVU:
4080         {
4081             TCGv t2 = tcg_const_tl(0);
4082             TCGv t3 = tcg_const_tl(1);
4083             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4084             tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
4085             tcg_temp_free(t3);
4086             tcg_temp_free(t2);
4087         }
4088         break;
4089     case R6_OPC_DMODU:
4090         {
4091             TCGv t2 = tcg_const_tl(0);
4092             TCGv t3 = tcg_const_tl(1);
4093             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4094             tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
4095             tcg_temp_free(t3);
4096             tcg_temp_free(t2);
4097         }
4098         break;
4099     case R6_OPC_DMUL:
4100         tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4101         break;
4102     case R6_OPC_DMUH:
4103         {
4104             TCGv t2 = tcg_temp_new();
4105             tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
4106             tcg_temp_free(t2);
4107         }
4108         break;
4109     case R6_OPC_DMULU:
4110         tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4111         break;
4112     case R6_OPC_DMUHU:
4113         {
4114             TCGv t2 = tcg_temp_new();
4115             tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
4116             tcg_temp_free(t2);
4117         }
4118         break;
4119 #endif
4120     default:
4121         MIPS_INVAL("r6 mul/div");
4122         generate_exception_end(ctx, EXCP_RI);
4123         goto out;
4124     }
4125  out:
4126     tcg_temp_free(t0);
4127     tcg_temp_free(t1);
4128 }
4129
4130 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
4131                        int acc, int rs, int rt)
4132 {
4133     TCGv t0, t1;
4134
4135     t0 = tcg_temp_new();
4136     t1 = tcg_temp_new();
4137
4138     gen_load_gpr(t0, rs);
4139     gen_load_gpr(t1, rt);
4140
4141     if (acc != 0) {
4142         check_dsp(ctx);
4143     }
4144
4145     switch (opc) {
4146     case OPC_DIV:
4147         {
4148             TCGv t2 = tcg_temp_new();
4149             TCGv t3 = tcg_temp_new();
4150             tcg_gen_ext32s_tl(t0, t0);
4151             tcg_gen_ext32s_tl(t1, t1);
4152             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4153             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4154             tcg_gen_and_tl(t2, t2, t3);
4155             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4156             tcg_gen_or_tl(t2, t2, t3);
4157             tcg_gen_movi_tl(t3, 0);
4158             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4159             tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4160             tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4161             tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4162             tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4163             tcg_temp_free(t3);
4164             tcg_temp_free(t2);
4165         }
4166         break;
4167     case OPC_DIVU:
4168         {
4169             TCGv t2 = tcg_const_tl(0);
4170             TCGv t3 = tcg_const_tl(1);
4171             tcg_gen_ext32u_tl(t0, t0);
4172             tcg_gen_ext32u_tl(t1, t1);
4173             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4174             tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
4175             tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
4176             tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4177             tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4178             tcg_temp_free(t3);
4179             tcg_temp_free(t2);
4180         }
4181         break;
4182     case OPC_MULT:
4183         {
4184             TCGv_i32 t2 = tcg_temp_new_i32();
4185             TCGv_i32 t3 = tcg_temp_new_i32();
4186             tcg_gen_trunc_tl_i32(t2, t0);
4187             tcg_gen_trunc_tl_i32(t3, t1);
4188             tcg_gen_muls2_i32(t2, t3, t2, t3);
4189             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4190             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4191             tcg_temp_free_i32(t2);
4192             tcg_temp_free_i32(t3);
4193         }
4194         break;
4195     case OPC_MULTU:
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_mulu2_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 #if defined(TARGET_MIPS64)
4209     case OPC_DDIV:
4210         {
4211             TCGv t2 = tcg_temp_new();
4212             TCGv t3 = tcg_temp_new();
4213             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4214             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4215             tcg_gen_and_tl(t2, t2, t3);
4216             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4217             tcg_gen_or_tl(t2, t2, t3);
4218             tcg_gen_movi_tl(t3, 0);
4219             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4220             tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4221             tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4222             tcg_temp_free(t3);
4223             tcg_temp_free(t2);
4224         }
4225         break;
4226     case OPC_DDIVU:
4227         {
4228             TCGv t2 = tcg_const_tl(0);
4229             TCGv t3 = tcg_const_tl(1);
4230             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4231             tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
4232             tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
4233             tcg_temp_free(t3);
4234             tcg_temp_free(t2);
4235         }
4236         break;
4237     case OPC_DMULT:
4238         tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
4239         break;
4240     case OPC_DMULTU:
4241         tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
4242         break;
4243 #endif
4244     case OPC_MADD:
4245         {
4246             TCGv_i64 t2 = tcg_temp_new_i64();
4247             TCGv_i64 t3 = tcg_temp_new_i64();
4248
4249             tcg_gen_ext_tl_i64(t2, t0);
4250             tcg_gen_ext_tl_i64(t3, t1);
4251             tcg_gen_mul_i64(t2, t2, t3);
4252             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4253             tcg_gen_add_i64(t2, t2, t3);
4254             tcg_temp_free_i64(t3);
4255             gen_move_low32(cpu_LO[acc], t2);
4256             gen_move_high32(cpu_HI[acc], t2);
4257             tcg_temp_free_i64(t2);
4258         }
4259         break;
4260     case OPC_MADDU:
4261         {
4262             TCGv_i64 t2 = tcg_temp_new_i64();
4263             TCGv_i64 t3 = tcg_temp_new_i64();
4264
4265             tcg_gen_ext32u_tl(t0, t0);
4266             tcg_gen_ext32u_tl(t1, t1);
4267             tcg_gen_extu_tl_i64(t2, t0);
4268             tcg_gen_extu_tl_i64(t3, t1);
4269             tcg_gen_mul_i64(t2, t2, t3);
4270             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4271             tcg_gen_add_i64(t2, t2, t3);
4272             tcg_temp_free_i64(t3);
4273             gen_move_low32(cpu_LO[acc], t2);
4274             gen_move_high32(cpu_HI[acc], t2);
4275             tcg_temp_free_i64(t2);
4276         }
4277         break;
4278     case OPC_MSUB:
4279         {
4280             TCGv_i64 t2 = tcg_temp_new_i64();
4281             TCGv_i64 t3 = tcg_temp_new_i64();
4282
4283             tcg_gen_ext_tl_i64(t2, t0);
4284             tcg_gen_ext_tl_i64(t3, t1);
4285             tcg_gen_mul_i64(t2, t2, t3);
4286             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4287             tcg_gen_sub_i64(t2, t3, t2);
4288             tcg_temp_free_i64(t3);
4289             gen_move_low32(cpu_LO[acc], t2);
4290             gen_move_high32(cpu_HI[acc], t2);
4291             tcg_temp_free_i64(t2);
4292         }
4293         break;
4294     case OPC_MSUBU:
4295         {
4296             TCGv_i64 t2 = tcg_temp_new_i64();
4297             TCGv_i64 t3 = tcg_temp_new_i64();
4298
4299             tcg_gen_ext32u_tl(t0, t0);
4300             tcg_gen_ext32u_tl(t1, t1);
4301             tcg_gen_extu_tl_i64(t2, t0);
4302             tcg_gen_extu_tl_i64(t3, t1);
4303             tcg_gen_mul_i64(t2, t2, t3);
4304             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4305             tcg_gen_sub_i64(t2, t3, t2);
4306             tcg_temp_free_i64(t3);
4307             gen_move_low32(cpu_LO[acc], t2);
4308             gen_move_high32(cpu_HI[acc], t2);
4309             tcg_temp_free_i64(t2);
4310         }
4311         break;
4312     default:
4313         MIPS_INVAL("mul/div");
4314         generate_exception_end(ctx, EXCP_RI);
4315         goto out;
4316     }
4317  out:
4318     tcg_temp_free(t0);
4319     tcg_temp_free(t1);
4320 }
4321
4322 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
4323                             int rd, int rs, int rt)
4324 {
4325     TCGv t0 = tcg_temp_new();
4326     TCGv t1 = tcg_temp_new();
4327
4328     gen_load_gpr(t0, rs);
4329     gen_load_gpr(t1, rt);
4330
4331     switch (opc) {
4332     case OPC_VR54XX_MULS:
4333         gen_helper_muls(t0, cpu_env, t0, t1);
4334         break;
4335     case OPC_VR54XX_MULSU:
4336         gen_helper_mulsu(t0, cpu_env, t0, t1);
4337         break;
4338     case OPC_VR54XX_MACC:
4339         gen_helper_macc(t0, cpu_env, t0, t1);
4340         break;
4341     case OPC_VR54XX_MACCU:
4342         gen_helper_maccu(t0, cpu_env, t0, t1);
4343         break;
4344     case OPC_VR54XX_MSAC:
4345         gen_helper_msac(t0, cpu_env, t0, t1);
4346         break;
4347     case OPC_VR54XX_MSACU:
4348         gen_helper_msacu(t0, cpu_env, t0, t1);
4349         break;
4350     case OPC_VR54XX_MULHI:
4351         gen_helper_mulhi(t0, cpu_env, t0, t1);
4352         break;
4353     case OPC_VR54XX_MULHIU:
4354         gen_helper_mulhiu(t0, cpu_env, t0, t1);
4355         break;
4356     case OPC_VR54XX_MULSHI:
4357         gen_helper_mulshi(t0, cpu_env, t0, t1);
4358         break;
4359     case OPC_VR54XX_MULSHIU:
4360         gen_helper_mulshiu(t0, cpu_env, t0, t1);
4361         break;
4362     case OPC_VR54XX_MACCHI:
4363         gen_helper_macchi(t0, cpu_env, t0, t1);
4364         break;
4365     case OPC_VR54XX_MACCHIU:
4366         gen_helper_macchiu(t0, cpu_env, t0, t1);
4367         break;
4368     case OPC_VR54XX_MSACHI:
4369         gen_helper_msachi(t0, cpu_env, t0, t1);
4370         break;
4371     case OPC_VR54XX_MSACHIU:
4372         gen_helper_msachiu(t0, cpu_env, t0, t1);
4373         break;
4374     default:
4375         MIPS_INVAL("mul vr54xx");
4376         generate_exception_end(ctx, EXCP_RI);
4377         goto out;
4378     }
4379     gen_store_gpr(t0, rd);
4380
4381  out:
4382     tcg_temp_free(t0);
4383     tcg_temp_free(t1);
4384 }
4385
4386 static void gen_cl (DisasContext *ctx, uint32_t opc,
4387                     int rd, int rs)
4388 {
4389     TCGv t0;
4390
4391     if (rd == 0) {
4392         /* Treat as NOP. */
4393         return;
4394     }
4395     t0 = cpu_gpr[rd];
4396     gen_load_gpr(t0, rs);
4397
4398     switch (opc) {
4399     case OPC_CLO:
4400     case R6_OPC_CLO:
4401 #if defined(TARGET_MIPS64)
4402     case OPC_DCLO:
4403     case R6_OPC_DCLO:
4404 #endif
4405         tcg_gen_not_tl(t0, t0);
4406         break;
4407     }
4408
4409     switch (opc) {
4410     case OPC_CLO:
4411     case R6_OPC_CLO:
4412     case OPC_CLZ:
4413     case R6_OPC_CLZ:
4414         tcg_gen_ext32u_tl(t0, t0);
4415         tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
4416         tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
4417         break;
4418 #if defined(TARGET_MIPS64)
4419     case OPC_DCLO:
4420     case R6_OPC_DCLO:
4421     case OPC_DCLZ:
4422     case R6_OPC_DCLZ:
4423         tcg_gen_clzi_i64(t0, t0, 64);
4424         break;
4425 #endif
4426     }
4427 }
4428
4429 /* Godson integer instructions */
4430 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
4431                                  int rd, int rs, int rt)
4432 {
4433     TCGv t0, t1;
4434
4435     if (rd == 0) {
4436         /* Treat as NOP. */
4437         return;
4438     }
4439
4440     switch (opc) {
4441     case OPC_MULT_G_2E:
4442     case OPC_MULT_G_2F:
4443     case OPC_MULTU_G_2E:
4444     case OPC_MULTU_G_2F:
4445 #if defined(TARGET_MIPS64)
4446     case OPC_DMULT_G_2E:
4447     case OPC_DMULT_G_2F:
4448     case OPC_DMULTU_G_2E:
4449     case OPC_DMULTU_G_2F:
4450 #endif
4451         t0 = tcg_temp_new();
4452         t1 = tcg_temp_new();
4453         break;
4454     default:
4455         t0 = tcg_temp_local_new();
4456         t1 = tcg_temp_local_new();
4457         break;
4458     }
4459
4460     gen_load_gpr(t0, rs);
4461     gen_load_gpr(t1, rt);
4462
4463     switch (opc) {
4464     case OPC_MULT_G_2E:
4465     case OPC_MULT_G_2F:
4466         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
4467         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4468         break;
4469     case OPC_MULTU_G_2E:
4470     case OPC_MULTU_G_2F:
4471         tcg_gen_ext32u_tl(t0, t0);
4472         tcg_gen_ext32u_tl(t1, t1);
4473         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
4474         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4475         break;
4476     case OPC_DIV_G_2E:
4477     case OPC_DIV_G_2F:
4478         {
4479             TCGLabel *l1 = gen_new_label();
4480             TCGLabel *l2 = gen_new_label();
4481             TCGLabel *l3 = gen_new_label();
4482             tcg_gen_ext32s_tl(t0, t0);
4483             tcg_gen_ext32s_tl(t1, t1);
4484             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4485             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4486             tcg_gen_br(l3);
4487             gen_set_label(l1);
4488             tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
4489             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
4490             tcg_gen_mov_tl(cpu_gpr[rd], t0);
4491             tcg_gen_br(l3);
4492             gen_set_label(l2);
4493             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4494             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4495             gen_set_label(l3);
4496         }
4497         break;
4498     case OPC_DIVU_G_2E:
4499     case OPC_DIVU_G_2F:
4500         {
4501             TCGLabel *l1 = gen_new_label();
4502             TCGLabel *l2 = gen_new_label();
4503             tcg_gen_ext32u_tl(t0, t0);
4504             tcg_gen_ext32u_tl(t1, t1);
4505             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4506             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4507             tcg_gen_br(l2);
4508             gen_set_label(l1);
4509             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4510             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4511             gen_set_label(l2);
4512         }
4513         break;
4514     case OPC_MOD_G_2E:
4515     case OPC_MOD_G_2F:
4516         {
4517             TCGLabel *l1 = gen_new_label();
4518             TCGLabel *l2 = gen_new_label();
4519             TCGLabel *l3 = gen_new_label();
4520             tcg_gen_ext32u_tl(t0, t0);
4521             tcg_gen_ext32u_tl(t1, t1);
4522             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
4523             tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
4524             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
4525             gen_set_label(l1);
4526             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4527             tcg_gen_br(l3);
4528             gen_set_label(l2);
4529             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4530             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4531             gen_set_label(l3);
4532         }
4533         break;
4534     case OPC_MODU_G_2E:
4535     case OPC_MODU_G_2F:
4536         {
4537             TCGLabel *l1 = gen_new_label();
4538             TCGLabel *l2 = gen_new_label();
4539             tcg_gen_ext32u_tl(t0, t0);
4540             tcg_gen_ext32u_tl(t1, t1);
4541             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4542             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4543             tcg_gen_br(l2);
4544             gen_set_label(l1);
4545             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4546             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4547             gen_set_label(l2);
4548         }
4549         break;
4550 #if defined(TARGET_MIPS64)
4551     case OPC_DMULT_G_2E:
4552     case OPC_DMULT_G_2F:
4553         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
4554         break;
4555     case OPC_DMULTU_G_2E:
4556     case OPC_DMULTU_G_2F:
4557         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
4558         break;
4559     case OPC_DDIV_G_2E:
4560     case OPC_DDIV_G_2F:
4561         {
4562             TCGLabel *l1 = gen_new_label();
4563             TCGLabel *l2 = gen_new_label();
4564             TCGLabel *l3 = gen_new_label();
4565             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4566             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4567             tcg_gen_br(l3);
4568             gen_set_label(l1);
4569             tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
4570             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
4571             tcg_gen_mov_tl(cpu_gpr[rd], t0);
4572             tcg_gen_br(l3);
4573             gen_set_label(l2);
4574             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4575             gen_set_label(l3);
4576         }
4577         break;
4578     case OPC_DDIVU_G_2E:
4579     case OPC_DDIVU_G_2F:
4580         {
4581             TCGLabel *l1 = gen_new_label();
4582             TCGLabel *l2 = gen_new_label();
4583             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4584             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4585             tcg_gen_br(l2);
4586             gen_set_label(l1);
4587             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4588             gen_set_label(l2);
4589         }
4590         break;
4591     case OPC_DMOD_G_2E:
4592     case OPC_DMOD_G_2F:
4593         {
4594             TCGLabel *l1 = gen_new_label();
4595             TCGLabel *l2 = gen_new_label();
4596             TCGLabel *l3 = gen_new_label();
4597             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
4598             tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
4599             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
4600             gen_set_label(l1);
4601             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4602             tcg_gen_br(l3);
4603             gen_set_label(l2);
4604             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4605             gen_set_label(l3);
4606         }
4607         break;
4608     case OPC_DMODU_G_2E:
4609     case OPC_DMODU_G_2F:
4610         {
4611             TCGLabel *l1 = gen_new_label();
4612             TCGLabel *l2 = gen_new_label();
4613             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4614             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4615             tcg_gen_br(l2);
4616             gen_set_label(l1);
4617             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4618             gen_set_label(l2);
4619         }
4620         break;
4621 #endif
4622     }
4623
4624     tcg_temp_free(t0);
4625     tcg_temp_free(t1);
4626 }
4627
4628 /* Loongson multimedia instructions */
4629 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
4630 {
4631     uint32_t opc, shift_max;
4632     TCGv_i64 t0, t1;
4633
4634     opc = MASK_LMI(ctx->opcode);
4635     switch (opc) {
4636     case OPC_ADD_CP2:
4637     case OPC_SUB_CP2:
4638     case OPC_DADD_CP2:
4639     case OPC_DSUB_CP2:
4640         t0 = tcg_temp_local_new_i64();
4641         t1 = tcg_temp_local_new_i64();
4642         break;
4643     default:
4644         t0 = tcg_temp_new_i64();
4645         t1 = tcg_temp_new_i64();
4646         break;
4647     }
4648
4649     check_cp1_enabled(ctx);
4650     gen_load_fpr64(ctx, t0, rs);
4651     gen_load_fpr64(ctx, t1, rt);
4652
4653 #define LMI_HELPER(UP, LO) \
4654     case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
4655 #define LMI_HELPER_1(UP, LO) \
4656     case OPC_##UP: gen_helper_##LO(t0, t0); break
4657 #define LMI_DIRECT(UP, LO, OP) \
4658     case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
4659
4660     switch (opc) {
4661     LMI_HELPER(PADDSH, paddsh);
4662     LMI_HELPER(PADDUSH, paddush);
4663     LMI_HELPER(PADDH, paddh);
4664     LMI_HELPER(PADDW, paddw);
4665     LMI_HELPER(PADDSB, paddsb);
4666     LMI_HELPER(PADDUSB, paddusb);
4667     LMI_HELPER(PADDB, paddb);
4668
4669     LMI_HELPER(PSUBSH, psubsh);
4670     LMI_HELPER(PSUBUSH, psubush);
4671     LMI_HELPER(PSUBH, psubh);
4672     LMI_HELPER(PSUBW, psubw);
4673     LMI_HELPER(PSUBSB, psubsb);
4674     LMI_HELPER(PSUBUSB, psubusb);
4675     LMI_HELPER(PSUBB, psubb);
4676
4677     LMI_HELPER(PSHUFH, pshufh);
4678     LMI_HELPER(PACKSSWH, packsswh);
4679     LMI_HELPER(PACKSSHB, packsshb);
4680     LMI_HELPER(PACKUSHB, packushb);
4681
4682     LMI_HELPER(PUNPCKLHW, punpcklhw);
4683     LMI_HELPER(PUNPCKHHW, punpckhhw);
4684     LMI_HELPER(PUNPCKLBH, punpcklbh);
4685     LMI_HELPER(PUNPCKHBH, punpckhbh);
4686     LMI_HELPER(PUNPCKLWD, punpcklwd);
4687     LMI_HELPER(PUNPCKHWD, punpckhwd);
4688
4689     LMI_HELPER(PAVGH, pavgh);
4690     LMI_HELPER(PAVGB, pavgb);
4691     LMI_HELPER(PMAXSH, pmaxsh);
4692     LMI_HELPER(PMINSH, pminsh);
4693     LMI_HELPER(PMAXUB, pmaxub);
4694     LMI_HELPER(PMINUB, pminub);
4695
4696     LMI_HELPER(PCMPEQW, pcmpeqw);
4697     LMI_HELPER(PCMPGTW, pcmpgtw);
4698     LMI_HELPER(PCMPEQH, pcmpeqh);
4699     LMI_HELPER(PCMPGTH, pcmpgth);
4700     LMI_HELPER(PCMPEQB, pcmpeqb);
4701     LMI_HELPER(PCMPGTB, pcmpgtb);
4702
4703     LMI_HELPER(PSLLW, psllw);
4704     LMI_HELPER(PSLLH, psllh);
4705     LMI_HELPER(PSRLW, psrlw);
4706     LMI_HELPER(PSRLH, psrlh);
4707     LMI_HELPER(PSRAW, psraw);
4708     LMI_HELPER(PSRAH, psrah);
4709
4710     LMI_HELPER(PMULLH, pmullh);
4711     LMI_HELPER(PMULHH, pmulhh);
4712     LMI_HELPER(PMULHUH, pmulhuh);
4713     LMI_HELPER(PMADDHW, pmaddhw);
4714
4715     LMI_HELPER(PASUBUB, pasubub);
4716     LMI_HELPER_1(BIADD, biadd);
4717     LMI_HELPER_1(PMOVMSKB, pmovmskb);
4718
4719     LMI_DIRECT(PADDD, paddd, add);
4720     LMI_DIRECT(PSUBD, psubd, sub);
4721     LMI_DIRECT(XOR_CP2, xor, xor);
4722     LMI_DIRECT(NOR_CP2, nor, nor);
4723     LMI_DIRECT(AND_CP2, and, and);
4724     LMI_DIRECT(OR_CP2, or, or);
4725
4726     case OPC_PANDN:
4727         tcg_gen_andc_i64(t0, t1, t0);
4728         break;
4729
4730     case OPC_PINSRH_0:
4731         tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
4732         break;
4733     case OPC_PINSRH_1:
4734         tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
4735         break;
4736     case OPC_PINSRH_2:
4737         tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
4738         break;
4739     case OPC_PINSRH_3:
4740         tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
4741         break;
4742
4743     case OPC_PEXTRH:
4744         tcg_gen_andi_i64(t1, t1, 3);
4745         tcg_gen_shli_i64(t1, t1, 4);
4746         tcg_gen_shr_i64(t0, t0, t1);
4747         tcg_gen_ext16u_i64(t0, t0);
4748         break;
4749
4750     case OPC_ADDU_CP2:
4751         tcg_gen_add_i64(t0, t0, t1);
4752         tcg_gen_ext32s_i64(t0, t0);
4753         break;
4754     case OPC_SUBU_CP2:
4755         tcg_gen_sub_i64(t0, t0, t1);
4756         tcg_gen_ext32s_i64(t0, t0);
4757         break;
4758
4759     case OPC_SLL_CP2:
4760         shift_max = 32;
4761         goto do_shift;
4762     case OPC_SRL_CP2:
4763         shift_max = 32;
4764         goto do_shift;
4765     case OPC_SRA_CP2:
4766         shift_max = 32;
4767         goto do_shift;
4768     case OPC_DSLL_CP2:
4769         shift_max = 64;
4770         goto do_shift;
4771     case OPC_DSRL_CP2:
4772         shift_max = 64;
4773         goto do_shift;
4774     case OPC_DSRA_CP2:
4775         shift_max = 64;
4776         goto do_shift;
4777     do_shift:
4778         /* Make sure shift count isn't TCG undefined behaviour.  */
4779         tcg_gen_andi_i64(t1, t1, shift_max - 1);
4780
4781         switch (opc) {
4782         case OPC_SLL_CP2:
4783         case OPC_DSLL_CP2:
4784             tcg_gen_shl_i64(t0, t0, t1);
4785             break;
4786         case OPC_SRA_CP2:
4787         case OPC_DSRA_CP2:
4788             /* Since SRA is UndefinedResult without sign-extended inputs,
4789                we can treat SRA and DSRA the same.  */
4790             tcg_gen_sar_i64(t0, t0, t1);
4791             break;
4792         case OPC_SRL_CP2:
4793             /* We want to shift in zeros for SRL; zero-extend first.  */
4794             tcg_gen_ext32u_i64(t0, t0);
4795             /* FALLTHRU */
4796         case OPC_DSRL_CP2:
4797             tcg_gen_shr_i64(t0, t0, t1);
4798             break;
4799         }
4800
4801         if (shift_max == 32) {
4802             tcg_gen_ext32s_i64(t0, t0);
4803         }
4804
4805         /* Shifts larger than MAX produce zero.  */
4806         tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4807         tcg_gen_neg_i64(t1, t1);
4808         tcg_gen_and_i64(t0, t0, t1);
4809         break;
4810
4811     case OPC_ADD_CP2:
4812     case OPC_DADD_CP2:
4813         {
4814             TCGv_i64 t2 = tcg_temp_new_i64();
4815             TCGLabel *lab = gen_new_label();
4816
4817             tcg_gen_mov_i64(t2, t0);
4818             tcg_gen_add_i64(t0, t1, t2);
4819             if (opc == OPC_ADD_CP2) {
4820                 tcg_gen_ext32s_i64(t0, t0);
4821             }
4822             tcg_gen_xor_i64(t1, t1, t2);
4823             tcg_gen_xor_i64(t2, t2, t0);
4824             tcg_gen_andc_i64(t1, t2, t1);
4825             tcg_temp_free_i64(t2);
4826             tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4827             generate_exception(ctx, EXCP_OVERFLOW);
4828             gen_set_label(lab);
4829             break;
4830         }
4831
4832     case OPC_SUB_CP2:
4833     case OPC_DSUB_CP2:
4834         {
4835             TCGv_i64 t2 = tcg_temp_new_i64();
4836             TCGLabel *lab = gen_new_label();
4837
4838             tcg_gen_mov_i64(t2, t0);
4839             tcg_gen_sub_i64(t0, t1, t2);
4840             if (opc == OPC_SUB_CP2) {
4841                 tcg_gen_ext32s_i64(t0, t0);
4842             }
4843             tcg_gen_xor_i64(t1, t1, t2);
4844             tcg_gen_xor_i64(t2, t2, t0);
4845             tcg_gen_and_i64(t1, t1, t2);
4846             tcg_temp_free_i64(t2);
4847             tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4848             generate_exception(ctx, EXCP_OVERFLOW);
4849             gen_set_label(lab);
4850             break;
4851         }
4852
4853     case OPC_PMULUW:
4854         tcg_gen_ext32u_i64(t0, t0);
4855         tcg_gen_ext32u_i64(t1, t1);
4856         tcg_gen_mul_i64(t0, t0, t1);
4857         break;
4858
4859     case OPC_SEQU_CP2:
4860     case OPC_SEQ_CP2:
4861     case OPC_SLTU_CP2:
4862     case OPC_SLT_CP2:
4863     case OPC_SLEU_CP2:
4864     case OPC_SLE_CP2:
4865         /* ??? Document is unclear: Set FCC[CC].  Does that mean the
4866            FD field is the CC field?  */
4867     default:
4868         MIPS_INVAL("loongson_cp2");
4869         generate_exception_end(ctx, EXCP_RI);
4870         return;
4871     }
4872
4873 #undef LMI_HELPER
4874 #undef LMI_DIRECT
4875
4876     gen_store_fpr64(ctx, t0, rd);
4877
4878     tcg_temp_free_i64(t0);
4879     tcg_temp_free_i64(t1);
4880 }
4881
4882 /* Traps */
4883 static void gen_trap (DisasContext *ctx, uint32_t opc,
4884                       int rs, int rt, int16_t imm)
4885 {
4886     int cond;
4887     TCGv t0 = tcg_temp_new();
4888     TCGv t1 = tcg_temp_new();
4889
4890     cond = 0;
4891     /* Load needed operands */
4892     switch (opc) {
4893     case OPC_TEQ:
4894     case OPC_TGE:
4895     case OPC_TGEU:
4896     case OPC_TLT:
4897     case OPC_TLTU:
4898     case OPC_TNE:
4899         /* Compare two registers */
4900         if (rs != rt) {
4901             gen_load_gpr(t0, rs);
4902             gen_load_gpr(t1, rt);
4903             cond = 1;
4904         }
4905         break;
4906     case OPC_TEQI:
4907     case OPC_TGEI:
4908     case OPC_TGEIU:
4909     case OPC_TLTI:
4910     case OPC_TLTIU:
4911     case OPC_TNEI:
4912         /* Compare register to immediate */
4913         if (rs != 0 || imm != 0) {
4914             gen_load_gpr(t0, rs);
4915             tcg_gen_movi_tl(t1, (int32_t)imm);
4916             cond = 1;
4917         }
4918         break;
4919     }
4920     if (cond == 0) {
4921         switch (opc) {
4922         case OPC_TEQ:   /* rs == rs */
4923         case OPC_TEQI:  /* r0 == 0  */
4924         case OPC_TGE:   /* rs >= rs */
4925         case OPC_TGEI:  /* r0 >= 0  */
4926         case OPC_TGEU:  /* rs >= rs unsigned */
4927         case OPC_TGEIU: /* r0 >= 0  unsigned */
4928             /* Always trap */
4929             generate_exception_end(ctx, EXCP_TRAP);
4930             break;
4931         case OPC_TLT:   /* rs < rs           */
4932         case OPC_TLTI:  /* r0 < 0            */
4933         case OPC_TLTU:  /* rs < rs unsigned  */
4934         case OPC_TLTIU: /* r0 < 0  unsigned  */
4935         case OPC_TNE:   /* rs != rs          */
4936         case OPC_TNEI:  /* r0 != 0           */
4937             /* Never trap: treat as NOP. */
4938             break;
4939         }
4940     } else {
4941         TCGLabel *l1 = gen_new_label();
4942
4943         switch (opc) {
4944         case OPC_TEQ:
4945         case OPC_TEQI:
4946             tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
4947             break;
4948         case OPC_TGE:
4949         case OPC_TGEI:
4950             tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
4951             break;
4952         case OPC_TGEU:
4953         case OPC_TGEIU:
4954             tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
4955             break;
4956         case OPC_TLT:
4957         case OPC_TLTI:
4958             tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4959             break;
4960         case OPC_TLTU:
4961         case OPC_TLTIU:
4962             tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
4963             break;
4964         case OPC_TNE:
4965         case OPC_TNEI:
4966             tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
4967             break;
4968         }
4969         generate_exception(ctx, EXCP_TRAP);
4970         gen_set_label(l1);
4971     }
4972     tcg_temp_free(t0);
4973     tcg_temp_free(t1);
4974 }
4975
4976 static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
4977 {
4978     if (unlikely(ctx->base.singlestep_enabled)) {
4979         return false;
4980     }
4981
4982 #ifndef CONFIG_USER_ONLY
4983     return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
4984 #else
4985     return true;
4986 #endif
4987 }
4988
4989 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
4990 {
4991     if (use_goto_tb(ctx, dest)) {
4992         tcg_gen_goto_tb(n);
4993         gen_save_pc(dest);
4994         tcg_gen_exit_tb(ctx->base.tb, n);
4995     } else {
4996         gen_save_pc(dest);
4997         if (ctx->base.singlestep_enabled) {
4998             save_cpu_state(ctx, 0);
4999             gen_helper_raise_exception_debug(cpu_env);
5000         }
5001         tcg_gen_lookup_and_goto_ptr();
5002     }
5003 }
5004
5005 /* Branches (before delay slot) */
5006 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
5007                                 int insn_bytes,
5008                                 int rs, int rt, int32_t offset,
5009                                 int delayslot_size)
5010 {
5011     target_ulong btgt = -1;
5012     int blink = 0;
5013     int bcond_compute = 0;
5014     TCGv t0 = tcg_temp_new();
5015     TCGv t1 = tcg_temp_new();
5016
5017     if (ctx->hflags & MIPS_HFLAG_BMASK) {
5018 #ifdef MIPS_DEBUG_DISAS
5019         LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
5020                   TARGET_FMT_lx "\n", ctx->base.pc_next);
5021 #endif
5022         generate_exception_end(ctx, EXCP_RI);
5023         goto out;
5024     }
5025
5026     /* Load needed operands */
5027     switch (opc) {
5028     case OPC_BEQ:
5029     case OPC_BEQL:
5030     case OPC_BNE:
5031     case OPC_BNEL:
5032         /* Compare two registers */
5033         if (rs != rt) {
5034             gen_load_gpr(t0, rs);
5035             gen_load_gpr(t1, rt);
5036             bcond_compute = 1;
5037         }
5038         btgt = ctx->base.pc_next + insn_bytes + offset;
5039         break;
5040     case OPC_BGEZ:
5041     case OPC_BGEZAL:
5042     case OPC_BGEZALL:
5043     case OPC_BGEZL:
5044     case OPC_BGTZ:
5045     case OPC_BGTZL:
5046     case OPC_BLEZ:
5047     case OPC_BLEZL:
5048     case OPC_BLTZ:
5049     case OPC_BLTZAL:
5050     case OPC_BLTZALL:
5051     case OPC_BLTZL:
5052         /* Compare to zero */
5053         if (rs != 0) {
5054             gen_load_gpr(t0, rs);
5055             bcond_compute = 1;
5056         }
5057         btgt = ctx->base.pc_next + insn_bytes + offset;
5058         break;
5059     case OPC_BPOSGE32:
5060 #if defined(TARGET_MIPS64)
5061     case OPC_BPOSGE64:
5062         tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
5063 #else
5064         tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5065 #endif
5066         bcond_compute = 1;
5067         btgt = ctx->base.pc_next + insn_bytes + offset;
5068         break;
5069     case OPC_J:
5070     case OPC_JAL:
5071     case OPC_JALX:
5072         /* Jump to immediate */
5073         btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
5074             (uint32_t)offset;
5075         break;
5076     case OPC_JR:
5077     case OPC_JALR:
5078         /* Jump to register */
5079         if (offset != 0 && offset != 16) {
5080             /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5081                others are reserved. */
5082             MIPS_INVAL("jump hint");
5083             generate_exception_end(ctx, EXCP_RI);
5084             goto out;
5085         }
5086         gen_load_gpr(btarget, rs);
5087         break;
5088     default:
5089         MIPS_INVAL("branch/jump");
5090         generate_exception_end(ctx, EXCP_RI);
5091         goto out;
5092     }
5093     if (bcond_compute == 0) {
5094         /* No condition to be computed */
5095         switch (opc) {
5096         case OPC_BEQ:     /* rx == rx        */
5097         case OPC_BEQL:    /* rx == rx likely */
5098         case OPC_BGEZ:    /* 0 >= 0          */
5099         case OPC_BGEZL:   /* 0 >= 0 likely   */
5100         case OPC_BLEZ:    /* 0 <= 0          */
5101         case OPC_BLEZL:   /* 0 <= 0 likely   */
5102             /* Always take */
5103             ctx->hflags |= MIPS_HFLAG_B;
5104             break;
5105         case OPC_BGEZAL:  /* 0 >= 0          */
5106         case OPC_BGEZALL: /* 0 >= 0 likely   */
5107             /* Always take and link */
5108             blink = 31;
5109             ctx->hflags |= MIPS_HFLAG_B;
5110             break;
5111         case OPC_BNE:     /* rx != rx        */
5112         case OPC_BGTZ:    /* 0 > 0           */
5113         case OPC_BLTZ:    /* 0 < 0           */
5114             /* Treat as NOP. */
5115             goto out;
5116         case OPC_BLTZAL:  /* 0 < 0           */
5117             /* Handle as an unconditional branch to get correct delay
5118                slot checking.  */
5119             blink = 31;
5120             btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
5121             ctx->hflags |= MIPS_HFLAG_B;
5122             break;
5123         case OPC_BLTZALL: /* 0 < 0 likely */
5124             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
5125             /* Skip the instruction in the delay slot */
5126             ctx->base.pc_next += 4;
5127             goto out;
5128         case OPC_BNEL:    /* rx != rx likely */
5129         case OPC_BGTZL:   /* 0 > 0 likely */
5130         case OPC_BLTZL:   /* 0 < 0 likely */
5131             /* Skip the instruction in the delay slot */
5132             ctx->base.pc_next += 4;
5133             goto out;
5134         case OPC_J:
5135             ctx->hflags |= MIPS_HFLAG_B;
5136             break;
5137         case OPC_JALX:
5138             ctx->hflags |= MIPS_HFLAG_BX;
5139             /* Fallthrough */
5140         case OPC_JAL:
5141             blink = 31;
5142             ctx->hflags |= MIPS_HFLAG_B;
5143             break;
5144         case OPC_JR:
5145             ctx->hflags |= MIPS_HFLAG_BR;
5146             break;
5147         case OPC_JALR:
5148             blink = rt;
5149             ctx->hflags |= MIPS_HFLAG_BR;
5150             break;
5151         default:
5152             MIPS_INVAL("branch/jump");
5153             generate_exception_end(ctx, EXCP_RI);
5154             goto out;
5155         }
5156     } else {
5157         switch (opc) {
5158         case OPC_BEQ:
5159             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5160             goto not_likely;
5161         case OPC_BEQL:
5162             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5163             goto likely;
5164         case OPC_BNE:
5165             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5166             goto not_likely;
5167         case OPC_BNEL:
5168             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5169             goto likely;
5170         case OPC_BGEZ:
5171             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5172             goto not_likely;
5173         case OPC_BGEZL:
5174             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5175             goto likely;
5176         case OPC_BGEZAL:
5177             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5178             blink = 31;
5179             goto not_likely;
5180         case OPC_BGEZALL:
5181             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5182             blink = 31;
5183             goto likely;
5184         case OPC_BGTZ:
5185             tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5186             goto not_likely;
5187         case OPC_BGTZL:
5188             tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5189             goto likely;
5190         case OPC_BLEZ:
5191             tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
5192             goto not_likely;
5193         case OPC_BLEZL:
5194             tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
5195             goto likely;
5196         case OPC_BLTZ:
5197             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5198             goto not_likely;
5199         case OPC_BLTZL:
5200             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5201             goto likely;
5202         case OPC_BPOSGE32:
5203             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
5204             goto not_likely;
5205 #if defined(TARGET_MIPS64)
5206         case OPC_BPOSGE64:
5207             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
5208             goto not_likely;
5209 #endif
5210         case OPC_BLTZAL:
5211             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5212             blink = 31;
5213         not_likely:
5214             ctx->hflags |= MIPS_HFLAG_BC;
5215             break;
5216         case OPC_BLTZALL:
5217             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5218             blink = 31;
5219         likely:
5220             ctx->hflags |= MIPS_HFLAG_BL;
5221             break;
5222         default:
5223             MIPS_INVAL("conditional branch/jump");
5224             generate_exception_end(ctx, EXCP_RI);
5225             goto out;
5226         }
5227     }
5228
5229     ctx->btarget = btgt;
5230
5231     switch (delayslot_size) {
5232     case 2:
5233         ctx->hflags |= MIPS_HFLAG_BDS16;
5234         break;
5235     case 4:
5236         ctx->hflags |= MIPS_HFLAG_BDS32;
5237         break;
5238     }
5239
5240     if (blink > 0) {
5241         int post_delay = insn_bytes + delayslot_size;
5242         int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
5243
5244         tcg_gen_movi_tl(cpu_gpr[blink],
5245                         ctx->base.pc_next + post_delay + lowbit);
5246     }
5247
5248  out:
5249     if (insn_bytes == 2)
5250         ctx->hflags |= MIPS_HFLAG_B16;
5251     tcg_temp_free(t0);
5252     tcg_temp_free(t1);
5253 }
5254
5255
5256 /* nanoMIPS Branches */
5257 static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc,
5258                                 int insn_bytes,
5259                                 int rs, int rt, int32_t offset)
5260 {
5261     target_ulong btgt = -1;
5262     int bcond_compute = 0;
5263     TCGv t0 = tcg_temp_new();
5264     TCGv t1 = tcg_temp_new();
5265
5266     /* Load needed operands */
5267     switch (opc) {
5268     case OPC_BEQ:
5269     case OPC_BNE:
5270         /* Compare two registers */
5271         if (rs != rt) {
5272             gen_load_gpr(t0, rs);
5273             gen_load_gpr(t1, rt);
5274             bcond_compute = 1;
5275         }
5276         btgt = ctx->base.pc_next + insn_bytes + offset;
5277         break;
5278     case OPC_BGEZAL:
5279         /* Compare to zero */
5280         if (rs != 0) {
5281             gen_load_gpr(t0, rs);
5282             bcond_compute = 1;
5283         }
5284         btgt = ctx->base.pc_next + insn_bytes + offset;
5285         break;
5286     case OPC_BPOSGE32:
5287         tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5288         bcond_compute = 1;
5289         btgt = ctx->base.pc_next + insn_bytes + offset;
5290         break;
5291     case OPC_JR:
5292     case OPC_JALR:
5293         /* Jump to register */
5294         if (offset != 0 && offset != 16) {
5295             /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5296                others are reserved. */
5297             MIPS_INVAL("jump hint");
5298             generate_exception_end(ctx, EXCP_RI);
5299             goto out;
5300         }
5301         gen_load_gpr(btarget, rs);
5302         break;
5303     default:
5304         MIPS_INVAL("branch/jump");
5305         generate_exception_end(ctx, EXCP_RI);
5306         goto out;
5307     }
5308     if (bcond_compute == 0) {
5309         /* No condition to be computed */
5310         switch (opc) {
5311         case OPC_BEQ:     /* rx == rx        */
5312             /* Always take */
5313             ctx->hflags |= MIPS_HFLAG_B;
5314             break;
5315         case OPC_BGEZAL:  /* 0 >= 0          */
5316             /* Always take and link */
5317             tcg_gen_movi_tl(cpu_gpr[31],
5318                             ctx->base.pc_next + insn_bytes);
5319             ctx->hflags |= MIPS_HFLAG_B;
5320             break;
5321         case OPC_BNE:     /* rx != rx        */
5322             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
5323             /* Skip the instruction in the delay slot */
5324             ctx->base.pc_next += 4;
5325             goto out;
5326         case OPC_JR:
5327             ctx->hflags |= MIPS_HFLAG_BR;
5328             break;
5329         case OPC_JALR:
5330             if (rt > 0) {
5331                 tcg_gen_movi_tl(cpu_gpr[rt],
5332                                 ctx->base.pc_next + insn_bytes);
5333             }
5334             ctx->hflags |= MIPS_HFLAG_BR;
5335             break;
5336         default:
5337             MIPS_INVAL("branch/jump");
5338             generate_exception_end(ctx, EXCP_RI);
5339             goto out;
5340         }
5341     } else {
5342         switch (opc) {
5343         case OPC_BEQ:
5344             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5345             goto not_likely;
5346         case OPC_BNE:
5347             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5348             goto not_likely;
5349         case OPC_BGEZAL:
5350             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5351             tcg_gen_movi_tl(cpu_gpr[31],
5352                             ctx->base.pc_next + insn_bytes);
5353             goto not_likely;
5354         case OPC_BPOSGE32:
5355             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
5356         not_likely:
5357             ctx->hflags |= MIPS_HFLAG_BC;
5358             break;
5359         default:
5360             MIPS_INVAL("conditional branch/jump");
5361             generate_exception_end(ctx, EXCP_RI);
5362             goto out;
5363         }
5364     }
5365
5366     ctx->btarget = btgt;
5367
5368  out:
5369     if (insn_bytes == 2) {
5370         ctx->hflags |= MIPS_HFLAG_B16;
5371     }
5372     tcg_temp_free(t0);
5373     tcg_temp_free(t1);
5374 }
5375
5376
5377 /* special3 bitfield operations */
5378 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
5379                         int rs, int lsb, int msb)
5380 {
5381     TCGv t0 = tcg_temp_new();
5382     TCGv t1 = tcg_temp_new();
5383
5384     gen_load_gpr(t1, rs);
5385     switch (opc) {
5386     case OPC_EXT:
5387         if (lsb + msb > 31) {
5388             goto fail;
5389         }
5390         if (msb != 31) {
5391             tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
5392         } else {
5393             /* The two checks together imply that lsb == 0,
5394                so this is a simple sign-extension.  */
5395             tcg_gen_ext32s_tl(t0, t1);
5396         }
5397         break;
5398 #if defined(TARGET_MIPS64)
5399     case OPC_DEXTU:
5400         lsb += 32;
5401         goto do_dext;
5402     case OPC_DEXTM:
5403         msb += 32;
5404         goto do_dext;
5405     case OPC_DEXT:
5406     do_dext:
5407         if (lsb + msb > 63) {
5408             goto fail;
5409         }
5410         tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
5411         break;
5412 #endif
5413     case OPC_INS:
5414         if (lsb > msb) {
5415             goto fail;
5416         }
5417         gen_load_gpr(t0, rt);
5418         tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
5419         tcg_gen_ext32s_tl(t0, t0);
5420         break;
5421 #if defined(TARGET_MIPS64)
5422     case OPC_DINSU:
5423         lsb += 32;
5424         /* FALLTHRU */
5425     case OPC_DINSM:
5426         msb += 32;
5427         /* FALLTHRU */
5428     case OPC_DINS:
5429         if (lsb > msb) {
5430             goto fail;
5431         }
5432         gen_load_gpr(t0, rt);
5433         tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
5434         break;
5435 #endif
5436     default:
5437 fail:
5438         MIPS_INVAL("bitops");
5439         generate_exception_end(ctx, EXCP_RI);
5440         tcg_temp_free(t0);
5441         tcg_temp_free(t1);
5442         return;
5443     }
5444     gen_store_gpr(t0, rt);
5445     tcg_temp_free(t0);
5446     tcg_temp_free(t1);
5447 }
5448
5449 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
5450 {
5451     TCGv t0;
5452
5453     if (rd == 0) {
5454         /* If no destination, treat it as a NOP. */
5455         return;
5456     }
5457
5458     t0 = tcg_temp_new();
5459     gen_load_gpr(t0, rt);
5460     switch (op2) {
5461     case OPC_WSBH:
5462         {
5463             TCGv t1 = tcg_temp_new();
5464             TCGv t2 = tcg_const_tl(0x00FF00FF);
5465
5466             tcg_gen_shri_tl(t1, t0, 8);
5467             tcg_gen_and_tl(t1, t1, t2);
5468             tcg_gen_and_tl(t0, t0, t2);
5469             tcg_gen_shli_tl(t0, t0, 8);
5470             tcg_gen_or_tl(t0, t0, t1);
5471             tcg_temp_free(t2);
5472             tcg_temp_free(t1);
5473             tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
5474         }
5475         break;
5476     case OPC_SEB:
5477         tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
5478         break;
5479     case OPC_SEH:
5480         tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
5481         break;
5482 #if defined(TARGET_MIPS64)
5483     case OPC_DSBH:
5484         {
5485             TCGv t1 = tcg_temp_new();
5486             TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
5487
5488             tcg_gen_shri_tl(t1, t0, 8);
5489             tcg_gen_and_tl(t1, t1, t2);
5490             tcg_gen_and_tl(t0, t0, t2);
5491             tcg_gen_shli_tl(t0, t0, 8);
5492             tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
5493             tcg_temp_free(t2);
5494             tcg_temp_free(t1);
5495         }
5496         break;
5497     case OPC_DSHD:
5498         {
5499             TCGv t1 = tcg_temp_new();
5500             TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
5501
5502             tcg_gen_shri_tl(t1, t0, 16);
5503             tcg_gen_and_tl(t1, t1, t2);
5504             tcg_gen_and_tl(t0, t0, t2);
5505             tcg_gen_shli_tl(t0, t0, 16);
5506             tcg_gen_or_tl(t0, t0, t1);
5507             tcg_gen_shri_tl(t1, t0, 32);
5508             tcg_gen_shli_tl(t0, t0, 32);
5509             tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
5510             tcg_temp_free(t2);
5511             tcg_temp_free(t1);
5512         }
5513         break;
5514 #endif
5515     default:
5516         MIPS_INVAL("bsfhl");
5517         generate_exception_end(ctx, EXCP_RI);
5518         tcg_temp_free(t0);
5519         return;
5520     }
5521     tcg_temp_free(t0);
5522 }
5523
5524 static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
5525                     int imm2)
5526 {
5527     TCGv t0;
5528     TCGv t1;
5529     if (rd == 0) {
5530         /* Treat as NOP. */
5531         return;
5532     }
5533     t0 = tcg_temp_new();
5534     t1 = tcg_temp_new();
5535     gen_load_gpr(t0, rs);
5536     gen_load_gpr(t1, rt);
5537     tcg_gen_shli_tl(t0, t0, imm2 + 1);
5538     tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
5539     if (opc == OPC_LSA) {
5540         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5541     }
5542
5543     tcg_temp_free(t1);
5544     tcg_temp_free(t0);
5545
5546     return;
5547 }
5548
5549 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
5550                            int rt, int bits)
5551 {
5552     TCGv t0;
5553     if (rd == 0) {
5554         /* Treat as NOP. */
5555         return;
5556     }
5557     t0 = tcg_temp_new();
5558     if (bits == 0 || bits == wordsz) {
5559         if (bits == 0) {
5560             gen_load_gpr(t0, rt);
5561         } else {
5562             gen_load_gpr(t0, rs);
5563         }
5564         switch (wordsz) {
5565         case 32:
5566             tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
5567             break;
5568 #if defined(TARGET_MIPS64)
5569         case 64:
5570             tcg_gen_mov_tl(cpu_gpr[rd], t0);
5571             break;
5572 #endif
5573         }
5574     } else {
5575         TCGv t1 = tcg_temp_new();
5576         gen_load_gpr(t0, rt);
5577         gen_load_gpr(t1, rs);
5578         switch (wordsz) {
5579         case 32:
5580             {
5581                 TCGv_i64 t2 = tcg_temp_new_i64();
5582                 tcg_gen_concat_tl_i64(t2, t1, t0);
5583                 tcg_gen_shri_i64(t2, t2, 32 - bits);
5584                 gen_move_low32(cpu_gpr[rd], t2);
5585                 tcg_temp_free_i64(t2);
5586             }
5587             break;
5588 #if defined(TARGET_MIPS64)
5589         case 64:
5590             tcg_gen_shli_tl(t0, t0, bits);
5591             tcg_gen_shri_tl(t1, t1, 64 - bits);
5592             tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
5593             break;
5594 #endif
5595         }
5596         tcg_temp_free(t1);
5597     }
5598
5599     tcg_temp_free(t0);
5600 }
5601
5602 static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
5603                       int bp)
5604 {
5605     gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
5606 }
5607
5608 static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
5609                     int shift)
5610 {
5611     gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift);
5612 }
5613
5614 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
5615 {
5616     TCGv t0;
5617     if (rd == 0) {
5618         /* Treat as NOP. */
5619         return;
5620     }
5621     t0 = tcg_temp_new();
5622     gen_load_gpr(t0, rt);
5623     switch (opc) {
5624     case OPC_BITSWAP:
5625         gen_helper_bitswap(cpu_gpr[rd], t0);
5626         break;
5627 #if defined(TARGET_MIPS64)
5628     case OPC_DBITSWAP:
5629         gen_helper_dbitswap(cpu_gpr[rd], t0);
5630         break;
5631 #endif
5632     }
5633     tcg_temp_free(t0);
5634 }
5635
5636 #ifndef CONFIG_USER_ONLY
5637 /* CP0 (MMU and control) */
5638 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
5639 {
5640     TCGv_i64 t0 = tcg_temp_new_i64();
5641     TCGv_i64 t1 = tcg_temp_new_i64();
5642
5643     tcg_gen_ext_tl_i64(t0, arg);
5644     tcg_gen_ld_i64(t1, cpu_env, off);
5645 #if defined(TARGET_MIPS64)
5646     tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
5647 #else
5648     tcg_gen_concat32_i64(t1, t1, t0);
5649 #endif
5650     tcg_gen_st_i64(t1, cpu_env, off);
5651     tcg_temp_free_i64(t1);
5652     tcg_temp_free_i64(t0);
5653 }
5654
5655 static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
5656 {
5657     TCGv_i64 t0 = tcg_temp_new_i64();
5658     TCGv_i64 t1 = tcg_temp_new_i64();
5659
5660     tcg_gen_ext_tl_i64(t0, arg);
5661     tcg_gen_ld_i64(t1, cpu_env, off);
5662     tcg_gen_concat32_i64(t1, t1, t0);
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_mfhc0_entrylo(TCGv arg, target_ulong off)
5669 {
5670     TCGv_i64 t0 = tcg_temp_new_i64();
5671
5672     tcg_gen_ld_i64(t0, cpu_env, off);
5673 #if defined(TARGET_MIPS64)
5674     tcg_gen_shri_i64(t0, t0, 30);
5675 #else
5676     tcg_gen_shri_i64(t0, t0, 32);
5677 #endif
5678     gen_move_low32(arg, t0);
5679     tcg_temp_free_i64(t0);
5680 }
5681
5682 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
5683 {
5684     TCGv_i64 t0 = tcg_temp_new_i64();
5685
5686     tcg_gen_ld_i64(t0, cpu_env, off);
5687     tcg_gen_shri_i64(t0, t0, 32 + shift);
5688     gen_move_low32(arg, t0);
5689     tcg_temp_free_i64(t0);
5690 }
5691
5692 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
5693 {
5694     TCGv_i32 t0 = tcg_temp_new_i32();
5695
5696     tcg_gen_ld_i32(t0, cpu_env, off);
5697     tcg_gen_ext_i32_tl(arg, t0);
5698     tcg_temp_free_i32(t0);
5699 }
5700
5701 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
5702 {
5703     tcg_gen_ld_tl(arg, cpu_env, off);
5704     tcg_gen_ext32s_tl(arg, arg);
5705 }
5706
5707 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
5708 {
5709     TCGv_i32 t0 = tcg_temp_new_i32();
5710
5711     tcg_gen_trunc_tl_i32(t0, arg);
5712     tcg_gen_st_i32(t0, cpu_env, off);
5713     tcg_temp_free_i32(t0);
5714 }
5715
5716 #define CP0_CHECK(c)                            \
5717     do {                                        \
5718         if (!(c)) {                             \
5719             goto cp0_unimplemented;             \
5720         }                                       \
5721     } while (0)
5722
5723 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5724 {
5725     const char *rn = "invalid";
5726
5727     switch (reg) {
5728     case 2:
5729         switch (sel) {
5730         case 0:
5731             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5732             gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5733             rn = "EntryLo0";
5734             break;
5735         default:
5736             goto cp0_unimplemented;
5737         }
5738         break;
5739     case 3:
5740         switch (sel) {
5741         case 0:
5742             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5743             gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5744             rn = "EntryLo1";
5745             break;
5746         default:
5747             goto cp0_unimplemented;
5748         }
5749         break;
5750     case 17:
5751         switch (sel) {
5752         case 0:
5753             gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
5754                              ctx->CP0_LLAddr_shift);
5755             rn = "LLAddr";
5756             break;
5757         case 1:
5758             CP0_CHECK(ctx->mrp);
5759             gen_helper_mfhc0_maar(arg, cpu_env);
5760             rn = "MAAR";
5761             break;
5762         default:
5763             goto cp0_unimplemented;
5764         }
5765         break;
5766     case 28:
5767         switch (sel) {
5768         case 0:
5769         case 2:
5770         case 4:
5771         case 6:
5772             gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
5773             rn = "TagLo";
5774             break;
5775         default:
5776             goto cp0_unimplemented;
5777         }
5778         break;
5779     default:
5780         goto cp0_unimplemented;
5781     }
5782     trace_mips_translate_c0("mfhc0", rn, reg, sel);
5783     return;
5784
5785 cp0_unimplemented:
5786     qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
5787     tcg_gen_movi_tl(arg, 0);
5788 }
5789
5790 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5791 {
5792     const char *rn = "invalid";
5793     uint64_t mask = ctx->PAMask >> 36;
5794
5795     switch (reg) {
5796     case 2:
5797         switch (sel) {
5798         case 0:
5799             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5800             tcg_gen_andi_tl(arg, arg, mask);
5801             gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5802             rn = "EntryLo0";
5803             break;
5804         default:
5805             goto cp0_unimplemented;
5806         }
5807         break;
5808     case 3:
5809         switch (sel) {
5810         case 0:
5811             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5812             tcg_gen_andi_tl(arg, arg, mask);
5813             gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5814             rn = "EntryLo1";
5815             break;
5816         default:
5817             goto cp0_unimplemented;
5818         }
5819         break;
5820     case 17:
5821         switch (sel) {
5822         case 0:
5823             /* LLAddr is read-only (the only exception is bit 0 if LLB is
5824                supported); the CP0_LLAddr_rw_bitmask does not seem to be
5825                relevant for modern MIPS cores supporting MTHC0, therefore
5826                treating MTHC0 to LLAddr as NOP. */
5827             rn = "LLAddr";
5828             break;
5829         case 1:
5830             CP0_CHECK(ctx->mrp);
5831             gen_helper_mthc0_maar(cpu_env, arg);
5832             rn = "MAAR";
5833             break;
5834         default:
5835             goto cp0_unimplemented;
5836         }
5837         break;
5838     case 28:
5839         switch (sel) {
5840         case 0:
5841         case 2:
5842         case 4:
5843         case 6:
5844             tcg_gen_andi_tl(arg, arg, mask);
5845             gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
5846             rn = "TagLo";
5847             break;
5848         default:
5849             goto cp0_unimplemented;
5850         }
5851         break;
5852     default:
5853         goto cp0_unimplemented;
5854     }
5855     trace_mips_translate_c0("mthc0", rn, reg, sel);
5856
5857 cp0_unimplemented:
5858     qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
5859 }
5860
5861 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
5862 {
5863     if (ctx->insn_flags & ISA_MIPS32R6) {
5864         tcg_gen_movi_tl(arg, 0);
5865     } else {
5866         tcg_gen_movi_tl(arg, ~0);
5867     }
5868 }
5869
5870 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5871 {
5872     const char *rn = "invalid";
5873
5874     if (sel != 0)
5875         check_insn(ctx, ISA_MIPS32);
5876
5877     switch (reg) {
5878     case 0:
5879         switch (sel) {
5880         case 0:
5881             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5882             rn = "Index";
5883             break;
5884         case 1:
5885             CP0_CHECK(ctx->insn_flags & ASE_MT);
5886             gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5887             rn = "MVPControl";
5888             break;
5889         case 2:
5890             CP0_CHECK(ctx->insn_flags & ASE_MT);
5891             gen_helper_mfc0_mvpconf0(arg, cpu_env);
5892             rn = "MVPConf0";
5893             break;
5894         case 3:
5895             CP0_CHECK(ctx->insn_flags & ASE_MT);
5896             gen_helper_mfc0_mvpconf1(arg, cpu_env);
5897             rn = "MVPConf1";
5898             break;
5899         case 4:
5900             CP0_CHECK(ctx->vp);
5901             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
5902             rn = "VPControl";
5903             break;
5904         default:
5905             goto cp0_unimplemented;
5906         }
5907         break;
5908     case 1:
5909         switch (sel) {
5910         case 0:
5911             CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
5912             gen_helper_mfc0_random(arg, cpu_env);
5913             rn = "Random";
5914             break;
5915         case 1:
5916             CP0_CHECK(ctx->insn_flags & ASE_MT);
5917             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5918             rn = "VPEControl";
5919             break;
5920         case 2:
5921             CP0_CHECK(ctx->insn_flags & ASE_MT);
5922             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5923             rn = "VPEConf0";
5924             break;
5925         case 3:
5926             CP0_CHECK(ctx->insn_flags & ASE_MT);
5927             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5928             rn = "VPEConf1";
5929             break;
5930         case 4:
5931             CP0_CHECK(ctx->insn_flags & ASE_MT);
5932             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
5933             rn = "YQMask";
5934             break;
5935         case 5:
5936             CP0_CHECK(ctx->insn_flags & ASE_MT);
5937             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
5938             rn = "VPESchedule";
5939             break;
5940         case 6:
5941             CP0_CHECK(ctx->insn_flags & ASE_MT);
5942             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5943             rn = "VPEScheFBack";
5944             break;
5945         case 7:
5946             CP0_CHECK(ctx->insn_flags & ASE_MT);
5947             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5948             rn = "VPEOpt";
5949             break;
5950         default:
5951             goto cp0_unimplemented;
5952         }
5953         break;
5954     case 2:
5955         switch (sel) {
5956         case 0:
5957             {
5958                 TCGv_i64 tmp = tcg_temp_new_i64();
5959                 tcg_gen_ld_i64(tmp, cpu_env,
5960                                offsetof(CPUMIPSState, CP0_EntryLo0));
5961 #if defined(TARGET_MIPS64)
5962                 if (ctx->rxi) {
5963                     /* Move RI/XI fields to bits 31:30 */
5964                     tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5965                     tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5966                 }
5967 #endif
5968                 gen_move_low32(arg, tmp);
5969                 tcg_temp_free_i64(tmp);
5970             }
5971             rn = "EntryLo0";
5972             break;
5973         case 1:
5974             CP0_CHECK(ctx->insn_flags & ASE_MT);
5975             gen_helper_mfc0_tcstatus(arg, cpu_env);
5976             rn = "TCStatus";
5977             break;
5978         case 2:
5979             CP0_CHECK(ctx->insn_flags & ASE_MT);
5980             gen_helper_mfc0_tcbind(arg, cpu_env);
5981             rn = "TCBind";
5982             break;
5983         case 3:
5984             CP0_CHECK(ctx->insn_flags & ASE_MT);
5985             gen_helper_mfc0_tcrestart(arg, cpu_env);
5986             rn = "TCRestart";
5987             break;
5988         case 4:
5989             CP0_CHECK(ctx->insn_flags & ASE_MT);
5990             gen_helper_mfc0_tchalt(arg, cpu_env);
5991             rn = "TCHalt";
5992             break;
5993         case 5:
5994             CP0_CHECK(ctx->insn_flags & ASE_MT);
5995             gen_helper_mfc0_tccontext(arg, cpu_env);
5996             rn = "TCContext";
5997             break;
5998         case 6:
5999             CP0_CHECK(ctx->insn_flags & ASE_MT);
6000             gen_helper_mfc0_tcschedule(arg, cpu_env);
6001             rn = "TCSchedule";
6002             break;
6003         case 7:
6004             CP0_CHECK(ctx->insn_flags & ASE_MT);
6005             gen_helper_mfc0_tcschefback(arg, cpu_env);
6006             rn = "TCScheFBack";
6007             break;
6008         default:
6009             goto cp0_unimplemented;
6010         }
6011         break;
6012     case 3:
6013         switch (sel) {
6014         case 0:
6015             {
6016                 TCGv_i64 tmp = tcg_temp_new_i64();
6017                 tcg_gen_ld_i64(tmp, cpu_env,
6018                                offsetof(CPUMIPSState, CP0_EntryLo1));
6019 #if defined(TARGET_MIPS64)
6020                 if (ctx->rxi) {
6021                     /* Move RI/XI fields to bits 31:30 */
6022                     tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6023                     tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6024                 }
6025 #endif
6026                 gen_move_low32(arg, tmp);
6027                 tcg_temp_free_i64(tmp);
6028             }
6029             rn = "EntryLo1";
6030             break;
6031         case 1:
6032             CP0_CHECK(ctx->vp);
6033             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6034             rn = "GlobalNumber";
6035             break;
6036         default:
6037             goto cp0_unimplemented;
6038         }
6039         break;
6040     case 4:
6041         switch (sel) {
6042         case 0:
6043             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
6044             tcg_gen_ext32s_tl(arg, arg);
6045             rn = "Context";
6046             break;
6047         case 1:
6048 //            gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
6049             rn = "ContextConfig";
6050             goto cp0_unimplemented;
6051         case 2:
6052             CP0_CHECK(ctx->ulri);
6053             tcg_gen_ld_tl(arg, cpu_env,
6054                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6055             tcg_gen_ext32s_tl(arg, arg);
6056             rn = "UserLocal";
6057             break;
6058         default:
6059             goto cp0_unimplemented;
6060         }
6061         break;
6062     case 5:
6063         switch (sel) {
6064         case 0:
6065             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
6066             rn = "PageMask";
6067             break;
6068         case 1:
6069             check_insn(ctx, ISA_MIPS32R2);
6070             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
6071             rn = "PageGrain";
6072             break;
6073         case 2:
6074             CP0_CHECK(ctx->sc);
6075             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
6076             tcg_gen_ext32s_tl(arg, arg);
6077             rn = "SegCtl0";
6078             break;
6079         case 3:
6080             CP0_CHECK(ctx->sc);
6081             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
6082             tcg_gen_ext32s_tl(arg, arg);
6083             rn = "SegCtl1";
6084             break;
6085         case 4:
6086             CP0_CHECK(ctx->sc);
6087             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
6088             tcg_gen_ext32s_tl(arg, arg);
6089             rn = "SegCtl2";
6090             break;
6091         default:
6092             goto cp0_unimplemented;
6093         }
6094         break;
6095     case 6:
6096         switch (sel) {
6097         case 0:
6098             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
6099             rn = "Wired";
6100             break;
6101         case 1:
6102             check_insn(ctx, ISA_MIPS32R2);
6103             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
6104             rn = "SRSConf0";
6105             break;
6106         case 2:
6107             check_insn(ctx, ISA_MIPS32R2);
6108             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
6109             rn = "SRSConf1";
6110             break;
6111         case 3:
6112             check_insn(ctx, ISA_MIPS32R2);
6113             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
6114             rn = "SRSConf2";
6115             break;
6116         case 4:
6117             check_insn(ctx, ISA_MIPS32R2);
6118             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
6119             rn = "SRSConf3";
6120             break;
6121         case 5:
6122             check_insn(ctx, ISA_MIPS32R2);
6123             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
6124             rn = "SRSConf4";
6125             break;
6126         default:
6127             goto cp0_unimplemented;
6128         }
6129         break;
6130     case 7:
6131         switch (sel) {
6132         case 0:
6133             check_insn(ctx, ISA_MIPS32R2);
6134             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
6135             rn = "HWREna";
6136             break;
6137         default:
6138             goto cp0_unimplemented;
6139         }
6140         break;
6141     case 8:
6142         switch (sel) {
6143         case 0:
6144             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
6145             tcg_gen_ext32s_tl(arg, arg);
6146             rn = "BadVAddr";
6147             break;
6148         case 1:
6149             CP0_CHECK(ctx->bi);
6150             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6151             rn = "BadInstr";
6152             break;
6153         case 2:
6154             CP0_CHECK(ctx->bp);
6155             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6156             rn = "BadInstrP";
6157             break;
6158         case 3:
6159             CP0_CHECK(ctx->bi);
6160             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
6161             tcg_gen_andi_tl(arg, arg, ~0xffff);
6162             rn = "BadInstrX";
6163             break;
6164        default:
6165             goto cp0_unimplemented;
6166         }
6167         break;
6168     case 9:
6169         switch (sel) {
6170         case 0:
6171             /* Mark as an IO operation because we read the time.  */
6172             if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
6173                 gen_io_start();
6174             }
6175             gen_helper_mfc0_count(arg, cpu_env);
6176             if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
6177                 gen_io_end();
6178             }
6179             /* Break the TB to be able to take timer interrupts immediately
6180                after reading count. DISAS_STOP isn't sufficient, we need to
6181                ensure we break completely out of translated code.  */
6182             gen_save_pc(ctx->base.pc_next + 4);
6183             ctx->base.is_jmp = DISAS_EXIT;
6184             rn = "Count";
6185             break;
6186         /* 6,7 are implementation dependent */
6187         default:
6188             goto cp0_unimplemented;
6189         }
6190         break;
6191     case 10:
6192         switch (sel) {
6193         case 0:
6194             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
6195             tcg_gen_ext32s_tl(arg, arg);
6196             rn = "EntryHi";
6197             break;
6198         default:
6199             goto cp0_unimplemented;
6200         }
6201         break;
6202     case 11:
6203         switch (sel) {
6204         case 0:
6205             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
6206             rn = "Compare";
6207             break;
6208         /* 6,7 are implementation dependent */
6209         default:
6210             goto cp0_unimplemented;
6211         }
6212         break;
6213     case 12:
6214         switch (sel) {
6215         case 0:
6216             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
6217             rn = "Status";
6218             break;
6219         case 1:
6220             check_insn(ctx, ISA_MIPS32R2);
6221             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
6222             rn = "IntCtl";
6223             break;
6224         case 2:
6225             check_insn(ctx, ISA_MIPS32R2);
6226             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
6227             rn = "SRSCtl";
6228             break;
6229         case 3:
6230             check_insn(ctx, ISA_MIPS32R2);
6231             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6232             rn = "SRSMap";
6233             break;
6234         default:
6235             goto cp0_unimplemented;
6236        }
6237         break;
6238     case 13:
6239         switch (sel) {
6240         case 0:
6241             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
6242             rn = "Cause";
6243             break;
6244         default:
6245             goto cp0_unimplemented;
6246        }
6247         break;
6248     case 14:
6249         switch (sel) {
6250         case 0:
6251             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6252             tcg_gen_ext32s_tl(arg, arg);
6253             rn = "EPC";
6254             break;
6255         default:
6256             goto cp0_unimplemented;
6257         }
6258         break;
6259     case 15:
6260         switch (sel) {
6261         case 0:
6262             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
6263             rn = "PRid";
6264             break;
6265         case 1:
6266             check_insn(ctx, ISA_MIPS32R2);
6267             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
6268             tcg_gen_ext32s_tl(arg, arg);
6269             rn = "EBase";
6270             break;
6271         case 3:
6272             check_insn(ctx, ISA_MIPS32R2);
6273             CP0_CHECK(ctx->cmgcr);
6274             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6275             tcg_gen_ext32s_tl(arg, arg);
6276             rn = "CMGCRBase";
6277             break;
6278         default:
6279             goto cp0_unimplemented;
6280        }
6281         break;
6282     case 16:
6283         switch (sel) {
6284         case 0:
6285             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
6286             rn = "Config";
6287             break;
6288         case 1:
6289             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
6290             rn = "Config1";
6291             break;
6292         case 2:
6293             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
6294             rn = "Config2";
6295             break;
6296         case 3:
6297             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
6298             rn = "Config3";
6299             break;
6300         case 4:
6301             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6302             rn = "Config4";
6303             break;
6304         case 5:
6305             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6306             rn = "Config5";
6307             break;
6308         /* 6,7 are implementation dependent */
6309         case 6:
6310             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
6311             rn = "Config6";
6312             break;
6313         case 7:
6314             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
6315             rn = "Config7";
6316             break;
6317         default:
6318             goto cp0_unimplemented;
6319         }
6320         break;
6321     case 17:
6322         switch (sel) {
6323         case 0:
6324             gen_helper_mfc0_lladdr(arg, cpu_env);
6325             rn = "LLAddr";
6326             break;
6327         case 1:
6328             CP0_CHECK(ctx->mrp);
6329             gen_helper_mfc0_maar(arg, cpu_env);
6330             rn = "MAAR";
6331             break;
6332         case 2:
6333             CP0_CHECK(ctx->mrp);
6334             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
6335             rn = "MAARI";
6336             break;
6337         default:
6338             goto cp0_unimplemented;
6339         }
6340         break;
6341     case 18:
6342         switch (sel) {
6343         case 0:
6344         case 1:
6345         case 2:
6346         case 3:
6347         case 4:
6348         case 5:
6349         case 6:
6350         case 7:
6351             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6352             gen_helper_1e0i(mfc0_watchlo, arg, sel);
6353             rn = "WatchLo";
6354             break;
6355         default:
6356             goto cp0_unimplemented;
6357         }
6358         break;
6359     case 19:
6360         switch (sel) {
6361         case 0:
6362         case 1:
6363         case 2:
6364         case 3:
6365         case 4:
6366         case 5:
6367         case 6:
6368         case 7:
6369             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6370             gen_helper_1e0i(mfc0_watchhi, arg, sel);
6371             rn = "WatchHi";
6372             break;
6373         default:
6374             goto cp0_unimplemented;
6375         }
6376         break;
6377     case 20:
6378         switch (sel) {
6379         case 0:
6380 #if defined(TARGET_MIPS64)
6381             check_insn(ctx, ISA_MIPS3);
6382             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
6383             tcg_gen_ext32s_tl(arg, arg);
6384             rn = "XContext";
6385             break;
6386 #endif
6387         default:
6388             goto cp0_unimplemented;
6389         }
6390         break;
6391     case 21:
6392        /* Officially reserved, but sel 0 is used for R1x000 framemask */
6393         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6394         switch (sel) {
6395         case 0:
6396             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
6397             rn = "Framemask";
6398             break;
6399         default:
6400             goto cp0_unimplemented;
6401         }
6402         break;
6403     case 22:
6404         tcg_gen_movi_tl(arg, 0); /* unimplemented */
6405         rn = "'Diagnostic"; /* implementation dependent */
6406         break;
6407     case 23:
6408         switch (sel) {
6409         case 0:
6410             gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
6411             rn = "Debug";
6412             break;
6413         case 1:
6414 //            gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
6415             rn = "TraceControl";
6416             goto cp0_unimplemented;
6417         case 2:
6418 //            gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
6419             rn = "TraceControl2";
6420             goto cp0_unimplemented;
6421         case 3:
6422 //            gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
6423             rn = "UserTraceData";
6424             goto cp0_unimplemented;
6425         case 4:
6426 //            gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
6427             rn = "TraceBPC";
6428             goto cp0_unimplemented;
6429         default:
6430             goto cp0_unimplemented;
6431         }
6432         break;
6433     case 24:
6434         switch (sel) {
6435         case 0:
6436             /* EJTAG support */
6437             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6438             tcg_gen_ext32s_tl(arg, arg);
6439             rn = "DEPC";
6440             break;
6441         default:
6442             goto cp0_unimplemented;
6443         }
6444         break;
6445     case 25:
6446         switch (sel) {
6447         case 0:
6448             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
6449             rn = "Performance0";
6450             break;
6451         case 1:
6452 //            gen_helper_mfc0_performance1(arg);
6453             rn = "Performance1";
6454             goto cp0_unimplemented;
6455         case 2:
6456 //            gen_helper_mfc0_performance2(arg);
6457             rn = "Performance2";
6458             goto cp0_unimplemented;
6459         case 3:
6460 //            gen_helper_mfc0_performance3(arg);
6461             rn = "Performance3";
6462             goto cp0_unimplemented;
6463         case 4:
6464 //            gen_helper_mfc0_performance4(arg);
6465             rn = "Performance4";
6466             goto cp0_unimplemented;
6467         case 5:
6468 //            gen_helper_mfc0_performance5(arg);
6469             rn = "Performance5";
6470             goto cp0_unimplemented;
6471         case 6:
6472 //            gen_helper_mfc0_performance6(arg);
6473             rn = "Performance6";
6474             goto cp0_unimplemented;
6475         case 7:
6476 //            gen_helper_mfc0_performance7(arg);
6477             rn = "Performance7";
6478             goto cp0_unimplemented;
6479         default:
6480             goto cp0_unimplemented;
6481         }
6482         break;
6483     case 26:
6484         switch (sel) {
6485         case 0:
6486             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
6487             rn = "ErrCtl";
6488             break;
6489         default:
6490             goto cp0_unimplemented;
6491         }
6492         break;
6493     case 27:
6494         switch (sel) {
6495         case 0:
6496         case 1:
6497         case 2:
6498         case 3:
6499             tcg_gen_movi_tl(arg, 0); /* unimplemented */
6500             rn = "CacheErr";
6501             break;
6502         default:
6503             goto cp0_unimplemented;
6504         }
6505         break;
6506     case 28:
6507         switch (sel) {
6508         case 0:
6509         case 2:
6510         case 4:
6511         case 6:
6512             {
6513                 TCGv_i64 tmp = tcg_temp_new_i64();
6514                 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
6515                 gen_move_low32(arg, tmp);
6516                 tcg_temp_free_i64(tmp);
6517             }
6518             rn = "TagLo";
6519             break;
6520         case 1:
6521         case 3:
6522         case 5:
6523         case 7:
6524             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
6525             rn = "DataLo";
6526             break;
6527         default:
6528             goto cp0_unimplemented;
6529         }
6530         break;
6531     case 29:
6532         switch (sel) {
6533         case 0:
6534         case 2:
6535         case 4:
6536         case 6:
6537             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
6538             rn = "TagHi";
6539             break;
6540         case 1:
6541         case 3:
6542         case 5:
6543         case 7:
6544             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
6545             rn = "DataHi";
6546             break;
6547         default:
6548             goto cp0_unimplemented;
6549         }
6550         break;
6551     case 30:
6552         switch (sel) {
6553         case 0:
6554             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6555             tcg_gen_ext32s_tl(arg, arg);
6556             rn = "ErrorEPC";
6557             break;
6558         default:
6559             goto cp0_unimplemented;
6560         }
6561         break;
6562     case 31:
6563         switch (sel) {
6564         case 0:
6565             /* EJTAG support */
6566             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6567             rn = "DESAVE";
6568             break;
6569         case 2:
6570         case 3:
6571         case 4:
6572         case 5:
6573         case 6:
6574         case 7:
6575             CP0_CHECK(ctx->kscrexist & (1 << sel));
6576             tcg_gen_ld_tl(arg, cpu_env,
6577                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6578             tcg_gen_ext32s_tl(arg, arg);
6579             rn = "KScratch";
6580             break;
6581         default:
6582             goto cp0_unimplemented;
6583         }
6584         break;
6585     default:
6586        goto cp0_unimplemented;
6587     }
6588     trace_mips_translate_c0("mfc0", rn, reg, sel);
6589     return;
6590
6591 cp0_unimplemented:
6592     qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
6593     gen_mfc0_unimplemented(ctx, arg);
6594 }
6595
6596 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6597 {
6598     const char *rn = "invalid";
6599
6600     if (sel != 0)
6601         check_insn(ctx, ISA_MIPS32);
6602
6603     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
6604         gen_io_start();
6605     }
6606
6607     switch (reg) {
6608     case 0:
6609         switch (sel) {
6610         case 0:
6611             gen_helper_mtc0_index(cpu_env, arg);
6612             rn = "Index";
6613             break;
6614         case 1:
6615             CP0_CHECK(ctx->insn_flags & ASE_MT);
6616             gen_helper_mtc0_mvpcontrol(cpu_env, arg);
6617             rn = "MVPControl";
6618             break;
6619         case 2:
6620             CP0_CHECK(ctx->insn_flags & ASE_MT);
6621             /* ignored */
6622             rn = "MVPConf0";
6623             break;
6624         case 3:
6625             CP0_CHECK(ctx->insn_flags & ASE_MT);
6626             /* ignored */
6627             rn = "MVPConf1";
6628             break;
6629         case 4:
6630             CP0_CHECK(ctx->vp);
6631             /* ignored */
6632             rn = "VPControl";
6633             break;
6634         default:
6635             goto cp0_unimplemented;
6636         }
6637         break;
6638     case 1:
6639         switch (sel) {
6640         case 0:
6641             /* ignored */
6642             rn = "Random";
6643             break;
6644         case 1:
6645             CP0_CHECK(ctx->insn_flags & ASE_MT);
6646             gen_helper_mtc0_vpecontrol(cpu_env, arg);
6647             rn = "VPEControl";
6648             break;
6649         case 2:
6650             CP0_CHECK(ctx->insn_flags & ASE_MT);
6651             gen_helper_mtc0_vpeconf0(cpu_env, arg);
6652             rn = "VPEConf0";
6653             break;
6654         case 3:
6655             CP0_CHECK(ctx->insn_flags & ASE_MT);
6656             gen_helper_mtc0_vpeconf1(cpu_env, arg);
6657             rn = "VPEConf1";
6658             break;
6659         case 4:
6660             CP0_CHECK(ctx->insn_flags & ASE_MT);
6661             gen_helper_mtc0_yqmask(cpu_env, arg);
6662             rn = "YQMask";
6663             break;
6664         case 5:
6665             CP0_CHECK(ctx->insn_flags & ASE_MT);
6666             tcg_gen_st_tl(arg, cpu_env,
6667                           offsetof(CPUMIPSState, CP0_VPESchedule));
6668             rn = "VPESchedule";
6669             break;
6670         case 6:
6671             CP0_CHECK(ctx->insn_flags & ASE_MT);
6672             tcg_gen_st_tl(arg, cpu_env,
6673                           offsetof(CPUMIPSState, CP0_VPEScheFBack));
6674             rn = "VPEScheFBack";
6675             break;
6676         case 7:
6677             CP0_CHECK(ctx->insn_flags & ASE_MT);
6678             gen_helper_mtc0_vpeopt(cpu_env, arg);
6679             rn = "VPEOpt";
6680             break;
6681         default:
6682             goto cp0_unimplemented;
6683         }
6684         break;
6685     case 2:
6686         switch (sel) {
6687         case 0:
6688             gen_helper_mtc0_entrylo0(cpu_env, arg);
6689             rn = "EntryLo0";
6690             break;
6691         case 1:
6692             CP0_CHECK(ctx->insn_flags & ASE_MT);
6693             gen_helper_mtc0_tcstatus(cpu_env, arg);
6694             rn = "TCStatus";
6695             break;
6696         case 2:
6697             CP0_CHECK(ctx->insn_flags & ASE_MT);
6698             gen_helper_mtc0_tcbind(cpu_env, arg);
6699             rn = "TCBind";
6700             break;
6701         case 3:
6702             CP0_CHECK(ctx->insn_flags & ASE_MT);
6703             gen_helper_mtc0_tcrestart(cpu_env, arg);
6704             rn = "TCRestart";
6705             break;
6706         case 4:
6707             CP0_CHECK(ctx->insn_flags & ASE_MT);
6708             gen_helper_mtc0_tchalt(cpu_env, arg);
6709             rn = "TCHalt";
6710             break;
6711         case 5:
6712             CP0_CHECK(ctx->insn_flags & ASE_MT);
6713             gen_helper_mtc0_tccontext(cpu_env, arg);
6714             rn = "TCContext";
6715             break;
6716         case 6:
6717             CP0_CHECK(ctx->insn_flags & ASE_MT);
6718             gen_helper_mtc0_tcschedule(cpu_env, arg);
6719             rn = "TCSchedule";
6720             break;
6721         case 7:
6722             CP0_CHECK(ctx->insn_flags & ASE_MT);
6723             gen_helper_mtc0_tcschefback(cpu_env, arg);
6724             rn = "TCScheFBack";
6725             break;
6726         default:
6727             goto cp0_unimplemented;
6728         }
6729         break;
6730     case 3:
6731         switch (sel) {
6732         case 0:
6733             gen_helper_mtc0_entrylo1(cpu_env, arg);
6734             rn = "EntryLo1";
6735             break;
6736         case 1:
6737             CP0_CHECK(ctx->vp);
6738             /* ignored */
6739             rn = "GlobalNumber";
6740             break;
6741         default:
6742             goto cp0_unimplemented;
6743         }
6744         break;
6745     case 4:
6746         switch (sel) {
6747         case 0:
6748             gen_helper_mtc0_context(cpu_env, arg);
6749             rn = "Context";
6750             break;
6751         case 1:
6752 //            gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
6753             rn = "ContextConfig";
6754             goto cp0_unimplemented;
6755         case 2:
6756             CP0_CHECK(ctx->ulri);
6757             tcg_gen_st_tl(arg, cpu_env,
6758                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6759             rn = "UserLocal";
6760             break;
6761         default:
6762             goto cp0_unimplemented;
6763         }
6764         break;
6765     case 5:
6766         switch (sel) {
6767         case 0:
6768             gen_helper_mtc0_pagemask(cpu_env, arg);
6769             rn = "PageMask";
6770             break;
6771         case 1:
6772             check_insn(ctx, ISA_MIPS32R2);
6773             gen_helper_mtc0_pagegrain(cpu_env, arg);
6774             rn = "PageGrain";
6775             ctx->base.is_jmp = DISAS_STOP;
6776             break;
6777         case 2:
6778             CP0_CHECK(ctx->sc);
6779             gen_helper_mtc0_segctl0(cpu_env, arg);
6780             rn = "SegCtl0";
6781             break;
6782         case 3:
6783             CP0_CHECK(ctx->sc);
6784             gen_helper_mtc0_segctl1(cpu_env, arg);
6785             rn = "SegCtl1";
6786             break;
6787         case 4:
6788             CP0_CHECK(ctx->sc);
6789             gen_helper_mtc0_segctl2(cpu_env, arg);
6790             rn = "SegCtl2";
6791             break;
6792         default:
6793             goto cp0_unimplemented;
6794         }
6795         break;
6796     case 6:
6797         switch (sel) {
6798         case 0:
6799             gen_helper_mtc0_wired(cpu_env, arg);
6800             rn = "Wired";
6801             break;
6802         case 1:
6803             check_insn(ctx, ISA_MIPS32R2);
6804             gen_helper_mtc0_srsconf0(cpu_env, arg);
6805             rn = "SRSConf0";
6806             break;
6807         case 2:
6808             check_insn(ctx, ISA_MIPS32R2);
6809             gen_helper_mtc0_srsconf1(cpu_env, arg);
6810             rn = "SRSConf1";
6811             break;
6812         case 3:
6813             check_insn(ctx, ISA_MIPS32R2);
6814             gen_helper_mtc0_srsconf2(cpu_env, arg);
6815             rn = "SRSConf2";
6816             break;
6817         case 4:
6818             check_insn(ctx, ISA_MIPS32R2);
6819             gen_helper_mtc0_srsconf3(cpu_env, arg);
6820             rn = "SRSConf3";
6821             break;
6822         case 5:
6823             check_insn(ctx, ISA_MIPS32R2);
6824             gen_helper_mtc0_srsconf4(cpu_env, arg);
6825             rn = "SRSConf4";
6826             break;
6827         default:
6828             goto cp0_unimplemented;
6829         }
6830         break;
6831     case 7:
6832         switch (sel) {
6833         case 0:
6834             check_insn(ctx, ISA_MIPS32R2);
6835             gen_helper_mtc0_hwrena(cpu_env, arg);
6836             ctx->base.is_jmp = DISAS_STOP;
6837             rn = "HWREna";
6838             break;
6839         default:
6840             goto cp0_unimplemented;
6841         }
6842         break;
6843     case 8:
6844         switch (sel) {
6845         case 0:
6846             /* ignored */
6847             rn = "BadVAddr";
6848             break;
6849         case 1:
6850             /* ignored */
6851             rn = "BadInstr";
6852             break;
6853         case 2:
6854             /* ignored */
6855             rn = "BadInstrP";
6856             break;
6857         case 3:
6858             /* ignored */
6859             rn = "BadInstrX";
6860             break;
6861         default:
6862             goto cp0_unimplemented;
6863         }
6864         break;
6865     case 9:
6866         switch (sel) {
6867         case 0:
6868             gen_helper_mtc0_count(cpu_env, arg);
6869             rn = "Count";
6870             break;
6871         /* 6,7 are implementation dependent */
6872         default:
6873             goto cp0_unimplemented;
6874         }
6875         break;
6876     case 10:
6877         switch (sel) {
6878         case 0:
6879             gen_helper_mtc0_entryhi(cpu_env, arg);
6880             rn = "EntryHi";
6881             break;
6882         default:
6883             goto cp0_unimplemented;
6884         }
6885         break;
6886     case 11:
6887         switch (sel) {
6888         case 0:
6889             gen_helper_mtc0_compare(cpu_env, arg);
6890             rn = "Compare";
6891             break;
6892         /* 6,7 are implementation dependent */
6893         default:
6894             goto cp0_unimplemented;
6895         }
6896         break;
6897     case 12:
6898         switch (sel) {
6899         case 0:
6900             save_cpu_state(ctx, 1);
6901             gen_helper_mtc0_status(cpu_env, arg);
6902             /* DISAS_STOP isn't good enough here, hflags may have changed. */
6903             gen_save_pc(ctx->base.pc_next + 4);
6904             ctx->base.is_jmp = DISAS_EXIT;
6905             rn = "Status";
6906             break;
6907         case 1:
6908             check_insn(ctx, ISA_MIPS32R2);
6909             gen_helper_mtc0_intctl(cpu_env, arg);
6910             /* Stop translation as we may have switched the execution mode */
6911             ctx->base.is_jmp = DISAS_STOP;
6912             rn = "IntCtl";
6913             break;
6914         case 2:
6915             check_insn(ctx, ISA_MIPS32R2);
6916             gen_helper_mtc0_srsctl(cpu_env, arg);
6917             /* Stop translation as we may have switched the execution mode */
6918             ctx->base.is_jmp = DISAS_STOP;
6919             rn = "SRSCtl";
6920             break;
6921         case 3:
6922             check_insn(ctx, ISA_MIPS32R2);
6923             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6924             /* Stop translation as we may have switched the execution mode */
6925             ctx->base.is_jmp = DISAS_STOP;
6926             rn = "SRSMap";
6927             break;
6928         default:
6929             goto cp0_unimplemented;
6930         }
6931         break;
6932     case 13:
6933         switch (sel) {
6934         case 0:
6935             save_cpu_state(ctx, 1);
6936             gen_helper_mtc0_cause(cpu_env, arg);
6937             /* Stop translation as we may have triggered an interrupt.
6938              * DISAS_STOP isn't sufficient, we need to ensure we break out of
6939              * translated code to check for pending interrupts.  */
6940             gen_save_pc(ctx->base.pc_next + 4);
6941             ctx->base.is_jmp = DISAS_EXIT;
6942             rn = "Cause";
6943             break;
6944         default:
6945             goto cp0_unimplemented;
6946         }
6947         break;
6948     case 14:
6949         switch (sel) {
6950         case 0:
6951             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6952             rn = "EPC";
6953             break;
6954         default:
6955             goto cp0_unimplemented;
6956         }
6957         break;
6958     case 15:
6959         switch (sel) {
6960         case 0:
6961             /* ignored */
6962             rn = "PRid";
6963             break;
6964         case 1:
6965             check_insn(ctx, ISA_MIPS32R2);
6966             gen_helper_mtc0_ebase(cpu_env, arg);
6967             rn = "EBase";
6968             break;
6969         default:
6970             goto cp0_unimplemented;
6971         }
6972         break;
6973     case 16:
6974         switch (sel) {
6975         case 0:
6976             gen_helper_mtc0_config0(cpu_env, arg);
6977             rn = "Config";
6978             /* Stop translation as we may have switched the execution mode */
6979             ctx->base.is_jmp = DISAS_STOP;
6980             break;
6981         case 1:
6982             /* ignored, read only */
6983             rn = "Config1";
6984             break;
6985         case 2:
6986             gen_helper_mtc0_config2(cpu_env, arg);
6987             rn = "Config2";
6988             /* Stop translation as we may have switched the execution mode */
6989             ctx->base.is_jmp = DISAS_STOP;
6990             break;
6991         case 3:
6992             gen_helper_mtc0_config3(cpu_env, arg);
6993             rn = "Config3";
6994             /* Stop translation as we may have switched the execution mode */
6995             ctx->base.is_jmp = DISAS_STOP;
6996             break;
6997         case 4:
6998             gen_helper_mtc0_config4(cpu_env, arg);
6999             rn = "Config4";
7000             ctx->base.is_jmp = DISAS_STOP;
7001             break;
7002         case 5:
7003             gen_helper_mtc0_config5(cpu_env, arg);
7004             rn = "Config5";
7005             /* Stop translation as we may have switched the execution mode */
7006             ctx->base.is_jmp = DISAS_STOP;
7007             break;
7008         /* 6,7 are implementation dependent */
7009         case 6:
7010             /* ignored */
7011             rn = "Config6";
7012             break;
7013         case 7:
7014             /* ignored */
7015             rn = "Config7";
7016             break;
7017         default:
7018             rn = "Invalid config selector";
7019             goto cp0_unimplemented;
7020         }
7021         break;
7022     case 17:
7023         switch (sel) {
7024         case 0:
7025             gen_helper_mtc0_lladdr(cpu_env, arg);
7026             rn = "LLAddr";
7027             break;
7028         case 1:
7029             CP0_CHECK(ctx->mrp);
7030             gen_helper_mtc0_maar(cpu_env, arg);
7031             rn = "MAAR";
7032             break;
7033         case 2:
7034             CP0_CHECK(ctx->mrp);
7035             gen_helper_mtc0_maari(cpu_env, arg);
7036             rn = "MAARI";
7037             break;
7038         default:
7039             goto cp0_unimplemented;
7040         }
7041         break;
7042     case 18:
7043         switch (sel) {
7044         case 0:
7045         case 1:
7046         case 2:
7047         case 3:
7048         case 4:
7049         case 5:
7050         case 6:
7051         case 7:
7052             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7053             gen_helper_0e1i(mtc0_watchlo, arg, sel);
7054             rn = "WatchLo";
7055             break;
7056         default:
7057             goto cp0_unimplemented;
7058         }
7059         break;
7060     case 19:
7061         switch (sel) {
7062         case 0:
7063         case 1:
7064         case 2:
7065         case 3:
7066         case 4:
7067         case 5:
7068         case 6:
7069         case 7:
7070             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7071             gen_helper_0e1i(mtc0_watchhi, arg, sel);
7072             rn = "WatchHi";
7073             break;
7074         default:
7075             goto cp0_unimplemented;
7076         }
7077         break;
7078     case 20:
7079         switch (sel) {
7080         case 0:
7081 #if defined(TARGET_MIPS64)
7082             check_insn(ctx, ISA_MIPS3);
7083             gen_helper_mtc0_xcontext(cpu_env, arg);
7084             rn = "XContext";
7085             break;
7086 #endif
7087         default:
7088             goto cp0_unimplemented;
7089         }
7090         break;
7091     case 21:
7092        /* Officially reserved, but sel 0 is used for R1x000 framemask */
7093         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7094         switch (sel) {
7095         case 0:
7096             gen_helper_mtc0_framemask(cpu_env, arg);
7097             rn = "Framemask";
7098             break;
7099         default:
7100             goto cp0_unimplemented;
7101         }
7102         break;
7103     case 22:
7104         /* ignored */
7105         rn = "Diagnostic"; /* implementation dependent */
7106         break;
7107     case 23:
7108         switch (sel) {
7109         case 0:
7110             gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
7111             /* DISAS_STOP isn't good enough here, hflags may have changed. */
7112             gen_save_pc(ctx->base.pc_next + 4);
7113             ctx->base.is_jmp = DISAS_EXIT;
7114             rn = "Debug";
7115             break;
7116         case 1:
7117 //            gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
7118             rn = "TraceControl";
7119             /* Stop translation as we may have switched the execution mode */
7120             ctx->base.is_jmp = DISAS_STOP;
7121             goto cp0_unimplemented;
7122         case 2:
7123 //            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
7124             rn = "TraceControl2";
7125             /* Stop translation as we may have switched the execution mode */
7126             ctx->base.is_jmp = DISAS_STOP;
7127             goto cp0_unimplemented;
7128         case 3:
7129             /* Stop translation as we may have switched the execution mode */
7130             ctx->base.is_jmp = DISAS_STOP;
7131 //            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
7132             rn = "UserTraceData";
7133             /* Stop translation as we may have switched the execution mode */
7134             ctx->base.is_jmp = DISAS_STOP;
7135             goto cp0_unimplemented;
7136         case 4:
7137 //            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
7138             /* Stop translation as we may have switched the execution mode */
7139             ctx->base.is_jmp = DISAS_STOP;
7140             rn = "TraceBPC";
7141             goto cp0_unimplemented;
7142         default:
7143             goto cp0_unimplemented;
7144         }
7145         break;
7146     case 24:
7147         switch (sel) {
7148         case 0:
7149             /* EJTAG support */
7150             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7151             rn = "DEPC";
7152             break;
7153         default:
7154             goto cp0_unimplemented;
7155         }
7156         break;
7157     case 25:
7158         switch (sel) {
7159         case 0:
7160             gen_helper_mtc0_performance0(cpu_env, arg);
7161             rn = "Performance0";
7162             break;
7163         case 1:
7164 //            gen_helper_mtc0_performance1(arg);
7165             rn = "Performance1";
7166             goto cp0_unimplemented;
7167         case 2:
7168 //            gen_helper_mtc0_performance2(arg);
7169             rn = "Performance2";
7170             goto cp0_unimplemented;
7171         case 3:
7172 //            gen_helper_mtc0_performance3(arg);
7173             rn = "Performance3";
7174             goto cp0_unimplemented;
7175         case 4:
7176 //            gen_helper_mtc0_performance4(arg);
7177             rn = "Performance4";
7178             goto cp0_unimplemented;
7179         case 5:
7180 //            gen_helper_mtc0_performance5(arg);
7181             rn = "Performance5";
7182             goto cp0_unimplemented;
7183         case 6:
7184 //            gen_helper_mtc0_performance6(arg);
7185             rn = "Performance6";
7186             goto cp0_unimplemented;
7187         case 7:
7188 //            gen_helper_mtc0_performance7(arg);
7189             rn = "Performance7";
7190             goto cp0_unimplemented;
7191         default:
7192             goto cp0_unimplemented;
7193         }
7194        break;
7195     case 26:
7196         switch (sel) {
7197         case 0:
7198             gen_helper_mtc0_errctl(cpu_env, arg);
7199             ctx->base.is_jmp = DISAS_STOP;
7200             rn = "ErrCtl";
7201             break;
7202         default:
7203             goto cp0_unimplemented;
7204         }
7205         break;
7206     case 27:
7207         switch (sel) {
7208         case 0:
7209         case 1:
7210         case 2:
7211         case 3:
7212             /* ignored */
7213             rn = "CacheErr";
7214             break;
7215         default:
7216             goto cp0_unimplemented;
7217         }
7218        break;
7219     case 28:
7220         switch (sel) {
7221         case 0:
7222         case 2:
7223         case 4:
7224         case 6:
7225             gen_helper_mtc0_taglo(cpu_env, arg);
7226             rn = "TagLo";
7227             break;
7228         case 1:
7229         case 3:
7230         case 5:
7231         case 7:
7232             gen_helper_mtc0_datalo(cpu_env, arg);
7233             rn = "DataLo";
7234             break;
7235         default:
7236             goto cp0_unimplemented;
7237         }
7238         break;
7239     case 29:
7240         switch (sel) {
7241         case 0:
7242         case 2:
7243         case 4:
7244         case 6:
7245             gen_helper_mtc0_taghi(cpu_env, arg);
7246             rn = "TagHi";
7247             break;
7248         case 1:
7249         case 3:
7250         case 5:
7251         case 7:
7252             gen_helper_mtc0_datahi(cpu_env, arg);
7253             rn = "DataHi";
7254             break;
7255         default:
7256             rn = "invalid sel";
7257             goto cp0_unimplemented;
7258         }
7259        break;
7260     case 30:
7261         switch (sel) {
7262         case 0:
7263             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7264             rn = "ErrorEPC";
7265             break;
7266         default:
7267             goto cp0_unimplemented;
7268         }
7269         break;
7270     case 31:
7271         switch (sel) {
7272         case 0:
7273             /* EJTAG support */
7274             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7275             rn = "DESAVE";
7276             break;
7277         case 2:
7278         case 3:
7279         case 4:
7280         case 5:
7281         case 6:
7282         case 7:
7283             CP0_CHECK(ctx->kscrexist & (1 << sel));
7284             tcg_gen_st_tl(arg, cpu_env,
7285                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7286             rn = "KScratch";
7287             break;
7288         default:
7289             goto cp0_unimplemented;
7290         }
7291         break;
7292     default:
7293        goto cp0_unimplemented;
7294     }
7295     trace_mips_translate_c0("mtc0", rn, reg, sel);
7296
7297     /* For simplicity assume that all writes can cause interrupts.  */
7298     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7299         gen_io_end();
7300         /* DISAS_STOP isn't sufficient, we need to ensure we break out of
7301          * translated code to check for pending interrupts.  */
7302         gen_save_pc(ctx->base.pc_next + 4);
7303         ctx->base.is_jmp = DISAS_EXIT;
7304     }
7305     return;
7306
7307 cp0_unimplemented:
7308     qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
7309 }
7310
7311 #if defined(TARGET_MIPS64)
7312 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7313 {
7314     const char *rn = "invalid";
7315
7316     if (sel != 0)
7317         check_insn(ctx, ISA_MIPS64);
7318
7319     switch (reg) {
7320     case 0:
7321         switch (sel) {
7322         case 0:
7323             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7324             rn = "Index";
7325             break;
7326         case 1:
7327             CP0_CHECK(ctx->insn_flags & ASE_MT);
7328             gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7329             rn = "MVPControl";
7330             break;
7331         case 2:
7332             CP0_CHECK(ctx->insn_flags & ASE_MT);
7333             gen_helper_mfc0_mvpconf0(arg, cpu_env);
7334             rn = "MVPConf0";
7335             break;
7336         case 3:
7337             CP0_CHECK(ctx->insn_flags & ASE_MT);
7338             gen_helper_mfc0_mvpconf1(arg, cpu_env);
7339             rn = "MVPConf1";
7340             break;
7341         case 4:
7342             CP0_CHECK(ctx->vp);
7343             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
7344             rn = "VPControl";
7345             break;
7346         default:
7347             goto cp0_unimplemented;
7348         }
7349         break;
7350     case 1:
7351         switch (sel) {
7352         case 0:
7353             CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7354             gen_helper_mfc0_random(arg, cpu_env);
7355             rn = "Random";
7356             break;
7357         case 1:
7358             CP0_CHECK(ctx->insn_flags & ASE_MT);
7359             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7360             rn = "VPEControl";
7361             break;
7362         case 2:
7363             CP0_CHECK(ctx->insn_flags & ASE_MT);
7364             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7365             rn = "VPEConf0";
7366             break;
7367         case 3:
7368             CP0_CHECK(ctx->insn_flags & ASE_MT);
7369             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7370             rn = "VPEConf1";
7371             break;
7372         case 4:
7373             CP0_CHECK(ctx->insn_flags & ASE_MT);
7374             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
7375             rn = "YQMask";
7376             break;
7377         case 5:
7378             CP0_CHECK(ctx->insn_flags & ASE_MT);
7379             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
7380             rn = "VPESchedule";
7381             break;
7382         case 6:
7383             CP0_CHECK(ctx->insn_flags & ASE_MT);
7384             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7385             rn = "VPEScheFBack";
7386             break;
7387         case 7:
7388             CP0_CHECK(ctx->insn_flags & ASE_MT);
7389             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7390             rn = "VPEOpt";
7391             break;
7392         default:
7393             goto cp0_unimplemented;
7394         }
7395         break;
7396     case 2:
7397         switch (sel) {
7398         case 0:
7399             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
7400             rn = "EntryLo0";
7401             break;
7402         case 1:
7403             CP0_CHECK(ctx->insn_flags & ASE_MT);
7404             gen_helper_mfc0_tcstatus(arg, cpu_env);
7405             rn = "TCStatus";
7406             break;
7407         case 2:
7408             CP0_CHECK(ctx->insn_flags & ASE_MT);
7409             gen_helper_mfc0_tcbind(arg, cpu_env);
7410             rn = "TCBind";
7411             break;
7412         case 3:
7413             CP0_CHECK(ctx->insn_flags & ASE_MT);
7414             gen_helper_dmfc0_tcrestart(arg, cpu_env);
7415             rn = "TCRestart";
7416             break;
7417         case 4:
7418             CP0_CHECK(ctx->insn_flags & ASE_MT);
7419             gen_helper_dmfc0_tchalt(arg, cpu_env);
7420             rn = "TCHalt";
7421             break;
7422         case 5:
7423             CP0_CHECK(ctx->insn_flags & ASE_MT);
7424             gen_helper_dmfc0_tccontext(arg, cpu_env);
7425             rn = "TCContext";
7426             break;
7427         case 6:
7428             CP0_CHECK(ctx->insn_flags & ASE_MT);
7429             gen_helper_dmfc0_tcschedule(arg, cpu_env);
7430             rn = "TCSchedule";
7431             break;
7432         case 7:
7433             CP0_CHECK(ctx->insn_flags & ASE_MT);
7434             gen_helper_dmfc0_tcschefback(arg, cpu_env);
7435             rn = "TCScheFBack";
7436             break;
7437         default:
7438             goto cp0_unimplemented;
7439         }
7440         break;
7441     case 3:
7442         switch (sel) {
7443         case 0:
7444             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
7445             rn = "EntryLo1";
7446             break;
7447         case 1:
7448             CP0_CHECK(ctx->vp);
7449             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
7450             rn = "GlobalNumber";
7451             break;
7452         default:
7453             goto cp0_unimplemented;
7454         }
7455         break;
7456     case 4:
7457         switch (sel) {
7458         case 0:
7459             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
7460             rn = "Context";
7461             break;
7462         case 1:
7463 //            gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
7464             rn = "ContextConfig";
7465             goto cp0_unimplemented;
7466         case 2:
7467             CP0_CHECK(ctx->ulri);
7468             tcg_gen_ld_tl(arg, cpu_env,
7469                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7470             rn = "UserLocal";
7471             break;
7472         default:
7473             goto cp0_unimplemented;
7474         }
7475         break;
7476     case 5:
7477         switch (sel) {
7478         case 0:
7479             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
7480             rn = "PageMask";
7481             break;
7482         case 1:
7483             check_insn(ctx, ISA_MIPS32R2);
7484             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
7485             rn = "PageGrain";
7486             break;
7487         case 2:
7488             CP0_CHECK(ctx->sc);
7489             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
7490             rn = "SegCtl0";
7491             break;
7492         case 3:
7493             CP0_CHECK(ctx->sc);
7494             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
7495             rn = "SegCtl1";
7496             break;
7497         case 4:
7498             CP0_CHECK(ctx->sc);
7499             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
7500             rn = "SegCtl2";
7501             break;
7502         default:
7503             goto cp0_unimplemented;
7504         }
7505         break;
7506     case 6:
7507         switch (sel) {
7508         case 0:
7509             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
7510             rn = "Wired";
7511             break;
7512         case 1:
7513             check_insn(ctx, ISA_MIPS32R2);
7514             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
7515             rn = "SRSConf0";
7516             break;
7517         case 2:
7518             check_insn(ctx, ISA_MIPS32R2);
7519             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
7520             rn = "SRSConf1";
7521             break;
7522         case 3:
7523             check_insn(ctx, ISA_MIPS32R2);
7524             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
7525             rn = "SRSConf2";
7526             break;
7527         case 4:
7528             check_insn(ctx, ISA_MIPS32R2);
7529             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
7530             rn = "SRSConf3";
7531             break;
7532         case 5:
7533             check_insn(ctx, ISA_MIPS32R2);
7534             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
7535             rn = "SRSConf4";
7536             break;
7537         default:
7538             goto cp0_unimplemented;
7539         }
7540         break;
7541     case 7:
7542         switch (sel) {
7543         case 0:
7544             check_insn(ctx, ISA_MIPS32R2);
7545             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
7546             rn = "HWREna";
7547             break;
7548         default:
7549             goto cp0_unimplemented;
7550         }
7551         break;
7552     case 8:
7553         switch (sel) {
7554         case 0:
7555             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
7556             rn = "BadVAddr";
7557             break;
7558         case 1:
7559             CP0_CHECK(ctx->bi);
7560             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
7561             rn = "BadInstr";
7562             break;
7563         case 2:
7564             CP0_CHECK(ctx->bp);
7565             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
7566             rn = "BadInstrP";
7567             break;
7568         case 3:
7569             CP0_CHECK(ctx->bi);
7570             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
7571             tcg_gen_andi_tl(arg, arg, ~0xffff);
7572             rn = "BadInstrX";
7573             break;
7574         default:
7575             goto cp0_unimplemented;
7576         }
7577         break;
7578     case 9:
7579         switch (sel) {
7580         case 0:
7581             /* Mark as an IO operation because we read the time.  */
7582             if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7583                 gen_io_start();
7584             }
7585             gen_helper_mfc0_count(arg, cpu_env);
7586             if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7587                 gen_io_end();
7588             }
7589             /* Break the TB to be able to take timer interrupts immediately
7590                after reading count. DISAS_STOP isn't sufficient, we need to
7591                ensure we break completely out of translated code.  */
7592             gen_save_pc(ctx->base.pc_next + 4);
7593             ctx->base.is_jmp = DISAS_EXIT;
7594             rn = "Count";
7595             break;
7596         /* 6,7 are implementation dependent */
7597         default:
7598             goto cp0_unimplemented;
7599         }
7600         break;
7601     case 10:
7602         switch (sel) {
7603         case 0:
7604             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
7605             rn = "EntryHi";
7606             break;
7607         default:
7608             goto cp0_unimplemented;
7609         }
7610         break;
7611     case 11:
7612         switch (sel) {
7613         case 0:
7614             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
7615             rn = "Compare";
7616             break;
7617         /* 6,7 are implementation dependent */
7618         default:
7619             goto cp0_unimplemented;
7620         }
7621         break;
7622     case 12:
7623         switch (sel) {
7624         case 0:
7625             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
7626             rn = "Status";
7627             break;
7628         case 1:
7629             check_insn(ctx, ISA_MIPS32R2);
7630             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
7631             rn = "IntCtl";
7632             break;
7633         case 2:
7634             check_insn(ctx, ISA_MIPS32R2);
7635             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
7636             rn = "SRSCtl";
7637             break;
7638         case 3:
7639             check_insn(ctx, ISA_MIPS32R2);
7640             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7641             rn = "SRSMap";
7642             break;
7643         default:
7644             goto cp0_unimplemented;
7645         }
7646         break;
7647     case 13:
7648         switch (sel) {
7649         case 0:
7650             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
7651             rn = "Cause";
7652             break;
7653         default:
7654             goto cp0_unimplemented;
7655         }
7656         break;
7657     case 14:
7658         switch (sel) {
7659         case 0:
7660             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7661             rn = "EPC";
7662             break;
7663         default:
7664             goto cp0_unimplemented;
7665         }
7666         break;
7667     case 15:
7668         switch (sel) {
7669         case 0:
7670             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
7671             rn = "PRid";
7672             break;
7673         case 1:
7674             check_insn(ctx, ISA_MIPS32R2);
7675             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
7676             rn = "EBase";
7677             break;
7678         case 3:
7679             check_insn(ctx, ISA_MIPS32R2);
7680             CP0_CHECK(ctx->cmgcr);
7681             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7682             rn = "CMGCRBase";
7683             break;
7684         default:
7685             goto cp0_unimplemented;
7686         }
7687         break;
7688     case 16:
7689         switch (sel) {
7690         case 0:
7691             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
7692             rn = "Config";
7693             break;
7694         case 1:
7695             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
7696             rn = "Config1";
7697             break;
7698         case 2:
7699             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7700             rn = "Config2";
7701             break;
7702         case 3:
7703             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7704             rn = "Config3";
7705             break;
7706         case 4:
7707             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7708             rn = "Config4";
7709             break;
7710         case 5:
7711             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7712             rn = "Config5";
7713             break;
7714        /* 6,7 are implementation dependent */
7715         case 6:
7716             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
7717             rn = "Config6";
7718             break;
7719         case 7:
7720             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
7721             rn = "Config7";
7722             break;
7723         default:
7724             goto cp0_unimplemented;
7725         }
7726         break;
7727     case 17:
7728         switch (sel) {
7729         case 0:
7730             gen_helper_dmfc0_lladdr(arg, cpu_env);
7731             rn = "LLAddr";
7732             break;
7733         case 1:
7734             CP0_CHECK(ctx->mrp);
7735             gen_helper_dmfc0_maar(arg, cpu_env);
7736             rn = "MAAR";
7737             break;
7738         case 2:
7739             CP0_CHECK(ctx->mrp);
7740             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7741             rn = "MAARI";
7742             break;
7743         default:
7744             goto cp0_unimplemented;
7745         }
7746         break;
7747     case 18:
7748         switch (sel) {
7749         case 0:
7750         case 1:
7751         case 2:
7752         case 3:
7753         case 4:
7754         case 5:
7755         case 6:
7756         case 7:
7757             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7758             gen_helper_1e0i(dmfc0_watchlo, arg, sel);
7759             rn = "WatchLo";
7760             break;
7761         default:
7762             goto cp0_unimplemented;
7763         }
7764         break;
7765     case 19:
7766         switch (sel) {
7767         case 0:
7768         case 1:
7769         case 2:
7770         case 3:
7771         case 4:
7772         case 5:
7773         case 6:
7774         case 7:
7775             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7776             gen_helper_1e0i(mfc0_watchhi, arg, sel);
7777             rn = "WatchHi";
7778             break;
7779         default:
7780             goto cp0_unimplemented;
7781         }
7782         break;
7783     case 20:
7784         switch (sel) {
7785         case 0:
7786             check_insn(ctx, ISA_MIPS3);
7787             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
7788             rn = "XContext";
7789             break;
7790         default:
7791             goto cp0_unimplemented;
7792         }
7793         break;
7794     case 21:
7795        /* Officially reserved, but sel 0 is used for R1x000 framemask */
7796         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7797         switch (sel) {
7798         case 0:
7799             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
7800             rn = "Framemask";
7801             break;
7802         default:
7803             goto cp0_unimplemented;
7804         }
7805         break;
7806     case 22:
7807         tcg_gen_movi_tl(arg, 0); /* unimplemented */
7808         rn = "'Diagnostic"; /* implementation dependent */
7809         break;
7810     case 23:
7811         switch (sel) {
7812         case 0:
7813             gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
7814             rn = "Debug";
7815             break;
7816         case 1:
7817 //            gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
7818             rn = "TraceControl";
7819             goto cp0_unimplemented;
7820         case 2:
7821 //            gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
7822             rn = "TraceControl2";
7823             goto cp0_unimplemented;
7824         case 3:
7825 //            gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
7826             rn = "UserTraceData";
7827             goto cp0_unimplemented;
7828         case 4:
7829 //            gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
7830             rn = "TraceBPC";
7831             goto cp0_unimplemented;
7832         default:
7833             goto cp0_unimplemented;
7834         }
7835         break;
7836     case 24:
7837         switch (sel) {
7838         case 0:
7839             /* EJTAG support */
7840             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7841             rn = "DEPC";
7842             break;
7843         default:
7844             goto cp0_unimplemented;
7845         }
7846         break;
7847     case 25:
7848         switch (sel) {
7849         case 0:
7850             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
7851             rn = "Performance0";
7852             break;
7853         case 1:
7854 //            gen_helper_dmfc0_performance1(arg);
7855             rn = "Performance1";
7856             goto cp0_unimplemented;
7857         case 2:
7858 //            gen_helper_dmfc0_performance2(arg);
7859             rn = "Performance2";
7860             goto cp0_unimplemented;
7861         case 3:
7862 //            gen_helper_dmfc0_performance3(arg);
7863             rn = "Performance3";
7864             goto cp0_unimplemented;
7865         case 4:
7866 //            gen_helper_dmfc0_performance4(arg);
7867             rn = "Performance4";
7868             goto cp0_unimplemented;
7869         case 5:
7870 //            gen_helper_dmfc0_performance5(arg);
7871             rn = "Performance5";
7872             goto cp0_unimplemented;
7873         case 6:
7874 //            gen_helper_dmfc0_performance6(arg);
7875             rn = "Performance6";
7876             goto cp0_unimplemented;
7877         case 7:
7878 //            gen_helper_dmfc0_performance7(arg);
7879             rn = "Performance7";
7880             goto cp0_unimplemented;
7881         default:
7882             goto cp0_unimplemented;
7883         }
7884         break;
7885     case 26:
7886         switch (sel) {
7887         case 0:
7888             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7889             rn = "ErrCtl";
7890             break;
7891         default:
7892             goto cp0_unimplemented;
7893         }
7894         break;
7895     case 27:
7896         switch (sel) {
7897         /* ignored */
7898         case 0:
7899         case 1:
7900         case 2:
7901         case 3:
7902             tcg_gen_movi_tl(arg, 0); /* unimplemented */
7903             rn = "CacheErr";
7904             break;
7905         default:
7906             goto cp0_unimplemented;
7907         }
7908         break;
7909     case 28:
7910         switch (sel) {
7911         case 0:
7912         case 2:
7913         case 4:
7914         case 6:
7915             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
7916             rn = "TagLo";
7917             break;
7918         case 1:
7919         case 3:
7920         case 5:
7921         case 7:
7922             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
7923             rn = "DataLo";
7924             break;
7925         default:
7926             goto cp0_unimplemented;
7927         }
7928         break;
7929     case 29:
7930         switch (sel) {
7931         case 0:
7932         case 2:
7933         case 4:
7934         case 6:
7935             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7936             rn = "TagHi";
7937             break;
7938         case 1:
7939         case 3:
7940         case 5:
7941         case 7:
7942             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7943             rn = "DataHi";
7944             break;
7945         default:
7946             goto cp0_unimplemented;
7947         }
7948         break;
7949     case 30:
7950         switch (sel) {
7951         case 0:
7952             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7953             rn = "ErrorEPC";
7954             break;
7955         default:
7956             goto cp0_unimplemented;
7957         }
7958         break;
7959     case 31:
7960         switch (sel) {
7961         case 0:
7962             /* EJTAG support */
7963             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7964             rn = "DESAVE";
7965             break;
7966         case 2:
7967         case 3:
7968         case 4:
7969         case 5:
7970         case 6:
7971         case 7:
7972             CP0_CHECK(ctx->kscrexist & (1 << sel));
7973             tcg_gen_ld_tl(arg, cpu_env,
7974                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7975             rn = "KScratch";
7976             break;
7977         default:
7978             goto cp0_unimplemented;
7979         }
7980         break;
7981     default:
7982         goto cp0_unimplemented;
7983     }
7984     trace_mips_translate_c0("dmfc0", rn, reg, sel);
7985     return;
7986
7987 cp0_unimplemented:
7988     qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
7989     gen_mfc0_unimplemented(ctx, arg);
7990 }
7991
7992 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7993 {
7994     const char *rn = "invalid";
7995
7996     if (sel != 0)
7997         check_insn(ctx, ISA_MIPS64);
7998
7999     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8000         gen_io_start();
8001     }
8002
8003     switch (reg) {
8004     case 0:
8005         switch (sel) {
8006         case 0:
8007             gen_helper_mtc0_index(cpu_env, arg);
8008             rn = "Index";
8009             break;
8010         case 1:
8011             CP0_CHECK(ctx->insn_flags & ASE_MT);
8012             gen_helper_mtc0_mvpcontrol(cpu_env, arg);
8013             rn = "MVPControl";
8014             break;
8015         case 2:
8016             CP0_CHECK(ctx->insn_flags & ASE_MT);
8017             /* ignored */
8018             rn = "MVPConf0";
8019             break;
8020         case 3:
8021             CP0_CHECK(ctx->insn_flags & ASE_MT);
8022             /* ignored */
8023             rn = "MVPConf1";
8024             break;
8025         case 4:
8026             CP0_CHECK(ctx->vp);
8027             /* ignored */
8028             rn = "VPControl";
8029             break;
8030         default:
8031             goto cp0_unimplemented;
8032         }
8033         break;
8034     case 1:
8035         switch (sel) {
8036         case 0:
8037             /* ignored */
8038             rn = "Random";
8039             break;
8040         case 1:
8041             CP0_CHECK(ctx->insn_flags & ASE_MT);
8042             gen_helper_mtc0_vpecontrol(cpu_env, arg);
8043             rn = "VPEControl";
8044             break;
8045         case 2:
8046             CP0_CHECK(ctx->insn_flags & ASE_MT);
8047             gen_helper_mtc0_vpeconf0(cpu_env, arg);
8048             rn = "VPEConf0";
8049             break;
8050         case 3:
8051             CP0_CHECK(ctx->insn_flags & ASE_MT);
8052             gen_helper_mtc0_vpeconf1(cpu_env, arg);
8053             rn = "VPEConf1";
8054             break;
8055         case 4:
8056             CP0_CHECK(ctx->insn_flags & ASE_MT);
8057             gen_helper_mtc0_yqmask(cpu_env, arg);
8058             rn = "YQMask";
8059             break;
8060         case 5:
8061             CP0_CHECK(ctx->insn_flags & ASE_MT);
8062             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
8063             rn = "VPESchedule";
8064             break;
8065         case 6:
8066             CP0_CHECK(ctx->insn_flags & ASE_MT);
8067             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
8068             rn = "VPEScheFBack";
8069             break;
8070         case 7:
8071             CP0_CHECK(ctx->insn_flags & ASE_MT);
8072             gen_helper_mtc0_vpeopt(cpu_env, arg);
8073             rn = "VPEOpt";
8074             break;
8075         default:
8076             goto cp0_unimplemented;
8077         }
8078         break;
8079     case 2:
8080         switch (sel) {
8081         case 0:
8082             gen_helper_dmtc0_entrylo0(cpu_env, arg);
8083             rn = "EntryLo0";
8084             break;
8085         case 1:
8086             CP0_CHECK(ctx->insn_flags & ASE_MT);
8087             gen_helper_mtc0_tcstatus(cpu_env, arg);
8088             rn = "TCStatus";
8089             break;
8090         case 2:
8091             CP0_CHECK(ctx->insn_flags & ASE_MT);
8092             gen_helper_mtc0_tcbind(cpu_env, arg);
8093             rn = "TCBind";
8094             break;
8095         case 3:
8096             CP0_CHECK(ctx->insn_flags & ASE_MT);
8097             gen_helper_mtc0_tcrestart(cpu_env, arg);
8098             rn = "TCRestart";
8099             break;
8100         case 4:
8101             CP0_CHECK(ctx->insn_flags & ASE_MT);
8102             gen_helper_mtc0_tchalt(cpu_env, arg);
8103             rn = "TCHalt";
8104             break;
8105         case 5:
8106             CP0_CHECK(ctx->insn_flags & ASE_MT);
8107             gen_helper_mtc0_tccontext(cpu_env, arg);
8108             rn = "TCContext";
8109             break;
8110         case 6:
8111             CP0_CHECK(ctx->insn_flags & ASE_MT);
8112             gen_helper_mtc0_tcschedule(cpu_env, arg);
8113             rn = "TCSchedule";
8114             break;
8115         case 7:
8116             CP0_CHECK(ctx->insn_flags & ASE_MT);
8117             gen_helper_mtc0_tcschefback(cpu_env, arg);
8118             rn = "TCScheFBack";
8119             break;
8120         default:
8121             goto cp0_unimplemented;
8122         }
8123         break;
8124     case 3:
8125         switch (sel) {
8126         case 0:
8127             gen_helper_dmtc0_entrylo1(cpu_env, arg);
8128             rn = "EntryLo1";
8129             break;
8130         case 1:
8131             CP0_CHECK(ctx->vp);
8132             /* ignored */
8133             rn = "GlobalNumber";
8134             break;
8135         default:
8136             goto cp0_unimplemented;
8137         }
8138         break;
8139     case 4:
8140         switch (sel) {
8141         case 0:
8142             gen_helper_mtc0_context(cpu_env, arg);
8143             rn = "Context";
8144             break;
8145         case 1:
8146 //           gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
8147             rn = "ContextConfig";
8148             goto cp0_unimplemented;
8149         case 2:
8150             CP0_CHECK(ctx->ulri);
8151             tcg_gen_st_tl(arg, cpu_env,
8152                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8153             rn = "UserLocal";
8154             break;
8155         default:
8156             goto cp0_unimplemented;
8157         }
8158         break;
8159     case 5:
8160         switch (sel) {
8161         case 0:
8162             gen_helper_mtc0_pagemask(cpu_env, arg);
8163             rn = "PageMask";
8164             break;
8165         case 1:
8166             check_insn(ctx, ISA_MIPS32R2);
8167             gen_helper_mtc0_pagegrain(cpu_env, arg);
8168             rn = "PageGrain";
8169             break;
8170         case 2:
8171             CP0_CHECK(ctx->sc);
8172             gen_helper_mtc0_segctl0(cpu_env, arg);
8173             rn = "SegCtl0";
8174             break;
8175         case 3:
8176             CP0_CHECK(ctx->sc);
8177             gen_helper_mtc0_segctl1(cpu_env, arg);
8178             rn = "SegCtl1";
8179             break;
8180         case 4:
8181             CP0_CHECK(ctx->sc);
8182             gen_helper_mtc0_segctl2(cpu_env, arg);
8183             rn = "SegCtl2";
8184             break;
8185         default:
8186             goto cp0_unimplemented;
8187         }
8188         break;
8189     case 6:
8190         switch (sel) {
8191         case 0:
8192             gen_helper_mtc0_wired(cpu_env, arg);
8193             rn = "Wired";
8194             break;
8195         case 1:
8196             check_insn(ctx, ISA_MIPS32R2);
8197             gen_helper_mtc0_srsconf0(cpu_env, arg);
8198             rn = "SRSConf0";
8199             break;
8200         case 2:
8201             check_insn(ctx, ISA_MIPS32R2);
8202             gen_helper_mtc0_srsconf1(cpu_env, arg);
8203             rn = "SRSConf1";
8204             break;
8205         case 3:
8206             check_insn(ctx, ISA_MIPS32R2);
8207             gen_helper_mtc0_srsconf2(cpu_env, arg);
8208             rn = "SRSConf2";
8209             break;
8210         case 4:
8211             check_insn(ctx, ISA_MIPS32R2);
8212             gen_helper_mtc0_srsconf3(cpu_env, arg);
8213             rn = "SRSConf3";
8214             break;
8215         case 5:
8216             check_insn(ctx, ISA_MIPS32R2);
8217             gen_helper_mtc0_srsconf4(cpu_env, arg);
8218             rn = "SRSConf4";
8219             break;
8220         default:
8221             goto cp0_unimplemented;
8222         }
8223         break;
8224     case 7:
8225         switch (sel) {
8226         case 0:
8227             check_insn(ctx, ISA_MIPS32R2);
8228             gen_helper_mtc0_hwrena(cpu_env, arg);
8229             ctx->base.is_jmp = DISAS_STOP;
8230             rn = "HWREna";
8231             break;
8232         default:
8233             goto cp0_unimplemented;
8234         }
8235         break;
8236     case 8:
8237         switch (sel) {
8238         case 0:
8239             /* ignored */
8240             rn = "BadVAddr";
8241             break;
8242         case 1:
8243             /* ignored */
8244             rn = "BadInstr";
8245             break;
8246         case 2:
8247             /* ignored */
8248             rn = "BadInstrP";
8249             break;
8250         case 3:
8251             /* ignored */
8252             rn = "BadInstrX";
8253             break;
8254         default:
8255             goto cp0_unimplemented;
8256         }
8257         break;
8258     case 9:
8259         switch (sel) {
8260         case 0:
8261             gen_helper_mtc0_count(cpu_env, arg);
8262             rn = "Count";
8263             break;
8264         /* 6,7 are implementation dependent */
8265         default:
8266             goto cp0_unimplemented;
8267         }
8268         /* Stop translation as we may have switched the execution mode */
8269         ctx->base.is_jmp = DISAS_STOP;
8270         break;
8271     case 10:
8272         switch (sel) {
8273         case 0:
8274             gen_helper_mtc0_entryhi(cpu_env, arg);
8275             rn = "EntryHi";
8276             break;
8277         default:
8278             goto cp0_unimplemented;
8279         }
8280         break;
8281     case 11:
8282         switch (sel) {
8283         case 0:
8284             gen_helper_mtc0_compare(cpu_env, arg);
8285             rn = "Compare";
8286             break;
8287         /* 6,7 are implementation dependent */
8288         default:
8289             goto cp0_unimplemented;
8290         }
8291         /* Stop translation as we may have switched the execution mode */
8292         ctx->base.is_jmp = DISAS_STOP;
8293         break;
8294     case 12:
8295         switch (sel) {
8296         case 0:
8297             save_cpu_state(ctx, 1);
8298             gen_helper_mtc0_status(cpu_env, arg);
8299             /* DISAS_STOP isn't good enough here, hflags may have changed. */
8300             gen_save_pc(ctx->base.pc_next + 4);
8301             ctx->base.is_jmp = DISAS_EXIT;
8302             rn = "Status";
8303             break;
8304         case 1:
8305             check_insn(ctx, ISA_MIPS32R2);
8306             gen_helper_mtc0_intctl(cpu_env, arg);
8307             /* Stop translation as we may have switched the execution mode */
8308             ctx->base.is_jmp = DISAS_STOP;
8309             rn = "IntCtl";
8310             break;
8311         case 2:
8312             check_insn(ctx, ISA_MIPS32R2);
8313             gen_helper_mtc0_srsctl(cpu_env, arg);
8314             /* Stop translation as we may have switched the execution mode */
8315             ctx->base.is_jmp = DISAS_STOP;
8316             rn = "SRSCtl";
8317             break;
8318         case 3:
8319             check_insn(ctx, ISA_MIPS32R2);
8320             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8321             /* Stop translation as we may have switched the execution mode */
8322             ctx->base.is_jmp = DISAS_STOP;
8323             rn = "SRSMap";
8324             break;
8325         default:
8326             goto cp0_unimplemented;
8327         }
8328         break;
8329     case 13:
8330         switch (sel) {
8331         case 0:
8332             save_cpu_state(ctx, 1);
8333             gen_helper_mtc0_cause(cpu_env, arg);
8334             /* Stop translation as we may have triggered an interrupt.
8335              * DISAS_STOP isn't sufficient, we need to ensure we break out of
8336              * translated code to check for pending interrupts.  */
8337             gen_save_pc(ctx->base.pc_next + 4);
8338             ctx->base.is_jmp = DISAS_EXIT;
8339             rn = "Cause";
8340             break;
8341         default:
8342             goto cp0_unimplemented;
8343         }
8344         break;
8345     case 14:
8346         switch (sel) {
8347         case 0:
8348             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
8349             rn = "EPC";
8350             break;
8351         default:
8352             goto cp0_unimplemented;
8353         }
8354         break;
8355     case 15:
8356         switch (sel) {
8357         case 0:
8358             /* ignored */
8359             rn = "PRid";
8360             break;
8361         case 1:
8362             check_insn(ctx, ISA_MIPS32R2);
8363             gen_helper_mtc0_ebase(cpu_env, arg);
8364             rn = "EBase";
8365             break;
8366         default:
8367             goto cp0_unimplemented;
8368         }
8369         break;
8370     case 16:
8371         switch (sel) {
8372         case 0:
8373             gen_helper_mtc0_config0(cpu_env, arg);
8374             rn = "Config";
8375             /* Stop translation as we may have switched the execution mode */
8376             ctx->base.is_jmp = DISAS_STOP;
8377             break;
8378         case 1:
8379             /* ignored, read only */
8380             rn = "Config1";
8381             break;
8382         case 2:
8383             gen_helper_mtc0_config2(cpu_env, arg);
8384             rn = "Config2";
8385             /* Stop translation as we may have switched the execution mode */
8386             ctx->base.is_jmp = DISAS_STOP;
8387             break;
8388         case 3:
8389             gen_helper_mtc0_config3(cpu_env, arg);
8390             rn = "Config3";
8391             /* Stop translation as we may have switched the execution mode */
8392             ctx->base.is_jmp = DISAS_STOP;
8393             break;
8394         case 4:
8395             /* currently ignored */
8396             rn = "Config4";
8397             break;
8398         case 5:
8399             gen_helper_mtc0_config5(cpu_env, arg);
8400             rn = "Config5";
8401             /* Stop translation as we may have switched the execution mode */
8402             ctx->base.is_jmp = DISAS_STOP;
8403             break;
8404         /* 6,7 are implementation dependent */
8405         default:
8406             rn = "Invalid config selector";
8407             goto cp0_unimplemented;
8408         }
8409         break;
8410     case 17:
8411         switch (sel) {
8412         case 0:
8413             gen_helper_mtc0_lladdr(cpu_env, arg);
8414             rn = "LLAddr";
8415             break;
8416         case 1:
8417             CP0_CHECK(ctx->mrp);
8418             gen_helper_mtc0_maar(cpu_env, arg);
8419             rn = "MAAR";
8420             break;
8421         case 2:
8422             CP0_CHECK(ctx->mrp);
8423             gen_helper_mtc0_maari(cpu_env, arg);
8424             rn = "MAARI";
8425             break;
8426         default:
8427             goto cp0_unimplemented;
8428         }
8429         break;
8430     case 18:
8431         switch (sel) {
8432         case 0:
8433         case 1:
8434         case 2:
8435         case 3:
8436         case 4:
8437         case 5:
8438         case 6:
8439         case 7:
8440             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8441             gen_helper_0e1i(mtc0_watchlo, arg, sel);
8442             rn = "WatchLo";
8443             break;
8444         default:
8445             goto cp0_unimplemented;
8446         }
8447         break;
8448     case 19:
8449         switch (sel) {
8450         case 0:
8451         case 1:
8452         case 2:
8453         case 3:
8454         case 4:
8455         case 5:
8456         case 6:
8457         case 7:
8458             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8459             gen_helper_0e1i(mtc0_watchhi, arg, sel);
8460             rn = "WatchHi";
8461             break;
8462         default:
8463             goto cp0_unimplemented;
8464         }
8465         break;
8466     case 20:
8467         switch (sel) {
8468         case 0:
8469             check_insn(ctx, ISA_MIPS3);
8470             gen_helper_mtc0_xcontext(cpu_env, arg);
8471             rn = "XContext";
8472             break;
8473         default:
8474             goto cp0_unimplemented;
8475         }
8476         break;
8477     case 21:
8478        /* Officially reserved, but sel 0 is used for R1x000 framemask */
8479         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8480         switch (sel) {
8481         case 0:
8482             gen_helper_mtc0_framemask(cpu_env, arg);
8483             rn = "Framemask";
8484             break;
8485         default:
8486             goto cp0_unimplemented;
8487         }
8488         break;
8489     case 22:
8490         /* ignored */
8491         rn = "Diagnostic"; /* implementation dependent */
8492         break;
8493     case 23:
8494         switch (sel) {
8495         case 0:
8496             gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8497             /* DISAS_STOP isn't good enough here, hflags may have changed. */
8498             gen_save_pc(ctx->base.pc_next + 4);
8499             ctx->base.is_jmp = DISAS_EXIT;
8500             rn = "Debug";
8501             break;
8502         case 1:
8503 //            gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8504             /* Stop translation as we may have switched the execution mode */
8505             ctx->base.is_jmp = DISAS_STOP;
8506             rn = "TraceControl";
8507             goto cp0_unimplemented;
8508         case 2:
8509 //            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8510             /* Stop translation as we may have switched the execution mode */
8511             ctx->base.is_jmp = DISAS_STOP;
8512             rn = "TraceControl2";
8513             goto cp0_unimplemented;
8514         case 3:
8515 //            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8516             /* Stop translation as we may have switched the execution mode */
8517             ctx->base.is_jmp = DISAS_STOP;
8518             rn = "UserTraceData";
8519             goto cp0_unimplemented;
8520         case 4:
8521 //            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8522             /* Stop translation as we may have switched the execution mode */
8523             ctx->base.is_jmp = DISAS_STOP;
8524             rn = "TraceBPC";
8525             goto cp0_unimplemented;
8526         default:
8527             goto cp0_unimplemented;
8528         }
8529         break;
8530     case 24:
8531         switch (sel) {
8532         case 0:
8533             /* EJTAG support */
8534             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8535             rn = "DEPC";
8536             break;
8537         default:
8538             goto cp0_unimplemented;
8539         }
8540         break;
8541     case 25:
8542         switch (sel) {
8543         case 0:
8544             gen_helper_mtc0_performance0(cpu_env, arg);
8545             rn = "Performance0";
8546             break;
8547         case 1:
8548 //            gen_helper_mtc0_performance1(cpu_env, arg);
8549             rn = "Performance1";
8550             goto cp0_unimplemented;
8551         case 2:
8552 //            gen_helper_mtc0_performance2(cpu_env, arg);
8553             rn = "Performance2";
8554             goto cp0_unimplemented;
8555         case 3:
8556 //            gen_helper_mtc0_performance3(cpu_env, arg);
8557             rn = "Performance3";
8558             goto cp0_unimplemented;
8559         case 4:
8560 //            gen_helper_mtc0_performance4(cpu_env, arg);
8561             rn = "Performance4";
8562             goto cp0_unimplemented;
8563         case 5:
8564 //            gen_helper_mtc0_performance5(cpu_env, arg);
8565             rn = "Performance5";
8566             goto cp0_unimplemented;
8567         case 6:
8568 //            gen_helper_mtc0_performance6(cpu_env, arg);
8569             rn = "Performance6";
8570             goto cp0_unimplemented;
8571         case 7:
8572 //            gen_helper_mtc0_performance7(cpu_env, arg);
8573             rn = "Performance7";
8574             goto cp0_unimplemented;
8575         default:
8576             goto cp0_unimplemented;
8577         }
8578         break;
8579     case 26:
8580         switch (sel) {
8581         case 0:
8582             gen_helper_mtc0_errctl(cpu_env, arg);
8583             ctx->base.is_jmp = DISAS_STOP;
8584             rn = "ErrCtl";
8585             break;
8586         default:
8587             goto cp0_unimplemented;
8588         }
8589         break;
8590     case 27:
8591         switch (sel) {
8592         case 0:
8593         case 1:
8594         case 2:
8595         case 3:
8596             /* ignored */
8597             rn = "CacheErr";
8598             break;
8599         default:
8600             goto cp0_unimplemented;
8601         }
8602         break;
8603     case 28:
8604         switch (sel) {
8605         case 0:
8606         case 2:
8607         case 4:
8608         case 6:
8609             gen_helper_mtc0_taglo(cpu_env, arg);
8610             rn = "TagLo";
8611             break;
8612         case 1:
8613         case 3:
8614         case 5:
8615         case 7:
8616             gen_helper_mtc0_datalo(cpu_env, arg);
8617             rn = "DataLo";
8618             break;
8619         default:
8620             goto cp0_unimplemented;
8621         }
8622         break;
8623     case 29:
8624         switch (sel) {
8625         case 0:
8626         case 2:
8627         case 4:
8628         case 6:
8629             gen_helper_mtc0_taghi(cpu_env, arg);
8630             rn = "TagHi";
8631             break;
8632         case 1:
8633         case 3:
8634         case 5:
8635         case 7:
8636             gen_helper_mtc0_datahi(cpu_env, arg);
8637             rn = "DataHi";
8638             break;
8639         default:
8640             rn = "invalid sel";
8641             goto cp0_unimplemented;
8642         }
8643         break;
8644     case 30:
8645         switch (sel) {
8646         case 0:
8647             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8648             rn = "ErrorEPC";
8649             break;
8650         default:
8651             goto cp0_unimplemented;
8652         }
8653         break;
8654     case 31:
8655         switch (sel) {
8656         case 0:
8657             /* EJTAG support */
8658             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8659             rn = "DESAVE";
8660             break;
8661         case 2:
8662         case 3:
8663         case 4:
8664         case 5:
8665         case 6:
8666         case 7:
8667             CP0_CHECK(ctx->kscrexist & (1 << sel));
8668             tcg_gen_st_tl(arg, cpu_env,
8669                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8670             rn = "KScratch";
8671             break;
8672         default:
8673             goto cp0_unimplemented;
8674         }
8675         break;
8676     default:
8677         goto cp0_unimplemented;
8678     }
8679     trace_mips_translate_c0("dmtc0", rn, reg, sel);
8680
8681     /* For simplicity assume that all writes can cause interrupts.  */
8682     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8683         gen_io_end();
8684         /* DISAS_STOP isn't sufficient, we need to ensure we break out of
8685          * translated code to check for pending interrupts.  */
8686         gen_save_pc(ctx->base.pc_next + 4);
8687         ctx->base.is_jmp = DISAS_EXIT;
8688     }
8689     return;
8690
8691 cp0_unimplemented:
8692     qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8693 }
8694 #endif /* TARGET_MIPS64 */
8695
8696 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
8697                      int u, int sel, int h)
8698 {
8699     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
8700     TCGv t0 = tcg_temp_local_new();
8701
8702     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
8703         ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8704          (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
8705         tcg_gen_movi_tl(t0, -1);
8706     else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8707              (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
8708         tcg_gen_movi_tl(t0, -1);
8709     else if (u == 0) {
8710         switch (rt) {
8711         case 1:
8712             switch (sel) {
8713             case 1:
8714                 gen_helper_mftc0_vpecontrol(t0, cpu_env);
8715                 break;
8716             case 2:
8717                 gen_helper_mftc0_vpeconf0(t0, cpu_env);
8718                 break;
8719             default:
8720                 goto die;
8721                 break;
8722             }
8723             break;
8724         case 2:
8725             switch (sel) {
8726             case 1:
8727                 gen_helper_mftc0_tcstatus(t0, cpu_env);
8728                 break;
8729             case 2:
8730                 gen_helper_mftc0_tcbind(t0, cpu_env);
8731                 break;
8732             case 3:
8733                 gen_helper_mftc0_tcrestart(t0, cpu_env);
8734                 break;
8735             case 4:
8736                 gen_helper_mftc0_tchalt(t0, cpu_env);
8737                 break;
8738             case 5:
8739                 gen_helper_mftc0_tccontext(t0, cpu_env);
8740                 break;
8741             case 6:
8742                 gen_helper_mftc0_tcschedule(t0, cpu_env);
8743                 break;
8744             case 7:
8745                 gen_helper_mftc0_tcschefback(t0, cpu_env);
8746                 break;
8747             default:
8748                 gen_mfc0(ctx, t0, rt, sel);
8749                 break;
8750             }
8751             break;
8752         case 10:
8753             switch (sel) {
8754             case 0:
8755                 gen_helper_mftc0_entryhi(t0, cpu_env);
8756                 break;
8757             default:
8758                 gen_mfc0(ctx, t0, rt, sel);
8759                 break;
8760             }
8761         case 12:
8762             switch (sel) {
8763             case 0:
8764                 gen_helper_mftc0_status(t0, cpu_env);
8765                 break;
8766             default:
8767                 gen_mfc0(ctx, t0, rt, sel);
8768                 break;
8769             }
8770         case 13:
8771             switch (sel) {
8772             case 0:
8773                 gen_helper_mftc0_cause(t0, cpu_env);
8774                 break;
8775             default:
8776                 goto die;
8777                 break;
8778             }
8779             break;
8780         case 14:
8781             switch (sel) {
8782             case 0:
8783                 gen_helper_mftc0_epc(t0, cpu_env);
8784                 break;
8785             default:
8786                 goto die;
8787                 break;
8788             }
8789             break;
8790         case 15:
8791             switch (sel) {
8792             case 1:
8793                 gen_helper_mftc0_ebase(t0, cpu_env);
8794                 break;
8795             default:
8796                 goto die;
8797                 break;
8798             }
8799             break;
8800         case 16:
8801             switch (sel) {
8802             case 0:
8803             case 1:
8804             case 2:
8805             case 3:
8806             case 4:
8807             case 5:
8808             case 6:
8809             case 7:
8810                 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
8811                 break;
8812             default:
8813                 goto die;
8814                 break;
8815             }
8816             break;
8817         case 23:
8818             switch (sel) {
8819             case 0:
8820                 gen_helper_mftc0_debug(t0, cpu_env);
8821                 break;
8822             default:
8823                 gen_mfc0(ctx, t0, rt, sel);
8824                 break;
8825             }
8826             break;
8827         default:
8828             gen_mfc0(ctx, t0, rt, sel);
8829         }
8830     } else switch (sel) {
8831     /* GPR registers. */
8832     case 0:
8833         gen_helper_1e0i(mftgpr, t0, rt);
8834         break;
8835     /* Auxiliary CPU registers */
8836     case 1:
8837         switch (rt) {
8838         case 0:
8839             gen_helper_1e0i(mftlo, t0, 0);
8840             break;
8841         case 1:
8842             gen_helper_1e0i(mfthi, t0, 0);
8843             break;
8844         case 2:
8845             gen_helper_1e0i(mftacx, t0, 0);
8846             break;
8847         case 4:
8848             gen_helper_1e0i(mftlo, t0, 1);
8849             break;
8850         case 5:
8851             gen_helper_1e0i(mfthi, t0, 1);
8852             break;
8853         case 6:
8854             gen_helper_1e0i(mftacx, t0, 1);
8855             break;
8856         case 8:
8857             gen_helper_1e0i(mftlo, t0, 2);
8858             break;
8859         case 9:
8860             gen_helper_1e0i(mfthi, t0, 2);
8861             break;
8862         case 10:
8863             gen_helper_1e0i(mftacx, t0, 2);
8864             break;
8865         case 12:
8866             gen_helper_1e0i(mftlo, t0, 3);
8867             break;
8868         case 13:
8869             gen_helper_1e0i(mfthi, t0, 3);
8870             break;
8871         case 14:
8872             gen_helper_1e0i(mftacx, t0, 3);
8873             break;
8874         case 16:
8875             gen_helper_mftdsp(t0, cpu_env);
8876             break;
8877         default:
8878             goto die;
8879         }
8880         break;
8881     /* Floating point (COP1). */
8882     case 2:
8883         /* XXX: For now we support only a single FPU context. */
8884         if (h == 0) {
8885             TCGv_i32 fp0 = tcg_temp_new_i32();
8886
8887             gen_load_fpr32(ctx, fp0, rt);
8888             tcg_gen_ext_i32_tl(t0, fp0);
8889             tcg_temp_free_i32(fp0);
8890         } else {
8891             TCGv_i32 fp0 = tcg_temp_new_i32();
8892
8893             gen_load_fpr32h(ctx, fp0, rt);
8894             tcg_gen_ext_i32_tl(t0, fp0);
8895             tcg_temp_free_i32(fp0);
8896         }
8897         break;
8898     case 3:
8899         /* XXX: For now we support only a single FPU context. */
8900         gen_helper_1e0i(cfc1, t0, rt);
8901         break;
8902     /* COP2: Not implemented. */
8903     case 4:
8904     case 5:
8905         /* fall through */
8906     default:
8907         goto die;
8908     }
8909     trace_mips_translate_tr("mftr", rt, u, sel, h);
8910     gen_store_gpr(t0, rd);
8911     tcg_temp_free(t0);
8912     return;
8913
8914 die:
8915     tcg_temp_free(t0);
8916     LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
8917     generate_exception_end(ctx, EXCP_RI);
8918 }
8919
8920 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
8921                      int u, int sel, int h)
8922 {
8923     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
8924     TCGv t0 = tcg_temp_local_new();
8925
8926     gen_load_gpr(t0, rt);
8927     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
8928         ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8929          (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
8930         /* NOP */ ;
8931     else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8932              (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
8933         /* NOP */ ;
8934     else if (u == 0) {
8935         switch (rd) {
8936         case 1:
8937             switch (sel) {
8938             case 1:
8939                 gen_helper_mttc0_vpecontrol(cpu_env, t0);
8940                 break;
8941             case 2:
8942                 gen_helper_mttc0_vpeconf0(cpu_env, t0);
8943                 break;
8944             default:
8945                 goto die;
8946                 break;
8947             }
8948             break;
8949         case 2:
8950             switch (sel) {
8951             case 1:
8952                 gen_helper_mttc0_tcstatus(cpu_env, t0);
8953                 break;
8954             case 2:
8955                 gen_helper_mttc0_tcbind(cpu_env, t0);
8956                 break;
8957             case 3:
8958                 gen_helper_mttc0_tcrestart(cpu_env, t0);
8959                 break;
8960             case 4:
8961                 gen_helper_mttc0_tchalt(cpu_env, t0);
8962                 break;
8963             case 5:
8964                 gen_helper_mttc0_tccontext(cpu_env, t0);
8965                 break;
8966             case 6:
8967                 gen_helper_mttc0_tcschedule(cpu_env, t0);
8968                 break;
8969             case 7:
8970                 gen_helper_mttc0_tcschefback(cpu_env, t0);
8971                 break;
8972             default:
8973                 gen_mtc0(ctx, t0, rd, sel);
8974                 break;
8975             }
8976             break;
8977         case 10:
8978             switch (sel) {
8979             case 0:
8980                 gen_helper_mttc0_entryhi(cpu_env, t0);
8981                 break;
8982             default:
8983                 gen_mtc0(ctx, t0, rd, sel);
8984                 break;
8985             }
8986         case 12:
8987             switch (sel) {
8988             case 0:
8989                 gen_helper_mttc0_status(cpu_env, t0);
8990                 break;
8991             default:
8992                 gen_mtc0(ctx, t0, rd, sel);
8993                 break;
8994             }
8995         case 13:
8996             switch (sel) {
8997             case 0:
8998                 gen_helper_mttc0_cause(cpu_env, t0);
8999                 break;
9000             default:
9001                 goto die;
9002                 break;
9003             }
9004             break;
9005         case 15:
9006             switch (sel) {
9007             case 1:
9008                 gen_helper_mttc0_ebase(cpu_env, t0);
9009                 break;
9010             default:
9011                 goto die;
9012                 break;
9013             }
9014             break;
9015         case 23:
9016             switch (sel) {
9017             case 0:
9018                 gen_helper_mttc0_debug(cpu_env, t0);
9019                 break;
9020             default:
9021                 gen_mtc0(ctx, t0, rd, sel);
9022                 break;
9023             }
9024             break;
9025         default:
9026             gen_mtc0(ctx, t0, rd, sel);
9027         }
9028     } else switch (sel) {
9029     /* GPR registers. */
9030     case 0:
9031         gen_helper_0e1i(mttgpr, t0, rd);
9032         break;
9033     /* Auxiliary CPU registers */
9034     case 1:
9035         switch (rd) {
9036         case 0:
9037             gen_helper_0e1i(mttlo, t0, 0);
9038             break;
9039         case 1:
9040             gen_helper_0e1i(mtthi, t0, 0);
9041             break;
9042         case 2:
9043             gen_helper_0e1i(mttacx, t0, 0);
9044             break;
9045         case 4:
9046             gen_helper_0e1i(mttlo, t0, 1);
9047             break;
9048         case 5:
9049             gen_helper_0e1i(mtthi, t0, 1);
9050             break;
9051         case 6:
9052             gen_helper_0e1i(mttacx, t0, 1);
9053             break;
9054         case 8:
9055             gen_helper_0e1i(mttlo, t0, 2);
9056             break;
9057         case 9:
9058             gen_helper_0e1i(mtthi, t0, 2);
9059             break;
9060         case 10:
9061             gen_helper_0e1i(mttacx, t0, 2);
9062             break;
9063         case 12:
9064             gen_helper_0e1i(mttlo, t0, 3);
9065             break;
9066         case 13:
9067             gen_helper_0e1i(mtthi, t0, 3);
9068             break;
9069         case 14:
9070             gen_helper_0e1i(mttacx, t0, 3);
9071             break;
9072         case 16:
9073             gen_helper_mttdsp(cpu_env, t0);
9074             break;
9075         default:
9076             goto die;
9077         }
9078         break;
9079     /* Floating point (COP1). */
9080     case 2:
9081         /* XXX: For now we support only a single FPU context. */
9082         if (h == 0) {
9083             TCGv_i32 fp0 = tcg_temp_new_i32();
9084
9085             tcg_gen_trunc_tl_i32(fp0, t0);
9086             gen_store_fpr32(ctx, fp0, rd);
9087             tcg_temp_free_i32(fp0);
9088         } else {
9089             TCGv_i32 fp0 = tcg_temp_new_i32();
9090
9091             tcg_gen_trunc_tl_i32(fp0, t0);
9092             gen_store_fpr32h(ctx, fp0, rd);
9093             tcg_temp_free_i32(fp0);
9094         }
9095         break;
9096     case 3:
9097         /* XXX: For now we support only a single FPU context. */
9098         {
9099             TCGv_i32 fs_tmp = tcg_const_i32(rd);
9100
9101             gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
9102             tcg_temp_free_i32(fs_tmp);
9103         }
9104         /* Stop translation as we may have changed hflags */
9105         ctx->base.is_jmp = DISAS_STOP;
9106         break;
9107     /* COP2: Not implemented. */
9108     case 4:
9109     case 5:
9110         /* fall through */
9111     default:
9112         goto die;
9113     }
9114     trace_mips_translate_tr("mttr", rd, u, sel, h);
9115     tcg_temp_free(t0);
9116     return;
9117
9118 die:
9119     tcg_temp_free(t0);
9120     LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
9121     generate_exception_end(ctx, EXCP_RI);
9122 }
9123
9124 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
9125 {
9126     const char *opn = "ldst";
9127
9128     check_cp0_enabled(ctx);
9129     switch (opc) {
9130     case OPC_MFC0:
9131         if (rt == 0) {
9132             /* Treat as NOP. */
9133             return;
9134         }
9135         gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9136         opn = "mfc0";
9137         break;
9138     case OPC_MTC0:
9139         {
9140             TCGv t0 = tcg_temp_new();
9141
9142             gen_load_gpr(t0, rt);
9143             gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
9144             tcg_temp_free(t0);
9145         }
9146         opn = "mtc0";
9147         break;
9148 #if defined(TARGET_MIPS64)
9149     case OPC_DMFC0:
9150         check_insn(ctx, ISA_MIPS3);
9151         if (rt == 0) {
9152             /* Treat as NOP. */
9153             return;
9154         }
9155         gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9156         opn = "dmfc0";
9157         break;
9158     case OPC_DMTC0:
9159         check_insn(ctx, ISA_MIPS3);
9160         {
9161             TCGv t0 = tcg_temp_new();
9162
9163             gen_load_gpr(t0, rt);
9164             gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
9165             tcg_temp_free(t0);
9166         }
9167         opn = "dmtc0";
9168         break;
9169 #endif
9170     case OPC_MFHC0:
9171         check_mvh(ctx);
9172         if (rt == 0) {
9173             /* Treat as NOP. */
9174             return;
9175         }
9176         gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9177         opn = "mfhc0";
9178         break;
9179     case OPC_MTHC0:
9180         check_mvh(ctx);
9181         {
9182             TCGv t0 = tcg_temp_new();
9183             gen_load_gpr(t0, rt);
9184             gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
9185             tcg_temp_free(t0);
9186         }
9187         opn = "mthc0";
9188         break;
9189     case OPC_MFTR:
9190         check_cp0_enabled(ctx);
9191         if (rd == 0) {
9192             /* Treat as NOP. */
9193             return;
9194         }
9195         gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
9196                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9197         opn = "mftr";
9198         break;
9199     case OPC_MTTR:
9200         check_cp0_enabled(ctx);
9201         gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
9202                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9203         opn = "mttr";
9204         break;
9205     case OPC_TLBWI:
9206         opn = "tlbwi";
9207         if (!env->tlb->helper_tlbwi)
9208             goto die;
9209         gen_helper_tlbwi(cpu_env);
9210         break;
9211     case OPC_TLBINV:
9212         opn = "tlbinv";
9213         if (ctx->ie >= 2) {
9214             if (!env->tlb->helper_tlbinv) {
9215                 goto die;
9216             }
9217             gen_helper_tlbinv(cpu_env);
9218         } /* treat as nop if TLBINV not supported */
9219         break;
9220     case OPC_TLBINVF:
9221         opn = "tlbinvf";
9222         if (ctx->ie >= 2) {
9223             if (!env->tlb->helper_tlbinvf) {
9224                 goto die;
9225             }
9226             gen_helper_tlbinvf(cpu_env);
9227         } /* treat as nop if TLBINV not supported */
9228         break;
9229     case OPC_TLBWR:
9230         opn = "tlbwr";
9231         if (!env->tlb->helper_tlbwr)
9232             goto die;
9233         gen_helper_tlbwr(cpu_env);
9234         break;
9235     case OPC_TLBP:
9236         opn = "tlbp";
9237         if (!env->tlb->helper_tlbp)
9238             goto die;
9239         gen_helper_tlbp(cpu_env);
9240         break;
9241     case OPC_TLBR:
9242         opn = "tlbr";
9243         if (!env->tlb->helper_tlbr)
9244             goto die;
9245         gen_helper_tlbr(cpu_env);
9246         break;
9247     case OPC_ERET: /* OPC_ERETNC */
9248         if ((ctx->insn_flags & ISA_MIPS32R6) &&
9249             (ctx->hflags & MIPS_HFLAG_BMASK)) {
9250             goto die;
9251         } else {
9252             int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
9253             if (ctx->opcode & (1 << bit_shift)) {
9254                 /* OPC_ERETNC */
9255                 opn = "eretnc";
9256                 check_insn(ctx, ISA_MIPS32R5);
9257                 gen_helper_eretnc(cpu_env);
9258             } else {
9259                 /* OPC_ERET */
9260                 opn = "eret";
9261                 check_insn(ctx, ISA_MIPS2);
9262                 gen_helper_eret(cpu_env);
9263             }
9264             ctx->base.is_jmp = DISAS_EXIT;
9265         }
9266         break;
9267     case OPC_DERET:
9268         opn = "deret";
9269         check_insn(ctx, ISA_MIPS32);
9270         if ((ctx->insn_flags & ISA_MIPS32R6) &&
9271             (ctx->hflags & MIPS_HFLAG_BMASK)) {
9272             goto die;
9273         }
9274         if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9275             MIPS_INVAL(opn);
9276             generate_exception_end(ctx, EXCP_RI);
9277         } else {
9278             gen_helper_deret(cpu_env);
9279             ctx->base.is_jmp = DISAS_EXIT;
9280         }
9281         break;
9282     case OPC_WAIT:
9283         opn = "wait";
9284         check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
9285         if ((ctx->insn_flags & ISA_MIPS32R6) &&
9286             (ctx->hflags & MIPS_HFLAG_BMASK)) {
9287             goto die;
9288         }
9289         /* If we get an exception, we want to restart at next instruction */
9290         ctx->base.pc_next += 4;
9291         save_cpu_state(ctx, 1);
9292         ctx->base.pc_next -= 4;
9293         gen_helper_wait(cpu_env);
9294         ctx->base.is_jmp = DISAS_NORETURN;
9295         break;
9296     default:
9297  die:
9298         MIPS_INVAL(opn);
9299         generate_exception_end(ctx, EXCP_RI);
9300         return;
9301     }
9302     (void)opn; /* avoid a compiler warning */
9303 }
9304 #endif /* !CONFIG_USER_ONLY */
9305
9306 /* CP1 Branches (before delay slot) */
9307 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
9308                                 int32_t cc, int32_t offset)
9309 {
9310     target_ulong btarget;
9311     TCGv_i32 t0 = tcg_temp_new_i32();
9312
9313     if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9314         generate_exception_end(ctx, EXCP_RI);
9315         goto out;
9316     }
9317
9318     if (cc != 0)
9319         check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
9320
9321     btarget = ctx->base.pc_next + 4 + offset;
9322
9323     switch (op) {
9324     case OPC_BC1F:
9325         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9326         tcg_gen_not_i32(t0, t0);
9327         tcg_gen_andi_i32(t0, t0, 1);
9328         tcg_gen_extu_i32_tl(bcond, t0);
9329         goto not_likely;
9330     case OPC_BC1FL:
9331         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9332         tcg_gen_not_i32(t0, t0);
9333         tcg_gen_andi_i32(t0, t0, 1);
9334         tcg_gen_extu_i32_tl(bcond, t0);
9335         goto likely;
9336     case OPC_BC1T:
9337         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9338         tcg_gen_andi_i32(t0, t0, 1);
9339         tcg_gen_extu_i32_tl(bcond, t0);
9340         goto not_likely;
9341     case OPC_BC1TL:
9342         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9343         tcg_gen_andi_i32(t0, t0, 1);
9344         tcg_gen_extu_i32_tl(bcond, t0);
9345     likely:
9346         ctx->hflags |= MIPS_HFLAG_BL;
9347         break;
9348     case OPC_BC1FANY2:
9349         {
9350             TCGv_i32 t1 = tcg_temp_new_i32();
9351             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9352             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
9353             tcg_gen_nand_i32(t0, t0, t1);
9354             tcg_temp_free_i32(t1);
9355             tcg_gen_andi_i32(t0, t0, 1);
9356             tcg_gen_extu_i32_tl(bcond, t0);
9357         }
9358         goto not_likely;
9359     case OPC_BC1TANY2:
9360         {
9361             TCGv_i32 t1 = tcg_temp_new_i32();
9362             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9363             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
9364             tcg_gen_or_i32(t0, t0, t1);
9365             tcg_temp_free_i32(t1);
9366             tcg_gen_andi_i32(t0, t0, 1);
9367             tcg_gen_extu_i32_tl(bcond, t0);
9368         }
9369         goto not_likely;
9370     case OPC_BC1FANY4:
9371         {
9372             TCGv_i32 t1 = tcg_temp_new_i32();
9373             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9374             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
9375             tcg_gen_and_i32(t0, t0, t1);
9376             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
9377             tcg_gen_and_i32(t0, t0, t1);
9378             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
9379             tcg_gen_nand_i32(t0, t0, t1);
9380             tcg_temp_free_i32(t1);
9381             tcg_gen_andi_i32(t0, t0, 1);
9382             tcg_gen_extu_i32_tl(bcond, t0);
9383         }
9384         goto not_likely;
9385     case OPC_BC1TANY4:
9386         {
9387             TCGv_i32 t1 = tcg_temp_new_i32();
9388             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9389             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
9390             tcg_gen_or_i32(t0, t0, t1);
9391             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
9392             tcg_gen_or_i32(t0, t0, t1);
9393             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
9394             tcg_gen_or_i32(t0, t0, t1);
9395             tcg_temp_free_i32(t1);
9396             tcg_gen_andi_i32(t0, t0, 1);
9397             tcg_gen_extu_i32_tl(bcond, t0);
9398         }
9399     not_likely:
9400         ctx->hflags |= MIPS_HFLAG_BC;
9401         break;
9402     default:
9403         MIPS_INVAL("cp1 cond branch");
9404         generate_exception_end(ctx, EXCP_RI);
9405         goto out;
9406     }
9407     ctx->btarget = btarget;
9408     ctx->hflags |= MIPS_HFLAG_BDS32;
9409  out:
9410     tcg_temp_free_i32(t0);
9411 }
9412
9413 /* R6 CP1 Branches */
9414 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
9415                                    int32_t ft, int32_t offset,
9416                                    int delayslot_size)
9417 {
9418     target_ulong btarget;
9419     TCGv_i64 t0 = tcg_temp_new_i64();
9420
9421     if (ctx->hflags & MIPS_HFLAG_BMASK) {
9422 #ifdef MIPS_DEBUG_DISAS
9423         LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
9424                   "\n", ctx->base.pc_next);
9425 #endif
9426         generate_exception_end(ctx, EXCP_RI);
9427         goto out;
9428     }
9429
9430     gen_load_fpr64(ctx, t0, ft);
9431     tcg_gen_andi_i64(t0, t0, 1);
9432
9433     btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
9434
9435     switch (op) {
9436     case OPC_BC1EQZ:
9437         tcg_gen_xori_i64(t0, t0, 1);
9438         ctx->hflags |= MIPS_HFLAG_BC;
9439         break;
9440     case OPC_BC1NEZ:
9441         /* t0 already set */
9442         ctx->hflags |= MIPS_HFLAG_BC;
9443         break;
9444     default:
9445         MIPS_INVAL("cp1 cond branch");
9446         generate_exception_end(ctx, EXCP_RI);
9447         goto out;
9448     }
9449
9450     tcg_gen_trunc_i64_tl(bcond, t0);
9451
9452     ctx->btarget = btarget;
9453
9454     switch (delayslot_size) {
9455     case 2:
9456         ctx->hflags |= MIPS_HFLAG_BDS16;
9457         break;
9458     case 4:
9459         ctx->hflags |= MIPS_HFLAG_BDS32;
9460         break;
9461     }
9462
9463 out:
9464     tcg_temp_free_i64(t0);
9465 }
9466
9467 /* Coprocessor 1 (FPU) */
9468
9469 #define FOP(func, fmt) (((fmt) << 21) | (func))
9470
9471 enum fopcode {
9472     OPC_ADD_S = FOP(0, FMT_S),
9473     OPC_SUB_S = FOP(1, FMT_S),
9474     OPC_MUL_S = FOP(2, FMT_S),
9475     OPC_DIV_S = FOP(3, FMT_S),
9476     OPC_SQRT_S = FOP(4, FMT_S),
9477     OPC_ABS_S = FOP(5, FMT_S),
9478     OPC_MOV_S = FOP(6, FMT_S),
9479     OPC_NEG_S = FOP(7, FMT_S),
9480     OPC_ROUND_L_S = FOP(8, FMT_S),
9481     OPC_TRUNC_L_S = FOP(9, FMT_S),
9482     OPC_CEIL_L_S = FOP(10, FMT_S),
9483     OPC_FLOOR_L_S = FOP(11, FMT_S),
9484     OPC_ROUND_W_S = FOP(12, FMT_S),
9485     OPC_TRUNC_W_S = FOP(13, FMT_S),
9486     OPC_CEIL_W_S = FOP(14, FMT_S),
9487     OPC_FLOOR_W_S = FOP(15, FMT_S),
9488     OPC_SEL_S = FOP(16, FMT_S),
9489     OPC_MOVCF_S = FOP(17, FMT_S),
9490     OPC_MOVZ_S = FOP(18, FMT_S),
9491     OPC_MOVN_S = FOP(19, FMT_S),
9492     OPC_SELEQZ_S = FOP(20, FMT_S),
9493     OPC_RECIP_S = FOP(21, FMT_S),
9494     OPC_RSQRT_S = FOP(22, FMT_S),
9495     OPC_SELNEZ_S = FOP(23, FMT_S),
9496     OPC_MADDF_S = FOP(24, FMT_S),
9497     OPC_MSUBF_S = FOP(25, FMT_S),
9498     OPC_RINT_S = FOP(26, FMT_S),
9499     OPC_CLASS_S = FOP(27, FMT_S),
9500     OPC_MIN_S = FOP(28, FMT_S),
9501     OPC_RECIP2_S = FOP(28, FMT_S),
9502     OPC_MINA_S = FOP(29, FMT_S),
9503     OPC_RECIP1_S = FOP(29, FMT_S),
9504     OPC_MAX_S = FOP(30, FMT_S),
9505     OPC_RSQRT1_S = FOP(30, FMT_S),
9506     OPC_MAXA_S = FOP(31, FMT_S),
9507     OPC_RSQRT2_S = FOP(31, FMT_S),
9508     OPC_CVT_D_S = FOP(33, FMT_S),
9509     OPC_CVT_W_S = FOP(36, FMT_S),
9510     OPC_CVT_L_S = FOP(37, FMT_S),
9511     OPC_CVT_PS_S = FOP(38, FMT_S),
9512     OPC_CMP_F_S = FOP (48, FMT_S),
9513     OPC_CMP_UN_S = FOP (49, FMT_S),
9514     OPC_CMP_EQ_S = FOP (50, FMT_S),
9515     OPC_CMP_UEQ_S = FOP (51, FMT_S),
9516     OPC_CMP_OLT_S = FOP (52, FMT_S),
9517     OPC_CMP_ULT_S = FOP (53, FMT_S),
9518     OPC_CMP_OLE_S = FOP (54, FMT_S),
9519     OPC_CMP_ULE_S = FOP (55, FMT_S),
9520     OPC_CMP_SF_S = FOP (56, FMT_S),
9521     OPC_CMP_NGLE_S = FOP (57, FMT_S),
9522     OPC_CMP_SEQ_S = FOP (58, FMT_S),
9523     OPC_CMP_NGL_S = FOP (59, FMT_S),
9524     OPC_CMP_LT_S = FOP (60, FMT_S),
9525     OPC_CMP_NGE_S = FOP (61, FMT_S),
9526     OPC_CMP_LE_S = FOP (62, FMT_S),
9527     OPC_CMP_NGT_S = FOP (63, FMT_S),
9528
9529     OPC_ADD_D = FOP(0, FMT_D),
9530     OPC_SUB_D = FOP(1, FMT_D),
9531     OPC_MUL_D = FOP(2, FMT_D),
9532     OPC_DIV_D = FOP(3, FMT_D),
9533     OPC_SQRT_D = FOP(4, FMT_D),
9534     OPC_ABS_D = FOP(5, FMT_D),
9535     OPC_MOV_D = FOP(6, FMT_D),
9536     OPC_NEG_D = FOP(7, FMT_D),
9537     OPC_ROUND_L_D = FOP(8, FMT_D),
9538     OPC_TRUNC_L_D = FOP(9, FMT_D),
9539     OPC_CEIL_L_D = FOP(10, FMT_D),
9540     OPC_FLOOR_L_D = FOP(11, FMT_D),
9541     OPC_ROUND_W_D = FOP(12, FMT_D),
9542     OPC_TRUNC_W_D = FOP(13, FMT_D),
9543     OPC_CEIL_W_D = FOP(14, FMT_D),
9544     OPC_FLOOR_W_D = FOP(15, FMT_D),
9545     OPC_SEL_D = FOP(16, FMT_D),
9546     OPC_MOVCF_D = FOP(17, FMT_D),
9547     OPC_MOVZ_D = FOP(18, FMT_D),
9548     OPC_MOVN_D = FOP(19, FMT_D),
9549     OPC_SELEQZ_D = FOP(20, FMT_D),
9550     OPC_RECIP_D = FOP(21, FMT_D),
9551     OPC_RSQRT_D = FOP(22, FMT_D),
9552     OPC_SELNEZ_D = FOP(23, FMT_D),
9553     OPC_MADDF_D = FOP(24, FMT_D),
9554     OPC_MSUBF_D = FOP(25, FMT_D),
9555     OPC_RINT_D = FOP(26, FMT_D),
9556     OPC_CLASS_D = FOP(27, FMT_D),
9557     OPC_MIN_D = FOP(28, FMT_D),
9558     OPC_RECIP2_D = FOP(28, FMT_D),
9559     OPC_MINA_D = FOP(29, FMT_D),
9560     OPC_RECIP1_D = FOP(29, FMT_D),
9561     OPC_MAX_D = FOP(30, FMT_D),
9562     OPC_RSQRT1_D = FOP(30, FMT_D),
9563     OPC_MAXA_D = FOP(31, FMT_D),
9564     OPC_RSQRT2_D = FOP(31, FMT_D),
9565     OPC_CVT_S_D = FOP(32, FMT_D),
9566     OPC_CVT_W_D = FOP(36, FMT_D),
9567     OPC_CVT_L_D = FOP(37, FMT_D),
9568     OPC_CMP_F_D = FOP (48, FMT_D),
9569     OPC_CMP_UN_D = FOP (49, FMT_D),
9570     OPC_CMP_EQ_D = FOP (50, FMT_D),
9571     OPC_CMP_UEQ_D = FOP (51, FMT_D),
9572     OPC_CMP_OLT_D = FOP (52, FMT_D),
9573     OPC_CMP_ULT_D = FOP (53, FMT_D),
9574     OPC_CMP_OLE_D = FOP (54, FMT_D),
9575     OPC_CMP_ULE_D = FOP (55, FMT_D),
9576     OPC_CMP_SF_D = FOP (56, FMT_D),
9577     OPC_CMP_NGLE_D = FOP (57, FMT_D),
9578     OPC_CMP_SEQ_D = FOP (58, FMT_D),
9579     OPC_CMP_NGL_D = FOP (59, FMT_D),
9580     OPC_CMP_LT_D = FOP (60, FMT_D),
9581     OPC_CMP_NGE_D = FOP (61, FMT_D),
9582     OPC_CMP_LE_D = FOP (62, FMT_D),
9583     OPC_CMP_NGT_D = FOP (63, FMT_D),
9584
9585     OPC_CVT_S_W = FOP(32, FMT_W),
9586     OPC_CVT_D_W = FOP(33, FMT_W),
9587     OPC_CVT_S_L = FOP(32, FMT_L),
9588     OPC_CVT_D_L = FOP(33, FMT_L),
9589     OPC_CVT_PS_PW = FOP(38, FMT_W),
9590
9591     OPC_ADD_PS = FOP(0, FMT_PS),
9592     OPC_SUB_PS = FOP(1, FMT_PS),
9593     OPC_MUL_PS = FOP(2, FMT_PS),
9594     OPC_DIV_PS = FOP(3, FMT_PS),
9595     OPC_ABS_PS = FOP(5, FMT_PS),
9596     OPC_MOV_PS = FOP(6, FMT_PS),
9597     OPC_NEG_PS = FOP(7, FMT_PS),
9598     OPC_MOVCF_PS = FOP(17, FMT_PS),
9599     OPC_MOVZ_PS = FOP(18, FMT_PS),
9600     OPC_MOVN_PS = FOP(19, FMT_PS),
9601     OPC_ADDR_PS = FOP(24, FMT_PS),
9602     OPC_MULR_PS = FOP(26, FMT_PS),
9603     OPC_RECIP2_PS = FOP(28, FMT_PS),
9604     OPC_RECIP1_PS = FOP(29, FMT_PS),
9605     OPC_RSQRT1_PS = FOP(30, FMT_PS),
9606     OPC_RSQRT2_PS = FOP(31, FMT_PS),
9607
9608     OPC_CVT_S_PU = FOP(32, FMT_PS),
9609     OPC_CVT_PW_PS = FOP(36, FMT_PS),
9610     OPC_CVT_S_PL = FOP(40, FMT_PS),
9611     OPC_PLL_PS = FOP(44, FMT_PS),
9612     OPC_PLU_PS = FOP(45, FMT_PS),
9613     OPC_PUL_PS = FOP(46, FMT_PS),
9614     OPC_PUU_PS = FOP(47, FMT_PS),
9615     OPC_CMP_F_PS = FOP (48, FMT_PS),
9616     OPC_CMP_UN_PS = FOP (49, FMT_PS),
9617     OPC_CMP_EQ_PS = FOP (50, FMT_PS),
9618     OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
9619     OPC_CMP_OLT_PS = FOP (52, FMT_PS),
9620     OPC_CMP_ULT_PS = FOP (53, FMT_PS),
9621     OPC_CMP_OLE_PS = FOP (54, FMT_PS),
9622     OPC_CMP_ULE_PS = FOP (55, FMT_PS),
9623     OPC_CMP_SF_PS = FOP (56, FMT_PS),
9624     OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
9625     OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
9626     OPC_CMP_NGL_PS = FOP (59, FMT_PS),
9627     OPC_CMP_LT_PS = FOP (60, FMT_PS),
9628     OPC_CMP_NGE_PS = FOP (61, FMT_PS),
9629     OPC_CMP_LE_PS = FOP (62, FMT_PS),
9630     OPC_CMP_NGT_PS = FOP (63, FMT_PS),
9631 };
9632
9633 enum r6_f_cmp_op {
9634     R6_OPC_CMP_AF_S   = FOP(0, FMT_W),
9635     R6_OPC_CMP_UN_S   = FOP(1, FMT_W),
9636     R6_OPC_CMP_EQ_S   = FOP(2, FMT_W),
9637     R6_OPC_CMP_UEQ_S  = FOP(3, FMT_W),
9638     R6_OPC_CMP_LT_S   = FOP(4, FMT_W),
9639     R6_OPC_CMP_ULT_S  = FOP(5, FMT_W),
9640     R6_OPC_CMP_LE_S   = FOP(6, FMT_W),
9641     R6_OPC_CMP_ULE_S  = FOP(7, FMT_W),
9642     R6_OPC_CMP_SAF_S  = FOP(8, FMT_W),
9643     R6_OPC_CMP_SUN_S  = FOP(9, FMT_W),
9644     R6_OPC_CMP_SEQ_S  = FOP(10, FMT_W),
9645     R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
9646     R6_OPC_CMP_SLT_S  = FOP(12, FMT_W),
9647     R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
9648     R6_OPC_CMP_SLE_S  = FOP(14, FMT_W),
9649     R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
9650     R6_OPC_CMP_OR_S   = FOP(17, FMT_W),
9651     R6_OPC_CMP_UNE_S  = FOP(18, FMT_W),
9652     R6_OPC_CMP_NE_S   = FOP(19, FMT_W),
9653     R6_OPC_CMP_SOR_S  = FOP(25, FMT_W),
9654     R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
9655     R6_OPC_CMP_SNE_S  = FOP(27, FMT_W),
9656
9657     R6_OPC_CMP_AF_D   = FOP(0, FMT_L),
9658     R6_OPC_CMP_UN_D   = FOP(1, FMT_L),
9659     R6_OPC_CMP_EQ_D   = FOP(2, FMT_L),
9660     R6_OPC_CMP_UEQ_D  = FOP(3, FMT_L),
9661     R6_OPC_CMP_LT_D   = FOP(4, FMT_L),
9662     R6_OPC_CMP_ULT_D  = FOP(5, FMT_L),
9663     R6_OPC_CMP_LE_D   = FOP(6, FMT_L),
9664     R6_OPC_CMP_ULE_D  = FOP(7, FMT_L),
9665     R6_OPC_CMP_SAF_D  = FOP(8, FMT_L),
9666     R6_OPC_CMP_SUN_D  = FOP(9, FMT_L),
9667     R6_OPC_CMP_SEQ_D  = FOP(10, FMT_L),
9668     R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
9669     R6_OPC_CMP_SLT_D  = FOP(12, FMT_L),
9670     R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
9671     R6_OPC_CMP_SLE_D  = FOP(14, FMT_L),
9672     R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
9673     R6_OPC_CMP_OR_D   = FOP(17, FMT_L),
9674     R6_OPC_CMP_UNE_D  = FOP(18, FMT_L),
9675     R6_OPC_CMP_NE_D   = FOP(19, FMT_L),
9676     R6_OPC_CMP_SOR_D  = FOP(25, FMT_L),
9677     R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
9678     R6_OPC_CMP_SNE_D  = FOP(27, FMT_L),
9679 };
9680 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
9681 {
9682     TCGv t0 = tcg_temp_new();
9683
9684     switch (opc) {
9685     case OPC_MFC1:
9686         {
9687             TCGv_i32 fp0 = tcg_temp_new_i32();
9688
9689             gen_load_fpr32(ctx, fp0, fs);
9690             tcg_gen_ext_i32_tl(t0, fp0);
9691             tcg_temp_free_i32(fp0);
9692         }
9693         gen_store_gpr(t0, rt);
9694         break;
9695     case OPC_MTC1:
9696         gen_load_gpr(t0, rt);
9697         {
9698             TCGv_i32 fp0 = tcg_temp_new_i32();
9699
9700             tcg_gen_trunc_tl_i32(fp0, t0);
9701             gen_store_fpr32(ctx, fp0, fs);
9702             tcg_temp_free_i32(fp0);
9703         }
9704         break;
9705     case OPC_CFC1:
9706         gen_helper_1e0i(cfc1, t0, fs);
9707         gen_store_gpr(t0, rt);
9708         break;
9709     case OPC_CTC1:
9710         gen_load_gpr(t0, rt);
9711         save_cpu_state(ctx, 0);
9712         {
9713             TCGv_i32 fs_tmp = tcg_const_i32(fs);
9714
9715             gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
9716             tcg_temp_free_i32(fs_tmp);
9717         }
9718         /* Stop translation as we may have changed hflags */
9719         ctx->base.is_jmp = DISAS_STOP;
9720         break;
9721 #if defined(TARGET_MIPS64)
9722     case OPC_DMFC1:
9723         gen_load_fpr64(ctx, t0, fs);
9724         gen_store_gpr(t0, rt);
9725         break;
9726     case OPC_DMTC1:
9727         gen_load_gpr(t0, rt);
9728         gen_store_fpr64(ctx, t0, fs);
9729         break;
9730 #endif
9731     case OPC_MFHC1:
9732         {
9733             TCGv_i32 fp0 = tcg_temp_new_i32();
9734
9735             gen_load_fpr32h(ctx, fp0, fs);
9736             tcg_gen_ext_i32_tl(t0, fp0);
9737             tcg_temp_free_i32(fp0);
9738         }
9739         gen_store_gpr(t0, rt);
9740         break;
9741     case OPC_MTHC1:
9742         gen_load_gpr(t0, rt);
9743         {
9744             TCGv_i32 fp0 = tcg_temp_new_i32();
9745
9746             tcg_gen_trunc_tl_i32(fp0, t0);
9747             gen_store_fpr32h(ctx, fp0, fs);
9748             tcg_temp_free_i32(fp0);
9749         }
9750         break;
9751     default:
9752         MIPS_INVAL("cp1 move");
9753         generate_exception_end(ctx, EXCP_RI);
9754         goto out;
9755     }
9756
9757  out:
9758     tcg_temp_free(t0);
9759 }
9760
9761 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
9762 {
9763     TCGLabel *l1;
9764     TCGCond cond;
9765     TCGv_i32 t0;
9766
9767     if (rd == 0) {
9768         /* Treat as NOP. */
9769         return;
9770     }
9771
9772     if (tf)
9773         cond = TCG_COND_EQ;
9774     else
9775         cond = TCG_COND_NE;
9776
9777     l1 = gen_new_label();
9778     t0 = tcg_temp_new_i32();
9779     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9780     tcg_gen_brcondi_i32(cond, t0, 0, l1);
9781     tcg_temp_free_i32(t0);
9782     if (rs == 0) {
9783         tcg_gen_movi_tl(cpu_gpr[rd], 0);
9784     } else {
9785         tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
9786     }
9787     gen_set_label(l1);
9788 }
9789
9790 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
9791                                int tf)
9792 {
9793     int cond;
9794     TCGv_i32 t0 = tcg_temp_new_i32();
9795     TCGLabel *l1 = gen_new_label();
9796
9797     if (tf)
9798         cond = TCG_COND_EQ;
9799     else
9800         cond = TCG_COND_NE;
9801
9802     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9803     tcg_gen_brcondi_i32(cond, t0, 0, l1);
9804     gen_load_fpr32(ctx, t0, fs);
9805     gen_store_fpr32(ctx, t0, fd);
9806     gen_set_label(l1);
9807     tcg_temp_free_i32(t0);
9808 }
9809
9810 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
9811 {
9812     int cond;
9813     TCGv_i32 t0 = tcg_temp_new_i32();
9814     TCGv_i64 fp0;
9815     TCGLabel *l1 = gen_new_label();
9816
9817     if (tf)
9818         cond = TCG_COND_EQ;
9819     else
9820         cond = TCG_COND_NE;
9821
9822     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9823     tcg_gen_brcondi_i32(cond, t0, 0, l1);
9824     tcg_temp_free_i32(t0);
9825     fp0 = tcg_temp_new_i64();
9826     gen_load_fpr64(ctx, fp0, fs);
9827     gen_store_fpr64(ctx, fp0, fd);
9828     tcg_temp_free_i64(fp0);
9829     gen_set_label(l1);
9830 }
9831
9832 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
9833                                 int cc, int tf)
9834 {
9835     int cond;
9836     TCGv_i32 t0 = tcg_temp_new_i32();
9837     TCGLabel *l1 = gen_new_label();
9838     TCGLabel *l2 = gen_new_label();
9839
9840     if (tf)
9841         cond = TCG_COND_EQ;
9842     else
9843         cond = TCG_COND_NE;
9844
9845     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9846     tcg_gen_brcondi_i32(cond, t0, 0, l1);
9847     gen_load_fpr32(ctx, t0, fs);
9848     gen_store_fpr32(ctx, t0, fd);
9849     gen_set_label(l1);
9850
9851     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
9852     tcg_gen_brcondi_i32(cond, t0, 0, l2);
9853     gen_load_fpr32h(ctx, t0, fs);
9854     gen_store_fpr32h(ctx, t0, fd);
9855     tcg_temp_free_i32(t0);
9856     gen_set_label(l2);
9857 }
9858
9859 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9860                       int fs)
9861 {
9862     TCGv_i32 t1 = tcg_const_i32(0);
9863     TCGv_i32 fp0 = tcg_temp_new_i32();
9864     TCGv_i32 fp1 = tcg_temp_new_i32();
9865     TCGv_i32 fp2 = tcg_temp_new_i32();
9866     gen_load_fpr32(ctx, fp0, fd);
9867     gen_load_fpr32(ctx, fp1, ft);
9868     gen_load_fpr32(ctx, fp2, fs);
9869
9870     switch (op1) {
9871     case OPC_SEL_S:
9872         tcg_gen_andi_i32(fp0, fp0, 1);
9873         tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9874         break;
9875     case OPC_SELEQZ_S:
9876         tcg_gen_andi_i32(fp1, fp1, 1);
9877         tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9878         break;
9879     case OPC_SELNEZ_S:
9880         tcg_gen_andi_i32(fp1, fp1, 1);
9881         tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9882         break;
9883     default:
9884         MIPS_INVAL("gen_sel_s");
9885         generate_exception_end(ctx, EXCP_RI);
9886         break;
9887     }
9888
9889     gen_store_fpr32(ctx, fp0, fd);
9890     tcg_temp_free_i32(fp2);
9891     tcg_temp_free_i32(fp1);
9892     tcg_temp_free_i32(fp0);
9893     tcg_temp_free_i32(t1);
9894 }
9895
9896 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9897                       int fs)
9898 {
9899     TCGv_i64 t1 = tcg_const_i64(0);
9900     TCGv_i64 fp0 = tcg_temp_new_i64();
9901     TCGv_i64 fp1 = tcg_temp_new_i64();
9902     TCGv_i64 fp2 = tcg_temp_new_i64();
9903     gen_load_fpr64(ctx, fp0, fd);
9904     gen_load_fpr64(ctx, fp1, ft);
9905     gen_load_fpr64(ctx, fp2, fs);
9906
9907     switch (op1) {
9908     case OPC_SEL_D:
9909         tcg_gen_andi_i64(fp0, fp0, 1);
9910         tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9911         break;
9912     case OPC_SELEQZ_D:
9913         tcg_gen_andi_i64(fp1, fp1, 1);
9914         tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9915         break;
9916     case OPC_SELNEZ_D:
9917         tcg_gen_andi_i64(fp1, fp1, 1);
9918         tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9919         break;
9920     default:
9921         MIPS_INVAL("gen_sel_d");
9922         generate_exception_end(ctx, EXCP_RI);
9923         break;
9924     }
9925
9926     gen_store_fpr64(ctx, fp0, fd);
9927     tcg_temp_free_i64(fp2);
9928     tcg_temp_free_i64(fp1);
9929     tcg_temp_free_i64(fp0);
9930     tcg_temp_free_i64(t1);
9931 }
9932
9933 static void gen_farith (DisasContext *ctx, enum fopcode op1,
9934                         int ft, int fs, int fd, int cc)
9935 {
9936     uint32_t func = ctx->opcode & 0x3f;
9937     switch (op1) {
9938     case OPC_ADD_S:
9939         {
9940             TCGv_i32 fp0 = tcg_temp_new_i32();
9941             TCGv_i32 fp1 = tcg_temp_new_i32();
9942
9943             gen_load_fpr32(ctx, fp0, fs);
9944             gen_load_fpr32(ctx, fp1, ft);
9945             gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
9946             tcg_temp_free_i32(fp1);
9947             gen_store_fpr32(ctx, fp0, fd);
9948             tcg_temp_free_i32(fp0);
9949         }
9950         break;
9951     case OPC_SUB_S:
9952         {
9953             TCGv_i32 fp0 = tcg_temp_new_i32();
9954             TCGv_i32 fp1 = tcg_temp_new_i32();
9955
9956             gen_load_fpr32(ctx, fp0, fs);
9957             gen_load_fpr32(ctx, fp1, ft);
9958             gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
9959             tcg_temp_free_i32(fp1);
9960             gen_store_fpr32(ctx, fp0, fd);
9961             tcg_temp_free_i32(fp0);
9962         }
9963         break;
9964     case OPC_MUL_S:
9965         {
9966             TCGv_i32 fp0 = tcg_temp_new_i32();
9967             TCGv_i32 fp1 = tcg_temp_new_i32();
9968
9969             gen_load_fpr32(ctx, fp0, fs);
9970             gen_load_fpr32(ctx, fp1, ft);
9971             gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
9972             tcg_temp_free_i32(fp1);
9973             gen_store_fpr32(ctx, fp0, fd);
9974             tcg_temp_free_i32(fp0);
9975         }
9976         break;
9977     case OPC_DIV_S:
9978         {
9979             TCGv_i32 fp0 = tcg_temp_new_i32();
9980             TCGv_i32 fp1 = tcg_temp_new_i32();
9981
9982             gen_load_fpr32(ctx, fp0, fs);
9983             gen_load_fpr32(ctx, fp1, ft);
9984             gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
9985             tcg_temp_free_i32(fp1);
9986             gen_store_fpr32(ctx, fp0, fd);
9987             tcg_temp_free_i32(fp0);
9988         }
9989         break;
9990     case OPC_SQRT_S:
9991         {
9992             TCGv_i32 fp0 = tcg_temp_new_i32();
9993
9994             gen_load_fpr32(ctx, fp0, fs);
9995             gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
9996             gen_store_fpr32(ctx, fp0, fd);
9997             tcg_temp_free_i32(fp0);
9998         }
9999         break;
10000     case OPC_ABS_S:
10001         {
10002             TCGv_i32 fp0 = tcg_temp_new_i32();
10003
10004             gen_load_fpr32(ctx, fp0, fs);
10005             if (ctx->abs2008) {
10006                 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
10007             } else {
10008                 gen_helper_float_abs_s(fp0, fp0);
10009             }
10010             gen_store_fpr32(ctx, fp0, fd);
10011             tcg_temp_free_i32(fp0);
10012         }
10013         break;
10014     case OPC_MOV_S:
10015         {
10016             TCGv_i32 fp0 = tcg_temp_new_i32();
10017
10018             gen_load_fpr32(ctx, fp0, fs);
10019             gen_store_fpr32(ctx, fp0, fd);
10020             tcg_temp_free_i32(fp0);
10021         }
10022         break;
10023     case OPC_NEG_S:
10024         {
10025             TCGv_i32 fp0 = tcg_temp_new_i32();
10026
10027             gen_load_fpr32(ctx, fp0, fs);
10028             if (ctx->abs2008) {
10029                 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
10030             } else {
10031                 gen_helper_float_chs_s(fp0, fp0);
10032             }
10033             gen_store_fpr32(ctx, fp0, fd);
10034             tcg_temp_free_i32(fp0);
10035         }
10036         break;
10037     case OPC_ROUND_L_S:
10038         check_cp1_64bitmode(ctx);
10039         {
10040             TCGv_i32 fp32 = tcg_temp_new_i32();
10041             TCGv_i64 fp64 = tcg_temp_new_i64();
10042
10043             gen_load_fpr32(ctx, fp32, fs);
10044             if (ctx->nan2008) {
10045                 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
10046             } else {
10047                 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
10048             }
10049             tcg_temp_free_i32(fp32);
10050             gen_store_fpr64(ctx, fp64, fd);
10051             tcg_temp_free_i64(fp64);
10052         }
10053         break;
10054     case OPC_TRUNC_L_S:
10055         check_cp1_64bitmode(ctx);
10056         {
10057             TCGv_i32 fp32 = tcg_temp_new_i32();
10058             TCGv_i64 fp64 = tcg_temp_new_i64();
10059
10060             gen_load_fpr32(ctx, fp32, fs);
10061             if (ctx->nan2008) {
10062                 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
10063             } else {
10064                 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
10065             }
10066             tcg_temp_free_i32(fp32);
10067             gen_store_fpr64(ctx, fp64, fd);
10068             tcg_temp_free_i64(fp64);
10069         }
10070         break;
10071     case OPC_CEIL_L_S:
10072         check_cp1_64bitmode(ctx);
10073         {
10074             TCGv_i32 fp32 = tcg_temp_new_i32();
10075             TCGv_i64 fp64 = tcg_temp_new_i64();
10076
10077             gen_load_fpr32(ctx, fp32, fs);
10078             if (ctx->nan2008) {
10079                 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
10080             } else {
10081                 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
10082             }
10083             tcg_temp_free_i32(fp32);
10084             gen_store_fpr64(ctx, fp64, fd);
10085             tcg_temp_free_i64(fp64);
10086         }
10087         break;
10088     case OPC_FLOOR_L_S:
10089         check_cp1_64bitmode(ctx);
10090         {
10091             TCGv_i32 fp32 = tcg_temp_new_i32();
10092             TCGv_i64 fp64 = tcg_temp_new_i64();
10093
10094             gen_load_fpr32(ctx, fp32, fs);
10095             if (ctx->nan2008) {
10096                 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
10097             } else {
10098                 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
10099             }
10100             tcg_temp_free_i32(fp32);
10101             gen_store_fpr64(ctx, fp64, fd);
10102             tcg_temp_free_i64(fp64);
10103         }
10104         break;
10105     case OPC_ROUND_W_S:
10106         {
10107             TCGv_i32 fp0 = tcg_temp_new_i32();
10108
10109             gen_load_fpr32(ctx, fp0, fs);
10110             if (ctx->nan2008) {
10111                 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
10112             } else {
10113                 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
10114             }
10115             gen_store_fpr32(ctx, fp0, fd);
10116             tcg_temp_free_i32(fp0);
10117         }
10118         break;
10119     case OPC_TRUNC_W_S:
10120         {
10121             TCGv_i32 fp0 = tcg_temp_new_i32();
10122
10123             gen_load_fpr32(ctx, fp0, fs);
10124             if (ctx->nan2008) {
10125                 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
10126             } else {
10127                 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
10128             }
10129             gen_store_fpr32(ctx, fp0, fd);
10130             tcg_temp_free_i32(fp0);
10131         }
10132         break;
10133     case OPC_CEIL_W_S:
10134         {
10135             TCGv_i32 fp0 = tcg_temp_new_i32();
10136
10137             gen_load_fpr32(ctx, fp0, fs);
10138             if (ctx->nan2008) {
10139                 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
10140             } else {
10141                 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
10142             }
10143             gen_store_fpr32(ctx, fp0, fd);
10144             tcg_temp_free_i32(fp0);
10145         }
10146         break;
10147     case OPC_FLOOR_W_S:
10148         {
10149             TCGv_i32 fp0 = tcg_temp_new_i32();
10150
10151             gen_load_fpr32(ctx, fp0, fs);
10152             if (ctx->nan2008) {
10153                 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
10154             } else {
10155                 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
10156             }
10157             gen_store_fpr32(ctx, fp0, fd);
10158             tcg_temp_free_i32(fp0);
10159         }
10160         break;
10161     case OPC_SEL_S:
10162         check_insn(ctx, ISA_MIPS32R6);
10163         gen_sel_s(ctx, op1, fd, ft, fs);
10164         break;
10165     case OPC_SELEQZ_S:
10166         check_insn(ctx, ISA_MIPS32R6);
10167         gen_sel_s(ctx, op1, fd, ft, fs);
10168         break;
10169     case OPC_SELNEZ_S:
10170         check_insn(ctx, ISA_MIPS32R6);
10171         gen_sel_s(ctx, op1, fd, ft, fs);
10172         break;
10173     case OPC_MOVCF_S:
10174         check_insn_opc_removed(ctx, ISA_MIPS32R6);
10175         gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10176         break;
10177     case OPC_MOVZ_S:
10178         check_insn_opc_removed(ctx, ISA_MIPS32R6);
10179         {
10180             TCGLabel *l1 = gen_new_label();
10181             TCGv_i32 fp0;
10182
10183             if (ft != 0) {
10184                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10185             }
10186             fp0 = tcg_temp_new_i32();
10187             gen_load_fpr32(ctx, fp0, fs);
10188             gen_store_fpr32(ctx, fp0, fd);
10189             tcg_temp_free_i32(fp0);
10190             gen_set_label(l1);
10191         }
10192         break;
10193     case OPC_MOVN_S:
10194         check_insn_opc_removed(ctx, ISA_MIPS32R6);
10195         {
10196             TCGLabel *l1 = gen_new_label();
10197             TCGv_i32 fp0;
10198
10199             if (ft != 0) {
10200                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10201                 fp0 = tcg_temp_new_i32();
10202                 gen_load_fpr32(ctx, fp0, fs);
10203                 gen_store_fpr32(ctx, fp0, fd);
10204                 tcg_temp_free_i32(fp0);
10205                 gen_set_label(l1);
10206             }
10207         }
10208         break;
10209     case OPC_RECIP_S:
10210         {
10211             TCGv_i32 fp0 = tcg_temp_new_i32();
10212
10213             gen_load_fpr32(ctx, fp0, fs);
10214             gen_helper_float_recip_s(fp0, cpu_env, fp0);
10215             gen_store_fpr32(ctx, fp0, fd);
10216             tcg_temp_free_i32(fp0);
10217         }
10218         break;
10219     case OPC_RSQRT_S:
10220         {
10221             TCGv_i32 fp0 = tcg_temp_new_i32();
10222
10223             gen_load_fpr32(ctx, fp0, fs);
10224             gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
10225             gen_store_fpr32(ctx, fp0, fd);
10226             tcg_temp_free_i32(fp0);
10227         }
10228         break;
10229     case OPC_MADDF_S:
10230         check_insn(ctx, ISA_MIPS32R6);
10231         {
10232             TCGv_i32 fp0 = tcg_temp_new_i32();
10233             TCGv_i32 fp1 = tcg_temp_new_i32();
10234             TCGv_i32 fp2 = tcg_temp_new_i32();
10235             gen_load_fpr32(ctx, fp0, fs);
10236             gen_load_fpr32(ctx, fp1, ft);
10237             gen_load_fpr32(ctx, fp2, fd);
10238             gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
10239             gen_store_fpr32(ctx, fp2, fd);
10240             tcg_temp_free_i32(fp2);
10241             tcg_temp_free_i32(fp1);
10242             tcg_temp_free_i32(fp0);
10243         }
10244         break;
10245     case OPC_MSUBF_S:
10246         check_insn(ctx, ISA_MIPS32R6);
10247         {
10248             TCGv_i32 fp0 = tcg_temp_new_i32();
10249             TCGv_i32 fp1 = tcg_temp_new_i32();
10250             TCGv_i32 fp2 = tcg_temp_new_i32();
10251             gen_load_fpr32(ctx, fp0, fs);
10252             gen_load_fpr32(ctx, fp1, ft);
10253             gen_load_fpr32(ctx, fp2, fd);
10254             gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
10255             gen_store_fpr32(ctx, fp2, fd);
10256             tcg_temp_free_i32(fp2);
10257             tcg_temp_free_i32(fp1);
10258             tcg_temp_free_i32(fp0);
10259         }
10260         break;
10261     case OPC_RINT_S:
10262         check_insn(ctx, ISA_MIPS32R6);
10263         {
10264             TCGv_i32 fp0 = tcg_temp_new_i32();
10265             gen_load_fpr32(ctx, fp0, fs);
10266             gen_helper_float_rint_s(fp0, cpu_env, fp0);
10267             gen_store_fpr32(ctx, fp0, fd);
10268             tcg_temp_free_i32(fp0);
10269         }
10270         break;
10271     case OPC_CLASS_S:
10272         check_insn(ctx, ISA_MIPS32R6);
10273         {
10274             TCGv_i32 fp0 = tcg_temp_new_i32();
10275             gen_load_fpr32(ctx, fp0, fs);
10276             gen_helper_float_class_s(fp0, cpu_env, fp0);
10277             gen_store_fpr32(ctx, fp0, fd);
10278             tcg_temp_free_i32(fp0);
10279         }
10280         break;
10281     case OPC_MIN_S: /* OPC_RECIP2_S */
10282         if (ctx->insn_flags & ISA_MIPS32R6) {
10283             /* OPC_MIN_S */
10284             TCGv_i32 fp0 = tcg_temp_new_i32();
10285             TCGv_i32 fp1 = tcg_temp_new_i32();
10286             TCGv_i32 fp2 = tcg_temp_new_i32();
10287             gen_load_fpr32(ctx, fp0, fs);
10288             gen_load_fpr32(ctx, fp1, ft);
10289             gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
10290             gen_store_fpr32(ctx, fp2, fd);
10291             tcg_temp_free_i32(fp2);
10292             tcg_temp_free_i32(fp1);
10293             tcg_temp_free_i32(fp0);
10294         } else {
10295             /* OPC_RECIP2_S */
10296             check_cp1_64bitmode(ctx);
10297             {
10298                 TCGv_i32 fp0 = tcg_temp_new_i32();
10299                 TCGv_i32 fp1 = tcg_temp_new_i32();
10300
10301                 gen_load_fpr32(ctx, fp0, fs);
10302                 gen_load_fpr32(ctx, fp1, ft);
10303                 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
10304                 tcg_temp_free_i32(fp1);
10305                 gen_store_fpr32(ctx, fp0, fd);
10306                 tcg_temp_free_i32(fp0);
10307             }
10308         }
10309         break;
10310     case OPC_MINA_S: /* OPC_RECIP1_S */
10311         if (ctx->insn_flags & ISA_MIPS32R6) {
10312             /* OPC_MINA_S */
10313             TCGv_i32 fp0 = tcg_temp_new_i32();
10314             TCGv_i32 fp1 = tcg_temp_new_i32();
10315             TCGv_i32 fp2 = tcg_temp_new_i32();
10316             gen_load_fpr32(ctx, fp0, fs);
10317             gen_load_fpr32(ctx, fp1, ft);
10318             gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
10319             gen_store_fpr32(ctx, fp2, fd);
10320             tcg_temp_free_i32(fp2);
10321             tcg_temp_free_i32(fp1);
10322             tcg_temp_free_i32(fp0);
10323         } else {
10324             /* OPC_RECIP1_S */
10325             check_cp1_64bitmode(ctx);
10326             {
10327                 TCGv_i32 fp0 = tcg_temp_new_i32();
10328
10329                 gen_load_fpr32(ctx, fp0, fs);
10330                 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
10331                 gen_store_fpr32(ctx, fp0, fd);
10332                 tcg_temp_free_i32(fp0);
10333             }
10334         }
10335         break;
10336     case OPC_MAX_S: /* OPC_RSQRT1_S */
10337         if (ctx->insn_flags & ISA_MIPS32R6) {
10338             /* OPC_MAX_S */
10339             TCGv_i32 fp0 = tcg_temp_new_i32();
10340             TCGv_i32 fp1 = tcg_temp_new_i32();
10341             gen_load_fpr32(ctx, fp0, fs);
10342             gen_load_fpr32(ctx, fp1, ft);
10343             gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
10344             gen_store_fpr32(ctx, fp1, fd);
10345             tcg_temp_free_i32(fp1);
10346             tcg_temp_free_i32(fp0);
10347         } else {
10348             /* OPC_RSQRT1_S */
10349             check_cp1_64bitmode(ctx);
10350             {
10351                 TCGv_i32 fp0 = tcg_temp_new_i32();
10352
10353                 gen_load_fpr32(ctx, fp0, fs);
10354                 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
10355                 gen_store_fpr32(ctx, fp0, fd);
10356                 tcg_temp_free_i32(fp0);
10357             }
10358         }
10359         break;
10360     case OPC_MAXA_S: /* OPC_RSQRT2_S */
10361         if (ctx->insn_flags & ISA_MIPS32R6) {
10362             /* OPC_MAXA_S */
10363             TCGv_i32 fp0 = tcg_temp_new_i32();
10364             TCGv_i32 fp1 = tcg_temp_new_i32();
10365             gen_load_fpr32(ctx, fp0, fs);
10366             gen_load_fpr32(ctx, fp1, ft);
10367             gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
10368             gen_store_fpr32(ctx, fp1, fd);
10369             tcg_temp_free_i32(fp1);
10370             tcg_temp_free_i32(fp0);
10371         } else {
10372             /* OPC_RSQRT2_S */
10373             check_cp1_64bitmode(ctx);
10374             {
10375                 TCGv_i32 fp0 = tcg_temp_new_i32();
10376                 TCGv_i32 fp1 = tcg_temp_new_i32();
10377
10378                 gen_load_fpr32(ctx, fp0, fs);
10379                 gen_load_fpr32(ctx, fp1, ft);
10380                 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
10381                 tcg_temp_free_i32(fp1);
10382                 gen_store_fpr32(ctx, fp0, fd);
10383                 tcg_temp_free_i32(fp0);
10384             }
10385         }
10386         break;
10387     case OPC_CVT_D_S:
10388         check_cp1_registers(ctx, fd);
10389         {
10390             TCGv_i32 fp32 = tcg_temp_new_i32();
10391             TCGv_i64 fp64 = tcg_temp_new_i64();
10392
10393             gen_load_fpr32(ctx, fp32, fs);
10394             gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
10395             tcg_temp_free_i32(fp32);
10396             gen_store_fpr64(ctx, fp64, fd);
10397             tcg_temp_free_i64(fp64);
10398         }
10399         break;
10400     case OPC_CVT_W_S:
10401         {
10402             TCGv_i32 fp0 = tcg_temp_new_i32();
10403
10404             gen_load_fpr32(ctx, fp0, fs);
10405             if (ctx->nan2008) {
10406                 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
10407             } else {
10408                 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
10409             }
10410             gen_store_fpr32(ctx, fp0, fd);
10411             tcg_temp_free_i32(fp0);
10412         }
10413         break;
10414     case OPC_CVT_L_S:
10415         check_cp1_64bitmode(ctx);
10416         {
10417             TCGv_i32 fp32 = tcg_temp_new_i32();
10418             TCGv_i64 fp64 = tcg_temp_new_i64();
10419
10420             gen_load_fpr32(ctx, fp32, fs);
10421             if (ctx->nan2008) {
10422                 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
10423             } else {
10424                 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
10425             }
10426             tcg_temp_free_i32(fp32);
10427             gen_store_fpr64(ctx, fp64, fd);
10428             tcg_temp_free_i64(fp64);
10429         }
10430         break;
10431     case OPC_CVT_PS_S:
10432         check_ps(ctx);
10433         {
10434             TCGv_i64 fp64 = tcg_temp_new_i64();
10435             TCGv_i32 fp32_0 = tcg_temp_new_i32();
10436             TCGv_i32 fp32_1 = tcg_temp_new_i32();
10437
10438             gen_load_fpr32(ctx, fp32_0, fs);
10439             gen_load_fpr32(ctx, fp32_1, ft);
10440             tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
10441             tcg_temp_free_i32(fp32_1);
10442             tcg_temp_free_i32(fp32_0);
10443             gen_store_fpr64(ctx, fp64, fd);
10444             tcg_temp_free_i64(fp64);
10445         }
10446         break;
10447     case OPC_CMP_F_S:
10448     case OPC_CMP_UN_S:
10449     case OPC_CMP_EQ_S:
10450     case OPC_CMP_UEQ_S:
10451     case OPC_CMP_OLT_S:
10452     case OPC_CMP_ULT_S:
10453     case OPC_CMP_OLE_S:
10454     case OPC_CMP_ULE_S:
10455     case OPC_CMP_SF_S:
10456     case OPC_CMP_NGLE_S:
10457     case OPC_CMP_SEQ_S:
10458     case OPC_CMP_NGL_S:
10459     case OPC_CMP_LT_S:
10460     case OPC_CMP_NGE_S:
10461     case OPC_CMP_LE_S:
10462     case OPC_CMP_NGT_S:
10463         check_insn_opc_removed(ctx, ISA_MIPS32R6);
10464         if (ctx->opcode & (1 << 6)) {
10465             gen_cmpabs_s(ctx, func-48, ft, fs, cc);
10466         } else {
10467             gen_cmp_s(ctx, func-48, ft, fs, cc);
10468         }
10469         break;
10470     case OPC_ADD_D:
10471         check_cp1_registers(ctx, fs | ft | fd);
10472         {
10473             TCGv_i64 fp0 = tcg_temp_new_i64();
10474             TCGv_i64 fp1 = tcg_temp_new_i64();
10475
10476             gen_load_fpr64(ctx, fp0, fs);
10477             gen_load_fpr64(ctx, fp1, ft);
10478             gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
10479             tcg_temp_free_i64(fp1);
10480             gen_store_fpr64(ctx, fp0, fd);
10481             tcg_temp_free_i64(fp0);
10482         }
10483         break;
10484     case OPC_SUB_D:
10485         check_cp1_registers(ctx, fs | ft | fd);
10486         {
10487             TCGv_i64 fp0 = tcg_temp_new_i64();
10488             TCGv_i64 fp1 = tcg_temp_new_i64();
10489
10490             gen_load_fpr64(ctx, fp0, fs);
10491             gen_load_fpr64(ctx, fp1, ft);
10492             gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
10493             tcg_temp_free_i64(fp1);
10494             gen_store_fpr64(ctx, fp0, fd);
10495             tcg_temp_free_i64(fp0);
10496         }
10497         break;
10498     case OPC_MUL_D:
10499         check_cp1_registers(ctx, fs | ft | fd);
10500         {
10501             TCGv_i64 fp0 = tcg_temp_new_i64();
10502             TCGv_i64 fp1 = tcg_temp_new_i64();
10503
10504             gen_load_fpr64(ctx, fp0, fs);
10505             gen_load_fpr64(ctx, fp1, ft);
10506             gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
10507             tcg_temp_free_i64(fp1);
10508             gen_store_fpr64(ctx, fp0, fd);
10509             tcg_temp_free_i64(fp0);
10510         }
10511         break;
10512     case OPC_DIV_D:
10513         check_cp1_registers(ctx, fs | ft | fd);
10514         {
10515             TCGv_i64 fp0 = tcg_temp_new_i64();
10516             TCGv_i64 fp1 = tcg_temp_new_i64();
10517
10518             gen_load_fpr64(ctx, fp0, fs);
10519             gen_load_fpr64(ctx, fp1, ft);
10520             gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
10521             tcg_temp_free_i64(fp1);
10522             gen_store_fpr64(ctx, fp0, fd);
10523             tcg_temp_free_i64(fp0);
10524         }
10525         break;
10526     case OPC_SQRT_D:
10527         check_cp1_registers(ctx, fs | fd);
10528         {
10529             TCGv_i64 fp0 = tcg_temp_new_i64();
10530
10531             gen_load_fpr64(ctx, fp0, fs);
10532             gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
10533             gen_store_fpr64(ctx, fp0, fd);
10534             tcg_temp_free_i64(fp0);
10535         }
10536         break;
10537     case OPC_ABS_D:
10538         check_cp1_registers(ctx, fs | fd);
10539         {
10540             TCGv_i64 fp0 = tcg_temp_new_i64();
10541
10542             gen_load_fpr64(ctx, fp0, fs);
10543             if (ctx->abs2008) {
10544                 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
10545             } else {
10546                 gen_helper_float_abs_d(fp0, fp0);
10547             }
10548             gen_store_fpr64(ctx, fp0, fd);
10549             tcg_temp_free_i64(fp0);
10550         }
10551         break;
10552     case OPC_MOV_D:
10553         check_cp1_registers(ctx, fs | fd);
10554         {
10555             TCGv_i64 fp0 = tcg_temp_new_i64();
10556
10557             gen_load_fpr64(ctx, fp0, fs);
10558             gen_store_fpr64(ctx, fp0, fd);
10559             tcg_temp_free_i64(fp0);
10560         }
10561         break;
10562     case OPC_NEG_D:
10563         check_cp1_registers(ctx, fs | fd);
10564         {
10565             TCGv_i64 fp0 = tcg_temp_new_i64();
10566
10567             gen_load_fpr64(ctx, fp0, fs);
10568             if (ctx->abs2008) {
10569                 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
10570             } else {
10571                 gen_helper_float_chs_d(fp0, fp0);
10572             }
10573             gen_store_fpr64(ctx, fp0, fd);
10574             tcg_temp_free_i64(fp0);
10575         }
10576         break;
10577     case OPC_ROUND_L_D:
10578         check_cp1_64bitmode(ctx);
10579         {
10580             TCGv_i64 fp0 = tcg_temp_new_i64();
10581
10582             gen_load_fpr64(ctx, fp0, fs);
10583             if (ctx->nan2008) {
10584                 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
10585             } else {
10586                 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
10587             }
10588             gen_store_fpr64(ctx, fp0, fd);
10589             tcg_temp_free_i64(fp0);
10590         }
10591         break;
10592     case OPC_TRUNC_L_D:
10593         check_cp1_64bitmode(ctx);
10594         {
10595             TCGv_i64 fp0 = tcg_temp_new_i64();
10596
10597             gen_load_fpr64(ctx, fp0, fs);
10598             if (ctx->nan2008) {
10599                 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
10600             } else {
10601                 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
10602             }
10603             gen_store_fpr64(ctx, fp0, fd);
10604             tcg_temp_free_i64(fp0);
10605         }
10606         break;
10607     case OPC_CEIL_L_D:
10608         check_cp1_64bitmode(ctx);
10609         {
10610             TCGv_i64 fp0 = tcg_temp_new_i64();
10611
10612             gen_load_fpr64(ctx, fp0, fs);
10613             if (ctx->nan2008) {
10614                 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
10615             } else {
10616                 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
10617             }
10618             gen_store_fpr64(ctx, fp0, fd);
10619             tcg_temp_free_i64(fp0);
10620         }
10621         break;
10622     case OPC_FLOOR_L_D:
10623         check_cp1_64bitmode(ctx);
10624         {
10625             TCGv_i64 fp0 = tcg_temp_new_i64();
10626
10627             gen_load_fpr64(ctx, fp0, fs);
10628             if (ctx->nan2008) {
10629                 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
10630             } else {
10631                 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
10632             }
10633             gen_store_fpr64(ctx, fp0, fd);
10634             tcg_temp_free_i64(fp0);
10635         }
10636         break;
10637     case OPC_ROUND_W_D:
10638         check_cp1_registers(ctx, fs);
10639         {
10640             TCGv_i32 fp32 = tcg_temp_new_i32();
10641             TCGv_i64 fp64 = tcg_temp_new_i64();
10642
10643             gen_load_fpr64(ctx, fp64, fs);
10644             if (ctx->nan2008) {
10645                 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
10646             } else {
10647                 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
10648             }
10649             tcg_temp_free_i64(fp64);
10650             gen_store_fpr32(ctx, fp32, fd);
10651             tcg_temp_free_i32(fp32);
10652         }
10653         break;
10654     case OPC_TRUNC_W_D:
10655         check_cp1_registers(ctx, fs);
10656         {
10657             TCGv_i32 fp32 = tcg_temp_new_i32();
10658             TCGv_i64 fp64 = tcg_temp_new_i64();
10659
10660             gen_load_fpr64(ctx, fp64, fs);
10661             if (ctx->nan2008) {
10662                 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
10663             } else {
10664                 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
10665             }
10666             tcg_temp_free_i64(fp64);
10667             gen_store_fpr32(ctx, fp32, fd);
10668             tcg_temp_free_i32(fp32);
10669         }
10670         break;
10671     case OPC_CEIL_W_D:
10672         check_cp1_registers(ctx, fs);
10673         {
10674             TCGv_i32 fp32 = tcg_temp_new_i32();
10675             TCGv_i64 fp64 = tcg_temp_new_i64();
10676
10677             gen_load_fpr64(ctx, fp64, fs);
10678             if (ctx->nan2008) {
10679                 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
10680             } else {
10681                 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
10682             }
10683             tcg_temp_free_i64(fp64);
10684             gen_store_fpr32(ctx, fp32, fd);
10685             tcg_temp_free_i32(fp32);
10686         }
10687         break;
10688     case OPC_FLOOR_W_D:
10689         check_cp1_registers(ctx, fs);
10690         {
10691             TCGv_i32 fp32 = tcg_temp_new_i32();
10692             TCGv_i64 fp64 = tcg_temp_new_i64();
10693
10694             gen_load_fpr64(ctx, fp64, fs);
10695             if (ctx->nan2008) {
10696                 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
10697             } else {
10698                 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
10699             }
10700             tcg_temp_free_i64(fp64);
10701             gen_store_fpr32(ctx, fp32, fd);
10702             tcg_temp_free_i32(fp32);
10703         }
10704         break;
10705     case OPC_SEL_D:
10706         check_insn(ctx, ISA_MIPS32R6);
10707         gen_sel_d(ctx, op1, fd, ft, fs);
10708         break;
10709     case OPC_SELEQZ_D:
10710         check_insn(ctx, ISA_MIPS32R6);
10711         gen_sel_d(ctx, op1, fd, ft, fs);
10712         break;
10713     case OPC_SELNEZ_D:
10714         check_insn(ctx, ISA_MIPS32R6);
10715         gen_sel_d(ctx, op1, fd, ft, fs);
10716         break;
10717     case OPC_MOVCF_D:
10718         check_insn_opc_removed(ctx, ISA_MIPS32R6);
10719         gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10720         break;
10721     case OPC_MOVZ_D:
10722         check_insn_opc_removed(ctx, ISA_MIPS32R6);
10723         {
10724             TCGLabel *l1 = gen_new_label();
10725             TCGv_i64 fp0;
10726
10727             if (ft != 0) {
10728                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10729             }
10730             fp0 = tcg_temp_new_i64();
10731             gen_load_fpr64(ctx, fp0, fs);
10732             gen_store_fpr64(ctx, fp0, fd);
10733             tcg_temp_free_i64(fp0);
10734             gen_set_label(l1);
10735         }
10736         break;
10737     case OPC_MOVN_D:
10738         check_insn_opc_removed(ctx, ISA_MIPS32R6);
10739         {
10740             TCGLabel *l1 = gen_new_label();
10741             TCGv_i64 fp0;
10742
10743             if (ft != 0) {
10744                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10745                 fp0 = tcg_temp_new_i64();
10746                 gen_load_fpr64(ctx, fp0, fs);
10747                 gen_store_fpr64(ctx, fp0, fd);
10748                 tcg_temp_free_i64(fp0);
10749                 gen_set_label(l1);
10750             }
10751         }
10752         break;
10753     case OPC_RECIP_D:
10754         check_cp1_registers(ctx, fs | fd);
10755         {
10756             TCGv_i64 fp0 = tcg_temp_new_i64();
10757
10758             gen_load_fpr64(ctx, fp0, fs);
10759             gen_helper_float_recip_d(fp0, cpu_env, fp0);
10760             gen_store_fpr64(ctx, fp0, fd);
10761             tcg_temp_free_i64(fp0);
10762         }
10763         break;
10764     case OPC_RSQRT_D:
10765         check_cp1_registers(ctx, fs | fd);
10766         {
10767             TCGv_i64 fp0 = tcg_temp_new_i64();
10768
10769             gen_load_fpr64(ctx, fp0, fs);
10770             gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
10771             gen_store_fpr64(ctx, fp0, fd);
10772             tcg_temp_free_i64(fp0);
10773         }
10774         break;
10775     case OPC_MADDF_D:
10776         check_insn(ctx, ISA_MIPS32R6);
10777         {
10778             TCGv_i64 fp0 = tcg_temp_new_i64();
10779             TCGv_i64 fp1 = tcg_temp_new_i64();
10780             TCGv_i64 fp2 = tcg_temp_new_i64();
10781             gen_load_fpr64(ctx, fp0, fs);
10782             gen_load_fpr64(ctx, fp1, ft);
10783             gen_load_fpr64(ctx, fp2, fd);
10784             gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
10785             gen_store_fpr64(ctx, fp2, fd);
10786             tcg_temp_free_i64(fp2);
10787             tcg_temp_free_i64(fp1);
10788             tcg_temp_free_i64(fp0);
10789         }
10790         break;
10791     case OPC_MSUBF_D:
10792         check_insn(ctx, ISA_MIPS32R6);
10793         {
10794             TCGv_i64 fp0 = tcg_temp_new_i64();
10795             TCGv_i64 fp1 = tcg_temp_new_i64();
10796             TCGv_i64 fp2 = tcg_temp_new_i64();
10797             gen_load_fpr64(ctx, fp0, fs);
10798             gen_load_fpr64(ctx, fp1, ft);
10799             gen_load_fpr64(ctx, fp2, fd);
10800             gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
10801             gen_store_fpr64(ctx, fp2, fd);
10802             tcg_temp_free_i64(fp2);
10803             tcg_temp_free_i64(fp1);
10804             tcg_temp_free_i64(fp0);
10805         }
10806         break;
10807     case OPC_RINT_D:
10808         check_insn(ctx, ISA_MIPS32R6);
10809         {
10810             TCGv_i64 fp0 = tcg_temp_new_i64();
10811             gen_load_fpr64(ctx, fp0, fs);
10812             gen_helper_float_rint_d(fp0, cpu_env, fp0);
10813             gen_store_fpr64(ctx, fp0, fd);
10814             tcg_temp_free_i64(fp0);
10815         }
10816         break;
10817     case OPC_CLASS_D:
10818         check_insn(ctx, ISA_MIPS32R6);
10819         {
10820             TCGv_i64 fp0 = tcg_temp_new_i64();
10821             gen_load_fpr64(ctx, fp0, fs);
10822             gen_helper_float_class_d(fp0, cpu_env, fp0);
10823             gen_store_fpr64(ctx, fp0, fd);
10824             tcg_temp_free_i64(fp0);
10825         }
10826         break;
10827     case OPC_MIN_D: /* OPC_RECIP2_D */
10828         if (ctx->insn_flags & ISA_MIPS32R6) {
10829             /* OPC_MIN_D */
10830             TCGv_i64 fp0 = tcg_temp_new_i64();
10831             TCGv_i64 fp1 = tcg_temp_new_i64();
10832             gen_load_fpr64(ctx, fp0, fs);
10833             gen_load_fpr64(ctx, fp1, ft);
10834             gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
10835             gen_store_fpr64(ctx, fp1, fd);
10836             tcg_temp_free_i64(fp1);
10837             tcg_temp_free_i64(fp0);
10838         } else {
10839             /* OPC_RECIP2_D */
10840             check_cp1_64bitmode(ctx);
10841             {
10842                 TCGv_i64 fp0 = tcg_temp_new_i64();
10843                 TCGv_i64 fp1 = tcg_temp_new_i64();
10844
10845                 gen_load_fpr64(ctx, fp0, fs);
10846                 gen_load_fpr64(ctx, fp1, ft);
10847                 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
10848                 tcg_temp_free_i64(fp1);
10849                 gen_store_fpr64(ctx, fp0, fd);
10850                 tcg_temp_free_i64(fp0);
10851             }
10852         }
10853         break;
10854     case OPC_MINA_D: /* OPC_RECIP1_D */
10855         if (ctx->insn_flags & ISA_MIPS32R6) {
10856             /* OPC_MINA_D */
10857             TCGv_i64 fp0 = tcg_temp_new_i64();
10858             TCGv_i64 fp1 = tcg_temp_new_i64();
10859             gen_load_fpr64(ctx, fp0, fs);
10860             gen_load_fpr64(ctx, fp1, ft);
10861             gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
10862             gen_store_fpr64(ctx, fp1, fd);
10863             tcg_temp_free_i64(fp1);
10864             tcg_temp_free_i64(fp0);
10865         } else {
10866             /* OPC_RECIP1_D */
10867             check_cp1_64bitmode(ctx);
10868             {
10869                 TCGv_i64 fp0 = tcg_temp_new_i64();
10870
10871                 gen_load_fpr64(ctx, fp0, fs);
10872                 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
10873                 gen_store_fpr64(ctx, fp0, fd);
10874                 tcg_temp_free_i64(fp0);
10875             }
10876         }
10877         break;
10878     case OPC_MAX_D: /*  OPC_RSQRT1_D */
10879         if (ctx->insn_flags & ISA_MIPS32R6) {
10880             /* OPC_MAX_D */
10881             TCGv_i64 fp0 = tcg_temp_new_i64();
10882             TCGv_i64 fp1 = tcg_temp_new_i64();
10883             gen_load_fpr64(ctx, fp0, fs);
10884             gen_load_fpr64(ctx, fp1, ft);
10885             gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
10886             gen_store_fpr64(ctx, fp1, fd);
10887             tcg_temp_free_i64(fp1);
10888             tcg_temp_free_i64(fp0);
10889         } else {
10890             /* OPC_RSQRT1_D */
10891             check_cp1_64bitmode(ctx);
10892             {
10893                 TCGv_i64 fp0 = tcg_temp_new_i64();
10894
10895                 gen_load_fpr64(ctx, fp0, fs);
10896                 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
10897                 gen_store_fpr64(ctx, fp0, fd);
10898                 tcg_temp_free_i64(fp0);
10899             }
10900         }
10901         break;
10902     case OPC_MAXA_D: /* OPC_RSQRT2_D */
10903         if (ctx->insn_flags & ISA_MIPS32R6) {
10904             /* OPC_MAXA_D */
10905             TCGv_i64 fp0 = tcg_temp_new_i64();
10906             TCGv_i64 fp1 = tcg_temp_new_i64();
10907             gen_load_fpr64(ctx, fp0, fs);
10908             gen_load_fpr64(ctx, fp1, ft);
10909             gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
10910             gen_store_fpr64(ctx, fp1, fd);
10911             tcg_temp_free_i64(fp1);
10912             tcg_temp_free_i64(fp0);
10913         } else {
10914             /* OPC_RSQRT2_D */
10915             check_cp1_64bitmode(ctx);
10916             {
10917                 TCGv_i64 fp0 = tcg_temp_new_i64();
10918                 TCGv_i64 fp1 = tcg_temp_new_i64();
10919
10920                 gen_load_fpr64(ctx, fp0, fs);
10921                 gen_load_fpr64(ctx, fp1, ft);
10922                 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
10923                 tcg_temp_free_i64(fp1);
10924                 gen_store_fpr64(ctx, fp0, fd);
10925                 tcg_temp_free_i64(fp0);
10926             }
10927         }
10928         break;
10929     case OPC_CMP_F_D:
10930     case OPC_CMP_UN_D:
10931     case OPC_CMP_EQ_D:
10932     case OPC_CMP_UEQ_D:
10933     case OPC_CMP_OLT_D:
10934     case OPC_CMP_ULT_D:
10935     case OPC_CMP_OLE_D:
10936     case OPC_CMP_ULE_D:
10937     case OPC_CMP_SF_D:
10938     case OPC_CMP_NGLE_D:
10939     case OPC_CMP_SEQ_D:
10940     case OPC_CMP_NGL_D:
10941     case OPC_CMP_LT_D:
10942     case OPC_CMP_NGE_D:
10943     case OPC_CMP_LE_D:
10944     case OPC_CMP_NGT_D:
10945         check_insn_opc_removed(ctx, ISA_MIPS32R6);
10946         if (ctx->opcode & (1 << 6)) {
10947             gen_cmpabs_d(ctx, func-48, ft, fs, cc);
10948         } else {
10949             gen_cmp_d(ctx, func-48, ft, fs, cc);
10950         }
10951         break;
10952     case OPC_CVT_S_D:
10953         check_cp1_registers(ctx, fs);
10954         {
10955             TCGv_i32 fp32 = tcg_temp_new_i32();
10956             TCGv_i64 fp64 = tcg_temp_new_i64();
10957
10958             gen_load_fpr64(ctx, fp64, fs);
10959             gen_helper_float_cvts_d(fp32, cpu_env, fp64);
10960             tcg_temp_free_i64(fp64);
10961             gen_store_fpr32(ctx, fp32, fd);
10962             tcg_temp_free_i32(fp32);
10963         }
10964         break;
10965     case OPC_CVT_W_D:
10966         check_cp1_registers(ctx, fs);
10967         {
10968             TCGv_i32 fp32 = tcg_temp_new_i32();
10969             TCGv_i64 fp64 = tcg_temp_new_i64();
10970
10971             gen_load_fpr64(ctx, fp64, fs);
10972             if (ctx->nan2008) {
10973                 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
10974             } else {
10975                 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
10976             }
10977             tcg_temp_free_i64(fp64);
10978             gen_store_fpr32(ctx, fp32, fd);
10979             tcg_temp_free_i32(fp32);
10980         }
10981         break;
10982     case OPC_CVT_L_D:
10983         check_cp1_64bitmode(ctx);
10984         {
10985             TCGv_i64 fp0 = tcg_temp_new_i64();
10986
10987             gen_load_fpr64(ctx, fp0, fs);
10988             if (ctx->nan2008) {
10989                 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
10990             } else {
10991                 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
10992             }
10993             gen_store_fpr64(ctx, fp0, fd);
10994             tcg_temp_free_i64(fp0);
10995         }
10996         break;
10997     case OPC_CVT_S_W:
10998         {
10999             TCGv_i32 fp0 = tcg_temp_new_i32();
11000
11001             gen_load_fpr32(ctx, fp0, fs);
11002             gen_helper_float_cvts_w(fp0, cpu_env, fp0);
11003             gen_store_fpr32(ctx, fp0, fd);
11004             tcg_temp_free_i32(fp0);
11005         }
11006         break;
11007     case OPC_CVT_D_W:
11008         check_cp1_registers(ctx, fd);
11009         {
11010             TCGv_i32 fp32 = tcg_temp_new_i32();
11011             TCGv_i64 fp64 = tcg_temp_new_i64();
11012
11013             gen_load_fpr32(ctx, fp32, fs);
11014             gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
11015             tcg_temp_free_i32(fp32);
11016             gen_store_fpr64(ctx, fp64, fd);
11017             tcg_temp_free_i64(fp64);
11018         }
11019         break;
11020     case OPC_CVT_S_L:
11021         check_cp1_64bitmode(ctx);
11022         {
11023             TCGv_i32 fp32 = tcg_temp_new_i32();
11024             TCGv_i64 fp64 = tcg_temp_new_i64();
11025
11026             gen_load_fpr64(ctx, fp64, fs);
11027             gen_helper_float_cvts_l(fp32, cpu_env, fp64);
11028             tcg_temp_free_i64(fp64);
11029             gen_store_fpr32(ctx, fp32, fd);
11030             tcg_temp_free_i32(fp32);
11031         }
11032         break;
11033     case OPC_CVT_D_L:
11034         check_cp1_64bitmode(ctx);
11035         {
11036             TCGv_i64 fp0 = tcg_temp_new_i64();
11037
11038             gen_load_fpr64(ctx, fp0, fs);
11039             gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
11040             gen_store_fpr64(ctx, fp0, fd);
11041             tcg_temp_free_i64(fp0);
11042         }
11043         break;
11044     case OPC_CVT_PS_PW:
11045         check_ps(ctx);
11046         {
11047             TCGv_i64 fp0 = tcg_temp_new_i64();
11048
11049             gen_load_fpr64(ctx, fp0, fs);
11050             gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
11051             gen_store_fpr64(ctx, fp0, fd);
11052             tcg_temp_free_i64(fp0);
11053         }
11054         break;
11055     case OPC_ADD_PS:
11056         check_ps(ctx);
11057         {
11058             TCGv_i64 fp0 = tcg_temp_new_i64();
11059             TCGv_i64 fp1 = tcg_temp_new_i64();
11060
11061             gen_load_fpr64(ctx, fp0, fs);
11062             gen_load_fpr64(ctx, fp1, ft);
11063             gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
11064             tcg_temp_free_i64(fp1);
11065             gen_store_fpr64(ctx, fp0, fd);
11066             tcg_temp_free_i64(fp0);
11067         }
11068         break;
11069     case OPC_SUB_PS:
11070         check_ps(ctx);
11071         {
11072             TCGv_i64 fp0 = tcg_temp_new_i64();
11073             TCGv_i64 fp1 = tcg_temp_new_i64();
11074
11075             gen_load_fpr64(ctx, fp0, fs);
11076             gen_load_fpr64(ctx, fp1, ft);
11077             gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
11078             tcg_temp_free_i64(fp1);
11079             gen_store_fpr64(ctx, fp0, fd);
11080             tcg_temp_free_i64(fp0);
11081         }
11082         break;
11083     case OPC_MUL_PS:
11084         check_ps(ctx);
11085         {
11086             TCGv_i64 fp0 = tcg_temp_new_i64();
11087             TCGv_i64 fp1 = tcg_temp_new_i64();
11088
11089             gen_load_fpr64(ctx, fp0, fs);
11090             gen_load_fpr64(ctx, fp1, ft);
11091             gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
11092             tcg_temp_free_i64(fp1);
11093             gen_store_fpr64(ctx, fp0, fd);
11094             tcg_temp_free_i64(fp0);
11095         }
11096         break;
11097     case OPC_ABS_PS:
11098         check_ps(ctx);
11099         {
11100             TCGv_i64 fp0 = tcg_temp_new_i64();
11101
11102             gen_load_fpr64(ctx, fp0, fs);
11103             gen_helper_float_abs_ps(fp0, fp0);
11104             gen_store_fpr64(ctx, fp0, fd);
11105             tcg_temp_free_i64(fp0);
11106         }
11107         break;
11108     case OPC_MOV_PS:
11109         check_ps(ctx);
11110         {
11111             TCGv_i64 fp0 = tcg_temp_new_i64();
11112
11113             gen_load_fpr64(ctx, fp0, fs);
11114             gen_store_fpr64(ctx, fp0, fd);
11115             tcg_temp_free_i64(fp0);
11116         }
11117         break;
11118     case OPC_NEG_PS:
11119         check_ps(ctx);
11120         {
11121             TCGv_i64 fp0 = tcg_temp_new_i64();
11122
11123             gen_load_fpr64(ctx, fp0, fs);
11124             gen_helper_float_chs_ps(fp0, fp0);
11125             gen_store_fpr64(ctx, fp0, fd);
11126             tcg_temp_free_i64(fp0);
11127         }
11128         break;
11129     case OPC_MOVCF_PS:
11130         check_ps(ctx);
11131         gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11132         break;
11133     case OPC_MOVZ_PS:
11134         check_ps(ctx);
11135         {
11136             TCGLabel *l1 = gen_new_label();
11137             TCGv_i64 fp0;
11138
11139             if (ft != 0)
11140                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11141             fp0 = tcg_temp_new_i64();
11142             gen_load_fpr64(ctx, fp0, fs);
11143             gen_store_fpr64(ctx, fp0, fd);
11144             tcg_temp_free_i64(fp0);
11145             gen_set_label(l1);
11146         }
11147         break;
11148     case OPC_MOVN_PS:
11149         check_ps(ctx);
11150         {
11151             TCGLabel *l1 = gen_new_label();
11152             TCGv_i64 fp0;
11153
11154             if (ft != 0) {
11155                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11156                 fp0 = tcg_temp_new_i64();
11157                 gen_load_fpr64(ctx, fp0, fs);
11158                 gen_store_fpr64(ctx, fp0, fd);
11159                 tcg_temp_free_i64(fp0);
11160                 gen_set_label(l1);
11161             }
11162         }
11163         break;
11164     case OPC_ADDR_PS:
11165         check_ps(ctx);
11166         {
11167             TCGv_i64 fp0 = tcg_temp_new_i64();
11168             TCGv_i64 fp1 = tcg_temp_new_i64();
11169
11170             gen_load_fpr64(ctx, fp0, ft);
11171             gen_load_fpr64(ctx, fp1, fs);
11172             gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
11173             tcg_temp_free_i64(fp1);
11174             gen_store_fpr64(ctx, fp0, fd);
11175             tcg_temp_free_i64(fp0);
11176         }
11177         break;
11178     case OPC_MULR_PS:
11179         check_ps(ctx);
11180         {
11181             TCGv_i64 fp0 = tcg_temp_new_i64();
11182             TCGv_i64 fp1 = tcg_temp_new_i64();
11183
11184             gen_load_fpr64(ctx, fp0, ft);
11185             gen_load_fpr64(ctx, fp1, fs);
11186             gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
11187             tcg_temp_free_i64(fp1);
11188             gen_store_fpr64(ctx, fp0, fd);
11189             tcg_temp_free_i64(fp0);
11190         }
11191         break;
11192     case OPC_RECIP2_PS:
11193         check_ps(ctx);
11194         {
11195             TCGv_i64 fp0 = tcg_temp_new_i64();
11196             TCGv_i64 fp1 = tcg_temp_new_i64();
11197
11198             gen_load_fpr64(ctx, fp0, fs);
11199             gen_load_fpr64(ctx, fp1, ft);
11200             gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
11201             tcg_temp_free_i64(fp1);
11202             gen_store_fpr64(ctx, fp0, fd);
11203             tcg_temp_free_i64(fp0);
11204         }
11205         break;
11206     case OPC_RECIP1_PS:
11207         check_ps(ctx);
11208         {
11209             TCGv_i64 fp0 = tcg_temp_new_i64();
11210
11211             gen_load_fpr64(ctx, fp0, fs);
11212             gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
11213             gen_store_fpr64(ctx, fp0, fd);
11214             tcg_temp_free_i64(fp0);
11215         }
11216         break;
11217     case OPC_RSQRT1_PS:
11218         check_ps(ctx);
11219         {
11220             TCGv_i64 fp0 = tcg_temp_new_i64();
11221
11222             gen_load_fpr64(ctx, fp0, fs);
11223             gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
11224             gen_store_fpr64(ctx, fp0, fd);
11225             tcg_temp_free_i64(fp0);
11226         }
11227         break;
11228     case OPC_RSQRT2_PS:
11229         check_ps(ctx);
11230         {
11231             TCGv_i64 fp0 = tcg_temp_new_i64();
11232             TCGv_i64 fp1 = tcg_temp_new_i64();
11233
11234             gen_load_fpr64(ctx, fp0, fs);
11235             gen_load_fpr64(ctx, fp1, ft);
11236             gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
11237             tcg_temp_free_i64(fp1);
11238             gen_store_fpr64(ctx, fp0, fd);
11239             tcg_temp_free_i64(fp0);
11240         }
11241         break;
11242     case OPC_CVT_S_PU:
11243         check_cp1_64bitmode(ctx);
11244         {
11245             TCGv_i32 fp0 = tcg_temp_new_i32();
11246
11247             gen_load_fpr32h(ctx, fp0, fs);
11248             gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
11249             gen_store_fpr32(ctx, fp0, fd);
11250             tcg_temp_free_i32(fp0);
11251         }
11252         break;
11253     case OPC_CVT_PW_PS:
11254         check_ps(ctx);
11255         {
11256             TCGv_i64 fp0 = tcg_temp_new_i64();
11257
11258             gen_load_fpr64(ctx, fp0, fs);
11259             gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
11260             gen_store_fpr64(ctx, fp0, fd);
11261             tcg_temp_free_i64(fp0);
11262         }
11263         break;
11264     case OPC_CVT_S_PL:
11265         check_cp1_64bitmode(ctx);
11266         {
11267             TCGv_i32 fp0 = tcg_temp_new_i32();
11268
11269             gen_load_fpr32(ctx, fp0, fs);
11270             gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
11271             gen_store_fpr32(ctx, fp0, fd);
11272             tcg_temp_free_i32(fp0);
11273         }
11274         break;
11275     case OPC_PLL_PS:
11276         check_ps(ctx);
11277         {
11278             TCGv_i32 fp0 = tcg_temp_new_i32();
11279             TCGv_i32 fp1 = tcg_temp_new_i32();
11280
11281             gen_load_fpr32(ctx, fp0, fs);
11282             gen_load_fpr32(ctx, fp1, ft);
11283             gen_store_fpr32h(ctx, fp0, fd);
11284             gen_store_fpr32(ctx, fp1, fd);
11285             tcg_temp_free_i32(fp0);
11286             tcg_temp_free_i32(fp1);
11287         }
11288         break;
11289     case OPC_PLU_PS:
11290         check_ps(ctx);
11291         {
11292             TCGv_i32 fp0 = tcg_temp_new_i32();
11293             TCGv_i32 fp1 = tcg_temp_new_i32();
11294
11295             gen_load_fpr32(ctx, fp0, fs);
11296             gen_load_fpr32h(ctx, fp1, ft);
11297             gen_store_fpr32(ctx, fp1, fd);
11298             gen_store_fpr32h(ctx, fp0, fd);
11299             tcg_temp_free_i32(fp0);
11300             tcg_temp_free_i32(fp1);
11301         }
11302         break;
11303     case OPC_PUL_PS:
11304         check_ps(ctx);
11305         {
11306             TCGv_i32 fp0 = tcg_temp_new_i32();
11307             TCGv_i32 fp1 = tcg_temp_new_i32();
11308
11309             gen_load_fpr32h(ctx, fp0, fs);
11310             gen_load_fpr32(ctx, fp1, ft);
11311             gen_store_fpr32(ctx, fp1, fd);
11312             gen_store_fpr32h(ctx, fp0, fd);
11313             tcg_temp_free_i32(fp0);
11314             tcg_temp_free_i32(fp1);
11315         }
11316         break;
11317     case OPC_PUU_PS:
11318         check_ps(ctx);
11319         {
11320             TCGv_i32 fp0 = tcg_temp_new_i32();
11321             TCGv_i32 fp1 = tcg_temp_new_i32();
11322
11323             gen_load_fpr32h(ctx, fp0, fs);
11324             gen_load_fpr32h(ctx, fp1, ft);
11325             gen_store_fpr32(ctx, fp1, fd);
11326             gen_store_fpr32h(ctx, fp0, fd);
11327             tcg_temp_free_i32(fp0);
11328             tcg_temp_free_i32(fp1);
11329         }
11330         break;
11331     case OPC_CMP_F_PS:
11332     case OPC_CMP_UN_PS:
11333     case OPC_CMP_EQ_PS:
11334     case OPC_CMP_UEQ_PS:
11335     case OPC_CMP_OLT_PS:
11336     case OPC_CMP_ULT_PS:
11337     case OPC_CMP_OLE_PS:
11338     case OPC_CMP_ULE_PS:
11339     case OPC_CMP_SF_PS:
11340     case OPC_CMP_NGLE_PS:
11341     case OPC_CMP_SEQ_PS:
11342     case OPC_CMP_NGL_PS:
11343     case OPC_CMP_LT_PS:
11344     case OPC_CMP_NGE_PS:
11345     case OPC_CMP_LE_PS:
11346     case OPC_CMP_NGT_PS:
11347         if (ctx->opcode & (1 << 6)) {
11348             gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
11349         } else {
11350             gen_cmp_ps(ctx, func-48, ft, fs, cc);
11351         }
11352         break;
11353     default:
11354         MIPS_INVAL("farith");
11355         generate_exception_end(ctx, EXCP_RI);
11356         return;
11357     }
11358 }
11359
11360 /* Coprocessor 3 (FPU) */
11361 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
11362                            int fd, int fs, int base, int index)
11363 {
11364     TCGv t0 = tcg_temp_new();
11365
11366     if (base == 0) {
11367         gen_load_gpr(t0, index);
11368     } else if (index == 0) {
11369         gen_load_gpr(t0, base);
11370     } else {
11371         gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
11372     }
11373     /* Don't do NOP if destination is zero: we must perform the actual
11374        memory access. */
11375     switch (opc) {
11376     case OPC_LWXC1:
11377         check_cop1x(ctx);
11378         {
11379             TCGv_i32 fp0 = tcg_temp_new_i32();
11380
11381             tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
11382             tcg_gen_trunc_tl_i32(fp0, t0);
11383             gen_store_fpr32(ctx, fp0, fd);
11384             tcg_temp_free_i32(fp0);
11385         }
11386         break;
11387     case OPC_LDXC1:
11388         check_cop1x(ctx);
11389         check_cp1_registers(ctx, fd);
11390         {
11391             TCGv_i64 fp0 = tcg_temp_new_i64();
11392             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11393             gen_store_fpr64(ctx, fp0, fd);
11394             tcg_temp_free_i64(fp0);
11395         }
11396         break;
11397     case OPC_LUXC1:
11398         check_cp1_64bitmode(ctx);
11399         tcg_gen_andi_tl(t0, t0, ~0x7);
11400         {
11401             TCGv_i64 fp0 = tcg_temp_new_i64();
11402
11403             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11404             gen_store_fpr64(ctx, fp0, fd);
11405             tcg_temp_free_i64(fp0);
11406         }
11407         break;
11408     case OPC_SWXC1:
11409         check_cop1x(ctx);
11410         {
11411             TCGv_i32 fp0 = tcg_temp_new_i32();
11412             gen_load_fpr32(ctx, fp0, fs);
11413             tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
11414             tcg_temp_free_i32(fp0);
11415         }
11416         break;
11417     case OPC_SDXC1:
11418         check_cop1x(ctx);
11419         check_cp1_registers(ctx, fs);
11420         {
11421             TCGv_i64 fp0 = tcg_temp_new_i64();
11422             gen_load_fpr64(ctx, fp0, fs);
11423             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11424             tcg_temp_free_i64(fp0);
11425         }
11426         break;
11427     case OPC_SUXC1:
11428         check_cp1_64bitmode(ctx);
11429         tcg_gen_andi_tl(t0, t0, ~0x7);
11430         {
11431             TCGv_i64 fp0 = tcg_temp_new_i64();
11432             gen_load_fpr64(ctx, fp0, fs);
11433             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11434             tcg_temp_free_i64(fp0);
11435         }
11436         break;
11437     }
11438     tcg_temp_free(t0);
11439 }
11440
11441 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
11442                             int fd, int fr, int fs, int ft)
11443 {
11444     switch (opc) {
11445     case OPC_ALNV_PS:
11446         check_ps(ctx);
11447         {
11448             TCGv t0 = tcg_temp_local_new();
11449             TCGv_i32 fp = tcg_temp_new_i32();
11450             TCGv_i32 fph = tcg_temp_new_i32();
11451             TCGLabel *l1 = gen_new_label();
11452             TCGLabel *l2 = gen_new_label();
11453
11454             gen_load_gpr(t0, fr);
11455             tcg_gen_andi_tl(t0, t0, 0x7);
11456
11457             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
11458             gen_load_fpr32(ctx, fp, fs);
11459             gen_load_fpr32h(ctx, fph, fs);
11460             gen_store_fpr32(ctx, fp, fd);
11461             gen_store_fpr32h(ctx, fph, fd);
11462             tcg_gen_br(l2);
11463             gen_set_label(l1);
11464             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
11465             tcg_temp_free(t0);
11466 #ifdef TARGET_WORDS_BIGENDIAN
11467             gen_load_fpr32(ctx, fp, fs);
11468             gen_load_fpr32h(ctx, fph, ft);
11469             gen_store_fpr32h(ctx, fp, fd);
11470             gen_store_fpr32(ctx, fph, fd);
11471 #else
11472             gen_load_fpr32h(ctx, fph, fs);
11473             gen_load_fpr32(ctx, fp, ft);
11474             gen_store_fpr32(ctx, fph, fd);
11475             gen_store_fpr32h(ctx, fp, fd);
11476 #endif
11477             gen_set_label(l2);
11478             tcg_temp_free_i32(fp);
11479             tcg_temp_free_i32(fph);
11480         }
11481         break;
11482     case OPC_MADD_S:
11483         check_cop1x(ctx);
11484         {
11485             TCGv_i32 fp0 = tcg_temp_new_i32();
11486             TCGv_i32 fp1 = tcg_temp_new_i32();
11487             TCGv_i32 fp2 = tcg_temp_new_i32();
11488
11489             gen_load_fpr32(ctx, fp0, fs);
11490             gen_load_fpr32(ctx, fp1, ft);
11491             gen_load_fpr32(ctx, fp2, fr);
11492             gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
11493             tcg_temp_free_i32(fp0);
11494             tcg_temp_free_i32(fp1);
11495             gen_store_fpr32(ctx, fp2, fd);
11496             tcg_temp_free_i32(fp2);
11497         }
11498         break;
11499     case OPC_MADD_D:
11500         check_cop1x(ctx);
11501         check_cp1_registers(ctx, fd | fs | ft | fr);
11502         {
11503             TCGv_i64 fp0 = tcg_temp_new_i64();
11504             TCGv_i64 fp1 = tcg_temp_new_i64();
11505             TCGv_i64 fp2 = tcg_temp_new_i64();
11506
11507             gen_load_fpr64(ctx, fp0, fs);
11508             gen_load_fpr64(ctx, fp1, ft);
11509             gen_load_fpr64(ctx, fp2, fr);
11510             gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
11511             tcg_temp_free_i64(fp0);
11512             tcg_temp_free_i64(fp1);
11513             gen_store_fpr64(ctx, fp2, fd);
11514             tcg_temp_free_i64(fp2);
11515         }
11516         break;
11517     case OPC_MADD_PS:
11518         check_ps(ctx);
11519         {
11520             TCGv_i64 fp0 = tcg_temp_new_i64();
11521             TCGv_i64 fp1 = tcg_temp_new_i64();
11522             TCGv_i64 fp2 = tcg_temp_new_i64();
11523
11524             gen_load_fpr64(ctx, fp0, fs);
11525             gen_load_fpr64(ctx, fp1, ft);
11526             gen_load_fpr64(ctx, fp2, fr);
11527             gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
11528             tcg_temp_free_i64(fp0);
11529             tcg_temp_free_i64(fp1);
11530             gen_store_fpr64(ctx, fp2, fd);
11531             tcg_temp_free_i64(fp2);
11532         }
11533         break;
11534     case OPC_MSUB_S:
11535         check_cop1x(ctx);
11536         {
11537             TCGv_i32 fp0 = tcg_temp_new_i32();
11538             TCGv_i32 fp1 = tcg_temp_new_i32();
11539             TCGv_i32 fp2 = tcg_temp_new_i32();
11540
11541             gen_load_fpr32(ctx, fp0, fs);
11542             gen_load_fpr32(ctx, fp1, ft);
11543             gen_load_fpr32(ctx, fp2, fr);
11544             gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
11545             tcg_temp_free_i32(fp0);
11546             tcg_temp_free_i32(fp1);
11547             gen_store_fpr32(ctx, fp2, fd);
11548             tcg_temp_free_i32(fp2);
11549         }
11550         break;
11551     case OPC_MSUB_D:
11552         check_cop1x(ctx);
11553         check_cp1_registers(ctx, fd | fs | ft | fr);
11554         {
11555             TCGv_i64 fp0 = tcg_temp_new_i64();
11556             TCGv_i64 fp1 = tcg_temp_new_i64();
11557             TCGv_i64 fp2 = tcg_temp_new_i64();
11558
11559             gen_load_fpr64(ctx, fp0, fs);
11560             gen_load_fpr64(ctx, fp1, ft);
11561             gen_load_fpr64(ctx, fp2, fr);
11562             gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
11563             tcg_temp_free_i64(fp0);
11564             tcg_temp_free_i64(fp1);
11565             gen_store_fpr64(ctx, fp2, fd);
11566             tcg_temp_free_i64(fp2);
11567         }
11568         break;
11569     case OPC_MSUB_PS:
11570         check_ps(ctx);
11571         {
11572             TCGv_i64 fp0 = tcg_temp_new_i64();
11573             TCGv_i64 fp1 = tcg_temp_new_i64();
11574             TCGv_i64 fp2 = tcg_temp_new_i64();
11575
11576             gen_load_fpr64(ctx, fp0, fs);
11577             gen_load_fpr64(ctx, fp1, ft);
11578             gen_load_fpr64(ctx, fp2, fr);
11579             gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
11580             tcg_temp_free_i64(fp0);
11581             tcg_temp_free_i64(fp1);
11582             gen_store_fpr64(ctx, fp2, fd);
11583             tcg_temp_free_i64(fp2);
11584         }
11585         break;
11586     case OPC_NMADD_S:
11587         check_cop1x(ctx);
11588         {
11589             TCGv_i32 fp0 = tcg_temp_new_i32();
11590             TCGv_i32 fp1 = tcg_temp_new_i32();
11591             TCGv_i32 fp2 = tcg_temp_new_i32();
11592
11593             gen_load_fpr32(ctx, fp0, fs);
11594             gen_load_fpr32(ctx, fp1, ft);
11595             gen_load_fpr32(ctx, fp2, fr);
11596             gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
11597             tcg_temp_free_i32(fp0);
11598             tcg_temp_free_i32(fp1);
11599             gen_store_fpr32(ctx, fp2, fd);
11600             tcg_temp_free_i32(fp2);
11601         }
11602         break;
11603     case OPC_NMADD_D:
11604         check_cop1x(ctx);
11605         check_cp1_registers(ctx, fd | fs | ft | fr);
11606         {
11607             TCGv_i64 fp0 = tcg_temp_new_i64();
11608             TCGv_i64 fp1 = tcg_temp_new_i64();
11609             TCGv_i64 fp2 = tcg_temp_new_i64();
11610
11611             gen_load_fpr64(ctx, fp0, fs);
11612             gen_load_fpr64(ctx, fp1, ft);
11613             gen_load_fpr64(ctx, fp2, fr);
11614             gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
11615             tcg_temp_free_i64(fp0);
11616             tcg_temp_free_i64(fp1);
11617             gen_store_fpr64(ctx, fp2, fd);
11618             tcg_temp_free_i64(fp2);
11619         }
11620         break;
11621     case OPC_NMADD_PS:
11622         check_ps(ctx);
11623         {
11624             TCGv_i64 fp0 = tcg_temp_new_i64();
11625             TCGv_i64 fp1 = tcg_temp_new_i64();
11626             TCGv_i64 fp2 = tcg_temp_new_i64();
11627
11628             gen_load_fpr64(ctx, fp0, fs);
11629             gen_load_fpr64(ctx, fp1, ft);
11630             gen_load_fpr64(ctx, fp2, fr);
11631             gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
11632             tcg_temp_free_i64(fp0);
11633             tcg_temp_free_i64(fp1);
11634             gen_store_fpr64(ctx, fp2, fd);
11635             tcg_temp_free_i64(fp2);
11636         }
11637         break;
11638     case OPC_NMSUB_S:
11639         check_cop1x(ctx);
11640         {
11641             TCGv_i32 fp0 = tcg_temp_new_i32();
11642             TCGv_i32 fp1 = tcg_temp_new_i32();
11643             TCGv_i32 fp2 = tcg_temp_new_i32();
11644
11645             gen_load_fpr32(ctx, fp0, fs);
11646             gen_load_fpr32(ctx, fp1, ft);
11647             gen_load_fpr32(ctx, fp2, fr);
11648             gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
11649             tcg_temp_free_i32(fp0);
11650             tcg_temp_free_i32(fp1);
11651             gen_store_fpr32(ctx, fp2, fd);
11652             tcg_temp_free_i32(fp2);
11653         }
11654         break;
11655     case OPC_NMSUB_D:
11656         check_cop1x(ctx);
11657         check_cp1_registers(ctx, fd | fs | ft | fr);
11658         {
11659             TCGv_i64 fp0 = tcg_temp_new_i64();
11660             TCGv_i64 fp1 = tcg_temp_new_i64();
11661             TCGv_i64 fp2 = tcg_temp_new_i64();
11662
11663             gen_load_fpr64(ctx, fp0, fs);
11664             gen_load_fpr64(ctx, fp1, ft);
11665             gen_load_fpr64(ctx, fp2, fr);
11666             gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
11667             tcg_temp_free_i64(fp0);
11668             tcg_temp_free_i64(fp1);
11669             gen_store_fpr64(ctx, fp2, fd);
11670             tcg_temp_free_i64(fp2);
11671         }
11672         break;
11673     case OPC_NMSUB_PS:
11674         check_ps(ctx);
11675         {
11676             TCGv_i64 fp0 = tcg_temp_new_i64();
11677             TCGv_i64 fp1 = tcg_temp_new_i64();
11678             TCGv_i64 fp2 = tcg_temp_new_i64();
11679
11680             gen_load_fpr64(ctx, fp0, fs);
11681             gen_load_fpr64(ctx, fp1, ft);
11682             gen_load_fpr64(ctx, fp2, fr);
11683             gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
11684             tcg_temp_free_i64(fp0);
11685             tcg_temp_free_i64(fp1);
11686             gen_store_fpr64(ctx, fp2, fd);
11687             tcg_temp_free_i64(fp2);
11688         }
11689         break;
11690     default:
11691         MIPS_INVAL("flt3_arith");
11692         generate_exception_end(ctx, EXCP_RI);
11693         return;
11694     }
11695 }
11696
11697 static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
11698 {
11699     TCGv t0;
11700
11701 #if !defined(CONFIG_USER_ONLY)
11702     /* The Linux kernel will emulate rdhwr if it's not supported natively.
11703        Therefore only check the ISA in system mode.  */
11704     check_insn(ctx, ISA_MIPS32R2);
11705 #endif
11706     t0 = tcg_temp_new();
11707
11708     switch (rd) {
11709     case 0:
11710         gen_helper_rdhwr_cpunum(t0, cpu_env);
11711         gen_store_gpr(t0, rt);
11712         break;
11713     case 1:
11714         gen_helper_rdhwr_synci_step(t0, cpu_env);
11715         gen_store_gpr(t0, rt);
11716         break;
11717     case 2:
11718         if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
11719             gen_io_start();
11720         }
11721         gen_helper_rdhwr_cc(t0, cpu_env);
11722         if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
11723             gen_io_end();
11724         }
11725         gen_store_gpr(t0, rt);
11726         /* Break the TB to be able to take timer interrupts immediately
11727            after reading count. DISAS_STOP isn't sufficient, we need to ensure
11728            we break completely out of translated code.  */
11729         gen_save_pc(ctx->base.pc_next + 4);
11730         ctx->base.is_jmp = DISAS_EXIT;
11731         break;
11732     case 3:
11733         gen_helper_rdhwr_ccres(t0, cpu_env);
11734         gen_store_gpr(t0, rt);
11735         break;
11736     case 4:
11737         check_insn(ctx, ISA_MIPS32R6);
11738         if (sel != 0) {
11739             /* Performance counter registers are not implemented other than
11740              * control register 0.
11741              */
11742             generate_exception(ctx, EXCP_RI);
11743         }
11744         gen_helper_rdhwr_performance(t0, cpu_env);
11745         gen_store_gpr(t0, rt);
11746         break;
11747     case 5:
11748         check_insn(ctx, ISA_MIPS32R6);
11749         gen_helper_rdhwr_xnp(t0, cpu_env);
11750         gen_store_gpr(t0, rt);
11751         break;
11752     case 29:
11753 #if defined(CONFIG_USER_ONLY)
11754         tcg_gen_ld_tl(t0, cpu_env,
11755                       offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
11756         gen_store_gpr(t0, rt);
11757         break;
11758 #else
11759         if ((ctx->hflags & MIPS_HFLAG_CP0) ||
11760             (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
11761             tcg_gen_ld_tl(t0, cpu_env,
11762                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
11763             gen_store_gpr(t0, rt);
11764         } else {
11765             generate_exception_end(ctx, EXCP_RI);
11766         }
11767         break;
11768 #endif
11769     default:            /* Invalid */
11770         MIPS_INVAL("rdhwr");
11771         generate_exception_end(ctx, EXCP_RI);
11772         break;
11773     }
11774     tcg_temp_free(t0);
11775 }
11776
11777 static inline void clear_branch_hflags(DisasContext *ctx)
11778 {
11779     ctx->hflags &= ~MIPS_HFLAG_BMASK;
11780     if (ctx->base.is_jmp == DISAS_NEXT) {
11781         save_cpu_state(ctx, 0);
11782     } else {
11783         /* it is not safe to save ctx->hflags as hflags may be changed
11784            in execution time by the instruction in delay / forbidden slot. */
11785         tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
11786     }
11787 }
11788
11789 static void gen_branch(DisasContext *ctx, int insn_bytes)
11790 {
11791     if (ctx->hflags & MIPS_HFLAG_BMASK) {
11792         int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
11793         /* Branches completion */
11794         clear_branch_hflags(ctx);
11795         ctx->base.is_jmp = DISAS_NORETURN;
11796         /* FIXME: Need to clear can_do_io.  */
11797         switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
11798         case MIPS_HFLAG_FBNSLOT:
11799             gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
11800             break;
11801         case MIPS_HFLAG_B:
11802             /* unconditional branch */
11803             if (proc_hflags & MIPS_HFLAG_BX) {
11804                 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
11805             }
11806             gen_goto_tb(ctx, 0, ctx->btarget);
11807             break;
11808         case MIPS_HFLAG_BL:
11809             /* blikely taken case */
11810             gen_goto_tb(ctx, 0, ctx->btarget);
11811             break;
11812         case MIPS_HFLAG_BC:
11813             /* Conditional branch */
11814             {
11815                 TCGLabel *l1 = gen_new_label();
11816
11817                 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
11818                 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
11819                 gen_set_label(l1);
11820                 gen_goto_tb(ctx, 0, ctx->btarget);
11821             }
11822             break;
11823         case MIPS_HFLAG_BR:
11824             /* unconditional branch to register */
11825             if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
11826                 TCGv t0 = tcg_temp_new();
11827                 TCGv_i32 t1 = tcg_temp_new_i32();
11828
11829                 tcg_gen_andi_tl(t0, btarget, 0x1);
11830                 tcg_gen_trunc_tl_i32(t1, t0);
11831                 tcg_temp_free(t0);
11832                 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
11833                 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
11834                 tcg_gen_or_i32(hflags, hflags, t1);
11835                 tcg_temp_free_i32(t1);
11836
11837                 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
11838             } else {
11839                 tcg_gen_mov_tl(cpu_PC, btarget);
11840             }
11841             if (ctx->base.singlestep_enabled) {
11842                 save_cpu_state(ctx, 0);
11843                 gen_helper_raise_exception_debug(cpu_env);
11844             }
11845             tcg_gen_lookup_and_goto_ptr();
11846             break;
11847         default:
11848             fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
11849             abort();
11850         }
11851     }
11852 }
11853
11854 /* Compact Branches */
11855 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
11856                                        int rs, int rt, int32_t offset)
11857 {
11858     int bcond_compute = 0;
11859     TCGv t0 = tcg_temp_new();
11860     TCGv t1 = tcg_temp_new();
11861     int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
11862
11863     if (ctx->hflags & MIPS_HFLAG_BMASK) {
11864 #ifdef MIPS_DEBUG_DISAS
11865         LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
11866                   "\n", ctx->base.pc_next);
11867 #endif
11868         generate_exception_end(ctx, EXCP_RI);
11869         goto out;
11870     }
11871
11872     /* Load needed operands and calculate btarget */
11873     switch (opc) {
11874     /* compact branch */
11875     case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11876     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11877         gen_load_gpr(t0, rs);
11878         gen_load_gpr(t1, rt);
11879         bcond_compute = 1;
11880         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11881         if (rs <= rt && rs == 0) {
11882             /* OPC_BEQZALC, OPC_BNEZALC */
11883             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11884         }
11885         break;
11886     case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11887     case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11888         gen_load_gpr(t0, rs);
11889         gen_load_gpr(t1, rt);
11890         bcond_compute = 1;
11891         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11892         break;
11893     case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11894     case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11895         if (rs == 0 || rs == rt) {
11896             /* OPC_BLEZALC, OPC_BGEZALC */
11897             /* OPC_BGTZALC, OPC_BLTZALC */
11898             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11899         }
11900         gen_load_gpr(t0, rs);
11901         gen_load_gpr(t1, rt);
11902         bcond_compute = 1;
11903         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11904         break;
11905     case OPC_BC:
11906     case OPC_BALC:
11907         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11908         break;
11909     case OPC_BEQZC:
11910     case OPC_BNEZC:
11911         if (rs != 0) {
11912             /* OPC_BEQZC, OPC_BNEZC */
11913             gen_load_gpr(t0, rs);
11914             bcond_compute = 1;
11915             ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11916         } else {
11917             /* OPC_JIC, OPC_JIALC */
11918             TCGv tbase = tcg_temp_new();
11919             TCGv toffset = tcg_temp_new();
11920
11921             gen_load_gpr(tbase, rt);
11922             tcg_gen_movi_tl(toffset, offset);
11923             gen_op_addr_add(ctx, btarget, tbase, toffset);
11924             tcg_temp_free(tbase);
11925             tcg_temp_free(toffset);
11926         }
11927         break;
11928     default:
11929         MIPS_INVAL("Compact branch/jump");
11930         generate_exception_end(ctx, EXCP_RI);
11931         goto out;
11932     }
11933
11934     if (bcond_compute == 0) {
11935         /* Uncoditional compact branch */
11936         switch (opc) {
11937         case OPC_JIALC:
11938             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11939             /* Fallthrough */
11940         case OPC_JIC:
11941             ctx->hflags |= MIPS_HFLAG_BR;
11942             break;
11943         case OPC_BALC:
11944             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11945             /* Fallthrough */
11946         case OPC_BC:
11947             ctx->hflags |= MIPS_HFLAG_B;
11948             break;
11949         default:
11950             MIPS_INVAL("Compact branch/jump");
11951             generate_exception_end(ctx, EXCP_RI);
11952             goto out;
11953         }
11954
11955         /* Generating branch here as compact branches don't have delay slot */
11956         gen_branch(ctx, 4);
11957     } else {
11958         /* Conditional compact branch */
11959         TCGLabel *fs = gen_new_label();
11960         save_cpu_state(ctx, 0);
11961
11962         switch (opc) {
11963         case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11964             if (rs == 0 && rt != 0) {
11965                 /* OPC_BLEZALC */
11966                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11967             } else if (rs != 0 && rt != 0 && rs == rt) {
11968                 /* OPC_BGEZALC */
11969                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11970             } else {
11971                 /* OPC_BGEUC */
11972                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
11973             }
11974             break;
11975         case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11976             if (rs == 0 && rt != 0) {
11977                 /* OPC_BGTZALC */
11978                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11979             } else if (rs != 0 && rt != 0 && rs == rt) {
11980                 /* OPC_BLTZALC */
11981                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11982             } else {
11983                 /* OPC_BLTUC */
11984                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
11985             }
11986             break;
11987         case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11988             if (rs == 0 && rt != 0) {
11989                 /* OPC_BLEZC */
11990                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11991             } else if (rs != 0 && rt != 0 && rs == rt) {
11992                 /* OPC_BGEZC */
11993                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11994             } else {
11995                 /* OPC_BGEC */
11996                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
11997             }
11998             break;
11999         case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12000             if (rs == 0 && rt != 0) {
12001                 /* OPC_BGTZC */
12002                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12003             } else if (rs != 0 && rt != 0 && rs == rt) {
12004                 /* OPC_BLTZC */
12005                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12006             } else {
12007                 /* OPC_BLTC */
12008                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
12009             }
12010             break;
12011         case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12012         case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12013             if (rs >= rt) {
12014                 /* OPC_BOVC, OPC_BNVC */
12015                 TCGv t2 = tcg_temp_new();
12016                 TCGv t3 = tcg_temp_new();
12017                 TCGv t4 = tcg_temp_new();
12018                 TCGv input_overflow = tcg_temp_new();
12019
12020                 gen_load_gpr(t0, rs);
12021                 gen_load_gpr(t1, rt);
12022                 tcg_gen_ext32s_tl(t2, t0);
12023                 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
12024                 tcg_gen_ext32s_tl(t3, t1);
12025                 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
12026                 tcg_gen_or_tl(input_overflow, input_overflow, t4);
12027
12028                 tcg_gen_add_tl(t4, t2, t3);
12029                 tcg_gen_ext32s_tl(t4, t4);
12030                 tcg_gen_xor_tl(t2, t2, t3);
12031                 tcg_gen_xor_tl(t3, t4, t3);
12032                 tcg_gen_andc_tl(t2, t3, t2);
12033                 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
12034                 tcg_gen_or_tl(t4, t4, input_overflow);
12035                 if (opc == OPC_BOVC) {
12036                     /* OPC_BOVC */
12037                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
12038                 } else {
12039                     /* OPC_BNVC */
12040                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
12041                 }
12042                 tcg_temp_free(input_overflow);
12043                 tcg_temp_free(t4);
12044                 tcg_temp_free(t3);
12045                 tcg_temp_free(t2);
12046             } else if (rs < rt && rs == 0) {
12047                 /* OPC_BEQZALC, OPC_BNEZALC */
12048                 if (opc == OPC_BEQZALC) {
12049                     /* OPC_BEQZALC */
12050                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
12051                 } else {
12052                     /* OPC_BNEZALC */
12053                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
12054                 }
12055             } else {
12056                 /* OPC_BEQC, OPC_BNEC */
12057                 if (opc == OPC_BEQC) {
12058                     /* OPC_BEQC */
12059                     tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
12060                 } else {
12061                     /* OPC_BNEC */
12062                     tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
12063                 }
12064             }
12065             break;
12066         case OPC_BEQZC:
12067             tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
12068             break;
12069         case OPC_BNEZC:
12070             tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
12071             break;
12072         default:
12073             MIPS_INVAL("Compact conditional branch/jump");
12074             generate_exception_end(ctx, EXCP_RI);
12075             goto out;
12076         }
12077
12078         /* Generating branch here as compact branches don't have delay slot */
12079         gen_goto_tb(ctx, 1, ctx->btarget);
12080         gen_set_label(fs);
12081
12082         ctx->hflags |= MIPS_HFLAG_FBNSLOT;
12083     }
12084
12085 out:
12086     tcg_temp_free(t0);
12087     tcg_temp_free(t1);
12088 }
12089
12090 /* ISA extensions (ASEs) */
12091 /* MIPS16 extension to MIPS32 */
12092
12093 /* MIPS16 major opcodes */
12094 enum {
12095   M16_OPC_ADDIUSP = 0x00,
12096   M16_OPC_ADDIUPC = 0x01,
12097   M16_OPC_B = 0x02,
12098   M16_OPC_JAL = 0x03,
12099   M16_OPC_BEQZ = 0x04,
12100   M16_OPC_BNEQZ = 0x05,
12101   M16_OPC_SHIFT = 0x06,
12102   M16_OPC_LD = 0x07,
12103   M16_OPC_RRIA = 0x08,
12104   M16_OPC_ADDIU8 = 0x09,
12105   M16_OPC_SLTI = 0x0a,
12106   M16_OPC_SLTIU = 0x0b,
12107   M16_OPC_I8 = 0x0c,
12108   M16_OPC_LI = 0x0d,
12109   M16_OPC_CMPI = 0x0e,
12110   M16_OPC_SD = 0x0f,
12111   M16_OPC_LB = 0x10,
12112   M16_OPC_LH = 0x11,
12113   M16_OPC_LWSP = 0x12,
12114   M16_OPC_LW = 0x13,
12115   M16_OPC_LBU = 0x14,
12116   M16_OPC_LHU = 0x15,
12117   M16_OPC_LWPC = 0x16,
12118   M16_OPC_LWU = 0x17,
12119   M16_OPC_SB = 0x18,
12120   M16_OPC_SH = 0x19,
12121   M16_OPC_SWSP = 0x1a,
12122   M16_OPC_SW = 0x1b,
12123   M16_OPC_RRR = 0x1c,
12124   M16_OPC_RR = 0x1d,
12125   M16_OPC_EXTEND = 0x1e,
12126   M16_OPC_I64 = 0x1f
12127 };
12128
12129 /* I8 funct field */
12130 enum {
12131   I8_BTEQZ = 0x0,
12132   I8_BTNEZ = 0x1,
12133   I8_SWRASP = 0x2,
12134   I8_ADJSP = 0x3,
12135   I8_SVRS = 0x4,
12136   I8_MOV32R = 0x5,
12137   I8_MOVR32 = 0x7
12138 };
12139
12140 /* RRR f field */
12141 enum {
12142   RRR_DADDU = 0x0,
12143   RRR_ADDU = 0x1,
12144   RRR_DSUBU = 0x2,
12145   RRR_SUBU = 0x3
12146 };
12147
12148 /* RR funct field */
12149 enum {
12150   RR_JR = 0x00,
12151   RR_SDBBP = 0x01,
12152   RR_SLT = 0x02,
12153   RR_SLTU = 0x03,
12154   RR_SLLV = 0x04,
12155   RR_BREAK = 0x05,
12156   RR_SRLV = 0x06,
12157   RR_SRAV = 0x07,
12158   RR_DSRL = 0x08,
12159   RR_CMP = 0x0a,
12160   RR_NEG = 0x0b,
12161   RR_AND = 0x0c,
12162   RR_OR = 0x0d,
12163   RR_XOR = 0x0e,
12164   RR_NOT = 0x0f,
12165   RR_MFHI = 0x10,
12166   RR_CNVT = 0x11,
12167   RR_MFLO = 0x12,
12168   RR_DSRA = 0x13,
12169   RR_DSLLV = 0x14,
12170   RR_DSRLV = 0x16,
12171   RR_DSRAV = 0x17,
12172   RR_MULT = 0x18,
12173   RR_MULTU = 0x19,
12174   RR_DIV = 0x1a,
12175   RR_DIVU = 0x1b,
12176   RR_DMULT = 0x1c,
12177   RR_DMULTU = 0x1d,
12178   RR_DDIV = 0x1e,
12179   RR_DDIVU = 0x1f
12180 };
12181
12182 /* I64 funct field */
12183 enum {
12184   I64_LDSP = 0x0,
12185   I64_SDSP = 0x1,
12186   I64_SDRASP = 0x2,
12187   I64_DADJSP = 0x3,
12188   I64_LDPC = 0x4,
12189   I64_DADDIU5 = 0x5,
12190   I64_DADDIUPC = 0x6,
12191   I64_DADDIUSP = 0x7
12192 };
12193
12194 /* RR ry field for CNVT */
12195 enum {
12196   RR_RY_CNVT_ZEB = 0x0,
12197   RR_RY_CNVT_ZEH = 0x1,
12198   RR_RY_CNVT_ZEW = 0x2,
12199   RR_RY_CNVT_SEB = 0x4,
12200   RR_RY_CNVT_SEH = 0x5,
12201   RR_RY_CNVT_SEW = 0x6,
12202 };
12203
12204 static int xlat (int r)
12205 {
12206   static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12207
12208   return map[r];
12209 }
12210
12211 static void gen_mips16_save (DisasContext *ctx,
12212                              int xsregs, int aregs,
12213                              int do_ra, int do_s0, int do_s1,
12214                              int framesize)
12215 {
12216     TCGv t0 = tcg_temp_new();
12217     TCGv t1 = tcg_temp_new();
12218     TCGv t2 = tcg_temp_new();
12219     int args, astatic;
12220
12221     switch (aregs) {
12222     case 0:
12223     case 1:
12224     case 2:
12225     case 3:
12226     case 11:
12227         args = 0;
12228         break;
12229     case 4:
12230     case 5:
12231     case 6:
12232     case 7:
12233         args = 1;
12234         break;
12235     case 8:
12236     case 9:
12237     case 10:
12238         args = 2;
12239         break;
12240     case 12:
12241     case 13:
12242         args = 3;
12243         break;
12244     case 14:
12245         args = 4;
12246         break;
12247     default:
12248         generate_exception_end(ctx, EXCP_RI);
12249         return;
12250     }
12251
12252     switch (args) {
12253     case 4:
12254         gen_base_offset_addr(ctx, t0, 29, 12);
12255         gen_load_gpr(t1, 7);
12256         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12257         /* Fall through */
12258     case 3:
12259         gen_base_offset_addr(ctx, t0, 29, 8);
12260         gen_load_gpr(t1, 6);
12261         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12262         /* Fall through */
12263     case 2:
12264         gen_base_offset_addr(ctx, t0, 29, 4);
12265         gen_load_gpr(t1, 5);
12266         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12267         /* Fall through */
12268     case 1:
12269         gen_base_offset_addr(ctx, t0, 29, 0);
12270         gen_load_gpr(t1, 4);
12271         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12272     }
12273
12274     gen_load_gpr(t0, 29);
12275
12276 #define DECR_AND_STORE(reg) do {                                 \
12277         tcg_gen_movi_tl(t2, -4);                                 \
12278         gen_op_addr_add(ctx, t0, t0, t2);                        \
12279         gen_load_gpr(t1, reg);                                   \
12280         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
12281     } while (0)
12282
12283     if (do_ra) {
12284         DECR_AND_STORE(31);
12285     }
12286
12287     switch (xsregs) {
12288     case 7:
12289         DECR_AND_STORE(30);
12290         /* Fall through */
12291     case 6:
12292         DECR_AND_STORE(23);
12293         /* Fall through */
12294     case 5:
12295         DECR_AND_STORE(22);
12296         /* Fall through */
12297     case 4:
12298         DECR_AND_STORE(21);
12299         /* Fall through */
12300     case 3:
12301         DECR_AND_STORE(20);
12302         /* Fall through */
12303     case 2:
12304         DECR_AND_STORE(19);
12305         /* Fall through */
12306     case 1:
12307         DECR_AND_STORE(18);
12308     }
12309
12310     if (do_s1) {
12311         DECR_AND_STORE(17);
12312     }
12313     if (do_s0) {
12314         DECR_AND_STORE(16);
12315     }
12316
12317     switch (aregs) {
12318     case 0:
12319     case 4:
12320     case 8:
12321     case 12:
12322     case 14:
12323         astatic = 0;
12324         break;
12325     case 1:
12326     case 5:
12327     case 9:
12328     case 13:
12329         astatic = 1;
12330         break;
12331     case 2:
12332     case 6:
12333     case 10:
12334         astatic = 2;
12335         break;
12336     case 3:
12337     case 7:
12338         astatic = 3;
12339         break;
12340     case 11:
12341         astatic = 4;
12342         break;
12343     default:
12344         generate_exception_end(ctx, EXCP_RI);
12345         return;
12346     }
12347
12348     if (astatic > 0) {
12349         DECR_AND_STORE(7);
12350         if (astatic > 1) {
12351             DECR_AND_STORE(6);
12352             if (astatic > 2) {
12353                 DECR_AND_STORE(5);
12354                 if (astatic > 3) {
12355                     DECR_AND_STORE(4);
12356                 }
12357             }
12358         }
12359     }
12360 #undef DECR_AND_STORE
12361
12362     tcg_gen_movi_tl(t2, -framesize);
12363     gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
12364     tcg_temp_free(t0);
12365     tcg_temp_free(t1);
12366     tcg_temp_free(t2);
12367 }
12368
12369 static void gen_mips16_restore (DisasContext *ctx,
12370                                 int xsregs, int aregs,
12371                                 int do_ra, int do_s0, int do_s1,
12372                                 int framesize)
12373 {
12374     int astatic;
12375     TCGv t0 = tcg_temp_new();
12376     TCGv t1 = tcg_temp_new();
12377     TCGv t2 = tcg_temp_new();
12378
12379     tcg_gen_movi_tl(t2, framesize);
12380     gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
12381
12382 #define DECR_AND_LOAD(reg) do {                            \
12383         tcg_gen_movi_tl(t2, -4);                           \
12384         gen_op_addr_add(ctx, t0, t0, t2);                  \
12385         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
12386         gen_store_gpr(t1, reg);                            \
12387     } while (0)
12388
12389     if (do_ra) {
12390         DECR_AND_LOAD(31);
12391     }
12392
12393     switch (xsregs) {
12394     case 7:
12395         DECR_AND_LOAD(30);
12396         /* Fall through */
12397     case 6:
12398         DECR_AND_LOAD(23);
12399         /* Fall through */
12400     case 5:
12401         DECR_AND_LOAD(22);
12402         /* Fall through */
12403     case 4:
12404         DECR_AND_LOAD(21);
12405         /* Fall through */
12406     case 3:
12407         DECR_AND_LOAD(20);
12408         /* Fall through */
12409     case 2:
12410         DECR_AND_LOAD(19);
12411         /* Fall through */
12412     case 1:
12413         DECR_AND_LOAD(18);
12414     }
12415
12416     if (do_s1) {
12417         DECR_AND_LOAD(17);
12418     }
12419     if (do_s0) {
12420         DECR_AND_LOAD(16);
12421     }
12422
12423     switch (aregs) {
12424     case 0:
12425     case 4:
12426     case 8:
12427     case 12:
12428     case 14:
12429         astatic = 0;
12430         break;
12431     case 1:
12432     case 5:
12433     case 9:
12434     case 13:
12435         astatic = 1;
12436         break;
12437     case 2:
12438     case 6:
12439     case 10:
12440         astatic = 2;
12441         break;
12442     case 3:
12443     case 7:
12444         astatic = 3;
12445         break;
12446     case 11:
12447         astatic = 4;
12448         break;
12449     default:
12450         generate_exception_end(ctx, EXCP_RI);
12451         return;
12452     }
12453
12454     if (astatic > 0) {
12455         DECR_AND_LOAD(7);
12456         if (astatic > 1) {
12457             DECR_AND_LOAD(6);
12458             if (astatic > 2) {
12459                 DECR_AND_LOAD(5);
12460                 if (astatic > 3) {
12461                     DECR_AND_LOAD(4);
12462                 }
12463             }
12464         }
12465     }
12466 #undef DECR_AND_LOAD
12467
12468     tcg_gen_movi_tl(t2, framesize);
12469     gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
12470     tcg_temp_free(t0);
12471     tcg_temp_free(t1);
12472     tcg_temp_free(t2);
12473 }
12474
12475 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
12476                          int is_64_bit, int extended)
12477 {
12478     TCGv t0;
12479
12480     if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
12481         generate_exception_end(ctx, EXCP_RI);
12482         return;
12483     }
12484
12485     t0 = tcg_temp_new();
12486
12487     tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
12488     tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
12489     if (!is_64_bit) {
12490         tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12491     }
12492
12493     tcg_temp_free(t0);
12494 }
12495
12496 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
12497                                 int16_t offset)
12498 {
12499     TCGv_i32 t0 = tcg_const_i32(op);
12500     TCGv t1 = tcg_temp_new();
12501     gen_base_offset_addr(ctx, t1, base, offset);
12502     gen_helper_cache(cpu_env, t1, t0);
12503 }
12504
12505 #if defined(TARGET_MIPS64)
12506 static void decode_i64_mips16 (DisasContext *ctx,
12507                                int ry, int funct, int16_t offset,
12508                                int extended)
12509 {
12510     switch (funct) {
12511     case I64_LDSP:
12512         check_insn(ctx, ISA_MIPS3);
12513         check_mips_64(ctx);
12514         offset = extended ? offset : offset << 3;
12515         gen_ld(ctx, OPC_LD, ry, 29, offset);
12516         break;
12517     case I64_SDSP:
12518         check_insn(ctx, ISA_MIPS3);
12519         check_mips_64(ctx);
12520         offset = extended ? offset : offset << 3;
12521         gen_st(ctx, OPC_SD, ry, 29, offset);
12522         break;
12523     case I64_SDRASP:
12524         check_insn(ctx, ISA_MIPS3);
12525         check_mips_64(ctx);
12526         offset = extended ? offset : (ctx->opcode & 0xff) << 3;
12527         gen_st(ctx, OPC_SD, 31, 29, offset);
12528         break;
12529     case I64_DADJSP:
12530         check_insn(ctx, ISA_MIPS3);
12531         check_mips_64(ctx);
12532         offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
12533         gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
12534         break;
12535     case I64_LDPC:
12536         check_insn(ctx, ISA_MIPS3);
12537         check_mips_64(ctx);
12538         if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
12539             generate_exception_end(ctx, EXCP_RI);
12540         } else {
12541             offset = extended ? offset : offset << 3;
12542             gen_ld(ctx, OPC_LDPC, ry, 0, offset);
12543         }
12544         break;
12545     case I64_DADDIU5:
12546         check_insn(ctx, ISA_MIPS3);
12547         check_mips_64(ctx);
12548         offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
12549         gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
12550         break;
12551     case I64_DADDIUPC:
12552         check_insn(ctx, ISA_MIPS3);
12553         check_mips_64(ctx);
12554         offset = extended ? offset : offset << 2;
12555         gen_addiupc(ctx, ry, offset, 1, extended);
12556         break;
12557     case I64_DADDIUSP:
12558         check_insn(ctx, ISA_MIPS3);
12559         check_mips_64(ctx);
12560         offset = extended ? offset : offset << 2;
12561         gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
12562         break;
12563     }
12564 }
12565 #endif
12566
12567 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
12568 {
12569     int extend = cpu_lduw_code(env, ctx->base.pc_next + 2);
12570     int op, rx, ry, funct, sa;
12571     int16_t imm, offset;
12572
12573     ctx->opcode = (ctx->opcode << 16) | extend;
12574     op = (ctx->opcode >> 11) & 0x1f;
12575     sa = (ctx->opcode >> 22) & 0x1f;
12576     funct = (ctx->opcode >> 8) & 0x7;
12577     rx = xlat((ctx->opcode >> 8) & 0x7);
12578     ry = xlat((ctx->opcode >> 5) & 0x7);
12579     offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
12580                               | ((ctx->opcode >> 21) & 0x3f) << 5
12581                               | (ctx->opcode & 0x1f));
12582
12583     /* The extended opcodes cleverly reuse the opcodes from their 16-bit
12584        counterparts.  */
12585     switch (op) {
12586     case M16_OPC_ADDIUSP:
12587         gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
12588         break;
12589     case M16_OPC_ADDIUPC:
12590         gen_addiupc(ctx, rx, imm, 0, 1);
12591         break;
12592     case M16_OPC_B:
12593         gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
12594         /* No delay slot, so just process as a normal instruction */
12595         break;
12596     case M16_OPC_BEQZ:
12597         gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
12598         /* No delay slot, so just process as a normal instruction */
12599         break;
12600     case M16_OPC_BNEQZ:
12601         gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
12602         /* No delay slot, so just process as a normal instruction */
12603         break;
12604     case M16_OPC_SHIFT:
12605         switch (ctx->opcode & 0x3) {
12606         case 0x0:
12607             gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
12608             break;
12609         case 0x1:
12610 #if defined(TARGET_MIPS64)
12611             check_mips_64(ctx);
12612             gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
12613 #else
12614             generate_exception_end(ctx, EXCP_RI);
12615 #endif
12616             break;
12617         case 0x2:
12618             gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
12619             break;
12620         case 0x3:
12621             gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
12622             break;
12623         }
12624         break;
12625 #if defined(TARGET_MIPS64)
12626     case M16_OPC_LD:
12627         check_insn(ctx, ISA_MIPS3);
12628         check_mips_64(ctx);
12629         gen_ld(ctx, OPC_LD, ry, rx, offset);
12630         break;
12631 #endif
12632     case M16_OPC_RRIA:
12633         imm = ctx->opcode & 0xf;
12634         imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
12635         imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
12636         imm = (int16_t) (imm << 1) >> 1;
12637         if ((ctx->opcode >> 4) & 0x1) {
12638 #if defined(TARGET_MIPS64)
12639             check_mips_64(ctx);
12640             gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
12641 #else
12642             generate_exception_end(ctx, EXCP_RI);
12643 #endif
12644         } else {
12645             gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
12646         }
12647         break;
12648     case M16_OPC_ADDIU8:
12649         gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
12650         break;
12651     case M16_OPC_SLTI:
12652         gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
12653         break;
12654     case M16_OPC_SLTIU:
12655         gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
12656         break;
12657     case M16_OPC_I8:
12658         switch (funct) {
12659         case I8_BTEQZ:
12660             gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
12661             break;
12662         case I8_BTNEZ:
12663             gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
12664             break;
12665         case I8_SWRASP:
12666             gen_st(ctx, OPC_SW, 31, 29, imm);
12667             break;
12668         case I8_ADJSP:
12669             gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
12670             break;
12671         case I8_SVRS:
12672             check_insn(ctx, ISA_MIPS32);
12673             {
12674                 int xsregs = (ctx->opcode >> 24) & 0x7;
12675                 int aregs = (ctx->opcode >> 16) & 0xf;
12676                 int do_ra = (ctx->opcode >> 6) & 0x1;
12677                 int do_s0 = (ctx->opcode >> 5) & 0x1;
12678                 int do_s1 = (ctx->opcode >> 4) & 0x1;
12679                 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
12680                                  | (ctx->opcode & 0xf)) << 3;
12681
12682                 if (ctx->opcode & (1 << 7)) {
12683                     gen_mips16_save(ctx, xsregs, aregs,
12684                                     do_ra, do_s0, do_s1,
12685                                     framesize);
12686                 } else {
12687                     gen_mips16_restore(ctx, xsregs, aregs,
12688                                        do_ra, do_s0, do_s1,
12689                                        framesize);
12690                 }
12691             }
12692             break;
12693         default:
12694             generate_exception_end(ctx, EXCP_RI);
12695             break;
12696         }
12697         break;
12698     case M16_OPC_LI:
12699         tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
12700         break;
12701     case M16_OPC_CMPI:
12702         tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
12703         break;
12704 #if defined(TARGET_MIPS64)
12705     case M16_OPC_SD:
12706         check_insn(ctx, ISA_MIPS3);
12707         check_mips_64(ctx);
12708         gen_st(ctx, OPC_SD, ry, rx, offset);
12709         break;
12710 #endif
12711     case M16_OPC_LB:
12712         gen_ld(ctx, OPC_LB, ry, rx, offset);
12713         break;
12714     case M16_OPC_LH:
12715         gen_ld(ctx, OPC_LH, ry, rx, offset);
12716         break;
12717     case M16_OPC_LWSP:
12718         gen_ld(ctx, OPC_LW, rx, 29, offset);
12719         break;
12720     case M16_OPC_LW:
12721         gen_ld(ctx, OPC_LW, ry, rx, offset);
12722         break;
12723     case M16_OPC_LBU:
12724         gen_ld(ctx, OPC_LBU, ry, rx, offset);
12725         break;
12726     case M16_OPC_LHU:
12727         gen_ld(ctx, OPC_LHU, ry, rx, offset);
12728         break;
12729     case M16_OPC_LWPC:
12730         gen_ld(ctx, OPC_LWPC, rx, 0, offset);
12731         break;
12732 #if defined(TARGET_MIPS64)
12733     case M16_OPC_LWU:
12734         check_insn(ctx, ISA_MIPS3);
12735         check_mips_64(ctx);
12736         gen_ld(ctx, OPC_LWU, ry, rx, offset);
12737         break;
12738 #endif
12739     case M16_OPC_SB:
12740         gen_st(ctx, OPC_SB, ry, rx, offset);
12741         break;
12742     case M16_OPC_SH:
12743         gen_st(ctx, OPC_SH, ry, rx, offset);
12744         break;
12745     case M16_OPC_SWSP:
12746         gen_st(ctx, OPC_SW, rx, 29, offset);
12747         break;
12748     case M16_OPC_SW:
12749         gen_st(ctx, OPC_SW, ry, rx, offset);
12750         break;
12751 #if defined(TARGET_MIPS64)
12752     case M16_OPC_I64:
12753         decode_i64_mips16(ctx, ry, funct, offset, 1);
12754         break;
12755 #endif
12756     default:
12757         generate_exception_end(ctx, EXCP_RI);
12758         break;
12759     }
12760
12761     return 4;
12762 }
12763
12764 static inline bool is_uhi(int sdbbp_code)
12765 {
12766 #ifdef CONFIG_USER_ONLY
12767     return false;
12768 #else
12769     return semihosting_enabled() && sdbbp_code == 1;
12770 #endif
12771 }
12772
12773 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
12774 {
12775     int rx, ry;
12776     int sa;
12777     int op, cnvt_op, op1, offset;
12778     int funct;
12779     int n_bytes;
12780
12781     op = (ctx->opcode >> 11) & 0x1f;
12782     sa = (ctx->opcode >> 2) & 0x7;
12783     sa = sa == 0 ? 8 : sa;
12784     rx = xlat((ctx->opcode >> 8) & 0x7);
12785     cnvt_op = (ctx->opcode >> 5) & 0x7;
12786     ry = xlat((ctx->opcode >> 5) & 0x7);
12787     op1 = offset = ctx->opcode & 0x1f;
12788
12789     n_bytes = 2;
12790
12791     switch (op) {
12792     case M16_OPC_ADDIUSP:
12793         {
12794             int16_t imm = ((uint8_t) ctx->opcode) << 2;
12795
12796             gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
12797         }
12798         break;
12799     case M16_OPC_ADDIUPC:
12800         gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
12801         break;
12802     case M16_OPC_B:
12803         offset = (ctx->opcode & 0x7ff) << 1;
12804         offset = (int16_t)(offset << 4) >> 4;
12805         gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
12806         /* No delay slot, so just process as a normal instruction */
12807         break;
12808     case M16_OPC_JAL:
12809         offset = cpu_lduw_code(env, ctx->base.pc_next + 2);
12810         offset = (((ctx->opcode & 0x1f) << 21)
12811                   | ((ctx->opcode >> 5) & 0x1f) << 16
12812                   | offset) << 2;
12813         op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
12814         gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
12815         n_bytes = 4;
12816         break;
12817     case M16_OPC_BEQZ:
12818         gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
12819                            ((int8_t)ctx->opcode) << 1, 0);
12820         /* No delay slot, so just process as a normal instruction */
12821         break;
12822     case M16_OPC_BNEQZ:
12823         gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
12824                            ((int8_t)ctx->opcode) << 1, 0);
12825         /* No delay slot, so just process as a normal instruction */
12826         break;
12827     case M16_OPC_SHIFT:
12828         switch (ctx->opcode & 0x3) {
12829         case 0x0:
12830             gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
12831             break;
12832         case 0x1:
12833 #if defined(TARGET_MIPS64)
12834             check_insn(ctx, ISA_MIPS3);
12835             check_mips_64(ctx);
12836             gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
12837 #else
12838             generate_exception_end(ctx, EXCP_RI);
12839 #endif
12840             break;
12841         case 0x2:
12842             gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
12843             break;
12844         case 0x3:
12845             gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
12846             break;
12847         }
12848         break;
12849 #if defined(TARGET_MIPS64)
12850     case M16_OPC_LD:
12851         check_insn(ctx, ISA_MIPS3);
12852         check_mips_64(ctx);
12853         gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
12854         break;
12855 #endif
12856     case M16_OPC_RRIA:
12857         {
12858             int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
12859
12860             if ((ctx->opcode >> 4) & 1) {
12861 #if defined(TARGET_MIPS64)
12862                 check_insn(ctx, ISA_MIPS3);
12863                 check_mips_64(ctx);
12864                 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
12865 #else
12866                 generate_exception_end(ctx, EXCP_RI);
12867 #endif
12868             } else {
12869                 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
12870             }
12871         }
12872         break;
12873     case M16_OPC_ADDIU8:
12874         {
12875             int16_t imm = (int8_t) ctx->opcode;
12876
12877             gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
12878         }
12879         break;
12880     case M16_OPC_SLTI:
12881         {
12882             int16_t imm = (uint8_t) ctx->opcode;
12883             gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
12884         }
12885         break;
12886     case M16_OPC_SLTIU:
12887         {
12888             int16_t imm = (uint8_t) ctx->opcode;
12889             gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
12890         }
12891         break;
12892     case M16_OPC_I8:
12893         {
12894             int reg32;
12895
12896             funct = (ctx->opcode >> 8) & 0x7;
12897             switch (funct) {
12898             case I8_BTEQZ:
12899                 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
12900                                    ((int8_t)ctx->opcode) << 1, 0);
12901                 break;
12902             case I8_BTNEZ:
12903                 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
12904                                    ((int8_t)ctx->opcode) << 1, 0);
12905                 break;
12906             case I8_SWRASP:
12907                 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
12908                 break;
12909             case I8_ADJSP:
12910                 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
12911                               ((int8_t)ctx->opcode) << 3);
12912                 break;
12913             case I8_SVRS:
12914                 check_insn(ctx, ISA_MIPS32);
12915                 {
12916                     int do_ra = ctx->opcode & (1 << 6);
12917                     int do_s0 = ctx->opcode & (1 << 5);
12918                     int do_s1 = ctx->opcode & (1 << 4);
12919                     int framesize = ctx->opcode & 0xf;
12920
12921                     if (framesize == 0) {
12922                         framesize = 128;
12923                     } else {
12924                         framesize = framesize << 3;
12925                     }
12926
12927                     if (ctx->opcode & (1 << 7)) {
12928                         gen_mips16_save(ctx, 0, 0,
12929                                         do_ra, do_s0, do_s1, framesize);
12930                     } else {
12931                         gen_mips16_restore(ctx, 0, 0,
12932                                            do_ra, do_s0, do_s1, framesize);
12933                     }
12934                 }
12935                 break;
12936             case I8_MOV32R:
12937                 {
12938                     int rz = xlat(ctx->opcode & 0x7);
12939
12940                     reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
12941                         ((ctx->opcode >> 5) & 0x7);
12942                     gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
12943                 }
12944                 break;
12945             case I8_MOVR32:
12946                 reg32 = ctx->opcode & 0x1f;
12947                 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
12948                 break;
12949             default:
12950                 generate_exception_end(ctx, EXCP_RI);
12951                 break;
12952             }
12953         }
12954         break;
12955     case M16_OPC_LI:
12956         {
12957             int16_t imm = (uint8_t) ctx->opcode;
12958
12959             gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
12960         }
12961         break;
12962     case M16_OPC_CMPI:
12963         {
12964             int16_t imm = (uint8_t) ctx->opcode;
12965             gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
12966         }
12967         break;
12968 #if defined(TARGET_MIPS64)
12969     case M16_OPC_SD:
12970         check_insn(ctx, ISA_MIPS3);
12971         check_mips_64(ctx);
12972         gen_st(ctx, OPC_SD, ry, rx, offset << 3);
12973         break;
12974 #endif
12975     case M16_OPC_LB:
12976         gen_ld(ctx, OPC_LB, ry, rx, offset);
12977         break;
12978     case M16_OPC_LH:
12979         gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
12980         break;
12981     case M16_OPC_LWSP:
12982         gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
12983         break;
12984     case M16_OPC_LW:
12985         gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
12986         break;
12987     case M16_OPC_LBU:
12988         gen_ld(ctx, OPC_LBU, ry, rx, offset);
12989         break;
12990     case M16_OPC_LHU:
12991         gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
12992         break;
12993     case M16_OPC_LWPC:
12994         gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
12995         break;
12996 #if defined (TARGET_MIPS64)
12997     case M16_OPC_LWU:
12998         check_insn(ctx, ISA_MIPS3);
12999         check_mips_64(ctx);
13000         gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
13001         break;
13002 #endif
13003     case M16_OPC_SB:
13004         gen_st(ctx, OPC_SB, ry, rx, offset);
13005         break;
13006     case M16_OPC_SH:
13007         gen_st(ctx, OPC_SH, ry, rx, offset << 1);
13008         break;
13009     case M16_OPC_SWSP:
13010         gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
13011         break;
13012     case M16_OPC_SW:
13013         gen_st(ctx, OPC_SW, ry, rx, offset << 2);
13014         break;
13015     case M16_OPC_RRR:
13016         {
13017             int rz = xlat((ctx->opcode >> 2) & 0x7);
13018             int mips32_op;
13019
13020             switch (ctx->opcode & 0x3) {
13021             case RRR_ADDU:
13022                 mips32_op = OPC_ADDU;
13023                 break;
13024             case RRR_SUBU:
13025                 mips32_op = OPC_SUBU;
13026                 break;
13027 #if defined(TARGET_MIPS64)
13028             case RRR_DADDU:
13029                 mips32_op = OPC_DADDU;
13030                 check_insn(ctx, ISA_MIPS3);
13031                 check_mips_64(ctx);
13032                 break;
13033             case RRR_DSUBU:
13034                 mips32_op = OPC_DSUBU;
13035                 check_insn(ctx, ISA_MIPS3);
13036                 check_mips_64(ctx);
13037                 break;
13038 #endif
13039             default:
13040                 generate_exception_end(ctx, EXCP_RI);
13041                 goto done;
13042             }
13043
13044             gen_arith(ctx, mips32_op, rz, rx, ry);
13045         done:
13046             ;
13047         }
13048         break;
13049     case M16_OPC_RR:
13050         switch (op1) {
13051         case RR_JR:
13052             {
13053                 int nd = (ctx->opcode >> 7) & 0x1;
13054                 int link = (ctx->opcode >> 6) & 0x1;
13055                 int ra = (ctx->opcode >> 5) & 0x1;
13056
13057                 if (nd) {
13058                     check_insn(ctx, ISA_MIPS32);
13059                 }
13060
13061                 if (link) {
13062                     op = OPC_JALR;
13063                 } else {
13064                     op = OPC_JR;
13065                 }
13066
13067                 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
13068                                    (nd ? 0 : 2));
13069             }
13070             break;
13071         case RR_SDBBP:
13072             if (is_uhi(extract32(ctx->opcode, 5, 6))) {
13073                 gen_helper_do_semihosting(cpu_env);
13074             } else {
13075                 /* XXX: not clear which exception should be raised
13076                  *      when in debug mode...
13077                  */
13078                 check_insn(ctx, ISA_MIPS32);
13079                 generate_exception_end(ctx, EXCP_DBp);
13080             }
13081             break;
13082         case RR_SLT:
13083             gen_slt(ctx, OPC_SLT, 24, rx, ry);
13084             break;
13085         case RR_SLTU:
13086             gen_slt(ctx, OPC_SLTU, 24, rx, ry);
13087             break;
13088         case RR_BREAK:
13089             generate_exception_end(ctx, EXCP_BREAK);
13090             break;
13091         case RR_SLLV:
13092             gen_shift(ctx, OPC_SLLV, ry, rx, ry);
13093             break;
13094         case RR_SRLV:
13095             gen_shift(ctx, OPC_SRLV, ry, rx, ry);
13096             break;
13097         case RR_SRAV:
13098             gen_shift(ctx, OPC_SRAV, ry, rx, ry);
13099             break;
13100 #if defined (TARGET_MIPS64)
13101         case RR_DSRL:
13102             check_insn(ctx, ISA_MIPS3);
13103             check_mips_64(ctx);
13104             gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
13105             break;
13106 #endif
13107         case RR_CMP:
13108             gen_logic(ctx, OPC_XOR, 24, rx, ry);
13109             break;
13110         case RR_NEG:
13111             gen_arith(ctx, OPC_SUBU, rx, 0, ry);
13112             break;
13113         case RR_AND:
13114             gen_logic(ctx, OPC_AND, rx, rx, ry);
13115             break;
13116         case RR_OR:
13117             gen_logic(ctx, OPC_OR, rx, rx, ry);
13118             break;
13119         case RR_XOR:
13120             gen_logic(ctx, OPC_XOR, rx, rx, ry);
13121             break;
13122         case RR_NOT:
13123             gen_logic(ctx, OPC_NOR, rx, ry, 0);
13124             break;
13125         case RR_MFHI:
13126             gen_HILO(ctx, OPC_MFHI, 0, rx);
13127             break;
13128         case RR_CNVT:
13129             check_insn(ctx, ISA_MIPS32);
13130             switch (cnvt_op) {
13131             case RR_RY_CNVT_ZEB:
13132                 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13133                 break;
13134             case RR_RY_CNVT_ZEH:
13135                 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13136                 break;
13137             case RR_RY_CNVT_SEB:
13138                 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13139                 break;
13140             case RR_RY_CNVT_SEH:
13141                 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13142                 break;
13143 #if defined (TARGET_MIPS64)
13144             case RR_RY_CNVT_ZEW:
13145                 check_insn(ctx, ISA_MIPS64);
13146                 check_mips_64(ctx);
13147                 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13148                 break;
13149             case RR_RY_CNVT_SEW:
13150                 check_insn(ctx, ISA_MIPS64);
13151                 check_mips_64(ctx);
13152                 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13153                 break;
13154 #endif
13155             default:
13156                 generate_exception_end(ctx, EXCP_RI);
13157                 break;
13158             }
13159             break;
13160         case RR_MFLO:
13161             gen_HILO(ctx, OPC_MFLO, 0, rx);
13162             break;
13163 #if defined (TARGET_MIPS64)
13164         case RR_DSRA:
13165             check_insn(ctx, ISA_MIPS3);
13166             check_mips_64(ctx);
13167             gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
13168             break;
13169         case RR_DSLLV:
13170             check_insn(ctx, ISA_MIPS3);
13171             check_mips_64(ctx);
13172             gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
13173             break;
13174         case RR_DSRLV:
13175             check_insn(ctx, ISA_MIPS3);
13176             check_mips_64(ctx);
13177             gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
13178             break;
13179         case RR_DSRAV:
13180             check_insn(ctx, ISA_MIPS3);
13181             check_mips_64(ctx);
13182             gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
13183             break;
13184 #endif
13185         case RR_MULT:
13186             gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
13187             break;
13188         case RR_MULTU:
13189             gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
13190             break;
13191         case RR_DIV:
13192             gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
13193             break;
13194         case RR_DIVU:
13195             gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
13196             break;
13197 #if defined (TARGET_MIPS64)
13198         case RR_DMULT:
13199             check_insn(ctx, ISA_MIPS3);
13200             check_mips_64(ctx);
13201             gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
13202             break;
13203         case RR_DMULTU:
13204             check_insn(ctx, ISA_MIPS3);
13205             check_mips_64(ctx);
13206             gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
13207             break;
13208         case RR_DDIV:
13209             check_insn(ctx, ISA_MIPS3);
13210             check_mips_64(ctx);
13211             gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
13212             break;
13213         case RR_DDIVU:
13214             check_insn(ctx, ISA_MIPS3);
13215             check_mips_64(ctx);
13216             gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
13217             break;
13218 #endif
13219         default:
13220             generate_exception_end(ctx, EXCP_RI);
13221             break;
13222         }
13223         break;
13224     case M16_OPC_EXTEND:
13225         decode_extended_mips16_opc(env, ctx);
13226         n_bytes = 4;
13227         break;
13228 #if defined(TARGET_MIPS64)
13229     case M16_OPC_I64:
13230         funct = (ctx->opcode >> 8) & 0x7;
13231         decode_i64_mips16(ctx, ry, funct, offset, 0);
13232         break;
13233 #endif
13234     default:
13235         generate_exception_end(ctx, EXCP_RI);
13236         break;
13237     }
13238
13239     return n_bytes;
13240 }
13241
13242 /* microMIPS extension to MIPS32/MIPS64 */
13243
13244 /*
13245  * microMIPS32/microMIPS64 major opcodes
13246  *
13247  * 1. MIPS Architecture for Programmers Volume II-B:
13248  *      The microMIPS32 Instruction Set (Revision 3.05)
13249  *
13250  *    Table 6.2 microMIPS32 Encoding of Major Opcode Field
13251  *
13252  * 2. MIPS Architecture For Programmers Volume II-A:
13253  *      The MIPS64 Instruction Set (Revision 3.51)
13254  */
13255
13256 enum {
13257     POOL32A = 0x00,
13258     POOL16A = 0x01,
13259     LBU16 = 0x02,
13260     MOVE16 = 0x03,
13261     ADDI32 = 0x04,
13262     R6_LUI = 0x04,
13263     AUI = 0x04,
13264     LBU32 = 0x05,
13265     SB32 = 0x06,
13266     LB32 = 0x07,
13267
13268     POOL32B = 0x08,
13269     POOL16B = 0x09,
13270     LHU16 = 0x0a,
13271     ANDI16 = 0x0b,
13272     ADDIU32 = 0x0c,
13273     LHU32 = 0x0d,
13274     SH32 = 0x0e,
13275     LH32 = 0x0f,
13276
13277     POOL32I = 0x10,
13278     POOL16C = 0x11,
13279     LWSP16 = 0x12,
13280     POOL16D = 0x13,
13281     ORI32 = 0x14,
13282     POOL32F = 0x15,
13283     POOL32S = 0x16,  /* MIPS64 */
13284     DADDIU32 = 0x17, /* MIPS64 */
13285
13286     POOL32C = 0x18,
13287     LWGP16 = 0x19,
13288     LW16 = 0x1a,
13289     POOL16E = 0x1b,
13290     XORI32 = 0x1c,
13291     JALS32 = 0x1d,
13292     BOVC = 0x1d,
13293     BEQC = 0x1d,
13294     BEQZALC = 0x1d,
13295     ADDIUPC = 0x1e,
13296     PCREL = 0x1e,
13297     BNVC = 0x1f,
13298     BNEC = 0x1f,
13299     BNEZALC = 0x1f,
13300
13301     R6_BEQZC = 0x20,
13302     JIC = 0x20,
13303     POOL16F = 0x21,
13304     SB16 = 0x22,
13305     BEQZ16 = 0x23,
13306     BEQZC16 = 0x23,
13307     SLTI32 = 0x24,
13308     BEQ32 = 0x25,
13309     BC = 0x25,
13310     SWC132 = 0x26,
13311     LWC132 = 0x27,
13312
13313     /* 0x29 is reserved */
13314     RES_29 = 0x29,
13315     R6_BNEZC = 0x28,
13316     JIALC = 0x28,
13317     SH16 = 0x2a,
13318     BNEZ16 = 0x2b,
13319     BNEZC16 = 0x2b,
13320     SLTIU32 = 0x2c,
13321     BNE32 = 0x2d,
13322     BALC = 0x2d,
13323     SDC132 = 0x2e,
13324     LDC132 = 0x2f,
13325
13326     /* 0x31 is reserved */
13327     RES_31 = 0x31,
13328     BLEZALC = 0x30,
13329     BGEZALC = 0x30,
13330     BGEUC = 0x30,
13331     SWSP16 = 0x32,
13332     B16 = 0x33,
13333     BC16 = 0x33,
13334     ANDI32 = 0x34,
13335     J32 = 0x35,
13336     BGTZC = 0x35,
13337     BLTZC = 0x35,
13338     BLTC = 0x35,
13339     SD32 = 0x36, /* MIPS64 */
13340     LD32 = 0x37, /* MIPS64 */
13341
13342     /* 0x39 is reserved */
13343     RES_39 = 0x39,
13344     BGTZALC = 0x38,
13345     BLTZALC = 0x38,
13346     BLTUC = 0x38,
13347     SW16 = 0x3a,
13348     LI16 = 0x3b,
13349     JALX32 = 0x3c,
13350     JAL32 = 0x3d,
13351     BLEZC = 0x3d,
13352     BGEZC = 0x3d,
13353     BGEC = 0x3d,
13354     SW32 = 0x3e,
13355     LW32 = 0x3f
13356 };
13357
13358 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
13359 enum {
13360     ADDIUPC_00 = 0x00,
13361     ADDIUPC_01 = 0x01,
13362     ADDIUPC_02 = 0x02,
13363     ADDIUPC_03 = 0x03,
13364     ADDIUPC_04 = 0x04,
13365     ADDIUPC_05 = 0x05,
13366     ADDIUPC_06 = 0x06,
13367     ADDIUPC_07 = 0x07,
13368     AUIPC = 0x1e,
13369     ALUIPC = 0x1f,
13370     LWPC_08 = 0x08,
13371     LWPC_09 = 0x09,
13372     LWPC_0A = 0x0A,
13373     LWPC_0B = 0x0B,
13374     LWPC_0C = 0x0C,
13375     LWPC_0D = 0x0D,
13376     LWPC_0E = 0x0E,
13377     LWPC_0F = 0x0F,
13378 };
13379
13380 /* POOL32A encoding of minor opcode field */
13381
13382 enum {
13383     /* These opcodes are distinguished only by bits 9..6; those bits are
13384      * what are recorded below. */
13385     SLL32 = 0x0,
13386     SRL32 = 0x1,
13387     SRA = 0x2,
13388     ROTR = 0x3,
13389     SELEQZ = 0x5,
13390     SELNEZ = 0x6,
13391     R6_RDHWR = 0x7,
13392
13393     SLLV = 0x0,
13394     SRLV = 0x1,
13395     SRAV = 0x2,
13396     ROTRV = 0x3,
13397     ADD = 0x4,
13398     ADDU32 = 0x5,
13399     SUB = 0x6,
13400     SUBU32 = 0x7,
13401     MUL = 0x8,
13402     AND = 0x9,
13403     OR32 = 0xa,
13404     NOR = 0xb,
13405     XOR32 = 0xc,
13406     SLT = 0xd,
13407     SLTU = 0xe,
13408
13409     MOVN = 0x0,
13410     R6_MUL  = 0x0,
13411     MOVZ = 0x1,
13412     MUH  = 0x1,
13413     MULU = 0x2,
13414     MUHU = 0x3,
13415     LWXS = 0x4,
13416     R6_DIV  = 0x4,
13417     MOD  = 0x5,
13418     R6_DIVU = 0x6,
13419     MODU = 0x7,
13420
13421     /* The following can be distinguished by their lower 6 bits. */
13422     BREAK32 = 0x07,
13423     INS = 0x0c,
13424     LSA = 0x0f,
13425     ALIGN = 0x1f,
13426     EXT = 0x2c,
13427     POOL32AXF = 0x3c,
13428     SIGRIE = 0x3f
13429 };
13430
13431 /* POOL32AXF encoding of minor opcode field extension */
13432
13433 /*
13434  * 1. MIPS Architecture for Programmers Volume II-B:
13435  *      The microMIPS32 Instruction Set (Revision 3.05)
13436  *
13437  *    Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
13438  *
13439  * 2. MIPS Architecture for Programmers VolumeIV-e:
13440  *      The MIPS DSP Application-Specific Extension
13441  *        to the microMIPS32 Architecture (Revision 2.34)
13442  *
13443  *    Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
13444  */
13445
13446 enum {
13447     /* bits 11..6 */
13448     TEQ = 0x00,
13449     TGE = 0x08,
13450     TGEU = 0x10,
13451     TLT = 0x20,
13452     TLTU = 0x28,
13453     TNE = 0x30,
13454
13455     MFC0 = 0x03,
13456     MTC0 = 0x0b,
13457
13458     /* begin of microMIPS32 DSP */
13459
13460     /* bits 13..12 for 0x01 */
13461     MFHI_ACC = 0x0,
13462     MFLO_ACC = 0x1,
13463     MTHI_ACC = 0x2,
13464     MTLO_ACC = 0x3,
13465
13466     /* bits 13..12 for 0x2a */
13467     MADD_ACC = 0x0,
13468     MADDU_ACC = 0x1,
13469     MSUB_ACC = 0x2,
13470     MSUBU_ACC = 0x3,
13471
13472     /* bits 13..12 for 0x32 */
13473     MULT_ACC = 0x0,
13474     MULTU_ACC = 0x1,
13475
13476     /* end of microMIPS32 DSP */
13477
13478     /* bits 15..12 for 0x2c */
13479     BITSWAP = 0x0,
13480     SEB = 0x2,
13481     SEH = 0x3,
13482     CLO = 0x4,
13483     CLZ = 0x5,
13484     RDHWR = 0x6,
13485     WSBH = 0x7,
13486     MULT = 0x8,
13487     MULTU = 0x9,
13488     DIV = 0xa,
13489     DIVU = 0xb,
13490     MADD = 0xc,
13491     MADDU = 0xd,
13492     MSUB = 0xe,
13493     MSUBU = 0xf,
13494
13495     /* bits 15..12 for 0x34 */
13496     MFC2 = 0x4,
13497     MTC2 = 0x5,
13498     MFHC2 = 0x8,
13499     MTHC2 = 0x9,
13500     CFC2 = 0xc,
13501     CTC2 = 0xd,
13502
13503     /* bits 15..12 for 0x3c */
13504     JALR = 0x0,
13505     JR = 0x0,                   /* alias */
13506     JALRC = 0x0,
13507     JRC = 0x0,
13508     JALR_HB = 0x1,
13509     JALRC_HB = 0x1,
13510     JALRS = 0x4,
13511     JALRS_HB = 0x5,
13512
13513     /* bits 15..12 for 0x05 */
13514     RDPGPR = 0xe,
13515     WRPGPR = 0xf,
13516
13517     /* bits 15..12 for 0x0d */
13518     TLBP = 0x0,
13519     TLBR = 0x1,
13520     TLBWI = 0x2,
13521     TLBWR = 0x3,
13522     TLBINV = 0x4,
13523     TLBINVF = 0x5,
13524     WAIT = 0x9,
13525     IRET = 0xd,
13526     DERET = 0xe,
13527     ERET = 0xf,
13528
13529     /* bits 15..12 for 0x15 */
13530     DMT = 0x0,
13531     DVPE = 0x1,
13532     EMT = 0x2,
13533     EVPE = 0x3,
13534
13535     /* bits 15..12 for 0x1d */
13536     DI = 0x4,
13537     EI = 0x5,
13538
13539     /* bits 15..12 for 0x2d */
13540     SYNC = 0x6,
13541     SYSCALL = 0x8,
13542     SDBBP = 0xd,
13543
13544     /* bits 15..12 for 0x35 */
13545     MFHI32 = 0x0,
13546     MFLO32 = 0x1,
13547     MTHI32 = 0x2,
13548     MTLO32 = 0x3,
13549 };
13550
13551 /* POOL32B encoding of minor opcode field (bits 15..12) */
13552
13553 enum {
13554     LWC2 = 0x0,
13555     LWP = 0x1,
13556     LDP = 0x4,
13557     LWM32 = 0x5,
13558     CACHE = 0x6,
13559     LDM = 0x7,
13560     SWC2 = 0x8,
13561     SWP = 0x9,
13562     SDP = 0xc,
13563     SWM32 = 0xd,
13564     SDM = 0xf
13565 };
13566
13567 /* POOL32C encoding of minor opcode field (bits 15..12) */
13568
13569 enum {
13570     LWL = 0x0,
13571     SWL = 0x8,
13572     LWR = 0x1,
13573     SWR = 0x9,
13574     PREF = 0x2,
13575     ST_EVA = 0xa,
13576     LL = 0x3,
13577     SC = 0xb,
13578     LDL = 0x4,
13579     SDL = 0xc,
13580     LDR = 0x5,
13581     SDR = 0xd,
13582     LD_EVA = 0x6,
13583     LWU = 0xe,
13584     LLD = 0x7,
13585     SCD = 0xf
13586 };
13587
13588 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
13589
13590 enum {
13591     LBUE = 0x0,
13592     LHUE = 0x1,
13593     LWLE = 0x2,
13594     LWRE = 0x3,
13595     LBE = 0x4,
13596     LHE = 0x5,
13597     LLE = 0x6,
13598     LWE = 0x7,
13599 };
13600
13601 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
13602
13603 enum {
13604     SWLE = 0x0,
13605     SWRE = 0x1,
13606     PREFE = 0x2,
13607     CACHEE = 0x3,
13608     SBE = 0x4,
13609     SHE = 0x5,
13610     SCE = 0x6,
13611     SWE = 0x7,
13612 };
13613
13614 /* POOL32F encoding of minor opcode field (bits 5..0) */
13615
13616 enum {
13617     /* These are the bit 7..6 values */
13618     ADD_FMT = 0x0,
13619
13620     SUB_FMT = 0x1,
13621
13622     MUL_FMT = 0x2,
13623
13624     DIV_FMT = 0x3,
13625
13626     /* These are the bit 8..6 values */
13627     MOVN_FMT = 0x0,
13628     RSQRT2_FMT = 0x0,
13629     MOVF_FMT = 0x0,
13630     RINT_FMT = 0x0,
13631     SELNEZ_FMT = 0x0,
13632
13633     MOVZ_FMT = 0x1,
13634     LWXC1 = 0x1,
13635     MOVT_FMT = 0x1,
13636     CLASS_FMT = 0x1,
13637     SELEQZ_FMT = 0x1,
13638
13639     PLL_PS = 0x2,
13640     SWXC1 = 0x2,
13641     SEL_FMT = 0x2,
13642
13643     PLU_PS = 0x3,
13644     LDXC1 = 0x3,
13645
13646     MOVN_FMT_04 = 0x4,
13647     PUL_PS = 0x4,
13648     SDXC1 = 0x4,
13649     RECIP2_FMT = 0x4,
13650
13651     MOVZ_FMT_05 = 0x05,
13652     PUU_PS = 0x5,
13653     LUXC1 = 0x5,
13654
13655     CVT_PS_S = 0x6,
13656     SUXC1 = 0x6,
13657     ADDR_PS = 0x6,
13658     PREFX = 0x6,
13659     MADDF_FMT = 0x6,
13660
13661     MULR_PS = 0x7,
13662     MSUBF_FMT = 0x7,
13663
13664     MADD_S = 0x01,
13665     MADD_D = 0x09,
13666     MADD_PS = 0x11,
13667     ALNV_PS = 0x19,
13668     MSUB_S = 0x21,
13669     MSUB_D = 0x29,
13670     MSUB_PS = 0x31,
13671
13672     NMADD_S = 0x02,
13673     NMADD_D = 0x0a,
13674     NMADD_PS = 0x12,
13675     NMSUB_S = 0x22,
13676     NMSUB_D = 0x2a,
13677     NMSUB_PS = 0x32,
13678
13679     MIN_FMT = 0x3,
13680     MAX_FMT = 0xb,
13681     MINA_FMT = 0x23,
13682     MAXA_FMT = 0x2b,
13683     POOL32FXF = 0x3b,
13684
13685     CABS_COND_FMT = 0x1c,              /* MIPS3D */
13686     C_COND_FMT = 0x3c,
13687
13688     CMP_CONDN_S = 0x5,
13689     CMP_CONDN_D = 0x15
13690 };
13691
13692 /* POOL32Fxf encoding of minor opcode extension field */
13693
13694 enum {
13695     CVT_L = 0x04,
13696     RSQRT_FMT = 0x08,
13697     FLOOR_L = 0x0c,
13698     CVT_PW_PS = 0x1c,
13699     CVT_W = 0x24,
13700     SQRT_FMT = 0x28,
13701     FLOOR_W = 0x2c,
13702     CVT_PS_PW = 0x3c,
13703     CFC1 = 0x40,
13704     RECIP_FMT = 0x48,
13705     CEIL_L = 0x4c,
13706     CTC1 = 0x60,
13707     CEIL_W = 0x6c,
13708     MFC1 = 0x80,
13709     CVT_S_PL = 0x84,
13710     TRUNC_L = 0x8c,
13711     MTC1 = 0xa0,
13712     CVT_S_PU = 0xa4,
13713     TRUNC_W = 0xac,
13714     MFHC1 = 0xc0,
13715     ROUND_L = 0xcc,
13716     MTHC1 = 0xe0,
13717     ROUND_W = 0xec,
13718
13719     MOV_FMT = 0x01,
13720     MOVF = 0x05,
13721     ABS_FMT = 0x0d,
13722     RSQRT1_FMT = 0x1d,
13723     MOVT = 0x25,
13724     NEG_FMT = 0x2d,
13725     CVT_D = 0x4d,
13726     RECIP1_FMT = 0x5d,
13727     CVT_S = 0x6d
13728 };
13729
13730 /* POOL32I encoding of minor opcode field (bits 25..21) */
13731
13732 enum {
13733     BLTZ = 0x00,
13734     BLTZAL = 0x01,
13735     BGEZ = 0x02,
13736     BGEZAL = 0x03,
13737     BLEZ = 0x04,
13738     BNEZC = 0x05,
13739     BGTZ = 0x06,
13740     BEQZC = 0x07,
13741     TLTI = 0x08,
13742     BC1EQZC = 0x08,
13743     TGEI = 0x09,
13744     BC1NEZC = 0x09,
13745     TLTIU = 0x0a,
13746     BC2EQZC = 0x0a,
13747     TGEIU = 0x0b,
13748     BC2NEZC = 0x0a,
13749     TNEI = 0x0c,
13750     R6_SYNCI = 0x0c,
13751     LUI = 0x0d,
13752     TEQI = 0x0e,
13753     SYNCI = 0x10,
13754     BLTZALS = 0x11,
13755     BGEZALS = 0x13,
13756     BC2F = 0x14,
13757     BC2T = 0x15,
13758     BPOSGE64 = 0x1a,
13759     BPOSGE32 = 0x1b,
13760     /* These overlap and are distinguished by bit16 of the instruction */
13761     BC1F = 0x1c,
13762     BC1T = 0x1d,
13763     BC1ANY2F = 0x1c,
13764     BC1ANY2T = 0x1d,
13765     BC1ANY4F = 0x1e,
13766     BC1ANY4T = 0x1f
13767 };
13768
13769 /* POOL16A encoding of minor opcode field */
13770
13771 enum {
13772     ADDU16 = 0x0,
13773     SUBU16 = 0x1
13774 };
13775
13776 /* POOL16B encoding of minor opcode field */
13777
13778 enum {
13779     SLL16 = 0x0,
13780     SRL16 = 0x1
13781 };
13782
13783 /* POOL16C encoding of minor opcode field */
13784
13785 enum {
13786     NOT16 = 0x00,
13787     XOR16 = 0x04,
13788     AND16 = 0x08,
13789     OR16 = 0x0c,
13790     LWM16 = 0x10,
13791     SWM16 = 0x14,
13792     JR16 = 0x18,
13793     JRC16 = 0x1a,
13794     JALR16 = 0x1c,
13795     JALR16S = 0x1e,
13796     MFHI16 = 0x20,
13797     MFLO16 = 0x24,
13798     BREAK16 = 0x28,
13799     SDBBP16 = 0x2c,
13800     JRADDIUSP = 0x30
13801 };
13802
13803 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
13804
13805 enum {
13806     R6_NOT16    = 0x00,
13807     R6_AND16    = 0x01,
13808     R6_LWM16    = 0x02,
13809     R6_JRC16    = 0x03,
13810     MOVEP       = 0x04,
13811     MOVEP_05    = 0x05,
13812     MOVEP_06    = 0x06,
13813     MOVEP_07    = 0x07,
13814     R6_XOR16    = 0x08,
13815     R6_OR16     = 0x09,
13816     R6_SWM16    = 0x0a,
13817     JALRC16     = 0x0b,
13818     MOVEP_0C    = 0x0c,
13819     MOVEP_0D    = 0x0d,
13820     MOVEP_0E    = 0x0e,
13821     MOVEP_0F    = 0x0f,
13822     JRCADDIUSP  = 0x13,
13823     R6_BREAK16  = 0x1b,
13824     R6_SDBBP16  = 0x3b
13825 };
13826
13827 /* POOL16D encoding of minor opcode field */
13828
13829 enum {
13830     ADDIUS5 = 0x0,
13831     ADDIUSP = 0x1
13832 };
13833
13834 /* POOL16E encoding of minor opcode field */
13835
13836 enum {
13837     ADDIUR2 = 0x0,
13838     ADDIUR1SP = 0x1
13839 };
13840
13841 static int mmreg (int r)
13842 {
13843     static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13844
13845     return map[r];
13846 }
13847
13848 /* Used for 16-bit store instructions.  */
13849 static int mmreg2 (int r)
13850 {
13851     static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
13852
13853     return map[r];
13854 }
13855
13856 #define uMIPS_RD(op) ((op >> 7) & 0x7)
13857 #define uMIPS_RS(op) ((op >> 4) & 0x7)
13858 #define uMIPS_RS2(op) uMIPS_RS(op)
13859 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
13860 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
13861 #define uMIPS_RS5(op) (op & 0x1f)
13862
13863 /* Signed immediate */
13864 #define SIMM(op, start, width)                                          \
13865     ((int32_t)(((op >> start) & ((~0U) >> (32-width)))                 \
13866                << (32-width))                                           \
13867      >> (32-width))
13868 /* Zero-extended immediate */
13869 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
13870
13871 static void gen_addiur1sp(DisasContext *ctx)
13872 {
13873     int rd = mmreg(uMIPS_RD(ctx->opcode));
13874
13875     gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
13876 }
13877
13878 static void gen_addiur2(DisasContext *ctx)
13879 {
13880     static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
13881     int rd = mmreg(uMIPS_RD(ctx->opcode));
13882     int rs = mmreg(uMIPS_RS(ctx->opcode));
13883
13884     gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
13885 }
13886
13887 static void gen_addiusp(DisasContext *ctx)
13888 {
13889     int encoded = ZIMM(ctx->opcode, 1, 9);
13890     int decoded;
13891
13892     if (encoded <= 1) {
13893         decoded = 256 + encoded;
13894     } else if (encoded <= 255) {
13895         decoded = encoded;
13896     } else if (encoded <= 509) {
13897         decoded = encoded - 512;
13898     } else {
13899         decoded = encoded - 768;
13900     }
13901
13902     gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
13903 }
13904
13905 static void gen_addius5(DisasContext *ctx)
13906 {
13907     int imm = SIMM(ctx->opcode, 1, 4);
13908     int rd = (ctx->opcode >> 5) & 0x1f;
13909
13910     gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
13911 }
13912
13913 static void gen_andi16(DisasContext *ctx)
13914 {
13915     static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
13916                                  31, 32, 63, 64, 255, 32768, 65535 };
13917     int rd = mmreg(uMIPS_RD(ctx->opcode));
13918     int rs = mmreg(uMIPS_RS(ctx->opcode));
13919     int encoded = ZIMM(ctx->opcode, 0, 4);
13920
13921     gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
13922 }
13923
13924 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
13925                                int base, int16_t offset)
13926 {
13927     TCGv t0, t1;
13928     TCGv_i32 t2;
13929
13930     if (ctx->hflags & MIPS_HFLAG_BMASK) {
13931         generate_exception_end(ctx, EXCP_RI);
13932         return;
13933     }
13934
13935     t0 = tcg_temp_new();
13936
13937     gen_base_offset_addr(ctx, t0, base, offset);
13938
13939     t1 = tcg_const_tl(reglist);
13940     t2 = tcg_const_i32(ctx->mem_idx);
13941
13942     save_cpu_state(ctx, 1);
13943     switch (opc) {
13944     case LWM32:
13945         gen_helper_lwm(cpu_env, t0, t1, t2);
13946         break;
13947     case SWM32:
13948         gen_helper_swm(cpu_env, t0, t1, t2);
13949         break;
13950 #ifdef TARGET_MIPS64
13951     case LDM:
13952         gen_helper_ldm(cpu_env, t0, t1, t2);
13953         break;
13954     case SDM:
13955         gen_helper_sdm(cpu_env, t0, t1, t2);
13956         break;
13957 #endif
13958     }
13959     tcg_temp_free(t0);
13960     tcg_temp_free(t1);
13961     tcg_temp_free_i32(t2);
13962 }
13963
13964
13965 static void gen_pool16c_insn(DisasContext *ctx)
13966 {
13967     int rd = mmreg((ctx->opcode >> 3) & 0x7);
13968     int rs = mmreg(ctx->opcode & 0x7);
13969
13970     switch (((ctx->opcode) >> 4) & 0x3f) {
13971     case NOT16 + 0:
13972     case NOT16 + 1:
13973     case NOT16 + 2:
13974     case NOT16 + 3:
13975         gen_logic(ctx, OPC_NOR, rd, rs, 0);
13976         break;
13977     case XOR16 + 0:
13978     case XOR16 + 1:
13979     case XOR16 + 2:
13980     case XOR16 + 3:
13981         gen_logic(ctx, OPC_XOR, rd, rd, rs);
13982         break;
13983     case AND16 + 0:
13984     case AND16 + 1:
13985     case AND16 + 2:
13986     case AND16 + 3:
13987         gen_logic(ctx, OPC_AND, rd, rd, rs);
13988         break;
13989     case OR16 + 0:
13990     case OR16 + 1:
13991     case OR16 + 2:
13992     case OR16 + 3:
13993         gen_logic(ctx, OPC_OR, rd, rd, rs);
13994         break;
13995     case LWM16 + 0:
13996     case LWM16 + 1:
13997     case LWM16 + 2:
13998     case LWM16 + 3:
13999         {
14000             static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14001             int offset = ZIMM(ctx->opcode, 0, 4);
14002
14003             gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
14004                               29, offset << 2);
14005         }
14006         break;
14007     case SWM16 + 0:
14008     case SWM16 + 1:
14009     case SWM16 + 2:
14010     case SWM16 + 3:
14011         {
14012             static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14013             int offset = ZIMM(ctx->opcode, 0, 4);
14014
14015             gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
14016                               29, offset << 2);
14017         }
14018         break;
14019     case JR16 + 0:
14020     case JR16 + 1:
14021         {
14022             int reg = ctx->opcode & 0x1f;
14023
14024             gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
14025         }
14026         break;
14027     case JRC16 + 0:
14028     case JRC16 + 1:
14029         {
14030             int reg = ctx->opcode & 0x1f;
14031             gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
14032             /* Let normal delay slot handling in our caller take us
14033                to the branch target.  */
14034         }
14035         break;
14036     case JALR16 + 0:
14037     case JALR16 + 1:
14038         gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
14039         ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14040         break;
14041     case JALR16S + 0:
14042     case JALR16S + 1:
14043         gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
14044         ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14045         break;
14046     case MFHI16 + 0:
14047     case MFHI16 + 1:
14048         gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
14049         break;
14050     case MFLO16 + 0:
14051     case MFLO16 + 1:
14052         gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
14053         break;
14054     case BREAK16:
14055         generate_exception_end(ctx, EXCP_BREAK);
14056         break;
14057     case SDBBP16:
14058         if (is_uhi(extract32(ctx->opcode, 0, 4))) {
14059             gen_helper_do_semihosting(cpu_env);
14060         } else {
14061             /* XXX: not clear which exception should be raised
14062              *      when in debug mode...
14063              */
14064             check_insn(ctx, ISA_MIPS32);
14065             generate_exception_end(ctx, EXCP_DBp);
14066         }
14067         break;
14068     case JRADDIUSP + 0:
14069     case JRADDIUSP + 1:
14070         {
14071             int imm = ZIMM(ctx->opcode, 0, 5);
14072             gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
14073             gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
14074             /* Let normal delay slot handling in our caller take us
14075                to the branch target.  */
14076         }
14077         break;
14078     default:
14079         generate_exception_end(ctx, EXCP_RI);
14080         break;
14081     }
14082 }
14083
14084 static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
14085                              int enc_rs)
14086 {
14087     int rd, rs, re, rt;
14088     static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
14089     static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
14090     static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
14091     rd = rd_enc[enc_dest];
14092     re = re_enc[enc_dest];
14093     rs = rs_rt_enc[enc_rs];
14094     rt = rs_rt_enc[enc_rt];
14095     if (rs) {
14096         tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
14097     } else {
14098         tcg_gen_movi_tl(cpu_gpr[rd], 0);
14099     }
14100     if (rt) {
14101         tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
14102     } else {
14103         tcg_gen_movi_tl(cpu_gpr[re], 0);
14104     }
14105 }
14106
14107 static void gen_pool16c_r6_insn(DisasContext *ctx)
14108 {
14109     int rt = mmreg((ctx->opcode >> 7) & 0x7);
14110     int rs = mmreg((ctx->opcode >> 4) & 0x7);
14111
14112     switch (ctx->opcode & 0xf) {
14113     case R6_NOT16:
14114         gen_logic(ctx, OPC_NOR, rt, rs, 0);
14115         break;
14116     case R6_AND16:
14117         gen_logic(ctx, OPC_AND, rt, rt, rs);
14118         break;
14119     case R6_LWM16:
14120         {
14121             int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
14122             int offset = extract32(ctx->opcode, 4, 4);
14123             gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
14124         }
14125         break;
14126     case R6_JRC16: /* JRCADDIUSP */
14127         if ((ctx->opcode >> 4) & 1) {
14128             /* JRCADDIUSP */
14129             int imm = extract32(ctx->opcode, 5, 5);
14130             gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
14131             gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
14132         } else {
14133             /* JRC16 */
14134             rs = extract32(ctx->opcode, 5, 5);
14135             gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
14136         }
14137         break;
14138     case MOVEP:
14139     case MOVEP_05:
14140     case MOVEP_06:
14141     case MOVEP_07:
14142     case MOVEP_0C:
14143     case MOVEP_0D:
14144     case MOVEP_0E:
14145     case MOVEP_0F:
14146         {
14147             int enc_dest = uMIPS_RD(ctx->opcode);
14148             int enc_rt = uMIPS_RS2(ctx->opcode);
14149             int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
14150             gen_movep(ctx, enc_dest, enc_rt, enc_rs);
14151         }
14152         break;
14153     case R6_XOR16:
14154         gen_logic(ctx, OPC_XOR, rt, rt, rs);
14155         break;
14156     case R6_OR16:
14157         gen_logic(ctx, OPC_OR, rt, rt, rs);
14158         break;
14159     case R6_SWM16:
14160         {
14161             int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
14162             int offset = extract32(ctx->opcode, 4, 4);
14163             gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
14164         }
14165         break;
14166     case JALRC16: /* BREAK16, SDBBP16 */
14167         switch (ctx->opcode & 0x3f) {
14168         case JALRC16:
14169         case JALRC16 + 0x20:
14170             /* JALRC16 */
14171             gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
14172                                31, 0, 0);
14173             break;
14174         case R6_BREAK16:
14175             /* BREAK16 */
14176             generate_exception(ctx, EXCP_BREAK);
14177             break;
14178         case R6_SDBBP16:
14179             /* SDBBP16 */
14180             if (is_uhi(extract32(ctx->opcode, 6, 4))) {
14181                 gen_helper_do_semihosting(cpu_env);
14182             } else {
14183                 if (ctx->hflags & MIPS_HFLAG_SBRI) {
14184                     generate_exception(ctx, EXCP_RI);
14185                 } else {
14186                     generate_exception(ctx, EXCP_DBp);
14187                 }
14188             }
14189             break;
14190         }
14191         break;
14192     default:
14193         generate_exception(ctx, EXCP_RI);
14194         break;
14195     }
14196 }
14197
14198 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
14199 {
14200     TCGv t0 = tcg_temp_new();
14201     TCGv t1 = tcg_temp_new();
14202
14203     gen_load_gpr(t0, base);
14204
14205     if (index != 0) {
14206         gen_load_gpr(t1, index);
14207         tcg_gen_shli_tl(t1, t1, 2);
14208         gen_op_addr_add(ctx, t0, t1, t0);
14209     }
14210
14211     tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
14212     gen_store_gpr(t1, rd);
14213
14214     tcg_temp_free(t0);
14215     tcg_temp_free(t1);
14216 }
14217
14218 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
14219                            int base, int16_t offset)
14220 {
14221     TCGv t0, t1;
14222
14223     if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
14224         generate_exception_end(ctx, EXCP_RI);
14225         return;
14226     }
14227
14228     t0 = tcg_temp_new();
14229     t1 = tcg_temp_new();
14230
14231     gen_base_offset_addr(ctx, t0, base, offset);
14232
14233     switch (opc) {
14234     case LWP:
14235         if (rd == base) {
14236             generate_exception_end(ctx, EXCP_RI);
14237             return;
14238         }
14239         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
14240         gen_store_gpr(t1, rd);
14241         tcg_gen_movi_tl(t1, 4);
14242         gen_op_addr_add(ctx, t0, t0, t1);
14243         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
14244         gen_store_gpr(t1, rd+1);
14245         break;
14246     case SWP:
14247         gen_load_gpr(t1, rd);
14248         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
14249         tcg_gen_movi_tl(t1, 4);
14250         gen_op_addr_add(ctx, t0, t0, t1);
14251         gen_load_gpr(t1, rd+1);
14252         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
14253         break;
14254 #ifdef TARGET_MIPS64
14255     case LDP:
14256         if (rd == base) {
14257             generate_exception_end(ctx, EXCP_RI);
14258             return;
14259         }
14260         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14261         gen_store_gpr(t1, rd);
14262         tcg_gen_movi_tl(t1, 8);
14263         gen_op_addr_add(ctx, t0, t0, t1);
14264         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14265         gen_store_gpr(t1, rd+1);
14266         break;
14267     case SDP:
14268         gen_load_gpr(t1, rd);
14269         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14270         tcg_gen_movi_tl(t1, 8);
14271         gen_op_addr_add(ctx, t0, t0, t1);
14272         gen_load_gpr(t1, rd+1);
14273         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14274         break;
14275 #endif
14276     }
14277     tcg_temp_free(t0);
14278     tcg_temp_free(t1);
14279 }
14280
14281 static void gen_sync(int stype)
14282 {
14283     TCGBar tcg_mo = TCG_BAR_SC;
14284
14285     switch (stype) {
14286     case 0x4: /* SYNC_WMB */
14287         tcg_mo |= TCG_MO_ST_ST;
14288         break;
14289     case 0x10: /* SYNC_MB */
14290         tcg_mo |= TCG_MO_ALL;
14291         break;
14292     case 0x11: /* SYNC_ACQUIRE */
14293         tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
14294         break;
14295     case 0x12: /* SYNC_RELEASE */
14296         tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
14297         break;
14298     case 0x13: /* SYNC_RMB */
14299         tcg_mo |= TCG_MO_LD_LD;
14300         break;
14301     default:
14302         tcg_mo |= TCG_MO_ALL;
14303         break;
14304     }
14305
14306     tcg_gen_mb(tcg_mo);
14307 }
14308
14309 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
14310 {
14311     int extension = (ctx->opcode >> 6) & 0x3f;
14312     int minor = (ctx->opcode >> 12) & 0xf;
14313     uint32_t mips32_op;
14314
14315     switch (extension) {
14316     case TEQ:
14317         mips32_op = OPC_TEQ;
14318         goto do_trap;
14319     case TGE:
14320         mips32_op = OPC_TGE;
14321         goto do_trap;
14322     case TGEU:
14323         mips32_op = OPC_TGEU;
14324         goto do_trap;
14325     case TLT:
14326         mips32_op = OPC_TLT;
14327         goto do_trap;
14328     case TLTU:
14329         mips32_op = OPC_TLTU;
14330         goto do_trap;
14331     case TNE:
14332         mips32_op = OPC_TNE;
14333     do_trap:
14334         gen_trap(ctx, mips32_op, rs, rt, -1);
14335         break;
14336 #ifndef CONFIG_USER_ONLY
14337     case MFC0:
14338     case MFC0 + 32:
14339         check_cp0_enabled(ctx);
14340         if (rt == 0) {
14341             /* Treat as NOP. */
14342             break;
14343         }
14344         gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
14345         break;
14346     case MTC0:
14347     case MTC0 + 32:
14348         check_cp0_enabled(ctx);
14349         {
14350             TCGv t0 = tcg_temp_new();
14351
14352             gen_load_gpr(t0, rt);
14353             gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
14354             tcg_temp_free(t0);
14355         }
14356         break;
14357 #endif
14358     case 0x2a:
14359         switch (minor & 3) {
14360         case MADD_ACC:
14361             gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
14362             break;
14363         case MADDU_ACC:
14364             gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
14365             break;
14366         case MSUB_ACC:
14367             gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
14368             break;
14369         case MSUBU_ACC:
14370             gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
14371             break;
14372         default:
14373             goto pool32axf_invalid;
14374         }
14375         break;
14376     case 0x32:
14377         switch (minor & 3) {
14378         case MULT_ACC:
14379             gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
14380             break;
14381         case MULTU_ACC:
14382             gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
14383             break;
14384         default:
14385             goto pool32axf_invalid;
14386         }
14387         break;
14388     case 0x2c:
14389         switch (minor) {
14390         case BITSWAP:
14391             check_insn(ctx, ISA_MIPS32R6);
14392             gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
14393             break;
14394         case SEB:
14395             gen_bshfl(ctx, OPC_SEB, rs, rt);
14396             break;
14397         case SEH:
14398             gen_bshfl(ctx, OPC_SEH, rs, rt);
14399             break;
14400         case CLO:
14401             mips32_op = OPC_CLO;
14402             goto do_cl;
14403         case CLZ:
14404             mips32_op = OPC_CLZ;
14405         do_cl:
14406             check_insn(ctx, ISA_MIPS32);
14407             gen_cl(ctx, mips32_op, rt, rs);
14408             break;
14409         case RDHWR:
14410             check_insn_opc_removed(ctx, ISA_MIPS32R6);
14411             gen_rdhwr(ctx, rt, rs, 0);
14412             break;
14413         case WSBH:
14414             gen_bshfl(ctx, OPC_WSBH, rs, rt);
14415             break;
14416         case MULT:
14417             check_insn_opc_removed(ctx, ISA_MIPS32R6);
14418             mips32_op = OPC_MULT;
14419             goto do_mul;
14420         case MULTU:
14421             check_insn_opc_removed(ctx, ISA_MIPS32R6);
14422             mips32_op = OPC_MULTU;
14423             goto do_mul;
14424         case DIV:
14425             check_insn_opc_removed(ctx, ISA_MIPS32R6);
14426             mips32_op = OPC_DIV;
14427             goto do_div;
14428         case DIVU:
14429             check_insn_opc_removed(ctx, ISA_MIPS32R6);
14430             mips32_op = OPC_DIVU;
14431             goto do_div;
14432         do_div:
14433             check_insn(ctx, ISA_MIPS32);
14434             gen_muldiv(ctx, mips32_op, 0, rs, rt);
14435             break;
14436         case MADD:
14437             check_insn_opc_removed(ctx, ISA_MIPS32R6);
14438             mips32_op = OPC_MADD;
14439             goto do_mul;
14440         case MADDU:
14441             check_insn_opc_removed(ctx, ISA_MIPS32R6);
14442             mips32_op = OPC_MADDU;
14443             goto do_mul;
14444         case MSUB:
14445             check_insn_opc_removed(ctx, ISA_MIPS32R6);
14446             mips32_op = OPC_MSUB;
14447             goto do_mul;
14448         case MSUBU:
14449             check_insn_opc_removed(ctx, ISA_MIPS32R6);
14450             mips32_op = OPC_MSUBU;
14451         do_mul:
14452             check_insn(ctx, ISA_MIPS32);
14453             gen_muldiv(ctx, mips32_op, 0, rs, rt);
14454             break;
14455         default:
14456             goto pool32axf_invalid;
14457         }
14458         break;
14459     case 0x34:
14460         switch (minor) {
14461         case MFC2:
14462         case MTC2:
14463         case MFHC2:
14464         case MTHC2:
14465         case CFC2:
14466         case CTC2:
14467             generate_exception_err(ctx, EXCP_CpU, 2);
14468             break;
14469         default:
14470             goto pool32axf_invalid;
14471         }
14472         break;
14473     case 0x3c:
14474         switch (minor) {
14475         case JALR:    /* JALRC */
14476         case JALR_HB: /* JALRC_HB */
14477             if (ctx->insn_flags & ISA_MIPS32R6) {
14478                 /* JALRC, JALRC_HB */
14479                 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
14480             } else {
14481                 /* JALR, JALR_HB */
14482                 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
14483                 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14484             }
14485             break;
14486         case JALRS:
14487         case JALRS_HB:
14488             check_insn_opc_removed(ctx, ISA_MIPS32R6);
14489             gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
14490             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14491             break;
14492         default:
14493             goto pool32axf_invalid;
14494         }
14495         break;
14496     case 0x05:
14497         switch (minor) {
14498         case RDPGPR:
14499             check_cp0_enabled(ctx);
14500             check_insn(ctx, ISA_MIPS32R2);
14501             gen_load_srsgpr(rs, rt);
14502             break;
14503         case WRPGPR:
14504             check_cp0_enabled(ctx);
14505             check_insn(ctx, ISA_MIPS32R2);
14506             gen_store_srsgpr(rs, rt);
14507             break;
14508         default:
14509             goto pool32axf_invalid;
14510         }
14511         break;
14512 #ifndef CONFIG_USER_ONLY
14513     case 0x0d:
14514         switch (minor) {
14515         case TLBP:
14516             mips32_op = OPC_TLBP;
14517             goto do_cp0;
14518         case TLBR:
14519             mips32_op = OPC_TLBR;
14520             goto do_cp0;
14521         case TLBWI:
14522             mips32_op = OPC_TLBWI;
14523             goto do_cp0;
14524         case TLBWR:
14525             mips32_op = OPC_TLBWR;
14526             goto do_cp0;
14527         case TLBINV:
14528             mips32_op = OPC_TLBINV;
14529             goto do_cp0;
14530         case TLBINVF:
14531             mips32_op = OPC_TLBINVF;
14532             goto do_cp0;
14533         case WAIT:
14534             mips32_op = OPC_WAIT;
14535             goto do_cp0;
14536         case DERET:
14537             mips32_op = OPC_DERET;
14538             goto do_cp0;
14539         case ERET:
14540             mips32_op = OPC_ERET;
14541         do_cp0:
14542             gen_cp0(env, ctx, mips32_op, rt, rs);
14543             break;
14544         default:
14545             goto pool32axf_invalid;
14546         }
14547         break;
14548     case 0x1d:
14549         switch (minor) {
14550         case DI:
14551             check_cp0_enabled(ctx);
14552             {
14553                 TCGv t0 = tcg_temp_new();
14554
14555                 save_cpu_state(ctx, 1);
14556                 gen_helper_di(t0, cpu_env);
14557                 gen_store_gpr(t0, rs);
14558                 /* Stop translation as we may have switched the execution mode */
14559                 ctx->base.is_jmp = DISAS_STOP;
14560                 tcg_temp_free(t0);
14561             }
14562             break;
14563         case EI:
14564             check_cp0_enabled(ctx);
14565             {
14566                 TCGv t0 = tcg_temp_new();
14567
14568                 save_cpu_state(ctx, 1);
14569                 gen_helper_ei(t0, cpu_env);
14570                 gen_store_gpr(t0, rs);
14571                 /* DISAS_STOP isn't sufficient, we need to ensure we break out
14572                    of translated code to check for pending interrupts.  */
14573                 gen_save_pc(ctx->base.pc_next + 4);
14574                 ctx->base.is_jmp = DISAS_EXIT;
14575                 tcg_temp_free(t0);
14576             }
14577             break;
14578         default:
14579             goto pool32axf_invalid;
14580         }
14581         break;
14582 #endif
14583     case 0x2d:
14584         switch (minor) {
14585         case SYNC:
14586             gen_sync(extract32(ctx->opcode, 16, 5));
14587             break;
14588         case SYSCALL:
14589             generate_exception_end(ctx, EXCP_SYSCALL);
14590             break;
14591         case SDBBP:
14592             if (is_uhi(extract32(ctx->opcode, 16, 10))) {
14593                 gen_helper_do_semihosting(cpu_env);
14594             } else {
14595                 check_insn(ctx, ISA_MIPS32);
14596                 if (ctx->hflags & MIPS_HFLAG_SBRI) {
14597                     generate_exception_end(ctx, EXCP_RI);
14598                 } else {
14599                     generate_exception_end(ctx, EXCP_DBp);
14600                 }
14601             }
14602             break;
14603         default:
14604             goto pool32axf_invalid;
14605         }
14606         break;
14607     case 0x01:
14608         switch (minor & 3) {
14609         case MFHI_ACC:
14610             gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
14611             break;
14612         case MFLO_ACC:
14613             gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
14614             break;
14615         case MTHI_ACC:
14616             gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
14617             break;
14618         case MTLO_ACC:
14619             gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
14620             break;
14621         default:
14622             goto pool32axf_invalid;
14623         }
14624         break;
14625     case 0x35:
14626         check_insn_opc_removed(ctx, ISA_MIPS32R6);
14627         switch (minor) {
14628         case MFHI32:
14629             gen_HILO(ctx, OPC_MFHI, 0, rs);
14630             break;
14631         case MFLO32:
14632             gen_HILO(ctx, OPC_MFLO, 0, rs);
14633             break;
14634         case MTHI32:
14635             gen_HILO(ctx, OPC_MTHI, 0, rs);
14636             break;
14637         case MTLO32:
14638             gen_HILO(ctx, OPC_MTLO, 0, rs);
14639             break;
14640         default:
14641             goto pool32axf_invalid;
14642         }
14643         break;
14644     default:
14645     pool32axf_invalid:
14646         MIPS_INVAL("pool32axf");
14647         generate_exception_end(ctx, EXCP_RI);
14648         break;
14649     }
14650 }
14651
14652 /* Values for microMIPS fmt field.  Variable-width, depending on which
14653    formats the instruction supports.  */
14654
14655 enum {
14656     FMT_SD_S = 0,
14657     FMT_SD_D = 1,
14658
14659     FMT_SDPS_S = 0,
14660     FMT_SDPS_D = 1,
14661     FMT_SDPS_PS = 2,
14662
14663     FMT_SWL_S = 0,
14664     FMT_SWL_W = 1,
14665     FMT_SWL_L = 2,
14666
14667     FMT_DWL_D = 0,
14668     FMT_DWL_W = 1,
14669     FMT_DWL_L = 2
14670 };
14671
14672 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
14673 {
14674     int extension = (ctx->opcode >> 6) & 0x3ff;
14675     uint32_t mips32_op;
14676
14677 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
14678 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
14679 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
14680
14681     switch (extension) {
14682     case FLOAT_1BIT_FMT(CFC1, 0):
14683         mips32_op = OPC_CFC1;
14684         goto do_cp1;
14685     case FLOAT_1BIT_FMT(CTC1, 0):
14686         mips32_op = OPC_CTC1;
14687         goto do_cp1;
14688     case FLOAT_1BIT_FMT(MFC1, 0):
14689         mips32_op = OPC_MFC1;
14690         goto do_cp1;
14691     case FLOAT_1BIT_FMT(MTC1, 0):
14692         mips32_op = OPC_MTC1;
14693         goto do_cp1;
14694     case FLOAT_1BIT_FMT(MFHC1, 0):
14695         mips32_op = OPC_MFHC1;
14696         goto do_cp1;
14697     case FLOAT_1BIT_FMT(MTHC1, 0):
14698         mips32_op = OPC_MTHC1;
14699     do_cp1:
14700         gen_cp1(ctx, mips32_op, rt, rs);
14701         break;
14702
14703         /* Reciprocal square root */
14704     case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
14705         mips32_op = OPC_RSQRT_S;
14706         goto do_unaryfp;
14707     case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
14708         mips32_op = OPC_RSQRT_D;
14709         goto do_unaryfp;
14710
14711         /* Square root */
14712     case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
14713         mips32_op = OPC_SQRT_S;
14714         goto do_unaryfp;
14715     case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
14716         mips32_op = OPC_SQRT_D;
14717         goto do_unaryfp;
14718
14719         /* Reciprocal */
14720     case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
14721         mips32_op = OPC_RECIP_S;
14722         goto do_unaryfp;
14723     case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
14724         mips32_op = OPC_RECIP_D;
14725         goto do_unaryfp;
14726
14727         /* Floor */
14728     case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
14729         mips32_op = OPC_FLOOR_L_S;
14730         goto do_unaryfp;
14731     case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
14732         mips32_op = OPC_FLOOR_L_D;
14733         goto do_unaryfp;
14734     case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
14735         mips32_op = OPC_FLOOR_W_S;
14736         goto do_unaryfp;
14737     case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
14738         mips32_op = OPC_FLOOR_W_D;
14739         goto do_unaryfp;
14740
14741         /* Ceiling */
14742     case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
14743         mips32_op = OPC_CEIL_L_S;
14744         goto do_unaryfp;
14745     case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
14746         mips32_op = OPC_CEIL_L_D;
14747         goto do_unaryfp;
14748     case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
14749         mips32_op = OPC_CEIL_W_S;
14750         goto do_unaryfp;
14751     case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
14752         mips32_op = OPC_CEIL_W_D;
14753         goto do_unaryfp;
14754
14755         /* Truncation */
14756     case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
14757         mips32_op = OPC_TRUNC_L_S;
14758         goto do_unaryfp;
14759     case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
14760         mips32_op = OPC_TRUNC_L_D;
14761         goto do_unaryfp;
14762     case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
14763         mips32_op = OPC_TRUNC_W_S;
14764         goto do_unaryfp;
14765     case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
14766         mips32_op = OPC_TRUNC_W_D;
14767         goto do_unaryfp;
14768
14769         /* Round */
14770     case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
14771         mips32_op = OPC_ROUND_L_S;
14772         goto do_unaryfp;
14773     case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
14774         mips32_op = OPC_ROUND_L_D;
14775         goto do_unaryfp;
14776     case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
14777         mips32_op = OPC_ROUND_W_S;
14778         goto do_unaryfp;
14779     case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
14780         mips32_op = OPC_ROUND_W_D;
14781         goto do_unaryfp;
14782
14783         /* Integer to floating-point conversion */
14784     case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
14785         mips32_op = OPC_CVT_L_S;
14786         goto do_unaryfp;
14787     case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
14788         mips32_op = OPC_CVT_L_D;
14789         goto do_unaryfp;
14790     case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
14791         mips32_op = OPC_CVT_W_S;
14792         goto do_unaryfp;
14793     case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
14794         mips32_op = OPC_CVT_W_D;
14795         goto do_unaryfp;
14796
14797         /* Paired-foo conversions */
14798     case FLOAT_1BIT_FMT(CVT_S_PL, 0):
14799         mips32_op = OPC_CVT_S_PL;
14800         goto do_unaryfp;
14801     case FLOAT_1BIT_FMT(CVT_S_PU, 0):
14802         mips32_op = OPC_CVT_S_PU;
14803         goto do_unaryfp;
14804     case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
14805         mips32_op = OPC_CVT_PW_PS;
14806         goto do_unaryfp;
14807     case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
14808         mips32_op = OPC_CVT_PS_PW;
14809         goto do_unaryfp;
14810
14811         /* Floating-point moves */
14812     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
14813         mips32_op = OPC_MOV_S;
14814         goto do_unaryfp;
14815     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
14816         mips32_op = OPC_MOV_D;
14817         goto do_unaryfp;
14818     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
14819         mips32_op = OPC_MOV_PS;
14820         goto do_unaryfp;
14821
14822         /* Absolute value */
14823     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
14824         mips32_op = OPC_ABS_S;
14825         goto do_unaryfp;
14826     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
14827         mips32_op = OPC_ABS_D;
14828         goto do_unaryfp;
14829     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
14830         mips32_op = OPC_ABS_PS;
14831         goto do_unaryfp;
14832
14833         /* Negation */
14834     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
14835         mips32_op = OPC_NEG_S;
14836         goto do_unaryfp;
14837     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
14838         mips32_op = OPC_NEG_D;
14839         goto do_unaryfp;
14840     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
14841         mips32_op = OPC_NEG_PS;
14842         goto do_unaryfp;
14843
14844         /* Reciprocal square root step */
14845     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
14846         mips32_op = OPC_RSQRT1_S;
14847         goto do_unaryfp;
14848     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
14849         mips32_op = OPC_RSQRT1_D;
14850         goto do_unaryfp;
14851     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
14852         mips32_op = OPC_RSQRT1_PS;
14853         goto do_unaryfp;
14854
14855         /* Reciprocal step */
14856     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
14857         mips32_op = OPC_RECIP1_S;
14858         goto do_unaryfp;
14859     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
14860         mips32_op = OPC_RECIP1_S;
14861         goto do_unaryfp;
14862     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
14863         mips32_op = OPC_RECIP1_PS;
14864         goto do_unaryfp;
14865
14866         /* Conversions from double */
14867     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
14868         mips32_op = OPC_CVT_D_S;
14869         goto do_unaryfp;
14870     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
14871         mips32_op = OPC_CVT_D_W;
14872         goto do_unaryfp;
14873     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
14874         mips32_op = OPC_CVT_D_L;
14875         goto do_unaryfp;
14876
14877         /* Conversions from single */
14878     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
14879         mips32_op = OPC_CVT_S_D;
14880         goto do_unaryfp;
14881     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
14882         mips32_op = OPC_CVT_S_W;
14883         goto do_unaryfp;
14884     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
14885         mips32_op = OPC_CVT_S_L;
14886     do_unaryfp:
14887         gen_farith(ctx, mips32_op, -1, rs, rt, 0);
14888         break;
14889
14890         /* Conditional moves on floating-point codes */
14891     case COND_FLOAT_MOV(MOVT, 0):
14892     case COND_FLOAT_MOV(MOVT, 1):
14893     case COND_FLOAT_MOV(MOVT, 2):
14894     case COND_FLOAT_MOV(MOVT, 3):
14895     case COND_FLOAT_MOV(MOVT, 4):
14896     case COND_FLOAT_MOV(MOVT, 5):
14897     case COND_FLOAT_MOV(MOVT, 6):
14898     case COND_FLOAT_MOV(MOVT, 7):
14899         check_insn_opc_removed(ctx, ISA_MIPS32R6);
14900         gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
14901         break;
14902     case COND_FLOAT_MOV(MOVF, 0):
14903     case COND_FLOAT_MOV(MOVF, 1):
14904     case COND_FLOAT_MOV(MOVF, 2):
14905     case COND_FLOAT_MOV(MOVF, 3):
14906     case COND_FLOAT_MOV(MOVF, 4):
14907     case COND_FLOAT_MOV(MOVF, 5):
14908     case COND_FLOAT_MOV(MOVF, 6):
14909     case COND_FLOAT_MOV(MOVF, 7):
14910         check_insn_opc_removed(ctx, ISA_MIPS32R6);
14911         gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
14912         break;
14913     default:
14914         MIPS_INVAL("pool32fxf");
14915         generate_exception_end(ctx, EXCP_RI);
14916         break;
14917     }
14918 }
14919
14920 static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
14921 {
14922     int32_t offset;
14923     uint16_t insn;
14924     int rt, rs, rd, rr;
14925     int16_t imm;
14926     uint32_t op, minor, minor2, mips32_op;
14927     uint32_t cond, fmt, cc;
14928
14929     insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
14930     ctx->opcode = (ctx->opcode << 16) | insn;
14931
14932     rt = (ctx->opcode >> 21) & 0x1f;
14933     rs = (ctx->opcode >> 16) & 0x1f;
14934     rd = (ctx->opcode >> 11) & 0x1f;
14935     rr = (ctx->opcode >> 6) & 0x1f;
14936     imm = (int16_t) ctx->opcode;
14937
14938     op = (ctx->opcode >> 26) & 0x3f;
14939     switch (op) {
14940     case POOL32A:
14941         minor = ctx->opcode & 0x3f;
14942         switch (minor) {
14943         case 0x00:
14944             minor = (ctx->opcode >> 6) & 0xf;
14945             switch (minor) {
14946             case SLL32:
14947                 mips32_op = OPC_SLL;
14948                 goto do_shifti;
14949             case SRA:
14950                 mips32_op = OPC_SRA;
14951                 goto do_shifti;
14952             case SRL32:
14953                 mips32_op = OPC_SRL;
14954                 goto do_shifti;
14955             case ROTR:
14956                 mips32_op = OPC_ROTR;
14957             do_shifti:
14958                 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
14959                 break;
14960             case SELEQZ:
14961                 check_insn(ctx, ISA_MIPS32R6);
14962                 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
14963                 break;
14964             case SELNEZ:
14965                 check_insn(ctx, ISA_MIPS32R6);
14966                 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
14967                 break;
14968             case R6_RDHWR:
14969                 check_insn(ctx, ISA_MIPS32R6);
14970                 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
14971                 break;
14972             default:
14973                 goto pool32a_invalid;
14974             }
14975             break;
14976         case 0x10:
14977             minor = (ctx->opcode >> 6) & 0xf;
14978             switch (minor) {
14979                 /* Arithmetic */
14980             case ADD:
14981                 mips32_op = OPC_ADD;
14982                 goto do_arith;
14983             case ADDU32:
14984                 mips32_op = OPC_ADDU;
14985                 goto do_arith;
14986             case SUB:
14987                 mips32_op = OPC_SUB;
14988                 goto do_arith;
14989             case SUBU32:
14990                 mips32_op = OPC_SUBU;
14991                 goto do_arith;
14992             case MUL:
14993                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14994                 mips32_op = OPC_MUL;
14995             do_arith:
14996                 gen_arith(ctx, mips32_op, rd, rs, rt);
14997                 break;
14998                 /* Shifts */
14999             case SLLV:
15000                 mips32_op = OPC_SLLV;
15001                 goto do_shift;
15002             case SRLV:
15003                 mips32_op = OPC_SRLV;
15004                 goto do_shift;
15005             case SRAV:
15006                 mips32_op = OPC_SRAV;
15007                 goto do_shift;
15008             case ROTRV:
15009                 mips32_op = OPC_ROTRV;
15010             do_shift:
15011                 gen_shift(ctx, mips32_op, rd, rs, rt);
15012                 break;
15013                 /* Logical operations */
15014             case AND:
15015                 mips32_op = OPC_AND;
15016                 goto do_logic;
15017             case OR32:
15018                 mips32_op = OPC_OR;
15019                 goto do_logic;
15020             case NOR:
15021                 mips32_op = OPC_NOR;
15022                 goto do_logic;
15023             case XOR32:
15024                 mips32_op = OPC_XOR;
15025             do_logic:
15026                 gen_logic(ctx, mips32_op, rd, rs, rt);
15027                 break;
15028                 /* Set less than */
15029             case SLT:
15030                 mips32_op = OPC_SLT;
15031                 goto do_slt;
15032             case SLTU:
15033                 mips32_op = OPC_SLTU;
15034             do_slt:
15035                 gen_slt(ctx, mips32_op, rd, rs, rt);
15036                 break;
15037             default:
15038                 goto pool32a_invalid;
15039             }
15040             break;
15041         case 0x18:
15042             minor = (ctx->opcode >> 6) & 0xf;
15043             switch (minor) {
15044                 /* Conditional moves */
15045             case MOVN: /* MUL */
15046                 if (ctx->insn_flags & ISA_MIPS32R6) {
15047                     /* MUL */
15048                     gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
15049                 } else {
15050                     /* MOVN */
15051                     gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
15052                 }
15053                 break;
15054             case MOVZ: /* MUH */
15055                 if (ctx->insn_flags & ISA_MIPS32R6) {
15056                     /* MUH */
15057                     gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
15058                 } else {
15059                     /* MOVZ */
15060                     gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
15061                 }
15062                 break;
15063             case MULU:
15064                 check_insn(ctx, ISA_MIPS32R6);
15065                 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
15066                 break;
15067             case MUHU:
15068                 check_insn(ctx, ISA_MIPS32R6);
15069                 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
15070                 break;
15071             case LWXS: /* DIV */
15072                 if (ctx->insn_flags & ISA_MIPS32R6) {
15073                     /* DIV */
15074                     gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
15075                 } else {
15076                     /* LWXS */
15077                     gen_ldxs(ctx, rs, rt, rd);
15078                 }
15079                 break;
15080             case MOD:
15081                 check_insn(ctx, ISA_MIPS32R6);
15082                 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
15083                 break;
15084             case R6_DIVU:
15085                 check_insn(ctx, ISA_MIPS32R6);
15086                 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
15087                 break;
15088             case MODU:
15089                 check_insn(ctx, ISA_MIPS32R6);
15090                 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
15091                 break;
15092             default:
15093                 goto pool32a_invalid;
15094             }
15095             break;
15096         case INS:
15097             gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
15098             return;
15099         case LSA:
15100             check_insn(ctx, ISA_MIPS32R6);
15101             gen_lsa(ctx, OPC_LSA, rd, rs, rt,
15102                     extract32(ctx->opcode, 9, 2));
15103             break;
15104         case ALIGN:
15105             check_insn(ctx, ISA_MIPS32R6);
15106             gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2));
15107             break;
15108         case EXT:
15109             gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
15110             return;
15111         case POOL32AXF:
15112             gen_pool32axf(env, ctx, rt, rs);
15113             break;
15114         case BREAK32:
15115             generate_exception_end(ctx, EXCP_BREAK);
15116             break;
15117         case SIGRIE:
15118             check_insn(ctx, ISA_MIPS32R6);
15119             generate_exception_end(ctx, EXCP_RI);
15120             break;
15121         default:
15122         pool32a_invalid:
15123                 MIPS_INVAL("pool32a");
15124                 generate_exception_end(ctx, EXCP_RI);
15125                 break;
15126         }
15127         break;
15128     case POOL32B:
15129         minor = (ctx->opcode >> 12) & 0xf;
15130         switch (minor) {
15131         case CACHE:
15132             check_cp0_enabled(ctx);
15133             if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15134                 gen_cache_operation(ctx, rt, rs, imm);
15135             }
15136             break;
15137         case LWC2:
15138         case SWC2:
15139             /* COP2: Not implemented. */
15140             generate_exception_err(ctx, EXCP_CpU, 2);
15141             break;
15142 #ifdef TARGET_MIPS64
15143         case LDP:
15144         case SDP:
15145             check_insn(ctx, ISA_MIPS3);
15146             check_mips_64(ctx);
15147 #endif
15148             /* fall through */
15149         case LWP:
15150         case SWP:
15151             gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
15152             break;
15153 #ifdef TARGET_MIPS64
15154         case LDM:
15155         case SDM:
15156             check_insn(ctx, ISA_MIPS3);
15157             check_mips_64(ctx);
15158 #endif
15159             /* fall through */
15160         case LWM32:
15161         case SWM32:
15162             gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
15163             break;
15164         default:
15165             MIPS_INVAL("pool32b");
15166             generate_exception_end(ctx, EXCP_RI);
15167             break;
15168         }
15169         break;
15170     case POOL32F:
15171         if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
15172             minor = ctx->opcode & 0x3f;
15173             check_cp1_enabled(ctx);
15174             switch (minor) {
15175             case ALNV_PS:
15176                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15177                 mips32_op = OPC_ALNV_PS;
15178                 goto do_madd;
15179             case MADD_S:
15180                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15181                 mips32_op = OPC_MADD_S;
15182                 goto do_madd;
15183             case MADD_D:
15184                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15185                 mips32_op = OPC_MADD_D;
15186                 goto do_madd;
15187             case MADD_PS:
15188                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15189                 mips32_op = OPC_MADD_PS;
15190                 goto do_madd;
15191             case MSUB_S:
15192                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15193                 mips32_op = OPC_MSUB_S;
15194                 goto do_madd;
15195             case MSUB_D:
15196                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15197                 mips32_op = OPC_MSUB_D;
15198                 goto do_madd;
15199             case MSUB_PS:
15200                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15201                 mips32_op = OPC_MSUB_PS;
15202                 goto do_madd;
15203             case NMADD_S:
15204                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15205                 mips32_op = OPC_NMADD_S;
15206                 goto do_madd;
15207             case NMADD_D:
15208                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15209                 mips32_op = OPC_NMADD_D;
15210                 goto do_madd;
15211             case NMADD_PS:
15212                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15213                 mips32_op = OPC_NMADD_PS;
15214                 goto do_madd;
15215             case NMSUB_S:
15216                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15217                 mips32_op = OPC_NMSUB_S;
15218                 goto do_madd;
15219             case NMSUB_D:
15220                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15221                 mips32_op = OPC_NMSUB_D;
15222                 goto do_madd;
15223             case NMSUB_PS:
15224                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15225                 mips32_op = OPC_NMSUB_PS;
15226             do_madd:
15227                 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
15228                 break;
15229             case CABS_COND_FMT:
15230                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15231                 cond = (ctx->opcode >> 6) & 0xf;
15232                 cc = (ctx->opcode >> 13) & 0x7;
15233                 fmt = (ctx->opcode >> 10) & 0x3;
15234                 switch (fmt) {
15235                 case 0x0:
15236                     gen_cmpabs_s(ctx, cond, rt, rs, cc);
15237                     break;
15238                 case 0x1:
15239                     gen_cmpabs_d(ctx, cond, rt, rs, cc);
15240                     break;
15241                 case 0x2:
15242                     gen_cmpabs_ps(ctx, cond, rt, rs, cc);
15243                     break;
15244                 default:
15245                     goto pool32f_invalid;
15246                 }
15247                 break;
15248             case C_COND_FMT:
15249                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15250                 cond = (ctx->opcode >> 6) & 0xf;
15251                 cc = (ctx->opcode >> 13) & 0x7;
15252                 fmt = (ctx->opcode >> 10) & 0x3;
15253                 switch (fmt) {
15254                 case 0x0:
15255                     gen_cmp_s(ctx, cond, rt, rs, cc);
15256                     break;
15257                 case 0x1:
15258                     gen_cmp_d(ctx, cond, rt, rs, cc);
15259                     break;
15260                 case 0x2:
15261                     gen_cmp_ps(ctx, cond, rt, rs, cc);
15262                     break;
15263                 default:
15264                     goto pool32f_invalid;
15265                 }
15266                 break;
15267             case CMP_CONDN_S:
15268                 check_insn(ctx, ISA_MIPS32R6);
15269                 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
15270                 break;
15271             case CMP_CONDN_D:
15272                 check_insn(ctx, ISA_MIPS32R6);
15273                 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
15274                 break;
15275             case POOL32FXF:
15276                 gen_pool32fxf(ctx, rt, rs);
15277                 break;
15278             case 0x00:
15279                 /* PLL foo */
15280                 switch ((ctx->opcode >> 6) & 0x7) {
15281                 case PLL_PS:
15282                     mips32_op = OPC_PLL_PS;
15283                     goto do_ps;
15284                 case PLU_PS:
15285                     mips32_op = OPC_PLU_PS;
15286                     goto do_ps;
15287                 case PUL_PS:
15288                     mips32_op = OPC_PUL_PS;
15289                     goto do_ps;
15290                 case PUU_PS:
15291                     mips32_op = OPC_PUU_PS;
15292                     goto do_ps;
15293                 case CVT_PS_S:
15294                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
15295                     mips32_op = OPC_CVT_PS_S;
15296                 do_ps:
15297                     gen_farith(ctx, mips32_op, rt, rs, rd, 0);
15298                     break;
15299                 default:
15300                     goto pool32f_invalid;
15301                 }
15302                 break;
15303             case MIN_FMT:
15304                 check_insn(ctx, ISA_MIPS32R6);
15305                 switch ((ctx->opcode >> 9) & 0x3) {
15306                 case FMT_SDPS_S:
15307                     gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
15308                     break;
15309                 case FMT_SDPS_D:
15310                     gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
15311                     break;
15312                 default:
15313                     goto pool32f_invalid;
15314                 }
15315                 break;
15316             case 0x08:
15317                 /* [LS][WDU]XC1 */
15318                 switch ((ctx->opcode >> 6) & 0x7) {
15319                 case LWXC1:
15320                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
15321                     mips32_op = OPC_LWXC1;
15322                     goto do_ldst_cp1;
15323                 case SWXC1:
15324                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
15325                     mips32_op = OPC_SWXC1;
15326                     goto do_ldst_cp1;
15327                 case LDXC1:
15328                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
15329                     mips32_op = OPC_LDXC1;
15330                     goto do_ldst_cp1;
15331                 case SDXC1:
15332                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
15333                     mips32_op = OPC_SDXC1;
15334                     goto do_ldst_cp1;
15335                 case LUXC1:
15336                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
15337                     mips32_op = OPC_LUXC1;
15338                     goto do_ldst_cp1;
15339                 case SUXC1:
15340                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
15341                     mips32_op = OPC_SUXC1;
15342                 do_ldst_cp1:
15343                     gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
15344                     break;
15345                 default:
15346                     goto pool32f_invalid;
15347                 }
15348                 break;
15349             case MAX_FMT:
15350                 check_insn(ctx, ISA_MIPS32R6);
15351                 switch ((ctx->opcode >> 9) & 0x3) {
15352                 case FMT_SDPS_S:
15353                     gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
15354                     break;
15355                 case FMT_SDPS_D:
15356                     gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
15357                     break;
15358                 default:
15359                     goto pool32f_invalid;
15360                 }
15361                 break;
15362             case 0x18:
15363                 /* 3D insns */
15364                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15365                 fmt = (ctx->opcode >> 9) & 0x3;
15366                 switch ((ctx->opcode >> 6) & 0x7) {
15367                 case RSQRT2_FMT:
15368                     switch (fmt) {
15369                     case FMT_SDPS_S:
15370                         mips32_op = OPC_RSQRT2_S;
15371                         goto do_3d;
15372                     case FMT_SDPS_D:
15373                         mips32_op = OPC_RSQRT2_D;
15374                         goto do_3d;
15375                     case FMT_SDPS_PS:
15376                         mips32_op = OPC_RSQRT2_PS;
15377                         goto do_3d;
15378                     default:
15379                         goto pool32f_invalid;
15380                     }
15381                     break;
15382                 case RECIP2_FMT:
15383                     switch (fmt) {
15384                     case FMT_SDPS_S:
15385                         mips32_op = OPC_RECIP2_S;
15386                         goto do_3d;
15387                     case FMT_SDPS_D:
15388                         mips32_op = OPC_RECIP2_D;
15389                         goto do_3d;
15390                     case FMT_SDPS_PS:
15391                         mips32_op = OPC_RECIP2_PS;
15392                         goto do_3d;
15393                     default:
15394                         goto pool32f_invalid;
15395                     }
15396                     break;
15397                 case ADDR_PS:
15398                     mips32_op = OPC_ADDR_PS;
15399                     goto do_3d;
15400                 case MULR_PS:
15401                     mips32_op = OPC_MULR_PS;
15402                 do_3d:
15403                     gen_farith(ctx, mips32_op, rt, rs, rd, 0);
15404                     break;
15405                 default:
15406                     goto pool32f_invalid;
15407                 }
15408                 break;
15409             case 0x20:
15410                 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
15411                 cc = (ctx->opcode >> 13) & 0x7;
15412                 fmt = (ctx->opcode >> 9) & 0x3;
15413                 switch ((ctx->opcode >> 6) & 0x7) {
15414                 case MOVF_FMT: /* RINT_FMT */
15415                     if (ctx->insn_flags & ISA_MIPS32R6) {
15416                         /* RINT_FMT */
15417                         switch (fmt) {
15418                         case FMT_SDPS_S:
15419                             gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
15420                             break;
15421                         case FMT_SDPS_D:
15422                             gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
15423                             break;
15424                         default:
15425                             goto pool32f_invalid;
15426                         }
15427                     } else {
15428                         /* MOVF_FMT */
15429                         switch (fmt) {
15430                         case FMT_SDPS_S:
15431                             gen_movcf_s(ctx, rs, rt, cc, 0);
15432                             break;
15433                         case FMT_SDPS_D:
15434                             gen_movcf_d(ctx, rs, rt, cc, 0);
15435                             break;
15436                         case FMT_SDPS_PS:
15437                             check_ps(ctx);
15438                             gen_movcf_ps(ctx, rs, rt, cc, 0);
15439                             break;
15440                         default:
15441                             goto pool32f_invalid;
15442                         }
15443                     }
15444                     break;
15445                 case MOVT_FMT: /* CLASS_FMT */
15446                     if (ctx->insn_flags & ISA_MIPS32R6) {
15447                         /* CLASS_FMT */
15448                         switch (fmt) {
15449                         case FMT_SDPS_S:
15450                             gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
15451                             break;
15452                         case FMT_SDPS_D:
15453                             gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
15454                             break;
15455                         default:
15456                             goto pool32f_invalid;
15457                         }
15458                     } else {
15459                         /* MOVT_FMT */
15460                         switch (fmt) {
15461                         case FMT_SDPS_S:
15462                             gen_movcf_s(ctx, rs, rt, cc, 1);
15463                             break;
15464                         case FMT_SDPS_D:
15465                             gen_movcf_d(ctx, rs, rt, cc, 1);
15466                             break;
15467                         case FMT_SDPS_PS:
15468                             check_ps(ctx);
15469                             gen_movcf_ps(ctx, rs, rt, cc, 1);
15470                             break;
15471                         default:
15472                             goto pool32f_invalid;
15473                         }
15474                     }
15475                     break;
15476                 case PREFX:
15477                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
15478                     break;
15479                 default:
15480                     goto pool32f_invalid;
15481                 }
15482                 break;
15483 #define FINSN_3ARG_SDPS(prfx)                           \
15484                 switch ((ctx->opcode >> 8) & 0x3) {     \
15485                 case FMT_SDPS_S:                        \
15486                     mips32_op = OPC_##prfx##_S;         \
15487                     goto do_fpop;                       \
15488                 case FMT_SDPS_D:                        \
15489                     mips32_op = OPC_##prfx##_D;         \
15490                     goto do_fpop;                       \
15491                 case FMT_SDPS_PS:                       \
15492                     check_ps(ctx);                      \
15493                     mips32_op = OPC_##prfx##_PS;        \
15494                     goto do_fpop;                       \
15495                 default:                                \
15496                     goto pool32f_invalid;               \
15497                 }
15498             case MINA_FMT:
15499                 check_insn(ctx, ISA_MIPS32R6);
15500                 switch ((ctx->opcode >> 9) & 0x3) {
15501                 case FMT_SDPS_S:
15502                     gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
15503                     break;
15504                 case FMT_SDPS_D:
15505                     gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
15506                     break;
15507                 default:
15508                     goto pool32f_invalid;
15509                 }
15510                 break;
15511             case MAXA_FMT:
15512                 check_insn(ctx, ISA_MIPS32R6);
15513                 switch ((ctx->opcode >> 9) & 0x3) {
15514                 case FMT_SDPS_S:
15515                     gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
15516                     break;
15517                 case FMT_SDPS_D:
15518                     gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
15519                     break;
15520                 default:
15521                     goto pool32f_invalid;
15522                 }
15523                 break;
15524             case 0x30:
15525                 /* regular FP ops */
15526                 switch ((ctx->opcode >> 6) & 0x3) {
15527                 case ADD_FMT:
15528                     FINSN_3ARG_SDPS(ADD);
15529                     break;
15530                 case SUB_FMT:
15531                     FINSN_3ARG_SDPS(SUB);
15532                     break;
15533                 case MUL_FMT:
15534                     FINSN_3ARG_SDPS(MUL);
15535                     break;
15536                 case DIV_FMT:
15537                     fmt = (ctx->opcode >> 8) & 0x3;
15538                     if (fmt == 1) {
15539                         mips32_op = OPC_DIV_D;
15540                     } else if (fmt == 0) {
15541                         mips32_op = OPC_DIV_S;
15542                     } else {
15543                         goto pool32f_invalid;
15544                     }
15545                     goto do_fpop;
15546                 default:
15547                     goto pool32f_invalid;
15548                 }
15549                 break;
15550             case 0x38:
15551                 /* cmovs */
15552                 switch ((ctx->opcode >> 6) & 0x7) {
15553                 case MOVN_FMT: /* SELNEZ_FMT */
15554                     if (ctx->insn_flags & ISA_MIPS32R6) {
15555                         /* SELNEZ_FMT */
15556                         switch ((ctx->opcode >> 9) & 0x3) {
15557                         case FMT_SDPS_S:
15558                             gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
15559                             break;
15560                         case FMT_SDPS_D:
15561                             gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
15562                             break;
15563                         default:
15564                             goto pool32f_invalid;
15565                         }
15566                     } else {
15567                         /* MOVN_FMT */
15568                         FINSN_3ARG_SDPS(MOVN);
15569                     }
15570                     break;
15571                 case MOVN_FMT_04:
15572                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
15573                     FINSN_3ARG_SDPS(MOVN);
15574                     break;
15575                 case MOVZ_FMT: /* SELEQZ_FMT */
15576                     if (ctx->insn_flags & ISA_MIPS32R6) {
15577                         /* SELEQZ_FMT */
15578                         switch ((ctx->opcode >> 9) & 0x3) {
15579                         case FMT_SDPS_S:
15580                             gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
15581                             break;
15582                         case FMT_SDPS_D:
15583                             gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
15584                             break;
15585                         default:
15586                             goto pool32f_invalid;
15587                         }
15588                     } else {
15589                         /* MOVZ_FMT */
15590                         FINSN_3ARG_SDPS(MOVZ);
15591                     }
15592                     break;
15593                 case MOVZ_FMT_05:
15594                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
15595                     FINSN_3ARG_SDPS(MOVZ);
15596                     break;
15597                 case SEL_FMT:
15598                     check_insn(ctx, ISA_MIPS32R6);
15599                     switch ((ctx->opcode >> 9) & 0x3) {
15600                     case FMT_SDPS_S:
15601                         gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
15602                         break;
15603                     case FMT_SDPS_D:
15604                         gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
15605                         break;
15606                     default:
15607                         goto pool32f_invalid;
15608                     }
15609                     break;
15610                 case MADDF_FMT:
15611                     check_insn(ctx, ISA_MIPS32R6);
15612                     switch ((ctx->opcode >> 9) & 0x3) {
15613                     case FMT_SDPS_S:
15614                         mips32_op = OPC_MADDF_S;
15615                         goto do_fpop;
15616                     case FMT_SDPS_D:
15617                         mips32_op = OPC_MADDF_D;
15618                         goto do_fpop;
15619                     default:
15620                         goto pool32f_invalid;
15621                     }
15622                     break;
15623                 case MSUBF_FMT:
15624                     check_insn(ctx, ISA_MIPS32R6);
15625                     switch ((ctx->opcode >> 9) & 0x3) {
15626                     case FMT_SDPS_S:
15627                         mips32_op = OPC_MSUBF_S;
15628                         goto do_fpop;
15629                     case FMT_SDPS_D:
15630                         mips32_op = OPC_MSUBF_D;
15631                         goto do_fpop;
15632                     default:
15633                         goto pool32f_invalid;
15634                     }
15635                     break;
15636                 default:
15637                     goto pool32f_invalid;
15638                 }
15639                 break;
15640             do_fpop:
15641                 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
15642                 break;
15643             default:
15644             pool32f_invalid:
15645                 MIPS_INVAL("pool32f");
15646                 generate_exception_end(ctx, EXCP_RI);
15647                 break;
15648             }
15649         } else {
15650             generate_exception_err(ctx, EXCP_CpU, 1);
15651         }
15652         break;
15653     case POOL32I:
15654         minor = (ctx->opcode >> 21) & 0x1f;
15655         switch (minor) {
15656         case BLTZ:
15657             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15658             gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
15659             break;
15660         case BLTZAL:
15661             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15662             gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
15663             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15664             break;
15665         case BLTZALS:
15666             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15667             gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
15668             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15669             break;
15670         case BGEZ:
15671             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15672             gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
15673             break;
15674         case BGEZAL:
15675             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15676             gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
15677             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15678             break;
15679         case BGEZALS:
15680             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15681             gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
15682             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15683             break;
15684         case BLEZ:
15685             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15686             gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
15687             break;
15688         case BGTZ:
15689             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15690             gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
15691             break;
15692
15693             /* Traps */
15694         case TLTI: /* BC1EQZC */
15695             if (ctx->insn_flags & ISA_MIPS32R6) {
15696                 /* BC1EQZC */
15697                 check_cp1_enabled(ctx);
15698                 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
15699             } else {
15700                 /* TLTI */
15701                 mips32_op = OPC_TLTI;
15702                 goto do_trapi;
15703             }
15704             break;
15705         case TGEI: /* BC1NEZC */
15706             if (ctx->insn_flags & ISA_MIPS32R6) {
15707                 /* BC1NEZC */
15708                 check_cp1_enabled(ctx);
15709                 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
15710             } else {
15711                 /* TGEI */
15712                 mips32_op = OPC_TGEI;
15713                 goto do_trapi;
15714             }
15715             break;
15716         case TLTIU:
15717             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15718             mips32_op = OPC_TLTIU;
15719             goto do_trapi;
15720         case TGEIU:
15721             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15722             mips32_op = OPC_TGEIU;
15723             goto do_trapi;
15724         case TNEI: /* SYNCI */
15725             if (ctx->insn_flags & ISA_MIPS32R6) {
15726                 /* SYNCI */
15727                 /* Break the TB to be able to sync copied instructions
15728                    immediately */
15729                 ctx->base.is_jmp = DISAS_STOP;
15730             } else {
15731                 /* TNEI */
15732                 mips32_op = OPC_TNEI;
15733                 goto do_trapi;
15734             }
15735             break;
15736         case TEQI:
15737             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15738             mips32_op = OPC_TEQI;
15739         do_trapi:
15740             gen_trap(ctx, mips32_op, rs, -1, imm);
15741             break;
15742
15743         case BNEZC:
15744         case BEQZC:
15745             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15746             gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
15747                                4, rs, 0, imm << 1, 0);
15748             /* Compact branches don't have a delay slot, so just let
15749                the normal delay slot handling take us to the branch
15750                target. */
15751             break;
15752         case LUI:
15753             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15754             gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
15755             break;
15756         case SYNCI:
15757             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15758             /* Break the TB to be able to sync copied instructions
15759                immediately */
15760             ctx->base.is_jmp = DISAS_STOP;
15761             break;
15762         case BC2F:
15763         case BC2T:
15764             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15765             /* COP2: Not implemented. */
15766             generate_exception_err(ctx, EXCP_CpU, 2);
15767             break;
15768         case BC1F:
15769             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15770             mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
15771             goto do_cp1branch;
15772         case BC1T:
15773             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15774             mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
15775             goto do_cp1branch;
15776         case BC1ANY4F:
15777             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15778             mips32_op = OPC_BC1FANY4;
15779             goto do_cp1mips3d;
15780         case BC1ANY4T:
15781             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15782             mips32_op = OPC_BC1TANY4;
15783         do_cp1mips3d:
15784             check_cop1x(ctx);
15785             check_insn(ctx, ASE_MIPS3D);
15786             /* Fall through */
15787         do_cp1branch:
15788             if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15789                 check_cp1_enabled(ctx);
15790                 gen_compute_branch1(ctx, mips32_op,
15791                                     (ctx->opcode >> 18) & 0x7, imm << 1);
15792             } else {
15793                 generate_exception_err(ctx, EXCP_CpU, 1);
15794             }
15795             break;
15796         case BPOSGE64:
15797         case BPOSGE32:
15798             /* MIPS DSP: not implemented */
15799             /* Fall through */
15800         default:
15801             MIPS_INVAL("pool32i");
15802             generate_exception_end(ctx, EXCP_RI);
15803             break;
15804         }
15805         break;
15806     case POOL32C:
15807         minor = (ctx->opcode >> 12) & 0xf;
15808         offset = sextract32(ctx->opcode, 0,
15809                             (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
15810         switch (minor) {
15811         case LWL:
15812             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15813             mips32_op = OPC_LWL;
15814             goto do_ld_lr;
15815         case SWL:
15816             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15817             mips32_op = OPC_SWL;
15818             goto do_st_lr;
15819         case LWR:
15820             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15821             mips32_op = OPC_LWR;
15822             goto do_ld_lr;
15823         case SWR:
15824             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15825             mips32_op = OPC_SWR;
15826             goto do_st_lr;
15827 #if defined(TARGET_MIPS64)
15828         case LDL:
15829             check_insn(ctx, ISA_MIPS3);
15830             check_mips_64(ctx);
15831             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15832             mips32_op = OPC_LDL;
15833             goto do_ld_lr;
15834         case SDL:
15835             check_insn(ctx, ISA_MIPS3);
15836             check_mips_64(ctx);
15837             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15838             mips32_op = OPC_SDL;
15839             goto do_st_lr;
15840         case LDR:
15841             check_insn(ctx, ISA_MIPS3);
15842             check_mips_64(ctx);
15843             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15844             mips32_op = OPC_LDR;
15845             goto do_ld_lr;
15846         case SDR:
15847             check_insn(ctx, ISA_MIPS3);
15848             check_mips_64(ctx);
15849             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15850             mips32_op = OPC_SDR;
15851             goto do_st_lr;
15852         case LWU:
15853             check_insn(ctx, ISA_MIPS3);
15854             check_mips_64(ctx);
15855             mips32_op = OPC_LWU;
15856             goto do_ld_lr;
15857         case LLD:
15858             check_insn(ctx, ISA_MIPS3);
15859             check_mips_64(ctx);
15860             mips32_op = OPC_LLD;
15861             goto do_ld_lr;
15862 #endif
15863         case LL:
15864             mips32_op = OPC_LL;
15865             goto do_ld_lr;
15866         do_ld_lr:
15867             gen_ld(ctx, mips32_op, rt, rs, offset);
15868             break;
15869         do_st_lr:
15870             gen_st(ctx, mips32_op, rt, rs, offset);
15871             break;
15872         case SC:
15873             gen_st_cond(ctx, OPC_SC, rt, rs, offset);
15874             break;
15875 #if defined(TARGET_MIPS64)
15876         case SCD:
15877             check_insn(ctx, ISA_MIPS3);
15878             check_mips_64(ctx);
15879             gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
15880             break;
15881 #endif
15882         case LD_EVA:
15883             if (!ctx->eva) {
15884                 MIPS_INVAL("pool32c ld-eva");
15885                 generate_exception_end(ctx, EXCP_RI);
15886                 break;
15887             }
15888             check_cp0_enabled(ctx);
15889
15890             minor2 = (ctx->opcode >> 9) & 0x7;
15891             offset = sextract32(ctx->opcode, 0, 9);
15892             switch (minor2) {
15893             case LBUE:
15894                 mips32_op = OPC_LBUE;
15895                 goto do_ld_lr;
15896             case LHUE:
15897                 mips32_op = OPC_LHUE;
15898                 goto do_ld_lr;
15899             case LWLE:
15900                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15901                 mips32_op = OPC_LWLE;
15902                 goto do_ld_lr;
15903             case LWRE:
15904                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15905                 mips32_op = OPC_LWRE;
15906                 goto do_ld_lr;
15907             case LBE:
15908                 mips32_op = OPC_LBE;
15909                 goto do_ld_lr;
15910             case LHE:
15911                 mips32_op = OPC_LHE;
15912                 goto do_ld_lr;
15913             case LLE:
15914                 mips32_op = OPC_LLE;
15915                 goto do_ld_lr;
15916             case LWE:
15917                 mips32_op = OPC_LWE;
15918                 goto do_ld_lr;
15919             };
15920             break;
15921         case ST_EVA:
15922             if (!ctx->eva) {
15923                 MIPS_INVAL("pool32c st-eva");
15924                 generate_exception_end(ctx, EXCP_RI);
15925                 break;
15926             }
15927             check_cp0_enabled(ctx);
15928
15929             minor2 = (ctx->opcode >> 9) & 0x7;
15930             offset = sextract32(ctx->opcode, 0, 9);
15931             switch (minor2) {
15932             case SWLE:
15933                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15934                 mips32_op = OPC_SWLE;
15935                 goto do_st_lr;
15936             case SWRE:
15937                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15938                 mips32_op = OPC_SWRE;
15939                 goto do_st_lr;
15940             case PREFE:
15941                 /* Treat as no-op */
15942                 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
15943                     /* hint codes 24-31 are reserved and signal RI */
15944                     generate_exception(ctx, EXCP_RI);
15945                 }
15946                 break;
15947             case CACHEE:
15948                 /* Treat as no-op */
15949                 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15950                     gen_cache_operation(ctx, rt, rs, offset);
15951                 }
15952                 break;
15953             case SBE:
15954                 mips32_op = OPC_SBE;
15955                 goto do_st_lr;
15956             case SHE:
15957                 mips32_op = OPC_SHE;
15958                 goto do_st_lr;
15959             case SCE:
15960                 gen_st_cond(ctx, OPC_SCE, rt, rs, offset);
15961                 break;
15962             case SWE:
15963                 mips32_op = OPC_SWE;
15964                 goto do_st_lr;
15965             };
15966             break;
15967         case PREF:
15968             /* Treat as no-op */
15969             if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
15970                 /* hint codes 24-31 are reserved and signal RI */
15971                 generate_exception(ctx, EXCP_RI);
15972             }
15973             break;
15974         default:
15975             MIPS_INVAL("pool32c");
15976             generate_exception_end(ctx, EXCP_RI);
15977             break;
15978         }
15979         break;
15980     case ADDI32: /* AUI, LUI */
15981         if (ctx->insn_flags & ISA_MIPS32R6) {
15982             /* AUI, LUI */
15983             gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
15984         } else {
15985             /* ADDI32 */
15986             mips32_op = OPC_ADDI;
15987             goto do_addi;
15988         }
15989         break;
15990     case ADDIU32:
15991         mips32_op = OPC_ADDIU;
15992     do_addi:
15993         gen_arith_imm(ctx, mips32_op, rt, rs, imm);
15994         break;
15995
15996         /* Logical operations */
15997     case ORI32:
15998         mips32_op = OPC_ORI;
15999         goto do_logici;
16000     case XORI32:
16001         mips32_op = OPC_XORI;
16002         goto do_logici;
16003     case ANDI32:
16004         mips32_op = OPC_ANDI;
16005     do_logici:
16006         gen_logic_imm(ctx, mips32_op, rt, rs, imm);
16007         break;
16008
16009         /* Set less than immediate */
16010     case SLTI32:
16011         mips32_op = OPC_SLTI;
16012         goto do_slti;
16013     case SLTIU32:
16014         mips32_op = OPC_SLTIU;
16015     do_slti:
16016         gen_slt_imm(ctx, mips32_op, rt, rs, imm);
16017         break;
16018     case JALX32:
16019         check_insn_opc_removed(ctx, ISA_MIPS32R6);
16020         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
16021         gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
16022         ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16023         break;
16024     case JALS32: /* BOVC, BEQC, BEQZALC */
16025         if (ctx->insn_flags & ISA_MIPS32R6) {
16026             if (rs >= rt) {
16027                 /* BOVC */
16028                 mips32_op = OPC_BOVC;
16029             } else if (rs < rt && rs == 0) {
16030                 /* BEQZALC */
16031                 mips32_op = OPC_BEQZALC;
16032             } else {
16033                 /* BEQC */
16034                 mips32_op = OPC_BEQC;
16035             }
16036             gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16037         } else {
16038             /* JALS32 */
16039             offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
16040             gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
16041             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16042         }
16043         break;
16044     case BEQ32: /* BC */
16045         if (ctx->insn_flags & ISA_MIPS32R6) {
16046             /* BC */
16047             gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
16048                                        sextract32(ctx->opcode << 1, 0, 27));
16049         } else {
16050             /* BEQ32 */
16051             gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
16052         }
16053         break;
16054     case BNE32: /* BALC */
16055         if (ctx->insn_flags & ISA_MIPS32R6) {
16056             /* BALC */
16057             gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
16058                                        sextract32(ctx->opcode << 1, 0, 27));
16059         } else {
16060             /* BNE32 */
16061             gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
16062         }
16063         break;
16064     case J32: /* BGTZC, BLTZC, BLTC */
16065         if (ctx->insn_flags & ISA_MIPS32R6) {
16066             if (rs == 0 && rt != 0) {
16067                 /* BGTZC */
16068                 mips32_op = OPC_BGTZC;
16069             } else if (rs != 0 && rt != 0 && rs == rt) {
16070                 /* BLTZC */
16071                 mips32_op = OPC_BLTZC;
16072             } else {
16073                 /* BLTC */
16074                 mips32_op = OPC_BLTC;
16075             }
16076             gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16077         } else {
16078             /* J32 */
16079             gen_compute_branch(ctx, OPC_J, 4, rt, rs,
16080                                (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
16081         }
16082         break;
16083     case JAL32: /* BLEZC, BGEZC, BGEC */
16084         if (ctx->insn_flags & ISA_MIPS32R6) {
16085             if (rs == 0 && rt != 0) {
16086                 /* BLEZC */
16087                 mips32_op = OPC_BLEZC;
16088             } else if (rs != 0 && rt != 0 && rs == rt) {
16089                 /* BGEZC */
16090                 mips32_op = OPC_BGEZC;
16091             } else {
16092                 /* BGEC */
16093                 mips32_op = OPC_BGEC;
16094             }
16095             gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16096         } else {
16097             /* JAL32 */
16098             gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
16099                                (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
16100             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16101         }
16102         break;
16103         /* Floating point (COP1) */
16104     case LWC132:
16105         mips32_op = OPC_LWC1;
16106         goto do_cop1;
16107     case LDC132:
16108         mips32_op = OPC_LDC1;
16109         goto do_cop1;
16110     case SWC132:
16111         mips32_op = OPC_SWC1;
16112         goto do_cop1;
16113     case SDC132:
16114         mips32_op = OPC_SDC1;
16115     do_cop1:
16116         gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
16117         break;
16118     case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16119         if (ctx->insn_flags & ISA_MIPS32R6) {
16120             /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16121             switch ((ctx->opcode >> 16) & 0x1f) {
16122             case ADDIUPC_00:
16123             case ADDIUPC_01:
16124             case ADDIUPC_02:
16125             case ADDIUPC_03:
16126             case ADDIUPC_04:
16127             case ADDIUPC_05:
16128             case ADDIUPC_06:
16129             case ADDIUPC_07:
16130                 gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
16131                 break;
16132             case AUIPC:
16133                 gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
16134                 break;
16135             case ALUIPC:
16136                 gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
16137                 break;
16138             case LWPC_08:
16139             case LWPC_09:
16140             case LWPC_0A:
16141             case LWPC_0B:
16142             case LWPC_0C:
16143             case LWPC_0D:
16144             case LWPC_0E:
16145             case LWPC_0F:
16146                 gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
16147                 break;
16148             default:
16149                 generate_exception(ctx, EXCP_RI);
16150                 break;
16151             }
16152         } else {
16153             /* ADDIUPC */
16154             int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
16155             offset = SIMM(ctx->opcode, 0, 23) << 2;
16156
16157             gen_addiupc(ctx, reg, offset, 0, 0);
16158         }
16159         break;
16160     case BNVC: /* BNEC, BNEZALC */
16161         check_insn(ctx, ISA_MIPS32R6);
16162         if (rs >= rt) {
16163             /* BNVC */
16164             mips32_op = OPC_BNVC;
16165         } else if (rs < rt && rs == 0) {
16166             /* BNEZALC */
16167             mips32_op = OPC_BNEZALC;
16168         } else {
16169             /* BNEC */
16170             mips32_op = OPC_BNEC;
16171         }
16172         gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16173         break;
16174     case R6_BNEZC: /* JIALC */
16175         check_insn(ctx, ISA_MIPS32R6);
16176         if (rt != 0) {
16177             /* BNEZC */
16178             gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
16179                                        sextract32(ctx->opcode << 1, 0, 22));
16180         } else {
16181             /* JIALC */
16182             gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
16183         }
16184         break;
16185     case R6_BEQZC: /* JIC */
16186         check_insn(ctx, ISA_MIPS32R6);
16187         if (rt != 0) {
16188             /* BEQZC */
16189             gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
16190                                        sextract32(ctx->opcode << 1, 0, 22));
16191         } else {
16192             /* JIC */
16193             gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
16194         }
16195         break;
16196     case BLEZALC: /* BGEZALC, BGEUC */
16197         check_insn(ctx, ISA_MIPS32R6);
16198         if (rs == 0 && rt != 0) {
16199             /* BLEZALC */
16200             mips32_op = OPC_BLEZALC;
16201         } else if (rs != 0 && rt != 0 && rs == rt) {
16202             /* BGEZALC */
16203             mips32_op = OPC_BGEZALC;
16204         } else {
16205             /* BGEUC */
16206             mips32_op = OPC_BGEUC;
16207         }
16208         gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16209         break;
16210     case BGTZALC: /* BLTZALC, BLTUC */
16211         check_insn(ctx, ISA_MIPS32R6);
16212         if (rs == 0 && rt != 0) {
16213             /* BGTZALC */
16214             mips32_op = OPC_BGTZALC;
16215         } else if (rs != 0 && rt != 0 && rs == rt) {
16216             /* BLTZALC */
16217             mips32_op = OPC_BLTZALC;
16218         } else {
16219             /* BLTUC */
16220             mips32_op = OPC_BLTUC;
16221         }
16222         gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16223         break;
16224         /* Loads and stores */
16225     case LB32:
16226         mips32_op = OPC_LB;
16227         goto do_ld;
16228     case LBU32:
16229         mips32_op = OPC_LBU;
16230         goto do_ld;
16231     case LH32:
16232         mips32_op = OPC_LH;
16233         goto do_ld;
16234     case LHU32:
16235         mips32_op = OPC_LHU;
16236         goto do_ld;
16237     case LW32:
16238         mips32_op = OPC_LW;
16239         goto do_ld;
16240 #ifdef TARGET_MIPS64
16241     case LD32:
16242         check_insn(ctx, ISA_MIPS3);
16243         check_mips_64(ctx);
16244         mips32_op = OPC_LD;
16245         goto do_ld;
16246     case SD32:
16247         check_insn(ctx, ISA_MIPS3);
16248         check_mips_64(ctx);
16249         mips32_op = OPC_SD;
16250         goto do_st;
16251 #endif
16252     case SB32:
16253         mips32_op = OPC_SB;
16254         goto do_st;
16255     case SH32:
16256         mips32_op = OPC_SH;
16257         goto do_st;
16258     case SW32:
16259         mips32_op = OPC_SW;
16260         goto do_st;
16261     do_ld:
16262         gen_ld(ctx, mips32_op, rt, rs, imm);
16263         break;
16264     do_st:
16265         gen_st(ctx, mips32_op, rt, rs, imm);
16266         break;
16267     default:
16268         generate_exception_end(ctx, EXCP_RI);
16269         break;
16270     }
16271 }
16272
16273 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
16274 {
16275     uint32_t op;
16276
16277     /* make sure instructions are on a halfword boundary */
16278     if (ctx->base.pc_next & 0x1) {
16279         env->CP0_BadVAddr = ctx->base.pc_next;
16280         generate_exception_end(ctx, EXCP_AdEL);
16281         return 2;
16282     }
16283
16284     op = (ctx->opcode >> 10) & 0x3f;
16285     /* Enforce properly-sized instructions in a delay slot */
16286     if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
16287         switch (op & 0x7) { /* MSB-3..MSB-5 */
16288         case 0:
16289         /* POOL32A, POOL32B, POOL32I, POOL32C */
16290         case 4:
16291         /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
16292         case 5:
16293         /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
16294         case 6:
16295         /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
16296         case 7:
16297         /* LB32, LH32, LWC132, LDC132, LW32 */
16298             if (ctx->hflags & MIPS_HFLAG_BDS16) {
16299                 generate_exception_end(ctx, EXCP_RI);
16300                 return 2;
16301             }
16302             break;
16303         case 1:
16304         /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
16305         case 2:
16306         /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
16307         case 3:
16308         /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
16309             if (ctx->hflags & MIPS_HFLAG_BDS32) {
16310                 generate_exception_end(ctx, EXCP_RI);
16311                 return 2;
16312             }
16313             break;
16314         }
16315     }
16316
16317     switch (op) {
16318     case POOL16A:
16319         {
16320             int rd = mmreg(uMIPS_RD(ctx->opcode));
16321             int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
16322             int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
16323             uint32_t opc = 0;
16324
16325             switch (ctx->opcode & 0x1) {
16326             case ADDU16:
16327                 opc = OPC_ADDU;
16328                 break;
16329             case SUBU16:
16330                 opc = OPC_SUBU;
16331                 break;
16332             }
16333             if (ctx->insn_flags & ISA_MIPS32R6) {
16334                 /* In the Release 6 the register number location in
16335                  * the instruction encoding has changed.
16336                  */
16337                 gen_arith(ctx, opc, rs1, rd, rs2);
16338             } else {
16339                 gen_arith(ctx, opc, rd, rs1, rs2);
16340             }
16341         }
16342         break;
16343     case POOL16B:
16344         {
16345             int rd = mmreg(uMIPS_RD(ctx->opcode));
16346             int rs = mmreg(uMIPS_RS(ctx->opcode));
16347             int amount = (ctx->opcode >> 1) & 0x7;
16348             uint32_t opc = 0;
16349             amount = amount == 0 ? 8 : amount;
16350
16351             switch (ctx->opcode & 0x1) {
16352             case SLL16:
16353                 opc = OPC_SLL;
16354                 break;
16355             case SRL16:
16356                 opc = OPC_SRL;
16357                 break;
16358             }
16359
16360             gen_shift_imm(ctx, opc, rd, rs, amount);
16361         }
16362         break;
16363     case POOL16C:
16364         if (ctx->insn_flags & ISA_MIPS32R6) {
16365             gen_pool16c_r6_insn(ctx);
16366         } else {
16367             gen_pool16c_insn(ctx);
16368         }
16369         break;
16370     case LWGP16:
16371         {
16372             int rd = mmreg(uMIPS_RD(ctx->opcode));
16373             int rb = 28;            /* GP */
16374             int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
16375
16376             gen_ld(ctx, OPC_LW, rd, rb, offset);
16377         }
16378         break;
16379     case POOL16F:
16380         check_insn_opc_removed(ctx, ISA_MIPS32R6);
16381         if (ctx->opcode & 1) {
16382             generate_exception_end(ctx, EXCP_RI);
16383         } else {
16384             /* MOVEP */
16385             int enc_dest = uMIPS_RD(ctx->opcode);
16386             int enc_rt = uMIPS_RS2(ctx->opcode);
16387             int enc_rs = uMIPS_RS1(ctx->opcode);
16388             gen_movep(ctx, enc_dest, enc_rt, enc_rs);
16389         }
16390         break;
16391     case LBU16:
16392         {
16393             int rd = mmreg(uMIPS_RD(ctx->opcode));
16394             int rb = mmreg(uMIPS_RS(ctx->opcode));
16395             int16_t offset = ZIMM(ctx->opcode, 0, 4);
16396             offset = (offset == 0xf ? -1 : offset);
16397
16398             gen_ld(ctx, OPC_LBU, rd, rb, offset);
16399         }
16400         break;
16401     case LHU16:
16402         {
16403             int rd = mmreg(uMIPS_RD(ctx->opcode));
16404             int rb = mmreg(uMIPS_RS(ctx->opcode));
16405             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
16406
16407             gen_ld(ctx, OPC_LHU, rd, rb, offset);
16408         }
16409         break;
16410     case LWSP16:
16411         {
16412             int rd = (ctx->opcode >> 5) & 0x1f;
16413             int rb = 29;            /* SP */
16414             int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
16415
16416             gen_ld(ctx, OPC_LW, rd, rb, offset);
16417         }
16418         break;
16419     case LW16:
16420         {
16421             int rd = mmreg(uMIPS_RD(ctx->opcode));
16422             int rb = mmreg(uMIPS_RS(ctx->opcode));
16423             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
16424
16425             gen_ld(ctx, OPC_LW, rd, rb, offset);
16426         }
16427         break;
16428     case SB16:
16429         {
16430             int rd = mmreg2(uMIPS_RD(ctx->opcode));
16431             int rb = mmreg(uMIPS_RS(ctx->opcode));
16432             int16_t offset = ZIMM(ctx->opcode, 0, 4);
16433
16434             gen_st(ctx, OPC_SB, rd, rb, offset);
16435         }
16436         break;
16437     case SH16:
16438         {
16439             int rd = mmreg2(uMIPS_RD(ctx->opcode));
16440             int rb = mmreg(uMIPS_RS(ctx->opcode));
16441             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
16442
16443             gen_st(ctx, OPC_SH, rd, rb, offset);
16444         }
16445         break;
16446     case SWSP16:
16447         {
16448             int rd = (ctx->opcode >> 5) & 0x1f;
16449             int rb = 29;            /* SP */
16450             int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
16451
16452             gen_st(ctx, OPC_SW, rd, rb, offset);
16453         }
16454         break;
16455     case SW16:
16456         {
16457             int rd = mmreg2(uMIPS_RD(ctx->opcode));
16458             int rb = mmreg(uMIPS_RS(ctx->opcode));
16459             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
16460
16461             gen_st(ctx, OPC_SW, rd, rb, offset);
16462         }
16463         break;
16464     case MOVE16:
16465         {
16466             int rd = uMIPS_RD5(ctx->opcode);
16467             int rs = uMIPS_RS5(ctx->opcode);
16468
16469             gen_arith(ctx, OPC_ADDU, rd, rs, 0);
16470         }
16471         break;
16472     case ANDI16:
16473         gen_andi16(ctx);
16474         break;
16475     case POOL16D:
16476         switch (ctx->opcode & 0x1) {
16477         case ADDIUS5:
16478             gen_addius5(ctx);
16479             break;
16480         case ADDIUSP:
16481             gen_addiusp(ctx);
16482             break;
16483         }
16484         break;
16485     case POOL16E:
16486         switch (ctx->opcode & 0x1) {
16487         case ADDIUR2:
16488             gen_addiur2(ctx);
16489             break;
16490         case ADDIUR1SP:
16491             gen_addiur1sp(ctx);
16492             break;
16493         }
16494         break;
16495     case B16: /* BC16 */
16496         gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
16497                            sextract32(ctx->opcode, 0, 10) << 1,
16498                            (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
16499         break;
16500     case BNEZ16: /* BNEZC16 */
16501     case BEQZ16: /* BEQZC16 */
16502         gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
16503                            mmreg(uMIPS_RD(ctx->opcode)),
16504                            0, sextract32(ctx->opcode, 0, 7) << 1,
16505                            (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
16506
16507         break;
16508     case LI16:
16509         {
16510             int reg = mmreg(uMIPS_RD(ctx->opcode));
16511             int imm = ZIMM(ctx->opcode, 0, 7);
16512
16513             imm = (imm == 0x7f ? -1 : imm);
16514             tcg_gen_movi_tl(cpu_gpr[reg], imm);
16515         }
16516         break;
16517     case RES_29:
16518     case RES_31:
16519     case RES_39:
16520         generate_exception_end(ctx, EXCP_RI);
16521         break;
16522     default:
16523         decode_micromips32_opc(env, ctx);
16524         return 4;
16525     }
16526
16527     return 2;
16528 }
16529
16530 /*
16531  *
16532  * nanoMIPS opcodes
16533  *
16534  */
16535
16536 /* MAJOR, P16, and P32 pools opcodes */
16537 enum {
16538     NM_P_ADDIU      = 0x00,
16539     NM_ADDIUPC      = 0x01,
16540     NM_MOVE_BALC    = 0x02,
16541     NM_P16_MV       = 0x04,
16542     NM_LW16         = 0x05,
16543     NM_BC16         = 0x06,
16544     NM_P16_SR       = 0x07,
16545
16546     NM_POOL32A      = 0x08,
16547     NM_P_BAL        = 0x0a,
16548     NM_P16_SHIFT    = 0x0c,
16549     NM_LWSP16       = 0x0d,
16550     NM_BALC16       = 0x0e,
16551     NM_P16_4X4      = 0x0f,
16552
16553     NM_P_GP_W       = 0x10,
16554     NM_P_GP_BH      = 0x11,
16555     NM_P_J          = 0x12,
16556     NM_P16C         = 0x14,
16557     NM_LWGP16       = 0x15,
16558     NM_P16_LB       = 0x17,
16559
16560     NM_P48I         = 0x18,
16561     NM_P16_A1       = 0x1c,
16562     NM_LW4X4        = 0x1d,
16563     NM_P16_LH       = 0x1f,
16564
16565     NM_P_U12        = 0x20,
16566     NM_P_LS_U12     = 0x21,
16567     NM_P_BR1        = 0x22,
16568     NM_P16_A2       = 0x24,
16569     NM_SW16         = 0x25,
16570     NM_BEQZC16      = 0x26,
16571
16572     NM_POOL32F      = 0x28,
16573     NM_P_LS_S9      = 0x29,
16574     NM_P_BR2        = 0x2a,
16575
16576     NM_P16_ADDU     = 0x2c,
16577     NM_SWSP16       = 0x2d,
16578     NM_BNEZC16      = 0x2e,
16579     NM_MOVEP        = 0x2f,
16580
16581     NM_POOL32S      = 0x30,
16582     NM_P_BRI        = 0x32,
16583     NM_LI16         = 0x34,
16584     NM_SWGP16       = 0x35,
16585     NM_P16_BR       = 0x36,
16586
16587     NM_P_LUI        = 0x38,
16588     NM_ANDI16       = 0x3c,
16589     NM_SW4X4        = 0x3d,
16590     NM_MOVEPREV     = 0x3f,
16591 };
16592
16593 /* POOL32A instruction pool */
16594 enum {
16595     NM_POOL32A0    = 0x00,
16596     NM_SPECIAL2    = 0x01,
16597     NM_COP2_1      = 0x02,
16598     NM_UDI         = 0x03,
16599     NM_POOL32A5    = 0x05,
16600     NM_POOL32A7    = 0x07,
16601 };
16602
16603 /* P.GP.W instruction pool */
16604 enum {
16605     NM_ADDIUGP_W = 0x00,
16606     NM_LWGP      = 0x02,
16607     NM_SWGP      = 0x03,
16608 };
16609
16610 /* P48I instruction pool */
16611 enum {
16612     NM_LI48        = 0x00,
16613     NM_ADDIU48     = 0x01,
16614     NM_ADDIUGP48   = 0x02,
16615     NM_ADDIUPC48   = 0x03,
16616     NM_LWPC48      = 0x0b,
16617     NM_SWPC48      = 0x0f,
16618 };
16619
16620 /* P.U12 instruction pool */
16621 enum {
16622     NM_ORI      = 0x00,
16623     NM_XORI     = 0x01,
16624     NM_ANDI     = 0x02,
16625     NM_P_SR     = 0x03,
16626     NM_SLTI     = 0x04,
16627     NM_SLTIU    = 0x05,
16628     NM_SEQI     = 0x06,
16629     NM_ADDIUNEG = 0x08,
16630     NM_P_SHIFT  = 0x0c,
16631     NM_P_ROTX   = 0x0d,
16632     NM_P_INS    = 0x0e,
16633     NM_P_EXT    = 0x0f,
16634 };
16635
16636 /* POOL32F instruction pool */
16637 enum {
16638     NM_POOL32F_0   = 0x00,
16639     NM_POOL32F_3   = 0x03,
16640     NM_POOL32F_5   = 0x05,
16641 };
16642
16643 /* POOL32S instruction pool */
16644 enum {
16645     NM_POOL32S_0   = 0x00,
16646     NM_POOL32S_4   = 0x04,
16647 };
16648
16649 /* P.LUI instruction pool */
16650 enum {
16651     NM_LUI      = 0x00,
16652     NM_ALUIPC   = 0x01,
16653 };
16654
16655 /* P.GP.BH instruction pool */
16656 enum {
16657     NM_LBGP      = 0x00,
16658     NM_SBGP      = 0x01,
16659     NM_LBUGP     = 0x02,
16660     NM_ADDIUGP_B = 0x03,
16661     NM_P_GP_LH   = 0x04,
16662     NM_P_GP_SH   = 0x05,
16663     NM_P_GP_CP1  = 0x06,
16664 };
16665
16666 /* P.LS.U12 instruction pool */
16667 enum {
16668     NM_LB        = 0x00,
16669     NM_SB        = 0x01,
16670     NM_LBU       = 0x02,
16671     NM_P_PREFU12 = 0x03,
16672     NM_LH        = 0x04,
16673     NM_SH        = 0x05,
16674     NM_LHU       = 0x06,
16675     NM_LWU       = 0x07,
16676     NM_LW        = 0x08,
16677     NM_SW        = 0x09,
16678     NM_LWC1      = 0x0a,
16679     NM_SWC1      = 0x0b,
16680     NM_LDC1      = 0x0e,
16681     NM_SDC1      = 0x0f,
16682 };
16683
16684 /* P.LS.S9 instruction pool */
16685 enum {
16686     NM_P_LS_S0         = 0x00,
16687     NM_P_LS_S1         = 0x01,
16688     NM_P_LS_E0         = 0x02,
16689     NM_P_LS_WM         = 0x04,
16690     NM_P_LS_UAWM       = 0x05,
16691 };
16692
16693 /* P.BAL instruction pool */
16694 enum {
16695     NM_BC       = 0x00,
16696     NM_BALC     = 0x01,
16697 };
16698
16699 /* P.J instruction pool */
16700 enum {
16701     NM_JALRC    = 0x00,
16702     NM_JALRC_HB = 0x01,
16703     NM_P_BALRSC = 0x08,
16704 };
16705
16706 /* P.BR1 instruction pool */
16707 enum {
16708     NM_BEQC     = 0x00,
16709     NM_P_BR3A   = 0x01,
16710     NM_BGEC     = 0x02,
16711     NM_BGEUC    = 0x03,
16712 };
16713
16714 /* P.BR2 instruction pool */
16715 enum {
16716     NM_BNEC     = 0x00,
16717     NM_BLTC     = 0x02,
16718     NM_BLTUC    = 0x03,
16719 };
16720
16721 /* P.BRI instruction pool */
16722 enum {
16723     NM_BEQIC    = 0x00,
16724     NM_BBEQZC   = 0x01,
16725     NM_BGEIC    = 0x02,
16726     NM_BGEIUC   = 0x03,
16727     NM_BNEIC    = 0x04,
16728     NM_BBNEZC   = 0x05,
16729     NM_BLTIC    = 0x06,
16730     NM_BLTIUC   = 0x07,
16731 };
16732
16733 /* P16.SHIFT instruction pool */
16734 enum {
16735     NM_SLL16    = 0x00,
16736     NM_SRL16    = 0x01,
16737 };
16738
16739 /* POOL16C instruction pool */
16740 enum {
16741     NM_POOL16C_0  = 0x00,
16742     NM_LWXS16     = 0x01,
16743 };
16744
16745 /* P16.A1 instruction pool */
16746 enum {
16747     NM_ADDIUR1SP = 0x01,
16748 };
16749
16750 /* P16.A2 instruction pool */
16751 enum {
16752     NM_ADDIUR2  = 0x00,
16753     NM_P_ADDIURS5  = 0x01,
16754 };
16755
16756 /* P16.ADDU instruction pool */
16757 enum {
16758     NM_ADDU16     = 0x00,
16759     NM_SUBU16     = 0x01,
16760 };
16761
16762 /* P16.SR instruction pool */
16763 enum {
16764     NM_SAVE16        = 0x00,
16765     NM_RESTORE_JRC16 = 0x01,
16766 };
16767
16768 /* P16.4X4 instruction pool */
16769 enum {
16770     NM_ADDU4X4      = 0x00,
16771     NM_MUL4X4       = 0x01,
16772 };
16773
16774 /* P16.LB instruction pool */
16775 enum {
16776     NM_LB16       = 0x00,
16777     NM_SB16       = 0x01,
16778     NM_LBU16      = 0x02,
16779 };
16780
16781 /* P16.LH  instruction pool */
16782 enum {
16783     NM_LH16     = 0x00,
16784     NM_SH16     = 0x01,
16785     NM_LHU16    = 0x02,
16786 };
16787
16788 /* P.RI instruction pool */
16789 enum {
16790     NM_SIGRIE       = 0x00,
16791     NM_P_SYSCALL    = 0x01,
16792     NM_BREAK        = 0x02,
16793     NM_SDBBP        = 0x03,
16794 };
16795
16796 /* POOL32A0 instruction pool */
16797 enum {
16798     NM_P_TRAP   = 0x00,
16799     NM_SEB      = 0x01,
16800     NM_SLLV     = 0x02,
16801     NM_MUL      = 0x03,
16802     NM_MFC0     = 0x06,
16803     NM_MFHC0    = 0x07,
16804     NM_SEH      = 0x09,
16805     NM_SRLV     = 0x0a,
16806     NM_MUH      = 0x0b,
16807     NM_MTC0     = 0x0e,
16808     NM_MTHC0    = 0x0f,
16809     NM_SRAV     = 0x12,
16810     NM_MULU     = 0x13,
16811     NM_ROTRV    = 0x1a,
16812     NM_MUHU     = 0x1b,
16813     NM_ADD      = 0x22,
16814     NM_DIV      = 0x23,
16815     NM_ADDU     = 0x2a,
16816     NM_MOD      = 0x2b,
16817     NM_SUB      = 0x32,
16818     NM_DIVU     = 0x33,
16819     NM_RDHWR    = 0x38,
16820     NM_SUBU     = 0x3a,
16821     NM_MODU     = 0x3b,
16822     NM_P_CMOVE  = 0x42,
16823     NM_FORK     = 0x45,
16824     NM_MFTR     = 0x46,
16825     NM_MFHTR    = 0x47,
16826     NM_AND      = 0x4a,
16827     NM_YIELD    = 0x4d,
16828     NM_MTTR     = 0x4e,
16829     NM_MTHTR    = 0x4f,
16830     NM_OR       = 0x52,
16831     NM_D_E_MT_VPE = 0x56,
16832     NM_NOR      = 0x5a,
16833     NM_XOR      = 0x62,
16834     NM_SLT      = 0x6a,
16835     NM_P_SLTU   = 0x72,
16836     NM_SOV      = 0x7a,
16837 };
16838
16839 /* POOL32A5 instruction pool */
16840 enum {
16841     NM_CMP_EQ_PH        = 0x00,
16842     NM_CMP_LT_PH        = 0x08,
16843     NM_CMP_LE_PH        = 0x10,
16844     NM_CMPGU_EQ_QB      = 0x18,
16845     NM_CMPGU_LT_QB      = 0x20,
16846     NM_CMPGU_LE_QB      = 0x28,
16847     NM_CMPGDU_EQ_QB     = 0x30,
16848     NM_CMPGDU_LT_QB     = 0x38,
16849     NM_CMPGDU_LE_QB     = 0x40,
16850     NM_CMPU_EQ_QB       = 0x48,
16851     NM_CMPU_LT_QB       = 0x50,
16852     NM_CMPU_LE_QB       = 0x58,
16853     NM_ADDQ_S_W         = 0x60,
16854     NM_SUBQ_S_W         = 0x68,
16855     NM_ADDSC            = 0x70,
16856     NM_ADDWC            = 0x78,
16857
16858     NM_ADDQ_S_PH   = 0x01,
16859     NM_ADDQH_R_PH  = 0x09,
16860     NM_ADDQH_R_W   = 0x11,
16861     NM_ADDU_S_QB   = 0x19,
16862     NM_ADDU_S_PH   = 0x21,
16863     NM_ADDUH_R_QB  = 0x29,
16864     NM_SHRAV_R_PH  = 0x31,
16865     NM_SHRAV_R_QB  = 0x39,
16866     NM_SUBQ_S_PH   = 0x41,
16867     NM_SUBQH_R_PH  = 0x49,
16868     NM_SUBQH_R_W   = 0x51,
16869     NM_SUBU_S_QB   = 0x59,
16870     NM_SUBU_S_PH   = 0x61,
16871     NM_SUBUH_R_QB  = 0x69,
16872     NM_SHLLV_S_PH  = 0x71,
16873     NM_PRECR_SRA_R_PH_W = 0x79,
16874
16875     NM_MULEU_S_PH_QBL   = 0x12,
16876     NM_MULEU_S_PH_QBR   = 0x1a,
16877     NM_MULQ_RS_PH       = 0x22,
16878     NM_MULQ_S_PH        = 0x2a,
16879     NM_MULQ_RS_W        = 0x32,
16880     NM_MULQ_S_W         = 0x3a,
16881     NM_APPEND           = 0x42,
16882     NM_MODSUB           = 0x52,
16883     NM_SHRAV_R_W        = 0x5a,
16884     NM_SHRLV_PH         = 0x62,
16885     NM_SHRLV_QB         = 0x6a,
16886     NM_SHLLV_QB         = 0x72,
16887     NM_SHLLV_S_W        = 0x7a,
16888
16889     NM_SHILO            = 0x03,
16890
16891     NM_MULEQ_S_W_PHL    = 0x04,
16892     NM_MULEQ_S_W_PHR    = 0x0c,
16893
16894     NM_MUL_S_PH         = 0x05,
16895     NM_PRECR_QB_PH      = 0x0d,
16896     NM_PRECRQ_QB_PH     = 0x15,
16897     NM_PRECRQ_PH_W      = 0x1d,
16898     NM_PRECRQ_RS_PH_W   = 0x25,
16899     NM_PRECRQU_S_QB_PH  = 0x2d,
16900     NM_PACKRL_PH        = 0x35,
16901     NM_PICK_QB          = 0x3d,
16902     NM_PICK_PH          = 0x45,
16903
16904     NM_SHRA_R_W         = 0x5e,
16905     NM_SHRA_R_PH        = 0x66,
16906     NM_SHLL_S_PH        = 0x76,
16907     NM_SHLL_S_W         = 0x7e,
16908
16909     NM_REPL_PH          = 0x07
16910 };
16911
16912 /* POOL32A7 instruction pool */
16913 enum {
16914     NM_P_LSX        = 0x00,
16915     NM_LSA          = 0x01,
16916     NM_EXTW         = 0x03,
16917     NM_POOL32AXF    = 0x07,
16918 };
16919
16920 /* P.SR instruction pool */
16921 enum {
16922     NM_PP_SR           = 0x00,
16923     NM_P_SR_F          = 0x01,
16924 };
16925
16926 /* P.SHIFT instruction pool */
16927 enum {
16928     NM_P_SLL        = 0x00,
16929     NM_SRL          = 0x02,
16930     NM_SRA          = 0x04,
16931     NM_ROTR         = 0x06,
16932 };
16933
16934 /* P.ROTX instruction pool */
16935 enum {
16936     NM_ROTX         = 0x00,
16937 };
16938
16939 /* P.INS instruction pool */
16940 enum {
16941     NM_INS          = 0x00,
16942 };
16943
16944 /* P.EXT instruction pool */
16945 enum {
16946     NM_EXT          = 0x00,
16947 };
16948
16949 /* POOL32F_0 (fmt) instruction pool */
16950 enum {
16951     NM_RINT_S              = 0x04,
16952     NM_RINT_D              = 0x44,
16953     NM_ADD_S               = 0x06,
16954     NM_SELEQZ_S            = 0x07,
16955     NM_SELEQZ_D            = 0x47,
16956     NM_CLASS_S             = 0x0c,
16957     NM_CLASS_D             = 0x4c,
16958     NM_SUB_S               = 0x0e,
16959     NM_SELNEZ_S            = 0x0f,
16960     NM_SELNEZ_D            = 0x4f,
16961     NM_MUL_S               = 0x16,
16962     NM_SEL_S               = 0x17,
16963     NM_SEL_D               = 0x57,
16964     NM_DIV_S               = 0x1e,
16965     NM_ADD_D               = 0x26,
16966     NM_SUB_D               = 0x2e,
16967     NM_MUL_D               = 0x36,
16968     NM_MADDF_S             = 0x37,
16969     NM_MADDF_D             = 0x77,
16970     NM_DIV_D               = 0x3e,
16971     NM_MSUBF_S             = 0x3f,
16972     NM_MSUBF_D             = 0x7f,
16973 };
16974
16975 /* POOL32F_3  instruction pool */
16976 enum {
16977     NM_MIN_FMT         = 0x00,
16978     NM_MAX_FMT         = 0x01,
16979     NM_MINA_FMT        = 0x04,
16980     NM_MAXA_FMT        = 0x05,
16981     NM_POOL32FXF       = 0x07,
16982 };
16983
16984 /* POOL32F_5  instruction pool */
16985 enum {
16986     NM_CMP_CONDN_S     = 0x00,
16987     NM_CMP_CONDN_D     = 0x02,
16988 };
16989
16990 /* P.GP.LH instruction pool */
16991 enum {
16992     NM_LHGP    = 0x00,
16993     NM_LHUGP   = 0x01,
16994 };
16995
16996 /* P.GP.SH instruction pool */
16997 enum {
16998     NM_SHGP    = 0x00,
16999 };
17000
17001 /* P.GP.CP1 instruction pool */
17002 enum {
17003     NM_LWC1GP       = 0x00,
17004     NM_SWC1GP       = 0x01,
17005     NM_LDC1GP       = 0x02,
17006     NM_SDC1GP       = 0x03,
17007 };
17008
17009 /* P.LS.S0 instruction pool */
17010 enum {
17011     NM_LBS9     = 0x00,
17012     NM_LHS9     = 0x04,
17013     NM_LWS9     = 0x08,
17014     NM_LDS9     = 0x0c,
17015
17016     NM_SBS9     = 0x01,
17017     NM_SHS9     = 0x05,
17018     NM_SWS9     = 0x09,
17019     NM_SDS9     = 0x0d,
17020
17021     NM_LBUS9    = 0x02,
17022     NM_LHUS9    = 0x06,
17023     NM_LWC1S9   = 0x0a,
17024     NM_LDC1S9   = 0x0e,
17025
17026     NM_P_PREFS9 = 0x03,
17027     NM_LWUS9    = 0x07,
17028     NM_SWC1S9   = 0x0b,
17029     NM_SDC1S9   = 0x0f,
17030 };
17031
17032 /* P.LS.S1 instruction pool */
17033 enum {
17034     NM_ASET_ACLR = 0x02,
17035     NM_UALH      = 0x04,
17036     NM_UASH      = 0x05,
17037     NM_CACHE     = 0x07,
17038     NM_P_LL      = 0x0a,
17039     NM_P_SC      = 0x0b,
17040 };
17041
17042 /* P.LS.WM instruction pool */
17043 enum {
17044     NM_LWM       = 0x00,
17045     NM_SWM       = 0x01,
17046 };
17047
17048 /* P.LS.UAWM instruction pool */
17049 enum {
17050     NM_UALWM       = 0x00,
17051     NM_UASWM       = 0x01,
17052 };
17053
17054 /* P.BR3A instruction pool */
17055 enum {
17056     NM_BC1EQZC          = 0x00,
17057     NM_BC1NEZC          = 0x01,
17058     NM_BC2EQZC          = 0x02,
17059     NM_BC2NEZC          = 0x03,
17060     NM_BPOSGE32C        = 0x04,
17061 };
17062
17063 /* P16.RI instruction pool */
17064 enum {
17065     NM_P16_SYSCALL  = 0x01,
17066     NM_BREAK16      = 0x02,
17067     NM_SDBBP16      = 0x03,
17068 };
17069
17070 /* POOL16C_0 instruction pool */
17071 enum {
17072     NM_POOL16C_00      = 0x00,
17073 };
17074
17075 /* P16.JRC instruction pool */
17076 enum {
17077     NM_JRC          = 0x00,
17078     NM_JALRC16      = 0x01,
17079 };
17080
17081 /* P.SYSCALL instruction pool */
17082 enum {
17083     NM_SYSCALL      = 0x00,
17084     NM_HYPCALL      = 0x01,
17085 };
17086
17087 /* P.TRAP instruction pool */
17088 enum {
17089     NM_TEQ          = 0x00,
17090     NM_TNE          = 0x01,
17091 };
17092
17093 /* P.CMOVE instruction pool */
17094 enum {
17095     NM_MOVZ            = 0x00,
17096     NM_MOVN            = 0x01,
17097 };
17098
17099 /* POOL32Axf instruction pool */
17100 enum {
17101     NM_POOL32AXF_1 = 0x01,
17102     NM_POOL32AXF_2 = 0x02,
17103     NM_POOL32AXF_4 = 0x04,
17104     NM_POOL32AXF_5 = 0x05,
17105     NM_POOL32AXF_7 = 0x07,
17106 };
17107
17108 /* POOL32Axf_1 instruction pool */
17109 enum {
17110     NM_POOL32AXF_1_0 = 0x00,
17111     NM_POOL32AXF_1_1 = 0x01,
17112     NM_POOL32AXF_1_3 = 0x03,
17113     NM_POOL32AXF_1_4 = 0x04,
17114     NM_POOL32AXF_1_5 = 0x05,
17115     NM_POOL32AXF_1_7 = 0x07,
17116 };
17117
17118 /* POOL32Axf_2 instruction pool */
17119 enum {
17120     NM_POOL32AXF_2_0_7     = 0x00,
17121     NM_POOL32AXF_2_8_15    = 0x01,
17122     NM_POOL32AXF_2_16_23   = 0x02,
17123     NM_POOL32AXF_2_24_31   = 0x03,
17124 };
17125
17126 /* POOL32Axf_7 instruction pool */
17127 enum {
17128     NM_SHRA_R_QB    = 0x0,
17129     NM_SHRL_PH      = 0x1,
17130     NM_REPL_QB      = 0x2,
17131 };
17132
17133 /* POOL32Axf_1_0 instruction pool */
17134 enum {
17135     NM_MFHI = 0x0,
17136     NM_MFLO = 0x1,
17137     NM_MTHI = 0x2,
17138     NM_MTLO = 0x3,
17139 };
17140
17141 /* POOL32Axf_1_1 instruction pool */
17142 enum {
17143     NM_MTHLIP = 0x0,
17144     NM_SHILOV = 0x1,
17145 };
17146
17147 /* POOL32Axf_1_3 instruction pool */
17148 enum {
17149     NM_RDDSP    = 0x0,
17150     NM_WRDSP    = 0x1,
17151     NM_EXTP     = 0x2,
17152     NM_EXTPDP   = 0x3,
17153 };
17154
17155 /* POOL32Axf_1_4 instruction pool */
17156 enum {
17157     NM_SHLL_QB  = 0x0,
17158     NM_SHRL_QB  = 0x1,
17159 };
17160
17161 /* POOL32Axf_1_5 instruction pool */
17162 enum {
17163     NM_MAQ_S_W_PHR   = 0x0,
17164     NM_MAQ_S_W_PHL   = 0x1,
17165     NM_MAQ_SA_W_PHR  = 0x2,
17166     NM_MAQ_SA_W_PHL  = 0x3,
17167 };
17168
17169 /* POOL32Axf_1_7 instruction pool */
17170 enum {
17171     NM_EXTR_W       = 0x0,
17172     NM_EXTR_R_W     = 0x1,
17173     NM_EXTR_RS_W    = 0x2,
17174     NM_EXTR_S_H     = 0x3,
17175 };
17176
17177 /* POOL32Axf_2_0_7 instruction pool */
17178 enum {
17179     NM_DPA_W_PH     = 0x0,
17180     NM_DPAQ_S_W_PH  = 0x1,
17181     NM_DPS_W_PH     = 0x2,
17182     NM_DPSQ_S_W_PH  = 0x3,
17183     NM_BALIGN       = 0x4,
17184     NM_MADD         = 0x5,
17185     NM_MULT         = 0x6,
17186     NM_EXTRV_W      = 0x7,
17187 };
17188
17189 /* POOL32Axf_2_8_15 instruction pool */
17190 enum {
17191     NM_DPAX_W_PH    = 0x0,
17192     NM_DPAQ_SA_L_W  = 0x1,
17193     NM_DPSX_W_PH    = 0x2,
17194     NM_DPSQ_SA_L_W  = 0x3,
17195     NM_MADDU        = 0x5,
17196     NM_MULTU        = 0x6,
17197     NM_EXTRV_R_W    = 0x7,
17198 };
17199
17200 /* POOL32Axf_2_16_23 instruction pool */
17201 enum {
17202     NM_DPAU_H_QBL       = 0x0,
17203     NM_DPAQX_S_W_PH     = 0x1,
17204     NM_DPSU_H_QBL       = 0x2,
17205     NM_DPSQX_S_W_PH     = 0x3,
17206     NM_EXTPV            = 0x4,
17207     NM_MSUB             = 0x5,
17208     NM_MULSA_W_PH       = 0x6,
17209     NM_EXTRV_RS_W       = 0x7,
17210 };
17211
17212 /* POOL32Axf_2_24_31 instruction pool */
17213 enum {
17214     NM_DPAU_H_QBR       = 0x0,
17215     NM_DPAQX_SA_W_PH    = 0x1,
17216     NM_DPSU_H_QBR       = 0x2,
17217     NM_DPSQX_SA_W_PH    = 0x3,
17218     NM_EXTPDPV          = 0x4,
17219     NM_MSUBU            = 0x5,
17220     NM_MULSAQ_S_W_PH    = 0x6,
17221     NM_EXTRV_S_H        = 0x7,
17222 };
17223
17224 /* POOL32Axf_{4, 5} instruction pool */
17225 enum {
17226     NM_CLO      = 0x25,
17227     NM_CLZ      = 0x2d,
17228
17229     NM_TLBP     = 0x01,
17230     NM_TLBR     = 0x09,
17231     NM_TLBWI    = 0x11,
17232     NM_TLBWR    = 0x19,
17233     NM_TLBINV   = 0x03,
17234     NM_TLBINVF  = 0x0b,
17235     NM_DI       = 0x23,
17236     NM_EI       = 0x2b,
17237     NM_RDPGPR   = 0x70,
17238     NM_WRPGPR   = 0x78,
17239     NM_WAIT     = 0x61,
17240     NM_DERET    = 0x71,
17241     NM_ERETX    = 0x79,
17242
17243     /* nanoMIPS DSP instructions */
17244     NM_ABSQ_S_QB        = 0x00,
17245     NM_ABSQ_S_PH        = 0x08,
17246     NM_ABSQ_S_W         = 0x10,
17247     NM_PRECEQ_W_PHL     = 0x28,
17248     NM_PRECEQ_W_PHR     = 0x30,
17249     NM_PRECEQU_PH_QBL   = 0x38,
17250     NM_PRECEQU_PH_QBR   = 0x48,
17251     NM_PRECEU_PH_QBL    = 0x58,
17252     NM_PRECEU_PH_QBR    = 0x68,
17253     NM_PRECEQU_PH_QBLA  = 0x39,
17254     NM_PRECEQU_PH_QBRA  = 0x49,
17255     NM_PRECEU_PH_QBLA   = 0x59,
17256     NM_PRECEU_PH_QBRA   = 0x69,
17257     NM_REPLV_PH         = 0x01,
17258     NM_REPLV_QB         = 0x09,
17259     NM_BITREV           = 0x18,
17260     NM_INSV             = 0x20,
17261     NM_RADDU_W_QB       = 0x78,
17262
17263     NM_BITSWAP          = 0x05,
17264     NM_WSBH             = 0x3d,
17265 };
17266
17267 /* PP.SR instruction pool */
17268 enum {
17269     NM_SAVE         = 0x00,
17270     NM_RESTORE      = 0x02,
17271     NM_RESTORE_JRC  = 0x03,
17272 };
17273
17274 /* P.SR.F instruction pool */
17275 enum {
17276     NM_SAVEF        = 0x00,
17277     NM_RESTOREF     = 0x01,
17278 };
17279
17280 /* P16.SYSCALL  instruction pool */
17281 enum {
17282     NM_SYSCALL16     = 0x00,
17283     NM_HYPCALL16     = 0x01,
17284 };
17285
17286 /* POOL16C_00 instruction pool */
17287 enum {
17288     NM_NOT16           = 0x00,
17289     NM_XOR16           = 0x01,
17290     NM_AND16           = 0x02,
17291     NM_OR16            = 0x03,
17292 };
17293
17294 /* PP.LSX and PP.LSXS instruction pool */
17295 enum {
17296     NM_LBX      = 0x00,
17297     NM_LHX      = 0x04,
17298     NM_LWX      = 0x08,
17299     NM_LDX      = 0x0c,
17300
17301     NM_SBX      = 0x01,
17302     NM_SHX      = 0x05,
17303     NM_SWX      = 0x09,
17304     NM_SDX      = 0x0d,
17305
17306     NM_LBUX     = 0x02,
17307     NM_LHUX     = 0x06,
17308     NM_LWC1X    = 0x0a,
17309     NM_LDC1X    = 0x0e,
17310
17311     NM_LWUX     = 0x07,
17312     NM_SWC1X    = 0x0b,
17313     NM_SDC1X    = 0x0f,
17314
17315     NM_LHXS     = 0x04,
17316     NM_LWXS     = 0x08,
17317     NM_LDXS     = 0x0c,
17318
17319     NM_SHXS     = 0x05,
17320     NM_SWXS     = 0x09,
17321     NM_SDXS     = 0x0d,
17322
17323     NM_LHUXS    = 0x06,
17324     NM_LWC1XS   = 0x0a,
17325     NM_LDC1XS   = 0x0e,
17326
17327     NM_LWUXS    = 0x07,
17328     NM_SWC1XS   = 0x0b,
17329     NM_SDC1XS   = 0x0f,
17330 };
17331
17332 /* ERETx instruction pool */
17333 enum {
17334     NM_ERET     = 0x00,
17335     NM_ERETNC   = 0x01,
17336 };
17337
17338 /* POOL32FxF_{0, 1} insturction pool */
17339 enum {
17340     NM_CFC1     = 0x40,
17341     NM_CTC1     = 0x60,
17342     NM_MFC1     = 0x80,
17343     NM_MTC1     = 0xa0,
17344     NM_MFHC1    = 0xc0,
17345     NM_MTHC1    = 0xe0,
17346
17347     NM_CVT_S_PL = 0x84,
17348     NM_CVT_S_PU = 0xa4,
17349
17350     NM_CVT_L_S     = 0x004,
17351     NM_CVT_L_D     = 0x104,
17352     NM_CVT_W_S     = 0x024,
17353     NM_CVT_W_D     = 0x124,
17354
17355     NM_RSQRT_S     = 0x008,
17356     NM_RSQRT_D     = 0x108,
17357
17358     NM_SQRT_S      = 0x028,
17359     NM_SQRT_D      = 0x128,
17360
17361     NM_RECIP_S     = 0x048,
17362     NM_RECIP_D     = 0x148,
17363
17364     NM_FLOOR_L_S   = 0x00c,
17365     NM_FLOOR_L_D   = 0x10c,
17366
17367     NM_FLOOR_W_S   = 0x02c,
17368     NM_FLOOR_W_D   = 0x12c,
17369
17370     NM_CEIL_L_S    = 0x04c,
17371     NM_CEIL_L_D    = 0x14c,
17372     NM_CEIL_W_S    = 0x06c,
17373     NM_CEIL_W_D    = 0x16c,
17374     NM_TRUNC_L_S   = 0x08c,
17375     NM_TRUNC_L_D   = 0x18c,
17376     NM_TRUNC_W_S   = 0x0ac,
17377     NM_TRUNC_W_D   = 0x1ac,
17378     NM_ROUND_L_S   = 0x0cc,
17379     NM_ROUND_L_D   = 0x1cc,
17380     NM_ROUND_W_S   = 0x0ec,
17381     NM_ROUND_W_D   = 0x1ec,
17382
17383     NM_MOV_S       = 0x01,
17384     NM_MOV_D       = 0x81,
17385     NM_ABS_S       = 0x0d,
17386     NM_ABS_D       = 0x8d,
17387     NM_NEG_S       = 0x2d,
17388     NM_NEG_D       = 0xad,
17389     NM_CVT_D_S     = 0x04d,
17390     NM_CVT_D_W     = 0x0cd,
17391     NM_CVT_D_L     = 0x14d,
17392     NM_CVT_S_D     = 0x06d,
17393     NM_CVT_S_W     = 0x0ed,
17394     NM_CVT_S_L     = 0x16d,
17395 };
17396
17397 /* P.LL instruction pool */
17398 enum {
17399     NM_LL       = 0x00,
17400     NM_LLWP     = 0x01,
17401 };
17402
17403 /* P.SC instruction pool */
17404 enum {
17405     NM_SC       = 0x00,
17406     NM_SCWP     = 0x01,
17407 };
17408
17409 /* P.DVP instruction pool */
17410 enum {
17411     NM_DVP      = 0x00,
17412     NM_EVP      = 0x01,
17413 };
17414
17415
17416 /*
17417  *
17418  * nanoMIPS decoding engine
17419  *
17420  */
17421
17422
17423 /* extraction utilities */
17424
17425 #define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
17426 #define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
17427 #define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
17428 #define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
17429 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
17430 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
17431
17432 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
17433 static inline int decode_gpr_gpr3(int r)
17434 {
17435     static const int map[] = { 16, 17, 18, 19,  4,  5,  6,  7 };
17436
17437     return map[r & 0x7];
17438 }
17439
17440 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
17441 static inline int decode_gpr_gpr3_src_store(int r)
17442 {
17443     static const int map[] = {  0, 17, 18, 19,  4,  5,  6,  7 };
17444
17445     return map[r & 0x7];
17446 }
17447
17448 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
17449 static inline int decode_gpr_gpr4(int r)
17450 {
17451     static const int map[] = {  8,  9, 10, 11,  4,  5,  6,  7,
17452                                16, 17, 18, 19, 20, 21, 22, 23 };
17453
17454     return map[r & 0xf];
17455 }
17456
17457 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
17458 static inline int decode_gpr_gpr4_zero(int r)
17459 {
17460     static const int map[] = {  8,  9, 10,  0,  4,  5,  6,  7,
17461                                16, 17, 18, 19, 20, 21, 22, 23 };
17462
17463     return map[r & 0xf];
17464 }
17465
17466
17467 /* extraction utilities */
17468
17469 #define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
17470 #define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
17471 #define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
17472 #define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
17473 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
17474 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
17475
17476
17477 static void gen_adjust_sp(DisasContext *ctx, int u)
17478 {
17479     gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u);
17480 }
17481
17482 static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count,
17483                      uint8_t gp, uint16_t u)
17484 {
17485     int counter = 0;
17486     TCGv va = tcg_temp_new();
17487     TCGv t0 = tcg_temp_new();
17488
17489     while (counter != count) {
17490         bool use_gp = gp && (counter == count - 1);
17491         int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
17492         int this_offset = -((counter + 1) << 2);
17493         gen_base_offset_addr(ctx, va, 29, this_offset);
17494         gen_load_gpr(t0, this_rt);
17495         tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx,
17496                            (MO_TEUL | ctx->default_tcg_memop_mask));
17497         counter++;
17498     }
17499
17500     /* adjust stack pointer */
17501     gen_adjust_sp(ctx, -u);
17502
17503     tcg_temp_free(t0);
17504     tcg_temp_free(va);
17505 }
17506
17507 static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count,
17508                         uint8_t gp, uint16_t u)
17509 {
17510     int counter = 0;
17511     TCGv va = tcg_temp_new();
17512     TCGv t0 = tcg_temp_new();
17513
17514     while (counter != count) {
17515         bool use_gp = gp && (counter == count - 1);
17516         int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
17517         int this_offset = u - ((counter + 1) << 2);
17518         gen_base_offset_addr(ctx, va, 29, this_offset);
17519         tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL |
17520                         ctx->default_tcg_memop_mask);
17521         tcg_gen_ext32s_tl(t0, t0);
17522         gen_store_gpr(t0, this_rt);
17523         counter++;
17524     }
17525
17526     /* adjust stack pointer */
17527     gen_adjust_sp(ctx, u);
17528
17529     tcg_temp_free(t0);
17530     tcg_temp_free(va);
17531 }
17532
17533 static void gen_pool16c_nanomips_insn(DisasContext *ctx)
17534 {
17535     int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
17536     int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
17537
17538     switch (extract32(ctx->opcode, 2, 2)) {
17539     case NM_NOT16:
17540         gen_logic(ctx, OPC_NOR, rt, rs, 0);
17541         break;
17542     case NM_AND16:
17543         gen_logic(ctx, OPC_AND, rt, rt, rs);
17544         break;
17545     case NM_XOR16:
17546         gen_logic(ctx, OPC_XOR, rt, rt, rs);
17547         break;
17548     case NM_OR16:
17549         gen_logic(ctx, OPC_OR, rt, rt, rs);
17550         break;
17551     }
17552 }
17553
17554 static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
17555 {
17556     int rt = extract32(ctx->opcode, 21, 5);
17557     int rs = extract32(ctx->opcode, 16, 5);
17558     int rd = extract32(ctx->opcode, 11, 5);
17559
17560     switch (extract32(ctx->opcode, 3, 7)) {
17561     case NM_P_TRAP:
17562         switch (extract32(ctx->opcode, 10, 1)) {
17563         case NM_TEQ:
17564             check_nms(ctx);
17565             gen_trap(ctx, OPC_TEQ, rs, rt, -1);
17566             break;
17567         case NM_TNE:
17568             check_nms(ctx);
17569             gen_trap(ctx, OPC_TNE, rs, rt, -1);
17570             break;
17571         }
17572         break;
17573     case NM_RDHWR:
17574         check_nms(ctx);
17575         gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
17576         break;
17577     case NM_SEB:
17578         check_nms(ctx);
17579         gen_bshfl(ctx, OPC_SEB, rs, rt);
17580         break;
17581     case NM_SEH:
17582         gen_bshfl(ctx, OPC_SEH, rs, rt);
17583         break;
17584     case NM_SLLV:
17585         gen_shift(ctx, OPC_SLLV, rd, rt, rs);
17586         break;
17587     case NM_SRLV:
17588         gen_shift(ctx, OPC_SRLV, rd, rt, rs);
17589         break;
17590     case NM_SRAV:
17591         gen_shift(ctx, OPC_SRAV, rd, rt, rs);
17592         break;
17593     case NM_ROTRV:
17594         gen_shift(ctx, OPC_ROTRV, rd, rt, rs);
17595         break;
17596     case NM_ADD:
17597         gen_arith(ctx, OPC_ADD, rd, rs, rt);
17598         break;
17599     case NM_ADDU:
17600         gen_arith(ctx, OPC_ADDU, rd, rs, rt);
17601         break;
17602     case NM_SUB:
17603         check_nms(ctx);
17604         gen_arith(ctx, OPC_SUB, rd, rs, rt);
17605         break;
17606     case NM_SUBU:
17607         gen_arith(ctx, OPC_SUBU, rd, rs, rt);
17608         break;
17609     case NM_P_CMOVE:
17610         switch (extract32(ctx->opcode, 10, 1)) {
17611         case NM_MOVZ:
17612             gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
17613             break;
17614         case NM_MOVN:
17615             gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
17616             break;
17617         }
17618         break;
17619     case NM_AND:
17620         gen_logic(ctx, OPC_AND, rd, rs, rt);
17621         break;
17622     case NM_OR:
17623         gen_logic(ctx, OPC_OR, rd, rs, rt);
17624         break;
17625     case NM_NOR:
17626         gen_logic(ctx, OPC_NOR, rd, rs, rt);
17627         break;
17628     case NM_XOR:
17629         gen_logic(ctx, OPC_XOR, rd, rs, rt);
17630         break;
17631     case NM_SLT:
17632         gen_slt(ctx, OPC_SLT, rd, rs, rt);
17633         break;
17634     case NM_P_SLTU:
17635         if (rd == 0) {
17636             /* P_DVP */
17637 #ifndef CONFIG_USER_ONLY
17638             TCGv t0 = tcg_temp_new();
17639             switch (extract32(ctx->opcode, 10, 1)) {
17640             case NM_DVP:
17641                 if (ctx->vp) {
17642                     check_cp0_enabled(ctx);
17643                     gen_helper_dvp(t0, cpu_env);
17644                     gen_store_gpr(t0, rt);
17645                 }
17646                 break;
17647             case NM_EVP:
17648                 if (ctx->vp) {
17649                     check_cp0_enabled(ctx);
17650                     gen_helper_evp(t0, cpu_env);
17651                     gen_store_gpr(t0, rt);
17652                 }
17653                 break;
17654             }
17655             tcg_temp_free(t0);
17656 #endif
17657         } else {
17658             gen_slt(ctx, OPC_SLTU, rd, rs, rt);
17659         }
17660         break;
17661     case NM_SOV:
17662         {
17663             TCGv t0 = tcg_temp_new();
17664             TCGv t1 = tcg_temp_new();
17665             TCGv t2 = tcg_temp_new();
17666
17667             gen_load_gpr(t1, rs);
17668             gen_load_gpr(t2, rt);
17669             tcg_gen_add_tl(t0, t1, t2);
17670             tcg_gen_ext32s_tl(t0, t0);
17671             tcg_gen_xor_tl(t1, t1, t2);
17672             tcg_gen_xor_tl(t2, t0, t2);
17673             tcg_gen_andc_tl(t1, t2, t1);
17674
17675             /* operands of same sign, result different sign */
17676             tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0);
17677             gen_store_gpr(t0, rd);
17678
17679             tcg_temp_free(t0);
17680             tcg_temp_free(t1);
17681             tcg_temp_free(t2);
17682         }
17683         break;
17684     case NM_MUL:
17685         gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
17686         break;
17687     case NM_MUH:
17688         gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
17689         break;
17690     case NM_MULU:
17691         gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
17692         break;
17693     case NM_MUHU:
17694         gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
17695         break;
17696     case NM_DIV:
17697         gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
17698         break;
17699     case NM_MOD:
17700         gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
17701         break;
17702     case NM_DIVU:
17703         gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
17704         break;
17705     case NM_MODU:
17706         gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
17707         break;
17708 #ifndef CONFIG_USER_ONLY
17709     case NM_MFC0:
17710         check_cp0_enabled(ctx);
17711         if (rt == 0) {
17712             /* Treat as NOP. */
17713             break;
17714         }
17715         gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3));
17716         break;
17717     case NM_MTC0:
17718         check_cp0_enabled(ctx);
17719         {
17720             TCGv t0 = tcg_temp_new();
17721
17722             gen_load_gpr(t0, rt);
17723             gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3));
17724             tcg_temp_free(t0);
17725         }
17726         break;
17727     case NM_D_E_MT_VPE:
17728         {
17729             uint8_t sc = extract32(ctx->opcode, 10, 1);
17730             TCGv t0 = tcg_temp_new();
17731
17732             switch (sc) {
17733             case 0:
17734                 if (rs == 1) {
17735                     /* DMT */
17736                     check_cp0_mt(ctx);
17737                     gen_helper_dmt(t0);
17738                     gen_store_gpr(t0, rt);
17739                 } else if (rs == 0) {
17740                     /* DVPE */
17741                     check_cp0_mt(ctx);
17742                     gen_helper_dvpe(t0, cpu_env);
17743                     gen_store_gpr(t0, rt);
17744                 } else {
17745                     generate_exception_end(ctx, EXCP_RI);
17746                 }
17747                 break;
17748             case 1:
17749                 if (rs == 1) {
17750                     /* EMT */
17751                     check_cp0_mt(ctx);
17752                     gen_helper_emt(t0);
17753                     gen_store_gpr(t0, rt);
17754                 } else if (rs == 0) {
17755                     /* EVPE */
17756                     check_cp0_mt(ctx);
17757                     gen_helper_evpe(t0, cpu_env);
17758                     gen_store_gpr(t0, rt);
17759                 } else {
17760                     generate_exception_end(ctx, EXCP_RI);
17761                 }
17762                 break;
17763             }
17764
17765             tcg_temp_free(t0);
17766         }
17767         break;
17768     case NM_FORK:
17769         check_mt(ctx);
17770         {
17771             TCGv t0 = tcg_temp_new();
17772             TCGv t1 = tcg_temp_new();
17773
17774             gen_load_gpr(t0, rt);
17775             gen_load_gpr(t1, rs);
17776             gen_helper_fork(t0, t1);
17777             tcg_temp_free(t0);
17778             tcg_temp_free(t1);
17779         }
17780         break;
17781     case NM_MFTR:
17782     case NM_MFHTR:
17783         check_cp0_enabled(ctx);
17784         if (rd == 0) {
17785             /* Treat as NOP. */
17786             return;
17787         }
17788         gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
17789                  extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
17790         break;
17791     case NM_MTTR:
17792     case NM_MTHTR:
17793         check_cp0_enabled(ctx);
17794         gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
17795                  extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
17796         break;
17797     case NM_YIELD:
17798         check_mt(ctx);
17799         {
17800             TCGv t0 = tcg_temp_new();
17801
17802             gen_load_gpr(t0, rs);
17803             gen_helper_yield(t0, cpu_env, t0);
17804             gen_store_gpr(t0, rt);
17805             tcg_temp_free(t0);
17806         }
17807         break;
17808 #endif
17809     default:
17810         generate_exception_end(ctx, EXCP_RI);
17811         break;
17812     }
17813 }
17814
17815 /* dsp */
17816 static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc,
17817                                             int ret, int v1, int v2)
17818 {
17819     TCGv_i32 t0;
17820     TCGv v0_t;
17821     TCGv v1_t;
17822
17823     t0 = tcg_temp_new_i32();
17824
17825     v0_t = tcg_temp_new();
17826     v1_t = tcg_temp_new();
17827
17828     tcg_gen_movi_i32(t0, v2 >> 3);
17829
17830     gen_load_gpr(v0_t, ret);
17831     gen_load_gpr(v1_t, v1);
17832
17833     switch (opc) {
17834     case NM_MAQ_S_W_PHR:
17835         check_dsp(ctx);
17836         gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env);
17837         break;
17838     case NM_MAQ_S_W_PHL:
17839         check_dsp(ctx);
17840         gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env);
17841         break;
17842     case NM_MAQ_SA_W_PHR:
17843         check_dsp(ctx);
17844         gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env);
17845         break;
17846     case NM_MAQ_SA_W_PHL:
17847         check_dsp(ctx);
17848         gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env);
17849         break;
17850     default:
17851         generate_exception_end(ctx, EXCP_RI);
17852         break;
17853     }
17854
17855     tcg_temp_free_i32(t0);
17856
17857     tcg_temp_free(v0_t);
17858     tcg_temp_free(v1_t);
17859 }
17860
17861
17862 static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc,
17863                                     int ret, int v1, int v2)
17864 {
17865     int16_t imm;
17866     TCGv t0 = tcg_temp_new();
17867     TCGv t1 = tcg_temp_new();
17868     TCGv v0_t = tcg_temp_new();
17869
17870     gen_load_gpr(v0_t, v1);
17871
17872     switch (opc) {
17873     case NM_POOL32AXF_1_0:
17874         check_dsp(ctx);
17875         switch (extract32(ctx->opcode, 12, 2)) {
17876         case NM_MFHI:
17877             gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret);
17878             break;
17879         case NM_MFLO:
17880             gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret);
17881             break;
17882         case NM_MTHI:
17883             gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1);
17884             break;
17885         case NM_MTLO:
17886             gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1);
17887             break;
17888         }
17889         break;
17890     case NM_POOL32AXF_1_1:
17891         check_dsp(ctx);
17892         switch (extract32(ctx->opcode, 12, 2)) {
17893         case NM_MTHLIP:
17894             tcg_gen_movi_tl(t0, v2);
17895             gen_helper_mthlip(t0, v0_t, cpu_env);
17896             break;
17897         case NM_SHILOV:
17898             tcg_gen_movi_tl(t0, v2 >> 3);
17899             gen_helper_shilo(t0, v0_t, cpu_env);
17900             break;
17901         default:
17902             generate_exception_end(ctx, EXCP_RI);
17903             break;
17904         }
17905         break;
17906     case NM_POOL32AXF_1_3:
17907         check_dsp(ctx);
17908         imm = extract32(ctx->opcode, 14, 7);
17909         switch (extract32(ctx->opcode, 12, 2)) {
17910         case NM_RDDSP:
17911             tcg_gen_movi_tl(t0, imm);
17912             gen_helper_rddsp(t0, t0, cpu_env);
17913             gen_store_gpr(t0, ret);
17914             break;
17915         case NM_WRDSP:
17916             gen_load_gpr(t0, ret);
17917             tcg_gen_movi_tl(t1, imm);
17918             gen_helper_wrdsp(t0, t1, cpu_env);
17919             break;
17920         case NM_EXTP:
17921             tcg_gen_movi_tl(t0, v2 >> 3);
17922             tcg_gen_movi_tl(t1, v1);
17923             gen_helper_extp(t0, t0, t1, cpu_env);
17924             gen_store_gpr(t0, ret);
17925             break;
17926         case NM_EXTPDP:
17927             tcg_gen_movi_tl(t0, v2 >> 3);
17928             tcg_gen_movi_tl(t1, v1);
17929             gen_helper_extpdp(t0, t0, t1, cpu_env);
17930             gen_store_gpr(t0, ret);
17931             break;
17932         }
17933         break;
17934     case NM_POOL32AXF_1_4:
17935         check_dsp(ctx);
17936         tcg_gen_movi_tl(t0, v2 >> 2);
17937         switch (extract32(ctx->opcode, 12, 1)) {
17938         case NM_SHLL_QB:
17939             gen_helper_shll_qb(t0, t0, v0_t, cpu_env);
17940             gen_store_gpr(t0, ret);
17941             break;
17942         case NM_SHRL_QB:
17943             gen_helper_shrl_qb(t0, t0, v0_t);
17944             gen_store_gpr(t0, ret);
17945             break;
17946         }
17947         break;
17948     case NM_POOL32AXF_1_5:
17949         opc = extract32(ctx->opcode, 12, 2);
17950         gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2);
17951         break;
17952     case NM_POOL32AXF_1_7:
17953         check_dsp(ctx);
17954         tcg_gen_movi_tl(t0, v2 >> 3);
17955         tcg_gen_movi_tl(t1, v1);
17956         switch (extract32(ctx->opcode, 12, 2)) {
17957         case NM_EXTR_W:
17958             gen_helper_extr_w(t0, t0, t1, cpu_env);
17959             gen_store_gpr(t0, ret);
17960             break;
17961         case NM_EXTR_R_W:
17962             gen_helper_extr_r_w(t0, t0, t1, cpu_env);
17963             gen_store_gpr(t0, ret);
17964             break;
17965         case NM_EXTR_RS_W:
17966             gen_helper_extr_rs_w(t0, t0, t1, cpu_env);
17967             gen_store_gpr(t0, ret);
17968             break;
17969         case NM_EXTR_S_H:
17970             gen_helper_extr_s_h(t0, t0, t1, cpu_env);
17971             gen_store_gpr(t0, ret);
17972             break;
17973         }
17974         break;
17975     default:
17976         generate_exception_end(ctx, EXCP_RI);
17977         break;
17978     }
17979
17980     tcg_temp_free(t0);
17981     tcg_temp_free(t1);
17982     tcg_temp_free(v0_t);
17983 }
17984
17985 static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc,
17986                                     TCGv v0, TCGv v1, int rd)
17987 {
17988     TCGv_i32 t0;
17989
17990     t0 = tcg_temp_new_i32();
17991
17992     tcg_gen_movi_i32(t0, rd >> 3);
17993
17994     switch (opc) {
17995     case NM_POOL32AXF_2_0_7:
17996         switch (extract32(ctx->opcode, 9, 3)) {
17997         case NM_DPA_W_PH:
17998             check_dsp_r2(ctx);
17999             gen_helper_dpa_w_ph(t0, v1, v0, cpu_env);
18000             break;
18001         case NM_DPAQ_S_W_PH:
18002             check_dsp(ctx);
18003             gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env);
18004             break;
18005         case NM_DPS_W_PH:
18006             check_dsp_r2(ctx);
18007             gen_helper_dps_w_ph(t0, v1, v0, cpu_env);
18008             break;
18009         case NM_DPSQ_S_W_PH:
18010             check_dsp(ctx);
18011             gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env);
18012             break;
18013         default:
18014             generate_exception_end(ctx, EXCP_RI);
18015             break;
18016         }
18017         break;
18018     case NM_POOL32AXF_2_8_15:
18019         switch (extract32(ctx->opcode, 9, 3)) {
18020         case NM_DPAX_W_PH:
18021             check_dsp_r2(ctx);
18022             gen_helper_dpax_w_ph(t0, v0, v1, cpu_env);
18023             break;
18024         case NM_DPAQ_SA_L_W:
18025             check_dsp(ctx);
18026             gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env);
18027             break;
18028         case NM_DPSX_W_PH:
18029             check_dsp_r2(ctx);
18030             gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env);
18031             break;
18032         case NM_DPSQ_SA_L_W:
18033             check_dsp(ctx);
18034             gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env);
18035             break;
18036         default:
18037             generate_exception_end(ctx, EXCP_RI);
18038             break;
18039         }
18040         break;
18041     case NM_POOL32AXF_2_16_23:
18042         switch (extract32(ctx->opcode, 9, 3)) {
18043         case NM_DPAU_H_QBL:
18044             check_dsp(ctx);
18045             gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env);
18046             break;
18047         case NM_DPAQX_S_W_PH:
18048             check_dsp_r2(ctx);
18049             gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env);
18050             break;
18051         case NM_DPSU_H_QBL:
18052             check_dsp(ctx);
18053             gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env);
18054             break;
18055         case NM_DPSQX_S_W_PH:
18056             check_dsp_r2(ctx);
18057             gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env);
18058             break;
18059         case NM_MULSA_W_PH:
18060             check_dsp_r2(ctx);
18061             gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env);
18062             break;
18063         default:
18064             generate_exception_end(ctx, EXCP_RI);
18065             break;
18066         }
18067         break;
18068     case NM_POOL32AXF_2_24_31:
18069         switch (extract32(ctx->opcode, 9, 3)) {
18070         case NM_DPAU_H_QBR:
18071             check_dsp(ctx);
18072             gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env);
18073             break;
18074         case NM_DPAQX_SA_W_PH:
18075             check_dsp_r2(ctx);
18076             gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env);
18077             break;
18078         case NM_DPSU_H_QBR:
18079             check_dsp(ctx);
18080             gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env);
18081             break;
18082         case NM_DPSQX_SA_W_PH:
18083             check_dsp_r2(ctx);
18084             gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env);
18085             break;
18086         case NM_MULSAQ_S_W_PH:
18087             check_dsp(ctx);
18088             gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env);
18089             break;
18090         default:
18091             generate_exception_end(ctx, EXCP_RI);
18092             break;
18093         }
18094         break;
18095     default:
18096         generate_exception_end(ctx, EXCP_RI);
18097         break;
18098     }
18099
18100     tcg_temp_free_i32(t0);
18101 }
18102
18103 static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc,
18104                                           int rt, int rs, int rd)
18105 {
18106     int ret = rt;
18107     TCGv t0 = tcg_temp_new();
18108     TCGv t1 = tcg_temp_new();
18109     TCGv v0_t = tcg_temp_new();
18110     TCGv v1_t = tcg_temp_new();
18111
18112     gen_load_gpr(v0_t, rt);
18113     gen_load_gpr(v1_t, rs);
18114
18115     switch (opc) {
18116     case NM_POOL32AXF_2_0_7:
18117         switch (extract32(ctx->opcode, 9, 3)) {
18118         case NM_DPA_W_PH:
18119         case NM_DPAQ_S_W_PH:
18120         case NM_DPS_W_PH:
18121         case NM_DPSQ_S_W_PH:
18122             gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18123             break;
18124         case NM_BALIGN:
18125             check_dsp_r2(ctx);
18126             if (rt != 0) {
18127                 gen_load_gpr(t0, rs);
18128                 rd &= 3;
18129                 if (rd != 0 && rd != 2) {
18130                     tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd);
18131                     tcg_gen_ext32u_tl(t0, t0);
18132                     tcg_gen_shri_tl(t0, t0, 8 * (4 - rd));
18133                     tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
18134                 }
18135                 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
18136             }
18137             break;
18138         case NM_MADD:
18139             check_dsp(ctx);
18140             {
18141                 int acc = extract32(ctx->opcode, 14, 2);
18142                 TCGv_i64 t2 = tcg_temp_new_i64();
18143                 TCGv_i64 t3 = tcg_temp_new_i64();
18144
18145                 gen_load_gpr(t0, rt);
18146                 gen_load_gpr(t1, rs);
18147                 tcg_gen_ext_tl_i64(t2, t0);
18148                 tcg_gen_ext_tl_i64(t3, t1);
18149                 tcg_gen_mul_i64(t2, t2, t3);
18150                 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18151                 tcg_gen_add_i64(t2, t2, t3);
18152                 tcg_temp_free_i64(t3);
18153                 gen_move_low32(cpu_LO[acc], t2);
18154                 gen_move_high32(cpu_HI[acc], t2);
18155                 tcg_temp_free_i64(t2);
18156             }
18157             break;
18158         case NM_MULT:
18159             check_dsp(ctx);
18160             {
18161                 int acc = extract32(ctx->opcode, 14, 2);
18162                 TCGv_i32 t2 = tcg_temp_new_i32();
18163                 TCGv_i32 t3 = tcg_temp_new_i32();
18164
18165                 gen_load_gpr(t0, rs);
18166                 gen_load_gpr(t1, rt);
18167                 tcg_gen_trunc_tl_i32(t2, t0);
18168                 tcg_gen_trunc_tl_i32(t3, t1);
18169                 tcg_gen_muls2_i32(t2, t3, t2, t3);
18170                 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
18171                 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
18172                 tcg_temp_free_i32(t2);
18173                 tcg_temp_free_i32(t3);
18174             }
18175             break;
18176         case NM_EXTRV_W:
18177             check_dsp(ctx);
18178             gen_load_gpr(v1_t, rs);
18179             tcg_gen_movi_tl(t0, rd >> 3);
18180             gen_helper_extr_w(t0, t0, v1_t, cpu_env);
18181             gen_store_gpr(t0, ret);
18182             break;
18183         }
18184         break;
18185     case NM_POOL32AXF_2_8_15:
18186         switch (extract32(ctx->opcode, 9, 3)) {
18187         case NM_DPAX_W_PH:
18188         case NM_DPAQ_SA_L_W:
18189         case NM_DPSX_W_PH:
18190         case NM_DPSQ_SA_L_W:
18191             gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18192             break;
18193         case NM_MADDU:
18194             check_dsp(ctx);
18195             {
18196                 int acc = extract32(ctx->opcode, 14, 2);
18197                 TCGv_i64 t2 = tcg_temp_new_i64();
18198                 TCGv_i64 t3 = tcg_temp_new_i64();
18199
18200                 gen_load_gpr(t0, rs);
18201                 gen_load_gpr(t1, rt);
18202                 tcg_gen_ext32u_tl(t0, t0);
18203                 tcg_gen_ext32u_tl(t1, t1);
18204                 tcg_gen_extu_tl_i64(t2, t0);
18205                 tcg_gen_extu_tl_i64(t3, t1);
18206                 tcg_gen_mul_i64(t2, t2, t3);
18207                 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18208                 tcg_gen_add_i64(t2, t2, t3);
18209                 tcg_temp_free_i64(t3);
18210                 gen_move_low32(cpu_LO[acc], t2);
18211                 gen_move_high32(cpu_HI[acc], t2);
18212                 tcg_temp_free_i64(t2);
18213             }
18214             break;
18215         case NM_MULTU:
18216             check_dsp(ctx);
18217             {
18218                 int acc = extract32(ctx->opcode, 14, 2);
18219                 TCGv_i32 t2 = tcg_temp_new_i32();
18220                 TCGv_i32 t3 = tcg_temp_new_i32();
18221
18222                 gen_load_gpr(t0, rs);
18223                 gen_load_gpr(t1, rt);
18224                 tcg_gen_trunc_tl_i32(t2, t0);
18225                 tcg_gen_trunc_tl_i32(t3, t1);
18226                 tcg_gen_mulu2_i32(t2, t3, t2, t3);
18227                 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
18228                 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
18229                 tcg_temp_free_i32(t2);
18230                 tcg_temp_free_i32(t3);
18231             }
18232             break;
18233         case NM_EXTRV_R_W:
18234             check_dsp(ctx);
18235             tcg_gen_movi_tl(t0, rd >> 3);
18236             gen_helper_extr_r_w(t0, t0, v1_t, cpu_env);
18237             gen_store_gpr(t0, ret);
18238             break;
18239         default:
18240             generate_exception_end(ctx, EXCP_RI);
18241             break;
18242         }
18243         break;
18244     case NM_POOL32AXF_2_16_23:
18245         switch (extract32(ctx->opcode, 9, 3)) {
18246         case NM_DPAU_H_QBL:
18247         case NM_DPAQX_S_W_PH:
18248         case NM_DPSU_H_QBL:
18249         case NM_DPSQX_S_W_PH:
18250         case NM_MULSA_W_PH:
18251             gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18252             break;
18253         case NM_EXTPV:
18254             check_dsp(ctx);
18255             tcg_gen_movi_tl(t0, rd >> 3);
18256             gen_helper_extp(t0, t0, v1_t, cpu_env);
18257             gen_store_gpr(t0, ret);
18258             break;
18259         case NM_MSUB:
18260             check_dsp(ctx);
18261             {
18262                 int acc = extract32(ctx->opcode, 14, 2);
18263                 TCGv_i64 t2 = tcg_temp_new_i64();
18264                 TCGv_i64 t3 = tcg_temp_new_i64();
18265
18266                 gen_load_gpr(t0, rs);
18267                 gen_load_gpr(t1, rt);
18268                 tcg_gen_ext_tl_i64(t2, t0);
18269                 tcg_gen_ext_tl_i64(t3, t1);
18270                 tcg_gen_mul_i64(t2, t2, t3);
18271                 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18272                 tcg_gen_sub_i64(t2, t3, t2);
18273                 tcg_temp_free_i64(t3);
18274                 gen_move_low32(cpu_LO[acc], t2);
18275                 gen_move_high32(cpu_HI[acc], t2);
18276                 tcg_temp_free_i64(t2);
18277             }
18278             break;
18279         case NM_EXTRV_RS_W:
18280             check_dsp(ctx);
18281             tcg_gen_movi_tl(t0, rd >> 3);
18282             gen_helper_extr_rs_w(t0, t0, v1_t, cpu_env);
18283             gen_store_gpr(t0, ret);
18284             break;
18285         }
18286         break;
18287     case NM_POOL32AXF_2_24_31:
18288         switch (extract32(ctx->opcode, 9, 3)) {
18289         case NM_DPAU_H_QBR:
18290         case NM_DPAQX_SA_W_PH:
18291         case NM_DPSU_H_QBR:
18292         case NM_DPSQX_SA_W_PH:
18293         case NM_MULSAQ_S_W_PH:
18294             gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18295             break;
18296         case NM_EXTPDPV:
18297             check_dsp(ctx);
18298             tcg_gen_movi_tl(t0, rd >> 3);
18299             gen_helper_extpdp(t0, t0, v1_t, cpu_env);
18300             gen_store_gpr(t0, ret);
18301             break;
18302         case NM_MSUBU:
18303             check_dsp(ctx);
18304             {
18305                 int acc = extract32(ctx->opcode, 14, 2);
18306                 TCGv_i64 t2 = tcg_temp_new_i64();
18307                 TCGv_i64 t3 = tcg_temp_new_i64();
18308
18309                 gen_load_gpr(t0, rs);
18310                 gen_load_gpr(t1, rt);
18311                 tcg_gen_ext32u_tl(t0, t0);
18312                 tcg_gen_ext32u_tl(t1, t1);
18313                 tcg_gen_extu_tl_i64(t2, t0);
18314                 tcg_gen_extu_tl_i64(t3, t1);
18315                 tcg_gen_mul_i64(t2, t2, t3);
18316                 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18317                 tcg_gen_sub_i64(t2, t3, t2);
18318                 tcg_temp_free_i64(t3);
18319                 gen_move_low32(cpu_LO[acc], t2);
18320                 gen_move_high32(cpu_HI[acc], t2);
18321                 tcg_temp_free_i64(t2);
18322             }
18323             break;
18324         case NM_EXTRV_S_H:
18325             check_dsp(ctx);
18326             tcg_gen_movi_tl(t0, rd >> 3);
18327             gen_helper_extr_s_h(t0, t0, v0_t, cpu_env);
18328             gen_store_gpr(t0, ret);
18329             break;
18330         }
18331         break;
18332     default:
18333         generate_exception_end(ctx, EXCP_RI);
18334         break;
18335     }
18336
18337     tcg_temp_free(t0);
18338     tcg_temp_free(t1);
18339
18340     tcg_temp_free(v0_t);
18341     tcg_temp_free(v1_t);
18342 }
18343
18344 static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc,
18345                                           int rt, int rs)
18346 {
18347     int ret = rt;
18348     TCGv t0 = tcg_temp_new();
18349     TCGv v0_t = tcg_temp_new();
18350
18351     gen_load_gpr(v0_t, rs);
18352
18353     switch (opc) {
18354     case NM_ABSQ_S_QB:
18355         check_dsp_r2(ctx);
18356         gen_helper_absq_s_qb(v0_t, v0_t, cpu_env);
18357         gen_store_gpr(v0_t, ret);
18358         break;
18359     case NM_ABSQ_S_PH:
18360         check_dsp(ctx);
18361         gen_helper_absq_s_ph(v0_t, v0_t, cpu_env);
18362         gen_store_gpr(v0_t, ret);
18363         break;
18364     case NM_ABSQ_S_W:
18365         check_dsp(ctx);
18366         gen_helper_absq_s_w(v0_t, v0_t, cpu_env);
18367         gen_store_gpr(v0_t, ret);
18368         break;
18369     case NM_PRECEQ_W_PHL:
18370         check_dsp(ctx);
18371         tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000);
18372         tcg_gen_ext32s_tl(v0_t, v0_t);
18373         gen_store_gpr(v0_t, ret);
18374         break;
18375     case NM_PRECEQ_W_PHR:
18376         check_dsp(ctx);
18377         tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF);
18378         tcg_gen_shli_tl(v0_t, v0_t, 16);
18379         tcg_gen_ext32s_tl(v0_t, v0_t);
18380         gen_store_gpr(v0_t, ret);
18381         break;
18382     case NM_PRECEQU_PH_QBL:
18383         check_dsp(ctx);
18384         gen_helper_precequ_ph_qbl(v0_t, v0_t);
18385         gen_store_gpr(v0_t, ret);
18386         break;
18387     case NM_PRECEQU_PH_QBR:
18388         check_dsp(ctx);
18389         gen_helper_precequ_ph_qbr(v0_t, v0_t);
18390         gen_store_gpr(v0_t, ret);
18391         break;
18392     case NM_PRECEQU_PH_QBLA:
18393         check_dsp(ctx);
18394         gen_helper_precequ_ph_qbla(v0_t, v0_t);
18395         gen_store_gpr(v0_t, ret);
18396         break;
18397     case NM_PRECEQU_PH_QBRA:
18398         check_dsp(ctx);
18399         gen_helper_precequ_ph_qbra(v0_t, v0_t);
18400         gen_store_gpr(v0_t, ret);
18401         break;
18402     case NM_PRECEU_PH_QBL:
18403         check_dsp(ctx);
18404         gen_helper_preceu_ph_qbl(v0_t, v0_t);
18405         gen_store_gpr(v0_t, ret);
18406         break;
18407     case NM_PRECEU_PH_QBR:
18408         check_dsp(ctx);
18409         gen_helper_preceu_ph_qbr(v0_t, v0_t);
18410         gen_store_gpr(v0_t, ret);
18411         break;
18412     case NM_PRECEU_PH_QBLA:
18413         check_dsp(ctx);
18414         gen_helper_preceu_ph_qbla(v0_t, v0_t);
18415         gen_store_gpr(v0_t, ret);
18416         break;
18417     case NM_PRECEU_PH_QBRA:
18418         check_dsp(ctx);
18419         gen_helper_preceu_ph_qbra(v0_t, v0_t);
18420         gen_store_gpr(v0_t, ret);
18421         break;
18422     case NM_REPLV_PH:
18423         check_dsp(ctx);
18424         tcg_gen_ext16u_tl(v0_t, v0_t);
18425         tcg_gen_shli_tl(t0, v0_t, 16);
18426         tcg_gen_or_tl(v0_t, v0_t, t0);
18427         tcg_gen_ext32s_tl(v0_t, v0_t);
18428         gen_store_gpr(v0_t, ret);
18429         break;
18430     case NM_REPLV_QB:
18431         check_dsp(ctx);
18432         tcg_gen_ext8u_tl(v0_t, v0_t);
18433         tcg_gen_shli_tl(t0, v0_t, 8);
18434         tcg_gen_or_tl(v0_t, v0_t, t0);
18435         tcg_gen_shli_tl(t0, v0_t, 16);
18436         tcg_gen_or_tl(v0_t, v0_t, t0);
18437         tcg_gen_ext32s_tl(v0_t, v0_t);
18438         gen_store_gpr(v0_t, ret);
18439         break;
18440     case NM_BITREV:
18441         check_dsp(ctx);
18442         gen_helper_bitrev(v0_t, v0_t);
18443         gen_store_gpr(v0_t, ret);
18444         break;
18445     case NM_INSV:
18446         check_dsp(ctx);
18447         {
18448             TCGv tv0 = tcg_temp_new();
18449
18450             gen_load_gpr(tv0, rt);
18451             gen_helper_insv(v0_t, cpu_env, v0_t, tv0);
18452             gen_store_gpr(v0_t, ret);
18453             tcg_temp_free(tv0);
18454         }
18455         break;
18456     case NM_RADDU_W_QB:
18457         check_dsp(ctx);
18458         gen_helper_raddu_w_qb(v0_t, v0_t);
18459         gen_store_gpr(v0_t, ret);
18460         break;
18461     case NM_BITSWAP:
18462         gen_bitswap(ctx, OPC_BITSWAP, ret, rs);
18463         break;
18464     case NM_CLO:
18465         check_nms(ctx);
18466         gen_cl(ctx, OPC_CLO, ret, rs);
18467         break;
18468     case NM_CLZ:
18469         check_nms(ctx);
18470         gen_cl(ctx, OPC_CLZ, ret, rs);
18471         break;
18472     case NM_WSBH:
18473         gen_bshfl(ctx, OPC_WSBH, ret, rs);
18474         break;
18475     default:
18476         generate_exception_end(ctx, EXCP_RI);
18477         break;
18478     }
18479
18480     tcg_temp_free(v0_t);
18481     tcg_temp_free(t0);
18482 }
18483
18484 static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc,
18485                                           int rt, int rs, int rd)
18486 {
18487     TCGv t0 = tcg_temp_new();
18488     TCGv rs_t = tcg_temp_new();
18489
18490     gen_load_gpr(rs_t, rs);
18491
18492     switch (opc) {
18493     case NM_SHRA_R_QB:
18494         check_dsp_r2(ctx);
18495         tcg_gen_movi_tl(t0, rd >> 2);
18496         switch (extract32(ctx->opcode, 12, 1)) {
18497         case 0:
18498             /* NM_SHRA_QB */
18499             gen_helper_shra_qb(t0, t0, rs_t);
18500             gen_store_gpr(t0, rt);
18501             break;
18502         case 1:
18503             /* NM_SHRA_R_QB */
18504             gen_helper_shra_r_qb(t0, t0, rs_t);
18505             gen_store_gpr(t0, rt);
18506             break;
18507         }
18508         break;
18509     case NM_SHRL_PH:
18510         check_dsp_r2(ctx);
18511         tcg_gen_movi_tl(t0, rd >> 1);
18512         gen_helper_shrl_ph(t0, t0, rs_t);
18513         gen_store_gpr(t0, rt);
18514         break;
18515     case NM_REPL_QB:
18516         check_dsp(ctx);
18517         {
18518             int16_t imm;
18519             target_long result;
18520             imm = extract32(ctx->opcode, 13, 8);
18521             result = (uint32_t)imm << 24 |
18522                      (uint32_t)imm << 16 |
18523                      (uint32_t)imm << 8  |
18524                      (uint32_t)imm;
18525             result = (int32_t)result;
18526             tcg_gen_movi_tl(t0, result);
18527             gen_store_gpr(t0, rt);
18528         }
18529         break;
18530     default:
18531         generate_exception_end(ctx, EXCP_RI);
18532         break;
18533     }
18534     tcg_temp_free(t0);
18535     tcg_temp_free(rs_t);
18536 }
18537
18538
18539 static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
18540 {
18541     int rt = extract32(ctx->opcode, 21, 5);
18542     int rs = extract32(ctx->opcode, 16, 5);
18543     int rd = extract32(ctx->opcode, 11, 5);
18544
18545     switch (extract32(ctx->opcode, 6, 3)) {
18546     case NM_POOL32AXF_1:
18547         {
18548             int32_t op1 = extract32(ctx->opcode, 9, 3);
18549             gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd);
18550         }
18551         break;
18552     case NM_POOL32AXF_2:
18553         {
18554             int32_t op1 = extract32(ctx->opcode, 12, 2);
18555             gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd);
18556         }
18557         break;
18558     case NM_POOL32AXF_4:
18559         {
18560             int32_t op1 = extract32(ctx->opcode, 9, 7);
18561             gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs);
18562         }
18563         break;
18564     case NM_POOL32AXF_5:
18565         switch (extract32(ctx->opcode, 9, 7)) {
18566 #ifndef CONFIG_USER_ONLY
18567         case NM_TLBP:
18568             gen_cp0(env, ctx, OPC_TLBP, 0, 0);
18569             break;
18570         case NM_TLBR:
18571             gen_cp0(env, ctx, OPC_TLBR, 0, 0);
18572             break;
18573         case NM_TLBWI:
18574             gen_cp0(env, ctx, OPC_TLBWI, 0, 0);
18575             break;
18576         case NM_TLBWR:
18577             gen_cp0(env, ctx, OPC_TLBWR, 0, 0);
18578             break;
18579         case NM_TLBINV:
18580             gen_cp0(env, ctx, OPC_TLBINV, 0, 0);
18581             break;
18582         case NM_TLBINVF:
18583             gen_cp0(env, ctx, OPC_TLBINVF, 0, 0);
18584             break;
18585         case NM_DI:
18586             check_cp0_enabled(ctx);
18587             {
18588                 TCGv t0 = tcg_temp_new();
18589
18590                 save_cpu_state(ctx, 1);
18591                 gen_helper_di(t0, cpu_env);
18592                 gen_store_gpr(t0, rt);
18593             /* Stop translation as we may have switched the execution mode */
18594                 ctx->base.is_jmp = DISAS_STOP;
18595                 tcg_temp_free(t0);
18596             }
18597             break;
18598         case NM_EI:
18599             check_cp0_enabled(ctx);
18600             {
18601                 TCGv t0 = tcg_temp_new();
18602
18603                 save_cpu_state(ctx, 1);
18604                 gen_helper_ei(t0, cpu_env);
18605                 gen_store_gpr(t0, rt);
18606             /* Stop translation as we may have switched the execution mode */
18607                 ctx->base.is_jmp = DISAS_STOP;
18608                 tcg_temp_free(t0);
18609             }
18610             break;
18611         case NM_RDPGPR:
18612             gen_load_srsgpr(rs, rt);
18613             break;
18614         case NM_WRPGPR:
18615             gen_store_srsgpr(rs, rt);
18616             break;
18617         case NM_WAIT:
18618             gen_cp0(env, ctx, OPC_WAIT, 0, 0);
18619             break;
18620         case NM_DERET:
18621             gen_cp0(env, ctx, OPC_DERET, 0, 0);
18622             break;
18623         case NM_ERETX:
18624             gen_cp0(env, ctx, OPC_ERET, 0, 0);
18625             break;
18626 #endif
18627         default:
18628             generate_exception_end(ctx, EXCP_RI);
18629             break;
18630         }
18631         break;
18632     case NM_POOL32AXF_7:
18633         {
18634             int32_t op1 = extract32(ctx->opcode, 9, 3);
18635             gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd);
18636         }
18637         break;
18638     default:
18639         generate_exception_end(ctx, EXCP_RI);
18640         break;
18641     }
18642 }
18643
18644 /* Immediate Value Compact Branches */
18645 static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc,
18646                                    int rt, int32_t imm, int32_t offset)
18647 {
18648     TCGCond cond;
18649     int bcond_compute = 0;
18650     TCGv t0 = tcg_temp_new();
18651     TCGv t1 = tcg_temp_new();
18652
18653     gen_load_gpr(t0, rt);
18654     tcg_gen_movi_tl(t1, imm);
18655     ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
18656
18657     /* Load needed operands and calculate btarget */
18658     switch (opc) {
18659     case NM_BEQIC:
18660         if (rt == 0 && imm == 0) {
18661             /* Unconditional branch */
18662         } else if (rt == 0 && imm != 0) {
18663             /* Treat as NOP */
18664             goto out;
18665         } else {
18666             bcond_compute = 1;
18667             cond = TCG_COND_EQ;
18668         }
18669         break;
18670     case NM_BBEQZC:
18671     case NM_BBNEZC:
18672         check_nms(ctx);
18673         if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) {
18674             generate_exception_end(ctx, EXCP_RI);
18675             goto out;
18676         } else if (rt == 0 && opc == NM_BBEQZC) {
18677             /* Unconditional branch */
18678         } else if (rt == 0 && opc == NM_BBNEZC) {
18679             /* Treat as NOP */
18680             goto out;
18681         } else {
18682             tcg_gen_shri_tl(t0, t0, imm);
18683             tcg_gen_andi_tl(t0, t0, 1);
18684             tcg_gen_movi_tl(t1, 0);
18685             bcond_compute = 1;
18686             if (opc == NM_BBEQZC) {
18687                 cond = TCG_COND_EQ;
18688             } else {
18689                 cond = TCG_COND_NE;
18690             }
18691         }
18692         break;
18693     case NM_BNEIC:
18694         if (rt == 0 && imm == 0) {
18695             /* Treat as NOP */
18696             goto out;
18697         } else if (rt == 0 && imm != 0) {
18698             /* Unconditional branch */
18699         } else {
18700             bcond_compute = 1;
18701             cond = TCG_COND_NE;
18702         }
18703         break;
18704     case NM_BGEIC:
18705         if (rt == 0 && imm == 0) {
18706             /* Unconditional branch */
18707         } else  {
18708             bcond_compute = 1;
18709             cond = TCG_COND_GE;
18710         }
18711         break;
18712     case NM_BLTIC:
18713         bcond_compute = 1;
18714         cond = TCG_COND_LT;
18715         break;
18716     case NM_BGEIUC:
18717         if (rt == 0 && imm == 0) {
18718             /* Unconditional branch */
18719         } else  {
18720             bcond_compute = 1;
18721             cond = TCG_COND_GEU;
18722         }
18723         break;
18724     case NM_BLTIUC:
18725         bcond_compute = 1;
18726         cond = TCG_COND_LTU;
18727         break;
18728     default:
18729         MIPS_INVAL("Immediate Value Compact branch");
18730         generate_exception_end(ctx, EXCP_RI);
18731         goto out;
18732     }
18733
18734     if (bcond_compute == 0) {
18735         /* Uncoditional compact branch */
18736         gen_goto_tb(ctx, 0, ctx->btarget);
18737     } else {
18738         /* Conditional compact branch */
18739         TCGLabel *fs = gen_new_label();
18740
18741         tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs);
18742
18743         gen_goto_tb(ctx, 1, ctx->btarget);
18744         gen_set_label(fs);
18745
18746         gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
18747     }
18748
18749 out:
18750     tcg_temp_free(t0);
18751     tcg_temp_free(t1);
18752 }
18753
18754 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
18755 static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs,
18756                                                 int rt)
18757 {
18758     TCGv t0 = tcg_temp_new();
18759     TCGv t1 = tcg_temp_new();
18760
18761     /* load rs */
18762     gen_load_gpr(t0, rs);
18763
18764     /* link */
18765     if (rt != 0) {
18766         tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4);
18767     }
18768
18769     /* calculate btarget */
18770     tcg_gen_shli_tl(t0, t0, 1);
18771     tcg_gen_movi_tl(t1, ctx->base.pc_next + 4);
18772     gen_op_addr_add(ctx, btarget, t1, t0);
18773
18774     /* unconditional branch to register */
18775     tcg_gen_mov_tl(cpu_PC, btarget);
18776     tcg_gen_lookup_and_goto_ptr();
18777
18778     tcg_temp_free(t0);
18779     tcg_temp_free(t1);
18780 }
18781
18782 /* nanoMIPS Branches */
18783 static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc,
18784                                        int rs, int rt, int32_t offset)
18785 {
18786     int bcond_compute = 0;
18787     TCGv t0 = tcg_temp_new();
18788     TCGv t1 = tcg_temp_new();
18789
18790     /* Load needed operands and calculate btarget */
18791     switch (opc) {
18792     /* compact branch */
18793     case OPC_BGEC:
18794     case OPC_BLTC:
18795         gen_load_gpr(t0, rs);
18796         gen_load_gpr(t1, rt);
18797         bcond_compute = 1;
18798         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
18799         break;
18800     case OPC_BGEUC:
18801     case OPC_BLTUC:
18802         if (rs == 0 || rs == rt) {
18803             /* OPC_BLEZALC, OPC_BGEZALC */
18804             /* OPC_BGTZALC, OPC_BLTZALC */
18805             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4);
18806         }
18807         gen_load_gpr(t0, rs);
18808         gen_load_gpr(t1, rt);
18809         bcond_compute = 1;
18810         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
18811         break;
18812     case OPC_BC:
18813         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
18814         break;
18815     case OPC_BEQZC:
18816         if (rs != 0) {
18817             /* OPC_BEQZC, OPC_BNEZC */
18818             gen_load_gpr(t0, rs);
18819             bcond_compute = 1;
18820             ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
18821         } else {
18822             /* OPC_JIC, OPC_JIALC */
18823             TCGv tbase = tcg_temp_new();
18824             TCGv toffset = tcg_temp_new();
18825
18826             gen_load_gpr(tbase, rt);
18827             tcg_gen_movi_tl(toffset, offset);
18828             gen_op_addr_add(ctx, btarget, tbase, toffset);
18829             tcg_temp_free(tbase);
18830             tcg_temp_free(toffset);
18831         }
18832         break;
18833     default:
18834         MIPS_INVAL("Compact branch/jump");
18835         generate_exception_end(ctx, EXCP_RI);
18836         goto out;
18837     }
18838
18839     if (bcond_compute == 0) {
18840         /* Uncoditional compact branch */
18841         switch (opc) {
18842         case OPC_BC:
18843             gen_goto_tb(ctx, 0, ctx->btarget);
18844             break;
18845         default:
18846             MIPS_INVAL("Compact branch/jump");
18847             generate_exception_end(ctx, EXCP_RI);
18848             goto out;
18849         }
18850     } else {
18851         /* Conditional compact branch */
18852         TCGLabel *fs = gen_new_label();
18853
18854         switch (opc) {
18855         case OPC_BGEUC:
18856             if (rs == 0 && rt != 0) {
18857                 /* OPC_BLEZALC */
18858                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
18859             } else if (rs != 0 && rt != 0 && rs == rt) {
18860                 /* OPC_BGEZALC */
18861                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
18862             } else {
18863                 /* OPC_BGEUC */
18864                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
18865             }
18866             break;
18867         case OPC_BLTUC:
18868             if (rs == 0 && rt != 0) {
18869                 /* OPC_BGTZALC */
18870                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
18871             } else if (rs != 0 && rt != 0 && rs == rt) {
18872                 /* OPC_BLTZALC */
18873                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
18874             } else {
18875                 /* OPC_BLTUC */
18876                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
18877             }
18878             break;
18879         case OPC_BGEC:
18880             if (rs == 0 && rt != 0) {
18881                 /* OPC_BLEZC */
18882                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
18883             } else if (rs != 0 && rt != 0 && rs == rt) {
18884                 /* OPC_BGEZC */
18885                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
18886             } else {
18887                 /* OPC_BGEC */
18888                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
18889             }
18890             break;
18891         case OPC_BLTC:
18892             if (rs == 0 && rt != 0) {
18893                 /* OPC_BGTZC */
18894                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
18895             } else if (rs != 0 && rt != 0 && rs == rt) {
18896                 /* OPC_BLTZC */
18897                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
18898             } else {
18899                 /* OPC_BLTC */
18900                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
18901             }
18902             break;
18903         case OPC_BEQZC:
18904             tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
18905             break;
18906         default:
18907             MIPS_INVAL("Compact conditional branch/jump");
18908             generate_exception_end(ctx, EXCP_RI);
18909             goto out;
18910         }
18911
18912         /* Generating branch here as compact branches don't have delay slot */
18913         gen_goto_tb(ctx, 1, ctx->btarget);
18914         gen_set_label(fs);
18915
18916         gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
18917     }
18918
18919 out:
18920     tcg_temp_free(t0);
18921     tcg_temp_free(t1);
18922 }
18923
18924
18925 /* nanoMIPS CP1 Branches */
18926 static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op,
18927                                    int32_t ft, int32_t offset)
18928 {
18929     target_ulong btarget;
18930     TCGv_i64 t0 = tcg_temp_new_i64();
18931
18932     gen_load_fpr64(ctx, t0, ft);
18933     tcg_gen_andi_i64(t0, t0, 1);
18934
18935     btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
18936
18937     switch (op) {
18938     case NM_BC1EQZC:
18939         tcg_gen_xori_i64(t0, t0, 1);
18940         ctx->hflags |= MIPS_HFLAG_BC;
18941         break;
18942     case NM_BC1NEZC:
18943         /* t0 already set */
18944         ctx->hflags |= MIPS_HFLAG_BC;
18945         break;
18946     default:
18947         MIPS_INVAL("cp1 cond branch");
18948         generate_exception_end(ctx, EXCP_RI);
18949         goto out;
18950     }
18951
18952     tcg_gen_trunc_i64_tl(bcond, t0);
18953
18954     ctx->btarget = btarget;
18955
18956 out:
18957     tcg_temp_free_i64(t0);
18958 }
18959
18960
18961 static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt)
18962 {
18963     TCGv t0, t1;
18964     t0 = tcg_temp_new();
18965     t1 = tcg_temp_new();
18966
18967     gen_load_gpr(t0, rs);
18968     gen_load_gpr(t1, rt);
18969
18970     if ((extract32(ctx->opcode, 6, 1)) == 1) {
18971         /* PP.LSXS instructions require shifting */
18972         switch (extract32(ctx->opcode, 7, 4)) {
18973         case NM_SHXS:
18974             check_nms(ctx);
18975         case NM_LHXS:
18976         case NM_LHUXS:
18977             tcg_gen_shli_tl(t0, t0, 1);
18978             break;
18979         case NM_SWXS:
18980             check_nms(ctx);
18981         case NM_LWXS:
18982         case NM_LWC1XS:
18983         case NM_SWC1XS:
18984             tcg_gen_shli_tl(t0, t0, 2);
18985             break;
18986         case NM_LDC1XS:
18987         case NM_SDC1XS:
18988             tcg_gen_shli_tl(t0, t0, 3);
18989             break;
18990         }
18991     }
18992     gen_op_addr_add(ctx, t0, t0, t1);
18993
18994     switch (extract32(ctx->opcode, 7, 4)) {
18995     case NM_LBX:
18996         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
18997                            MO_SB);
18998         gen_store_gpr(t0, rd);
18999         break;
19000     case NM_LHX:
19001     /*case NM_LHXS:*/
19002         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19003                            MO_TESW);
19004         gen_store_gpr(t0, rd);
19005         break;
19006     case NM_LWX:
19007     /*case NM_LWXS:*/
19008         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19009                            MO_TESL);
19010         gen_store_gpr(t0, rd);
19011         break;
19012     case NM_LBUX:
19013         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19014                            MO_UB);
19015         gen_store_gpr(t0, rd);
19016         break;
19017     case NM_LHUX:
19018     /*case NM_LHUXS:*/
19019         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19020                            MO_TEUW);
19021         gen_store_gpr(t0, rd);
19022         break;
19023     case NM_SBX:
19024         check_nms(ctx);
19025         gen_load_gpr(t1, rd);
19026         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19027                            MO_8);
19028         break;
19029     case NM_SHX:
19030     /*case NM_SHXS:*/
19031         check_nms(ctx);
19032         gen_load_gpr(t1, rd);
19033         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19034                            MO_TEUW);
19035         break;
19036     case NM_SWX:
19037     /*case NM_SWXS:*/
19038         check_nms(ctx);
19039         gen_load_gpr(t1, rd);
19040         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19041                            MO_TEUL);
19042         break;
19043     case NM_LWC1X:
19044     /*case NM_LWC1XS:*/
19045     case NM_LDC1X:
19046     /*case NM_LDC1XS:*/
19047     case NM_SWC1X:
19048     /*case NM_SWC1XS:*/
19049     case NM_SDC1X:
19050     /*case NM_SDC1XS:*/
19051         if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
19052             check_cp1_enabled(ctx);
19053             switch (extract32(ctx->opcode, 7, 4)) {
19054             case NM_LWC1X:
19055             /*case NM_LWC1XS:*/
19056                 gen_flt_ldst(ctx, OPC_LWC1, rd, t0);
19057                 break;
19058             case NM_LDC1X:
19059             /*case NM_LDC1XS:*/
19060                 gen_flt_ldst(ctx, OPC_LDC1, rd, t0);
19061                 break;
19062             case NM_SWC1X:
19063             /*case NM_SWC1XS:*/
19064                 gen_flt_ldst(ctx, OPC_SWC1, rd, t0);
19065                 break;
19066             case NM_SDC1X:
19067             /*case NM_SDC1XS:*/
19068                 gen_flt_ldst(ctx, OPC_SDC1, rd, t0);
19069                 break;
19070             }
19071         } else {
19072             generate_exception_err(ctx, EXCP_CpU, 1);
19073         }
19074         break;
19075     default:
19076         generate_exception_end(ctx, EXCP_RI);
19077         break;
19078     }
19079
19080     tcg_temp_free(t0);
19081     tcg_temp_free(t1);
19082 }
19083
19084 static void gen_pool32f_nanomips_insn(DisasContext *ctx)
19085 {
19086     int rt, rs, rd;
19087
19088     rt = extract32(ctx->opcode, 21, 5);
19089     rs = extract32(ctx->opcode, 16, 5);
19090     rd = extract32(ctx->opcode, 11, 5);
19091
19092     if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) {
19093         generate_exception_end(ctx, EXCP_RI);
19094         return;
19095     }
19096     check_cp1_enabled(ctx);
19097     switch (extract32(ctx->opcode, 0, 3)) {
19098     case NM_POOL32F_0:
19099         switch (extract32(ctx->opcode, 3, 7)) {
19100         case NM_RINT_S:
19101             gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
19102             break;
19103         case NM_RINT_D:
19104             gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
19105             break;
19106         case NM_CLASS_S:
19107             gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
19108             break;
19109         case NM_CLASS_D:
19110             gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
19111             break;
19112         case NM_ADD_S:
19113             gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0);
19114             break;
19115         case NM_ADD_D:
19116             gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0);
19117             break;
19118         case NM_SUB_S:
19119             gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0);
19120             break;
19121         case NM_SUB_D:
19122             gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0);
19123             break;
19124         case NM_MUL_S:
19125             gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0);
19126             break;
19127         case NM_MUL_D:
19128             gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0);
19129             break;
19130         case NM_DIV_S:
19131             gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0);
19132             break;
19133         case NM_DIV_D:
19134             gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0);
19135             break;
19136         case NM_SELEQZ_S:
19137             gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
19138             break;
19139         case NM_SELEQZ_D:
19140             gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
19141             break;
19142         case NM_SELNEZ_S:
19143             gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
19144             break;
19145         case NM_SELNEZ_D:
19146             gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
19147             break;
19148         case NM_SEL_S:
19149             gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
19150             break;
19151         case NM_SEL_D:
19152             gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
19153             break;
19154         case NM_MADDF_S:
19155             gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0);
19156             break;
19157         case NM_MADDF_D:
19158             gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0);
19159             break;
19160         case NM_MSUBF_S:
19161             gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0);
19162             break;
19163         case NM_MSUBF_D:
19164             gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0);
19165             break;
19166         default:
19167             generate_exception_end(ctx, EXCP_RI);
19168             break;
19169         }
19170         break;
19171     case NM_POOL32F_3:
19172         switch (extract32(ctx->opcode, 3, 3)) {
19173         case NM_MIN_FMT:
19174             switch (extract32(ctx->opcode, 9, 1)) {
19175             case FMT_SDPS_S:
19176                 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
19177                 break;
19178             case FMT_SDPS_D:
19179                 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
19180                 break;
19181             }
19182             break;
19183         case NM_MAX_FMT:
19184             switch (extract32(ctx->opcode, 9, 1)) {
19185             case FMT_SDPS_S:
19186                 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
19187                 break;
19188             case FMT_SDPS_D:
19189                 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
19190                 break;
19191             }
19192             break;
19193         case NM_MINA_FMT:
19194             switch (extract32(ctx->opcode, 9, 1)) {
19195             case FMT_SDPS_S:
19196                 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
19197                 break;
19198             case FMT_SDPS_D:
19199                 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
19200                 break;
19201             }
19202             break;
19203         case NM_MAXA_FMT:
19204             switch (extract32(ctx->opcode, 9, 1)) {
19205             case FMT_SDPS_S:
19206                 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
19207                 break;
19208             case FMT_SDPS_D:
19209                 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
19210                 break;
19211             }
19212             break;
19213         case NM_POOL32FXF:
19214             switch (extract32(ctx->opcode, 6, 8)) {
19215             case NM_CFC1:
19216                 gen_cp1(ctx, OPC_CFC1, rt, rs);
19217                 break;
19218             case NM_CTC1:
19219                 gen_cp1(ctx, OPC_CTC1, rt, rs);
19220                 break;
19221             case NM_MFC1:
19222                 gen_cp1(ctx, OPC_MFC1, rt, rs);
19223                 break;
19224             case NM_MTC1:
19225                 gen_cp1(ctx, OPC_MTC1, rt, rs);
19226                 break;
19227             case NM_MFHC1:
19228                 gen_cp1(ctx, OPC_MFHC1, rt, rs);
19229                 break;
19230             case NM_MTHC1:
19231                 gen_cp1(ctx, OPC_MTHC1, rt, rs);
19232                 break;
19233             case NM_CVT_S_PL:
19234                 gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0);
19235                 break;
19236             case NM_CVT_S_PU:
19237                 gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0);
19238                 break;
19239             default:
19240                 switch (extract32(ctx->opcode, 6, 9)) {
19241                 case NM_CVT_L_S:
19242                     gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0);
19243                     break;
19244                 case NM_CVT_L_D:
19245                     gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0);
19246                     break;
19247                 case NM_CVT_W_S:
19248                     gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0);
19249                     break;
19250                 case NM_CVT_W_D:
19251                     gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0);
19252                     break;
19253                 case NM_RSQRT_S:
19254                     gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0);
19255                     break;
19256                 case NM_RSQRT_D:
19257                     gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0);
19258                     break;
19259                 case NM_SQRT_S:
19260                     gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0);
19261                     break;
19262                 case NM_SQRT_D:
19263                     gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0);
19264                     break;
19265                 case NM_RECIP_S:
19266                     gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0);
19267                     break;
19268                 case NM_RECIP_D:
19269                     gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0);
19270                     break;
19271                 case NM_FLOOR_L_S:
19272                     gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0);
19273                     break;
19274                 case NM_FLOOR_L_D:
19275                     gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0);
19276                     break;
19277                 case NM_FLOOR_W_S:
19278                     gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0);
19279                     break;
19280                 case NM_FLOOR_W_D:
19281                     gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0);
19282                     break;
19283                 case NM_CEIL_L_S:
19284                     gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0);
19285                     break;
19286                 case NM_CEIL_L_D:
19287                     gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0);
19288                     break;
19289                 case NM_CEIL_W_S:
19290                     gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0);
19291                     break;
19292                 case NM_CEIL_W_D:
19293                     gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0);
19294                     break;
19295                 case NM_TRUNC_L_S:
19296                     gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0);
19297                     break;
19298                 case NM_TRUNC_L_D:
19299                     gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0);
19300                     break;
19301                 case NM_TRUNC_W_S:
19302                     gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0);
19303                     break;
19304                 case NM_TRUNC_W_D:
19305                     gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0);
19306                     break;
19307                 case NM_ROUND_L_S:
19308                     gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0);
19309                     break;
19310                 case NM_ROUND_L_D:
19311                     gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0);
19312                     break;
19313                 case NM_ROUND_W_S:
19314                     gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0);
19315                     break;
19316                 case NM_ROUND_W_D:
19317                     gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0);
19318                     break;
19319                 case NM_MOV_S:
19320                     gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0);
19321                     break;
19322                 case NM_MOV_D:
19323                     gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0);
19324                     break;
19325                 case NM_ABS_S:
19326                     gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0);
19327                     break;
19328                 case NM_ABS_D:
19329                     gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0);
19330                     break;
19331                 case NM_NEG_S:
19332                     gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0);
19333                     break;
19334                 case NM_NEG_D:
19335                     gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0);
19336                     break;
19337                 case NM_CVT_D_S:
19338                     gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0);
19339                     break;
19340                 case NM_CVT_D_W:
19341                     gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0);
19342                     break;
19343                 case NM_CVT_D_L:
19344                     gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0);
19345                     break;
19346                 case NM_CVT_S_D:
19347                     gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0);
19348                     break;
19349                 case NM_CVT_S_W:
19350                     gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0);
19351                     break;
19352                 case NM_CVT_S_L:
19353                     gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0);
19354                     break;
19355                 default:
19356                     generate_exception_end(ctx, EXCP_RI);
19357                     break;
19358                 }
19359                 break;
19360             }
19361             break;
19362         }
19363         break;
19364     case NM_POOL32F_5:
19365         switch (extract32(ctx->opcode, 3, 3)) {
19366         case NM_CMP_CONDN_S:
19367             gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
19368             break;
19369         case NM_CMP_CONDN_D:
19370             gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
19371             break;
19372         default:
19373             generate_exception_end(ctx, EXCP_RI);
19374             break;
19375         }
19376         break;
19377     default:
19378         generate_exception_end(ctx, EXCP_RI);
19379         break;
19380     }
19381 }
19382
19383 static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc,
19384                                        int rd, int rs, int rt)
19385 {
19386     int ret = rd;
19387     TCGv t0 = tcg_temp_new();
19388     TCGv v1_t = tcg_temp_new();
19389     TCGv v2_t = tcg_temp_new();
19390
19391     gen_load_gpr(v1_t, rs);
19392     gen_load_gpr(v2_t, rt);
19393
19394     switch (opc) {
19395     case NM_CMP_EQ_PH:
19396         check_dsp(ctx);
19397         gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
19398         break;
19399     case NM_CMP_LT_PH:
19400         check_dsp(ctx);
19401         gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
19402         break;
19403     case NM_CMP_LE_PH:
19404         check_dsp(ctx);
19405         gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
19406         break;
19407     case NM_CMPU_EQ_QB:
19408         check_dsp(ctx);
19409         gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
19410         break;
19411     case NM_CMPU_LT_QB:
19412         check_dsp(ctx);
19413         gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
19414         break;
19415     case NM_CMPU_LE_QB:
19416         check_dsp(ctx);
19417         gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
19418         break;
19419     case NM_CMPGU_EQ_QB:
19420         check_dsp(ctx);
19421         gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
19422         gen_store_gpr(v1_t, ret);
19423         break;
19424     case NM_CMPGU_LT_QB:
19425         check_dsp(ctx);
19426         gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
19427         gen_store_gpr(v1_t, ret);
19428         break;
19429     case NM_CMPGU_LE_QB:
19430         check_dsp(ctx);
19431         gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
19432         gen_store_gpr(v1_t, ret);
19433         break;
19434     case NM_CMPGDU_EQ_QB:
19435         check_dsp_r2(ctx);
19436         gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
19437         tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
19438         gen_store_gpr(v1_t, ret);
19439         break;
19440     case NM_CMPGDU_LT_QB:
19441         check_dsp_r2(ctx);
19442         gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
19443         tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
19444         gen_store_gpr(v1_t, ret);
19445         break;
19446     case NM_CMPGDU_LE_QB:
19447         check_dsp_r2(ctx);
19448         gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
19449         tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
19450         gen_store_gpr(v1_t, ret);
19451         break;
19452     case NM_PACKRL_PH:
19453         check_dsp(ctx);
19454         gen_helper_packrl_ph(v1_t, v1_t, v2_t);
19455         gen_store_gpr(v1_t, ret);
19456         break;
19457     case NM_PICK_QB:
19458         check_dsp(ctx);
19459         gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env);
19460         gen_store_gpr(v1_t, ret);
19461         break;
19462     case NM_PICK_PH:
19463         check_dsp(ctx);
19464         gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env);
19465         gen_store_gpr(v1_t, ret);
19466         break;
19467     case NM_ADDQ_S_W:
19468         check_dsp(ctx);
19469         gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env);
19470         gen_store_gpr(v1_t, ret);
19471         break;
19472     case NM_SUBQ_S_W:
19473         check_dsp(ctx);
19474         gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env);
19475         gen_store_gpr(v1_t, ret);
19476         break;
19477     case NM_ADDSC:
19478         check_dsp(ctx);
19479         gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env);
19480         gen_store_gpr(v1_t, ret);
19481         break;
19482     case NM_ADDWC:
19483         check_dsp(ctx);
19484         gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env);
19485         gen_store_gpr(v1_t, ret);
19486         break;
19487     case NM_ADDQ_S_PH:
19488         check_dsp(ctx);
19489         switch (extract32(ctx->opcode, 10, 1)) {
19490         case 0:
19491             /* ADDQ_PH */
19492             gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env);
19493             gen_store_gpr(v1_t, ret);
19494             break;
19495         case 1:
19496             /* ADDQ_S_PH */
19497             gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env);
19498             gen_store_gpr(v1_t, ret);
19499             break;
19500         }
19501         break;
19502     case NM_ADDQH_R_PH:
19503         check_dsp_r2(ctx);
19504         switch (extract32(ctx->opcode, 10, 1)) {
19505         case 0:
19506             /* ADDQH_PH */
19507             gen_helper_addqh_ph(v1_t, v1_t, v2_t);
19508             gen_store_gpr(v1_t, ret);
19509             break;
19510         case 1:
19511             /* ADDQH_R_PH */
19512             gen_helper_addqh_r_ph(v1_t, v1_t, v2_t);
19513             gen_store_gpr(v1_t, ret);
19514             break;
19515         }
19516         break;
19517     case NM_ADDQH_R_W:
19518         check_dsp_r2(ctx);
19519         switch (extract32(ctx->opcode, 10, 1)) {
19520         case 0:
19521             /* ADDQH_W */
19522             gen_helper_addqh_w(v1_t, v1_t, v2_t);
19523             gen_store_gpr(v1_t, ret);
19524             break;
19525         case 1:
19526             /* ADDQH_R_W */
19527             gen_helper_addqh_r_w(v1_t, v1_t, v2_t);
19528             gen_store_gpr(v1_t, ret);
19529             break;
19530         }
19531         break;
19532     case NM_ADDU_S_QB:
19533         check_dsp(ctx);
19534         switch (extract32(ctx->opcode, 10, 1)) {
19535         case 0:
19536             /* ADDU_QB */
19537             gen_helper_addu_qb(v1_t, v1_t, v2_t, cpu_env);
19538             gen_store_gpr(v1_t, ret);
19539             break;
19540         case 1:
19541             /* ADDU_S_QB */
19542             gen_helper_addu_s_qb(v1_t, v1_t, v2_t, cpu_env);
19543             gen_store_gpr(v1_t, ret);
19544             break;
19545         }
19546         break;
19547     case NM_ADDU_S_PH:
19548         check_dsp_r2(ctx);
19549         switch (extract32(ctx->opcode, 10, 1)) {
19550         case 0:
19551             /* ADDU_PH */
19552             gen_helper_addu_ph(v1_t, v1_t, v2_t, cpu_env);
19553             gen_store_gpr(v1_t, ret);
19554             break;
19555         case 1:
19556             /* ADDU_S_PH */
19557             gen_helper_addu_s_ph(v1_t, v1_t, v2_t, cpu_env);
19558             gen_store_gpr(v1_t, ret);
19559             break;
19560         }
19561         break;
19562     case NM_ADDUH_R_QB:
19563         check_dsp_r2(ctx);
19564         switch (extract32(ctx->opcode, 10, 1)) {
19565         case 0:
19566             /* ADDUH_QB */
19567             gen_helper_adduh_qb(v1_t, v1_t, v2_t);
19568             gen_store_gpr(v1_t, ret);
19569             break;
19570         case 1:
19571             /* ADDUH_R_QB */
19572             gen_helper_adduh_r_qb(v1_t, v1_t, v2_t);
19573             gen_store_gpr(v1_t, ret);
19574             break;
19575         }
19576         break;
19577     case NM_SHRAV_R_PH:
19578         check_dsp(ctx);
19579         switch (extract32(ctx->opcode, 10, 1)) {
19580         case 0:
19581             /* SHRAV_PH */
19582             gen_helper_shra_ph(v1_t, v1_t, v2_t);
19583             gen_store_gpr(v1_t, ret);
19584             break;
19585         case 1:
19586             /* SHRAV_R_PH */
19587             gen_helper_shra_r_ph(v1_t, v1_t, v2_t);
19588             gen_store_gpr(v1_t, ret);
19589             break;
19590         }
19591         break;
19592     case NM_SHRAV_R_QB:
19593         check_dsp_r2(ctx);
19594         switch (extract32(ctx->opcode, 10, 1)) {
19595         case 0:
19596             /* SHRAV_QB */
19597             gen_helper_shra_qb(v1_t, v1_t, v2_t);
19598             gen_store_gpr(v1_t, ret);
19599             break;
19600         case 1:
19601             /* SHRAV_R_QB */
19602             gen_helper_shra_r_qb(v1_t, v1_t, v2_t);
19603             gen_store_gpr(v1_t, ret);
19604             break;
19605         }
19606         break;
19607     case NM_SUBQ_S_PH:
19608         check_dsp(ctx);
19609         switch (extract32(ctx->opcode, 10, 1)) {
19610         case 0:
19611             /* SUBQ_PH */
19612             gen_helper_subq_ph(v1_t, v1_t, v2_t, cpu_env);
19613             gen_store_gpr(v1_t, ret);
19614             break;
19615         case 1:
19616             /* SUBQ_S_PH */
19617             gen_helper_subq_s_ph(v1_t, v1_t, v2_t, cpu_env);
19618             gen_store_gpr(v1_t, ret);
19619             break;
19620         }
19621         break;
19622     case NM_SUBQH_R_PH:
19623         check_dsp_r2(ctx);
19624         switch (extract32(ctx->opcode, 10, 1)) {
19625         case 0:
19626             /* SUBQH_PH */
19627             gen_helper_subqh_ph(v1_t, v1_t, v2_t);
19628             gen_store_gpr(v1_t, ret);
19629             break;
19630         case 1:
19631             /* SUBQH_R_PH */
19632             gen_helper_subqh_r_ph(v1_t, v1_t, v2_t);
19633             gen_store_gpr(v1_t, ret);
19634             break;
19635         }
19636         break;
19637     case NM_SUBQH_R_W:
19638         check_dsp_r2(ctx);
19639         switch (extract32(ctx->opcode, 10, 1)) {
19640         case 0:
19641             /* SUBQH_W */
19642             gen_helper_subqh_w(v1_t, v1_t, v2_t);
19643             gen_store_gpr(v1_t, ret);
19644             break;
19645         case 1:
19646             /* SUBQH_R_W */
19647             gen_helper_subqh_r_w(v1_t, v1_t, v2_t);
19648             gen_store_gpr(v1_t, ret);
19649             break;
19650         }
19651         break;
19652     case NM_SUBU_S_QB:
19653         check_dsp(ctx);
19654         switch (extract32(ctx->opcode, 10, 1)) {
19655         case 0:
19656             /* SUBU_QB */
19657             gen_helper_subu_qb(v1_t, v1_t, v2_t, cpu_env);
19658             gen_store_gpr(v1_t, ret);
19659             break;
19660         case 1:
19661             /* SUBU_S_QB */
19662             gen_helper_subu_s_qb(v1_t, v1_t, v2_t, cpu_env);
19663             gen_store_gpr(v1_t, ret);
19664             break;
19665         }
19666         break;
19667     case NM_SUBU_S_PH:
19668         check_dsp_r2(ctx);
19669         switch (extract32(ctx->opcode, 10, 1)) {
19670         case 0:
19671             /* SUBU_PH */
19672             gen_helper_subu_ph(v1_t, v1_t, v2_t, cpu_env);
19673             gen_store_gpr(v1_t, ret);
19674             break;
19675         case 1:
19676             /* SUBU_S_PH */
19677             gen_helper_subu_s_ph(v1_t, v1_t, v2_t, cpu_env);
19678             gen_store_gpr(v1_t, ret);
19679             break;
19680         }
19681         break;
19682     case NM_SUBUH_R_QB:
19683         check_dsp_r2(ctx);
19684         switch (extract32(ctx->opcode, 10, 1)) {
19685         case 0:
19686             /* SUBUH_QB */
19687             gen_helper_subuh_qb(v1_t, v1_t, v2_t);
19688             gen_store_gpr(v1_t, ret);
19689             break;
19690         case 1:
19691             /* SUBUH_R_QB */
19692             gen_helper_subuh_r_qb(v1_t, v1_t, v2_t);
19693             gen_store_gpr(v1_t, ret);
19694             break;
19695         }
19696         break;
19697     case NM_SHLLV_S_PH:
19698         check_dsp(ctx);
19699         switch (extract32(ctx->opcode, 10, 1)) {
19700         case 0:
19701             /* SHLLV_PH */
19702             gen_helper_shll_ph(v1_t, v1_t, v2_t, cpu_env);
19703             gen_store_gpr(v1_t, ret);
19704             break;
19705         case 1:
19706             /* SHLLV_S_PH */
19707             gen_helper_shll_s_ph(v1_t, v1_t, v2_t, cpu_env);
19708             gen_store_gpr(v1_t, ret);
19709             break;
19710         }
19711         break;
19712     case NM_PRECR_SRA_R_PH_W:
19713         check_dsp_r2(ctx);
19714         switch (extract32(ctx->opcode, 10, 1)) {
19715         case 0:
19716             /* PRECR_SRA_PH_W */
19717             {
19718                 TCGv_i32 sa_t = tcg_const_i32(rd);
19719                 gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t,
19720                                           cpu_gpr[rt]);
19721                 gen_store_gpr(v1_t, rt);
19722                 tcg_temp_free_i32(sa_t);
19723             }
19724             break;
19725         case 1:
19726             /* PRECR_SRA_R_PH_W */
19727             {
19728                 TCGv_i32 sa_t = tcg_const_i32(rd);
19729                 gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t,
19730                                             cpu_gpr[rt]);
19731                 gen_store_gpr(v1_t, rt);
19732                 tcg_temp_free_i32(sa_t);
19733             }
19734             break;
19735        }
19736         break;
19737     case NM_MULEU_S_PH_QBL:
19738         check_dsp(ctx);
19739         gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, cpu_env);
19740         gen_store_gpr(v1_t, ret);
19741         break;
19742     case NM_MULEU_S_PH_QBR:
19743         check_dsp(ctx);
19744         gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, cpu_env);
19745         gen_store_gpr(v1_t, ret);
19746         break;
19747     case NM_MULQ_RS_PH:
19748         check_dsp(ctx);
19749         gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, cpu_env);
19750         gen_store_gpr(v1_t, ret);
19751         break;
19752     case NM_MULQ_S_PH:
19753         check_dsp_r2(ctx);
19754         gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, cpu_env);
19755         gen_store_gpr(v1_t, ret);
19756         break;
19757     case NM_MULQ_RS_W:
19758         check_dsp_r2(ctx);
19759         gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, cpu_env);
19760         gen_store_gpr(v1_t, ret);
19761         break;
19762     case NM_MULQ_S_W:
19763         check_dsp_r2(ctx);
19764         gen_helper_mulq_s_w(v1_t, v1_t, v2_t, cpu_env);
19765         gen_store_gpr(v1_t, ret);
19766         break;
19767     case NM_APPEND:
19768         check_dsp_r2(ctx);
19769         gen_load_gpr(t0, rs);
19770         if (rd != 0) {
19771             tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd);
19772         }
19773         tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
19774         break;
19775     case NM_MODSUB:
19776         check_dsp(ctx);
19777         gen_helper_modsub(v1_t, v1_t, v2_t);
19778         gen_store_gpr(v1_t, ret);
19779         break;
19780     case NM_SHRAV_R_W:
19781         check_dsp(ctx);
19782         gen_helper_shra_r_w(v1_t, v1_t, v2_t);
19783         gen_store_gpr(v1_t, ret);
19784         break;
19785     case NM_SHRLV_PH:
19786         check_dsp_r2(ctx);
19787         gen_helper_shrl_ph(v1_t, v1_t, v2_t);
19788         gen_store_gpr(v1_t, ret);
19789         break;
19790     case NM_SHRLV_QB:
19791         check_dsp(ctx);
19792         gen_helper_shrl_qb(v1_t, v1_t, v2_t);
19793         gen_store_gpr(v1_t, ret);
19794         break;
19795     case NM_SHLLV_QB:
19796         check_dsp(ctx);
19797         gen_helper_shll_qb(v1_t, v1_t, v2_t, cpu_env);
19798         gen_store_gpr(v1_t, ret);
19799         break;
19800     case NM_SHLLV_S_W:
19801         check_dsp(ctx);
19802         gen_helper_shll_s_w(v1_t, v1_t, v2_t, cpu_env);
19803         gen_store_gpr(v1_t, ret);
19804         break;
19805     case NM_SHILO:
19806         check_dsp(ctx);
19807         {
19808             TCGv tv0 = tcg_temp_new();
19809             TCGv tv1 = tcg_temp_new();
19810             int16_t imm = extract32(ctx->opcode, 16, 7);
19811
19812             tcg_gen_movi_tl(tv0, rd >> 3);
19813             tcg_gen_movi_tl(tv1, imm);
19814             gen_helper_shilo(tv0, tv1, cpu_env);
19815         }
19816         break;
19817     case NM_MULEQ_S_W_PHL:
19818         check_dsp(ctx);
19819         gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, cpu_env);
19820         gen_store_gpr(v1_t, ret);
19821         break;
19822     case NM_MULEQ_S_W_PHR:
19823         check_dsp(ctx);
19824         gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, cpu_env);
19825         gen_store_gpr(v1_t, ret);
19826         break;
19827     case NM_MUL_S_PH:
19828         check_dsp_r2(ctx);
19829         switch (extract32(ctx->opcode, 10, 1)) {
19830         case 0:
19831             /* MUL_PH */
19832             gen_helper_mul_ph(v1_t, v1_t, v2_t, cpu_env);
19833             gen_store_gpr(v1_t, ret);
19834             break;
19835         case 1:
19836             /* MUL_S_PH */
19837             gen_helper_mul_s_ph(v1_t, v1_t, v2_t, cpu_env);
19838             gen_store_gpr(v1_t, ret);
19839             break;
19840         }
19841         break;
19842     case NM_PRECR_QB_PH:
19843         check_dsp_r2(ctx);
19844         gen_helper_precr_qb_ph(v1_t, v1_t, v2_t);
19845         gen_store_gpr(v1_t, ret);
19846         break;
19847     case NM_PRECRQ_QB_PH:
19848         check_dsp(ctx);
19849         gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t);
19850         gen_store_gpr(v1_t, ret);
19851         break;
19852     case NM_PRECRQ_PH_W:
19853         check_dsp(ctx);
19854         gen_helper_precrq_ph_w(v1_t, v1_t, v2_t);
19855         gen_store_gpr(v1_t, ret);
19856         break;
19857     case NM_PRECRQ_RS_PH_W:
19858         check_dsp(ctx);
19859         gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, cpu_env);
19860         gen_store_gpr(v1_t, ret);
19861         break;
19862     case NM_PRECRQU_S_QB_PH:
19863         check_dsp(ctx);
19864         gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, cpu_env);
19865         gen_store_gpr(v1_t, ret);
19866         break;
19867     case NM_SHRA_R_W:
19868         check_dsp(ctx);
19869         tcg_gen_movi_tl(t0, rd);
19870         gen_helper_shra_r_w(v1_t, t0, v1_t);
19871         gen_store_gpr(v1_t, rt);
19872         break;
19873     case NM_SHRA_R_PH:
19874         check_dsp(ctx);
19875         tcg_gen_movi_tl(t0, rd >> 1);
19876         switch (extract32(ctx->opcode, 10, 1)) {
19877         case 0:
19878             /* SHRA_PH */
19879             gen_helper_shra_ph(v1_t, t0, v1_t);
19880             break;
19881             gen_store_gpr(v1_t, rt);
19882         case 1:
19883             /* SHRA_R_PH */
19884             gen_helper_shra_r_ph(v1_t, t0, v1_t);
19885             gen_store_gpr(v1_t, rt);
19886             break;
19887         }
19888         break;
19889     case NM_SHLL_S_PH:
19890         check_dsp(ctx);
19891         tcg_gen_movi_tl(t0, rd >> 1);
19892         switch (extract32(ctx->opcode, 10, 2)) {
19893         case 0:
19894             /* SHLL_PH */
19895             gen_helper_shll_ph(v1_t, t0, v1_t, cpu_env);
19896             gen_store_gpr(v1_t, rt);
19897             break;
19898         case 2:
19899             /* SHLL_S_PH */
19900             gen_helper_shll_s_ph(v1_t, t0, v1_t, cpu_env);
19901             gen_store_gpr(v1_t, rt);
19902             break;
19903         default:
19904             generate_exception_end(ctx, EXCP_RI);
19905             break;
19906         }
19907         break;
19908     case NM_SHLL_S_W:
19909         check_dsp(ctx);
19910         tcg_gen_movi_tl(t0, rd);
19911         gen_helper_shll_s_w(v1_t, t0, v1_t, cpu_env);
19912         gen_store_gpr(v1_t, rt);
19913         break;
19914     case NM_REPL_PH:
19915         check_dsp(ctx);
19916         {
19917             int16_t imm;
19918             imm = sextract32(ctx->opcode, 11, 11);
19919             imm = (int16_t)(imm << 6) >> 6;
19920             if (rt != 0) {
19921                 tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm));
19922             }
19923         }
19924         break;
19925     default:
19926         generate_exception_end(ctx, EXCP_RI);
19927         break;
19928     }
19929 }
19930
19931 static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
19932 {
19933     uint16_t insn;
19934     uint32_t op;
19935     int rt, rs, rd;
19936     int offset;
19937     int imm;
19938
19939     insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
19940     ctx->opcode = (ctx->opcode << 16) | insn;
19941
19942     rt = extract32(ctx->opcode, 21, 5);
19943     rs = extract32(ctx->opcode, 16, 5);
19944     rd = extract32(ctx->opcode, 11, 5);
19945
19946     op = extract32(ctx->opcode, 26, 6);
19947     switch (op) {
19948     case NM_P_ADDIU:
19949         if (rt == 0) {
19950             /* P.RI */
19951             switch (extract32(ctx->opcode, 19, 2)) {
19952             case NM_SIGRIE:
19953             default:
19954                 generate_exception_end(ctx, EXCP_RI);
19955                 break;
19956             case NM_P_SYSCALL:
19957                 if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) {
19958                     generate_exception_end(ctx, EXCP_SYSCALL);
19959                 } else {
19960                     generate_exception_end(ctx, EXCP_RI);
19961                 }
19962                 break;
19963             case NM_BREAK:
19964                 generate_exception_end(ctx, EXCP_BREAK);
19965                 break;
19966             case NM_SDBBP:
19967                 if (is_uhi(extract32(ctx->opcode, 0, 19))) {
19968                     gen_helper_do_semihosting(cpu_env);
19969                 } else {
19970                     if (ctx->hflags & MIPS_HFLAG_SBRI) {
19971                         generate_exception_end(ctx, EXCP_RI);
19972                     } else {
19973                         generate_exception_end(ctx, EXCP_DBp);
19974                     }
19975                 }
19976                 break;
19977             }
19978         } else {
19979             /* NM_ADDIU */
19980             imm = extract32(ctx->opcode, 0, 16);
19981             if (rs != 0) {
19982                 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm);
19983             } else {
19984                 tcg_gen_movi_tl(cpu_gpr[rt], imm);
19985             }
19986             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
19987         }
19988         break;
19989     case NM_ADDIUPC:
19990         if (rt != 0) {
19991             offset = sextract32(ctx->opcode, 0, 1) << 21 |
19992                      extract32(ctx->opcode, 1, 20) << 1;
19993             target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset);
19994             tcg_gen_movi_tl(cpu_gpr[rt], addr);
19995         }
19996         break;
19997     case NM_POOL32A:
19998         switch (ctx->opcode & 0x07) {
19999         case NM_POOL32A0:
20000             gen_pool32a0_nanomips_insn(env, ctx);
20001             break;
20002         case NM_POOL32A5:
20003             {
20004                 int32_t op1 = extract32(ctx->opcode, 3, 7);
20005                 gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt);
20006             }
20007             break;
20008         case NM_POOL32A7:
20009             switch (extract32(ctx->opcode, 3, 3)) {
20010             case NM_P_LSX:
20011                 gen_p_lsx(ctx, rd, rs, rt);
20012                 break;
20013             case NM_LSA:
20014                 /* In nanoMIPS, the shift field directly encodes the shift
20015                  * amount, meaning that the supported shift values are in
20016                  * the range 0 to 3 (instead of 1 to 4 in MIPSR6). */
20017                 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
20018                         extract32(ctx->opcode, 9, 2) - 1);
20019                 break;
20020             case NM_EXTW:
20021                 gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5));
20022                 break;
20023             case NM_POOL32AXF:
20024                 gen_pool32axf_nanomips_insn(env, ctx);
20025                 break;
20026             default:
20027                 generate_exception_end(ctx, EXCP_RI);
20028                 break;
20029             }
20030             break;
20031         default:
20032             generate_exception_end(ctx, EXCP_RI);
20033             break;
20034         }
20035         break;
20036     case NM_P_GP_W:
20037         switch (ctx->opcode & 0x03) {
20038         case NM_ADDIUGP_W:
20039             if (rt != 0) {
20040                 offset = extract32(ctx->opcode, 0, 21);
20041                 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset);
20042             }
20043             break;
20044         case NM_LWGP:
20045             gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
20046             break;
20047         case NM_SWGP:
20048             gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
20049             break;
20050         default:
20051             generate_exception_end(ctx, EXCP_RI);
20052             break;
20053         }
20054         break;
20055     case NM_P48I:
20056         {
20057             insn = cpu_lduw_code(env, ctx->base.pc_next + 4);
20058             target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16;
20059             switch (extract32(ctx->opcode, 16, 5)) {
20060             case NM_LI48:
20061                 check_nms(ctx);
20062                 if (rt != 0) {
20063                     tcg_gen_movi_tl(cpu_gpr[rt], addr_off);
20064                 }
20065                 break;
20066             case NM_ADDIU48:
20067                 check_nms(ctx);
20068                 if (rt != 0) {
20069                     tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off);
20070                     tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20071                 }
20072                 break;
20073             case NM_ADDIUGP48:
20074                 check_nms(ctx);
20075                 if (rt != 0) {
20076                     gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_off);
20077                 }
20078                 break;
20079             case NM_ADDIUPC48:
20080                 check_nms(ctx);
20081                 if (rt != 0) {
20082                     target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20083                                                 addr_off);
20084
20085                     tcg_gen_movi_tl(cpu_gpr[rt], addr);
20086                 }
20087                 break;
20088             case NM_LWPC48:
20089                 check_nms(ctx);
20090                 if (rt != 0) {
20091                     TCGv t0;
20092                     t0 = tcg_temp_new();
20093
20094                     target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20095                                                 addr_off);
20096
20097                     tcg_gen_movi_tl(t0, addr);
20098                     tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_TESL);
20099                     tcg_temp_free(t0);
20100                 }
20101                 break;
20102             case NM_SWPC48:
20103                 check_nms(ctx);
20104                 {
20105                     TCGv t0, t1;
20106                     t0 = tcg_temp_new();
20107                     t1 = tcg_temp_new();
20108
20109                     target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20110                                                 addr_off);
20111
20112                     tcg_gen_movi_tl(t0, addr);
20113                     gen_load_gpr(t1, rt);
20114
20115                     tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
20116
20117                     tcg_temp_free(t0);
20118                     tcg_temp_free(t1);
20119                 }
20120                 break;
20121             default:
20122                 generate_exception_end(ctx, EXCP_RI);
20123                 break;
20124             }
20125             return 6;
20126         }
20127     case NM_P_U12:
20128         switch (extract32(ctx->opcode, 12, 4)) {
20129         case NM_ORI:
20130             gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12));
20131             break;
20132         case NM_XORI:
20133             gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12));
20134             break;
20135         case NM_ANDI:
20136             gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12));
20137             break;
20138         case NM_P_SR:
20139             switch (extract32(ctx->opcode, 20, 1)) {
20140             case NM_PP_SR:
20141                 switch (ctx->opcode & 3) {
20142                 case NM_SAVE:
20143                     gen_save(ctx, rt, extract32(ctx->opcode, 16, 4),
20144                              extract32(ctx->opcode, 2, 1),
20145                              extract32(ctx->opcode, 3, 9) << 3);
20146                     break;
20147                 case NM_RESTORE:
20148                 case NM_RESTORE_JRC:
20149                     gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4),
20150                                 extract32(ctx->opcode, 2, 1),
20151                                 extract32(ctx->opcode, 3, 9) << 3);
20152                     if ((ctx->opcode & 3) == NM_RESTORE_JRC) {
20153                         gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
20154                     }
20155                     break;
20156                 default:
20157                     generate_exception_end(ctx, EXCP_RI);
20158                     break;
20159                 }
20160                 break;
20161             case NM_P_SR_F:
20162                 generate_exception_end(ctx, EXCP_RI);
20163                 break;
20164             }
20165             break;
20166         case NM_SLTI:
20167             gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12));
20168             break;
20169         case NM_SLTIU:
20170             gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12));
20171             break;
20172         case NM_SEQI:
20173             {
20174                 TCGv t0 = tcg_temp_new();
20175
20176                 imm = extract32(ctx->opcode, 0, 12);
20177                 gen_load_gpr(t0, rs);
20178                 tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm);
20179                 gen_store_gpr(t0, rt);
20180
20181                 tcg_temp_free(t0);
20182             }
20183             break;
20184         case NM_ADDIUNEG:
20185             imm = (int16_t) extract32(ctx->opcode, 0, 12);
20186             gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm);
20187             break;
20188         case NM_P_SHIFT:
20189             {
20190                 int shift = extract32(ctx->opcode, 0, 5);
20191                 switch (extract32(ctx->opcode, 5, 4)) {
20192                 case NM_P_SLL:
20193                     if (rt == 0 && shift == 0) {
20194                         /* NOP */
20195                     } else if (rt == 0 && shift == 3) {
20196                         /* EHB - treat as NOP */
20197                     } else if (rt == 0 && shift == 5) {
20198                         /* PAUSE - treat as NOP */
20199                     } else if (rt == 0 && shift == 6) {
20200                         /* SYNC */
20201                         gen_sync(extract32(ctx->opcode, 16, 5));
20202                     } else {
20203                         /* SLL */
20204                         gen_shift_imm(ctx, OPC_SLL, rt, rs,
20205                                       extract32(ctx->opcode, 0, 5));
20206                     }
20207                     break;
20208                 case NM_SRL:
20209                     gen_shift_imm(ctx, OPC_SRL, rt, rs,
20210                                   extract32(ctx->opcode, 0, 5));
20211                     break;
20212                 case NM_SRA:
20213                     gen_shift_imm(ctx, OPC_SRA, rt, rs,
20214                                   extract32(ctx->opcode, 0, 5));
20215                     break;
20216                 case NM_ROTR:
20217                     gen_shift_imm(ctx, OPC_ROTR, rt, rs,
20218                                   extract32(ctx->opcode, 0, 5));
20219                     break;
20220                 }
20221             }
20222             break;
20223         case NM_P_ROTX:
20224             check_nms(ctx);
20225             if (rt != 0) {
20226                 TCGv t0 = tcg_temp_new();
20227                 TCGv_i32 shift = tcg_const_i32(extract32(ctx->opcode, 0, 5));
20228                 TCGv_i32 shiftx = tcg_const_i32(extract32(ctx->opcode, 7, 4)
20229                                                 << 1);
20230                 TCGv_i32 stripe = tcg_const_i32(extract32(ctx->opcode, 6, 1));
20231
20232                 gen_load_gpr(t0, rs);
20233                 gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe);
20234                 tcg_temp_free(t0);
20235
20236                 tcg_temp_free_i32(shift);
20237                 tcg_temp_free_i32(shiftx);
20238                 tcg_temp_free_i32(stripe);
20239             }
20240             break;
20241         case NM_P_INS:
20242             switch (((ctx->opcode >> 10) & 2) |
20243                     (extract32(ctx->opcode, 5, 1))) {
20244             case NM_INS:
20245                 check_nms(ctx);
20246                 gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5),
20247                            extract32(ctx->opcode, 6, 5));
20248                 break;
20249             default:
20250                 generate_exception_end(ctx, EXCP_RI);
20251                 break;
20252             }
20253             break;
20254         case NM_P_EXT:
20255             switch (((ctx->opcode >> 10) & 2) |
20256                     (extract32(ctx->opcode, 5, 1))) {
20257             case NM_EXT:
20258                 check_nms(ctx);
20259                 gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5),
20260                            extract32(ctx->opcode, 6, 5));
20261                 break;
20262             default:
20263                 generate_exception_end(ctx, EXCP_RI);
20264                 break;
20265             }
20266             break;
20267         default:
20268             generate_exception_end(ctx, EXCP_RI);
20269             break;
20270         }
20271         break;
20272     case NM_POOL32F:
20273         gen_pool32f_nanomips_insn(ctx);
20274         break;
20275     case NM_POOL32S:
20276         break;
20277     case NM_P_LUI:
20278         switch (extract32(ctx->opcode, 1, 1)) {
20279         case NM_LUI:
20280             if (rt != 0) {
20281                 tcg_gen_movi_tl(cpu_gpr[rt],
20282                                 sextract32(ctx->opcode, 0, 1) << 31 |
20283                                 extract32(ctx->opcode, 2, 10) << 21 |
20284                                 extract32(ctx->opcode, 12, 9) << 12);
20285             }
20286             break;
20287         case NM_ALUIPC:
20288             if (rt != 0) {
20289                 offset = sextract32(ctx->opcode, 0, 1) << 31 |
20290                          extract32(ctx->opcode, 2, 10) << 21 |
20291                          extract32(ctx->opcode, 12, 9) << 12;
20292                 target_long addr;
20293                 addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset);
20294                 tcg_gen_movi_tl(cpu_gpr[rt], addr);
20295             }
20296             break;
20297         }
20298         break;
20299     case NM_P_GP_BH:
20300         {
20301             uint32_t u = extract32(ctx->opcode, 0, 18);
20302
20303             switch (extract32(ctx->opcode, 18, 3)) {
20304             case NM_LBGP:
20305                 gen_ld(ctx, OPC_LB, rt, 28, u);
20306                 break;
20307             case NM_SBGP:
20308                 gen_st(ctx, OPC_SB, rt, 28, u);
20309                 break;
20310             case NM_LBUGP:
20311                 gen_ld(ctx, OPC_LBU, rt, 28, u);
20312                 break;
20313             case NM_ADDIUGP_B:
20314                 if (rt != 0) {
20315                     gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u);
20316                 }
20317                 break;
20318             case NM_P_GP_LH:
20319                 u &= ~1;
20320                 switch (ctx->opcode & 1) {
20321                 case NM_LHGP:
20322                     gen_ld(ctx, OPC_LH, rt, 28, u);
20323                     break;
20324                 case NM_LHUGP:
20325                     gen_ld(ctx, OPC_LHU, rt, 28, u);
20326                     break;
20327                 }
20328                 break;
20329             case NM_P_GP_SH:
20330                 u &= ~1;
20331                 switch (ctx->opcode & 1) {
20332                 case NM_SHGP:
20333                     gen_st(ctx, OPC_SH, rt, 28, u);
20334                     break;
20335                 default:
20336                     generate_exception_end(ctx, EXCP_RI);
20337                     break;
20338                 }
20339                 break;
20340             case NM_P_GP_CP1:
20341                 u &= ~0x3;
20342                 switch (ctx->opcode & 0x3) {
20343                 case NM_LWC1GP:
20344                     gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u);
20345                     break;
20346                 case NM_LDC1GP:
20347                     gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u);
20348                     break;
20349                 case NM_SWC1GP:
20350                     gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u);
20351                     break;
20352                 case NM_SDC1GP:
20353                     gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u);
20354                     break;
20355                 }
20356                 break;
20357             default:
20358                 generate_exception_end(ctx, EXCP_RI);
20359                 break;
20360             }
20361         }
20362         break;
20363     case NM_P_LS_U12:
20364         {
20365             uint32_t u = extract32(ctx->opcode, 0, 12);
20366
20367             switch (extract32(ctx->opcode, 12, 4)) {
20368             case NM_P_PREFU12:
20369                 if (rt == 31) {
20370                     /* SYNCI */
20371                     /* Break the TB to be able to sync copied instructions
20372                        immediately */
20373                     ctx->base.is_jmp = DISAS_STOP;
20374                 } else {
20375                     /* PREF */
20376                     /* Treat as NOP. */
20377                 }
20378                 break;
20379             case NM_LB:
20380                 gen_ld(ctx, OPC_LB, rt, rs, u);
20381                 break;
20382             case NM_LH:
20383                 gen_ld(ctx, OPC_LH, rt, rs, u);
20384                 break;
20385             case NM_LW:
20386                 gen_ld(ctx, OPC_LW, rt, rs, u);
20387                 break;
20388             case NM_LBU:
20389                 gen_ld(ctx, OPC_LBU, rt, rs, u);
20390                 break;
20391             case NM_LHU:
20392                 gen_ld(ctx, OPC_LHU, rt, rs, u);
20393                 break;
20394             case NM_SB:
20395                 gen_st(ctx, OPC_SB, rt, rs, u);
20396                 break;
20397             case NM_SH:
20398                 gen_st(ctx, OPC_SH, rt, rs, u);
20399                 break;
20400             case NM_SW:
20401                 gen_st(ctx, OPC_SW, rt, rs, u);
20402                 break;
20403             case NM_LWC1:
20404                 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u);
20405                 break;
20406             case NM_LDC1:
20407                 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u);
20408                 break;
20409             case NM_SWC1:
20410                 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u);
20411                 break;
20412             case NM_SDC1:
20413                 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u);
20414                 break;
20415             default:
20416                 generate_exception_end(ctx, EXCP_RI);
20417                 break;
20418             }
20419         }
20420         break;
20421     case NM_P_LS_S9:
20422         {
20423             int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) |
20424                         extract32(ctx->opcode, 0, 8);
20425
20426             switch (extract32(ctx->opcode, 8, 3)) {
20427             case NM_P_LS_S0:
20428                 switch (extract32(ctx->opcode, 11, 4)) {
20429                 case NM_LBS9:
20430                     gen_ld(ctx, OPC_LB, rt, rs, s);
20431                     break;
20432                 case NM_LHS9:
20433                     gen_ld(ctx, OPC_LH, rt, rs, s);
20434                     break;
20435                 case NM_LWS9:
20436                     gen_ld(ctx, OPC_LW, rt, rs, s);
20437                     break;
20438                 case NM_LBUS9:
20439                     gen_ld(ctx, OPC_LBU, rt, rs, s);
20440                     break;
20441                 case NM_LHUS9:
20442                     gen_ld(ctx, OPC_LHU, rt, rs, s);
20443                     break;
20444                 case NM_SBS9:
20445                     gen_st(ctx, OPC_SB, rt, rs, s);
20446                     break;
20447                 case NM_SHS9:
20448                     gen_st(ctx, OPC_SH, rt, rs, s);
20449                     break;
20450                 case NM_SWS9:
20451                     gen_st(ctx, OPC_SW, rt, rs, s);
20452                     break;
20453                 case NM_LWC1S9:
20454                     gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s);
20455                     break;
20456                 case NM_LDC1S9:
20457                     gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s);
20458                     break;
20459                 case NM_SWC1S9:
20460                     gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s);
20461                     break;
20462                 case NM_SDC1S9:
20463                     gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s);
20464                     break;
20465                 case NM_P_PREFS9:
20466                     if (rt == 31) {
20467                         /* SYNCI */
20468                         /* Break the TB to be able to sync copied instructions
20469                            immediately */
20470                         ctx->base.is_jmp = DISAS_STOP;
20471                     } else {
20472                         /* PREF */
20473                         /* Treat as NOP. */
20474                     }
20475                     break;
20476                 default:
20477                     generate_exception_end(ctx, EXCP_RI);
20478                     break;
20479                 }
20480                 break;
20481             case NM_P_LS_S1:
20482                 switch (extract32(ctx->opcode, 11, 4)) {
20483                 case NM_UALH:
20484                 case NM_UASH:
20485                     check_nms(ctx);
20486                     {
20487                         TCGv t0 = tcg_temp_new();
20488                         TCGv t1 = tcg_temp_new();
20489
20490                         gen_base_offset_addr(ctx, t0, rs, s);
20491
20492                         switch (extract32(ctx->opcode, 11, 4)) {
20493                         case NM_UALH:
20494                             tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
20495                                                MO_UNALN);
20496                             gen_store_gpr(t0, rt);
20497                             break;
20498                         case NM_UASH:
20499                             gen_load_gpr(t1, rt);
20500                             tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
20501                                                MO_UNALN);
20502                             break;
20503                         }
20504                         tcg_temp_free(t0);
20505                         tcg_temp_free(t1);
20506                     }
20507                     break;
20508                 case NM_P_LL:
20509                     switch (ctx->opcode & 0x03) {
20510                     case NM_LL:
20511                         gen_ld(ctx, OPC_LL, rt, rs, s);
20512                         break;
20513                     case NM_LLWP:
20514                         check_xnp(ctx);
20515                         gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
20516                         break;
20517                     }
20518                     break;
20519                 case NM_P_SC:
20520                     switch (ctx->opcode & 0x03) {
20521                     case NM_SC:
20522                         gen_st_cond(ctx, OPC_SC, rt, rs, s);
20523                         break;
20524                     case NM_SCWP:
20525                         check_xnp(ctx);
20526                         gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
20527                         break;
20528                     }
20529                     break;
20530                 case NM_CACHE:
20531                     check_cp0_enabled(ctx);
20532                     if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
20533                         gen_cache_operation(ctx, rt, rs, s);
20534                     }
20535                     break;
20536                 }
20537                 break;
20538             case NM_P_LS_WM:
20539             case NM_P_LS_UAWM:
20540                 check_nms(ctx);
20541                 {
20542                     int count = extract32(ctx->opcode, 12, 3);
20543                     int counter = 0;
20544
20545                     offset = sextract32(ctx->opcode, 15, 1) << 8 |
20546                              extract32(ctx->opcode, 0, 8);
20547                     TCGv va = tcg_temp_new();
20548                     TCGv t1 = tcg_temp_new();
20549                     TCGMemOp memop = (extract32(ctx->opcode, 8, 3)) ==
20550                                       NM_P_LS_UAWM ? MO_UNALN : 0;
20551
20552                     count = (count == 0) ? 8 : count;
20553                     while (counter != count) {
20554                         int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10);
20555                         int this_offset = offset + (counter << 2);
20556
20557                         gen_base_offset_addr(ctx, va, rs, this_offset);
20558
20559                         switch (extract32(ctx->opcode, 11, 1)) {
20560                         case NM_LWM:
20561                             tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx,
20562                                                memop | MO_TESL);
20563                             gen_store_gpr(t1, this_rt);
20564                             if ((this_rt == rs) &&
20565                                 (counter != (count - 1))) {
20566                                 /* UNPREDICTABLE */
20567                             }
20568                             break;
20569                         case NM_SWM:
20570                             this_rt = (rt == 0) ? 0 : this_rt;
20571                             gen_load_gpr(t1, this_rt);
20572                             tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx,
20573                                                memop | MO_TEUL);
20574                             break;
20575                         }
20576                         counter++;
20577                     }
20578                     tcg_temp_free(va);
20579                     tcg_temp_free(t1);
20580                 }
20581                 break;
20582             default:
20583                 generate_exception_end(ctx, EXCP_RI);
20584                 break;
20585             }
20586         }
20587         break;
20588     case NM_MOVE_BALC:
20589         check_nms(ctx);
20590         {
20591             TCGv t0 = tcg_temp_new();
20592             int32_t s = sextract32(ctx->opcode, 0, 1) << 21 |
20593                         extract32(ctx->opcode, 1, 20) << 1;
20594             rd = (extract32(ctx->opcode, 24, 1)) == 0 ? 4 : 5;
20595             rt = decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3 |
20596                             extract32(ctx->opcode, 21, 3));
20597             gen_load_gpr(t0, rt);
20598             tcg_gen_mov_tl(cpu_gpr[rd], t0);
20599             gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
20600             tcg_temp_free(t0);
20601         }
20602         break;
20603     case NM_P_BAL:
20604         {
20605             int32_t s = sextract32(ctx->opcode, 0, 1) << 25 |
20606                         extract32(ctx->opcode, 1, 24) << 1;
20607
20608             if ((extract32(ctx->opcode, 25, 1)) == 0) {
20609                 /* BC */
20610                 gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s);
20611             } else {
20612                 /* BALC */
20613                 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
20614             }
20615         }
20616         break;
20617     case NM_P_J:
20618         switch (extract32(ctx->opcode, 12, 4)) {
20619         case NM_JALRC:
20620         case NM_JALRC_HB:
20621             gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0);
20622             break;
20623         case NM_P_BALRSC:
20624             gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt);
20625             break;
20626         default:
20627             generate_exception_end(ctx, EXCP_RI);
20628             break;
20629         }
20630         break;
20631     case NM_P_BR1:
20632         {
20633             int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
20634                         extract32(ctx->opcode, 1, 13) << 1;
20635             switch (extract32(ctx->opcode, 14, 2)) {
20636             case NM_BEQC:
20637                 check_nms(ctx);
20638                 gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s);
20639                 break;
20640             case NM_P_BR3A:
20641                 s = sextract32(ctx->opcode, 0, 1) << 14 |
20642                     extract32(ctx->opcode, 1, 13) << 1;
20643                 check_cp1_enabled(ctx);
20644                 switch (extract32(ctx->opcode, 16, 5)) {
20645                 case NM_BC1EQZC:
20646                     gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s);
20647                     break;
20648                 case NM_BC1NEZC:
20649                     gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s);
20650                     break;
20651                 case NM_BPOSGE32C:
20652                     check_dsp_r3(ctx);
20653                     {
20654                         int32_t imm = extract32(ctx->opcode, 1, 13) |
20655                                       extract32(ctx->opcode, 0, 1) << 13;
20656
20657                         gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2,
20658                                               imm);
20659                     }
20660                     break;
20661                 default:
20662                     generate_exception_end(ctx, EXCP_RI);
20663                     break;
20664                 }
20665                 break;
20666             case NM_BGEC:
20667                 if (rs == rt) {
20668                     gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s);
20669                 } else {
20670                     gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s);
20671                 }
20672                 break;
20673             case NM_BGEUC:
20674                 if (rs == rt || rt == 0) {
20675                     gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s);
20676                 } else if (rs == 0) {
20677                     gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s);
20678                 } else {
20679                     gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, s);
20680                 }
20681                 break;
20682             }
20683         }
20684         break;
20685     case NM_P_BR2:
20686         {
20687             int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
20688                         extract32(ctx->opcode, 1, 13) << 1;
20689             switch (extract32(ctx->opcode, 14, 2)) {
20690             case NM_BNEC:
20691                 check_nms(ctx);
20692                 gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s);
20693                 break;
20694             case NM_BLTC:
20695                 if (rs != 0 && rt != 0 && rs == rt) {
20696                     /* NOP */
20697                     ctx->hflags |= MIPS_HFLAG_FBNSLOT;
20698                 } else {
20699                     gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s);
20700                 }
20701                 break;
20702             case NM_BLTUC:
20703                 if (rs == 0 || rs == rt) {
20704                     /* NOP */
20705                     ctx->hflags |= MIPS_HFLAG_FBNSLOT;
20706                 } else {
20707                     gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, s);
20708                 }
20709                 break;
20710             default:
20711                 generate_exception_end(ctx, EXCP_RI);
20712                 break;
20713             }
20714         }
20715         break;
20716     case NM_P_BRI:
20717         {
20718             int32_t s = sextract32(ctx->opcode, 0, 1) << 11 |
20719                         extract32(ctx->opcode, 1, 10) << 1;
20720             uint32_t u = extract32(ctx->opcode, 11, 7);
20721
20722             gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3),
20723                                    rt, u, s);
20724         }
20725         break;
20726     default:
20727         generate_exception_end(ctx, EXCP_RI);
20728         break;
20729     }
20730     return 4;
20731 }
20732
20733 static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
20734 {
20735     uint32_t op;
20736     int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
20737     int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
20738     int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS1(ctx->opcode));
20739     int offset;
20740     int imm;
20741
20742     /* make sure instructions are on a halfword boundary */
20743     if (ctx->base.pc_next & 0x1) {
20744         TCGv tmp = tcg_const_tl(ctx->base.pc_next);
20745         tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
20746         tcg_temp_free(tmp);
20747         generate_exception_end(ctx, EXCP_AdEL);
20748         return 2;
20749     }
20750
20751     op = extract32(ctx->opcode, 10, 6);
20752     switch (op) {
20753     case NM_P16_MV:
20754         rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
20755         if (rt != 0) {
20756             /* MOVE */
20757             rs = NANOMIPS_EXTRACT_RS5(ctx->opcode);
20758             gen_arith(ctx, OPC_ADDU, rt, rs, 0);
20759         } else {
20760             /* P16.RI */
20761             switch (extract32(ctx->opcode, 3, 2)) {
20762             case NM_P16_SYSCALL:
20763                 if (extract32(ctx->opcode, 2, 1) == 0) {
20764                     generate_exception_end(ctx, EXCP_SYSCALL);
20765                 } else {
20766                     generate_exception_end(ctx, EXCP_RI);
20767                 }
20768                 break;
20769             case NM_BREAK16:
20770                 generate_exception_end(ctx, EXCP_BREAK);
20771                 break;
20772             case NM_SDBBP16:
20773                 if (is_uhi(extract32(ctx->opcode, 0, 3))) {
20774                     gen_helper_do_semihosting(cpu_env);
20775                 } else {
20776                     if (ctx->hflags & MIPS_HFLAG_SBRI) {
20777                         generate_exception_end(ctx, EXCP_RI);
20778                     } else {
20779                         generate_exception_end(ctx, EXCP_DBp);
20780                     }
20781                 }
20782                 break;
20783             default:
20784                 generate_exception_end(ctx, EXCP_RI);
20785                 break;
20786             }
20787         }
20788         break;
20789     case NM_P16_SHIFT:
20790         {
20791             int shift = extract32(ctx->opcode, 0, 3);
20792             uint32_t opc = 0;
20793             shift = (shift == 0) ? 8 : shift;
20794
20795             switch (extract32(ctx->opcode, 3, 1)) {
20796             case NM_SLL16:
20797                 opc = OPC_SLL;
20798                 break;
20799             case NM_SRL16:
20800                 opc = OPC_SRL;
20801                 break;
20802             }
20803             gen_shift_imm(ctx, opc, rt, rs, shift);
20804         }
20805         break;
20806     case NM_P16C:
20807         switch (ctx->opcode & 1) {
20808         case NM_POOL16C_0:
20809             gen_pool16c_nanomips_insn(ctx);
20810             break;
20811         case NM_LWXS16:
20812             gen_ldxs(ctx, rt, rs, rd);
20813             break;
20814         }
20815         break;
20816     case NM_P16_A1:
20817         switch (extract32(ctx->opcode, 6, 1)) {
20818         case NM_ADDIUR1SP:
20819             imm = extract32(ctx->opcode, 0, 6) << 2;
20820             gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm);
20821             break;
20822         default:
20823             generate_exception_end(ctx, EXCP_RI);
20824             break;
20825         }
20826         break;
20827     case NM_P16_A2:
20828         switch (extract32(ctx->opcode, 3, 1)) {
20829         case NM_ADDIUR2:
20830             imm = extract32(ctx->opcode, 0, 3) << 2;
20831             gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm);
20832             break;
20833         case NM_P_ADDIURS5:
20834             rt = extract32(ctx->opcode, 5, 5);
20835             if (rt != 0) {
20836                 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
20837                 imm = (sextract32(ctx->opcode, 4, 1) << 3) |
20838                       (extract32(ctx->opcode, 0, 3));
20839                 gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm);
20840             }
20841             break;
20842         }
20843         break;
20844     case NM_P16_ADDU:
20845         switch (ctx->opcode & 0x1) {
20846         case NM_ADDU16:
20847             gen_arith(ctx, OPC_ADDU, rd, rs, rt);
20848             break;
20849         case NM_SUBU16:
20850             gen_arith(ctx, OPC_SUBU, rd, rs, rt);
20851             break;
20852         }
20853         break;
20854     case NM_P16_4X4:
20855         rt = (extract32(ctx->opcode, 9, 1) << 3) |
20856               extract32(ctx->opcode, 5, 3);
20857         rs = (extract32(ctx->opcode, 4, 1) << 3) |
20858               extract32(ctx->opcode, 0, 3);
20859         rt = decode_gpr_gpr4(rt);
20860         rs = decode_gpr_gpr4(rs);
20861         switch ((extract32(ctx->opcode, 7, 2) & 0x2) |
20862                 (extract32(ctx->opcode, 3, 1))) {
20863         case NM_ADDU4X4:
20864             check_nms(ctx);
20865             gen_arith(ctx, OPC_ADDU, rt, rs, rt);
20866             break;
20867         case NM_MUL4X4:
20868             check_nms(ctx);
20869             gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt);
20870             break;
20871         default:
20872             generate_exception_end(ctx, EXCP_RI);
20873             break;
20874         }
20875         break;
20876     case NM_LI16:
20877         {
20878             int imm = extract32(ctx->opcode, 0, 7);
20879             imm = (imm == 0x7f ? -1 : imm);
20880             if (rt != 0) {
20881                 tcg_gen_movi_tl(cpu_gpr[rt], imm);
20882             }
20883         }
20884         break;
20885     case NM_ANDI16:
20886         {
20887             uint32_t u = extract32(ctx->opcode, 0, 4);
20888             u = (u == 12) ? 0xff :
20889                 (u == 13) ? 0xffff : u;
20890             gen_logic_imm(ctx, OPC_ANDI, rt, rs, u);
20891         }
20892         break;
20893     case NM_P16_LB:
20894         offset = extract32(ctx->opcode, 0, 2);
20895         switch (extract32(ctx->opcode, 2, 2)) {
20896         case NM_LB16:
20897             gen_ld(ctx, OPC_LB, rt, rs, offset);
20898             break;
20899         case NM_SB16:
20900             rt = decode_gpr_gpr3_src_store(
20901                      NANOMIPS_EXTRACT_RD(ctx->opcode));
20902             gen_st(ctx, OPC_SB, rt, rs, offset);
20903             break;
20904         case NM_LBU16:
20905             gen_ld(ctx, OPC_LBU, rt, rs, offset);
20906             break;
20907         default:
20908             generate_exception_end(ctx, EXCP_RI);
20909             break;
20910         }
20911         break;
20912     case NM_P16_LH:
20913         offset = extract32(ctx->opcode, 1, 2) << 1;
20914         switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) {
20915         case NM_LH16:
20916             gen_ld(ctx, OPC_LH, rt, rs, offset);
20917             break;
20918         case NM_SH16:
20919             rt = decode_gpr_gpr3_src_store(
20920                      NANOMIPS_EXTRACT_RD(ctx->opcode));
20921             gen_st(ctx, OPC_SH, rt, rs, offset);
20922             break;
20923         case NM_LHU16:
20924             gen_ld(ctx, OPC_LHU, rt, rs, offset);
20925             break;
20926         default:
20927             generate_exception_end(ctx, EXCP_RI);
20928             break;
20929         }
20930         break;
20931     case NM_LW16:
20932         offset = extract32(ctx->opcode, 0, 4) << 2;
20933         gen_ld(ctx, OPC_LW, rt, rs, offset);
20934         break;
20935     case NM_LWSP16:
20936         rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
20937         offset = extract32(ctx->opcode, 0, 5) << 2;
20938         gen_ld(ctx, OPC_LW, rt, 29, offset);
20939         break;
20940     case NM_LW4X4:
20941         check_nms(ctx);
20942         rt = (extract32(ctx->opcode, 9, 1) << 3) |
20943              extract32(ctx->opcode, 5, 3);
20944         rs = (extract32(ctx->opcode, 4, 1) << 3) |
20945              extract32(ctx->opcode, 0, 3);
20946         offset = (extract32(ctx->opcode, 3, 1) << 3) |
20947                  (extract32(ctx->opcode, 8, 1) << 2);
20948         rt = decode_gpr_gpr4(rt);
20949         rs = decode_gpr_gpr4(rs);
20950         gen_ld(ctx, OPC_LW, rt, rs, offset);
20951         break;
20952     case NM_SW4X4:
20953         check_nms(ctx);
20954         rt = (extract32(ctx->opcode, 9, 1) << 3) |
20955              extract32(ctx->opcode, 5, 3);
20956         rs = (extract32(ctx->opcode, 4, 1) << 3) |
20957              extract32(ctx->opcode, 0, 3);
20958         offset = (extract32(ctx->opcode, 3, 1) << 3) |
20959                  (extract32(ctx->opcode, 8, 1) << 2);
20960         rt = decode_gpr_gpr4_zero(rt);
20961         rs = decode_gpr_gpr4(rs);
20962         gen_st(ctx, OPC_SW, rt, rs, offset);
20963         break;
20964     case NM_LWGP16:
20965         offset = extract32(ctx->opcode, 0, 7) << 2;
20966         gen_ld(ctx, OPC_LW, rt, 28, offset);
20967         break;
20968     case NM_SWSP16:
20969         rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
20970         offset = extract32(ctx->opcode, 0, 5) << 2;
20971         gen_st(ctx, OPC_SW, rt, 29, offset);
20972         break;
20973     case NM_SW16:
20974         rt = decode_gpr_gpr3_src_store(
20975                  NANOMIPS_EXTRACT_RD(ctx->opcode));
20976         rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
20977         offset = extract32(ctx->opcode, 0, 4) << 2;
20978         gen_st(ctx, OPC_SW, rt, rs, offset);
20979         break;
20980     case NM_SWGP16:
20981         rt = decode_gpr_gpr3_src_store(
20982                  NANOMIPS_EXTRACT_RD(ctx->opcode));
20983         offset = extract32(ctx->opcode, 0, 7) << 2;
20984         gen_st(ctx, OPC_SW, rt, 28, offset);
20985         break;
20986     case NM_BC16:
20987         gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0,
20988                            (sextract32(ctx->opcode, 0, 1) << 10) |
20989                            (extract32(ctx->opcode, 1, 9) << 1));
20990         break;
20991     case NM_BALC16:
20992         gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0,
20993                            (sextract32(ctx->opcode, 0, 1) << 10) |
20994                            (extract32(ctx->opcode, 1, 9) << 1));
20995         break;
20996     case NM_BEQZC16:
20997         gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0,
20998                            (sextract32(ctx->opcode, 0, 1) << 7) |
20999                            (extract32(ctx->opcode, 1, 6) << 1));
21000         break;
21001     case NM_BNEZC16:
21002         gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0,
21003                            (sextract32(ctx->opcode, 0, 1) << 7) |
21004                            (extract32(ctx->opcode, 1, 6) << 1));
21005         break;
21006     case NM_P16_BR:
21007         switch (ctx->opcode & 0xf) {
21008         case 0:
21009             /* P16.JRC */
21010             switch (extract32(ctx->opcode, 4, 1)) {
21011             case NM_JRC:
21012                 gen_compute_branch_nm(ctx, OPC_JR, 2,
21013                                    extract32(ctx->opcode, 5, 5), 0, 0);
21014                 break;
21015             case NM_JALRC16:
21016                 gen_compute_branch_nm(ctx, OPC_JALR, 2,
21017                                    extract32(ctx->opcode, 5, 5), 31, 0);
21018                 break;
21019             }
21020             break;
21021         default:
21022             {
21023                 /* P16.BRI */
21024                 uint32_t opc = extract32(ctx->opcode, 4, 3) <
21025                                extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE;
21026                 gen_compute_branch_nm(ctx, opc, 2, rs, rt,
21027                                    extract32(ctx->opcode, 0, 4) << 1);
21028             }
21029             break;
21030         }
21031         break;
21032     case NM_P16_SR:
21033         {
21034             int count = extract32(ctx->opcode, 0, 4);
21035             int u = extract32(ctx->opcode, 4, 4) << 4;
21036
21037             rt = 30 + extract32(ctx->opcode, 9, 1);
21038             switch (extract32(ctx->opcode, 8, 1)) {
21039             case NM_SAVE16:
21040                 gen_save(ctx, rt, count, 0, u);
21041                 break;
21042             case NM_RESTORE_JRC16:
21043                 gen_restore(ctx, rt, count, 0, u);
21044                 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
21045                 break;
21046             }
21047         }
21048         break;
21049     case NM_MOVEP:
21050     case NM_MOVEPREV:
21051         check_nms(ctx);
21052         {
21053             static const int gpr2reg1[] = {4, 5, 6, 7};
21054             static const int gpr2reg2[] = {5, 6, 7, 8};
21055             int re;
21056             int rd2 = extract32(ctx->opcode, 3, 1) << 1 |
21057                       extract32(ctx->opcode, 8, 1);
21058             int r1 = gpr2reg1[rd2];
21059             int r2 = gpr2reg2[rd2];
21060             int r3 = extract32(ctx->opcode, 4, 1) << 3 |
21061                      extract32(ctx->opcode, 0, 3);
21062             int r4 = extract32(ctx->opcode, 9, 1) << 3 |
21063                      extract32(ctx->opcode, 5, 3);
21064             TCGv t0 = tcg_temp_new();
21065             TCGv t1 = tcg_temp_new();
21066             if (op == NM_MOVEP) {
21067                 rd = r1;
21068                 re = r2;
21069                 rs = decode_gpr_gpr4_zero(r3);
21070                 rt = decode_gpr_gpr4_zero(r4);
21071             } else {
21072                 rd = decode_gpr_gpr4(r3);
21073                 re = decode_gpr_gpr4(r4);
21074                 rs = r1;
21075                 rt = r2;
21076             }
21077             gen_load_gpr(t0, rs);
21078             gen_load_gpr(t1, rt);
21079             tcg_gen_mov_tl(cpu_gpr[rd], t0);
21080             tcg_gen_mov_tl(cpu_gpr[re], t1);
21081             tcg_temp_free(t0);
21082             tcg_temp_free(t1);
21083         }
21084         break;
21085     default:
21086         return decode_nanomips_32_48_opc(env, ctx);
21087     }
21088
21089     return 2;
21090 }
21091
21092
21093 /* SmartMIPS extension to MIPS32 */
21094
21095 #if defined(TARGET_MIPS64)
21096
21097 /* MDMX extension to MIPS64 */
21098
21099 #endif
21100
21101 /* MIPSDSP functions. */
21102 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
21103                            int rd, int base, int offset)
21104 {
21105     TCGv t0;
21106
21107     check_dsp(ctx);
21108     t0 = tcg_temp_new();
21109
21110     if (base == 0) {
21111         gen_load_gpr(t0, offset);
21112     } else if (offset == 0) {
21113         gen_load_gpr(t0, base);
21114     } else {
21115         gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
21116     }
21117
21118     switch (opc) {
21119     case OPC_LBUX:
21120         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
21121         gen_store_gpr(t0, rd);
21122         break;
21123     case OPC_LHX:
21124         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
21125         gen_store_gpr(t0, rd);
21126         break;
21127     case OPC_LWX:
21128         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
21129         gen_store_gpr(t0, rd);
21130         break;
21131 #if defined(TARGET_MIPS64)
21132     case OPC_LDX:
21133         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
21134         gen_store_gpr(t0, rd);
21135         break;
21136 #endif
21137     }
21138     tcg_temp_free(t0);
21139 }
21140
21141 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
21142                               int ret, int v1, int v2)
21143 {
21144     TCGv v1_t;
21145     TCGv v2_t;
21146
21147     if (ret == 0) {
21148         /* Treat as NOP. */
21149         return;
21150     }
21151
21152     v1_t = tcg_temp_new();
21153     v2_t = tcg_temp_new();
21154
21155     gen_load_gpr(v1_t, v1);
21156     gen_load_gpr(v2_t, v2);
21157
21158     switch (op1) {
21159     /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
21160     case OPC_MULT_G_2E:
21161         check_dsp_r2(ctx);
21162         switch (op2) {
21163         case OPC_ADDUH_QB:
21164             gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
21165             break;
21166         case OPC_ADDUH_R_QB:
21167             gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
21168             break;
21169         case OPC_ADDQH_PH:
21170             gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
21171             break;
21172         case OPC_ADDQH_R_PH:
21173             gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
21174             break;
21175         case OPC_ADDQH_W:
21176             gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
21177             break;
21178         case OPC_ADDQH_R_W:
21179             gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
21180             break;
21181         case OPC_SUBUH_QB:
21182             gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
21183             break;
21184         case OPC_SUBUH_R_QB:
21185             gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
21186             break;
21187         case OPC_SUBQH_PH:
21188             gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
21189             break;
21190         case OPC_SUBQH_R_PH:
21191             gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
21192             break;
21193         case OPC_SUBQH_W:
21194             gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
21195             break;
21196         case OPC_SUBQH_R_W:
21197             gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
21198             break;
21199         }
21200         break;
21201     case OPC_ABSQ_S_PH_DSP:
21202         switch (op2) {
21203         case OPC_ABSQ_S_QB:
21204             check_dsp_r2(ctx);
21205             gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
21206             break;
21207         case OPC_ABSQ_S_PH:
21208             check_dsp(ctx);
21209             gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
21210             break;
21211         case OPC_ABSQ_S_W:
21212             check_dsp(ctx);
21213             gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
21214             break;
21215         case OPC_PRECEQ_W_PHL:
21216             check_dsp(ctx);
21217             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
21218             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
21219             break;
21220         case OPC_PRECEQ_W_PHR:
21221             check_dsp(ctx);
21222             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
21223             tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
21224             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
21225             break;
21226         case OPC_PRECEQU_PH_QBL:
21227             check_dsp(ctx);
21228             gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
21229             break;
21230         case OPC_PRECEQU_PH_QBR:
21231             check_dsp(ctx);
21232             gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
21233             break;
21234         case OPC_PRECEQU_PH_QBLA:
21235             check_dsp(ctx);
21236             gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
21237             break;
21238         case OPC_PRECEQU_PH_QBRA:
21239             check_dsp(ctx);
21240             gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
21241             break;
21242         case OPC_PRECEU_PH_QBL:
21243             check_dsp(ctx);
21244             gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
21245             break;
21246         case OPC_PRECEU_PH_QBR:
21247             check_dsp(ctx);
21248             gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
21249             break;
21250         case OPC_PRECEU_PH_QBLA:
21251             check_dsp(ctx);
21252             gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
21253             break;
21254         case OPC_PRECEU_PH_QBRA:
21255             check_dsp(ctx);
21256             gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
21257             break;
21258         }
21259         break;
21260     case OPC_ADDU_QB_DSP:
21261         switch (op2) {
21262         case OPC_ADDQ_PH:
21263             check_dsp(ctx);
21264             gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21265             break;
21266         case OPC_ADDQ_S_PH:
21267             check_dsp(ctx);
21268             gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21269             break;
21270         case OPC_ADDQ_S_W:
21271             check_dsp(ctx);
21272             gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21273             break;
21274         case OPC_ADDU_QB:
21275             check_dsp(ctx);
21276             gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21277             break;
21278         case OPC_ADDU_S_QB:
21279             check_dsp(ctx);
21280             gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21281             break;
21282         case OPC_ADDU_PH:
21283             check_dsp_r2(ctx);
21284             gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21285             break;
21286         case OPC_ADDU_S_PH:
21287             check_dsp_r2(ctx);
21288             gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21289             break;
21290         case OPC_SUBQ_PH:
21291             check_dsp(ctx);
21292             gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21293             break;
21294         case OPC_SUBQ_S_PH:
21295             check_dsp(ctx);
21296             gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21297             break;
21298         case OPC_SUBQ_S_W:
21299             check_dsp(ctx);
21300             gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21301             break;
21302         case OPC_SUBU_QB:
21303             check_dsp(ctx);
21304             gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21305             break;
21306         case OPC_SUBU_S_QB:
21307             check_dsp(ctx);
21308             gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21309             break;
21310         case OPC_SUBU_PH:
21311             check_dsp_r2(ctx);
21312             gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21313             break;
21314         case OPC_SUBU_S_PH:
21315             check_dsp_r2(ctx);
21316             gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21317             break;
21318         case OPC_ADDSC:
21319             check_dsp(ctx);
21320             gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21321             break;
21322         case OPC_ADDWC:
21323             check_dsp(ctx);
21324             gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21325             break;
21326         case OPC_MODSUB:
21327             check_dsp(ctx);
21328             gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
21329             break;
21330         case OPC_RADDU_W_QB:
21331             check_dsp(ctx);
21332             gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
21333             break;
21334         }
21335         break;
21336     case OPC_CMPU_EQ_QB_DSP:
21337         switch (op2) {
21338         case OPC_PRECR_QB_PH:
21339             check_dsp_r2(ctx);
21340             gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
21341             break;
21342         case OPC_PRECRQ_QB_PH:
21343             check_dsp(ctx);
21344             gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
21345             break;
21346         case OPC_PRECR_SRA_PH_W:
21347             check_dsp_r2(ctx);
21348             {
21349                 TCGv_i32 sa_t = tcg_const_i32(v2);
21350                 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
21351                                           cpu_gpr[ret]);
21352                 tcg_temp_free_i32(sa_t);
21353                 break;
21354             }
21355         case OPC_PRECR_SRA_R_PH_W:
21356             check_dsp_r2(ctx);
21357             {
21358                 TCGv_i32 sa_t = tcg_const_i32(v2);
21359                 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
21360                                             cpu_gpr[ret]);
21361                 tcg_temp_free_i32(sa_t);
21362                 break;
21363             }
21364         case OPC_PRECRQ_PH_W:
21365             check_dsp(ctx);
21366             gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
21367             break;
21368         case OPC_PRECRQ_RS_PH_W:
21369             check_dsp(ctx);
21370             gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21371             break;
21372         case OPC_PRECRQU_S_QB_PH:
21373             check_dsp(ctx);
21374             gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21375             break;
21376         }
21377         break;
21378 #ifdef TARGET_MIPS64
21379     case OPC_ABSQ_S_QH_DSP:
21380         switch (op2) {
21381         case OPC_PRECEQ_L_PWL:
21382             check_dsp(ctx);
21383             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
21384             break;
21385         case OPC_PRECEQ_L_PWR:
21386             check_dsp(ctx);
21387             tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
21388             break;
21389         case OPC_PRECEQ_PW_QHL:
21390             check_dsp(ctx);
21391             gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
21392             break;
21393         case OPC_PRECEQ_PW_QHR:
21394             check_dsp(ctx);
21395             gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
21396             break;
21397         case OPC_PRECEQ_PW_QHLA:
21398             check_dsp(ctx);
21399             gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
21400             break;
21401         case OPC_PRECEQ_PW_QHRA:
21402             check_dsp(ctx);
21403             gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
21404             break;
21405         case OPC_PRECEQU_QH_OBL:
21406             check_dsp(ctx);
21407             gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
21408             break;
21409         case OPC_PRECEQU_QH_OBR:
21410             check_dsp(ctx);
21411             gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
21412             break;
21413         case OPC_PRECEQU_QH_OBLA:
21414             check_dsp(ctx);
21415             gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
21416             break;
21417         case OPC_PRECEQU_QH_OBRA:
21418             check_dsp(ctx);
21419             gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
21420             break;
21421         case OPC_PRECEU_QH_OBL:
21422             check_dsp(ctx);
21423             gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
21424             break;
21425         case OPC_PRECEU_QH_OBR:
21426             check_dsp(ctx);
21427             gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
21428             break;
21429         case OPC_PRECEU_QH_OBLA:
21430             check_dsp(ctx);
21431             gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
21432             break;
21433         case OPC_PRECEU_QH_OBRA:
21434             check_dsp(ctx);
21435             gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
21436             break;
21437         case OPC_ABSQ_S_OB:
21438             check_dsp_r2(ctx);
21439             gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
21440             break;
21441         case OPC_ABSQ_S_PW:
21442             check_dsp(ctx);
21443             gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
21444             break;
21445         case OPC_ABSQ_S_QH:
21446             check_dsp(ctx);
21447             gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
21448             break;
21449         }
21450         break;
21451     case OPC_ADDU_OB_DSP:
21452         switch (op2) {
21453         case OPC_RADDU_L_OB:
21454             check_dsp(ctx);
21455             gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
21456             break;
21457         case OPC_SUBQ_PW:
21458             check_dsp(ctx);
21459             gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21460             break;
21461         case OPC_SUBQ_S_PW:
21462             check_dsp(ctx);
21463             gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21464             break;
21465         case OPC_SUBQ_QH:
21466             check_dsp(ctx);
21467             gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21468             break;
21469         case OPC_SUBQ_S_QH:
21470             check_dsp(ctx);
21471             gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21472             break;
21473         case OPC_SUBU_OB:
21474             check_dsp(ctx);
21475             gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21476             break;
21477         case OPC_SUBU_S_OB:
21478             check_dsp(ctx);
21479             gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21480             break;
21481         case OPC_SUBU_QH:
21482             check_dsp_r2(ctx);
21483             gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21484             break;
21485         case OPC_SUBU_S_QH:
21486             check_dsp_r2(ctx);
21487             gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21488             break;
21489         case OPC_SUBUH_OB:
21490             check_dsp_r2(ctx);
21491             gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
21492             break;
21493         case OPC_SUBUH_R_OB:
21494             check_dsp_r2(ctx);
21495             gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
21496             break;
21497         case OPC_ADDQ_PW:
21498             check_dsp(ctx);
21499             gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21500             break;
21501         case OPC_ADDQ_S_PW:
21502             check_dsp(ctx);
21503             gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21504             break;
21505         case OPC_ADDQ_QH:
21506             check_dsp(ctx);
21507             gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21508             break;
21509         case OPC_ADDQ_S_QH:
21510             check_dsp(ctx);
21511             gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21512             break;
21513         case OPC_ADDU_OB:
21514             check_dsp(ctx);
21515             gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21516             break;
21517         case OPC_ADDU_S_OB:
21518             check_dsp(ctx);
21519             gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21520             break;
21521         case OPC_ADDU_QH:
21522             check_dsp_r2(ctx);
21523             gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21524             break;
21525         case OPC_ADDU_S_QH:
21526             check_dsp_r2(ctx);
21527             gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21528             break;
21529         case OPC_ADDUH_OB:
21530             check_dsp_r2(ctx);
21531             gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
21532             break;
21533         case OPC_ADDUH_R_OB:
21534             check_dsp_r2(ctx);
21535             gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
21536             break;
21537         }
21538         break;
21539     case OPC_CMPU_EQ_OB_DSP:
21540         switch (op2) {
21541         case OPC_PRECR_OB_QH:
21542             check_dsp_r2(ctx);
21543             gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
21544             break;
21545         case OPC_PRECR_SRA_QH_PW:
21546             check_dsp_r2(ctx);
21547             {
21548                 TCGv_i32 ret_t = tcg_const_i32(ret);
21549                 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
21550                 tcg_temp_free_i32(ret_t);
21551                 break;
21552             }
21553         case OPC_PRECR_SRA_R_QH_PW:
21554             check_dsp_r2(ctx);
21555             {
21556                 TCGv_i32 sa_v = tcg_const_i32(ret);
21557                 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
21558                 tcg_temp_free_i32(sa_v);
21559                 break;
21560             }
21561         case OPC_PRECRQ_OB_QH:
21562             check_dsp(ctx);
21563             gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
21564             break;
21565         case OPC_PRECRQ_PW_L:
21566             check_dsp(ctx);
21567             gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
21568             break;
21569         case OPC_PRECRQ_QH_PW:
21570             check_dsp(ctx);
21571             gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
21572             break;
21573         case OPC_PRECRQ_RS_QH_PW:
21574             check_dsp(ctx);
21575             gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21576             break;
21577         case OPC_PRECRQU_S_OB_QH:
21578             check_dsp(ctx);
21579             gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21580             break;
21581         }
21582         break;
21583 #endif
21584     }
21585
21586     tcg_temp_free(v1_t);
21587     tcg_temp_free(v2_t);
21588 }
21589
21590 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
21591                               int ret, int v1, int v2)
21592 {
21593     uint32_t op2;
21594     TCGv t0;
21595     TCGv v1_t;
21596     TCGv v2_t;
21597
21598     if (ret == 0) {
21599         /* Treat as NOP. */
21600         return;
21601     }
21602
21603     t0 = tcg_temp_new();
21604     v1_t = tcg_temp_new();
21605     v2_t = tcg_temp_new();
21606
21607     tcg_gen_movi_tl(t0, v1);
21608     gen_load_gpr(v1_t, v1);
21609     gen_load_gpr(v2_t, v2);
21610
21611     switch (opc) {
21612     case OPC_SHLL_QB_DSP:
21613         {
21614             op2 = MASK_SHLL_QB(ctx->opcode);
21615             switch (op2) {
21616             case OPC_SHLL_QB:
21617                 check_dsp(ctx);
21618                 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
21619                 break;
21620             case OPC_SHLLV_QB:
21621                 check_dsp(ctx);
21622                 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21623                 break;
21624             case OPC_SHLL_PH:
21625                 check_dsp(ctx);
21626                 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
21627                 break;
21628             case OPC_SHLLV_PH:
21629                 check_dsp(ctx);
21630                 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21631                 break;
21632             case OPC_SHLL_S_PH:
21633                 check_dsp(ctx);
21634                 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
21635                 break;
21636             case OPC_SHLLV_S_PH:
21637                 check_dsp(ctx);
21638                 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21639                 break;
21640             case OPC_SHLL_S_W:
21641                 check_dsp(ctx);
21642                 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
21643                 break;
21644             case OPC_SHLLV_S_W:
21645                 check_dsp(ctx);
21646                 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21647                 break;
21648             case OPC_SHRL_QB:
21649                 check_dsp(ctx);
21650                 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
21651                 break;
21652             case OPC_SHRLV_QB:
21653                 check_dsp(ctx);
21654                 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
21655                 break;
21656             case OPC_SHRL_PH:
21657                 check_dsp_r2(ctx);
21658                 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
21659                 break;
21660             case OPC_SHRLV_PH:
21661                 check_dsp_r2(ctx);
21662                 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
21663                 break;
21664             case OPC_SHRA_QB:
21665                 check_dsp_r2(ctx);
21666                 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
21667                 break;
21668             case OPC_SHRA_R_QB:
21669                 check_dsp_r2(ctx);
21670                 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
21671                 break;
21672             case OPC_SHRAV_QB:
21673                 check_dsp_r2(ctx);
21674                 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
21675                 break;
21676             case OPC_SHRAV_R_QB:
21677                 check_dsp_r2(ctx);
21678                 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
21679                 break;
21680             case OPC_SHRA_PH:
21681                 check_dsp(ctx);
21682                 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
21683                 break;
21684             case OPC_SHRA_R_PH:
21685                 check_dsp(ctx);
21686                 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
21687                 break;
21688             case OPC_SHRAV_PH:
21689                 check_dsp(ctx);
21690                 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
21691                 break;
21692             case OPC_SHRAV_R_PH:
21693                 check_dsp(ctx);
21694                 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
21695                 break;
21696             case OPC_SHRA_R_W:
21697                 check_dsp(ctx);
21698                 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
21699                 break;
21700             case OPC_SHRAV_R_W:
21701                 check_dsp(ctx);
21702                 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
21703                 break;
21704             default:            /* Invalid */
21705                 MIPS_INVAL("MASK SHLL.QB");
21706                 generate_exception_end(ctx, EXCP_RI);
21707                 break;
21708             }
21709             break;
21710         }
21711 #ifdef TARGET_MIPS64
21712     case OPC_SHLL_OB_DSP:
21713         op2 = MASK_SHLL_OB(ctx->opcode);
21714         switch (op2) {
21715         case OPC_SHLL_PW:
21716             check_dsp(ctx);
21717             gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
21718             break;
21719         case OPC_SHLLV_PW:
21720             check_dsp(ctx);
21721             gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
21722             break;
21723         case OPC_SHLL_S_PW:
21724             check_dsp(ctx);
21725             gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
21726             break;
21727         case OPC_SHLLV_S_PW:
21728             check_dsp(ctx);
21729             gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
21730             break;
21731         case OPC_SHLL_OB:
21732             check_dsp(ctx);
21733             gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
21734             break;
21735         case OPC_SHLLV_OB:
21736             check_dsp(ctx);
21737             gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
21738             break;
21739         case OPC_SHLL_QH:
21740             check_dsp(ctx);
21741             gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
21742             break;
21743         case OPC_SHLLV_QH:
21744             check_dsp(ctx);
21745             gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
21746             break;
21747         case OPC_SHLL_S_QH:
21748             check_dsp(ctx);
21749             gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
21750             break;
21751         case OPC_SHLLV_S_QH:
21752             check_dsp(ctx);
21753             gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
21754             break;
21755         case OPC_SHRA_OB:
21756             check_dsp_r2(ctx);
21757             gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
21758             break;
21759         case OPC_SHRAV_OB:
21760             check_dsp_r2(ctx);
21761             gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
21762             break;
21763         case OPC_SHRA_R_OB:
21764             check_dsp_r2(ctx);
21765             gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
21766             break;
21767         case OPC_SHRAV_R_OB:
21768             check_dsp_r2(ctx);
21769             gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
21770             break;
21771         case OPC_SHRA_PW:
21772             check_dsp(ctx);
21773             gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
21774             break;
21775         case OPC_SHRAV_PW:
21776             check_dsp(ctx);
21777             gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
21778             break;
21779         case OPC_SHRA_R_PW:
21780             check_dsp(ctx);
21781             gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
21782             break;
21783         case OPC_SHRAV_R_PW:
21784             check_dsp(ctx);
21785             gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
21786             break;
21787         case OPC_SHRA_QH:
21788             check_dsp(ctx);
21789             gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
21790             break;
21791         case OPC_SHRAV_QH:
21792             check_dsp(ctx);
21793             gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
21794             break;
21795         case OPC_SHRA_R_QH:
21796             check_dsp(ctx);
21797             gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
21798             break;
21799         case OPC_SHRAV_R_QH:
21800             check_dsp(ctx);
21801             gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
21802             break;
21803         case OPC_SHRL_OB:
21804             check_dsp(ctx);
21805             gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
21806             break;
21807         case OPC_SHRLV_OB:
21808             check_dsp(ctx);
21809             gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
21810             break;
21811         case OPC_SHRL_QH:
21812             check_dsp_r2(ctx);
21813             gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
21814             break;
21815         case OPC_SHRLV_QH:
21816             check_dsp_r2(ctx);
21817             gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
21818             break;
21819         default:            /* Invalid */
21820             MIPS_INVAL("MASK SHLL.OB");
21821             generate_exception_end(ctx, EXCP_RI);
21822             break;
21823         }
21824         break;
21825 #endif
21826     }
21827
21828     tcg_temp_free(t0);
21829     tcg_temp_free(v1_t);
21830     tcg_temp_free(v2_t);
21831 }
21832
21833 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
21834                                  int ret, int v1, int v2, int check_ret)
21835 {
21836     TCGv_i32 t0;
21837     TCGv v1_t;
21838     TCGv v2_t;
21839
21840     if ((ret == 0) && (check_ret == 1)) {
21841         /* Treat as NOP. */
21842         return;
21843     }
21844
21845     t0 = tcg_temp_new_i32();
21846     v1_t = tcg_temp_new();
21847     v2_t = tcg_temp_new();
21848
21849     tcg_gen_movi_i32(t0, ret);
21850     gen_load_gpr(v1_t, v1);
21851     gen_load_gpr(v2_t, v2);
21852
21853     switch (op1) {
21854     /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
21855      * the same mask and op1. */
21856     case OPC_MULT_G_2E:
21857         check_dsp_r2(ctx);
21858         switch (op2) {
21859         case  OPC_MUL_PH:
21860             gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21861             break;
21862         case  OPC_MUL_S_PH:
21863             gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21864             break;
21865         case OPC_MULQ_S_W:
21866             gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21867             break;
21868         case OPC_MULQ_RS_W:
21869             gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21870             break;
21871         }
21872         break;
21873     case OPC_DPA_W_PH_DSP:
21874         switch (op2) {
21875         case OPC_DPAU_H_QBL:
21876             check_dsp(ctx);
21877             gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
21878             break;
21879         case OPC_DPAU_H_QBR:
21880             check_dsp(ctx);
21881             gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
21882             break;
21883         case OPC_DPSU_H_QBL:
21884             check_dsp(ctx);
21885             gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
21886             break;
21887         case OPC_DPSU_H_QBR:
21888             check_dsp(ctx);
21889             gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
21890             break;
21891         case OPC_DPA_W_PH:
21892             check_dsp_r2(ctx);
21893             gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
21894             break;
21895         case OPC_DPAX_W_PH:
21896             check_dsp_r2(ctx);
21897             gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
21898             break;
21899         case OPC_DPAQ_S_W_PH:
21900             check_dsp(ctx);
21901             gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
21902             break;
21903         case OPC_DPAQX_S_W_PH:
21904             check_dsp_r2(ctx);
21905             gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
21906             break;
21907         case OPC_DPAQX_SA_W_PH:
21908             check_dsp_r2(ctx);
21909             gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
21910             break;
21911         case OPC_DPS_W_PH:
21912             check_dsp_r2(ctx);
21913             gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
21914             break;
21915         case OPC_DPSX_W_PH:
21916             check_dsp_r2(ctx);
21917             gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
21918             break;
21919         case OPC_DPSQ_S_W_PH:
21920             check_dsp(ctx);
21921             gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
21922             break;
21923         case OPC_DPSQX_S_W_PH:
21924             check_dsp_r2(ctx);
21925             gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
21926             break;
21927         case OPC_DPSQX_SA_W_PH:
21928             check_dsp_r2(ctx);
21929             gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
21930             break;
21931         case OPC_MULSAQ_S_W_PH:
21932             check_dsp(ctx);
21933             gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
21934             break;
21935         case OPC_DPAQ_SA_L_W:
21936             check_dsp(ctx);
21937             gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
21938             break;
21939         case OPC_DPSQ_SA_L_W:
21940             check_dsp(ctx);
21941             gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
21942             break;
21943         case OPC_MAQ_S_W_PHL:
21944             check_dsp(ctx);
21945             gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
21946             break;
21947         case OPC_MAQ_S_W_PHR:
21948             check_dsp(ctx);
21949             gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
21950             break;
21951         case OPC_MAQ_SA_W_PHL:
21952             check_dsp(ctx);
21953             gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
21954             break;
21955         case OPC_MAQ_SA_W_PHR:
21956             check_dsp(ctx);
21957             gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
21958             break;
21959         case OPC_MULSA_W_PH:
21960             check_dsp_r2(ctx);
21961             gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
21962             break;
21963         }
21964         break;
21965 #ifdef TARGET_MIPS64
21966     case OPC_DPAQ_W_QH_DSP:
21967         {
21968             int ac = ret & 0x03;
21969             tcg_gen_movi_i32(t0, ac);
21970
21971             switch (op2) {
21972             case OPC_DMADD:
21973                 check_dsp(ctx);
21974                 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
21975                 break;
21976             case OPC_DMADDU:
21977                 check_dsp(ctx);
21978                 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
21979                 break;
21980             case OPC_DMSUB:
21981                 check_dsp(ctx);
21982                 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
21983                 break;
21984             case OPC_DMSUBU:
21985                 check_dsp(ctx);
21986                 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
21987                 break;
21988             case OPC_DPA_W_QH:
21989                 check_dsp_r2(ctx);
21990                 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
21991                 break;
21992             case OPC_DPAQ_S_W_QH:
21993                 check_dsp(ctx);
21994                 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
21995                 break;
21996             case OPC_DPAQ_SA_L_PW:
21997                 check_dsp(ctx);
21998                 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
21999                 break;
22000             case OPC_DPAU_H_OBL:
22001                 check_dsp(ctx);
22002                 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
22003                 break;
22004             case OPC_DPAU_H_OBR:
22005                 check_dsp(ctx);
22006                 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
22007                 break;
22008             case OPC_DPS_W_QH:
22009                 check_dsp_r2(ctx);
22010                 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
22011                 break;
22012             case OPC_DPSQ_S_W_QH:
22013                 check_dsp(ctx);
22014                 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22015                 break;
22016             case OPC_DPSQ_SA_L_PW:
22017                 check_dsp(ctx);
22018                 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
22019                 break;
22020             case OPC_DPSU_H_OBL:
22021                 check_dsp(ctx);
22022                 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
22023                 break;
22024             case OPC_DPSU_H_OBR:
22025                 check_dsp(ctx);
22026                 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
22027                 break;
22028             case OPC_MAQ_S_L_PWL:
22029                 check_dsp(ctx);
22030                 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
22031                 break;
22032             case OPC_MAQ_S_L_PWR:
22033                 check_dsp(ctx);
22034                 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
22035                 break;
22036             case OPC_MAQ_S_W_QHLL:
22037                 check_dsp(ctx);
22038                 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
22039                 break;
22040             case OPC_MAQ_SA_W_QHLL:
22041                 check_dsp(ctx);
22042                 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
22043                 break;
22044             case OPC_MAQ_S_W_QHLR:
22045                 check_dsp(ctx);
22046                 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
22047                 break;
22048             case OPC_MAQ_SA_W_QHLR:
22049                 check_dsp(ctx);
22050                 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
22051                 break;
22052             case OPC_MAQ_S_W_QHRL:
22053                 check_dsp(ctx);
22054                 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
22055                 break;
22056             case OPC_MAQ_SA_W_QHRL:
22057                 check_dsp(ctx);
22058                 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
22059                 break;
22060             case OPC_MAQ_S_W_QHRR:
22061                 check_dsp(ctx);
22062                 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
22063                 break;
22064             case OPC_MAQ_SA_W_QHRR:
22065                 check_dsp(ctx);
22066                 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
22067                 break;
22068             case OPC_MULSAQ_S_L_PW:
22069                 check_dsp(ctx);
22070                 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
22071                 break;
22072             case OPC_MULSAQ_S_W_QH:
22073                 check_dsp(ctx);
22074                 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22075                 break;
22076             }
22077         }
22078         break;
22079 #endif
22080     case OPC_ADDU_QB_DSP:
22081         switch (op2) {
22082         case OPC_MULEU_S_PH_QBL:
22083             check_dsp(ctx);
22084             gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22085             break;
22086         case OPC_MULEU_S_PH_QBR:
22087             check_dsp(ctx);
22088             gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22089             break;
22090         case OPC_MULQ_RS_PH:
22091             check_dsp(ctx);
22092             gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22093             break;
22094         case OPC_MULEQ_S_W_PHL:
22095             check_dsp(ctx);
22096             gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22097             break;
22098         case OPC_MULEQ_S_W_PHR:
22099             check_dsp(ctx);
22100             gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22101             break;
22102         case OPC_MULQ_S_PH:
22103             check_dsp_r2(ctx);
22104             gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22105             break;
22106         }
22107         break;
22108 #ifdef TARGET_MIPS64
22109     case OPC_ADDU_OB_DSP:
22110         switch (op2) {
22111         case OPC_MULEQ_S_PW_QHL:
22112             check_dsp(ctx);
22113             gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22114             break;
22115         case OPC_MULEQ_S_PW_QHR:
22116             check_dsp(ctx);
22117             gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22118             break;
22119         case OPC_MULEU_S_QH_OBL:
22120             check_dsp(ctx);
22121             gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22122             break;
22123         case OPC_MULEU_S_QH_OBR:
22124             check_dsp(ctx);
22125             gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22126             break;
22127         case OPC_MULQ_RS_QH:
22128             check_dsp(ctx);
22129             gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22130             break;
22131         }
22132         break;
22133 #endif
22134     }
22135
22136     tcg_temp_free_i32(t0);
22137     tcg_temp_free(v1_t);
22138     tcg_temp_free(v2_t);
22139 }
22140
22141 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
22142                                 int ret, int val)
22143 {
22144     int16_t imm;
22145     TCGv t0;
22146     TCGv val_t;
22147
22148     if (ret == 0) {
22149         /* Treat as NOP. */
22150         return;
22151     }
22152
22153     t0 = tcg_temp_new();
22154     val_t = tcg_temp_new();
22155     gen_load_gpr(val_t, val);
22156
22157     switch (op1) {
22158     case OPC_ABSQ_S_PH_DSP:
22159         switch (op2) {
22160         case OPC_BITREV:
22161             check_dsp(ctx);
22162             gen_helper_bitrev(cpu_gpr[ret], val_t);
22163             break;
22164         case OPC_REPL_QB:
22165             check_dsp(ctx);
22166             {
22167                 target_long result;
22168                 imm = (ctx->opcode >> 16) & 0xFF;
22169                 result = (uint32_t)imm << 24 |
22170                          (uint32_t)imm << 16 |
22171                          (uint32_t)imm << 8  |
22172                          (uint32_t)imm;
22173                 result = (int32_t)result;
22174                 tcg_gen_movi_tl(cpu_gpr[ret], result);
22175             }
22176             break;
22177         case OPC_REPLV_QB:
22178             check_dsp(ctx);
22179             tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
22180             tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
22181             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22182             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
22183             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22184             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22185             break;
22186         case OPC_REPL_PH:
22187             check_dsp(ctx);
22188             {
22189                 imm = (ctx->opcode >> 16) & 0x03FF;
22190                 imm = (int16_t)(imm << 6) >> 6;
22191                 tcg_gen_movi_tl(cpu_gpr[ret], \
22192                                 (target_long)((int32_t)imm << 16 | \
22193                                 (uint16_t)imm));
22194             }
22195             break;
22196         case OPC_REPLV_PH:
22197             check_dsp(ctx);
22198             tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
22199             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
22200             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22201             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22202             break;
22203         }
22204         break;
22205 #ifdef TARGET_MIPS64
22206     case OPC_ABSQ_S_QH_DSP:
22207         switch (op2) {
22208         case OPC_REPL_OB:
22209             check_dsp(ctx);
22210             {
22211                 target_long temp;
22212
22213                 imm = (ctx->opcode >> 16) & 0xFF;
22214                 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
22215                 temp = (temp << 16) | temp;
22216                 temp = (temp << 32) | temp;
22217                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
22218                 break;
22219             }
22220         case OPC_REPL_PW:
22221             check_dsp(ctx);
22222             {
22223                 target_long temp;
22224
22225                 imm = (ctx->opcode >> 16) & 0x03FF;
22226                 imm = (int16_t)(imm << 6) >> 6;
22227                 temp = ((target_long)imm << 32) \
22228                        | ((target_long)imm & 0xFFFFFFFF);
22229                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
22230                 break;
22231             }
22232         case OPC_REPL_QH:
22233             check_dsp(ctx);
22234             {
22235                 target_long temp;
22236
22237                 imm = (ctx->opcode >> 16) & 0x03FF;
22238                 imm = (int16_t)(imm << 6) >> 6;
22239
22240                 temp = ((uint64_t)(uint16_t)imm << 48) |
22241                        ((uint64_t)(uint16_t)imm << 32) |
22242                        ((uint64_t)(uint16_t)imm << 16) |
22243                        (uint64_t)(uint16_t)imm;
22244                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
22245                 break;
22246             }
22247         case OPC_REPLV_OB:
22248             check_dsp(ctx);
22249             tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
22250             tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
22251             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22252             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
22253             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22254             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
22255             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22256             break;
22257         case OPC_REPLV_PW:
22258             check_dsp(ctx);
22259             tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
22260             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
22261             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22262             break;
22263         case OPC_REPLV_QH:
22264             check_dsp(ctx);
22265             tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
22266             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
22267             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22268             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
22269             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22270             break;
22271         }
22272         break;
22273 #endif
22274     }
22275     tcg_temp_free(t0);
22276     tcg_temp_free(val_t);
22277 }
22278
22279 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
22280                                      uint32_t op1, uint32_t op2,
22281                                      int ret, int v1, int v2, int check_ret)
22282 {
22283     TCGv t1;
22284     TCGv v1_t;
22285     TCGv v2_t;
22286
22287     if ((ret == 0) && (check_ret == 1)) {
22288         /* Treat as NOP. */
22289         return;
22290     }
22291
22292     t1 = tcg_temp_new();
22293     v1_t = tcg_temp_new();
22294     v2_t = tcg_temp_new();
22295
22296     gen_load_gpr(v1_t, v1);
22297     gen_load_gpr(v2_t, v2);
22298
22299     switch (op1) {
22300     case OPC_CMPU_EQ_QB_DSP:
22301         switch (op2) {
22302         case OPC_CMPU_EQ_QB:
22303             check_dsp(ctx);
22304             gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
22305             break;
22306         case OPC_CMPU_LT_QB:
22307             check_dsp(ctx);
22308             gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
22309             break;
22310         case OPC_CMPU_LE_QB:
22311             check_dsp(ctx);
22312             gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
22313             break;
22314         case OPC_CMPGU_EQ_QB:
22315             check_dsp(ctx);
22316             gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
22317             break;
22318         case OPC_CMPGU_LT_QB:
22319             check_dsp(ctx);
22320             gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
22321             break;
22322         case OPC_CMPGU_LE_QB:
22323             check_dsp(ctx);
22324             gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
22325             break;
22326         case OPC_CMPGDU_EQ_QB:
22327             check_dsp_r2(ctx);
22328             gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
22329             tcg_gen_mov_tl(cpu_gpr[ret], t1);
22330             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
22331             tcg_gen_shli_tl(t1, t1, 24);
22332             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
22333             break;
22334         case OPC_CMPGDU_LT_QB:
22335             check_dsp_r2(ctx);
22336             gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
22337             tcg_gen_mov_tl(cpu_gpr[ret], t1);
22338             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
22339             tcg_gen_shli_tl(t1, t1, 24);
22340             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
22341             break;
22342         case OPC_CMPGDU_LE_QB:
22343             check_dsp_r2(ctx);
22344             gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
22345             tcg_gen_mov_tl(cpu_gpr[ret], t1);
22346             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
22347             tcg_gen_shli_tl(t1, t1, 24);
22348             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
22349             break;
22350         case OPC_CMP_EQ_PH:
22351             check_dsp(ctx);
22352             gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
22353             break;
22354         case OPC_CMP_LT_PH:
22355             check_dsp(ctx);
22356             gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
22357             break;
22358         case OPC_CMP_LE_PH:
22359             check_dsp(ctx);
22360             gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
22361             break;
22362         case OPC_PICK_QB:
22363             check_dsp(ctx);
22364             gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22365             break;
22366         case OPC_PICK_PH:
22367             check_dsp(ctx);
22368             gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22369             break;
22370         case OPC_PACKRL_PH:
22371             check_dsp(ctx);
22372             gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
22373             break;
22374         }
22375         break;
22376 #ifdef TARGET_MIPS64
22377     case OPC_CMPU_EQ_OB_DSP:
22378         switch (op2) {
22379         case OPC_CMP_EQ_PW:
22380             check_dsp(ctx);
22381             gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
22382             break;
22383         case OPC_CMP_LT_PW:
22384             check_dsp(ctx);
22385             gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
22386             break;
22387         case OPC_CMP_LE_PW:
22388             check_dsp(ctx);
22389             gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
22390             break;
22391         case OPC_CMP_EQ_QH:
22392             check_dsp(ctx);
22393             gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
22394             break;
22395         case OPC_CMP_LT_QH:
22396             check_dsp(ctx);
22397             gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
22398             break;
22399         case OPC_CMP_LE_QH:
22400             check_dsp(ctx);
22401             gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
22402             break;
22403         case OPC_CMPGDU_EQ_OB:
22404             check_dsp_r2(ctx);
22405             gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22406             break;
22407         case OPC_CMPGDU_LT_OB:
22408             check_dsp_r2(ctx);
22409             gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22410             break;
22411         case OPC_CMPGDU_LE_OB:
22412             check_dsp_r2(ctx);
22413             gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22414             break;
22415         case OPC_CMPGU_EQ_OB:
22416             check_dsp(ctx);
22417             gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
22418             break;
22419         case OPC_CMPGU_LT_OB:
22420             check_dsp(ctx);
22421             gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
22422             break;
22423         case OPC_CMPGU_LE_OB:
22424             check_dsp(ctx);
22425             gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
22426             break;
22427         case OPC_CMPU_EQ_OB:
22428             check_dsp(ctx);
22429             gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
22430             break;
22431         case OPC_CMPU_LT_OB:
22432             check_dsp(ctx);
22433             gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
22434             break;
22435         case OPC_CMPU_LE_OB:
22436             check_dsp(ctx);
22437             gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
22438             break;
22439         case OPC_PACKRL_PW:
22440             check_dsp(ctx);
22441             gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
22442             break;
22443         case OPC_PICK_OB:
22444             check_dsp(ctx);
22445             gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22446             break;
22447         case OPC_PICK_PW:
22448             check_dsp(ctx);
22449             gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22450             break;
22451         case OPC_PICK_QH:
22452             check_dsp(ctx);
22453             gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22454             break;
22455         }
22456         break;
22457 #endif
22458     }
22459
22460     tcg_temp_free(t1);
22461     tcg_temp_free(v1_t);
22462     tcg_temp_free(v2_t);
22463 }
22464
22465 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
22466                                uint32_t op1, int rt, int rs, int sa)
22467 {
22468     TCGv t0;
22469
22470     check_dsp_r2(ctx);
22471
22472     if (rt == 0) {
22473         /* Treat as NOP. */
22474         return;
22475     }
22476
22477     t0 = tcg_temp_new();
22478     gen_load_gpr(t0, rs);
22479
22480     switch (op1) {
22481     case OPC_APPEND_DSP:
22482         switch (MASK_APPEND(ctx->opcode)) {
22483         case OPC_APPEND:
22484             if (sa != 0) {
22485                 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
22486             }
22487             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
22488             break;
22489         case OPC_PREPEND:
22490             if (sa != 0) {
22491                 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
22492                 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
22493                 tcg_gen_shli_tl(t0, t0, 32 - sa);
22494                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
22495             }
22496             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
22497             break;
22498         case OPC_BALIGN:
22499             sa &= 3;
22500             if (sa != 0 && sa != 2) {
22501                 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
22502                 tcg_gen_ext32u_tl(t0, t0);
22503                 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
22504                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
22505             }
22506             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
22507             break;
22508         default:            /* Invalid */
22509             MIPS_INVAL("MASK APPEND");
22510             generate_exception_end(ctx, EXCP_RI);
22511             break;
22512         }
22513         break;
22514 #ifdef TARGET_MIPS64
22515     case OPC_DAPPEND_DSP:
22516         switch (MASK_DAPPEND(ctx->opcode)) {
22517         case OPC_DAPPEND:
22518             if (sa != 0) {
22519                 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
22520             }
22521             break;
22522         case OPC_PREPENDD:
22523             tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
22524             tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
22525             tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
22526             break;
22527         case OPC_PREPENDW:
22528             if (sa != 0) {
22529                 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
22530                 tcg_gen_shli_tl(t0, t0, 64 - sa);
22531                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
22532             }
22533             break;
22534         case OPC_DBALIGN:
22535             sa &= 7;
22536             if (sa != 0 && sa != 2 && sa != 4) {
22537                 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
22538                 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
22539                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
22540             }
22541             break;
22542         default:            /* Invalid */
22543             MIPS_INVAL("MASK DAPPEND");
22544             generate_exception_end(ctx, EXCP_RI);
22545             break;
22546         }
22547         break;
22548 #endif
22549     }
22550     tcg_temp_free(t0);
22551 }
22552
22553 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
22554                                 int ret, int v1, int v2, int check_ret)
22555
22556 {
22557     TCGv t0;
22558     TCGv t1;
22559     TCGv v1_t;
22560     TCGv v2_t;
22561     int16_t imm;
22562
22563     if ((ret == 0) && (check_ret == 1)) {
22564         /* Treat as NOP. */
22565         return;
22566     }
22567
22568     t0 = tcg_temp_new();
22569     t1 = tcg_temp_new();
22570     v1_t = tcg_temp_new();
22571     v2_t = tcg_temp_new();
22572
22573     gen_load_gpr(v1_t, v1);
22574     gen_load_gpr(v2_t, v2);
22575
22576     switch (op1) {
22577     case OPC_EXTR_W_DSP:
22578         check_dsp(ctx);
22579         switch (op2) {
22580         case OPC_EXTR_W:
22581             tcg_gen_movi_tl(t0, v2);
22582             tcg_gen_movi_tl(t1, v1);
22583             gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
22584             break;
22585         case OPC_EXTR_R_W:
22586             tcg_gen_movi_tl(t0, v2);
22587             tcg_gen_movi_tl(t1, v1);
22588             gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
22589             break;
22590         case OPC_EXTR_RS_W:
22591             tcg_gen_movi_tl(t0, v2);
22592             tcg_gen_movi_tl(t1, v1);
22593             gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
22594             break;
22595         case OPC_EXTR_S_H:
22596             tcg_gen_movi_tl(t0, v2);
22597             tcg_gen_movi_tl(t1, v1);
22598             gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
22599             break;
22600         case OPC_EXTRV_S_H:
22601             tcg_gen_movi_tl(t0, v2);
22602             gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
22603             break;
22604         case OPC_EXTRV_W:
22605             tcg_gen_movi_tl(t0, v2);
22606             gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
22607             break;
22608         case OPC_EXTRV_R_W:
22609             tcg_gen_movi_tl(t0, v2);
22610             gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
22611             break;
22612         case OPC_EXTRV_RS_W:
22613             tcg_gen_movi_tl(t0, v2);
22614             gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
22615             break;
22616         case OPC_EXTP:
22617             tcg_gen_movi_tl(t0, v2);
22618             tcg_gen_movi_tl(t1, v1);
22619             gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
22620             break;
22621         case OPC_EXTPV:
22622             tcg_gen_movi_tl(t0, v2);
22623             gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
22624             break;
22625         case OPC_EXTPDP:
22626             tcg_gen_movi_tl(t0, v2);
22627             tcg_gen_movi_tl(t1, v1);
22628             gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
22629             break;
22630         case OPC_EXTPDPV:
22631             tcg_gen_movi_tl(t0, v2);
22632             gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
22633             break;
22634         case OPC_SHILO:
22635             imm = (ctx->opcode >> 20) & 0x3F;
22636             tcg_gen_movi_tl(t0, ret);
22637             tcg_gen_movi_tl(t1, imm);
22638             gen_helper_shilo(t0, t1, cpu_env);
22639             break;
22640         case OPC_SHILOV:
22641             tcg_gen_movi_tl(t0, ret);
22642             gen_helper_shilo(t0, v1_t, cpu_env);
22643             break;
22644         case OPC_MTHLIP:
22645             tcg_gen_movi_tl(t0, ret);
22646             gen_helper_mthlip(t0, v1_t, cpu_env);
22647             break;
22648         case OPC_WRDSP:
22649             imm = (ctx->opcode >> 11) & 0x3FF;
22650             tcg_gen_movi_tl(t0, imm);
22651             gen_helper_wrdsp(v1_t, t0, cpu_env);
22652             break;
22653         case OPC_RDDSP:
22654             imm = (ctx->opcode >> 16) & 0x03FF;
22655             tcg_gen_movi_tl(t0, imm);
22656             gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
22657             break;
22658         }
22659         break;
22660 #ifdef TARGET_MIPS64
22661     case OPC_DEXTR_W_DSP:
22662         check_dsp(ctx);
22663         switch (op2) {
22664         case OPC_DMTHLIP:
22665             tcg_gen_movi_tl(t0, ret);
22666             gen_helper_dmthlip(v1_t, t0, cpu_env);
22667             break;
22668         case OPC_DSHILO:
22669             {
22670                 int shift = (ctx->opcode >> 19) & 0x7F;
22671                 int ac = (ctx->opcode >> 11) & 0x03;
22672                 tcg_gen_movi_tl(t0, shift);
22673                 tcg_gen_movi_tl(t1, ac);
22674                 gen_helper_dshilo(t0, t1, cpu_env);
22675                 break;
22676             }
22677         case OPC_DSHILOV:
22678             {
22679                 int ac = (ctx->opcode >> 11) & 0x03;
22680                 tcg_gen_movi_tl(t0, ac);
22681                 gen_helper_dshilo(v1_t, t0, cpu_env);
22682                 break;
22683             }
22684         case OPC_DEXTP:
22685             tcg_gen_movi_tl(t0, v2);
22686             tcg_gen_movi_tl(t1, v1);
22687
22688             gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
22689             break;
22690         case OPC_DEXTPV:
22691             tcg_gen_movi_tl(t0, v2);
22692             gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
22693             break;
22694         case OPC_DEXTPDP:
22695             tcg_gen_movi_tl(t0, v2);
22696             tcg_gen_movi_tl(t1, v1);
22697             gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
22698             break;
22699         case OPC_DEXTPDPV:
22700             tcg_gen_movi_tl(t0, v2);
22701             gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
22702             break;
22703         case OPC_DEXTR_L:
22704             tcg_gen_movi_tl(t0, v2);
22705             tcg_gen_movi_tl(t1, v1);
22706             gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
22707             break;
22708         case OPC_DEXTR_R_L:
22709             tcg_gen_movi_tl(t0, v2);
22710             tcg_gen_movi_tl(t1, v1);
22711             gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
22712             break;
22713         case OPC_DEXTR_RS_L:
22714             tcg_gen_movi_tl(t0, v2);
22715             tcg_gen_movi_tl(t1, v1);
22716             gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
22717             break;
22718         case OPC_DEXTR_W:
22719             tcg_gen_movi_tl(t0, v2);
22720             tcg_gen_movi_tl(t1, v1);
22721             gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
22722             break;
22723         case OPC_DEXTR_R_W:
22724             tcg_gen_movi_tl(t0, v2);
22725             tcg_gen_movi_tl(t1, v1);
22726             gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
22727             break;
22728         case OPC_DEXTR_RS_W:
22729             tcg_gen_movi_tl(t0, v2);
22730             tcg_gen_movi_tl(t1, v1);
22731             gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
22732             break;
22733         case OPC_DEXTR_S_H:
22734             tcg_gen_movi_tl(t0, v2);
22735             tcg_gen_movi_tl(t1, v1);
22736             gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
22737             break;
22738         case OPC_DEXTRV_S_H:
22739             tcg_gen_movi_tl(t0, v2);
22740             tcg_gen_movi_tl(t1, v1);
22741             gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
22742             break;
22743         case OPC_DEXTRV_L:
22744             tcg_gen_movi_tl(t0, v2);
22745             gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
22746             break;
22747         case OPC_DEXTRV_R_L:
22748             tcg_gen_movi_tl(t0, v2);
22749             gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
22750             break;
22751         case OPC_DEXTRV_RS_L:
22752             tcg_gen_movi_tl(t0, v2);
22753             gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
22754             break;
22755         case OPC_DEXTRV_W:
22756             tcg_gen_movi_tl(t0, v2);
22757             gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
22758             break;
22759         case OPC_DEXTRV_R_W:
22760             tcg_gen_movi_tl(t0, v2);
22761             gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
22762             break;
22763         case OPC_DEXTRV_RS_W:
22764             tcg_gen_movi_tl(t0, v2);
22765             gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
22766             break;
22767         }
22768         break;
22769 #endif
22770     }
22771
22772     tcg_temp_free(t0);
22773     tcg_temp_free(t1);
22774     tcg_temp_free(v1_t);
22775     tcg_temp_free(v2_t);
22776 }
22777
22778 /* End MIPSDSP functions. */
22779
22780 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
22781 {
22782     int rs, rt, rd, sa;
22783     uint32_t op1, op2;
22784
22785     rs = (ctx->opcode >> 21) & 0x1f;
22786     rt = (ctx->opcode >> 16) & 0x1f;
22787     rd = (ctx->opcode >> 11) & 0x1f;
22788     sa = (ctx->opcode >> 6) & 0x1f;
22789
22790     op1 = MASK_SPECIAL(ctx->opcode);
22791     switch (op1) {
22792     case OPC_LSA:
22793         gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
22794         break;
22795     case OPC_MULT:
22796     case OPC_MULTU:
22797     case OPC_DIV:
22798     case OPC_DIVU:
22799         op2 = MASK_R6_MULDIV(ctx->opcode);
22800         switch (op2) {
22801         case R6_OPC_MUL:
22802         case R6_OPC_MUH:
22803         case R6_OPC_MULU:
22804         case R6_OPC_MUHU:
22805         case R6_OPC_DIV:
22806         case R6_OPC_MOD:
22807         case R6_OPC_DIVU:
22808         case R6_OPC_MODU:
22809             gen_r6_muldiv(ctx, op2, rd, rs, rt);
22810             break;
22811         default:
22812             MIPS_INVAL("special_r6 muldiv");
22813             generate_exception_end(ctx, EXCP_RI);
22814             break;
22815         }
22816         break;
22817     case OPC_SELEQZ:
22818     case OPC_SELNEZ:
22819         gen_cond_move(ctx, op1, rd, rs, rt);
22820         break;
22821     case R6_OPC_CLO:
22822     case R6_OPC_CLZ:
22823         if (rt == 0 && sa == 1) {
22824             /* Major opcode and function field is shared with preR6 MFHI/MTHI.
22825                We need additionally to check other fields */
22826             gen_cl(ctx, op1, rd, rs);
22827         } else {
22828             generate_exception_end(ctx, EXCP_RI);
22829         }
22830         break;
22831     case R6_OPC_SDBBP:
22832         if (is_uhi(extract32(ctx->opcode, 6, 20))) {
22833             gen_helper_do_semihosting(cpu_env);
22834         } else {
22835             if (ctx->hflags & MIPS_HFLAG_SBRI) {
22836                 generate_exception_end(ctx, EXCP_RI);
22837             } else {
22838                 generate_exception_end(ctx, EXCP_DBp);
22839             }
22840         }
22841         break;
22842 #if defined(TARGET_MIPS64)
22843     case OPC_DLSA:
22844         check_mips_64(ctx);
22845         gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
22846         break;
22847     case R6_OPC_DCLO:
22848     case R6_OPC_DCLZ:
22849         if (rt == 0 && sa == 1) {
22850             /* Major opcode and function field is shared with preR6 MFHI/MTHI.
22851                We need additionally to check other fields */
22852             check_mips_64(ctx);
22853             gen_cl(ctx, op1, rd, rs);
22854         } else {
22855             generate_exception_end(ctx, EXCP_RI);
22856         }
22857         break;
22858     case OPC_DMULT:
22859     case OPC_DMULTU:
22860     case OPC_DDIV:
22861     case OPC_DDIVU:
22862
22863         op2 = MASK_R6_MULDIV(ctx->opcode);
22864         switch (op2) {
22865         case R6_OPC_DMUL:
22866         case R6_OPC_DMUH:
22867         case R6_OPC_DMULU:
22868         case R6_OPC_DMUHU:
22869         case R6_OPC_DDIV:
22870         case R6_OPC_DMOD:
22871         case R6_OPC_DDIVU:
22872         case R6_OPC_DMODU:
22873             check_mips_64(ctx);
22874             gen_r6_muldiv(ctx, op2, rd, rs, rt);
22875             break;
22876         default:
22877             MIPS_INVAL("special_r6 muldiv");
22878             generate_exception_end(ctx, EXCP_RI);
22879             break;
22880         }
22881         break;
22882 #endif
22883     default:            /* Invalid */
22884         MIPS_INVAL("special_r6");
22885         generate_exception_end(ctx, EXCP_RI);
22886         break;
22887     }
22888 }
22889
22890 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
22891 {
22892     int rs, rt, rd, sa;
22893     uint32_t op1;
22894
22895     rs = (ctx->opcode >> 21) & 0x1f;
22896     rt = (ctx->opcode >> 16) & 0x1f;
22897     rd = (ctx->opcode >> 11) & 0x1f;
22898     sa = (ctx->opcode >> 6) & 0x1f;
22899
22900     op1 = MASK_SPECIAL(ctx->opcode);
22901     switch (op1) {
22902     case OPC_MOVN:         /* Conditional move */
22903     case OPC_MOVZ:
22904         check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
22905                    INSN_LOONGSON2E | INSN_LOONGSON2F);
22906         gen_cond_move(ctx, op1, rd, rs, rt);
22907         break;
22908     case OPC_MFHI:          /* Move from HI/LO */
22909     case OPC_MFLO:
22910         gen_HILO(ctx, op1, rs & 3, rd);
22911         break;
22912     case OPC_MTHI:
22913     case OPC_MTLO:          /* Move to HI/LO */
22914         gen_HILO(ctx, op1, rd & 3, rs);
22915         break;
22916     case OPC_MOVCI:
22917         check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
22918         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
22919             check_cp1_enabled(ctx);
22920             gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
22921                       (ctx->opcode >> 16) & 1);
22922         } else {
22923             generate_exception_err(ctx, EXCP_CpU, 1);
22924         }
22925         break;
22926     case OPC_MULT:
22927     case OPC_MULTU:
22928         if (sa) {
22929             check_insn(ctx, INSN_VR54XX);
22930             op1 = MASK_MUL_VR54XX(ctx->opcode);
22931             gen_mul_vr54xx(ctx, op1, rd, rs, rt);
22932         } else {
22933             gen_muldiv(ctx, op1, rd & 3, rs, rt);
22934         }
22935         break;
22936     case OPC_DIV:
22937     case OPC_DIVU:
22938         gen_muldiv(ctx, op1, 0, rs, rt);
22939         break;
22940 #if defined(TARGET_MIPS64)
22941     case OPC_DMULT:
22942     case OPC_DMULTU:
22943     case OPC_DDIV:
22944     case OPC_DDIVU:
22945         check_insn(ctx, ISA_MIPS3);
22946         check_mips_64(ctx);
22947         gen_muldiv(ctx, op1, 0, rs, rt);
22948         break;
22949 #endif
22950     case OPC_JR:
22951         gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
22952         break;
22953     case OPC_SPIM:
22954 #ifdef MIPS_STRICT_STANDARD
22955         MIPS_INVAL("SPIM");
22956         generate_exception_end(ctx, EXCP_RI);
22957 #else
22958         /* Implemented as RI exception for now. */
22959         MIPS_INVAL("spim (unofficial)");
22960         generate_exception_end(ctx, EXCP_RI);
22961 #endif
22962         break;
22963     default:            /* Invalid */
22964         MIPS_INVAL("special_legacy");
22965         generate_exception_end(ctx, EXCP_RI);
22966         break;
22967     }
22968 }
22969
22970 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
22971 {
22972     int rs, rt, rd, sa;
22973     uint32_t op1;
22974
22975     rs = (ctx->opcode >> 21) & 0x1f;
22976     rt = (ctx->opcode >> 16) & 0x1f;
22977     rd = (ctx->opcode >> 11) & 0x1f;
22978     sa = (ctx->opcode >> 6) & 0x1f;
22979
22980     op1 = MASK_SPECIAL(ctx->opcode);
22981     switch (op1) {
22982     case OPC_SLL:          /* Shift with immediate */
22983         if (sa == 5 && rd == 0 &&
22984             rs == 0 && rt == 0) { /* PAUSE */
22985             if ((ctx->insn_flags & ISA_MIPS32R6) &&
22986                 (ctx->hflags & MIPS_HFLAG_BMASK)) {
22987                 generate_exception_end(ctx, EXCP_RI);
22988                 break;
22989             }
22990         }
22991         /* Fallthrough */
22992     case OPC_SRA:
22993         gen_shift_imm(ctx, op1, rd, rt, sa);
22994         break;
22995     case OPC_SRL:
22996         switch ((ctx->opcode >> 21) & 0x1f) {
22997         case 1:
22998             /* rotr is decoded as srl on non-R2 CPUs */
22999             if (ctx->insn_flags & ISA_MIPS32R2) {
23000                 op1 = OPC_ROTR;
23001             }
23002             /* Fallthrough */
23003         case 0:
23004             gen_shift_imm(ctx, op1, rd, rt, sa);
23005             break;
23006         default:
23007             generate_exception_end(ctx, EXCP_RI);
23008             break;
23009         }
23010         break;
23011     case OPC_ADD:
23012     case OPC_ADDU:
23013     case OPC_SUB:
23014     case OPC_SUBU:
23015         gen_arith(ctx, op1, rd, rs, rt);
23016         break;
23017     case OPC_SLLV:         /* Shifts */
23018     case OPC_SRAV:
23019         gen_shift(ctx, op1, rd, rs, rt);
23020         break;
23021     case OPC_SRLV:
23022         switch ((ctx->opcode >> 6) & 0x1f) {
23023         case 1:
23024             /* rotrv is decoded as srlv on non-R2 CPUs */
23025             if (ctx->insn_flags & ISA_MIPS32R2) {
23026                 op1 = OPC_ROTRV;
23027             }
23028             /* Fallthrough */
23029         case 0:
23030             gen_shift(ctx, op1, rd, rs, rt);
23031             break;
23032         default:
23033             generate_exception_end(ctx, EXCP_RI);
23034             break;
23035         }
23036         break;
23037     case OPC_SLT:          /* Set on less than */
23038     case OPC_SLTU:
23039         gen_slt(ctx, op1, rd, rs, rt);
23040         break;
23041     case OPC_AND:          /* Logic*/
23042     case OPC_OR:
23043     case OPC_NOR:
23044     case OPC_XOR:
23045         gen_logic(ctx, op1, rd, rs, rt);
23046         break;
23047     case OPC_JALR:
23048         gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
23049         break;
23050     case OPC_TGE: /* Traps */
23051     case OPC_TGEU:
23052     case OPC_TLT:
23053     case OPC_TLTU:
23054     case OPC_TEQ:
23055     case OPC_TNE:
23056         check_insn(ctx, ISA_MIPS2);
23057         gen_trap(ctx, op1, rs, rt, -1);
23058         break;
23059     case OPC_LSA: /* OPC_PMON */
23060         if ((ctx->insn_flags & ISA_MIPS32R6) ||
23061             (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
23062             decode_opc_special_r6(env, ctx);
23063         } else {
23064             /* Pmon entry point, also R4010 selsl */
23065 #ifdef MIPS_STRICT_STANDARD
23066             MIPS_INVAL("PMON / selsl");
23067             generate_exception_end(ctx, EXCP_RI);
23068 #else
23069             gen_helper_0e0i(pmon, sa);
23070 #endif
23071         }
23072         break;
23073     case OPC_SYSCALL:
23074         generate_exception_end(ctx, EXCP_SYSCALL);
23075         break;
23076     case OPC_BREAK:
23077         generate_exception_end(ctx, EXCP_BREAK);
23078         break;
23079     case OPC_SYNC:
23080         check_insn(ctx, ISA_MIPS2);
23081         gen_sync(extract32(ctx->opcode, 6, 5));
23082         break;
23083
23084 #if defined(TARGET_MIPS64)
23085         /* MIPS64 specific opcodes */
23086     case OPC_DSLL:
23087     case OPC_DSRA:
23088     case OPC_DSLL32:
23089     case OPC_DSRA32:
23090         check_insn(ctx, ISA_MIPS3);
23091         check_mips_64(ctx);
23092         gen_shift_imm(ctx, op1, rd, rt, sa);
23093         break;
23094     case OPC_DSRL:
23095         switch ((ctx->opcode >> 21) & 0x1f) {
23096         case 1:
23097             /* drotr is decoded as dsrl on non-R2 CPUs */
23098             if (ctx->insn_flags & ISA_MIPS32R2) {
23099                 op1 = OPC_DROTR;
23100             }
23101             /* Fallthrough */
23102         case 0:
23103             check_insn(ctx, ISA_MIPS3);
23104             check_mips_64(ctx);
23105             gen_shift_imm(ctx, op1, rd, rt, sa);
23106             break;
23107         default:
23108             generate_exception_end(ctx, EXCP_RI);
23109             break;
23110         }
23111         break;
23112     case OPC_DSRL32:
23113         switch ((ctx->opcode >> 21) & 0x1f) {
23114         case 1:
23115             /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
23116             if (ctx->insn_flags & ISA_MIPS32R2) {
23117                 op1 = OPC_DROTR32;
23118             }
23119             /* Fallthrough */
23120         case 0:
23121             check_insn(ctx, ISA_MIPS3);
23122             check_mips_64(ctx);
23123             gen_shift_imm(ctx, op1, rd, rt, sa);
23124             break;
23125         default:
23126             generate_exception_end(ctx, EXCP_RI);
23127             break;
23128         }
23129         break;
23130     case OPC_DADD:
23131     case OPC_DADDU:
23132     case OPC_DSUB:
23133     case OPC_DSUBU:
23134         check_insn(ctx, ISA_MIPS3);
23135         check_mips_64(ctx);
23136         gen_arith(ctx, op1, rd, rs, rt);
23137         break;
23138     case OPC_DSLLV:
23139     case OPC_DSRAV:
23140         check_insn(ctx, ISA_MIPS3);
23141         check_mips_64(ctx);
23142         gen_shift(ctx, op1, rd, rs, rt);
23143         break;
23144     case OPC_DSRLV:
23145         switch ((ctx->opcode >> 6) & 0x1f) {
23146         case 1:
23147             /* drotrv is decoded as dsrlv on non-R2 CPUs */
23148             if (ctx->insn_flags & ISA_MIPS32R2) {
23149                 op1 = OPC_DROTRV;
23150             }
23151             /* Fallthrough */
23152         case 0:
23153             check_insn(ctx, ISA_MIPS3);
23154             check_mips_64(ctx);
23155             gen_shift(ctx, op1, rd, rs, rt);
23156             break;
23157         default:
23158             generate_exception_end(ctx, EXCP_RI);
23159             break;
23160         }
23161         break;
23162     case OPC_DLSA:
23163         if ((ctx->insn_flags & ISA_MIPS32R6) ||
23164             (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
23165             decode_opc_special_r6(env, ctx);
23166         }
23167         break;
23168 #endif
23169     default:
23170         if (ctx->insn_flags & ISA_MIPS32R6) {
23171             decode_opc_special_r6(env, ctx);
23172         } else {
23173             decode_opc_special_legacy(env, ctx);
23174         }
23175     }
23176 }
23177
23178 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
23179 {
23180     int rs, rt, rd;
23181     uint32_t op1;
23182
23183     check_insn_opc_removed(ctx, ISA_MIPS32R6);
23184
23185     rs = (ctx->opcode >> 21) & 0x1f;
23186     rt = (ctx->opcode >> 16) & 0x1f;
23187     rd = (ctx->opcode >> 11) & 0x1f;
23188
23189     op1 = MASK_SPECIAL2(ctx->opcode);
23190     switch (op1) {
23191     case OPC_MADD: /* Multiply and add/sub */
23192     case OPC_MADDU:
23193     case OPC_MSUB:
23194     case OPC_MSUBU:
23195         check_insn(ctx, ISA_MIPS32);
23196         gen_muldiv(ctx, op1, rd & 3, rs, rt);
23197         break;
23198     case OPC_MUL:
23199         gen_arith(ctx, op1, rd, rs, rt);
23200         break;
23201     case OPC_DIV_G_2F:
23202     case OPC_DIVU_G_2F:
23203     case OPC_MULT_G_2F:
23204     case OPC_MULTU_G_2F:
23205     case OPC_MOD_G_2F:
23206     case OPC_MODU_G_2F:
23207         check_insn(ctx, INSN_LOONGSON2F);
23208         gen_loongson_integer(ctx, op1, rd, rs, rt);
23209         break;
23210     case OPC_CLO:
23211     case OPC_CLZ:
23212         check_insn(ctx, ISA_MIPS32);
23213         gen_cl(ctx, op1, rd, rs);
23214         break;
23215     case OPC_SDBBP:
23216         if (is_uhi(extract32(ctx->opcode, 6, 20))) {
23217             gen_helper_do_semihosting(cpu_env);
23218         } else {
23219             /* XXX: not clear which exception should be raised
23220              *      when in debug mode...
23221              */
23222             check_insn(ctx, ISA_MIPS32);
23223             generate_exception_end(ctx, EXCP_DBp);
23224         }
23225         break;
23226 #if defined(TARGET_MIPS64)
23227     case OPC_DCLO:
23228     case OPC_DCLZ:
23229         check_insn(ctx, ISA_MIPS64);
23230         check_mips_64(ctx);
23231         gen_cl(ctx, op1, rd, rs);
23232         break;
23233     case OPC_DMULT_G_2F:
23234     case OPC_DMULTU_G_2F:
23235     case OPC_DDIV_G_2F:
23236     case OPC_DDIVU_G_2F:
23237     case OPC_DMOD_G_2F:
23238     case OPC_DMODU_G_2F:
23239         check_insn(ctx, INSN_LOONGSON2F);
23240         gen_loongson_integer(ctx, op1, rd, rs, rt);
23241         break;
23242 #endif
23243     default:            /* Invalid */
23244         MIPS_INVAL("special2_legacy");
23245         generate_exception_end(ctx, EXCP_RI);
23246         break;
23247     }
23248 }
23249
23250 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
23251 {
23252     int rs, rt, rd, sa;
23253     uint32_t op1, op2;
23254     int16_t imm;
23255
23256     rs = (ctx->opcode >> 21) & 0x1f;
23257     rt = (ctx->opcode >> 16) & 0x1f;
23258     rd = (ctx->opcode >> 11) & 0x1f;
23259     sa = (ctx->opcode >> 6) & 0x1f;
23260     imm = (int16_t)ctx->opcode >> 7;
23261
23262     op1 = MASK_SPECIAL3(ctx->opcode);
23263     switch (op1) {
23264     case R6_OPC_PREF:
23265         if (rt >= 24) {
23266             /* hint codes 24-31 are reserved and signal RI */
23267             generate_exception_end(ctx, EXCP_RI);
23268         }
23269         /* Treat as NOP. */
23270         break;
23271     case R6_OPC_CACHE:
23272         check_cp0_enabled(ctx);
23273         if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
23274             gen_cache_operation(ctx, rt, rs, imm);
23275         }
23276         break;
23277     case R6_OPC_SC:
23278         gen_st_cond(ctx, op1, rt, rs, imm);
23279         break;
23280     case R6_OPC_LL:
23281         gen_ld(ctx, op1, rt, rs, imm);
23282         break;
23283     case OPC_BSHFL:
23284         {
23285             if (rd == 0) {
23286                 /* Treat as NOP. */
23287                 break;
23288             }
23289             op2 = MASK_BSHFL(ctx->opcode);
23290             switch (op2) {
23291             case OPC_ALIGN:
23292             case OPC_ALIGN_END:
23293                 gen_align(ctx, 32, rd, rs, rt, sa & 3);
23294                 break;
23295             case OPC_BITSWAP:
23296                 gen_bitswap(ctx, op2, rd, rt);
23297                 break;
23298             }
23299         }
23300         break;
23301 #if defined(TARGET_MIPS64)
23302     case R6_OPC_SCD:
23303         gen_st_cond(ctx, op1, rt, rs, imm);
23304         break;
23305     case R6_OPC_LLD:
23306         gen_ld(ctx, op1, rt, rs, imm);
23307         break;
23308     case OPC_DBSHFL:
23309         check_mips_64(ctx);
23310         {
23311             if (rd == 0) {
23312                 /* Treat as NOP. */
23313                 break;
23314             }
23315             op2 = MASK_DBSHFL(ctx->opcode);
23316             switch (op2) {
23317             case OPC_DALIGN:
23318             case OPC_DALIGN_END:
23319                 gen_align(ctx, 64, rd, rs, rt, sa & 7);
23320                 break;
23321             case OPC_DBITSWAP:
23322                 gen_bitswap(ctx, op2, rd, rt);
23323                 break;
23324             }
23325
23326         }
23327         break;
23328 #endif
23329     default:            /* Invalid */
23330         MIPS_INVAL("special3_r6");
23331         generate_exception_end(ctx, EXCP_RI);
23332         break;
23333     }
23334 }
23335
23336 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
23337 {
23338     int rs, rt, rd;
23339     uint32_t op1, op2;
23340
23341     rs = (ctx->opcode >> 21) & 0x1f;
23342     rt = (ctx->opcode >> 16) & 0x1f;
23343     rd = (ctx->opcode >> 11) & 0x1f;
23344
23345     op1 = MASK_SPECIAL3(ctx->opcode);
23346     switch (op1) {
23347     case OPC_DIV_G_2E:
23348     case OPC_DIVU_G_2E:
23349     case OPC_MOD_G_2E:
23350     case OPC_MODU_G_2E:
23351     case OPC_MULT_G_2E:
23352     case OPC_MULTU_G_2E:
23353         /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
23354          * the same mask and op1. */
23355         if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
23356             op2 = MASK_ADDUH_QB(ctx->opcode);
23357             switch (op2) {
23358             case OPC_ADDUH_QB:
23359             case OPC_ADDUH_R_QB:
23360             case OPC_ADDQH_PH:
23361             case OPC_ADDQH_R_PH:
23362             case OPC_ADDQH_W:
23363             case OPC_ADDQH_R_W:
23364             case OPC_SUBUH_QB:
23365             case OPC_SUBUH_R_QB:
23366             case OPC_SUBQH_PH:
23367             case OPC_SUBQH_R_PH:
23368             case OPC_SUBQH_W:
23369             case OPC_SUBQH_R_W:
23370                 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23371                 break;
23372             case OPC_MUL_PH:
23373             case OPC_MUL_S_PH:
23374             case OPC_MULQ_S_W:
23375             case OPC_MULQ_RS_W:
23376                 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
23377                 break;
23378             default:
23379                 MIPS_INVAL("MASK ADDUH.QB");
23380                 generate_exception_end(ctx, EXCP_RI);
23381                 break;
23382             }
23383         } else if (ctx->insn_flags & INSN_LOONGSON2E) {
23384             gen_loongson_integer(ctx, op1, rd, rs, rt);
23385         } else {
23386             generate_exception_end(ctx, EXCP_RI);
23387         }
23388         break;
23389     case OPC_LX_DSP:
23390         op2 = MASK_LX(ctx->opcode);
23391         switch (op2) {
23392 #if defined(TARGET_MIPS64)
23393         case OPC_LDX:
23394 #endif
23395         case OPC_LBUX:
23396         case OPC_LHX:
23397         case OPC_LWX:
23398             gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
23399             break;
23400         default:            /* Invalid */
23401             MIPS_INVAL("MASK LX");
23402             generate_exception_end(ctx, EXCP_RI);
23403             break;
23404         }
23405         break;
23406     case OPC_ABSQ_S_PH_DSP:
23407         op2 = MASK_ABSQ_S_PH(ctx->opcode);
23408         switch (op2) {
23409         case OPC_ABSQ_S_QB:
23410         case OPC_ABSQ_S_PH:
23411         case OPC_ABSQ_S_W:
23412         case OPC_PRECEQ_W_PHL:
23413         case OPC_PRECEQ_W_PHR:
23414         case OPC_PRECEQU_PH_QBL:
23415         case OPC_PRECEQU_PH_QBR:
23416         case OPC_PRECEQU_PH_QBLA:
23417         case OPC_PRECEQU_PH_QBRA:
23418         case OPC_PRECEU_PH_QBL:
23419         case OPC_PRECEU_PH_QBR:
23420         case OPC_PRECEU_PH_QBLA:
23421         case OPC_PRECEU_PH_QBRA:
23422             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23423             break;
23424         case OPC_BITREV:
23425         case OPC_REPL_QB:
23426         case OPC_REPLV_QB:
23427         case OPC_REPL_PH:
23428         case OPC_REPLV_PH:
23429             gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
23430             break;
23431         default:
23432             MIPS_INVAL("MASK ABSQ_S.PH");
23433             generate_exception_end(ctx, EXCP_RI);
23434             break;
23435         }
23436         break;
23437     case OPC_ADDU_QB_DSP:
23438         op2 = MASK_ADDU_QB(ctx->opcode);
23439         switch (op2) {
23440         case OPC_ADDQ_PH:
23441         case OPC_ADDQ_S_PH:
23442         case OPC_ADDQ_S_W:
23443         case OPC_ADDU_QB:
23444         case OPC_ADDU_S_QB:
23445         case OPC_ADDU_PH:
23446         case OPC_ADDU_S_PH:
23447         case OPC_SUBQ_PH:
23448         case OPC_SUBQ_S_PH:
23449         case OPC_SUBQ_S_W:
23450         case OPC_SUBU_QB:
23451         case OPC_SUBU_S_QB:
23452         case OPC_SUBU_PH:
23453         case OPC_SUBU_S_PH:
23454         case OPC_ADDSC:
23455         case OPC_ADDWC:
23456         case OPC_MODSUB:
23457         case OPC_RADDU_W_QB:
23458             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23459             break;
23460         case OPC_MULEU_S_PH_QBL:
23461         case OPC_MULEU_S_PH_QBR:
23462         case OPC_MULQ_RS_PH:
23463         case OPC_MULEQ_S_W_PHL:
23464         case OPC_MULEQ_S_W_PHR:
23465         case OPC_MULQ_S_PH:
23466             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
23467             break;
23468         default:            /* Invalid */
23469             MIPS_INVAL("MASK ADDU.QB");
23470             generate_exception_end(ctx, EXCP_RI);
23471             break;
23472
23473         }
23474         break;
23475     case OPC_CMPU_EQ_QB_DSP:
23476         op2 = MASK_CMPU_EQ_QB(ctx->opcode);
23477         switch (op2) {
23478         case OPC_PRECR_SRA_PH_W:
23479         case OPC_PRECR_SRA_R_PH_W:
23480             gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
23481             break;
23482         case OPC_PRECR_QB_PH:
23483         case OPC_PRECRQ_QB_PH:
23484         case OPC_PRECRQ_PH_W:
23485         case OPC_PRECRQ_RS_PH_W:
23486         case OPC_PRECRQU_S_QB_PH:
23487             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23488             break;
23489         case OPC_CMPU_EQ_QB:
23490         case OPC_CMPU_LT_QB:
23491         case OPC_CMPU_LE_QB:
23492         case OPC_CMP_EQ_PH:
23493         case OPC_CMP_LT_PH:
23494         case OPC_CMP_LE_PH:
23495             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
23496             break;
23497         case OPC_CMPGU_EQ_QB:
23498         case OPC_CMPGU_LT_QB:
23499         case OPC_CMPGU_LE_QB:
23500         case OPC_CMPGDU_EQ_QB:
23501         case OPC_CMPGDU_LT_QB:
23502         case OPC_CMPGDU_LE_QB:
23503         case OPC_PICK_QB:
23504         case OPC_PICK_PH:
23505         case OPC_PACKRL_PH:
23506             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
23507             break;
23508         default:            /* Invalid */
23509             MIPS_INVAL("MASK CMPU.EQ.QB");
23510             generate_exception_end(ctx, EXCP_RI);
23511             break;
23512         }
23513         break;
23514     case OPC_SHLL_QB_DSP:
23515         gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
23516         break;
23517     case OPC_DPA_W_PH_DSP:
23518         op2 = MASK_DPA_W_PH(ctx->opcode);
23519         switch (op2) {
23520         case OPC_DPAU_H_QBL:
23521         case OPC_DPAU_H_QBR:
23522         case OPC_DPSU_H_QBL:
23523         case OPC_DPSU_H_QBR:
23524         case OPC_DPA_W_PH:
23525         case OPC_DPAX_W_PH:
23526         case OPC_DPAQ_S_W_PH:
23527         case OPC_DPAQX_S_W_PH:
23528         case OPC_DPAQX_SA_W_PH:
23529         case OPC_DPS_W_PH:
23530         case OPC_DPSX_W_PH:
23531         case OPC_DPSQ_S_W_PH:
23532         case OPC_DPSQX_S_W_PH:
23533         case OPC_DPSQX_SA_W_PH:
23534         case OPC_MULSAQ_S_W_PH:
23535         case OPC_DPAQ_SA_L_W:
23536         case OPC_DPSQ_SA_L_W:
23537         case OPC_MAQ_S_W_PHL:
23538         case OPC_MAQ_S_W_PHR:
23539         case OPC_MAQ_SA_W_PHL:
23540         case OPC_MAQ_SA_W_PHR:
23541         case OPC_MULSA_W_PH:
23542             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
23543             break;
23544         default:            /* Invalid */
23545             MIPS_INVAL("MASK DPAW.PH");
23546             generate_exception_end(ctx, EXCP_RI);
23547             break;
23548         }
23549         break;
23550     case OPC_INSV_DSP:
23551         op2 = MASK_INSV(ctx->opcode);
23552         switch (op2) {
23553         case OPC_INSV:
23554             check_dsp(ctx);
23555             {
23556                 TCGv t0, t1;
23557
23558                 if (rt == 0) {
23559                     break;
23560                 }
23561
23562                 t0 = tcg_temp_new();
23563                 t1 = tcg_temp_new();
23564
23565                 gen_load_gpr(t0, rt);
23566                 gen_load_gpr(t1, rs);
23567
23568                 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
23569
23570                 tcg_temp_free(t0);
23571                 tcg_temp_free(t1);
23572                 break;
23573             }
23574         default:            /* Invalid */
23575             MIPS_INVAL("MASK INSV");
23576             generate_exception_end(ctx, EXCP_RI);
23577             break;
23578         }
23579         break;
23580     case OPC_APPEND_DSP:
23581         gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
23582         break;
23583     case OPC_EXTR_W_DSP:
23584         op2 = MASK_EXTR_W(ctx->opcode);
23585         switch (op2) {
23586         case OPC_EXTR_W:
23587         case OPC_EXTR_R_W:
23588         case OPC_EXTR_RS_W:
23589         case OPC_EXTR_S_H:
23590         case OPC_EXTRV_S_H:
23591         case OPC_EXTRV_W:
23592         case OPC_EXTRV_R_W:
23593         case OPC_EXTRV_RS_W:
23594         case OPC_EXTP:
23595         case OPC_EXTPV:
23596         case OPC_EXTPDP:
23597         case OPC_EXTPDPV:
23598             gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
23599             break;
23600         case OPC_RDDSP:
23601             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
23602             break;
23603         case OPC_SHILO:
23604         case OPC_SHILOV:
23605         case OPC_MTHLIP:
23606         case OPC_WRDSP:
23607             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
23608             break;
23609         default:            /* Invalid */
23610             MIPS_INVAL("MASK EXTR.W");
23611             generate_exception_end(ctx, EXCP_RI);
23612             break;
23613         }
23614         break;
23615 #if defined(TARGET_MIPS64)
23616     case OPC_DDIV_G_2E:
23617     case OPC_DDIVU_G_2E:
23618     case OPC_DMULT_G_2E:
23619     case OPC_DMULTU_G_2E:
23620     case OPC_DMOD_G_2E:
23621     case OPC_DMODU_G_2E:
23622         check_insn(ctx, INSN_LOONGSON2E);
23623         gen_loongson_integer(ctx, op1, rd, rs, rt);
23624         break;
23625     case OPC_ABSQ_S_QH_DSP:
23626         op2 = MASK_ABSQ_S_QH(ctx->opcode);
23627         switch (op2) {
23628         case OPC_PRECEQ_L_PWL:
23629         case OPC_PRECEQ_L_PWR:
23630         case OPC_PRECEQ_PW_QHL:
23631         case OPC_PRECEQ_PW_QHR:
23632         case OPC_PRECEQ_PW_QHLA:
23633         case OPC_PRECEQ_PW_QHRA:
23634         case OPC_PRECEQU_QH_OBL:
23635         case OPC_PRECEQU_QH_OBR:
23636         case OPC_PRECEQU_QH_OBLA:
23637         case OPC_PRECEQU_QH_OBRA:
23638         case OPC_PRECEU_QH_OBL:
23639         case OPC_PRECEU_QH_OBR:
23640         case OPC_PRECEU_QH_OBLA:
23641         case OPC_PRECEU_QH_OBRA:
23642         case OPC_ABSQ_S_OB:
23643         case OPC_ABSQ_S_PW:
23644         case OPC_ABSQ_S_QH:
23645             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23646             break;
23647         case OPC_REPL_OB:
23648         case OPC_REPL_PW:
23649         case OPC_REPL_QH:
23650         case OPC_REPLV_OB:
23651         case OPC_REPLV_PW:
23652         case OPC_REPLV_QH:
23653             gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
23654             break;
23655         default:            /* Invalid */
23656             MIPS_INVAL("MASK ABSQ_S.QH");
23657             generate_exception_end(ctx, EXCP_RI);
23658             break;
23659         }
23660         break;
23661     case OPC_ADDU_OB_DSP:
23662         op2 = MASK_ADDU_OB(ctx->opcode);
23663         switch (op2) {
23664         case OPC_RADDU_L_OB:
23665         case OPC_SUBQ_PW:
23666         case OPC_SUBQ_S_PW:
23667         case OPC_SUBQ_QH:
23668         case OPC_SUBQ_S_QH:
23669         case OPC_SUBU_OB:
23670         case OPC_SUBU_S_OB:
23671         case OPC_SUBU_QH:
23672         case OPC_SUBU_S_QH:
23673         case OPC_SUBUH_OB:
23674         case OPC_SUBUH_R_OB:
23675         case OPC_ADDQ_PW:
23676         case OPC_ADDQ_S_PW:
23677         case OPC_ADDQ_QH:
23678         case OPC_ADDQ_S_QH:
23679         case OPC_ADDU_OB:
23680         case OPC_ADDU_S_OB:
23681         case OPC_ADDU_QH:
23682         case OPC_ADDU_S_QH:
23683         case OPC_ADDUH_OB:
23684         case OPC_ADDUH_R_OB:
23685             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23686             break;
23687         case OPC_MULEQ_S_PW_QHL:
23688         case OPC_MULEQ_S_PW_QHR:
23689         case OPC_MULEU_S_QH_OBL:
23690         case OPC_MULEU_S_QH_OBR:
23691         case OPC_MULQ_RS_QH:
23692             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
23693             break;
23694         default:            /* Invalid */
23695             MIPS_INVAL("MASK ADDU.OB");
23696             generate_exception_end(ctx, EXCP_RI);
23697             break;
23698         }
23699         break;
23700     case OPC_CMPU_EQ_OB_DSP:
23701         op2 = MASK_CMPU_EQ_OB(ctx->opcode);
23702         switch (op2) {
23703         case OPC_PRECR_SRA_QH_PW:
23704         case OPC_PRECR_SRA_R_QH_PW:
23705             /* Return value is rt. */
23706             gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
23707             break;
23708         case OPC_PRECR_OB_QH:
23709         case OPC_PRECRQ_OB_QH:
23710         case OPC_PRECRQ_PW_L:
23711         case OPC_PRECRQ_QH_PW:
23712         case OPC_PRECRQ_RS_QH_PW:
23713         case OPC_PRECRQU_S_OB_QH:
23714             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23715             break;
23716         case OPC_CMPU_EQ_OB:
23717         case OPC_CMPU_LT_OB:
23718         case OPC_CMPU_LE_OB:
23719         case OPC_CMP_EQ_QH:
23720         case OPC_CMP_LT_QH:
23721         case OPC_CMP_LE_QH:
23722         case OPC_CMP_EQ_PW:
23723         case OPC_CMP_LT_PW:
23724         case OPC_CMP_LE_PW:
23725             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
23726             break;
23727         case OPC_CMPGDU_EQ_OB:
23728         case OPC_CMPGDU_LT_OB:
23729         case OPC_CMPGDU_LE_OB:
23730         case OPC_CMPGU_EQ_OB:
23731         case OPC_CMPGU_LT_OB:
23732         case OPC_CMPGU_LE_OB:
23733         case OPC_PACKRL_PW:
23734         case OPC_PICK_OB:
23735         case OPC_PICK_PW:
23736         case OPC_PICK_QH:
23737             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
23738             break;
23739         default:            /* Invalid */
23740             MIPS_INVAL("MASK CMPU_EQ.OB");
23741             generate_exception_end(ctx, EXCP_RI);
23742             break;
23743         }
23744         break;
23745     case OPC_DAPPEND_DSP:
23746         gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
23747         break;
23748     case OPC_DEXTR_W_DSP:
23749         op2 = MASK_DEXTR_W(ctx->opcode);
23750         switch (op2) {
23751         case OPC_DEXTP:
23752         case OPC_DEXTPDP:
23753         case OPC_DEXTPDPV:
23754         case OPC_DEXTPV:
23755         case OPC_DEXTR_L:
23756         case OPC_DEXTR_R_L:
23757         case OPC_DEXTR_RS_L:
23758         case OPC_DEXTR_W:
23759         case OPC_DEXTR_R_W:
23760         case OPC_DEXTR_RS_W:
23761         case OPC_DEXTR_S_H:
23762         case OPC_DEXTRV_L:
23763         case OPC_DEXTRV_R_L:
23764         case OPC_DEXTRV_RS_L:
23765         case OPC_DEXTRV_S_H:
23766         case OPC_DEXTRV_W:
23767         case OPC_DEXTRV_R_W:
23768         case OPC_DEXTRV_RS_W:
23769             gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
23770             break;
23771         case OPC_DMTHLIP:
23772         case OPC_DSHILO:
23773         case OPC_DSHILOV:
23774             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
23775             break;
23776         default:            /* Invalid */
23777             MIPS_INVAL("MASK EXTR.W");
23778             generate_exception_end(ctx, EXCP_RI);
23779             break;
23780         }
23781         break;
23782     case OPC_DPAQ_W_QH_DSP:
23783         op2 = MASK_DPAQ_W_QH(ctx->opcode);
23784         switch (op2) {
23785         case OPC_DPAU_H_OBL:
23786         case OPC_DPAU_H_OBR:
23787         case OPC_DPSU_H_OBL:
23788         case OPC_DPSU_H_OBR:
23789         case OPC_DPA_W_QH:
23790         case OPC_DPAQ_S_W_QH:
23791         case OPC_DPS_W_QH:
23792         case OPC_DPSQ_S_W_QH:
23793         case OPC_MULSAQ_S_W_QH:
23794         case OPC_DPAQ_SA_L_PW:
23795         case OPC_DPSQ_SA_L_PW:
23796         case OPC_MULSAQ_S_L_PW:
23797             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
23798             break;
23799         case OPC_MAQ_S_W_QHLL:
23800         case OPC_MAQ_S_W_QHLR:
23801         case OPC_MAQ_S_W_QHRL:
23802         case OPC_MAQ_S_W_QHRR:
23803         case OPC_MAQ_SA_W_QHLL:
23804         case OPC_MAQ_SA_W_QHLR:
23805         case OPC_MAQ_SA_W_QHRL:
23806         case OPC_MAQ_SA_W_QHRR:
23807         case OPC_MAQ_S_L_PWL:
23808         case OPC_MAQ_S_L_PWR:
23809         case OPC_DMADD:
23810         case OPC_DMADDU:
23811         case OPC_DMSUB:
23812         case OPC_DMSUBU:
23813             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
23814             break;
23815         default:            /* Invalid */
23816             MIPS_INVAL("MASK DPAQ.W.QH");
23817             generate_exception_end(ctx, EXCP_RI);
23818             break;
23819         }
23820         break;
23821     case OPC_DINSV_DSP:
23822         op2 = MASK_INSV(ctx->opcode);
23823         switch (op2) {
23824         case OPC_DINSV:
23825         {
23826             TCGv t0, t1;
23827
23828             if (rt == 0) {
23829                 break;
23830             }
23831             check_dsp(ctx);
23832
23833             t0 = tcg_temp_new();
23834             t1 = tcg_temp_new();
23835
23836             gen_load_gpr(t0, rt);
23837             gen_load_gpr(t1, rs);
23838
23839             gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
23840
23841             tcg_temp_free(t0);
23842             tcg_temp_free(t1);
23843             break;
23844         }
23845         default:            /* Invalid */
23846             MIPS_INVAL("MASK DINSV");
23847             generate_exception_end(ctx, EXCP_RI);
23848             break;
23849         }
23850         break;
23851     case OPC_SHLL_OB_DSP:
23852         gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
23853         break;
23854 #endif
23855     default:            /* Invalid */
23856         MIPS_INVAL("special3_legacy");
23857         generate_exception_end(ctx, EXCP_RI);
23858         break;
23859     }
23860 }
23861
23862 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
23863 {
23864     int rs, rt, rd, sa;
23865     uint32_t op1, op2;
23866     int16_t imm;
23867
23868     rs = (ctx->opcode >> 21) & 0x1f;
23869     rt = (ctx->opcode >> 16) & 0x1f;
23870     rd = (ctx->opcode >> 11) & 0x1f;
23871     sa = (ctx->opcode >> 6) & 0x1f;
23872     imm = sextract32(ctx->opcode, 7, 9);
23873
23874     op1 = MASK_SPECIAL3(ctx->opcode);
23875
23876     /*
23877      * EVA loads and stores overlap Loongson 2E instructions decoded by
23878      * decode_opc_special3_legacy(), so be careful to allow their decoding when
23879      * EVA is absent.
23880      */
23881     if (ctx->eva) {
23882         switch (op1) {
23883         case OPC_LWLE:
23884         case OPC_LWRE:
23885             check_insn_opc_removed(ctx, ISA_MIPS32R6);
23886             /* fall through */
23887         case OPC_LBUE:
23888         case OPC_LHUE:
23889         case OPC_LBE:
23890         case OPC_LHE:
23891         case OPC_LLE:
23892         case OPC_LWE:
23893             check_cp0_enabled(ctx);
23894             gen_ld(ctx, op1, rt, rs, imm);
23895             return;
23896         case OPC_SWLE:
23897         case OPC_SWRE:
23898             check_insn_opc_removed(ctx, ISA_MIPS32R6);
23899             /* fall through */
23900         case OPC_SBE:
23901         case OPC_SHE:
23902         case OPC_SWE:
23903             check_cp0_enabled(ctx);
23904             gen_st(ctx, op1, rt, rs, imm);
23905             return;
23906         case OPC_SCE:
23907             check_cp0_enabled(ctx);
23908             gen_st_cond(ctx, op1, rt, rs, imm);
23909             return;
23910         case OPC_CACHEE:
23911             check_cp0_enabled(ctx);
23912             if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
23913                 gen_cache_operation(ctx, rt, rs, imm);
23914             }
23915             /* Treat as NOP. */
23916             return;
23917         case OPC_PREFE:
23918             check_cp0_enabled(ctx);
23919             /* Treat as NOP. */
23920             return;
23921         }
23922     }
23923
23924     switch (op1) {
23925     case OPC_EXT:
23926     case OPC_INS:
23927         check_insn(ctx, ISA_MIPS32R2);
23928         gen_bitops(ctx, op1, rt, rs, sa, rd);
23929         break;
23930     case OPC_BSHFL:
23931         op2 = MASK_BSHFL(ctx->opcode);
23932         switch (op2) {
23933         case OPC_ALIGN:
23934         case OPC_ALIGN_END:
23935         case OPC_BITSWAP:
23936             check_insn(ctx, ISA_MIPS32R6);
23937             decode_opc_special3_r6(env, ctx);
23938             break;
23939         default:
23940             check_insn(ctx, ISA_MIPS32R2);
23941             gen_bshfl(ctx, op2, rt, rd);
23942             break;
23943         }
23944         break;
23945 #if defined(TARGET_MIPS64)
23946     case OPC_DEXTM:
23947     case OPC_DEXTU:
23948     case OPC_DEXT:
23949     case OPC_DINSM:
23950     case OPC_DINSU:
23951     case OPC_DINS:
23952         check_insn(ctx, ISA_MIPS64R2);
23953         check_mips_64(ctx);
23954         gen_bitops(ctx, op1, rt, rs, sa, rd);
23955         break;
23956     case OPC_DBSHFL:
23957         op2 = MASK_DBSHFL(ctx->opcode);
23958         switch (op2) {
23959         case OPC_DALIGN:
23960         case OPC_DALIGN_END:
23961         case OPC_DBITSWAP:
23962             check_insn(ctx, ISA_MIPS32R6);
23963             decode_opc_special3_r6(env, ctx);
23964             break;
23965         default:
23966             check_insn(ctx, ISA_MIPS64R2);
23967             check_mips_64(ctx);
23968             op2 = MASK_DBSHFL(ctx->opcode);
23969             gen_bshfl(ctx, op2, rt, rd);
23970             break;
23971         }
23972         break;
23973 #endif
23974     case OPC_RDHWR:
23975         gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
23976         break;
23977     case OPC_FORK:
23978         check_mt(ctx);
23979         {
23980             TCGv t0 = tcg_temp_new();
23981             TCGv t1 = tcg_temp_new();
23982
23983             gen_load_gpr(t0, rt);
23984             gen_load_gpr(t1, rs);
23985             gen_helper_fork(t0, t1);
23986             tcg_temp_free(t0);
23987             tcg_temp_free(t1);
23988         }
23989         break;
23990     case OPC_YIELD:
23991         check_mt(ctx);
23992         {
23993             TCGv t0 = tcg_temp_new();
23994
23995             gen_load_gpr(t0, rs);
23996             gen_helper_yield(t0, cpu_env, t0);
23997             gen_store_gpr(t0, rd);
23998             tcg_temp_free(t0);
23999         }
24000         break;
24001     default:
24002         if (ctx->insn_flags & ISA_MIPS32R6) {
24003             decode_opc_special3_r6(env, ctx);
24004         } else {
24005             decode_opc_special3_legacy(env, ctx);
24006         }
24007     }
24008 }
24009
24010 /* MIPS SIMD Architecture (MSA)  */
24011 static inline int check_msa_access(DisasContext *ctx)
24012 {
24013     if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
24014                  !(ctx->hflags & MIPS_HFLAG_F64))) {
24015         generate_exception_end(ctx, EXCP_RI);
24016         return 0;
24017     }
24018
24019     if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
24020         if (ctx->insn_flags & ASE_MSA) {
24021             generate_exception_end(ctx, EXCP_MSADIS);
24022             return 0;
24023         } else {
24024             generate_exception_end(ctx, EXCP_RI);
24025             return 0;
24026         }
24027     }
24028     return 1;
24029 }
24030
24031 static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
24032 {
24033     /* generates tcg ops to check if any element is 0 */
24034     /* Note this function only works with MSA_WRLEN = 128 */
24035     uint64_t eval_zero_or_big = 0;
24036     uint64_t eval_big = 0;
24037     TCGv_i64 t0 = tcg_temp_new_i64();
24038     TCGv_i64 t1 = tcg_temp_new_i64();
24039     switch (df) {
24040     case DF_BYTE:
24041         eval_zero_or_big = 0x0101010101010101ULL;
24042         eval_big = 0x8080808080808080ULL;
24043         break;
24044     case DF_HALF:
24045         eval_zero_or_big = 0x0001000100010001ULL;
24046         eval_big = 0x8000800080008000ULL;
24047         break;
24048     case DF_WORD:
24049         eval_zero_or_big = 0x0000000100000001ULL;
24050         eval_big = 0x8000000080000000ULL;
24051         break;
24052     case DF_DOUBLE:
24053         eval_zero_or_big = 0x0000000000000001ULL;
24054         eval_big = 0x8000000000000000ULL;
24055         break;
24056     }
24057     tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
24058     tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
24059     tcg_gen_andi_i64(t0, t0, eval_big);
24060     tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
24061     tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
24062     tcg_gen_andi_i64(t1, t1, eval_big);
24063     tcg_gen_or_i64(t0, t0, t1);
24064     /* if all bits are zero then all elements are not zero */
24065     /* if some bit is non-zero then some element is zero */
24066     tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
24067     tcg_gen_trunc_i64_tl(tresult, t0);
24068     tcg_temp_free_i64(t0);
24069     tcg_temp_free_i64(t1);
24070 }
24071
24072 static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
24073 {
24074     uint8_t df = (ctx->opcode >> 21) & 0x3;
24075     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
24076     int64_t s16 = (int16_t)ctx->opcode;
24077
24078     check_msa_access(ctx);
24079
24080     if (ctx->hflags & MIPS_HFLAG_BMASK) {
24081         generate_exception_end(ctx, EXCP_RI);
24082         return;
24083     }
24084     switch (op1) {
24085     case OPC_BZ_V:
24086     case OPC_BNZ_V:
24087         {
24088             TCGv_i64 t0 = tcg_temp_new_i64();
24089             tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
24090             tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
24091                     TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
24092             tcg_gen_trunc_i64_tl(bcond, t0);
24093             tcg_temp_free_i64(t0);
24094         }
24095         break;
24096     case OPC_BZ_B:
24097     case OPC_BZ_H:
24098     case OPC_BZ_W:
24099     case OPC_BZ_D:
24100         gen_check_zero_element(bcond, df, wt);
24101         break;
24102     case OPC_BNZ_B:
24103     case OPC_BNZ_H:
24104     case OPC_BNZ_W:
24105     case OPC_BNZ_D:
24106         gen_check_zero_element(bcond, df, wt);
24107         tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
24108         break;
24109     }
24110
24111     ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
24112
24113     ctx->hflags |= MIPS_HFLAG_BC;
24114     ctx->hflags |= MIPS_HFLAG_BDS32;
24115 }
24116
24117 static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
24118 {
24119 #define MASK_MSA_I8(op)    (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
24120     uint8_t i8 = (ctx->opcode >> 16) & 0xff;
24121     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24122     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24123
24124     TCGv_i32 twd = tcg_const_i32(wd);
24125     TCGv_i32 tws = tcg_const_i32(ws);
24126     TCGv_i32 ti8 = tcg_const_i32(i8);
24127
24128     switch (MASK_MSA_I8(ctx->opcode)) {
24129     case OPC_ANDI_B:
24130         gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
24131         break;
24132     case OPC_ORI_B:
24133         gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
24134         break;
24135     case OPC_NORI_B:
24136         gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
24137         break;
24138     case OPC_XORI_B:
24139         gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
24140         break;
24141     case OPC_BMNZI_B:
24142         gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
24143         break;
24144     case OPC_BMZI_B:
24145         gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
24146         break;
24147     case OPC_BSELI_B:
24148         gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
24149         break;
24150     case OPC_SHF_B:
24151     case OPC_SHF_H:
24152     case OPC_SHF_W:
24153         {
24154             uint8_t df = (ctx->opcode >> 24) & 0x3;
24155             if (df == DF_DOUBLE) {
24156                 generate_exception_end(ctx, EXCP_RI);
24157             } else {
24158                 TCGv_i32 tdf = tcg_const_i32(df);
24159                 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
24160                 tcg_temp_free_i32(tdf);
24161             }
24162         }
24163         break;
24164     default:
24165         MIPS_INVAL("MSA instruction");
24166         generate_exception_end(ctx, EXCP_RI);
24167         break;
24168     }
24169
24170     tcg_temp_free_i32(twd);
24171     tcg_temp_free_i32(tws);
24172     tcg_temp_free_i32(ti8);
24173 }
24174
24175 static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
24176 {
24177 #define MASK_MSA_I5(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
24178     uint8_t df = (ctx->opcode >> 21) & 0x3;
24179     int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
24180     uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
24181     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24182     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24183
24184     TCGv_i32 tdf = tcg_const_i32(df);
24185     TCGv_i32 twd = tcg_const_i32(wd);
24186     TCGv_i32 tws = tcg_const_i32(ws);
24187     TCGv_i32 timm = tcg_temp_new_i32();
24188     tcg_gen_movi_i32(timm, u5);
24189
24190     switch (MASK_MSA_I5(ctx->opcode)) {
24191     case OPC_ADDVI_df:
24192         gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
24193         break;
24194     case OPC_SUBVI_df:
24195         gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
24196         break;
24197     case OPC_MAXI_S_df:
24198         tcg_gen_movi_i32(timm, s5);
24199         gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
24200         break;
24201     case OPC_MAXI_U_df:
24202         gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
24203         break;
24204     case OPC_MINI_S_df:
24205         tcg_gen_movi_i32(timm, s5);
24206         gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
24207         break;
24208     case OPC_MINI_U_df:
24209         gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
24210         break;
24211     case OPC_CEQI_df:
24212         tcg_gen_movi_i32(timm, s5);
24213         gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
24214         break;
24215     case OPC_CLTI_S_df:
24216         tcg_gen_movi_i32(timm, s5);
24217         gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
24218         break;
24219     case OPC_CLTI_U_df:
24220         gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
24221         break;
24222     case OPC_CLEI_S_df:
24223         tcg_gen_movi_i32(timm, s5);
24224         gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
24225         break;
24226     case OPC_CLEI_U_df:
24227         gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
24228         break;
24229     case OPC_LDI_df:
24230         {
24231             int32_t s10 = sextract32(ctx->opcode, 11, 10);
24232             tcg_gen_movi_i32(timm, s10);
24233             gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
24234         }
24235         break;
24236     default:
24237         MIPS_INVAL("MSA instruction");
24238         generate_exception_end(ctx, EXCP_RI);
24239         break;
24240     }
24241
24242     tcg_temp_free_i32(tdf);
24243     tcg_temp_free_i32(twd);
24244     tcg_temp_free_i32(tws);
24245     tcg_temp_free_i32(timm);
24246 }
24247
24248 static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
24249 {
24250 #define MASK_MSA_BIT(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
24251     uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
24252     uint32_t df = 0, m = 0;
24253     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24254     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24255
24256     TCGv_i32 tdf;
24257     TCGv_i32 tm;
24258     TCGv_i32 twd;
24259     TCGv_i32 tws;
24260
24261     if ((dfm & 0x40) == 0x00) {
24262         m = dfm & 0x3f;
24263         df = DF_DOUBLE;
24264     } else if ((dfm & 0x60) == 0x40) {
24265         m = dfm & 0x1f;
24266         df = DF_WORD;
24267     } else if ((dfm & 0x70) == 0x60) {
24268         m = dfm & 0x0f;
24269         df = DF_HALF;
24270     } else if ((dfm & 0x78) == 0x70) {
24271         m = dfm & 0x7;
24272         df = DF_BYTE;
24273     } else {
24274         generate_exception_end(ctx, EXCP_RI);
24275         return;
24276     }
24277
24278     tdf = tcg_const_i32(df);
24279     tm  = tcg_const_i32(m);
24280     twd = tcg_const_i32(wd);
24281     tws = tcg_const_i32(ws);
24282
24283     switch (MASK_MSA_BIT(ctx->opcode)) {
24284     case OPC_SLLI_df:
24285         gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
24286         break;
24287     case OPC_SRAI_df:
24288         gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
24289         break;
24290     case OPC_SRLI_df:
24291         gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
24292         break;
24293     case OPC_BCLRI_df:
24294         gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
24295         break;
24296     case OPC_BSETI_df:
24297         gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
24298         break;
24299     case OPC_BNEGI_df:
24300         gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
24301         break;
24302     case OPC_BINSLI_df:
24303         gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
24304         break;
24305     case OPC_BINSRI_df:
24306         gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
24307         break;
24308     case OPC_SAT_S_df:
24309         gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
24310         break;
24311     case OPC_SAT_U_df:
24312         gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
24313         break;
24314     case OPC_SRARI_df:
24315         gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
24316         break;
24317     case OPC_SRLRI_df:
24318         gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
24319         break;
24320     default:
24321         MIPS_INVAL("MSA instruction");
24322         generate_exception_end(ctx, EXCP_RI);
24323         break;
24324     }
24325
24326     tcg_temp_free_i32(tdf);
24327     tcg_temp_free_i32(tm);
24328     tcg_temp_free_i32(twd);
24329     tcg_temp_free_i32(tws);
24330 }
24331
24332 static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
24333 {
24334 #define MASK_MSA_3R(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
24335     uint8_t df = (ctx->opcode >> 21) & 0x3;
24336     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
24337     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24338     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24339
24340     TCGv_i32 tdf = tcg_const_i32(df);
24341     TCGv_i32 twd = tcg_const_i32(wd);
24342     TCGv_i32 tws = tcg_const_i32(ws);
24343     TCGv_i32 twt = tcg_const_i32(wt);
24344
24345     switch (MASK_MSA_3R(ctx->opcode)) {
24346     case OPC_SLL_df:
24347         gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
24348         break;
24349     case OPC_ADDV_df:
24350         gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
24351         break;
24352     case OPC_CEQ_df:
24353         gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
24354         break;
24355     case OPC_ADD_A_df:
24356         gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
24357         break;
24358     case OPC_SUBS_S_df:
24359         gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
24360         break;
24361     case OPC_MULV_df:
24362         gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
24363         break;
24364     case OPC_SLD_df:
24365         gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
24366         break;
24367     case OPC_VSHF_df:
24368         gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
24369         break;
24370     case OPC_SRA_df:
24371         gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
24372         break;
24373     case OPC_SUBV_df:
24374         gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
24375         break;
24376     case OPC_ADDS_A_df:
24377         gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
24378         break;
24379     case OPC_SUBS_U_df:
24380         gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
24381         break;
24382     case OPC_MADDV_df:
24383         gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
24384         break;
24385     case OPC_SPLAT_df:
24386         gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
24387         break;
24388     case OPC_SRAR_df:
24389         gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
24390         break;
24391     case OPC_SRL_df:
24392         gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
24393         break;
24394     case OPC_MAX_S_df:
24395         gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
24396         break;
24397     case OPC_CLT_S_df:
24398         gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
24399         break;
24400     case OPC_ADDS_S_df:
24401         gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
24402         break;
24403     case OPC_SUBSUS_U_df:
24404         gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
24405         break;
24406     case OPC_MSUBV_df:
24407         gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
24408         break;
24409     case OPC_PCKEV_df:
24410         gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
24411         break;
24412     case OPC_SRLR_df:
24413         gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
24414         break;
24415     case OPC_BCLR_df:
24416         gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
24417         break;
24418     case OPC_MAX_U_df:
24419         gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
24420         break;
24421     case OPC_CLT_U_df:
24422         gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
24423         break;
24424     case OPC_ADDS_U_df:
24425         gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
24426         break;
24427     case OPC_SUBSUU_S_df:
24428         gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
24429         break;
24430     case OPC_PCKOD_df:
24431         gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
24432         break;
24433     case OPC_BSET_df:
24434         gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
24435         break;
24436     case OPC_MIN_S_df:
24437         gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
24438         break;
24439     case OPC_CLE_S_df:
24440         gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
24441         break;
24442     case OPC_AVE_S_df:
24443         gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
24444         break;
24445     case OPC_ASUB_S_df:
24446         gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
24447         break;
24448     case OPC_DIV_S_df:
24449         gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
24450         break;
24451     case OPC_ILVL_df:
24452         gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
24453         break;
24454     case OPC_BNEG_df:
24455         gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
24456         break;
24457     case OPC_MIN_U_df:
24458         gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
24459         break;
24460     case OPC_CLE_U_df:
24461         gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
24462         break;
24463     case OPC_AVE_U_df:
24464         gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
24465         break;
24466     case OPC_ASUB_U_df:
24467         gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
24468         break;
24469     case OPC_DIV_U_df:
24470         gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
24471         break;
24472     case OPC_ILVR_df:
24473         gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
24474         break;
24475     case OPC_BINSL_df:
24476         gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
24477         break;
24478     case OPC_MAX_A_df:
24479         gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
24480         break;
24481     case OPC_AVER_S_df:
24482         gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
24483         break;
24484     case OPC_MOD_S_df:
24485         gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
24486         break;
24487     case OPC_ILVEV_df:
24488         gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
24489         break;
24490     case OPC_BINSR_df:
24491         gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
24492         break;
24493     case OPC_MIN_A_df:
24494         gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
24495         break;
24496     case OPC_AVER_U_df:
24497         gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
24498         break;
24499     case OPC_MOD_U_df:
24500         gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
24501         break;
24502     case OPC_ILVOD_df:
24503         gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
24504         break;
24505
24506     case OPC_DOTP_S_df:
24507     case OPC_DOTP_U_df:
24508     case OPC_DPADD_S_df:
24509     case OPC_DPADD_U_df:
24510     case OPC_DPSUB_S_df:
24511     case OPC_HADD_S_df:
24512     case OPC_DPSUB_U_df:
24513     case OPC_HADD_U_df:
24514     case OPC_HSUB_S_df:
24515     case OPC_HSUB_U_df:
24516         if (df == DF_BYTE) {
24517             generate_exception_end(ctx, EXCP_RI);
24518             break;
24519         }
24520         switch (MASK_MSA_3R(ctx->opcode)) {
24521         case OPC_DOTP_S_df:
24522             gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
24523             break;
24524         case OPC_DOTP_U_df:
24525             gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
24526             break;
24527         case OPC_DPADD_S_df:
24528             gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
24529             break;
24530         case OPC_DPADD_U_df:
24531             gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
24532             break;
24533         case OPC_DPSUB_S_df:
24534             gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
24535             break;
24536         case OPC_HADD_S_df:
24537             gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
24538             break;
24539         case OPC_DPSUB_U_df:
24540             gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
24541             break;
24542         case OPC_HADD_U_df:
24543             gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
24544             break;
24545         case OPC_HSUB_S_df:
24546             gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
24547             break;
24548         case OPC_HSUB_U_df:
24549             gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
24550             break;
24551         }
24552         break;
24553     default:
24554         MIPS_INVAL("MSA instruction");
24555         generate_exception_end(ctx, EXCP_RI);
24556         break;
24557     }
24558     tcg_temp_free_i32(twd);
24559     tcg_temp_free_i32(tws);
24560     tcg_temp_free_i32(twt);
24561     tcg_temp_free_i32(tdf);
24562 }
24563
24564 static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
24565 {
24566 #define MASK_MSA_ELM_DF3E(op)   (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
24567     uint8_t source = (ctx->opcode >> 11) & 0x1f;
24568     uint8_t dest = (ctx->opcode >> 6) & 0x1f;
24569     TCGv telm = tcg_temp_new();
24570     TCGv_i32 tsr = tcg_const_i32(source);
24571     TCGv_i32 tdt = tcg_const_i32(dest);
24572
24573     switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
24574     case OPC_CTCMSA:
24575         gen_load_gpr(telm, source);
24576         gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
24577         break;
24578     case OPC_CFCMSA:
24579         gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
24580         gen_store_gpr(telm, dest);
24581         break;
24582     case OPC_MOVE_V:
24583         gen_helper_msa_move_v(cpu_env, tdt, tsr);
24584         break;
24585     default:
24586         MIPS_INVAL("MSA instruction");
24587         generate_exception_end(ctx, EXCP_RI);
24588         break;
24589     }
24590
24591     tcg_temp_free(telm);
24592     tcg_temp_free_i32(tdt);
24593     tcg_temp_free_i32(tsr);
24594 }
24595
24596 static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
24597         uint32_t n)
24598 {
24599 #define MASK_MSA_ELM(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
24600     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24601     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24602
24603     TCGv_i32 tws = tcg_const_i32(ws);
24604     TCGv_i32 twd = tcg_const_i32(wd);
24605     TCGv_i32 tn  = tcg_const_i32(n);
24606     TCGv_i32 tdf = tcg_const_i32(df);
24607
24608     switch (MASK_MSA_ELM(ctx->opcode)) {
24609     case OPC_SLDI_df:
24610         gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
24611         break;
24612     case OPC_SPLATI_df:
24613         gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
24614         break;
24615     case OPC_INSVE_df:
24616         gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
24617         break;
24618     case OPC_COPY_S_df:
24619     case OPC_COPY_U_df:
24620     case OPC_INSERT_df:
24621 #if !defined(TARGET_MIPS64)
24622         /* Double format valid only for MIPS64 */
24623         if (df == DF_DOUBLE) {
24624             generate_exception_end(ctx, EXCP_RI);
24625             break;
24626         }
24627 #endif
24628         switch (MASK_MSA_ELM(ctx->opcode)) {
24629         case OPC_COPY_S_df:
24630             if (likely(wd != 0)) {
24631                 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
24632             }
24633             break;
24634         case OPC_COPY_U_df:
24635             if (likely(wd != 0)) {
24636                 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
24637             }
24638             break;
24639         case OPC_INSERT_df:
24640             gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
24641             break;
24642         }
24643         break;
24644     default:
24645         MIPS_INVAL("MSA instruction");
24646         generate_exception_end(ctx, EXCP_RI);
24647     }
24648     tcg_temp_free_i32(twd);
24649     tcg_temp_free_i32(tws);
24650     tcg_temp_free_i32(tn);
24651     tcg_temp_free_i32(tdf);
24652 }
24653
24654 static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
24655 {
24656     uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
24657     uint32_t df = 0, n = 0;
24658
24659     if ((dfn & 0x30) == 0x00) {
24660         n = dfn & 0x0f;
24661         df = DF_BYTE;
24662     } else if ((dfn & 0x38) == 0x20) {
24663         n = dfn & 0x07;
24664         df = DF_HALF;
24665     } else if ((dfn & 0x3c) == 0x30) {
24666         n = dfn & 0x03;
24667         df = DF_WORD;
24668     } else if ((dfn & 0x3e) == 0x38) {
24669         n = dfn & 0x01;
24670         df = DF_DOUBLE;
24671     } else if (dfn == 0x3E) {
24672         /* CTCMSA, CFCMSA, MOVE.V */
24673         gen_msa_elm_3e(env, ctx);
24674         return;
24675     } else {
24676         generate_exception_end(ctx, EXCP_RI);
24677         return;
24678     }
24679
24680     gen_msa_elm_df(env, ctx, df, n);
24681 }
24682
24683 static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
24684 {
24685 #define MASK_MSA_3RF(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
24686     uint8_t df = (ctx->opcode >> 21) & 0x1;
24687     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
24688     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24689     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24690
24691     TCGv_i32 twd = tcg_const_i32(wd);
24692     TCGv_i32 tws = tcg_const_i32(ws);
24693     TCGv_i32 twt = tcg_const_i32(wt);
24694     TCGv_i32 tdf = tcg_temp_new_i32();
24695
24696     /* adjust df value for floating-point instruction */
24697     tcg_gen_movi_i32(tdf, df + 2);
24698
24699     switch (MASK_MSA_3RF(ctx->opcode)) {
24700     case OPC_FCAF_df:
24701         gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
24702         break;
24703     case OPC_FADD_df:
24704         gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
24705         break;
24706     case OPC_FCUN_df:
24707         gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
24708         break;
24709     case OPC_FSUB_df:
24710         gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
24711         break;
24712     case OPC_FCOR_df:
24713         gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
24714         break;
24715     case OPC_FCEQ_df:
24716         gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
24717         break;
24718     case OPC_FMUL_df:
24719         gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
24720         break;
24721     case OPC_FCUNE_df:
24722         gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
24723         break;
24724     case OPC_FCUEQ_df:
24725         gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
24726         break;
24727     case OPC_FDIV_df:
24728         gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
24729         break;
24730     case OPC_FCNE_df:
24731         gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
24732         break;
24733     case OPC_FCLT_df:
24734         gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
24735         break;
24736     case OPC_FMADD_df:
24737         gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
24738         break;
24739     case OPC_MUL_Q_df:
24740         tcg_gen_movi_i32(tdf, df + 1);
24741         gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
24742         break;
24743     case OPC_FCULT_df:
24744         gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
24745         break;
24746     case OPC_FMSUB_df:
24747         gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
24748         break;
24749     case OPC_MADD_Q_df:
24750         tcg_gen_movi_i32(tdf, df + 1);
24751         gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
24752         break;
24753     case OPC_FCLE_df:
24754         gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
24755         break;
24756     case OPC_MSUB_Q_df:
24757         tcg_gen_movi_i32(tdf, df + 1);
24758         gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
24759         break;
24760     case OPC_FCULE_df:
24761         gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
24762         break;
24763     case OPC_FEXP2_df:
24764         gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
24765         break;
24766     case OPC_FSAF_df:
24767         gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
24768         break;
24769     case OPC_FEXDO_df:
24770         gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
24771         break;
24772     case OPC_FSUN_df:
24773         gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
24774         break;
24775     case OPC_FSOR_df:
24776         gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
24777         break;
24778     case OPC_FSEQ_df:
24779         gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
24780         break;
24781     case OPC_FTQ_df:
24782         gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
24783         break;
24784     case OPC_FSUNE_df:
24785         gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
24786         break;
24787     case OPC_FSUEQ_df:
24788         gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
24789         break;
24790     case OPC_FSNE_df:
24791         gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
24792         break;
24793     case OPC_FSLT_df:
24794         gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
24795         break;
24796     case OPC_FMIN_df:
24797         gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
24798         break;
24799     case OPC_MULR_Q_df:
24800         tcg_gen_movi_i32(tdf, df + 1);
24801         gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
24802         break;
24803     case OPC_FSULT_df:
24804         gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
24805         break;
24806     case OPC_FMIN_A_df:
24807         gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
24808         break;
24809     case OPC_MADDR_Q_df:
24810         tcg_gen_movi_i32(tdf, df + 1);
24811         gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
24812         break;
24813     case OPC_FSLE_df:
24814         gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
24815         break;
24816     case OPC_FMAX_df:
24817         gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
24818         break;
24819     case OPC_MSUBR_Q_df:
24820         tcg_gen_movi_i32(tdf, df + 1);
24821         gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
24822         break;
24823     case OPC_FSULE_df:
24824         gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
24825         break;
24826     case OPC_FMAX_A_df:
24827         gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
24828         break;
24829     default:
24830         MIPS_INVAL("MSA instruction");
24831         generate_exception_end(ctx, EXCP_RI);
24832         break;
24833     }
24834
24835     tcg_temp_free_i32(twd);
24836     tcg_temp_free_i32(tws);
24837     tcg_temp_free_i32(twt);
24838     tcg_temp_free_i32(tdf);
24839 }
24840
24841 static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
24842 {
24843 #define MASK_MSA_2R(op)     (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
24844                             (op & (0x7 << 18)))
24845     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
24846     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24847     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24848     uint8_t df = (ctx->opcode >> 16) & 0x3;
24849     TCGv_i32 twd = tcg_const_i32(wd);
24850     TCGv_i32 tws = tcg_const_i32(ws);
24851     TCGv_i32 twt = tcg_const_i32(wt);
24852     TCGv_i32 tdf = tcg_const_i32(df);
24853
24854     switch (MASK_MSA_2R(ctx->opcode)) {
24855     case OPC_FILL_df:
24856 #if !defined(TARGET_MIPS64)
24857         /* Double format valid only for MIPS64 */
24858         if (df == DF_DOUBLE) {
24859             generate_exception_end(ctx, EXCP_RI);
24860             break;
24861         }
24862 #endif
24863         gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
24864         break;
24865     case OPC_PCNT_df:
24866         gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
24867         break;
24868     case OPC_NLOC_df:
24869         gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
24870         break;
24871     case OPC_NLZC_df:
24872         gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
24873         break;
24874     default:
24875         MIPS_INVAL("MSA instruction");
24876         generate_exception_end(ctx, EXCP_RI);
24877         break;
24878     }
24879
24880     tcg_temp_free_i32(twd);
24881     tcg_temp_free_i32(tws);
24882     tcg_temp_free_i32(twt);
24883     tcg_temp_free_i32(tdf);
24884 }
24885
24886 static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
24887 {
24888 #define MASK_MSA_2RF(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
24889                             (op & (0xf << 17)))
24890     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
24891     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24892     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24893     uint8_t df = (ctx->opcode >> 16) & 0x1;
24894     TCGv_i32 twd = tcg_const_i32(wd);
24895     TCGv_i32 tws = tcg_const_i32(ws);
24896     TCGv_i32 twt = tcg_const_i32(wt);
24897     /* adjust df value for floating-point instruction */
24898     TCGv_i32 tdf = tcg_const_i32(df + 2);
24899
24900     switch (MASK_MSA_2RF(ctx->opcode)) {
24901     case OPC_FCLASS_df:
24902         gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
24903         break;
24904     case OPC_FTRUNC_S_df:
24905         gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
24906         break;
24907     case OPC_FTRUNC_U_df:
24908         gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
24909         break;
24910     case OPC_FSQRT_df:
24911         gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
24912         break;
24913     case OPC_FRSQRT_df:
24914         gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
24915         break;
24916     case OPC_FRCP_df:
24917         gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
24918         break;
24919     case OPC_FRINT_df:
24920         gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
24921         break;
24922     case OPC_FLOG2_df:
24923         gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
24924         break;
24925     case OPC_FEXUPL_df:
24926         gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
24927         break;
24928     case OPC_FEXUPR_df:
24929         gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
24930         break;
24931     case OPC_FFQL_df:
24932         gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
24933         break;
24934     case OPC_FFQR_df:
24935         gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
24936         break;
24937     case OPC_FTINT_S_df:
24938         gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
24939         break;
24940     case OPC_FTINT_U_df:
24941         gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
24942         break;
24943     case OPC_FFINT_S_df:
24944         gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
24945         break;
24946     case OPC_FFINT_U_df:
24947         gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
24948         break;
24949     }
24950
24951     tcg_temp_free_i32(twd);
24952     tcg_temp_free_i32(tws);
24953     tcg_temp_free_i32(twt);
24954     tcg_temp_free_i32(tdf);
24955 }
24956
24957 static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
24958 {
24959 #define MASK_MSA_VEC(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
24960     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
24961     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24962     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24963     TCGv_i32 twd = tcg_const_i32(wd);
24964     TCGv_i32 tws = tcg_const_i32(ws);
24965     TCGv_i32 twt = tcg_const_i32(wt);
24966
24967     switch (MASK_MSA_VEC(ctx->opcode)) {
24968     case OPC_AND_V:
24969         gen_helper_msa_and_v(cpu_env, twd, tws, twt);
24970         break;
24971     case OPC_OR_V:
24972         gen_helper_msa_or_v(cpu_env, twd, tws, twt);
24973         break;
24974     case OPC_NOR_V:
24975         gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
24976         break;
24977     case OPC_XOR_V:
24978         gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
24979         break;
24980     case OPC_BMNZ_V:
24981         gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
24982         break;
24983     case OPC_BMZ_V:
24984         gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
24985         break;
24986     case OPC_BSEL_V:
24987         gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
24988         break;
24989     default:
24990         MIPS_INVAL("MSA instruction");
24991         generate_exception_end(ctx, EXCP_RI);
24992         break;
24993     }
24994
24995     tcg_temp_free_i32(twd);
24996     tcg_temp_free_i32(tws);
24997     tcg_temp_free_i32(twt);
24998 }
24999
25000 static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
25001 {
25002     switch (MASK_MSA_VEC(ctx->opcode)) {
25003     case OPC_AND_V:
25004     case OPC_OR_V:
25005     case OPC_NOR_V:
25006     case OPC_XOR_V:
25007     case OPC_BMNZ_V:
25008     case OPC_BMZ_V:
25009     case OPC_BSEL_V:
25010         gen_msa_vec_v(env, ctx);
25011         break;
25012     case OPC_MSA_2R:
25013         gen_msa_2r(env, ctx);
25014         break;
25015     case OPC_MSA_2RF:
25016         gen_msa_2rf(env, ctx);
25017         break;
25018     default:
25019         MIPS_INVAL("MSA instruction");
25020         generate_exception_end(ctx, EXCP_RI);
25021         break;
25022     }
25023 }
25024
25025 static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
25026 {
25027     uint32_t opcode = ctx->opcode;
25028     check_insn(ctx, ASE_MSA);
25029     check_msa_access(ctx);
25030
25031     switch (MASK_MSA_MINOR(opcode)) {
25032     case OPC_MSA_I8_00:
25033     case OPC_MSA_I8_01:
25034     case OPC_MSA_I8_02:
25035         gen_msa_i8(env, ctx);
25036         break;
25037     case OPC_MSA_I5_06:
25038     case OPC_MSA_I5_07:
25039         gen_msa_i5(env, ctx);
25040         break;
25041     case OPC_MSA_BIT_09:
25042     case OPC_MSA_BIT_0A:
25043         gen_msa_bit(env, ctx);
25044         break;
25045     case OPC_MSA_3R_0D:
25046     case OPC_MSA_3R_0E:
25047     case OPC_MSA_3R_0F:
25048     case OPC_MSA_3R_10:
25049     case OPC_MSA_3R_11:
25050     case OPC_MSA_3R_12:
25051     case OPC_MSA_3R_13:
25052     case OPC_MSA_3R_14:
25053     case OPC_MSA_3R_15:
25054         gen_msa_3r(env, ctx);
25055         break;
25056     case OPC_MSA_ELM:
25057         gen_msa_elm(env, ctx);
25058         break;
25059     case OPC_MSA_3RF_1A:
25060     case OPC_MSA_3RF_1B:
25061     case OPC_MSA_3RF_1C:
25062         gen_msa_3rf(env, ctx);
25063         break;
25064     case OPC_MSA_VEC:
25065         gen_msa_vec(env, ctx);
25066         break;
25067     case OPC_LD_B:
25068     case OPC_LD_H:
25069     case OPC_LD_W:
25070     case OPC_LD_D:
25071     case OPC_ST_B:
25072     case OPC_ST_H:
25073     case OPC_ST_W:
25074     case OPC_ST_D:
25075         {
25076             int32_t s10 = sextract32(ctx->opcode, 16, 10);
25077             uint8_t rs = (ctx->opcode >> 11) & 0x1f;
25078             uint8_t wd = (ctx->opcode >> 6) & 0x1f;
25079             uint8_t df = (ctx->opcode >> 0) & 0x3;
25080
25081             TCGv_i32 twd = tcg_const_i32(wd);
25082             TCGv taddr = tcg_temp_new();
25083             gen_base_offset_addr(ctx, taddr, rs, s10 << df);
25084
25085             switch (MASK_MSA_MINOR(opcode)) {
25086             case OPC_LD_B:
25087                 gen_helper_msa_ld_b(cpu_env, twd, taddr);
25088                 break;
25089             case OPC_LD_H:
25090                 gen_helper_msa_ld_h(cpu_env, twd, taddr);
25091                 break;
25092             case OPC_LD_W:
25093                 gen_helper_msa_ld_w(cpu_env, twd, taddr);
25094                 break;
25095             case OPC_LD_D:
25096                 gen_helper_msa_ld_d(cpu_env, twd, taddr);
25097                 break;
25098             case OPC_ST_B:
25099                 gen_helper_msa_st_b(cpu_env, twd, taddr);
25100                 break;
25101             case OPC_ST_H:
25102                 gen_helper_msa_st_h(cpu_env, twd, taddr);
25103                 break;
25104             case OPC_ST_W:
25105                 gen_helper_msa_st_w(cpu_env, twd, taddr);
25106                 break;
25107             case OPC_ST_D:
25108                 gen_helper_msa_st_d(cpu_env, twd, taddr);
25109                 break;
25110             }
25111
25112             tcg_temp_free_i32(twd);
25113             tcg_temp_free(taddr);
25114         }
25115         break;
25116     default:
25117         MIPS_INVAL("MSA instruction");
25118         generate_exception_end(ctx, EXCP_RI);
25119         break;
25120     }
25121
25122 }
25123
25124 static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
25125 {
25126     int32_t offset;
25127     int rs, rt, rd, sa;
25128     uint32_t op, op1;
25129     int16_t imm;
25130
25131     /* make sure instructions are on a word boundary */
25132     if (ctx->base.pc_next & 0x3) {
25133         env->CP0_BadVAddr = ctx->base.pc_next;
25134         generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
25135         return;
25136     }
25137
25138     /* Handle blikely not taken case */
25139     if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
25140         TCGLabel *l1 = gen_new_label();
25141
25142         tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
25143         tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
25144         gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
25145         gen_set_label(l1);
25146     }
25147
25148     op = MASK_OP_MAJOR(ctx->opcode);
25149     rs = (ctx->opcode >> 21) & 0x1f;
25150     rt = (ctx->opcode >> 16) & 0x1f;
25151     rd = (ctx->opcode >> 11) & 0x1f;
25152     sa = (ctx->opcode >> 6) & 0x1f;
25153     imm = (int16_t)ctx->opcode;
25154     switch (op) {
25155     case OPC_SPECIAL:
25156         decode_opc_special(env, ctx);
25157         break;
25158     case OPC_SPECIAL2:
25159         decode_opc_special2_legacy(env, ctx);
25160         break;
25161     case OPC_SPECIAL3:
25162         decode_opc_special3(env, ctx);
25163         break;
25164     case OPC_REGIMM:
25165         op1 = MASK_REGIMM(ctx->opcode);
25166         switch (op1) {
25167         case OPC_BLTZL: /* REGIMM branches */
25168         case OPC_BGEZL:
25169         case OPC_BLTZALL:
25170         case OPC_BGEZALL:
25171             check_insn(ctx, ISA_MIPS2);
25172             check_insn_opc_removed(ctx, ISA_MIPS32R6);
25173             /* Fallthrough */
25174         case OPC_BLTZ:
25175         case OPC_BGEZ:
25176             gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
25177             break;
25178         case OPC_BLTZAL:
25179         case OPC_BGEZAL:
25180             if (ctx->insn_flags & ISA_MIPS32R6) {
25181                 if (rs == 0) {
25182                     /* OPC_NAL, OPC_BAL */
25183                     gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
25184                 } else {
25185                     generate_exception_end(ctx, EXCP_RI);
25186                 }
25187             } else {
25188                 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
25189             }
25190             break;
25191         case OPC_TGEI: /* REGIMM traps */
25192         case OPC_TGEIU:
25193         case OPC_TLTI:
25194         case OPC_TLTIU:
25195         case OPC_TEQI:
25196
25197         case OPC_TNEI:
25198             check_insn(ctx, ISA_MIPS2);
25199             check_insn_opc_removed(ctx, ISA_MIPS32R6);
25200             gen_trap(ctx, op1, rs, -1, imm);
25201             break;
25202         case OPC_SIGRIE:
25203             check_insn(ctx, ISA_MIPS32R6);
25204             generate_exception_end(ctx, EXCP_RI);
25205             break;
25206         case OPC_SYNCI:
25207             check_insn(ctx, ISA_MIPS32R2);
25208             /* Break the TB to be able to sync copied instructions
25209                immediately */
25210             ctx->base.is_jmp = DISAS_STOP;
25211             break;
25212         case OPC_BPOSGE32:    /* MIPS DSP branch */
25213 #if defined(TARGET_MIPS64)
25214         case OPC_BPOSGE64:
25215 #endif
25216             check_dsp(ctx);
25217             gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
25218             break;
25219 #if defined(TARGET_MIPS64)
25220         case OPC_DAHI:
25221             check_insn(ctx, ISA_MIPS32R6);
25222             check_mips_64(ctx);
25223             if (rs != 0) {
25224                 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
25225             }
25226             break;
25227         case OPC_DATI:
25228             check_insn(ctx, ISA_MIPS32R6);
25229             check_mips_64(ctx);
25230             if (rs != 0) {
25231                 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
25232             }
25233             break;
25234 #endif
25235         default:            /* Invalid */
25236             MIPS_INVAL("regimm");
25237             generate_exception_end(ctx, EXCP_RI);
25238             break;
25239         }
25240         break;
25241     case OPC_CP0:
25242         check_cp0_enabled(ctx);
25243         op1 = MASK_CP0(ctx->opcode);
25244         switch (op1) {
25245         case OPC_MFC0:
25246         case OPC_MTC0:
25247         case OPC_MFTR:
25248         case OPC_MTTR:
25249         case OPC_MFHC0:
25250         case OPC_MTHC0:
25251 #if defined(TARGET_MIPS64)
25252         case OPC_DMFC0:
25253         case OPC_DMTC0:
25254 #endif
25255 #ifndef CONFIG_USER_ONLY
25256             gen_cp0(env, ctx, op1, rt, rd);
25257 #endif /* !CONFIG_USER_ONLY */
25258             break;
25259         case OPC_C0:
25260         case OPC_C0_1:
25261         case OPC_C0_2:
25262         case OPC_C0_3:
25263         case OPC_C0_4:
25264         case OPC_C0_5:
25265         case OPC_C0_6:
25266         case OPC_C0_7:
25267         case OPC_C0_8:
25268         case OPC_C0_9:
25269         case OPC_C0_A:
25270         case OPC_C0_B:
25271         case OPC_C0_C:
25272         case OPC_C0_D:
25273         case OPC_C0_E:
25274         case OPC_C0_F:
25275 #ifndef CONFIG_USER_ONLY
25276             gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
25277 #endif /* !CONFIG_USER_ONLY */
25278             break;
25279         case OPC_MFMC0:
25280 #ifndef CONFIG_USER_ONLY
25281             {
25282                 uint32_t op2;
25283                 TCGv t0 = tcg_temp_new();
25284
25285                 op2 = MASK_MFMC0(ctx->opcode);
25286                 switch (op2) {
25287                 case OPC_DMT:
25288                     check_cp0_mt(ctx);
25289                     gen_helper_dmt(t0);
25290                     gen_store_gpr(t0, rt);
25291                     break;
25292                 case OPC_EMT:
25293                     check_cp0_mt(ctx);
25294                     gen_helper_emt(t0);
25295                     gen_store_gpr(t0, rt);
25296                     break;
25297                 case OPC_DVPE:
25298                     check_cp0_mt(ctx);
25299                     gen_helper_dvpe(t0, cpu_env);
25300                     gen_store_gpr(t0, rt);
25301                     break;
25302                 case OPC_EVPE:
25303                     check_cp0_mt(ctx);
25304                     gen_helper_evpe(t0, cpu_env);
25305                     gen_store_gpr(t0, rt);
25306                     break;
25307                 case OPC_DVP:
25308                     check_insn(ctx, ISA_MIPS32R6);
25309                     if (ctx->vp) {
25310                         gen_helper_dvp(t0, cpu_env);
25311                         gen_store_gpr(t0, rt);
25312                     }
25313                     break;
25314                 case OPC_EVP:
25315                     check_insn(ctx, ISA_MIPS32R6);
25316                     if (ctx->vp) {
25317                         gen_helper_evp(t0, cpu_env);
25318                         gen_store_gpr(t0, rt);
25319                     }
25320                     break;
25321                 case OPC_DI:
25322                     check_insn(ctx, ISA_MIPS32R2);
25323                     save_cpu_state(ctx, 1);
25324                     gen_helper_di(t0, cpu_env);
25325                     gen_store_gpr(t0, rt);
25326                     /* Stop translation as we may have switched
25327                        the execution mode.  */
25328                     ctx->base.is_jmp = DISAS_STOP;
25329                     break;
25330                 case OPC_EI:
25331                     check_insn(ctx, ISA_MIPS32R2);
25332                     save_cpu_state(ctx, 1);
25333                     gen_helper_ei(t0, cpu_env);
25334                     gen_store_gpr(t0, rt);
25335                     /* DISAS_STOP isn't sufficient, we need to ensure we break
25336                        out of translated code to check for pending interrupts */
25337                     gen_save_pc(ctx->base.pc_next + 4);
25338                     ctx->base.is_jmp = DISAS_EXIT;
25339                     break;
25340                 default:            /* Invalid */
25341                     MIPS_INVAL("mfmc0");
25342                     generate_exception_end(ctx, EXCP_RI);
25343                     break;
25344                 }
25345                 tcg_temp_free(t0);
25346             }
25347 #endif /* !CONFIG_USER_ONLY */
25348             break;
25349         case OPC_RDPGPR:
25350             check_insn(ctx, ISA_MIPS32R2);
25351             gen_load_srsgpr(rt, rd);
25352             break;
25353         case OPC_WRPGPR:
25354             check_insn(ctx, ISA_MIPS32R2);
25355             gen_store_srsgpr(rt, rd);
25356             break;
25357         default:
25358             MIPS_INVAL("cp0");
25359             generate_exception_end(ctx, EXCP_RI);
25360             break;
25361         }
25362         break;
25363     case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
25364         if (ctx->insn_flags & ISA_MIPS32R6) {
25365             /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
25366             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25367         } else {
25368             /* OPC_ADDI */
25369             /* Arithmetic with immediate opcode */
25370             gen_arith_imm(ctx, op, rt, rs, imm);
25371         }
25372         break;
25373     case OPC_ADDIU:
25374          gen_arith_imm(ctx, op, rt, rs, imm);
25375          break;
25376     case OPC_SLTI: /* Set on less than with immediate opcode */
25377     case OPC_SLTIU:
25378          gen_slt_imm(ctx, op, rt, rs, imm);
25379          break;
25380     case OPC_ANDI: /* Arithmetic with immediate opcode */
25381     case OPC_LUI: /* OPC_AUI */
25382     case OPC_ORI:
25383     case OPC_XORI:
25384          gen_logic_imm(ctx, op, rt, rs, imm);
25385          break;
25386     case OPC_J: /* Jump */
25387     case OPC_JAL:
25388          offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
25389          gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
25390          break;
25391     /* Branch */
25392     case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
25393         if (ctx->insn_flags & ISA_MIPS32R6) {
25394             if (rt == 0) {
25395                 generate_exception_end(ctx, EXCP_RI);
25396                 break;
25397             }
25398             /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
25399             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25400         } else {
25401             /* OPC_BLEZL */
25402             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
25403         }
25404         break;
25405     case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
25406         if (ctx->insn_flags & ISA_MIPS32R6) {
25407             if (rt == 0) {
25408                 generate_exception_end(ctx, EXCP_RI);
25409                 break;
25410             }
25411             /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
25412             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25413         } else {
25414             /* OPC_BGTZL */
25415             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
25416         }
25417         break;
25418     case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
25419         if (rt == 0) {
25420             /* OPC_BLEZ */
25421             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
25422         } else {
25423             check_insn(ctx, ISA_MIPS32R6);
25424             /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
25425             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25426         }
25427         break;
25428     case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
25429         if (rt == 0) {
25430             /* OPC_BGTZ */
25431             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
25432         } else {
25433             check_insn(ctx, ISA_MIPS32R6);
25434             /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
25435             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25436         }
25437         break;
25438     case OPC_BEQL:
25439     case OPC_BNEL:
25440         check_insn(ctx, ISA_MIPS2);
25441          check_insn_opc_removed(ctx, ISA_MIPS32R6);
25442         /* Fallthrough */
25443     case OPC_BEQ:
25444     case OPC_BNE:
25445          gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
25446          break;
25447     case OPC_LL: /* Load and stores */
25448         check_insn(ctx, ISA_MIPS2);
25449         /* Fallthrough */
25450     case OPC_LWL:
25451     case OPC_LWR:
25452         check_insn_opc_removed(ctx, ISA_MIPS32R6);
25453          /* Fallthrough */
25454     case OPC_LB:
25455     case OPC_LH:
25456     case OPC_LW:
25457     case OPC_LWPC:
25458     case OPC_LBU:
25459     case OPC_LHU:
25460          gen_ld(ctx, op, rt, rs, imm);
25461          break;
25462     case OPC_SWL:
25463     case OPC_SWR:
25464         check_insn_opc_removed(ctx, ISA_MIPS32R6);
25465         /* fall through */
25466     case OPC_SB:
25467     case OPC_SH:
25468     case OPC_SW:
25469          gen_st(ctx, op, rt, rs, imm);
25470          break;
25471     case OPC_SC:
25472         check_insn(ctx, ISA_MIPS2);
25473          check_insn_opc_removed(ctx, ISA_MIPS32R6);
25474          gen_st_cond(ctx, op, rt, rs, imm);
25475          break;
25476     case OPC_CACHE:
25477         check_insn_opc_removed(ctx, ISA_MIPS32R6);
25478         check_cp0_enabled(ctx);
25479         check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
25480         if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
25481             gen_cache_operation(ctx, rt, rs, imm);
25482         }
25483         /* Treat as NOP. */
25484         break;
25485     case OPC_PREF:
25486         check_insn_opc_removed(ctx, ISA_MIPS32R6);
25487         check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
25488         /* Treat as NOP. */
25489         break;
25490
25491     /* Floating point (COP1). */
25492     case OPC_LWC1:
25493     case OPC_LDC1:
25494     case OPC_SWC1:
25495     case OPC_SDC1:
25496         gen_cop1_ldst(ctx, op, rt, rs, imm);
25497         break;
25498
25499     case OPC_CP1:
25500         op1 = MASK_CP1(ctx->opcode);
25501
25502         switch (op1) {
25503         case OPC_MFHC1:
25504         case OPC_MTHC1:
25505             check_cp1_enabled(ctx);
25506             check_insn(ctx, ISA_MIPS32R2);
25507             /* fall through */
25508         case OPC_MFC1:
25509         case OPC_CFC1:
25510         case OPC_MTC1:
25511         case OPC_CTC1:
25512             check_cp1_enabled(ctx);
25513             gen_cp1(ctx, op1, rt, rd);
25514             break;
25515 #if defined(TARGET_MIPS64)
25516         case OPC_DMFC1:
25517         case OPC_DMTC1:
25518             check_cp1_enabled(ctx);
25519             check_insn(ctx, ISA_MIPS3);
25520             check_mips_64(ctx);
25521             gen_cp1(ctx, op1, rt, rd);
25522             break;
25523 #endif
25524         case OPC_BC1EQZ: /* OPC_BC1ANY2 */
25525             check_cp1_enabled(ctx);
25526             if (ctx->insn_flags & ISA_MIPS32R6) {
25527                 /* OPC_BC1EQZ */
25528                 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
25529                                        rt, imm << 2, 4);
25530             } else {
25531                 /* OPC_BC1ANY2 */
25532                 check_cop1x(ctx);
25533                 check_insn(ctx, ASE_MIPS3D);
25534                 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
25535                                     (rt >> 2) & 0x7, imm << 2);
25536             }
25537             break;
25538         case OPC_BC1NEZ:
25539             check_cp1_enabled(ctx);
25540             check_insn(ctx, ISA_MIPS32R6);
25541             gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
25542                                    rt, imm << 2, 4);
25543             break;
25544         case OPC_BC1ANY4:
25545             check_cp1_enabled(ctx);
25546             check_insn_opc_removed(ctx, ISA_MIPS32R6);
25547             check_cop1x(ctx);
25548             check_insn(ctx, ASE_MIPS3D);
25549             /* fall through */
25550         case OPC_BC1:
25551             check_cp1_enabled(ctx);
25552             check_insn_opc_removed(ctx, ISA_MIPS32R6);
25553             gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
25554                                 (rt >> 2) & 0x7, imm << 2);
25555             break;
25556         case OPC_PS_FMT:
25557             check_ps(ctx);
25558             /* fall through */
25559         case OPC_S_FMT:
25560         case OPC_D_FMT:
25561             check_cp1_enabled(ctx);
25562             gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
25563                        (imm >> 8) & 0x7);
25564             break;
25565         case OPC_W_FMT:
25566         case OPC_L_FMT:
25567         {
25568             int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
25569             check_cp1_enabled(ctx);
25570             if (ctx->insn_flags & ISA_MIPS32R6) {
25571                 switch (r6_op) {
25572                 case R6_OPC_CMP_AF_S:
25573                 case R6_OPC_CMP_UN_S:
25574                 case R6_OPC_CMP_EQ_S:
25575                 case R6_OPC_CMP_UEQ_S:
25576                 case R6_OPC_CMP_LT_S:
25577                 case R6_OPC_CMP_ULT_S:
25578                 case R6_OPC_CMP_LE_S:
25579                 case R6_OPC_CMP_ULE_S:
25580                 case R6_OPC_CMP_SAF_S:
25581                 case R6_OPC_CMP_SUN_S:
25582                 case R6_OPC_CMP_SEQ_S:
25583                 case R6_OPC_CMP_SEUQ_S:
25584                 case R6_OPC_CMP_SLT_S:
25585                 case R6_OPC_CMP_SULT_S:
25586                 case R6_OPC_CMP_SLE_S:
25587                 case R6_OPC_CMP_SULE_S:
25588                 case R6_OPC_CMP_OR_S:
25589                 case R6_OPC_CMP_UNE_S:
25590                 case R6_OPC_CMP_NE_S:
25591                 case R6_OPC_CMP_SOR_S:
25592                 case R6_OPC_CMP_SUNE_S:
25593                 case R6_OPC_CMP_SNE_S:
25594                     gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
25595                     break;
25596                 case R6_OPC_CMP_AF_D:
25597                 case R6_OPC_CMP_UN_D:
25598                 case R6_OPC_CMP_EQ_D:
25599                 case R6_OPC_CMP_UEQ_D:
25600                 case R6_OPC_CMP_LT_D:
25601                 case R6_OPC_CMP_ULT_D:
25602                 case R6_OPC_CMP_LE_D:
25603                 case R6_OPC_CMP_ULE_D:
25604                 case R6_OPC_CMP_SAF_D:
25605                 case R6_OPC_CMP_SUN_D:
25606                 case R6_OPC_CMP_SEQ_D:
25607                 case R6_OPC_CMP_SEUQ_D:
25608                 case R6_OPC_CMP_SLT_D:
25609                 case R6_OPC_CMP_SULT_D:
25610                 case R6_OPC_CMP_SLE_D:
25611                 case R6_OPC_CMP_SULE_D:
25612                 case R6_OPC_CMP_OR_D:
25613                 case R6_OPC_CMP_UNE_D:
25614                 case R6_OPC_CMP_NE_D:
25615                 case R6_OPC_CMP_SOR_D:
25616                 case R6_OPC_CMP_SUNE_D:
25617                 case R6_OPC_CMP_SNE_D:
25618                     gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
25619                     break;
25620                 default:
25621                     gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
25622                                rt, rd, sa, (imm >> 8) & 0x7);
25623
25624                     break;
25625                 }
25626             } else {
25627                 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
25628                            (imm >> 8) & 0x7);
25629             }
25630             break;
25631         }
25632         case OPC_BZ_V:
25633         case OPC_BNZ_V:
25634         case OPC_BZ_B:
25635         case OPC_BZ_H:
25636         case OPC_BZ_W:
25637         case OPC_BZ_D:
25638         case OPC_BNZ_B:
25639         case OPC_BNZ_H:
25640         case OPC_BNZ_W:
25641         case OPC_BNZ_D:
25642             check_insn(ctx, ASE_MSA);
25643             gen_msa_branch(env, ctx, op1);
25644             break;
25645         default:
25646             MIPS_INVAL("cp1");
25647             generate_exception_end(ctx, EXCP_RI);
25648             break;
25649         }
25650         break;
25651
25652     /* Compact branches [R6] and COP2 [non-R6] */
25653     case OPC_BC: /* OPC_LWC2 */
25654     case OPC_BALC: /* OPC_SWC2 */
25655         if (ctx->insn_flags & ISA_MIPS32R6) {
25656             /* OPC_BC, OPC_BALC */
25657             gen_compute_compact_branch(ctx, op, 0, 0,
25658                                        sextract32(ctx->opcode << 2, 0, 28));
25659         } else {
25660             /* OPC_LWC2, OPC_SWC2 */
25661             /* COP2: Not implemented. */
25662             generate_exception_err(ctx, EXCP_CpU, 2);
25663         }
25664         break;
25665     case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
25666     case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
25667         if (ctx->insn_flags & ISA_MIPS32R6) {
25668             if (rs != 0) {
25669                 /* OPC_BEQZC, OPC_BNEZC */
25670                 gen_compute_compact_branch(ctx, op, rs, 0,
25671                                            sextract32(ctx->opcode << 2, 0, 23));
25672             } else {
25673                 /* OPC_JIC, OPC_JIALC */
25674                 gen_compute_compact_branch(ctx, op, 0, rt, imm);
25675             }
25676         } else {
25677             /* OPC_LWC2, OPC_SWC2 */
25678             /* COP2: Not implemented. */
25679             generate_exception_err(ctx, EXCP_CpU, 2);
25680         }
25681         break;
25682     case OPC_CP2:
25683         check_insn(ctx, INSN_LOONGSON2F);
25684         /* Note that these instructions use different fields.  */
25685         gen_loongson_multimedia(ctx, sa, rd, rt);
25686         break;
25687
25688     case OPC_CP3:
25689         check_insn_opc_removed(ctx, ISA_MIPS32R6);
25690         if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
25691             check_cp1_enabled(ctx);
25692             op1 = MASK_CP3(ctx->opcode);
25693             switch (op1) {
25694             case OPC_LUXC1:
25695             case OPC_SUXC1:
25696                 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
25697                 /* Fallthrough */
25698             case OPC_LWXC1:
25699             case OPC_LDXC1:
25700             case OPC_SWXC1:
25701             case OPC_SDXC1:
25702                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
25703                 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
25704                 break;
25705             case OPC_PREFX:
25706                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
25707                 /* Treat as NOP. */
25708                 break;
25709             case OPC_ALNV_PS:
25710                 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
25711                 /* Fallthrough */
25712             case OPC_MADD_S:
25713             case OPC_MADD_D:
25714             case OPC_MADD_PS:
25715             case OPC_MSUB_S:
25716             case OPC_MSUB_D:
25717             case OPC_MSUB_PS:
25718             case OPC_NMADD_S:
25719             case OPC_NMADD_D:
25720             case OPC_NMADD_PS:
25721             case OPC_NMSUB_S:
25722             case OPC_NMSUB_D:
25723             case OPC_NMSUB_PS:
25724                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
25725                 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
25726                 break;
25727             default:
25728                 MIPS_INVAL("cp3");
25729                 generate_exception_end(ctx, EXCP_RI);
25730                 break;
25731             }
25732         } else {
25733             generate_exception_err(ctx, EXCP_CpU, 1);
25734         }
25735         break;
25736
25737 #if defined(TARGET_MIPS64)
25738     /* MIPS64 opcodes */
25739     case OPC_LDL:
25740     case OPC_LDR:
25741     case OPC_LLD:
25742         check_insn_opc_removed(ctx, ISA_MIPS32R6);
25743         /* fall through */
25744     case OPC_LWU:
25745     case OPC_LD:
25746         check_insn(ctx, ISA_MIPS3);
25747         check_mips_64(ctx);
25748         gen_ld(ctx, op, rt, rs, imm);
25749         break;
25750     case OPC_SDL:
25751     case OPC_SDR:
25752         check_insn_opc_removed(ctx, ISA_MIPS32R6);
25753         /* fall through */
25754     case OPC_SD:
25755         check_insn(ctx, ISA_MIPS3);
25756         check_mips_64(ctx);
25757         gen_st(ctx, op, rt, rs, imm);
25758         break;
25759     case OPC_SCD:
25760         check_insn_opc_removed(ctx, ISA_MIPS32R6);
25761         check_insn(ctx, ISA_MIPS3);
25762         check_mips_64(ctx);
25763         gen_st_cond(ctx, op, rt, rs, imm);
25764         break;
25765     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
25766         if (ctx->insn_flags & ISA_MIPS32R6) {
25767             /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
25768             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25769         } else {
25770             /* OPC_DADDI */
25771             check_insn(ctx, ISA_MIPS3);
25772             check_mips_64(ctx);
25773             gen_arith_imm(ctx, op, rt, rs, imm);
25774         }
25775         break;
25776     case OPC_DADDIU:
25777         check_insn(ctx, ISA_MIPS3);
25778         check_mips_64(ctx);
25779         gen_arith_imm(ctx, op, rt, rs, imm);
25780         break;
25781 #else
25782     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
25783         if (ctx->insn_flags & ISA_MIPS32R6) {
25784             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25785         } else {
25786             MIPS_INVAL("major opcode");
25787             generate_exception_end(ctx, EXCP_RI);
25788         }
25789         break;
25790 #endif
25791     case OPC_DAUI: /* OPC_JALX */
25792         if (ctx->insn_flags & ISA_MIPS32R6) {
25793 #if defined(TARGET_MIPS64)
25794             /* OPC_DAUI */
25795             check_mips_64(ctx);
25796             if (rs == 0) {
25797                 generate_exception(ctx, EXCP_RI);
25798             } else if (rt != 0) {
25799                 TCGv t0 = tcg_temp_new();
25800                 gen_load_gpr(t0, rs);
25801                 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
25802                 tcg_temp_free(t0);
25803             }
25804 #else
25805             generate_exception_end(ctx, EXCP_RI);
25806             MIPS_INVAL("major opcode");
25807 #endif
25808         } else {
25809             /* OPC_JALX */
25810             check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
25811             offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
25812             gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
25813         }
25814         break;
25815     case OPC_MSA: /* OPC_MDMX */
25816         /* MDMX: Not implemented. */
25817         gen_msa(env, ctx);
25818         break;
25819     case OPC_PCREL:
25820         check_insn(ctx, ISA_MIPS32R6);
25821         gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
25822         break;
25823     default:            /* Invalid */
25824         MIPS_INVAL("major opcode");
25825         generate_exception_end(ctx, EXCP_RI);
25826         break;
25827     }
25828 }
25829
25830 static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
25831 {
25832     DisasContext *ctx = container_of(dcbase, DisasContext, base);
25833     CPUMIPSState *env = cs->env_ptr;
25834
25835     ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
25836     ctx->saved_pc = -1;
25837     ctx->insn_flags = env->insn_flags;
25838     ctx->CP0_Config1 = env->CP0_Config1;
25839     ctx->CP0_Config2 = env->CP0_Config2;
25840     ctx->CP0_Config3 = env->CP0_Config3;
25841     ctx->CP0_Config5 = env->CP0_Config5;
25842     ctx->btarget = 0;
25843     ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
25844     ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
25845     ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
25846     ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
25847     ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
25848     ctx->PAMask = env->PAMask;
25849     ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
25850     ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
25851     ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
25852     ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
25853     ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
25854     /* Restore delay slot state from the tb context.  */
25855     ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
25856     ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
25857     ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
25858              (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
25859     ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
25860     ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
25861     ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
25862     ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
25863     restore_cpu_state(env, ctx);
25864 #ifdef CONFIG_USER_ONLY
25865         ctx->mem_idx = MIPS_HFLAG_UM;
25866 #else
25867         ctx->mem_idx = hflags_mmu_index(ctx->hflags);
25868 #endif
25869     ctx->default_tcg_memop_mask = (ctx->insn_flags & ISA_MIPS32R6) ?
25870                                   MO_UNALN : MO_ALIGN;
25871
25872     LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
25873               ctx->hflags);
25874 }
25875
25876 static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
25877 {
25878 }
25879
25880 static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
25881 {
25882     DisasContext *ctx = container_of(dcbase, DisasContext, base);
25883
25884     tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
25885                        ctx->btarget);
25886 }
25887
25888 static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
25889                                      const CPUBreakpoint *bp)
25890 {
25891     DisasContext *ctx = container_of(dcbase, DisasContext, base);
25892
25893     save_cpu_state(ctx, 1);
25894     ctx->base.is_jmp = DISAS_NORETURN;
25895     gen_helper_raise_exception_debug(cpu_env);
25896     /* The address covered by the breakpoint must be included in
25897        [tb->pc, tb->pc + tb->size) in order to for it to be
25898        properly cleared -- thus we increment the PC here so that
25899        the logic setting tb->size below does the right thing.  */
25900     ctx->base.pc_next += 4;
25901     return true;
25902 }
25903
25904 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
25905 {
25906     CPUMIPSState *env = cs->env_ptr;
25907     DisasContext *ctx = container_of(dcbase, DisasContext, base);
25908     int insn_bytes;
25909     int is_slot;
25910
25911     is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
25912     if (ctx->insn_flags & ISA_NANOMIPS32) {
25913         ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
25914         insn_bytes = decode_nanomips_opc(env, ctx);
25915     } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
25916         ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
25917         insn_bytes = 4;
25918         decode_opc(env, ctx);
25919     } else if (ctx->insn_flags & ASE_MICROMIPS) {
25920         ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
25921         insn_bytes = decode_micromips_opc(env, ctx);
25922     } else if (ctx->insn_flags & ASE_MIPS16) {
25923         ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
25924         insn_bytes = decode_mips16_opc(env, ctx);
25925     } else {
25926         generate_exception_end(ctx, EXCP_RI);
25927         g_assert(ctx->base.is_jmp == DISAS_NORETURN);
25928         return;
25929     }
25930
25931     if (ctx->hflags & MIPS_HFLAG_BMASK) {
25932         if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
25933                              MIPS_HFLAG_FBNSLOT))) {
25934             /* force to generate branch as there is neither delay nor
25935                forbidden slot */
25936             is_slot = 1;
25937         }
25938         if ((ctx->hflags & MIPS_HFLAG_M16) &&
25939             (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
25940             /* Force to generate branch as microMIPS R6 doesn't restrict
25941                branches in the forbidden slot. */
25942             is_slot = 1;
25943         }
25944     }
25945     if (is_slot) {
25946         gen_branch(ctx, insn_bytes);
25947     }
25948     ctx->base.pc_next += insn_bytes;
25949
25950     if (ctx->base.is_jmp != DISAS_NEXT) {
25951         return;
25952     }
25953     /* Execute a branch and its delay slot as a single instruction.
25954        This is what GDB expects and is consistent with what the
25955        hardware does (e.g. if a delay slot instruction faults, the
25956        reported PC is the PC of the branch).  */
25957     if (ctx->base.singlestep_enabled &&
25958         (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
25959         ctx->base.is_jmp = DISAS_TOO_MANY;
25960     }
25961     if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
25962         ctx->base.is_jmp = DISAS_TOO_MANY;
25963     }
25964 }
25965
25966 static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
25967 {
25968     DisasContext *ctx = container_of(dcbase, DisasContext, base);
25969
25970     if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
25971         save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
25972         gen_helper_raise_exception_debug(cpu_env);
25973     } else {
25974         switch (ctx->base.is_jmp) {
25975         case DISAS_STOP:
25976             gen_save_pc(ctx->base.pc_next);
25977             tcg_gen_lookup_and_goto_ptr();
25978             break;
25979         case DISAS_NEXT:
25980         case DISAS_TOO_MANY:
25981             save_cpu_state(ctx, 0);
25982             gen_goto_tb(ctx, 0, ctx->base.pc_next);
25983             break;
25984         case DISAS_EXIT:
25985             tcg_gen_exit_tb(NULL, 0);
25986             break;
25987         case DISAS_NORETURN:
25988             break;
25989         default:
25990             g_assert_not_reached();
25991         }
25992     }
25993 }
25994
25995 static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
25996 {
25997     qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
25998     log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
25999 }
26000
26001 static const TranslatorOps mips_tr_ops = {
26002     .init_disas_context = mips_tr_init_disas_context,
26003     .tb_start           = mips_tr_tb_start,
26004     .insn_start         = mips_tr_insn_start,
26005     .breakpoint_check   = mips_tr_breakpoint_check,
26006     .translate_insn     = mips_tr_translate_insn,
26007     .tb_stop            = mips_tr_tb_stop,
26008     .disas_log          = mips_tr_disas_log,
26009 };
26010
26011 void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
26012 {
26013     DisasContext ctx;
26014
26015     translator_loop(&mips_tr_ops, &ctx.base, cs, tb);
26016 }
26017
26018 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
26019                            int flags)
26020 {
26021     int i;
26022     int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
26023
26024 #define printfpr(fp)                                                    \
26025     do {                                                                \
26026         if (is_fpu64)                                                   \
26027             fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
26028                         " fd:%13g fs:%13g psu: %13g\n",                 \
26029                         (fp)->w[FP_ENDIAN_IDX], (fp)->d,                \
26030                         (double)(fp)->fd,                               \
26031                         (double)(fp)->fs[FP_ENDIAN_IDX],                \
26032                         (double)(fp)->fs[!FP_ENDIAN_IDX]);              \
26033         else {                                                          \
26034             fpr_t tmp;                                                  \
26035             tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];              \
26036             tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];       \
26037             fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
26038                         " fd:%13g fs:%13g psu:%13g\n",                  \
26039                         tmp.w[FP_ENDIAN_IDX], tmp.d,                    \
26040                         (double)tmp.fd,                                 \
26041                         (double)tmp.fs[FP_ENDIAN_IDX],                  \
26042                         (double)tmp.fs[!FP_ENDIAN_IDX]);                \
26043         }                                                               \
26044     } while(0)
26045
26046
26047     fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%02x\n",
26048                 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
26049                 get_float_exception_flags(&env->active_fpu.fp_status));
26050     for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
26051         fpu_fprintf(f, "%3s: ", fregnames[i]);
26052         printfpr(&env->active_fpu.fpr[i]);
26053     }
26054
26055 #undef printfpr
26056 }
26057
26058 void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
26059                          int flags)
26060 {
26061     MIPSCPU *cpu = MIPS_CPU(cs);
26062     CPUMIPSState *env = &cpu->env;
26063     int i;
26064
26065     cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
26066                 " LO=0x" TARGET_FMT_lx " ds %04x "
26067                 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
26068                 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
26069                 env->hflags, env->btarget, env->bcond);
26070     for (i = 0; i < 32; i++) {
26071         if ((i & 3) == 0)
26072             cpu_fprintf(f, "GPR%02d:", i);
26073         cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
26074         if ((i & 3) == 3)
26075             cpu_fprintf(f, "\n");
26076     }
26077
26078     cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
26079                 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
26080     cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
26081                 PRIx64 "\n",
26082                 env->CP0_Config0, env->CP0_Config1, env->lladdr);
26083     cpu_fprintf(f, "    Config2 0x%08x Config3 0x%08x\n",
26084                 env->CP0_Config2, env->CP0_Config3);
26085     cpu_fprintf(f, "    Config4 0x%08x Config5 0x%08x\n",
26086                 env->CP0_Config4, env->CP0_Config5);
26087     if ((flags & CPU_DUMP_FPU) && (env->hflags & MIPS_HFLAG_FPU)) {
26088         fpu_dump_state(env, f, cpu_fprintf, flags);
26089     }
26090 }
26091
26092 void mips_tcg_init(void)
26093 {
26094     int i;
26095
26096     cpu_gpr[0] = NULL;
26097     for (i = 1; i < 32; i++)
26098         cpu_gpr[i] = tcg_global_mem_new(cpu_env,
26099                                         offsetof(CPUMIPSState, active_tc.gpr[i]),
26100                                         regnames[i]);
26101
26102     for (i = 0; i < 32; i++) {
26103         int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
26104         msa_wr_d[i * 2] =
26105                 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
26106         /* The scalar floating-point unit (FPU) registers are mapped on
26107          * the MSA vector registers. */
26108         fpu_f64[i] = msa_wr_d[i * 2];
26109         off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
26110         msa_wr_d[i * 2 + 1] =
26111                 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
26112     }
26113
26114     cpu_PC = tcg_global_mem_new(cpu_env,
26115                                 offsetof(CPUMIPSState, active_tc.PC), "PC");
26116     for (i = 0; i < MIPS_DSP_ACC; i++) {
26117         cpu_HI[i] = tcg_global_mem_new(cpu_env,
26118                                        offsetof(CPUMIPSState, active_tc.HI[i]),
26119                                        regnames_HI[i]);
26120         cpu_LO[i] = tcg_global_mem_new(cpu_env,
26121                                        offsetof(CPUMIPSState, active_tc.LO[i]),
26122                                        regnames_LO[i]);
26123     }
26124     cpu_dspctrl = tcg_global_mem_new(cpu_env,
26125                                      offsetof(CPUMIPSState, active_tc.DSPControl),
26126                                      "DSPControl");
26127     bcond = tcg_global_mem_new(cpu_env,
26128                                offsetof(CPUMIPSState, bcond), "bcond");
26129     btarget = tcg_global_mem_new(cpu_env,
26130                                  offsetof(CPUMIPSState, btarget), "btarget");
26131     hflags = tcg_global_mem_new_i32(cpu_env,
26132                                     offsetof(CPUMIPSState, hflags), "hflags");
26133
26134     fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
26135                                       offsetof(CPUMIPSState, active_fpu.fcr0),
26136                                       "fcr0");
26137     fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
26138                                        offsetof(CPUMIPSState, active_fpu.fcr31),
26139                                        "fcr31");
26140 }
26141
26142 #include "translate_init.inc.c"
26143
26144 void cpu_mips_realize_env(CPUMIPSState *env)
26145 {
26146     env->exception_base = (int32_t)0xBFC00000;
26147
26148 #ifndef CONFIG_USER_ONLY
26149     mmu_init(env, env->cpu_model);
26150 #endif
26151     fpu_init(env, env->cpu_model);
26152     mvp_init(env, env->cpu_model);
26153 }
26154
26155 bool cpu_supports_cps_smp(const char *cpu_type)
26156 {
26157     const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
26158     return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
26159 }
26160
26161 bool cpu_supports_isa(const char *cpu_type, unsigned int isa)
26162 {
26163     const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
26164     return (mcc->cpu_def->insn_flags & isa) != 0;
26165 }
26166
26167 void cpu_set_exception_base(int vp_index, target_ulong address)
26168 {
26169     MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
26170     vp->env.exception_base = address;
26171 }
26172
26173 void cpu_state_reset(CPUMIPSState *env)
26174 {
26175     MIPSCPU *cpu = mips_env_get_cpu(env);
26176     CPUState *cs = CPU(cpu);
26177
26178     /* Reset registers to their default values */
26179     env->CP0_PRid = env->cpu_model->CP0_PRid;
26180     env->CP0_Config0 = env->cpu_model->CP0_Config0;
26181 #ifdef TARGET_WORDS_BIGENDIAN
26182     env->CP0_Config0 |= (1 << CP0C0_BE);
26183 #endif
26184     env->CP0_Config1 = env->cpu_model->CP0_Config1;
26185     env->CP0_Config2 = env->cpu_model->CP0_Config2;
26186     env->CP0_Config3 = env->cpu_model->CP0_Config3;
26187     env->CP0_Config4 = env->cpu_model->CP0_Config4;
26188     env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
26189     env->CP0_Config5 = env->cpu_model->CP0_Config5;
26190     env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
26191     env->CP0_Config6 = env->cpu_model->CP0_Config6;
26192     env->CP0_Config7 = env->cpu_model->CP0_Config7;
26193     env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
26194                                  << env->cpu_model->CP0_LLAddr_shift;
26195     env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
26196     env->SYNCI_Step = env->cpu_model->SYNCI_Step;
26197     env->CCRes = env->cpu_model->CCRes;
26198     env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
26199     env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
26200     env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
26201     env->current_tc = 0;
26202     env->SEGBITS = env->cpu_model->SEGBITS;
26203     env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
26204 #if defined(TARGET_MIPS64)
26205     if (env->cpu_model->insn_flags & ISA_MIPS3) {
26206         env->SEGMask |= 3ULL << 62;
26207     }
26208 #endif
26209     env->PABITS = env->cpu_model->PABITS;
26210     env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
26211     env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
26212     env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
26213     env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
26214     env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
26215     env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
26216     env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
26217     env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
26218     env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
26219     env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
26220     env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
26221     env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
26222     env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
26223     env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
26224     env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
26225     env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
26226     env->msair = env->cpu_model->MSAIR;
26227     env->insn_flags = env->cpu_model->insn_flags;
26228
26229 #if defined(CONFIG_USER_ONLY)
26230     env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
26231 # ifdef TARGET_MIPS64
26232     /* Enable 64-bit register mode.  */
26233     env->CP0_Status |= (1 << CP0St_PX);
26234 # endif
26235 # ifdef TARGET_ABI_MIPSN64
26236     /* Enable 64-bit address mode.  */
26237     env->CP0_Status |= (1 << CP0St_UX);
26238 # endif
26239     /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
26240        hardware registers.  */
26241     env->CP0_HWREna |= 0x0000000F;
26242     if (env->CP0_Config1 & (1 << CP0C1_FP)) {
26243         env->CP0_Status |= (1 << CP0St_CU1);
26244     }
26245     if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
26246         env->CP0_Status |= (1 << CP0St_MX);
26247     }
26248 # if defined(TARGET_MIPS64)
26249     /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
26250     if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
26251         (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
26252         env->CP0_Status |= (1 << CP0St_FR);
26253     }
26254 # endif
26255 #else
26256     if (env->hflags & MIPS_HFLAG_BMASK) {
26257         /* If the exception was raised from a delay slot,
26258            come back to the jump.  */
26259         env->CP0_ErrorEPC = (env->active_tc.PC
26260                              - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
26261     } else {
26262         env->CP0_ErrorEPC = env->active_tc.PC;
26263     }
26264     env->active_tc.PC = env->exception_base;
26265     env->CP0_Random = env->tlb->nb_tlb - 1;
26266     env->tlb->tlb_in_use = env->tlb->nb_tlb;
26267     env->CP0_Wired = 0;
26268     env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
26269     env->CP0_EBase = (cs->cpu_index & 0x3FF);
26270     if (mips_um_ksegs_enabled()) {
26271         env->CP0_EBase |= 0x40000000;
26272     } else {
26273         env->CP0_EBase |= (int32_t)0x80000000;
26274     }
26275     if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
26276         env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
26277     }
26278     env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
26279                                  0x3ff : 0xff;
26280     env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
26281     /* vectored interrupts not implemented, timer on int 7,
26282        no performance counters. */
26283     env->CP0_IntCtl = 0xe0000000;
26284     {
26285         int i;
26286
26287         for (i = 0; i < 7; i++) {
26288             env->CP0_WatchLo[i] = 0;
26289             env->CP0_WatchHi[i] = 0x80000000;
26290         }
26291         env->CP0_WatchLo[7] = 0;
26292         env->CP0_WatchHi[7] = 0;
26293     }
26294     /* Count register increments in debug mode, EJTAG version 1 */
26295     env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
26296
26297     cpu_mips_store_count(env, 1);
26298
26299     if (env->CP0_Config3 & (1 << CP0C3_MT)) {
26300         int i;
26301
26302         /* Only TC0 on VPE 0 starts as active.  */
26303         for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
26304             env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
26305             env->tcs[i].CP0_TCHalt = 1;
26306         }
26307         env->active_tc.CP0_TCHalt = 1;
26308         cs->halted = 1;
26309
26310         if (cs->cpu_index == 0) {
26311             /* VPE0 starts up enabled.  */
26312             env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
26313             env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
26314
26315             /* TC0 starts up unhalted.  */
26316             cs->halted = 0;
26317             env->active_tc.CP0_TCHalt = 0;
26318             env->tcs[0].CP0_TCHalt = 0;
26319             /* With thread 0 active.  */
26320             env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
26321             env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
26322         }
26323     }
26324
26325     /*
26326      * Configure default legacy segmentation control. We use this regardless of
26327      * whether segmentation control is presented to the guest.
26328      */
26329     /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
26330     env->CP0_SegCtl0 =   (CP0SC_AM_MK << CP0SC_AM);
26331     /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
26332     env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
26333     /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
26334     env->CP0_SegCtl1 =   (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
26335                          (2 << CP0SC_C);
26336     /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
26337     env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
26338                          (3 << CP0SC_C)) << 16;
26339     /* USeg (seg4 0x40000000..0x7FFFFFFF) */
26340     env->CP0_SegCtl2 =   (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
26341                          (1 << CP0SC_EU) | (2 << CP0SC_C);
26342     /* USeg (seg5 0x00000000..0x3FFFFFFF) */
26343     env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
26344                          (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
26345     /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
26346     env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
26347 #endif
26348     if ((env->insn_flags & ISA_MIPS32R6) &&
26349         (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
26350         /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
26351         env->CP0_Status |= (1 << CP0St_FR);
26352     }
26353
26354     if (env->CP0_Config3 & (1 << CP0C3_ISA) & (1 << (CP0C3_ISA + 1))) {
26355         /*  microMIPS on reset when Config3.ISA is 3 */
26356         env->hflags |= MIPS_HFLAG_M16;
26357     }
26358
26359     /* MSA */
26360     if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
26361         msa_reset(env);
26362     }
26363
26364     compute_hflags(env);
26365     restore_fp_status(env);
26366     restore_pamask(env);
26367     cs->exception_index = EXCP_NONE;
26368
26369     if (semihosting_get_argc()) {
26370         /* UHI interface can be used to obtain argc and argv */
26371         env->active_tc.gpr[4] = -1;
26372     }
26373 }
26374
26375 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
26376                           target_ulong *data)
26377 {
26378     env->active_tc.PC = data[0];
26379     env->hflags &= ~MIPS_HFLAG_BMASK;
26380     env->hflags |= data[1];
26381     switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
26382     case MIPS_HFLAG_BR:
26383         break;
26384     case MIPS_HFLAG_BC:
26385     case MIPS_HFLAG_BL:
26386     case MIPS_HFLAG_B:
26387         env->btarget = data[2];
26388         break;
26389     }
26390 }