1 /*
2  *  MIPS emulation for QEMU - main translation routines
3  *
4  *  Copyright (c) 2004-2005 Jocelyn Mayer
5  *  Copyright (c) 2006 Marius Groeger (FPU operations)
6  *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7  *  Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
8  *  Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 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/tcg-op.h"
30 #include "exec/cpu_ldst.h"
31 #include "hw/mips/cpudevs.h"
32 
33 #include "exec/helper-proto.h"
34 #include "exec/helper-gen.h"
35 #include "hw/semihosting/semihost.h"
36 
37 #include "target/mips/trace.h"
38 #include "trace-tcg.h"
39 #include "exec/translator.h"
40 #include "exec/log.h"
41 #include "qemu/qemu-print.h"
42 
43 #define MIPS_DEBUG_DISAS 0
44 
45 /* MIPS major opcodes */
46 #define MASK_OP_MAJOR(op)       (op & (0x3F << 26))
47 
48 enum {
49     /* indirect opcode tables */
50     OPC_SPECIAL  = (0x00 << 26),
51     OPC_REGIMM   = (0x01 << 26),
52     OPC_CP0      = (0x10 << 26),
53     OPC_CP1      = (0x11 << 26),
54     OPC_CP2      = (0x12 << 26),
55     OPC_CP3      = (0x13 << 26),
56     OPC_SPECIAL2 = (0x1C << 26),
57     OPC_SPECIAL3 = (0x1F << 26),
58     /* arithmetic with immediate */
59     OPC_ADDI     = (0x08 << 26),
60     OPC_ADDIU    = (0x09 << 26),
61     OPC_SLTI     = (0x0A << 26),
62     OPC_SLTIU    = (0x0B << 26),
63     /* logic with immediate */
64     OPC_ANDI     = (0x0C << 26),
65     OPC_ORI      = (0x0D << 26),
66     OPC_XORI     = (0x0E << 26),
67     OPC_LUI      = (0x0F << 26),
68     /* arithmetic with immediate */
69     OPC_DADDI    = (0x18 << 26),
70     OPC_DADDIU   = (0x19 << 26),
71     /* Jump and branches */
72     OPC_J        = (0x02 << 26),
73     OPC_JAL      = (0x03 << 26),
74     OPC_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
75     OPC_BEQL     = (0x14 << 26),
76     OPC_BNE      = (0x05 << 26),
77     OPC_BNEL     = (0x15 << 26),
78     OPC_BLEZ     = (0x06 << 26),
79     OPC_BLEZL    = (0x16 << 26),
80     OPC_BGTZ     = (0x07 << 26),
81     OPC_BGTZL    = (0x17 << 26),
82     OPC_JALX     = (0x1D << 26),
83     OPC_DAUI     = (0x1D << 26),
84     /* Load and stores */
85     OPC_LDL      = (0x1A << 26),
86     OPC_LDR      = (0x1B << 26),
87     OPC_LB       = (0x20 << 26),
88     OPC_LH       = (0x21 << 26),
89     OPC_LWL      = (0x22 << 26),
90     OPC_LW       = (0x23 << 26),
91     OPC_LWPC     = OPC_LW | 0x5,
92     OPC_LBU      = (0x24 << 26),
93     OPC_LHU      = (0x25 << 26),
94     OPC_LWR      = (0x26 << 26),
95     OPC_LWU      = (0x27 << 26),
96     OPC_SB       = (0x28 << 26),
97     OPC_SH       = (0x29 << 26),
98     OPC_SWL      = (0x2A << 26),
99     OPC_SW       = (0x2B << 26),
100     OPC_SDL      = (0x2C << 26),
101     OPC_SDR      = (0x2D << 26),
102     OPC_SWR      = (0x2E << 26),
103     OPC_LL       = (0x30 << 26),
104     OPC_LLD      = (0x34 << 26),
105     OPC_LD       = (0x37 << 26),
106     OPC_LDPC     = OPC_LD | 0x5,
107     OPC_SC       = (0x38 << 26),
108     OPC_SCD      = (0x3C << 26),
109     OPC_SD       = (0x3F << 26),
110     /* Floating point load/store */
111     OPC_LWC1     = (0x31 << 26),
112     OPC_LWC2     = (0x32 << 26),
113     OPC_LDC1     = (0x35 << 26),
114     OPC_LDC2     = (0x36 << 26),
115     OPC_SWC1     = (0x39 << 26),
116     OPC_SWC2     = (0x3A << 26),
117     OPC_SDC1     = (0x3D << 26),
118     OPC_SDC2     = (0x3E << 26),
119     /* Compact Branches */
120     OPC_BLEZALC  = (0x06 << 26),
121     OPC_BGEZALC  = (0x06 << 26),
122     OPC_BGEUC    = (0x06 << 26),
123     OPC_BGTZALC  = (0x07 << 26),
124     OPC_BLTZALC  = (0x07 << 26),
125     OPC_BLTUC    = (0x07 << 26),
126     OPC_BOVC     = (0x08 << 26),
127     OPC_BEQZALC  = (0x08 << 26),
128     OPC_BEQC     = (0x08 << 26),
129     OPC_BLEZC    = (0x16 << 26),
130     OPC_BGEZC    = (0x16 << 26),
131     OPC_BGEC     = (0x16 << 26),
132     OPC_BGTZC    = (0x17 << 26),
133     OPC_BLTZC    = (0x17 << 26),
134     OPC_BLTC     = (0x17 << 26),
135     OPC_BNVC     = (0x18 << 26),
136     OPC_BNEZALC  = (0x18 << 26),
137     OPC_BNEC     = (0x18 << 26),
138     OPC_BC       = (0x32 << 26),
139     OPC_BEQZC    = (0x36 << 26),
140     OPC_JIC      = (0x36 << 26),
141     OPC_BALC     = (0x3A << 26),
142     OPC_BNEZC    = (0x3E << 26),
143     OPC_JIALC    = (0x3E << 26),
144     /* MDMX ASE specific */
145     OPC_MDMX     = (0x1E << 26),
146     /* MSA ASE, same as MDMX */
147     OPC_MSA      = OPC_MDMX,
148     /* Cache and prefetch */
149     OPC_CACHE    = (0x2F << 26),
150     OPC_PREF     = (0x33 << 26),
151     /* PC-relative address computation / loads */
152     OPC_PCREL    = (0x3B << 26),
153 };
154 
155 /* PC-relative address computation / loads  */
156 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
157 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
158 enum {
159     /* Instructions determined by bits 19 and 20 */
160     OPC_ADDIUPC = OPC_PCREL | (0 << 19),
161     R6_OPC_LWPC = OPC_PCREL | (1 << 19),
162     OPC_LWUPC   = OPC_PCREL | (2 << 19),
163 
164     /* Instructions determined by bits 16 ... 20 */
165     OPC_AUIPC   = OPC_PCREL | (0x1e << 16),
166     OPC_ALUIPC  = OPC_PCREL | (0x1f << 16),
167 
168     /* Other */
169     R6_OPC_LDPC = OPC_PCREL | (6 << 18),
170 };
171 
172 /* MIPS special opcodes */
173 #define MASK_SPECIAL(op)            (MASK_OP_MAJOR(op) | (op & 0x3F))
174 
175 enum {
176     /* Shifts */
177     OPC_SLL      = 0x00 | OPC_SPECIAL,
178     /* NOP is SLL r0, r0, 0   */
179     /* SSNOP is SLL r0, r0, 1 */
180     /* EHB is SLL r0, r0, 3 */
181     OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
182     OPC_ROTR     = OPC_SRL | (1 << 21),
183     OPC_SRA      = 0x03 | OPC_SPECIAL,
184     OPC_SLLV     = 0x04 | OPC_SPECIAL,
185     OPC_SRLV     = 0x06 | OPC_SPECIAL, /* also ROTRV */
186     OPC_ROTRV    = OPC_SRLV | (1 << 6),
187     OPC_SRAV     = 0x07 | OPC_SPECIAL,
188     OPC_DSLLV    = 0x14 | OPC_SPECIAL,
189     OPC_DSRLV    = 0x16 | OPC_SPECIAL, /* also DROTRV */
190     OPC_DROTRV   = OPC_DSRLV | (1 << 6),
191     OPC_DSRAV    = 0x17 | OPC_SPECIAL,
192     OPC_DSLL     = 0x38 | OPC_SPECIAL,
193     OPC_DSRL     = 0x3A | OPC_SPECIAL, /* also DROTR */
194     OPC_DROTR    = OPC_DSRL | (1 << 21),
195     OPC_DSRA     = 0x3B | OPC_SPECIAL,
196     OPC_DSLL32   = 0x3C | OPC_SPECIAL,
197     OPC_DSRL32   = 0x3E | OPC_SPECIAL, /* also DROTR32 */
198     OPC_DROTR32  = OPC_DSRL32 | (1 << 21),
199     OPC_DSRA32   = 0x3F | OPC_SPECIAL,
200     /* Multiplication / division */
201     OPC_MULT     = 0x18 | OPC_SPECIAL,
202     OPC_MULTU    = 0x19 | OPC_SPECIAL,
203     OPC_DIV      = 0x1A | OPC_SPECIAL,
204     OPC_DIVU     = 0x1B | OPC_SPECIAL,
205     OPC_DMULT    = 0x1C | OPC_SPECIAL,
206     OPC_DMULTU   = 0x1D | OPC_SPECIAL,
207     OPC_DDIV     = 0x1E | OPC_SPECIAL,
208     OPC_DDIVU    = 0x1F | OPC_SPECIAL,
209 
210     /* 2 registers arithmetic / logic */
211     OPC_ADD      = 0x20 | OPC_SPECIAL,
212     OPC_ADDU     = 0x21 | OPC_SPECIAL,
213     OPC_SUB      = 0x22 | OPC_SPECIAL,
214     OPC_SUBU     = 0x23 | OPC_SPECIAL,
215     OPC_AND      = 0x24 | OPC_SPECIAL,
216     OPC_OR       = 0x25 | OPC_SPECIAL,
217     OPC_XOR      = 0x26 | OPC_SPECIAL,
218     OPC_NOR      = 0x27 | OPC_SPECIAL,
219     OPC_SLT      = 0x2A | OPC_SPECIAL,
220     OPC_SLTU     = 0x2B | OPC_SPECIAL,
221     OPC_DADD     = 0x2C | OPC_SPECIAL,
222     OPC_DADDU    = 0x2D | OPC_SPECIAL,
223     OPC_DSUB     = 0x2E | OPC_SPECIAL,
224     OPC_DSUBU    = 0x2F | OPC_SPECIAL,
225     /* Jumps */
226     OPC_JR       = 0x08 | OPC_SPECIAL, /* Also JR.HB */
227     OPC_JALR     = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
228     /* Traps */
229     OPC_TGE      = 0x30 | OPC_SPECIAL,
230     OPC_TGEU     = 0x31 | OPC_SPECIAL,
231     OPC_TLT      = 0x32 | OPC_SPECIAL,
232     OPC_TLTU     = 0x33 | OPC_SPECIAL,
233     OPC_TEQ      = 0x34 | OPC_SPECIAL,
234     OPC_TNE      = 0x36 | OPC_SPECIAL,
235     /* HI / LO registers load & stores */
236     OPC_MFHI     = 0x10 | OPC_SPECIAL,
237     OPC_MTHI     = 0x11 | OPC_SPECIAL,
238     OPC_MFLO     = 0x12 | OPC_SPECIAL,
239     OPC_MTLO     = 0x13 | OPC_SPECIAL,
240     /* Conditional moves */
241     OPC_MOVZ     = 0x0A | OPC_SPECIAL,
242     OPC_MOVN     = 0x0B | OPC_SPECIAL,
243 
244     OPC_SELEQZ   = 0x35 | OPC_SPECIAL,
245     OPC_SELNEZ   = 0x37 | OPC_SPECIAL,
246 
247     OPC_MOVCI    = 0x01 | OPC_SPECIAL,
248 
249     /* Special */
250     OPC_PMON     = 0x05 | OPC_SPECIAL, /* unofficial */
251     OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
252     OPC_BREAK    = 0x0D | OPC_SPECIAL,
253     OPC_SPIM     = 0x0E | OPC_SPECIAL, /* unofficial */
254     OPC_SYNC     = 0x0F | OPC_SPECIAL,
255 
256     OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
257     OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
258     OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
259     OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
260 };
261 
262 /*
263  * R6 Multiply and Divide instructions have the same opcode
264  * and function field as legacy OPC_MULT[U]/OPC_DIV[U]
265  */
266 #define MASK_R6_MULDIV(op)          (MASK_SPECIAL(op) | (op & (0x7ff)))
267 
268 enum {
269     R6_OPC_MUL   = OPC_MULT  | (2 << 6),
270     R6_OPC_MUH   = OPC_MULT  | (3 << 6),
271     R6_OPC_MULU  = OPC_MULTU | (2 << 6),
272     R6_OPC_MUHU  = OPC_MULTU | (3 << 6),
273     R6_OPC_DIV   = OPC_DIV   | (2 << 6),
274     R6_OPC_MOD   = OPC_DIV   | (3 << 6),
275     R6_OPC_DIVU  = OPC_DIVU  | (2 << 6),
276     R6_OPC_MODU  = OPC_DIVU  | (3 << 6),
277 
278     R6_OPC_DMUL   = OPC_DMULT  | (2 << 6),
279     R6_OPC_DMUH   = OPC_DMULT  | (3 << 6),
280     R6_OPC_DMULU  = OPC_DMULTU | (2 << 6),
281     R6_OPC_DMUHU  = OPC_DMULTU | (3 << 6),
282     R6_OPC_DDIV   = OPC_DDIV   | (2 << 6),
283     R6_OPC_DMOD   = OPC_DDIV   | (3 << 6),
284     R6_OPC_DDIVU  = OPC_DDIVU  | (2 << 6),
285     R6_OPC_DMODU  = OPC_DDIVU  | (3 << 6),
286 
287     R6_OPC_CLZ      = 0x10 | OPC_SPECIAL,
288     R6_OPC_CLO      = 0x11 | OPC_SPECIAL,
289     R6_OPC_DCLZ     = 0x12 | OPC_SPECIAL,
290     R6_OPC_DCLO     = 0x13 | OPC_SPECIAL,
291     R6_OPC_SDBBP    = 0x0e | OPC_SPECIAL,
292 
293     OPC_LSA  = 0x05 | OPC_SPECIAL,
294     OPC_DLSA = 0x15 | OPC_SPECIAL,
295 };
296 
297 /* Multiplication variants of the vr54xx. */
298 #define MASK_MUL_VR54XX(op)         (MASK_SPECIAL(op) | (op & (0x1F << 6)))
299 
300 enum {
301     OPC_VR54XX_MULS    = (0x03 << 6) | OPC_MULT,
302     OPC_VR54XX_MULSU   = (0x03 << 6) | OPC_MULTU,
303     OPC_VR54XX_MACC    = (0x05 << 6) | OPC_MULT,
304     OPC_VR54XX_MACCU   = (0x05 << 6) | OPC_MULTU,
305     OPC_VR54XX_MSAC    = (0x07 << 6) | OPC_MULT,
306     OPC_VR54XX_MSACU   = (0x07 << 6) | OPC_MULTU,
307     OPC_VR54XX_MULHI   = (0x09 << 6) | OPC_MULT,
308     OPC_VR54XX_MULHIU  = (0x09 << 6) | OPC_MULTU,
309     OPC_VR54XX_MULSHI  = (0x0B << 6) | OPC_MULT,
310     OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
311     OPC_VR54XX_MACCHI  = (0x0D << 6) | OPC_MULT,
312     OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
313     OPC_VR54XX_MSACHI  = (0x0F << 6) | OPC_MULT,
314     OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
315 };
316 
317 /* REGIMM (rt field) opcodes */
318 #define MASK_REGIMM(op)             (MASK_OP_MAJOR(op) | (op & (0x1F << 16)))
319 
320 enum {
321     OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
322     OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
323     OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
324     OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
325     OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
326     OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
327     OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
328     OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
329     OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
330     OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
331     OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
332     OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
333     OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
334     OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
335     OPC_SIGRIE   = (0x17 << 16) | OPC_REGIMM,
336     OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
337 
338     OPC_DAHI     = (0x06 << 16) | OPC_REGIMM,
339     OPC_DATI     = (0x1e << 16) | OPC_REGIMM,
340 };
341 
342 /* Special2 opcodes */
343 #define MASK_SPECIAL2(op)           (MASK_OP_MAJOR(op) | (op & 0x3F))
344 
345 enum {
346     /* Multiply & xxx operations */
347     OPC_MADD     = 0x00 | OPC_SPECIAL2,
348     OPC_MADDU    = 0x01 | OPC_SPECIAL2,
349     OPC_MUL      = 0x02 | OPC_SPECIAL2,
350     OPC_MSUB     = 0x04 | OPC_SPECIAL2,
351     OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
352     /* Loongson 2F */
353     OPC_MULT_G_2F   = 0x10 | OPC_SPECIAL2,
354     OPC_DMULT_G_2F  = 0x11 | OPC_SPECIAL2,
355     OPC_MULTU_G_2F  = 0x12 | OPC_SPECIAL2,
356     OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
357     OPC_DIV_G_2F    = 0x14 | OPC_SPECIAL2,
358     OPC_DDIV_G_2F   = 0x15 | OPC_SPECIAL2,
359     OPC_DIVU_G_2F   = 0x16 | OPC_SPECIAL2,
360     OPC_DDIVU_G_2F  = 0x17 | OPC_SPECIAL2,
361     OPC_MOD_G_2F    = 0x1c | OPC_SPECIAL2,
362     OPC_DMOD_G_2F   = 0x1d | OPC_SPECIAL2,
363     OPC_MODU_G_2F   = 0x1e | OPC_SPECIAL2,
364     OPC_DMODU_G_2F  = 0x1f | OPC_SPECIAL2,
365     /* Misc */
366     OPC_CLZ      = 0x20 | OPC_SPECIAL2,
367     OPC_CLO      = 0x21 | OPC_SPECIAL2,
368     OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
369     OPC_DCLO     = 0x25 | OPC_SPECIAL2,
370     /* Special */
371     OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
372 };
373 
374 /* Special3 opcodes */
375 #define MASK_SPECIAL3(op)           (MASK_OP_MAJOR(op) | (op & 0x3F))
376 
377 enum {
378     OPC_EXT      = 0x00 | OPC_SPECIAL3,
379     OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
380     OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
381     OPC_DEXT     = 0x03 | OPC_SPECIAL3,
382     OPC_INS      = 0x04 | OPC_SPECIAL3,
383     OPC_DINSM    = 0x05 | OPC_SPECIAL3,
384     OPC_DINSU    = 0x06 | OPC_SPECIAL3,
385     OPC_DINS     = 0x07 | OPC_SPECIAL3,
386     OPC_FORK     = 0x08 | OPC_SPECIAL3,
387     OPC_YIELD    = 0x09 | OPC_SPECIAL3,
388     OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
389     OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
390     OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
391     OPC_GINV     = 0x3D | OPC_SPECIAL3,
392 
393     /* Loongson 2E */
394     OPC_MULT_G_2E   = 0x18 | OPC_SPECIAL3,
395     OPC_MULTU_G_2E  = 0x19 | OPC_SPECIAL3,
396     OPC_DIV_G_2E    = 0x1A | OPC_SPECIAL3,
397     OPC_DIVU_G_2E   = 0x1B | OPC_SPECIAL3,
398     OPC_DMULT_G_2E  = 0x1C | OPC_SPECIAL3,
399     OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
400     OPC_DDIV_G_2E   = 0x1E | OPC_SPECIAL3,
401     OPC_DDIVU_G_2E  = 0x1F | OPC_SPECIAL3,
402     OPC_MOD_G_2E    = 0x22 | OPC_SPECIAL3,
403     OPC_MODU_G_2E   = 0x23 | OPC_SPECIAL3,
404     OPC_DMOD_G_2E   = 0x26 | OPC_SPECIAL3,
405     OPC_DMODU_G_2E  = 0x27 | OPC_SPECIAL3,
406 
407     /* MIPS DSP Load */
408     OPC_LX_DSP         = 0x0A | OPC_SPECIAL3,
409     /* MIPS DSP Arithmetic */
410     OPC_ADDU_QB_DSP    = 0x10 | OPC_SPECIAL3,
411     OPC_ADDU_OB_DSP    = 0x14 | OPC_SPECIAL3,
412     OPC_ABSQ_S_PH_DSP  = 0x12 | OPC_SPECIAL3,
413     OPC_ABSQ_S_QH_DSP  = 0x16 | OPC_SPECIAL3,
414     /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E.  */
415     /* OPC_ADDUH_QB_DSP   = 0x18 | OPC_SPECIAL3,  */
416     OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
417     OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
418     /* MIPS DSP GPR-Based Shift Sub-class */
419     OPC_SHLL_QB_DSP    = 0x13 | OPC_SPECIAL3,
420     OPC_SHLL_OB_DSP    = 0x17 | OPC_SPECIAL3,
421     /* MIPS DSP Multiply Sub-class insns */
422     /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP.  */
423     /* OPC_MUL_PH_DSP     = 0x18 | OPC_SPECIAL3,  */
424     OPC_DPA_W_PH_DSP   = 0x30 | OPC_SPECIAL3,
425     OPC_DPAQ_W_QH_DSP  = 0x34 | OPC_SPECIAL3,
426     /* DSP Bit/Manipulation Sub-class */
427     OPC_INSV_DSP       = 0x0C | OPC_SPECIAL3,
428     OPC_DINSV_DSP      = 0x0D | OPC_SPECIAL3,
429     /* MIPS DSP Append Sub-class */
430     OPC_APPEND_DSP     = 0x31 | OPC_SPECIAL3,
431     OPC_DAPPEND_DSP    = 0x35 | OPC_SPECIAL3,
432     /* MIPS DSP Accumulator and DSPControl Access Sub-class */
433     OPC_EXTR_W_DSP     = 0x38 | OPC_SPECIAL3,
434     OPC_DEXTR_W_DSP    = 0x3C | OPC_SPECIAL3,
435 
436     /* EVA */
437     OPC_LWLE           = 0x19 | OPC_SPECIAL3,
438     OPC_LWRE           = 0x1A | OPC_SPECIAL3,
439     OPC_CACHEE         = 0x1B | OPC_SPECIAL3,
440     OPC_SBE            = 0x1C | OPC_SPECIAL3,
441     OPC_SHE            = 0x1D | OPC_SPECIAL3,
442     OPC_SCE            = 0x1E | OPC_SPECIAL3,
443     OPC_SWE            = 0x1F | OPC_SPECIAL3,
444     OPC_SWLE           = 0x21 | OPC_SPECIAL3,
445     OPC_SWRE           = 0x22 | OPC_SPECIAL3,
446     OPC_PREFE          = 0x23 | OPC_SPECIAL3,
447     OPC_LBUE           = 0x28 | OPC_SPECIAL3,
448     OPC_LHUE           = 0x29 | OPC_SPECIAL3,
449     OPC_LBE            = 0x2C | OPC_SPECIAL3,
450     OPC_LHE            = 0x2D | OPC_SPECIAL3,
451     OPC_LLE            = 0x2E | OPC_SPECIAL3,
452     OPC_LWE            = 0x2F | OPC_SPECIAL3,
453 
454     /* R6 */
455     R6_OPC_PREF        = 0x35 | OPC_SPECIAL3,
456     R6_OPC_CACHE       = 0x25 | OPC_SPECIAL3,
457     R6_OPC_LL          = 0x36 | OPC_SPECIAL3,
458     R6_OPC_SC          = 0x26 | OPC_SPECIAL3,
459     R6_OPC_LLD         = 0x37 | OPC_SPECIAL3,
460     R6_OPC_SCD         = 0x27 | OPC_SPECIAL3,
461 };
462 
463 /* Loongson EXT load/store quad word opcodes */
464 #define MASK_LOONGSON_GSLSQ(op)           (MASK_OP_MAJOR(op) | (op & 0x8020))
465 enum {
466     OPC_GSLQ        = 0x0020 | OPC_LWC2,
467     OPC_GSLQC1      = 0x8020 | OPC_LWC2,
468     OPC_GSSHFL      = OPC_LWC2,
469     OPC_GSSQ        = 0x0020 | OPC_SWC2,
470     OPC_GSSQC1      = 0x8020 | OPC_SWC2,
471     OPC_GSSHFS      = OPC_SWC2,
472 };
473 
474 /* Loongson EXT shifted load/store opcodes */
475 #define MASK_LOONGSON_GSSHFLS(op)         (MASK_OP_MAJOR(op) | (op & 0xc03f))
476 enum {
477     OPC_GSLWLC1     = 0x4 | OPC_GSSHFL,
478     OPC_GSLWRC1     = 0x5 | OPC_GSSHFL,
479     OPC_GSLDLC1     = 0x6 | OPC_GSSHFL,
480     OPC_GSLDRC1     = 0x7 | OPC_GSSHFL,
481     OPC_GSSWLC1     = 0x4 | OPC_GSSHFS,
482     OPC_GSSWRC1     = 0x5 | OPC_GSSHFS,
483     OPC_GSSDLC1     = 0x6 | OPC_GSSHFS,
484     OPC_GSSDRC1     = 0x7 | OPC_GSSHFS,
485 };
486 
487 /* Loongson EXT LDC2/SDC2 opcodes */
488 #define MASK_LOONGSON_LSDC2(op)           (MASK_OP_MAJOR(op) | (op & 0x7))
489 
490 enum {
491     OPC_GSLBX      = 0x0 | OPC_LDC2,
492     OPC_GSLHX      = 0x1 | OPC_LDC2,
493     OPC_GSLWX      = 0x2 | OPC_LDC2,
494     OPC_GSLDX      = 0x3 | OPC_LDC2,
495     OPC_GSLWXC1    = 0x6 | OPC_LDC2,
496     OPC_GSLDXC1    = 0x7 | OPC_LDC2,
497     OPC_GSSBX      = 0x0 | OPC_SDC2,
498     OPC_GSSHX      = 0x1 | OPC_SDC2,
499     OPC_GSSWX      = 0x2 | OPC_SDC2,
500     OPC_GSSDX      = 0x3 | OPC_SDC2,
501     OPC_GSSWXC1    = 0x6 | OPC_SDC2,
502     OPC_GSSDXC1    = 0x7 | OPC_SDC2,
503 };
504 
505 /* BSHFL opcodes */
506 #define MASK_BSHFL(op)              (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
507 
508 enum {
509     OPC_WSBH      = (0x02 << 6) | OPC_BSHFL,
510     OPC_SEB       = (0x10 << 6) | OPC_BSHFL,
511     OPC_SEH       = (0x18 << 6) | OPC_BSHFL,
512     OPC_ALIGN     = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */
513     OPC_ALIGN_1   = (0x09 << 6) | OPC_BSHFL,
514     OPC_ALIGN_2   = (0x0A << 6) | OPC_BSHFL,
515     OPC_ALIGN_3   = (0x0B << 6) | OPC_BSHFL,
516     OPC_BITSWAP   = (0x00 << 6) | OPC_BSHFL  /* 00000 */
517 };
518 
519 /* DBSHFL opcodes */
520 #define MASK_DBSHFL(op)             (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
521 
522 enum {
523     OPC_DSBH       = (0x02 << 6) | OPC_DBSHFL,
524     OPC_DSHD       = (0x05 << 6) | OPC_DBSHFL,
525     OPC_DALIGN     = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */
526     OPC_DALIGN_1   = (0x09 << 6) | OPC_DBSHFL,
527     OPC_DALIGN_2   = (0x0A << 6) | OPC_DBSHFL,
528     OPC_DALIGN_3   = (0x0B << 6) | OPC_DBSHFL,
529     OPC_DALIGN_4   = (0x0C << 6) | OPC_DBSHFL,
530     OPC_DALIGN_5   = (0x0D << 6) | OPC_DBSHFL,
531     OPC_DALIGN_6   = (0x0E << 6) | OPC_DBSHFL,
532     OPC_DALIGN_7   = (0x0F << 6) | OPC_DBSHFL,
533     OPC_DBITSWAP   = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
534 };
535 
536 /* MIPS DSP REGIMM opcodes */
537 enum {
538     OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
539     OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
540 };
541 
542 #define MASK_LX(op)                 (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
543 /* MIPS DSP Load */
544 enum {
545     OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
546     OPC_LHX  = (0x04 << 6) | OPC_LX_DSP,
547     OPC_LWX  = (0x00 << 6) | OPC_LX_DSP,
548     OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
549 };
550 
551 #define MASK_ADDU_QB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
552 enum {
553     /* MIPS DSP Arithmetic Sub-class */
554     OPC_ADDQ_PH        = (0x0A << 6) | OPC_ADDU_QB_DSP,
555     OPC_ADDQ_S_PH      = (0x0E << 6) | OPC_ADDU_QB_DSP,
556     OPC_ADDQ_S_W       = (0x16 << 6) | OPC_ADDU_QB_DSP,
557     OPC_ADDU_QB        = (0x00 << 6) | OPC_ADDU_QB_DSP,
558     OPC_ADDU_S_QB      = (0x04 << 6) | OPC_ADDU_QB_DSP,
559     OPC_ADDU_PH        = (0x08 << 6) | OPC_ADDU_QB_DSP,
560     OPC_ADDU_S_PH      = (0x0C << 6) | OPC_ADDU_QB_DSP,
561     OPC_SUBQ_PH        = (0x0B << 6) | OPC_ADDU_QB_DSP,
562     OPC_SUBQ_S_PH      = (0x0F << 6) | OPC_ADDU_QB_DSP,
563     OPC_SUBQ_S_W       = (0x17 << 6) | OPC_ADDU_QB_DSP,
564     OPC_SUBU_QB        = (0x01 << 6) | OPC_ADDU_QB_DSP,
565     OPC_SUBU_S_QB      = (0x05 << 6) | OPC_ADDU_QB_DSP,
566     OPC_SUBU_PH        = (0x09 << 6) | OPC_ADDU_QB_DSP,
567     OPC_SUBU_S_PH      = (0x0D << 6) | OPC_ADDU_QB_DSP,
568     OPC_ADDSC          = (0x10 << 6) | OPC_ADDU_QB_DSP,
569     OPC_ADDWC          = (0x11 << 6) | OPC_ADDU_QB_DSP,
570     OPC_MODSUB         = (0x12 << 6) | OPC_ADDU_QB_DSP,
571     OPC_RADDU_W_QB     = (0x14 << 6) | OPC_ADDU_QB_DSP,
572     /* MIPS DSP Multiply Sub-class insns */
573     OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
574     OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
575     OPC_MULQ_RS_PH     = (0x1F << 6) | OPC_ADDU_QB_DSP,
576     OPC_MULEQ_S_W_PHL  = (0x1C << 6) | OPC_ADDU_QB_DSP,
577     OPC_MULEQ_S_W_PHR  = (0x1D << 6) | OPC_ADDU_QB_DSP,
578     OPC_MULQ_S_PH      = (0x1E << 6) | OPC_ADDU_QB_DSP,
579 };
580 
581 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
582 #define MASK_ADDUH_QB(op)           (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
583 enum {
584     /* MIPS DSP Arithmetic Sub-class */
585     OPC_ADDUH_QB   = (0x00 << 6) | OPC_ADDUH_QB_DSP,
586     OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
587     OPC_ADDQH_PH   = (0x08 << 6) | OPC_ADDUH_QB_DSP,
588     OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
589     OPC_ADDQH_W    = (0x10 << 6) | OPC_ADDUH_QB_DSP,
590     OPC_ADDQH_R_W  = (0x12 << 6) | OPC_ADDUH_QB_DSP,
591     OPC_SUBUH_QB   = (0x01 << 6) | OPC_ADDUH_QB_DSP,
592     OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
593     OPC_SUBQH_PH   = (0x09 << 6) | OPC_ADDUH_QB_DSP,
594     OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
595     OPC_SUBQH_W    = (0x11 << 6) | OPC_ADDUH_QB_DSP,
596     OPC_SUBQH_R_W  = (0x13 << 6) | OPC_ADDUH_QB_DSP,
597     /* MIPS DSP Multiply Sub-class insns */
598     OPC_MUL_PH     = (0x0C << 6) | OPC_ADDUH_QB_DSP,
599     OPC_MUL_S_PH   = (0x0E << 6) | OPC_ADDUH_QB_DSP,
600     OPC_MULQ_S_W   = (0x16 << 6) | OPC_ADDUH_QB_DSP,
601     OPC_MULQ_RS_W  = (0x17 << 6) | OPC_ADDUH_QB_DSP,
602 };
603 
604 #define MASK_ABSQ_S_PH(op)          (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
605 enum {
606     /* MIPS DSP Arithmetic Sub-class */
607     OPC_ABSQ_S_QB       = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
608     OPC_ABSQ_S_PH       = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
609     OPC_ABSQ_S_W        = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
610     OPC_PRECEQ_W_PHL    = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
611     OPC_PRECEQ_W_PHR    = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
612     OPC_PRECEQU_PH_QBL  = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
613     OPC_PRECEQU_PH_QBR  = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
614     OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
615     OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
616     OPC_PRECEU_PH_QBL   = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
617     OPC_PRECEU_PH_QBR   = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
618     OPC_PRECEU_PH_QBLA  = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
619     OPC_PRECEU_PH_QBRA  = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
620     /* DSP Bit/Manipulation Sub-class */
621     OPC_BITREV          = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
622     OPC_REPL_QB         = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
623     OPC_REPLV_QB        = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
624     OPC_REPL_PH         = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
625     OPC_REPLV_PH        = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
626 };
627 
628 #define MASK_CMPU_EQ_QB(op)         (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
629 enum {
630     /* MIPS DSP Arithmetic Sub-class */
631     OPC_PRECR_QB_PH      = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
632     OPC_PRECRQ_QB_PH     = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
633     OPC_PRECR_SRA_PH_W   = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
634     OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
635     OPC_PRECRQ_PH_W      = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
636     OPC_PRECRQ_RS_PH_W   = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
637     OPC_PRECRQU_S_QB_PH  = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
638     /* DSP Compare-Pick Sub-class */
639     OPC_CMPU_EQ_QB       = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
640     OPC_CMPU_LT_QB       = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
641     OPC_CMPU_LE_QB       = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
642     OPC_CMPGU_EQ_QB      = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
643     OPC_CMPGU_LT_QB      = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
644     OPC_CMPGU_LE_QB      = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
645     OPC_CMPGDU_EQ_QB     = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
646     OPC_CMPGDU_LT_QB     = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
647     OPC_CMPGDU_LE_QB     = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
648     OPC_CMP_EQ_PH        = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
649     OPC_CMP_LT_PH        = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
650     OPC_CMP_LE_PH        = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
651     OPC_PICK_QB          = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
652     OPC_PICK_PH          = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
653     OPC_PACKRL_PH        = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
654 };
655 
656 #define MASK_SHLL_QB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
657 enum {
658     /* MIPS DSP GPR-Based Shift Sub-class */
659     OPC_SHLL_QB    = (0x00 << 6) | OPC_SHLL_QB_DSP,
660     OPC_SHLLV_QB   = (0x02 << 6) | OPC_SHLL_QB_DSP,
661     OPC_SHLL_PH    = (0x08 << 6) | OPC_SHLL_QB_DSP,
662     OPC_SHLLV_PH   = (0x0A << 6) | OPC_SHLL_QB_DSP,
663     OPC_SHLL_S_PH  = (0x0C << 6) | OPC_SHLL_QB_DSP,
664     OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
665     OPC_SHLL_S_W   = (0x14 << 6) | OPC_SHLL_QB_DSP,
666     OPC_SHLLV_S_W  = (0x16 << 6) | OPC_SHLL_QB_DSP,
667     OPC_SHRL_QB    = (0x01 << 6) | OPC_SHLL_QB_DSP,
668     OPC_SHRLV_QB   = (0x03 << 6) | OPC_SHLL_QB_DSP,
669     OPC_SHRL_PH    = (0x19 << 6) | OPC_SHLL_QB_DSP,
670     OPC_SHRLV_PH   = (0x1B << 6) | OPC_SHLL_QB_DSP,
671     OPC_SHRA_QB    = (0x04 << 6) | OPC_SHLL_QB_DSP,
672     OPC_SHRA_R_QB  = (0x05 << 6) | OPC_SHLL_QB_DSP,
673     OPC_SHRAV_QB   = (0x06 << 6) | OPC_SHLL_QB_DSP,
674     OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
675     OPC_SHRA_PH    = (0x09 << 6) | OPC_SHLL_QB_DSP,
676     OPC_SHRAV_PH   = (0x0B << 6) | OPC_SHLL_QB_DSP,
677     OPC_SHRA_R_PH  = (0x0D << 6) | OPC_SHLL_QB_DSP,
678     OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
679     OPC_SHRA_R_W   = (0x15 << 6) | OPC_SHLL_QB_DSP,
680     OPC_SHRAV_R_W  = (0x17 << 6) | OPC_SHLL_QB_DSP,
681 };
682 
683 #define MASK_DPA_W_PH(op)           (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
684 enum {
685     /* MIPS DSP Multiply Sub-class insns */
686     OPC_DPAU_H_QBL    = (0x03 << 6) | OPC_DPA_W_PH_DSP,
687     OPC_DPAU_H_QBR    = (0x07 << 6) | OPC_DPA_W_PH_DSP,
688     OPC_DPSU_H_QBL    = (0x0B << 6) | OPC_DPA_W_PH_DSP,
689     OPC_DPSU_H_QBR    = (0x0F << 6) | OPC_DPA_W_PH_DSP,
690     OPC_DPA_W_PH      = (0x00 << 6) | OPC_DPA_W_PH_DSP,
691     OPC_DPAX_W_PH     = (0x08 << 6) | OPC_DPA_W_PH_DSP,
692     OPC_DPAQ_S_W_PH   = (0x04 << 6) | OPC_DPA_W_PH_DSP,
693     OPC_DPAQX_S_W_PH  = (0x18 << 6) | OPC_DPA_W_PH_DSP,
694     OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
695     OPC_DPS_W_PH      = (0x01 << 6) | OPC_DPA_W_PH_DSP,
696     OPC_DPSX_W_PH     = (0x09 << 6) | OPC_DPA_W_PH_DSP,
697     OPC_DPSQ_S_W_PH   = (0x05 << 6) | OPC_DPA_W_PH_DSP,
698     OPC_DPSQX_S_W_PH  = (0x19 << 6) | OPC_DPA_W_PH_DSP,
699     OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
700     OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
701     OPC_DPAQ_SA_L_W   = (0x0C << 6) | OPC_DPA_W_PH_DSP,
702     OPC_DPSQ_SA_L_W   = (0x0D << 6) | OPC_DPA_W_PH_DSP,
703     OPC_MAQ_S_W_PHL   = (0x14 << 6) | OPC_DPA_W_PH_DSP,
704     OPC_MAQ_S_W_PHR   = (0x16 << 6) | OPC_DPA_W_PH_DSP,
705     OPC_MAQ_SA_W_PHL  = (0x10 << 6) | OPC_DPA_W_PH_DSP,
706     OPC_MAQ_SA_W_PHR  = (0x12 << 6) | OPC_DPA_W_PH_DSP,
707     OPC_MULSA_W_PH    = (0x02 << 6) | OPC_DPA_W_PH_DSP,
708 };
709 
710 #define MASK_INSV(op)               (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
711 enum {
712     /* DSP Bit/Manipulation Sub-class */
713     OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
714 };
715 
716 #define MASK_APPEND(op)             (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
717 enum {
718     /* MIPS DSP Append Sub-class */
719     OPC_APPEND  = (0x00 << 6) | OPC_APPEND_DSP,
720     OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
721     OPC_BALIGN  = (0x10 << 6) | OPC_APPEND_DSP,
722 };
723 
724 #define MASK_EXTR_W(op)             (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
725 enum {
726     /* MIPS DSP Accumulator and DSPControl Access Sub-class */
727     OPC_EXTR_W     = (0x00 << 6) | OPC_EXTR_W_DSP,
728     OPC_EXTR_R_W   = (0x04 << 6) | OPC_EXTR_W_DSP,
729     OPC_EXTR_RS_W  = (0x06 << 6) | OPC_EXTR_W_DSP,
730     OPC_EXTR_S_H   = (0x0E << 6) | OPC_EXTR_W_DSP,
731     OPC_EXTRV_S_H  = (0x0F << 6) | OPC_EXTR_W_DSP,
732     OPC_EXTRV_W    = (0x01 << 6) | OPC_EXTR_W_DSP,
733     OPC_EXTRV_R_W  = (0x05 << 6) | OPC_EXTR_W_DSP,
734     OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
735     OPC_EXTP       = (0x02 << 6) | OPC_EXTR_W_DSP,
736     OPC_EXTPV      = (0x03 << 6) | OPC_EXTR_W_DSP,
737     OPC_EXTPDP     = (0x0A << 6) | OPC_EXTR_W_DSP,
738     OPC_EXTPDPV    = (0x0B << 6) | OPC_EXTR_W_DSP,
739     OPC_SHILO      = (0x1A << 6) | OPC_EXTR_W_DSP,
740     OPC_SHILOV     = (0x1B << 6) | OPC_EXTR_W_DSP,
741     OPC_MTHLIP     = (0x1F << 6) | OPC_EXTR_W_DSP,
742     OPC_WRDSP      = (0x13 << 6) | OPC_EXTR_W_DSP,
743     OPC_RDDSP      = (0x12 << 6) | OPC_EXTR_W_DSP,
744 };
745 
746 #define MASK_ABSQ_S_QH(op)          (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
747 enum {
748     /* MIPS DSP Arithmetic Sub-class */
749     OPC_PRECEQ_L_PWL    = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
750     OPC_PRECEQ_L_PWR    = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
751     OPC_PRECEQ_PW_QHL   = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
752     OPC_PRECEQ_PW_QHR   = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
753     OPC_PRECEQ_PW_QHLA  = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
754     OPC_PRECEQ_PW_QHRA  = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
755     OPC_PRECEQU_QH_OBL  = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
756     OPC_PRECEQU_QH_OBR  = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
757     OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
758     OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
759     OPC_PRECEU_QH_OBL   = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
760     OPC_PRECEU_QH_OBR   = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
761     OPC_PRECEU_QH_OBLA  = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
762     OPC_PRECEU_QH_OBRA  = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
763     OPC_ABSQ_S_OB       = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
764     OPC_ABSQ_S_PW       = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
765     OPC_ABSQ_S_QH       = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
766     /* DSP Bit/Manipulation Sub-class */
767     OPC_REPL_OB         = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
768     OPC_REPL_PW         = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
769     OPC_REPL_QH         = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
770     OPC_REPLV_OB        = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
771     OPC_REPLV_PW        = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
772     OPC_REPLV_QH        = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
773 };
774 
775 #define MASK_ADDU_OB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
776 enum {
777     /* MIPS DSP Multiply Sub-class insns */
778     OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
779     OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
780     OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
781     OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
782     OPC_MULQ_RS_QH     = (0x1F << 6) | OPC_ADDU_OB_DSP,
783     /* MIPS DSP Arithmetic Sub-class */
784     OPC_RADDU_L_OB     = (0x14 << 6) | OPC_ADDU_OB_DSP,
785     OPC_SUBQ_PW        = (0x13 << 6) | OPC_ADDU_OB_DSP,
786     OPC_SUBQ_S_PW      = (0x17 << 6) | OPC_ADDU_OB_DSP,
787     OPC_SUBQ_QH        = (0x0B << 6) | OPC_ADDU_OB_DSP,
788     OPC_SUBQ_S_QH      = (0x0F << 6) | OPC_ADDU_OB_DSP,
789     OPC_SUBU_OB        = (0x01 << 6) | OPC_ADDU_OB_DSP,
790     OPC_SUBU_S_OB      = (0x05 << 6) | OPC_ADDU_OB_DSP,
791     OPC_SUBU_QH        = (0x09 << 6) | OPC_ADDU_OB_DSP,
792     OPC_SUBU_S_QH      = (0x0D << 6) | OPC_ADDU_OB_DSP,
793     OPC_SUBUH_OB       = (0x19 << 6) | OPC_ADDU_OB_DSP,
794     OPC_SUBUH_R_OB     = (0x1B << 6) | OPC_ADDU_OB_DSP,
795     OPC_ADDQ_PW        = (0x12 << 6) | OPC_ADDU_OB_DSP,
796     OPC_ADDQ_S_PW      = (0x16 << 6) | OPC_ADDU_OB_DSP,
797     OPC_ADDQ_QH        = (0x0A << 6) | OPC_ADDU_OB_DSP,
798     OPC_ADDQ_S_QH      = (0x0E << 6) | OPC_ADDU_OB_DSP,
799     OPC_ADDU_OB        = (0x00 << 6) | OPC_ADDU_OB_DSP,
800     OPC_ADDU_S_OB      = (0x04 << 6) | OPC_ADDU_OB_DSP,
801     OPC_ADDU_QH        = (0x08 << 6) | OPC_ADDU_OB_DSP,
802     OPC_ADDU_S_QH      = (0x0C << 6) | OPC_ADDU_OB_DSP,
803     OPC_ADDUH_OB       = (0x18 << 6) | OPC_ADDU_OB_DSP,
804     OPC_ADDUH_R_OB     = (0x1A << 6) | OPC_ADDU_OB_DSP,
805 };
806 
807 #define MASK_CMPU_EQ_OB(op)         (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
808 enum {
809     /* DSP Compare-Pick Sub-class */
810     OPC_CMP_EQ_PW         = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
811     OPC_CMP_LT_PW         = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
812     OPC_CMP_LE_PW         = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
813     OPC_CMP_EQ_QH         = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
814     OPC_CMP_LT_QH         = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
815     OPC_CMP_LE_QH         = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
816     OPC_CMPGDU_EQ_OB      = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
817     OPC_CMPGDU_LT_OB      = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
818     OPC_CMPGDU_LE_OB      = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
819     OPC_CMPGU_EQ_OB       = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
820     OPC_CMPGU_LT_OB       = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
821     OPC_CMPGU_LE_OB       = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
822     OPC_CMPU_EQ_OB        = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
823     OPC_CMPU_LT_OB        = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
824     OPC_CMPU_LE_OB        = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
825     OPC_PACKRL_PW         = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
826     OPC_PICK_OB           = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
827     OPC_PICK_PW           = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
828     OPC_PICK_QH           = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
829     /* MIPS DSP Arithmetic Sub-class */
830     OPC_PRECR_OB_QH       = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
831     OPC_PRECR_SRA_QH_PW   = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
832     OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
833     OPC_PRECRQ_OB_QH      = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
834     OPC_PRECRQ_PW_L       = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
835     OPC_PRECRQ_QH_PW      = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
836     OPC_PRECRQ_RS_QH_PW   = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
837     OPC_PRECRQU_S_OB_QH   = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
838 };
839 
840 #define MASK_DAPPEND(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
841 enum {
842     /* DSP Append Sub-class */
843     OPC_DAPPEND  = (0x00 << 6) | OPC_DAPPEND_DSP,
844     OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
845     OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
846     OPC_DBALIGN  = (0x10 << 6) | OPC_DAPPEND_DSP,
847 };
848 
849 #define MASK_DEXTR_W(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
850 enum {
851     /* MIPS DSP Accumulator and DSPControl Access Sub-class */
852     OPC_DMTHLIP     = (0x1F << 6) | OPC_DEXTR_W_DSP,
853     OPC_DSHILO      = (0x1A << 6) | OPC_DEXTR_W_DSP,
854     OPC_DEXTP       = (0x02 << 6) | OPC_DEXTR_W_DSP,
855     OPC_DEXTPDP     = (0x0A << 6) | OPC_DEXTR_W_DSP,
856     OPC_DEXTPDPV    = (0x0B << 6) | OPC_DEXTR_W_DSP,
857     OPC_DEXTPV      = (0x03 << 6) | OPC_DEXTR_W_DSP,
858     OPC_DEXTR_L     = (0x10 << 6) | OPC_DEXTR_W_DSP,
859     OPC_DEXTR_R_L   = (0x14 << 6) | OPC_DEXTR_W_DSP,
860     OPC_DEXTR_RS_L  = (0x16 << 6) | OPC_DEXTR_W_DSP,
861     OPC_DEXTR_W     = (0x00 << 6) | OPC_DEXTR_W_DSP,
862     OPC_DEXTR_R_W   = (0x04 << 6) | OPC_DEXTR_W_DSP,
863     OPC_DEXTR_RS_W  = (0x06 << 6) | OPC_DEXTR_W_DSP,
864     OPC_DEXTR_S_H   = (0x0E << 6) | OPC_DEXTR_W_DSP,
865     OPC_DEXTRV_L    = (0x11 << 6) | OPC_DEXTR_W_DSP,
866     OPC_DEXTRV_R_L  = (0x15 << 6) | OPC_DEXTR_W_DSP,
867     OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
868     OPC_DEXTRV_S_H  = (0x0F << 6) | OPC_DEXTR_W_DSP,
869     OPC_DEXTRV_W    = (0x01 << 6) | OPC_DEXTR_W_DSP,
870     OPC_DEXTRV_R_W  = (0x05 << 6) | OPC_DEXTR_W_DSP,
871     OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
872     OPC_DSHILOV     = (0x1B << 6) | OPC_DEXTR_W_DSP,
873 };
874 
875 #define MASK_DINSV(op)              (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
876 enum {
877     /* DSP Bit/Manipulation Sub-class */
878     OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
879 };
880 
881 #define MASK_DPAQ_W_QH(op)          (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
882 enum {
883     /* MIPS DSP Multiply Sub-class insns */
884     OPC_DMADD         = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
885     OPC_DMADDU        = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
886     OPC_DMSUB         = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
887     OPC_DMSUBU        = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
888     OPC_DPA_W_QH      = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
889     OPC_DPAQ_S_W_QH   = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
890     OPC_DPAQ_SA_L_PW  = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
891     OPC_DPAU_H_OBL    = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
892     OPC_DPAU_H_OBR    = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
893     OPC_DPS_W_QH      = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
894     OPC_DPSQ_S_W_QH   = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
895     OPC_DPSQ_SA_L_PW  = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
896     OPC_DPSU_H_OBL    = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
897     OPC_DPSU_H_OBR    = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
898     OPC_MAQ_S_L_PWL   = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
899     OPC_MAQ_S_L_PWR   = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
900     OPC_MAQ_S_W_QHLL  = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
901     OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
902     OPC_MAQ_S_W_QHLR  = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
903     OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
904     OPC_MAQ_S_W_QHRL  = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
905     OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
906     OPC_MAQ_S_W_QHRR  = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
907     OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
908     OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
909     OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
910 };
911 
912 #define MASK_SHLL_OB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
913 enum {
914     /* MIPS DSP GPR-Based Shift Sub-class */
915     OPC_SHLL_PW    = (0x10 << 6) | OPC_SHLL_OB_DSP,
916     OPC_SHLL_S_PW  = (0x14 << 6) | OPC_SHLL_OB_DSP,
917     OPC_SHLLV_OB   = (0x02 << 6) | OPC_SHLL_OB_DSP,
918     OPC_SHLLV_PW   = (0x12 << 6) | OPC_SHLL_OB_DSP,
919     OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
920     OPC_SHLLV_QH   = (0x0A << 6) | OPC_SHLL_OB_DSP,
921     OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
922     OPC_SHRA_PW    = (0x11 << 6) | OPC_SHLL_OB_DSP,
923     OPC_SHRA_R_PW  = (0x15 << 6) | OPC_SHLL_OB_DSP,
924     OPC_SHRAV_OB   = (0x06 << 6) | OPC_SHLL_OB_DSP,
925     OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
926     OPC_SHRAV_PW   = (0x13 << 6) | OPC_SHLL_OB_DSP,
927     OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
928     OPC_SHRAV_QH   = (0x0B << 6) | OPC_SHLL_OB_DSP,
929     OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
930     OPC_SHRLV_OB   = (0x03 << 6) | OPC_SHLL_OB_DSP,
931     OPC_SHRLV_QH   = (0x1B << 6) | OPC_SHLL_OB_DSP,
932     OPC_SHLL_OB    = (0x00 << 6) | OPC_SHLL_OB_DSP,
933     OPC_SHLL_QH    = (0x08 << 6) | OPC_SHLL_OB_DSP,
934     OPC_SHLL_S_QH  = (0x0C << 6) | OPC_SHLL_OB_DSP,
935     OPC_SHRA_OB    = (0x04 << 6) | OPC_SHLL_OB_DSP,
936     OPC_SHRA_R_OB  = (0x05 << 6) | OPC_SHLL_OB_DSP,
937     OPC_SHRA_QH    = (0x09 << 6) | OPC_SHLL_OB_DSP,
938     OPC_SHRA_R_QH  = (0x0D << 6) | OPC_SHLL_OB_DSP,
939     OPC_SHRL_OB    = (0x01 << 6) | OPC_SHLL_OB_DSP,
940     OPC_SHRL_QH    = (0x19 << 6) | OPC_SHLL_OB_DSP,
941 };
942 
943 /* Coprocessor 0 (rs field) */
944 #define MASK_CP0(op)                (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
945 
946 enum {
947     OPC_MFC0     = (0x00 << 21) | OPC_CP0,
948     OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
949     OPC_MFHC0    = (0x02 << 21) | OPC_CP0,
950     OPC_MTC0     = (0x04 << 21) | OPC_CP0,
951     OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
952     OPC_MTHC0    = (0x06 << 21) | OPC_CP0,
953     OPC_MFTR     = (0x08 << 21) | OPC_CP0,
954     OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
955     OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
956     OPC_MTTR     = (0x0C << 21) | OPC_CP0,
957     OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
958     OPC_C0       = (0x10 << 21) | OPC_CP0,
959     OPC_C0_1     = (0x11 << 21) | OPC_CP0,
960     OPC_C0_2     = (0x12 << 21) | OPC_CP0,
961     OPC_C0_3     = (0x13 << 21) | OPC_CP0,
962     OPC_C0_4     = (0x14 << 21) | OPC_CP0,
963     OPC_C0_5     = (0x15 << 21) | OPC_CP0,
964     OPC_C0_6     = (0x16 << 21) | OPC_CP0,
965     OPC_C0_7     = (0x17 << 21) | OPC_CP0,
966     OPC_C0_8     = (0x18 << 21) | OPC_CP0,
967     OPC_C0_9     = (0x19 << 21) | OPC_CP0,
968     OPC_C0_A     = (0x1A << 21) | OPC_CP0,
969     OPC_C0_B     = (0x1B << 21) | OPC_CP0,
970     OPC_C0_C     = (0x1C << 21) | OPC_CP0,
971     OPC_C0_D     = (0x1D << 21) | OPC_CP0,
972     OPC_C0_E     = (0x1E << 21) | OPC_CP0,
973     OPC_C0_F     = (0x1F << 21) | OPC_CP0,
974 };
975 
976 /* MFMC0 opcodes */
977 #define MASK_MFMC0(op)              (MASK_CP0(op) | (op & 0xFFFF))
978 
979 enum {
980     OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
981     OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
982     OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
983     OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
984     OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
985     OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
986     OPC_DVP      = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
987     OPC_EVP      = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
988 };
989 
990 /* Coprocessor 0 (with rs == C0) */
991 #define MASK_C0(op)                 (MASK_CP0(op) | (op & 0x3F))
992 
993 enum {
994     OPC_TLBR     = 0x01 | OPC_C0,
995     OPC_TLBWI    = 0x02 | OPC_C0,
996     OPC_TLBINV   = 0x03 | OPC_C0,
997     OPC_TLBINVF  = 0x04 | OPC_C0,
998     OPC_TLBWR    = 0x06 | OPC_C0,
999     OPC_TLBP     = 0x08 | OPC_C0,
1000     OPC_RFE      = 0x10 | OPC_C0,
1001     OPC_ERET     = 0x18 | OPC_C0,
1002     OPC_DERET    = 0x1F | OPC_C0,
1003     OPC_WAIT     = 0x20 | OPC_C0,
1004 };
1005 
1006 /* Coprocessor 1 (rs field) */
1007 #define MASK_CP1(op)                (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
1008 
1009 /* Values for the fmt field in FP instructions */
1010 enum {
1011     /* 0 - 15 are reserved */
1012     FMT_S = 16,          /* single fp */
1013     FMT_D = 17,          /* double fp */
1014     FMT_E = 18,          /* extended fp */
1015     FMT_Q = 19,          /* quad fp */
1016     FMT_W = 20,          /* 32-bit fixed */
1017     FMT_L = 21,          /* 64-bit fixed */
1018     FMT_PS = 22,         /* paired single fp */
1019     /* 23 - 31 are reserved */
1020 };
1021 
1022 enum {
1023     OPC_MFC1     = (0x00 << 21) | OPC_CP1,
1024     OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
1025     OPC_CFC1     = (0x02 << 21) | OPC_CP1,
1026     OPC_MFHC1    = (0x03 << 21) | OPC_CP1,
1027     OPC_MTC1     = (0x04 << 21) | OPC_CP1,
1028     OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
1029     OPC_CTC1     = (0x06 << 21) | OPC_CP1,
1030     OPC_MTHC1    = (0x07 << 21) | OPC_CP1,
1031     OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
1032     OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
1033     OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
1034     OPC_BZ_V     = (0x0B << 21) | OPC_CP1,
1035     OPC_BNZ_V    = (0x0F << 21) | OPC_CP1,
1036     OPC_S_FMT    = (FMT_S << 21) | OPC_CP1,
1037     OPC_D_FMT    = (FMT_D << 21) | OPC_CP1,
1038     OPC_E_FMT    = (FMT_E << 21) | OPC_CP1,
1039     OPC_Q_FMT    = (FMT_Q << 21) | OPC_CP1,
1040     OPC_W_FMT    = (FMT_W << 21) | OPC_CP1,
1041     OPC_L_FMT    = (FMT_L << 21) | OPC_CP1,
1042     OPC_PS_FMT   = (FMT_PS << 21) | OPC_CP1,
1043     OPC_BC1EQZ   = (0x09 << 21) | OPC_CP1,
1044     OPC_BC1NEZ   = (0x0D << 21) | OPC_CP1,
1045     OPC_BZ_B     = (0x18 << 21) | OPC_CP1,
1046     OPC_BZ_H     = (0x19 << 21) | OPC_CP1,
1047     OPC_BZ_W     = (0x1A << 21) | OPC_CP1,
1048     OPC_BZ_D     = (0x1B << 21) | OPC_CP1,
1049     OPC_BNZ_B    = (0x1C << 21) | OPC_CP1,
1050     OPC_BNZ_H    = (0x1D << 21) | OPC_CP1,
1051     OPC_BNZ_W    = (0x1E << 21) | OPC_CP1,
1052     OPC_BNZ_D    = (0x1F << 21) | OPC_CP1,
1053 };
1054 
1055 #define MASK_CP1_FUNC(op)           (MASK_CP1(op) | (op & 0x3F))
1056 #define MASK_BC1(op)                (MASK_CP1(op) | (op & (0x3 << 16)))
1057 
1058 enum {
1059     OPC_BC1F     = (0x00 << 16) | OPC_BC1,
1060     OPC_BC1T     = (0x01 << 16) | OPC_BC1,
1061     OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
1062     OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
1063 };
1064 
1065 enum {
1066     OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
1067     OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
1068 };
1069 
1070 enum {
1071     OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
1072     OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
1073 };
1074 
1075 #define MASK_CP2(op)                (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
1076 
1077 enum {
1078     OPC_MFC2    = (0x00 << 21) | OPC_CP2,
1079     OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
1080     OPC_CFC2    = (0x02 << 21) | OPC_CP2,
1081     OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
1082     OPC_MTC2    = (0x04 << 21) | OPC_CP2,
1083     OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
1084     OPC_CTC2    = (0x06 << 21) | OPC_CP2,
1085     OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
1086     OPC_BC2     = (0x08 << 21) | OPC_CP2,
1087     OPC_BC2EQZ  = (0x09 << 21) | OPC_CP2,
1088     OPC_BC2NEZ  = (0x0D << 21) | OPC_CP2,
1089 };
1090 
1091 #define MASK_LMMI(op)    (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1092 
1093 enum {
1094     OPC_PADDSH      = (24 << 21) | (0x00) | OPC_CP2,
1095     OPC_PADDUSH     = (25 << 21) | (0x00) | OPC_CP2,
1096     OPC_PADDH       = (26 << 21) | (0x00) | OPC_CP2,
1097     OPC_PADDW       = (27 << 21) | (0x00) | OPC_CP2,
1098     OPC_PADDSB      = (28 << 21) | (0x00) | OPC_CP2,
1099     OPC_PADDUSB     = (29 << 21) | (0x00) | OPC_CP2,
1100     OPC_PADDB       = (30 << 21) | (0x00) | OPC_CP2,
1101     OPC_PADDD       = (31 << 21) | (0x00) | OPC_CP2,
1102 
1103     OPC_PSUBSH      = (24 << 21) | (0x01) | OPC_CP2,
1104     OPC_PSUBUSH     = (25 << 21) | (0x01) | OPC_CP2,
1105     OPC_PSUBH       = (26 << 21) | (0x01) | OPC_CP2,
1106     OPC_PSUBW       = (27 << 21) | (0x01) | OPC_CP2,
1107     OPC_PSUBSB      = (28 << 21) | (0x01) | OPC_CP2,
1108     OPC_PSUBUSB     = (29 << 21) | (0x01) | OPC_CP2,
1109     OPC_PSUBB       = (30 << 21) | (0x01) | OPC_CP2,
1110     OPC_PSUBD       = (31 << 21) | (0x01) | OPC_CP2,
1111 
1112     OPC_PSHUFH      = (24 << 21) | (0x02) | OPC_CP2,
1113     OPC_PACKSSWH    = (25 << 21) | (0x02) | OPC_CP2,
1114     OPC_PACKSSHB    = (26 << 21) | (0x02) | OPC_CP2,
1115     OPC_PACKUSHB    = (27 << 21) | (0x02) | OPC_CP2,
1116     OPC_XOR_CP2     = (28 << 21) | (0x02) | OPC_CP2,
1117     OPC_NOR_CP2     = (29 << 21) | (0x02) | OPC_CP2,
1118     OPC_AND_CP2     = (30 << 21) | (0x02) | OPC_CP2,
1119     OPC_PANDN       = (31 << 21) | (0x02) | OPC_CP2,
1120 
1121     OPC_PUNPCKLHW   = (24 << 21) | (0x03) | OPC_CP2,
1122     OPC_PUNPCKHHW   = (25 << 21) | (0x03) | OPC_CP2,
1123     OPC_PUNPCKLBH   = (26 << 21) | (0x03) | OPC_CP2,
1124     OPC_PUNPCKHBH   = (27 << 21) | (0x03) | OPC_CP2,
1125     OPC_PINSRH_0    = (28 << 21) | (0x03) | OPC_CP2,
1126     OPC_PINSRH_1    = (29 << 21) | (0x03) | OPC_CP2,
1127     OPC_PINSRH_2    = (30 << 21) | (0x03) | OPC_CP2,
1128     OPC_PINSRH_3    = (31 << 21) | (0x03) | OPC_CP2,
1129 
1130     OPC_PAVGH       = (24 << 21) | (0x08) | OPC_CP2,
1131     OPC_PAVGB       = (25 << 21) | (0x08) | OPC_CP2,
1132     OPC_PMAXSH      = (26 << 21) | (0x08) | OPC_CP2,
1133     OPC_PMINSH      = (27 << 21) | (0x08) | OPC_CP2,
1134     OPC_PMAXUB      = (28 << 21) | (0x08) | OPC_CP2,
1135     OPC_PMINUB      = (29 << 21) | (0x08) | OPC_CP2,
1136 
1137     OPC_PCMPEQW     = (24 << 21) | (0x09) | OPC_CP2,
1138     OPC_PCMPGTW     = (25 << 21) | (0x09) | OPC_CP2,
1139     OPC_PCMPEQH     = (26 << 21) | (0x09) | OPC_CP2,
1140     OPC_PCMPGTH     = (27 << 21) | (0x09) | OPC_CP2,
1141     OPC_PCMPEQB     = (28 << 21) | (0x09) | OPC_CP2,
1142     OPC_PCMPGTB     = (29 << 21) | (0x09) | OPC_CP2,
1143 
1144     OPC_PSLLW       = (24 << 21) | (0x0A) | OPC_CP2,
1145     OPC_PSLLH       = (25 << 21) | (0x0A) | OPC_CP2,
1146     OPC_PMULLH      = (26 << 21) | (0x0A) | OPC_CP2,
1147     OPC_PMULHH      = (27 << 21) | (0x0A) | OPC_CP2,
1148     OPC_PMULUW      = (28 << 21) | (0x0A) | OPC_CP2,
1149     OPC_PMULHUH     = (29 << 21) | (0x0A) | OPC_CP2,
1150 
1151     OPC_PSRLW       = (24 << 21) | (0x0B) | OPC_CP2,
1152     OPC_PSRLH       = (25 << 21) | (0x0B) | OPC_CP2,
1153     OPC_PSRAW       = (26 << 21) | (0x0B) | OPC_CP2,
1154     OPC_PSRAH       = (27 << 21) | (0x0B) | OPC_CP2,
1155     OPC_PUNPCKLWD   = (28 << 21) | (0x0B) | OPC_CP2,
1156     OPC_PUNPCKHWD   = (29 << 21) | (0x0B) | OPC_CP2,
1157 
1158     OPC_ADDU_CP2    = (24 << 21) | (0x0C) | OPC_CP2,
1159     OPC_OR_CP2      = (25 << 21) | (0x0C) | OPC_CP2,
1160     OPC_ADD_CP2     = (26 << 21) | (0x0C) | OPC_CP2,
1161     OPC_DADD_CP2    = (27 << 21) | (0x0C) | OPC_CP2,
1162     OPC_SEQU_CP2    = (28 << 21) | (0x0C) | OPC_CP2,
1163     OPC_SEQ_CP2     = (29 << 21) | (0x0C) | OPC_CP2,
1164 
1165     OPC_SUBU_CP2    = (24 << 21) | (0x0D) | OPC_CP2,
1166     OPC_PASUBUB     = (25 << 21) | (0x0D) | OPC_CP2,
1167     OPC_SUB_CP2     = (26 << 21) | (0x0D) | OPC_CP2,
1168     OPC_DSUB_CP2    = (27 << 21) | (0x0D) | OPC_CP2,
1169     OPC_SLTU_CP2    = (28 << 21) | (0x0D) | OPC_CP2,
1170     OPC_SLT_CP2     = (29 << 21) | (0x0D) | OPC_CP2,
1171 
1172     OPC_SLL_CP2     = (24 << 21) | (0x0E) | OPC_CP2,
1173     OPC_DSLL_CP2    = (25 << 21) | (0x0E) | OPC_CP2,
1174     OPC_PEXTRH      = (26 << 21) | (0x0E) | OPC_CP2,
1175     OPC_PMADDHW     = (27 << 21) | (0x0E) | OPC_CP2,
1176     OPC_SLEU_CP2    = (28 << 21) | (0x0E) | OPC_CP2,
1177     OPC_SLE_CP2     = (29 << 21) | (0x0E) | OPC_CP2,
1178 
1179     OPC_SRL_CP2     = (24 << 21) | (0x0F) | OPC_CP2,
1180     OPC_DSRL_CP2    = (25 << 21) | (0x0F) | OPC_CP2,
1181     OPC_SRA_CP2     = (26 << 21) | (0x0F) | OPC_CP2,
1182     OPC_DSRA_CP2    = (27 << 21) | (0x0F) | OPC_CP2,
1183     OPC_BIADD       = (28 << 21) | (0x0F) | OPC_CP2,
1184     OPC_PMOVMSKB    = (29 << 21) | (0x0F) | OPC_CP2,
1185 };
1186 
1187 
1188 #define MASK_CP3(op)                (MASK_OP_MAJOR(op) | (op & 0x3F))
1189 
1190 enum {
1191     OPC_LWXC1       = 0x00 | OPC_CP3,
1192     OPC_LDXC1       = 0x01 | OPC_CP3,
1193     OPC_LUXC1       = 0x05 | OPC_CP3,
1194     OPC_SWXC1       = 0x08 | OPC_CP3,
1195     OPC_SDXC1       = 0x09 | OPC_CP3,
1196     OPC_SUXC1       = 0x0D | OPC_CP3,
1197     OPC_PREFX       = 0x0F | OPC_CP3,
1198     OPC_ALNV_PS     = 0x1E | OPC_CP3,
1199     OPC_MADD_S      = 0x20 | OPC_CP3,
1200     OPC_MADD_D      = 0x21 | OPC_CP3,
1201     OPC_MADD_PS     = 0x26 | OPC_CP3,
1202     OPC_MSUB_S      = 0x28 | OPC_CP3,
1203     OPC_MSUB_D      = 0x29 | OPC_CP3,
1204     OPC_MSUB_PS     = 0x2E | OPC_CP3,
1205     OPC_NMADD_S     = 0x30 | OPC_CP3,
1206     OPC_NMADD_D     = 0x31 | OPC_CP3,
1207     OPC_NMADD_PS    = 0x36 | OPC_CP3,
1208     OPC_NMSUB_S     = 0x38 | OPC_CP3,
1209     OPC_NMSUB_D     = 0x39 | OPC_CP3,
1210     OPC_NMSUB_PS    = 0x3E | OPC_CP3,
1211 };
1212 
1213 /* MSA Opcodes */
1214 #define MASK_MSA_MINOR(op)          (MASK_OP_MAJOR(op) | (op & 0x3F))
1215 enum {
1216     OPC_MSA_I8_00   = 0x00 | OPC_MSA,
1217     OPC_MSA_I8_01   = 0x01 | OPC_MSA,
1218     OPC_MSA_I8_02   = 0x02 | OPC_MSA,
1219     OPC_MSA_I5_06   = 0x06 | OPC_MSA,
1220     OPC_MSA_I5_07   = 0x07 | OPC_MSA,
1221     OPC_MSA_BIT_09  = 0x09 | OPC_MSA,
1222     OPC_MSA_BIT_0A  = 0x0A | OPC_MSA,
1223     OPC_MSA_3R_0D   = 0x0D | OPC_MSA,
1224     OPC_MSA_3R_0E   = 0x0E | OPC_MSA,
1225     OPC_MSA_3R_0F   = 0x0F | OPC_MSA,
1226     OPC_MSA_3R_10   = 0x10 | OPC_MSA,
1227     OPC_MSA_3R_11   = 0x11 | OPC_MSA,
1228     OPC_MSA_3R_12   = 0x12 | OPC_MSA,
1229     OPC_MSA_3R_13   = 0x13 | OPC_MSA,
1230     OPC_MSA_3R_14   = 0x14 | OPC_MSA,
1231     OPC_MSA_3R_15   = 0x15 | OPC_MSA,
1232     OPC_MSA_ELM     = 0x19 | OPC_MSA,
1233     OPC_MSA_3RF_1A  = 0x1A | OPC_MSA,
1234     OPC_MSA_3RF_1B  = 0x1B | OPC_MSA,
1235     OPC_MSA_3RF_1C  = 0x1C | OPC_MSA,
1236     OPC_MSA_VEC     = 0x1E | OPC_MSA,
1237 
1238     /* MI10 instruction */
1239     OPC_LD_B        = (0x20) | OPC_MSA,
1240     OPC_LD_H        = (0x21) | OPC_MSA,
1241     OPC_LD_W        = (0x22) | OPC_MSA,
1242     OPC_LD_D        = (0x23) | OPC_MSA,
1243     OPC_ST_B        = (0x24) | OPC_MSA,
1244     OPC_ST_H        = (0x25) | OPC_MSA,
1245     OPC_ST_W        = (0x26) | OPC_MSA,
1246     OPC_ST_D        = (0x27) | OPC_MSA,
1247 };
1248 
1249 enum {
1250     /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1251     OPC_ADDVI_df    = (0x0 << 23) | OPC_MSA_I5_06,
1252     OPC_CEQI_df     = (0x0 << 23) | OPC_MSA_I5_07,
1253     OPC_SUBVI_df    = (0x1 << 23) | OPC_MSA_I5_06,
1254     OPC_MAXI_S_df   = (0x2 << 23) | OPC_MSA_I5_06,
1255     OPC_CLTI_S_df   = (0x2 << 23) | OPC_MSA_I5_07,
1256     OPC_MAXI_U_df   = (0x3 << 23) | OPC_MSA_I5_06,
1257     OPC_CLTI_U_df   = (0x3 << 23) | OPC_MSA_I5_07,
1258     OPC_MINI_S_df   = (0x4 << 23) | OPC_MSA_I5_06,
1259     OPC_CLEI_S_df   = (0x4 << 23) | OPC_MSA_I5_07,
1260     OPC_MINI_U_df   = (0x5 << 23) | OPC_MSA_I5_06,
1261     OPC_CLEI_U_df   = (0x5 << 23) | OPC_MSA_I5_07,
1262     OPC_LDI_df      = (0x6 << 23) | OPC_MSA_I5_07,
1263 
1264     /* I8 instruction */
1265     OPC_ANDI_B      = (0x0 << 24) | OPC_MSA_I8_00,
1266     OPC_BMNZI_B     = (0x0 << 24) | OPC_MSA_I8_01,
1267     OPC_SHF_B       = (0x0 << 24) | OPC_MSA_I8_02,
1268     OPC_ORI_B       = (0x1 << 24) | OPC_MSA_I8_00,
1269     OPC_BMZI_B      = (0x1 << 24) | OPC_MSA_I8_01,
1270     OPC_SHF_H       = (0x1 << 24) | OPC_MSA_I8_02,
1271     OPC_NORI_B      = (0x2 << 24) | OPC_MSA_I8_00,
1272     OPC_BSELI_B     = (0x2 << 24) | OPC_MSA_I8_01,
1273     OPC_SHF_W       = (0x2 << 24) | OPC_MSA_I8_02,
1274     OPC_XORI_B      = (0x3 << 24) | OPC_MSA_I8_00,
1275 
1276     /* VEC/2R/2RF instruction */
1277     OPC_AND_V       = (0x00 << 21) | OPC_MSA_VEC,
1278     OPC_OR_V        = (0x01 << 21) | OPC_MSA_VEC,
1279     OPC_NOR_V       = (0x02 << 21) | OPC_MSA_VEC,
1280     OPC_XOR_V       = (0x03 << 21) | OPC_MSA_VEC,
1281     OPC_BMNZ_V      = (0x04 << 21) | OPC_MSA_VEC,
1282     OPC_BMZ_V       = (0x05 << 21) | OPC_MSA_VEC,
1283     OPC_BSEL_V      = (0x06 << 21) | OPC_MSA_VEC,
1284 
1285     OPC_MSA_2R      = (0x18 << 21) | OPC_MSA_VEC,
1286     OPC_MSA_2RF     = (0x19 << 21) | OPC_MSA_VEC,
1287 
1288     /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1289     OPC_FILL_df     = (0x00 << 18) | OPC_MSA_2R,
1290     OPC_PCNT_df     = (0x01 << 18) | OPC_MSA_2R,
1291     OPC_NLOC_df     = (0x02 << 18) | OPC_MSA_2R,
1292     OPC_NLZC_df     = (0x03 << 18) | OPC_MSA_2R,
1293 
1294     /* 2RF instruction df(bit 16) = _w, _d */
1295     OPC_FCLASS_df   = (0x00 << 17) | OPC_MSA_2RF,
1296     OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1297     OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1298     OPC_FSQRT_df    = (0x03 << 17) | OPC_MSA_2RF,
1299     OPC_FRSQRT_df   = (0x04 << 17) | OPC_MSA_2RF,
1300     OPC_FRCP_df     = (0x05 << 17) | OPC_MSA_2RF,
1301     OPC_FRINT_df    = (0x06 << 17) | OPC_MSA_2RF,
1302     OPC_FLOG2_df    = (0x07 << 17) | OPC_MSA_2RF,
1303     OPC_FEXUPL_df   = (0x08 << 17) | OPC_MSA_2RF,
1304     OPC_FEXUPR_df   = (0x09 << 17) | OPC_MSA_2RF,
1305     OPC_FFQL_df     = (0x0A << 17) | OPC_MSA_2RF,
1306     OPC_FFQR_df     = (0x0B << 17) | OPC_MSA_2RF,
1307     OPC_FTINT_S_df  = (0x0C << 17) | OPC_MSA_2RF,
1308     OPC_FTINT_U_df  = (0x0D << 17) | OPC_MSA_2RF,
1309     OPC_FFINT_S_df  = (0x0E << 17) | OPC_MSA_2RF,
1310     OPC_FFINT_U_df  = (0x0F << 17) | OPC_MSA_2RF,
1311 
1312     /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1313     OPC_SLL_df      = (0x0 << 23) | OPC_MSA_3R_0D,
1314     OPC_ADDV_df     = (0x0 << 23) | OPC_MSA_3R_0E,
1315     OPC_CEQ_df      = (0x0 << 23) | OPC_MSA_3R_0F,
1316     OPC_ADD_A_df    = (0x0 << 23) | OPC_MSA_3R_10,
1317     OPC_SUBS_S_df   = (0x0 << 23) | OPC_MSA_3R_11,
1318     OPC_MULV_df     = (0x0 << 23) | OPC_MSA_3R_12,
1319     OPC_DOTP_S_df   = (0x0 << 23) | OPC_MSA_3R_13,
1320     OPC_SLD_df      = (0x0 << 23) | OPC_MSA_3R_14,
1321     OPC_VSHF_df     = (0x0 << 23) | OPC_MSA_3R_15,
1322     OPC_SRA_df      = (0x1 << 23) | OPC_MSA_3R_0D,
1323     OPC_SUBV_df     = (0x1 << 23) | OPC_MSA_3R_0E,
1324     OPC_ADDS_A_df   = (0x1 << 23) | OPC_MSA_3R_10,
1325     OPC_SUBS_U_df   = (0x1 << 23) | OPC_MSA_3R_11,
1326     OPC_MADDV_df    = (0x1 << 23) | OPC_MSA_3R_12,
1327     OPC_DOTP_U_df   = (0x1 << 23) | OPC_MSA_3R_13,
1328     OPC_SPLAT_df    = (0x1 << 23) | OPC_MSA_3R_14,
1329     OPC_SRAR_df     = (0x1 << 23) | OPC_MSA_3R_15,
1330     OPC_SRL_df      = (0x2 << 23) | OPC_MSA_3R_0D,
1331     OPC_MAX_S_df    = (0x2 << 23) | OPC_MSA_3R_0E,
1332     OPC_CLT_S_df    = (0x2 << 23) | OPC_MSA_3R_0F,
1333     OPC_ADDS_S_df   = (0x2 << 23) | OPC_MSA_3R_10,
1334     OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1335     OPC_MSUBV_df    = (0x2 << 23) | OPC_MSA_3R_12,
1336     OPC_DPADD_S_df  = (0x2 << 23) | OPC_MSA_3R_13,
1337     OPC_PCKEV_df    = (0x2 << 23) | OPC_MSA_3R_14,
1338     OPC_SRLR_df     = (0x2 << 23) | OPC_MSA_3R_15,
1339     OPC_BCLR_df     = (0x3 << 23) | OPC_MSA_3R_0D,
1340     OPC_MAX_U_df    = (0x3 << 23) | OPC_MSA_3R_0E,
1341     OPC_CLT_U_df    = (0x3 << 23) | OPC_MSA_3R_0F,
1342     OPC_ADDS_U_df   = (0x3 << 23) | OPC_MSA_3R_10,
1343     OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1344     OPC_DPADD_U_df  = (0x3 << 23) | OPC_MSA_3R_13,
1345     OPC_PCKOD_df    = (0x3 << 23) | OPC_MSA_3R_14,
1346     OPC_BSET_df     = (0x4 << 23) | OPC_MSA_3R_0D,
1347     OPC_MIN_S_df    = (0x4 << 23) | OPC_MSA_3R_0E,
1348     OPC_CLE_S_df    = (0x4 << 23) | OPC_MSA_3R_0F,
1349     OPC_AVE_S_df    = (0x4 << 23) | OPC_MSA_3R_10,
1350     OPC_ASUB_S_df   = (0x4 << 23) | OPC_MSA_3R_11,
1351     OPC_DIV_S_df    = (0x4 << 23) | OPC_MSA_3R_12,
1352     OPC_DPSUB_S_df  = (0x4 << 23) | OPC_MSA_3R_13,
1353     OPC_ILVL_df     = (0x4 << 23) | OPC_MSA_3R_14,
1354     OPC_HADD_S_df   = (0x4 << 23) | OPC_MSA_3R_15,
1355     OPC_BNEG_df     = (0x5 << 23) | OPC_MSA_3R_0D,
1356     OPC_MIN_U_df    = (0x5 << 23) | OPC_MSA_3R_0E,
1357     OPC_CLE_U_df    = (0x5 << 23) | OPC_MSA_3R_0F,
1358     OPC_AVE_U_df    = (0x5 << 23) | OPC_MSA_3R_10,
1359     OPC_ASUB_U_df   = (0x5 << 23) | OPC_MSA_3R_11,
1360     OPC_DIV_U_df    = (0x5 << 23) | OPC_MSA_3R_12,
1361     OPC_DPSUB_U_df  = (0x5 << 23) | OPC_MSA_3R_13,
1362     OPC_ILVR_df     = (0x5 << 23) | OPC_MSA_3R_14,
1363     OPC_HADD_U_df   = (0x5 << 23) | OPC_MSA_3R_15,
1364     OPC_BINSL_df    = (0x6 << 23) | OPC_MSA_3R_0D,
1365     OPC_MAX_A_df    = (0x6 << 23) | OPC_MSA_3R_0E,
1366     OPC_AVER_S_df   = (0x6 << 23) | OPC_MSA_3R_10,
1367     OPC_MOD_S_df    = (0x6 << 23) | OPC_MSA_3R_12,
1368     OPC_ILVEV_df    = (0x6 << 23) | OPC_MSA_3R_14,
1369     OPC_HSUB_S_df   = (0x6 << 23) | OPC_MSA_3R_15,
1370     OPC_BINSR_df    = (0x7 << 23) | OPC_MSA_3R_0D,
1371     OPC_MIN_A_df    = (0x7 << 23) | OPC_MSA_3R_0E,
1372     OPC_AVER_U_df   = (0x7 << 23) | OPC_MSA_3R_10,
1373     OPC_MOD_U_df    = (0x7 << 23) | OPC_MSA_3R_12,
1374     OPC_ILVOD_df    = (0x7 << 23) | OPC_MSA_3R_14,
1375     OPC_HSUB_U_df   = (0x7 << 23) | OPC_MSA_3R_15,
1376 
1377     /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1378     OPC_SLDI_df     = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1379     OPC_CTCMSA      = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1380     OPC_SPLATI_df   = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1381     OPC_CFCMSA      = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1382     OPC_COPY_S_df   = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1383     OPC_MOVE_V      = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1384     OPC_COPY_U_df   = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1385     OPC_INSERT_df   = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1386     OPC_INSVE_df    = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1387 
1388     /* 3RF instruction _df(bit 21) = _w, _d */
1389     OPC_FCAF_df     = (0x0 << 22) | OPC_MSA_3RF_1A,
1390     OPC_FADD_df     = (0x0 << 22) | OPC_MSA_3RF_1B,
1391     OPC_FCUN_df     = (0x1 << 22) | OPC_MSA_3RF_1A,
1392     OPC_FSUB_df     = (0x1 << 22) | OPC_MSA_3RF_1B,
1393     OPC_FCOR_df     = (0x1 << 22) | OPC_MSA_3RF_1C,
1394     OPC_FCEQ_df     = (0x2 << 22) | OPC_MSA_3RF_1A,
1395     OPC_FMUL_df     = (0x2 << 22) | OPC_MSA_3RF_1B,
1396     OPC_FCUNE_df    = (0x2 << 22) | OPC_MSA_3RF_1C,
1397     OPC_FCUEQ_df    = (0x3 << 22) | OPC_MSA_3RF_1A,
1398     OPC_FDIV_df     = (0x3 << 22) | OPC_MSA_3RF_1B,
1399     OPC_FCNE_df     = (0x3 << 22) | OPC_MSA_3RF_1C,
1400     OPC_FCLT_df     = (0x4 << 22) | OPC_MSA_3RF_1A,
1401     OPC_FMADD_df    = (0x4 << 22) | OPC_MSA_3RF_1B,
1402     OPC_MUL_Q_df    = (0x4 << 22) | OPC_MSA_3RF_1C,
1403     OPC_FCULT_df    = (0x5 << 22) | OPC_MSA_3RF_1A,
1404     OPC_FMSUB_df    = (0x5 << 22) | OPC_MSA_3RF_1B,
1405     OPC_MADD_Q_df   = (0x5 << 22) | OPC_MSA_3RF_1C,
1406     OPC_FCLE_df     = (0x6 << 22) | OPC_MSA_3RF_1A,
1407     OPC_MSUB_Q_df   = (0x6 << 22) | OPC_MSA_3RF_1C,
1408     OPC_FCULE_df    = (0x7 << 22) | OPC_MSA_3RF_1A,
1409     OPC_FEXP2_df    = (0x7 << 22) | OPC_MSA_3RF_1B,
1410     OPC_FSAF_df     = (0x8 << 22) | OPC_MSA_3RF_1A,
1411     OPC_FEXDO_df    = (0x8 << 22) | OPC_MSA_3RF_1B,
1412     OPC_FSUN_df     = (0x9 << 22) | OPC_MSA_3RF_1A,
1413     OPC_FSOR_df     = (0x9 << 22) | OPC_MSA_3RF_1C,
1414     OPC_FSEQ_df     = (0xA << 22) | OPC_MSA_3RF_1A,
1415     OPC_FTQ_df      = (0xA << 22) | OPC_MSA_3RF_1B,
1416     OPC_FSUNE_df    = (0xA << 22) | OPC_MSA_3RF_1C,
1417     OPC_FSUEQ_df    = (0xB << 22) | OPC_MSA_3RF_1A,
1418     OPC_FSNE_df     = (0xB << 22) | OPC_MSA_3RF_1C,
1419     OPC_FSLT_df     = (0xC << 22) | OPC_MSA_3RF_1A,
1420     OPC_FMIN_df     = (0xC << 22) | OPC_MSA_3RF_1B,
1421     OPC_MULR_Q_df   = (0xC << 22) | OPC_MSA_3RF_1C,
1422     OPC_FSULT_df    = (0xD << 22) | OPC_MSA_3RF_1A,
1423     OPC_FMIN_A_df   = (0xD << 22) | OPC_MSA_3RF_1B,
1424     OPC_MADDR_Q_df  = (0xD << 22) | OPC_MSA_3RF_1C,
1425     OPC_FSLE_df     = (0xE << 22) | OPC_MSA_3RF_1A,
1426     OPC_FMAX_df     = (0xE << 22) | OPC_MSA_3RF_1B,
1427     OPC_MSUBR_Q_df  = (0xE << 22) | OPC_MSA_3RF_1C,
1428     OPC_FSULE_df    = (0xF << 22) | OPC_MSA_3RF_1A,
1429     OPC_FMAX_A_df   = (0xF << 22) | OPC_MSA_3RF_1B,
1430 
1431     /* BIT instruction df(bits 22..16) = _B _H _W _D */
1432     OPC_SLLI_df     = (0x0 << 23) | OPC_MSA_BIT_09,
1433     OPC_SAT_S_df    = (0x0 << 23) | OPC_MSA_BIT_0A,
1434     OPC_SRAI_df     = (0x1 << 23) | OPC_MSA_BIT_09,
1435     OPC_SAT_U_df    = (0x1 << 23) | OPC_MSA_BIT_0A,
1436     OPC_SRLI_df     = (0x2 << 23) | OPC_MSA_BIT_09,
1437     OPC_SRARI_df    = (0x2 << 23) | OPC_MSA_BIT_0A,
1438     OPC_BCLRI_df    = (0x3 << 23) | OPC_MSA_BIT_09,
1439     OPC_SRLRI_df    = (0x3 << 23) | OPC_MSA_BIT_0A,
1440     OPC_BSETI_df    = (0x4 << 23) | OPC_MSA_BIT_09,
1441     OPC_BNEGI_df    = (0x5 << 23) | OPC_MSA_BIT_09,
1442     OPC_BINSLI_df   = (0x6 << 23) | OPC_MSA_BIT_09,
1443     OPC_BINSRI_df   = (0x7 << 23) | OPC_MSA_BIT_09,
1444 };
1445 
1446 
1447 /*
1448  *
1449  *       AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
1450  *       ============================================
1451  *
1452  *
1453  * MXU (full name: MIPS eXtension/enhanced Unit) is a SIMD extension of MIPS32
1454  * instructions set. It is designed to fit the needs of signal, graphical and
1455  * video processing applications. MXU instruction set is used in Xburst family
1456  * of microprocessors by Ingenic.
1457  *
1458  * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X16 is
1459  * the control register.
1460  *
1461  *
1462  *     The notation used in MXU assembler mnemonics
1463  *     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1464  *
1465  *  Register operands:
1466  *
1467  *   XRa, XRb, XRc, XRd - MXU registers
1468  *   Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
1469  *
1470  *  Non-register operands:
1471  *
1472  *   aptn1 - 1-bit accumulate add/subtract pattern
1473  *   aptn2 - 2-bit accumulate add/subtract pattern
1474  *   eptn2 - 2-bit execute add/subtract pattern
1475  *   optn2 - 2-bit operand pattern
1476  *   optn3 - 3-bit operand pattern
1477  *   sft4  - 4-bit shift amount
1478  *   strd2 - 2-bit stride amount
1479  *
1480  *  Prefixes:
1481  *
1482  *   Level of parallelism:                Operand size:
1483  *    S - single operation at a time       32 - word
1484  *    D - two operations in parallel       16 - half word
1485  *    Q - four operations in parallel       8 - byte
1486  *
1487  *  Operations:
1488  *
1489  *   ADD   - Add or subtract
1490  *   ADDC  - Add with carry-in
1491  *   ACC   - Accumulate
1492  *   ASUM  - Sum together then accumulate (add or subtract)
1493  *   ASUMC - Sum together then accumulate (add or subtract) with carry-in
1494  *   AVG   - Average between 2 operands
1495  *   ABD   - Absolute difference
1496  *   ALN   - Align data
1497  *   AND   - Logical bitwise 'and' operation
1498  *   CPS   - Copy sign
1499  *   EXTR  - Extract bits
1500  *   I2M   - Move from GPR register to MXU register
1501  *   LDD   - Load data from memory to XRF
1502  *   LDI   - Load data from memory to XRF (and increase the address base)
1503  *   LUI   - Load unsigned immediate
1504  *   MUL   - Multiply
1505  *   MULU  - Unsigned multiply
1506  *   MADD  - 64-bit operand add 32x32 product
1507  *   MSUB  - 64-bit operand subtract 32x32 product
1508  *   MAC   - Multiply and accumulate (add or subtract)
1509  *   MAD   - Multiply and add or subtract
1510  *   MAX   - Maximum between 2 operands
1511  *   MIN   - Minimum between 2 operands
1512  *   M2I   - Move from MXU register to GPR register
1513  *   MOVZ  - Move if zero
1514  *   MOVN  - Move if non-zero
1515  *   NOR   - Logical bitwise 'nor' operation
1516  *   OR    - Logical bitwise 'or' operation
1517  *   STD   - Store data from XRF to memory
1518  *   SDI   - Store data from XRF to memory (and increase the address base)
1519  *   SLT   - Set of less than comparison
1520  *   SAD   - Sum of absolute differences
1521  *   SLL   - Logical shift left
1522  *   SLR   - Logical shift right
1523  *   SAR   - Arithmetic shift right
1524  *   SAT   - Saturation
1525  *   SFL   - Shuffle
1526  *   SCOP  - Calculate x’s scope (-1, means x<0; 0, means x==0; 1, means x>0)
1527  *   XOR   - Logical bitwise 'exclusive or' operation
1528  *
1529  *  Suffixes:
1530  *
1531  *   E - Expand results
1532  *   F - Fixed point multiplication
1533  *   L - Low part result
1534  *   R - Doing rounding
1535  *   V - Variable instead of immediate
1536  *   W - Combine above L and V
1537  *
1538  *
1539  *     The list of MXU instructions grouped by functionality
1540  *     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1541  *
1542  * Load/Store instructions           Multiplication instructions
1543  * -----------------------           ---------------------------
1544  *
1545  *  S32LDD XRa, Rb, s12               S32MADD XRa, XRd, Rs, Rt
1546  *  S32STD XRa, Rb, s12               S32MADDU XRa, XRd, Rs, Rt
1547  *  S32LDDV XRa, Rb, rc, strd2        S32MSUB XRa, XRd, Rs, Rt
1548  *  S32STDV XRa, Rb, rc, strd2        S32MSUBU XRa, XRd, Rs, Rt
1549  *  S32LDI XRa, Rb, s12               S32MUL XRa, XRd, Rs, Rt
1550  *  S32SDI XRa, Rb, s12               S32MULU XRa, XRd, Rs, Rt
1551  *  S32LDIV XRa, Rb, rc, strd2        D16MUL XRa, XRb, XRc, XRd, optn2
1552  *  S32SDIV XRa, Rb, rc, strd2        D16MULE XRa, XRb, XRc, optn2
1553  *  S32LDDR XRa, Rb, s12              D16MULF XRa, XRb, XRc, optn2
1554  *  S32STDR XRa, Rb, s12              D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
1555  *  S32LDDVR XRa, Rb, rc, strd2       D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
1556  *  S32STDVR XRa, Rb, rc, strd2       D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
1557  *  S32LDIR XRa, Rb, s12              D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
1558  *  S32SDIR XRa, Rb, s12              S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
1559  *  S32LDIVR XRa, Rb, rc, strd2       Q8MUL XRa, XRb, XRc, XRd
1560  *  S32SDIVR XRa, Rb, rc, strd2       Q8MULSU XRa, XRb, XRc, XRd
1561  *  S16LDD XRa, Rb, s10, eptn2        Q8MAC XRa, XRb, XRc, XRd, aptn2
1562  *  S16STD XRa, Rb, s10, eptn2        Q8MACSU XRa, XRb, XRc, XRd, aptn2
1563  *  S16LDI XRa, Rb, s10, eptn2        Q8MADL XRa, XRb, XRc, XRd, aptn2
1564  *  S16SDI XRa, Rb, s10, eptn2
1565  *  S8LDD XRa, Rb, s8, eptn3
1566  *  S8STD XRa, Rb, s8, eptn3         Addition and subtraction instructions
1567  *  S8LDI XRa, Rb, s8, eptn3         -------------------------------------
1568  *  S8SDI XRa, Rb, s8, eptn3
1569  *  LXW Rd, Rs, Rt, strd2             D32ADD XRa, XRb, XRc, XRd, eptn2
1570  *  LXH Rd, Rs, Rt, strd2             D32ADDC XRa, XRb, XRc, XRd
1571  *  LXHU Rd, Rs, Rt, strd2            D32ACC XRa, XRb, XRc, XRd, eptn2
1572  *  LXB Rd, Rs, Rt, strd2             D32ACCM XRa, XRb, XRc, XRd, eptn2
1573  *  LXBU Rd, Rs, Rt, strd2            D32ASUM XRa, XRb, XRc, XRd, eptn2
1574  *                                    S32CPS XRa, XRb, XRc
1575  *                                    Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
1576  * Comparison instructions            Q16ACC XRa, XRb, XRc, XRd, eptn2
1577  * -----------------------            Q16ACCM XRa, XRb, XRc, XRd, eptn2
1578  *                                    D16ASUM XRa, XRb, XRc, XRd, eptn2
1579  *  S32MAX XRa, XRb, XRc              D16CPS XRa, XRb,
1580  *  S32MIN XRa, XRb, XRc              D16AVG XRa, XRb, XRc
1581  *  S32SLT XRa, XRb, XRc              D16AVGR XRa, XRb, XRc
1582  *  S32MOVZ XRa, XRb, XRc             Q8ADD XRa, XRb, XRc, eptn2
1583  *  S32MOVN XRa, XRb, XRc             Q8ADDE XRa, XRb, XRc, XRd, eptn2
1584  *  D16MAX XRa, XRb, XRc              Q8ACCE XRa, XRb, XRc, XRd, eptn2
1585  *  D16MIN XRa, XRb, XRc              Q8ABD XRa, XRb, XRc
1586  *  D16SLT XRa, XRb, XRc              Q8SAD XRa, XRb, XRc, XRd
1587  *  D16MOVZ XRa, XRb, XRc             Q8AVG XRa, XRb, XRc
1588  *  D16MOVN XRa, XRb, XRc             Q8AVGR XRa, XRb, XRc
1589  *  Q8MAX XRa, XRb, XRc               D8SUM XRa, XRb, XRc, XRd
1590  *  Q8MIN XRa, XRb, XRc               D8SUMC XRa, XRb, XRc, XRd
1591  *  Q8SLT XRa, XRb, XRc
1592  *  Q8SLTU XRa, XRb, XRc
1593  *  Q8MOVZ XRa, XRb, XRc             Shift instructions
1594  *  Q8MOVN XRa, XRb, XRc             ------------------
1595  *
1596  *                                    D32SLL XRa, XRb, XRc, XRd, sft4
1597  * Bitwise instructions               D32SLR XRa, XRb, XRc, XRd, sft4
1598  * --------------------               D32SAR XRa, XRb, XRc, XRd, sft4
1599  *                                    D32SARL XRa, XRb, XRc, sft4
1600  *  S32NOR XRa, XRb, XRc              D32SLLV XRa, XRb, Rb
1601  *  S32AND XRa, XRb, XRc              D32SLRV XRa, XRb, Rb
1602  *  S32XOR XRa, XRb, XRc              D32SARV XRa, XRb, Rb
1603  *  S32OR XRa, XRb, XRc               D32SARW XRa, XRb, XRc, Rb
1604  *                                    Q16SLL XRa, XRb, XRc, XRd, sft4
1605  *                                    Q16SLR XRa, XRb, XRc, XRd, sft4
1606  * Miscellaneous instructions         Q16SAR XRa, XRb, XRc, XRd, sft4
1607  * -------------------------          Q16SLLV XRa, XRb, Rb
1608  *                                    Q16SLRV XRa, XRb, Rb
1609  *  S32SFL XRa, XRb, XRc, XRd, optn2  Q16SARV XRa, XRb, Rb
1610  *  S32ALN XRa, XRb, XRc, Rb
1611  *  S32ALNI XRa, XRb, XRc, s3
1612  *  S32LUI XRa, s8, optn3            Move instructions
1613  *  S32EXTR XRa, XRb, Rb, bits5      -----------------
1614  *  S32EXTRV XRa, XRb, Rs, Rt
1615  *  Q16SCOP XRa, XRb, XRc, XRd        S32M2I XRa, Rb
1616  *  Q16SAT XRa, XRb, XRc              S32I2M XRa, Rb
1617  *
1618  *
1619  *     The opcode organization of MXU instructions
1620  *     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1621  *
1622  * The bits 31..26 of all MXU instructions are equal to 0x1C (also referred
1623  * as opcode SPECIAL2 in the base MIPS ISA). The organization and meaning of
1624  * other bits up to the instruction level is as follows:
1625  *
1626  *              bits
1627  *             05..00
1628  *
1629  *          ┌─ 000000 ─ OPC_MXU_S32MADD
1630  *          ├─ 000001 ─ OPC_MXU_S32MADDU
1631  *          ├─ 000010 ─ <not assigned>   (non-MXU OPC_MUL)
1632  *          │
1633  *          │                               20..18
1634  *          ├─ 000011 ─ OPC_MXU__POOL00 ─┬─ 000 ─ OPC_MXU_S32MAX
1635  *          │                            ├─ 001 ─ OPC_MXU_S32MIN
1636  *          │                            ├─ 010 ─ OPC_MXU_D16MAX
1637  *          │                            ├─ 011 ─ OPC_MXU_D16MIN
1638  *          │                            ├─ 100 ─ OPC_MXU_Q8MAX
1639  *          │                            ├─ 101 ─ OPC_MXU_Q8MIN
1640  *          │                            ├─ 110 ─ OPC_MXU_Q8SLT
1641  *          │                            └─ 111 ─ OPC_MXU_Q8SLTU
1642  *          ├─ 000100 ─ OPC_MXU_S32MSUB
1643  *          ├─ 000101 ─ OPC_MXU_S32MSUBU    20..18
1644  *          ├─ 000110 ─ OPC_MXU__POOL01 ─┬─ 000 ─ OPC_MXU_S32SLT
1645  *          │                            ├─ 001 ─ OPC_MXU_D16SLT
1646  *          │                            ├─ 010 ─ OPC_MXU_D16AVG
1647  *          │                            ├─ 011 ─ OPC_MXU_D16AVGR
1648  *          │                            ├─ 100 ─ OPC_MXU_Q8AVG
1649  *          │                            ├─ 101 ─ OPC_MXU_Q8AVGR
1650  *          │                            └─ 111 ─ OPC_MXU_Q8ADD
1651  *          │
1652  *          │                               20..18
1653  *          ├─ 000111 ─ OPC_MXU__POOL02 ─┬─ 000 ─ OPC_MXU_S32CPS
1654  *          │                            ├─ 010 ─ OPC_MXU_D16CPS
1655  *          │                            ├─ 100 ─ OPC_MXU_Q8ABD
1656  *          │                            └─ 110 ─ OPC_MXU_Q16SAT
1657  *          ├─ 001000 ─ OPC_MXU_D16MUL
1658  *          │                               25..24
1659  *          ├─ 001001 ─ OPC_MXU__POOL03 ─┬─ 00 ─ OPC_MXU_D16MULF
1660  *          │                            └─ 01 ─ OPC_MXU_D16MULE
1661  *          ├─ 001010 ─ OPC_MXU_D16MAC
1662  *          ├─ 001011 ─ OPC_MXU_D16MACF
1663  *          ├─ 001100 ─ OPC_MXU_D16MADL
1664  *          ├─ 001101 ─ OPC_MXU_S16MAD
1665  *          ├─ 001110 ─ OPC_MXU_Q16ADD
1666  *          ├─ 001111 ─ OPC_MXU_D16MACE     23
1667  *          │                            ┌─ 0 ─ OPC_MXU_S32LDD
1668  *          ├─ 010000 ─ OPC_MXU__POOL04 ─┴─ 1 ─ OPC_MXU_S32LDDR
1669  *          │
1670  *          │                               23
1671  *          ├─ 010001 ─ OPC_MXU__POOL05 ─┬─ 0 ─ OPC_MXU_S32STD
1672  *          │                            └─ 1 ─ OPC_MXU_S32STDR
1673  *          │
1674  *          │                               13..10
1675  *          ├─ 010010 ─ OPC_MXU__POOL06 ─┬─ 0000 ─ OPC_MXU_S32LDDV
1676  *          │                            └─ 0001 ─ OPC_MXU_S32LDDVR
1677  *          │
1678  *          │                               13..10
1679  *          ├─ 010011 ─ OPC_MXU__POOL07 ─┬─ 0000 ─ OPC_MXU_S32STDV
1680  *          │                            └─ 0001 ─ OPC_MXU_S32STDVR
1681  *          │
1682  *          │                               23
1683  *          ├─ 010100 ─ OPC_MXU__POOL08 ─┬─ 0 ─ OPC_MXU_S32LDI
1684  *          │                            └─ 1 ─ OPC_MXU_S32LDIR
1685  *          │
1686  *          │                               23
1687  *          ├─ 010101 ─ OPC_MXU__POOL09 ─┬─ 0 ─ OPC_MXU_S32SDI
1688  *          │                            └─ 1 ─ OPC_MXU_S32SDIR
1689  *          │
1690  *          │                               13..10
1691  *          ├─ 010110 ─ OPC_MXU__POOL10 ─┬─ 0000 ─ OPC_MXU_S32LDIV
1692  *          │                            └─ 0001 ─ OPC_MXU_S32LDIVR
1693  *          │
1694  *          │                               13..10
1695  *          ├─ 010111 ─ OPC_MXU__POOL11 ─┬─ 0000 ─ OPC_MXU_S32SDIV
1696  *          │                            └─ 0001 ─ OPC_MXU_S32SDIVR
1697  *          ├─ 011000 ─ OPC_MXU_D32ADD
1698  *          │                               23..22
1699  *   MXU    ├─ 011001 ─ OPC_MXU__POOL12 ─┬─ 00 ─ OPC_MXU_D32ACC
1700  * opcodes ─┤                            ├─ 01 ─ OPC_MXU_D32ACCM
1701  *          │                            └─ 10 ─ OPC_MXU_D32ASUM
1702  *          ├─ 011010 ─ <not assigned>
1703  *          │                               23..22
1704  *          ├─ 011011 ─ OPC_MXU__POOL13 ─┬─ 00 ─ OPC_MXU_Q16ACC
1705  *          │                            ├─ 01 ─ OPC_MXU_Q16ACCM
1706  *          │                            └─ 10 ─ OPC_MXU_Q16ASUM
1707  *          │
1708  *          │                               23..22
1709  *          ├─ 011100 ─ OPC_MXU__POOL14 ─┬─ 00 ─ OPC_MXU_Q8ADDE
1710  *          │                            ├─ 01 ─ OPC_MXU_D8SUM
1711  *          ├─ 011101 ─ OPC_MXU_Q8ACCE   └─ 10 ─ OPC_MXU_D8SUMC
1712  *          ├─ 011110 ─ <not assigned>
1713  *          ├─ 011111 ─ <not assigned>
1714  *          ├─ 100000 ─ <not assigned>   (overlaps with CLZ)
1715  *          ├─ 100001 ─ <not assigned>   (overlaps with CLO)
1716  *          ├─ 100010 ─ OPC_MXU_S8LDD
1717  *          ├─ 100011 ─ OPC_MXU_S8STD       15..14
1718  *          ├─ 100100 ─ OPC_MXU_S8LDI    ┌─ 00 ─ OPC_MXU_S32MUL
1719  *          ├─ 100101 ─ OPC_MXU_S8SDI    ├─ 00 ─ OPC_MXU_S32MULU
1720  *          │                            ├─ 00 ─ OPC_MXU_S32EXTR
1721  *          ├─ 100110 ─ OPC_MXU__POOL15 ─┴─ 00 ─ OPC_MXU_S32EXTRV
1722  *          │
1723  *          │                               20..18
1724  *          ├─ 100111 ─ OPC_MXU__POOL16 ─┬─ 000 ─ OPC_MXU_D32SARW
1725  *          │                            ├─ 001 ─ OPC_MXU_S32ALN
1726  *          │                            ├─ 010 ─ OPC_MXU_S32ALNI
1727  *          │                            ├─ 011 ─ OPC_MXU_S32LUI
1728  *          │                            ├─ 100 ─ OPC_MXU_S32NOR
1729  *          │                            ├─ 101 ─ OPC_MXU_S32AND
1730  *          │                            ├─ 110 ─ OPC_MXU_S32OR
1731  *          │                            └─ 111 ─ OPC_MXU_S32XOR
1732  *          │
1733  *          │                               7..5
1734  *          ├─ 101000 ─ OPC_MXU__POOL17 ─┬─ 000 ─ OPC_MXU_LXB
1735  *          │                            ├─ 001 ─ OPC_MXU_LXH
1736  *          ├─ 101001 ─ <not assigned>   ├─ 011 ─ OPC_MXU_LXW
1737  *          ├─ 101010 ─ OPC_MXU_S16LDD   ├─ 100 ─ OPC_MXU_LXBU
1738  *          ├─ 101011 ─ OPC_MXU_S16STD   └─ 101 ─ OPC_MXU_LXHU
1739  *          ├─ 101100 ─ OPC_MXU_S16LDI
1740  *          ├─ 101101 ─ OPC_MXU_S16SDI
1741  *          ├─ 101110 ─ OPC_MXU_S32M2I
1742  *          ├─ 101111 ─ OPC_MXU_S32I2M
1743  *          ├─ 110000 ─ OPC_MXU_D32SLL
1744  *          ├─ 110001 ─ OPC_MXU_D32SLR      20..18
1745  *          ├─ 110010 ─ OPC_MXU_D32SARL  ┌─ 000 ─ OPC_MXU_D32SLLV
1746  *          ├─ 110011 ─ OPC_MXU_D32SAR   ├─ 001 ─ OPC_MXU_D32SLRV
1747  *          ├─ 110100 ─ OPC_MXU_Q16SLL   ├─ 010 ─ OPC_MXU_D32SARV
1748  *          ├─ 110101 ─ OPC_MXU_Q16SLR   ├─ 011 ─ OPC_MXU_Q16SLLV
1749  *          │                            ├─ 100 ─ OPC_MXU_Q16SLRV
1750  *          ├─ 110110 ─ OPC_MXU__POOL18 ─┴─ 101 ─ OPC_MXU_Q16SARV
1751  *          │
1752  *          ├─ 110111 ─ OPC_MXU_Q16SAR
1753  *          │                               23..22
1754  *          ├─ 111000 ─ OPC_MXU__POOL19 ─┬─ 00 ─ OPC_MXU_Q8MUL
1755  *          │                            └─ 01 ─ OPC_MXU_Q8MULSU
1756  *          │
1757  *          │                               20..18
1758  *          ├─ 111001 ─ OPC_MXU__POOL20 ─┬─ 000 ─ OPC_MXU_Q8MOVZ
1759  *          │                            ├─ 001 ─ OPC_MXU_Q8MOVN
1760  *          │                            ├─ 010 ─ OPC_MXU_D16MOVZ
1761  *          │                            ├─ 011 ─ OPC_MXU_D16MOVN
1762  *          │                            ├─ 100 ─ OPC_MXU_S32MOVZ
1763  *          │                            └─ 101 ─ OPC_MXU_S32MOVN
1764  *          │
1765  *          │                               23..22
1766  *          ├─ 111010 ─ OPC_MXU__POOL21 ─┬─ 00 ─ OPC_MXU_Q8MAC
1767  *          │                            └─ 10 ─ OPC_MXU_Q8MACSU
1768  *          ├─ 111011 ─ OPC_MXU_Q16SCOP
1769  *          ├─ 111100 ─ OPC_MXU_Q8MADL
1770  *          ├─ 111101 ─ OPC_MXU_S32SFL
1771  *          ├─ 111110 ─ OPC_MXU_Q8SAD
1772  *          └─ 111111 ─ <not assigned>   (overlaps with SDBBP)
1773  *
1774  *
1775  * Compiled after:
1776  *
1777  *   "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
1778  *   Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2, 2017
1779  */
1780 
1781 enum {
1782     OPC_MXU_S32MADD  = 0x00,
1783     OPC_MXU_S32MADDU = 0x01,
1784     OPC__MXU_MUL     = 0x02,
1785     OPC_MXU__POOL00  = 0x03,
1786     OPC_MXU_S32MSUB  = 0x04,
1787     OPC_MXU_S32MSUBU = 0x05,
1788     OPC_MXU__POOL01  = 0x06,
1789     OPC_MXU__POOL02  = 0x07,
1790     OPC_MXU_D16MUL   = 0x08,
1791     OPC_MXU__POOL03  = 0x09,
1792     OPC_MXU_D16MAC   = 0x0A,
1793     OPC_MXU_D16MACF  = 0x0B,
1794     OPC_MXU_D16MADL  = 0x0C,
1795     OPC_MXU_S16MAD   = 0x0D,
1796     OPC_MXU_Q16ADD   = 0x0E,
1797     OPC_MXU_D16MACE  = 0x0F,
1798     OPC_MXU__POOL04  = 0x10,
1799     OPC_MXU__POOL05  = 0x11,
1800     OPC_MXU__POOL06  = 0x12,
1801     OPC_MXU__POOL07  = 0x13,
1802     OPC_MXU__POOL08  = 0x14,
1803     OPC_MXU__POOL09  = 0x15,
1804     OPC_MXU__POOL10  = 0x16,
1805     OPC_MXU__POOL11  = 0x17,
1806     OPC_MXU_D32ADD   = 0x18,
1807     OPC_MXU__POOL12  = 0x19,
1808     /* not assigned 0x1A */
1809     OPC_MXU__POOL13  = 0x1B,
1810     OPC_MXU__POOL14  = 0x1C,
1811     OPC_MXU_Q8ACCE   = 0x1D,
1812     /* not assigned 0x1E */
1813     /* not assigned 0x1F */
1814     /* not assigned 0x20 */
1815     /* not assigned 0x21 */
1816     OPC_MXU_S8LDD    = 0x22,
1817     OPC_MXU_S8STD    = 0x23,
1818     OPC_MXU_S8LDI    = 0x24,
1819     OPC_MXU_S8SDI    = 0x25,
1820     OPC_MXU__POOL15  = 0x26,
1821     OPC_MXU__POOL16  = 0x27,
1822     OPC_MXU__POOL17  = 0x28,
1823     /* not assigned 0x29 */
1824     OPC_MXU_S16LDD   = 0x2A,
1825     OPC_MXU_S16STD   = 0x2B,
1826     OPC_MXU_S16LDI   = 0x2C,
1827     OPC_MXU_S16SDI   = 0x2D,
1828     OPC_MXU_S32M2I   = 0x2E,
1829     OPC_MXU_S32I2M   = 0x2F,
1830     OPC_MXU_D32SLL   = 0x30,
1831     OPC_MXU_D32SLR   = 0x31,
1832     OPC_MXU_D32SARL  = 0x32,
1833     OPC_MXU_D32SAR   = 0x33,
1834     OPC_MXU_Q16SLL   = 0x34,
1835     OPC_MXU_Q16SLR   = 0x35,
1836     OPC_MXU__POOL18  = 0x36,
1837     OPC_MXU_Q16SAR   = 0x37,
1838     OPC_MXU__POOL19  = 0x38,
1839     OPC_MXU__POOL20  = 0x39,
1840     OPC_MXU__POOL21  = 0x3A,
1841     OPC_MXU_Q16SCOP  = 0x3B,
1842     OPC_MXU_Q8MADL   = 0x3C,
1843     OPC_MXU_S32SFL   = 0x3D,
1844     OPC_MXU_Q8SAD    = 0x3E,
1845     /* not assigned 0x3F */
1846 };
1847 
1848 
1849 /*
1850  * MXU pool 00
1851  */
1852 enum {
1853     OPC_MXU_S32MAX   = 0x00,
1854     OPC_MXU_S32MIN   = 0x01,
1855     OPC_MXU_D16MAX   = 0x02,
1856     OPC_MXU_D16MIN   = 0x03,
1857     OPC_MXU_Q8MAX    = 0x04,
1858     OPC_MXU_Q8MIN    = 0x05,
1859     OPC_MXU_Q8SLT    = 0x06,
1860     OPC_MXU_Q8SLTU   = 0x07,
1861 };
1862 
1863 /*
1864  * MXU pool 01
1865  */
1866 enum {
1867     OPC_MXU_S32SLT   = 0x00,
1868     OPC_MXU_D16SLT   = 0x01,
1869     OPC_MXU_D16AVG   = 0x02,
1870     OPC_MXU_D16AVGR  = 0x03,
1871     OPC_MXU_Q8AVG    = 0x04,
1872     OPC_MXU_Q8AVGR   = 0x05,
1873     OPC_MXU_Q8ADD    = 0x07,
1874 };
1875 
1876 /*
1877  * MXU pool 02
1878  */
1879 enum {
1880     OPC_MXU_S32CPS   = 0x00,
1881     OPC_MXU_D16CPS   = 0x02,
1882     OPC_MXU_Q8ABD    = 0x04,
1883     OPC_MXU_Q16SAT   = 0x06,
1884 };
1885 
1886 /*
1887  * MXU pool 03
1888  */
1889 enum {
1890     OPC_MXU_D16MULF  = 0x00,
1891     OPC_MXU_D16MULE  = 0x01,
1892 };
1893 
1894 /*
1895  * MXU pool 04
1896  */
1897 enum {
1898     OPC_MXU_S32LDD   = 0x00,
1899     OPC_MXU_S32LDDR  = 0x01,
1900 };
1901 
1902 /*
1903  * MXU pool 05
1904  */
1905 enum {
1906     OPC_MXU_S32STD   = 0x00,
1907     OPC_MXU_S32STDR  = 0x01,
1908 };
1909 
1910 /*
1911  * MXU pool 06
1912  */
1913 enum {
1914     OPC_MXU_S32LDDV  = 0x00,
1915     OPC_MXU_S32LDDVR = 0x01,
1916 };
1917 
1918 /*
1919  * MXU pool 07
1920  */
1921 enum {
1922     OPC_MXU_S32STDV  = 0x00,
1923     OPC_MXU_S32STDVR = 0x01,
1924 };
1925 
1926 /*
1927  * MXU pool 08
1928  */
1929 enum {
1930     OPC_MXU_S32LDI   = 0x00,
1931     OPC_MXU_S32LDIR  = 0x01,
1932 };
1933 
1934 /*
1935  * MXU pool 09
1936  */
1937 enum {
1938     OPC_MXU_S32SDI   = 0x00,
1939     OPC_MXU_S32SDIR  = 0x01,
1940 };
1941 
1942 /*
1943  * MXU pool 10
1944  */
1945 enum {
1946     OPC_MXU_S32LDIV  = 0x00,
1947     OPC_MXU_S32LDIVR = 0x01,
1948 };
1949 
1950 /*
1951  * MXU pool 11
1952  */
1953 enum {
1954     OPC_MXU_S32SDIV  = 0x00,
1955     OPC_MXU_S32SDIVR = 0x01,
1956 };
1957 
1958 /*
1959  * MXU pool 12
1960  */
1961 enum {
1962     OPC_MXU_D32ACC   = 0x00,
1963     OPC_MXU_D32ACCM  = 0x01,
1964     OPC_MXU_D32ASUM  = 0x02,
1965 };
1966 
1967 /*
1968  * MXU pool 13
1969  */
1970 enum {
1971     OPC_MXU_Q16ACC   = 0x00,
1972     OPC_MXU_Q16ACCM  = 0x01,
1973     OPC_MXU_Q16ASUM  = 0x02,
1974 };
1975 
1976 /*
1977  * MXU pool 14
1978  */
1979 enum {
1980     OPC_MXU_Q8ADDE   = 0x00,
1981     OPC_MXU_D8SUM    = 0x01,
1982     OPC_MXU_D8SUMC   = 0x02,
1983 };
1984 
1985 /*
1986  * MXU pool 15
1987  */
1988 enum {
1989     OPC_MXU_S32MUL   = 0x00,
1990     OPC_MXU_S32MULU  = 0x01,
1991     OPC_MXU_S32EXTR  = 0x02,
1992     OPC_MXU_S32EXTRV = 0x03,
1993 };
1994 
1995 /*
1996  * MXU pool 16
1997  */
1998 enum {
1999     OPC_MXU_D32SARW  = 0x00,
2000     OPC_MXU_S32ALN   = 0x01,
2001     OPC_MXU_S32ALNI  = 0x02,
2002     OPC_MXU_S32LUI   = 0x03,
2003     OPC_MXU_S32NOR   = 0x04,
2004     OPC_MXU_S32AND   = 0x05,
2005     OPC_MXU_S32OR    = 0x06,
2006     OPC_MXU_S32XOR   = 0x07,
2007 };
2008 
2009 /*
2010  * MXU pool 17
2011  */
2012 enum {
2013     OPC_MXU_LXB      = 0x00,
2014     OPC_MXU_LXH      = 0x01,
2015     OPC_MXU_LXW      = 0x03,
2016     OPC_MXU_LXBU     = 0x04,
2017     OPC_MXU_LXHU     = 0x05,
2018 };
2019 
2020 /*
2021  * MXU pool 18
2022  */
2023 enum {
2024     OPC_MXU_D32SLLV  = 0x00,
2025     OPC_MXU_D32SLRV  = 0x01,
2026     OPC_MXU_D32SARV  = 0x03,
2027     OPC_MXU_Q16SLLV  = 0x04,
2028     OPC_MXU_Q16SLRV  = 0x05,
2029     OPC_MXU_Q16SARV  = 0x07,
2030 };
2031 
2032 /*
2033  * MXU pool 19
2034  */
2035 enum {
2036     OPC_MXU_Q8MUL    = 0x00,
2037     OPC_MXU_Q8MULSU  = 0x01,
2038 };
2039 
2040 /*
2041  * MXU pool 20
2042  */
2043 enum {
2044     OPC_MXU_Q8MOVZ   = 0x00,
2045     OPC_MXU_Q8MOVN   = 0x01,
2046     OPC_MXU_D16MOVZ  = 0x02,
2047     OPC_MXU_D16MOVN  = 0x03,
2048     OPC_MXU_S32MOVZ  = 0x04,
2049     OPC_MXU_S32MOVN  = 0x05,
2050 };
2051 
2052 /*
2053  * MXU pool 21
2054  */
2055 enum {
2056     OPC_MXU_Q8MAC    = 0x00,
2057     OPC_MXU_Q8MACSU  = 0x01,
2058 };
2059 
2060 /*
2061  *     Overview of the TX79-specific instruction set
2062  *     =============================================
2063  *
2064  * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits
2065  * are only used by the specific quadword (128-bit) LQ/SQ load/store
2066  * instructions and certain multimedia instructions (MMIs). These MMIs
2067  * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
2068  * or sixteen 8-bit paths.
2069  *
2070  * Reference:
2071  *
2072  * The Toshiba TX System RISC TX79 Core Architecture manual,
2073  * https://wiki.qemu.org/File:C790.pdf
2074  *
2075  *     Three-Operand Multiply and Multiply-Add (4 instructions)
2076  *     --------------------------------------------------------
2077  * MADD    [rd,] rs, rt      Multiply/Add
2078  * MADDU   [rd,] rs, rt      Multiply/Add Unsigned
2079  * MULT    [rd,] rs, rt      Multiply (3-operand)
2080  * MULTU   [rd,] rs, rt      Multiply Unsigned (3-operand)
2081  *
2082  *     Multiply Instructions for Pipeline 1 (10 instructions)
2083  *     ------------------------------------------------------
2084  * MULT1   [rd,] rs, rt      Multiply Pipeline 1
2085  * MULTU1  [rd,] rs, rt      Multiply Unsigned Pipeline 1
2086  * DIV1    rs, rt            Divide Pipeline 1
2087  * DIVU1   rs, rt            Divide Unsigned Pipeline 1
2088  * MADD1   [rd,] rs, rt      Multiply-Add Pipeline 1
2089  * MADDU1  [rd,] rs, rt      Multiply-Add Unsigned Pipeline 1
2090  * MFHI1   rd                Move From HI1 Register
2091  * MFLO1   rd                Move From LO1 Register
2092  * MTHI1   rs                Move To HI1 Register
2093  * MTLO1   rs                Move To LO1 Register
2094  *
2095  *     Arithmetic (19 instructions)
2096  *     ----------------------------
2097  * PADDB   rd, rs, rt        Parallel Add Byte
2098  * PSUBB   rd, rs, rt        Parallel Subtract Byte
2099  * PADDH   rd, rs, rt        Parallel Add Halfword
2100  * PSUBH   rd, rs, rt        Parallel Subtract Halfword
2101  * PADDW   rd, rs, rt        Parallel Add Word
2102  * PSUBW   rd, rs, rt        Parallel Subtract Word
2103  * PADSBH  rd, rs, rt        Parallel Add/Subtract Halfword
2104  * PADDSB  rd, rs, rt        Parallel Add with Signed Saturation Byte
2105  * PSUBSB  rd, rs, rt        Parallel Subtract with Signed Saturation Byte
2106  * PADDSH  rd, rs, rt        Parallel Add with Signed Saturation Halfword
2107  * PSUBSH  rd, rs, rt        Parallel Subtract with Signed Saturation Halfword
2108  * PADDSW  rd, rs, rt        Parallel Add with Signed Saturation Word
2109  * PSUBSW  rd, rs, rt        Parallel Subtract with Signed Saturation Word
2110  * PADDUB  rd, rs, rt        Parallel Add with Unsigned saturation Byte
2111  * PSUBUB  rd, rs, rt        Parallel Subtract with Unsigned saturation Byte
2112  * PADDUH  rd, rs, rt        Parallel Add with Unsigned saturation Halfword
2113  * PSUBUH  rd, rs, rt        Parallel Subtract with Unsigned saturation Halfword
2114  * PADDUW  rd, rs, rt        Parallel Add with Unsigned saturation Word
2115  * PSUBUW  rd, rs, rt        Parallel Subtract with Unsigned saturation Word
2116  *
2117  *     Min/Max (4 instructions)
2118  *     ------------------------
2119  * PMAXH   rd, rs, rt        Parallel Maximum Halfword
2120  * PMINH   rd, rs, rt        Parallel Minimum Halfword
2121  * PMAXW   rd, rs, rt        Parallel Maximum Word
2122  * PMINW   rd, rs, rt        Parallel Minimum Word
2123  *
2124  *     Absolute (2 instructions)
2125  *     -------------------------
2126  * PABSH   rd, rt            Parallel Absolute Halfword
2127  * PABSW   rd, rt            Parallel Absolute Word
2128  *
2129  *     Logical (4 instructions)
2130  *     ------------------------
2131  * PAND    rd, rs, rt        Parallel AND
2132  * POR     rd, rs, rt        Parallel OR
2133  * PXOR    rd, rs, rt        Parallel XOR
2134  * PNOR    rd, rs, rt        Parallel NOR
2135  *
2136  *     Shift (9 instructions)
2137  *     ----------------------
2138  * PSLLH   rd, rt, sa        Parallel Shift Left Logical Halfword
2139  * PSRLH   rd, rt, sa        Parallel Shift Right Logical Halfword
2140  * PSRAH   rd, rt, sa        Parallel Shift Right Arithmetic Halfword
2141  * PSLLW   rd, rt, sa        Parallel Shift Left Logical Word
2142  * PSRLW   rd, rt, sa        Parallel Shift Right Logical Word
2143  * PSRAW   rd, rt, sa        Parallel Shift Right Arithmetic Word
2144  * PSLLVW  rd, rt, rs        Parallel Shift Left Logical Variable Word
2145  * PSRLVW  rd, rt, rs        Parallel Shift Right Logical Variable Word
2146  * PSRAVW  rd, rt, rs        Parallel Shift Right Arithmetic Variable Word
2147  *
2148  *     Compare (6 instructions)
2149  *     ------------------------
2150  * PCGTB   rd, rs, rt        Parallel Compare for Greater Than Byte
2151  * PCEQB   rd, rs, rt        Parallel Compare for Equal Byte
2152  * PCGTH   rd, rs, rt        Parallel Compare for Greater Than Halfword
2153  * PCEQH   rd, rs, rt        Parallel Compare for Equal Halfword
2154  * PCGTW   rd, rs, rt        Parallel Compare for Greater Than Word
2155  * PCEQW   rd, rs, rt        Parallel Compare for Equal Word
2156  *
2157  *     LZC (1 instruction)
2158  *     -------------------
2159  * PLZCW   rd, rs            Parallel Leading Zero or One Count Word
2160  *
2161  *     Quadword Load and Store (2 instructions)
2162  *     ----------------------------------------
2163  * LQ      rt, offset(base)  Load Quadword
2164  * SQ      rt, offset(base)  Store Quadword
2165  *
2166  *     Multiply and Divide (19 instructions)
2167  *     -------------------------------------
2168  * PMULTW  rd, rs, rt        Parallel Multiply Word
2169  * PMULTUW rd, rs, rt        Parallel Multiply Unsigned Word
2170  * PDIVW   rs, rt            Parallel Divide Word
2171  * PDIVUW  rs, rt            Parallel Divide Unsigned Word
2172  * PMADDW  rd, rs, rt        Parallel Multiply-Add Word
2173  * PMADDUW rd, rs, rt        Parallel Multiply-Add Unsigned Word
2174  * PMSUBW  rd, rs, rt        Parallel Multiply-Subtract Word
2175  * PMULTH  rd, rs, rt        Parallel Multiply Halfword
2176  * PMADDH  rd, rs, rt        Parallel Multiply-Add Halfword
2177  * PMSUBH  rd, rs, rt        Parallel Multiply-Subtract Halfword
2178  * PHMADH  rd, rs, rt        Parallel Horizontal Multiply-Add Halfword
2179  * PHMSBH  rd, rs, rt        Parallel Horizontal Multiply-Subtract Halfword
2180  * PDIVBW  rs, rt            Parallel Divide Broadcast Word
2181  * PMFHI   rd                Parallel Move From HI Register
2182  * PMFLO   rd                Parallel Move From LO Register
2183  * PMTHI   rs                Parallel Move To HI Register
2184  * PMTLO   rs                Parallel Move To LO Register
2185  * PMFHL   rd                Parallel Move From HI/LO Register
2186  * PMTHL   rs                Parallel Move To HI/LO Register
2187  *
2188  *     Pack/Extend (11 instructions)
2189  *     -----------------------------
2190  * PPAC5   rd, rt            Parallel Pack to 5 bits
2191  * PPACB   rd, rs, rt        Parallel Pack to Byte
2192  * PPACH   rd, rs, rt        Parallel Pack to Halfword
2193  * PPACW   rd, rs, rt        Parallel Pack to Word
2194  * PEXT5   rd, rt            Parallel Extend Upper from 5 bits
2195  * PEXTUB  rd, rs, rt        Parallel Extend Upper from Byte
2196  * PEXTLB  rd, rs, rt        Parallel Extend Lower from Byte
2197  * PEXTUH  rd, rs, rt        Parallel Extend Upper from Halfword
2198  * PEXTLH  rd, rs, rt        Parallel Extend Lower from Halfword
2199  * PEXTUW  rd, rs, rt        Parallel Extend Upper from Word
2200  * PEXTLW  rd, rs, rt        Parallel Extend Lower from Word
2201  *
2202  *     Others (16 instructions)
2203  *     ------------------------
2204  * PCPYH   rd, rt            Parallel Copy Halfword
2205  * PCPYLD  rd, rs, rt        Parallel Copy Lower Doubleword
2206  * PCPYUD  rd, rs, rt        Parallel Copy Upper Doubleword
2207  * PREVH   rd, rt            Parallel Reverse Halfword
2208  * PINTH   rd, rs, rt        Parallel Interleave Halfword
2209  * PINTEH  rd, rs, rt        Parallel Interleave Even Halfword
2210  * PEXEH   rd, rt            Parallel Exchange Even Halfword
2211  * PEXCH   rd, rt            Parallel Exchange Center Halfword
2212  * PEXEW   rd, rt            Parallel Exchange Even Word
2213  * PEXCW   rd, rt            Parallel Exchange Center Word
2214  * QFSRV   rd, rs, rt        Quadword Funnel Shift Right Variable
2215  * MFSA    rd                Move from Shift Amount Register
2216  * MTSA    rs                Move to Shift Amount Register
2217  * MTSAB   rs, immediate     Move Byte Count to Shift Amount Register
2218  * MTSAH   rs, immediate     Move Halfword Count to Shift Amount Register
2219  * PROT3W  rd, rt            Parallel Rotate 3 Words
2220  *
2221  *     MMI (MultiMedia Instruction) encodings
2222  *     ======================================
2223  *
2224  * MMI instructions encoding table keys:
2225  *
2226  *     *   This code is reserved for future use. An attempt to execute it
2227  *         causes a Reserved Instruction exception.
2228  *     %   This code indicates an instruction class. The instruction word
2229  *         must be further decoded by examining additional tables that show
2230  *         the values for other instruction fields.
2231  *     #   This code is reserved for the unsupported instructions DMULT,
2232  *         DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
2233  *         to execute it causes a Reserved Instruction exception.
2234  *
2235  * MMI instructions encoded by opcode field (MMI, LQ, SQ):
2236  *
2237  *  31    26                                        0
2238  * +--------+----------------------------------------+
2239  * | opcode |                                        |
2240  * +--------+----------------------------------------+
2241  *
2242  *   opcode  bits 28..26
2243  *     bits |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7
2244  *   31..29 |  000  |  001  |  010  |  011  |  100  |  101  |  110  |  111
2245  *   -------+-------+-------+-------+-------+-------+-------+-------+-------
2246  *    0 000 |SPECIAL| REGIMM|   J   |  JAL  |  BEQ  |  BNE  |  BLEZ |  BGTZ
2247  *    1 001 |  ADDI | ADDIU |  SLTI | SLTIU |  ANDI |  ORI  |  XORI |  LUI
2248  *    2 010 |  COP0 |  COP1 |   *   |   *   |  BEQL |  BNEL | BLEZL | BGTZL
2249  *    3 011 | DADDI | DADDIU|  LDL  |  LDR  |  MMI% |   *   |   LQ  |   SQ
2250  *    4 100 |   LB  |   LH  |  LWL  |   LW  |  LBU  |  LHU  |  LWR  |  LWU
2251  *    5 101 |   SB  |   SH  |  SWL  |   SW  |  SDL  |  SDR  |  SWR  | CACHE
2252  *    6 110 |   #   |  LWC1 |   #   |  PREF |   #   |  LDC1 |   #   |   LD
2253  *    7 111 |   #   |  SWC1 |   #   |   *   |   #   |  SDC1 |   #   |   SD
2254  */
2255 
2256 enum {
2257     MMI_OPC_CLASS_MMI = 0x1C << 26,    /* Same as OPC_SPECIAL2 */
2258     MMI_OPC_LQ        = 0x1E << 26,    /* Same as OPC_MSA */
2259     MMI_OPC_SQ        = 0x1F << 26,    /* Same as OPC_SPECIAL3 */
2260 };
2261 
2262 /*
2263  * MMI instructions with opcode field = MMI:
2264  *
2265  *  31    26                                 5      0
2266  * +--------+-------------------------------+--------+
2267  * |   MMI  |                               |function|
2268  * +--------+-------------------------------+--------+
2269  *
2270  * function  bits 2..0
2271  *     bits |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7
2272  *     5..3 |  000  |  001  |  010  |  011  |  100  |  101  |  110  |  111
2273  *   -------+-------+-------+-------+-------+-------+-------+-------+-------
2274  *    0 000 |  MADD | MADDU |   *   |   *   | PLZCW |   *   |   *   |   *
2275  *    1 001 | MMI0% | MMI2% |   *   |   *   |   *   |   *   |   *   |   *
2276  *    2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 |   *   |   *   |   *   |   *
2277  *    3 011 | MULT1 | MULTU1|  DIV1 | DIVU1 |   *   |   *   |   *   |   *
2278  *    4 100 | MADD1 | MADDU1|   *   |   *   |   *   |   *   |   *   |   *
2279  *    5 101 | MMI1% | MMI3% |   *   |   *   |   *   |   *   |   *   |   *
2280  *    6 110 | PMFHL | PMTHL |   *   |   *   | PSLLH |   *   | PSRLH | PSRAH
2281  *    7 111 |   *   |   *   |   *   |   *   | PSLLW |   *   | PSRLW | PSRAW
2282  */
2283 
2284 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
2285 enum {
2286     MMI_OPC_MADD       = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */
2287     MMI_OPC_MADDU      = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */
2288     MMI_OPC_PLZCW      = 0x04 | MMI_OPC_CLASS_MMI,
2289     MMI_OPC_CLASS_MMI0 = 0x08 | MMI_OPC_CLASS_MMI,
2290     MMI_OPC_CLASS_MMI2 = 0x09 | MMI_OPC_CLASS_MMI,
2291     MMI_OPC_MFHI1      = 0x10 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MFHI */
2292     MMI_OPC_MTHI1      = 0x11 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MTHI */
2293     MMI_OPC_MFLO1      = 0x12 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MFLO */
2294     MMI_OPC_MTLO1      = 0x13 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MTLO */
2295     MMI_OPC_MULT1      = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */
2296     MMI_OPC_MULTU1     = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */
2297     MMI_OPC_DIV1       = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV  */
2298     MMI_OPC_DIVU1      = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */
2299     MMI_OPC_MADD1      = 0x20 | MMI_OPC_CLASS_MMI,
2300     MMI_OPC_MADDU1     = 0x21 | MMI_OPC_CLASS_MMI,
2301     MMI_OPC_CLASS_MMI1 = 0x28 | MMI_OPC_CLASS_MMI,
2302     MMI_OPC_CLASS_MMI3 = 0x29 | MMI_OPC_CLASS_MMI,
2303     MMI_OPC_PMFHL      = 0x30 | MMI_OPC_CLASS_MMI,
2304     MMI_OPC_PMTHL      = 0x31 | MMI_OPC_CLASS_MMI,
2305     MMI_OPC_PSLLH      = 0x34 | MMI_OPC_CLASS_MMI,
2306     MMI_OPC_PSRLH      = 0x36 | MMI_OPC_CLASS_MMI,
2307     MMI_OPC_PSRAH      = 0x37 | MMI_OPC_CLASS_MMI,
2308     MMI_OPC_PSLLW      = 0x3C | MMI_OPC_CLASS_MMI,
2309     MMI_OPC_PSRLW      = 0x3E | MMI_OPC_CLASS_MMI,
2310     MMI_OPC_PSRAW      = 0x3F | MMI_OPC_CLASS_MMI,
2311 };
2312 
2313 /*
2314  * MMI instructions with opcode field = MMI and bits 5..0 = MMI0:
2315  *
2316  *  31    26                        10     6 5      0
2317  * +--------+----------------------+--------+--------+
2318  * |   MMI  |                      |function|  MMI0  |
2319  * +--------+----------------------+--------+--------+
2320  *
2321  * function  bits 7..6
2322  *     bits |   0   |   1   |   2   |   3
2323  *    10..8 |   00  |   01  |   10  |   11
2324  *   -------+-------+-------+-------+-------
2325  *    0 000 | PADDW | PSUBW | PCGTW | PMAXW
2326  *    1 001 | PADDH | PSUBH | PCGTH | PMAXH
2327  *    2 010 | PADDB | PSUBB | PCGTB |   *
2328  *    3 011 |   *   |   *   |   *   |   *
2329  *    4 100 | PADDSW| PSUBSW| PEXTLW| PPACW
2330  *    5 101 | PADDSH| PSUBSH| PEXTLH| PPACH
2331  *    6 110 | PADDSB| PSUBSB| PEXTLB| PPACB
2332  *    7 111 |   *   |   *   | PEXT5 | PPAC5
2333  */
2334 
2335 #define MASK_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2336 enum {
2337     MMI_OPC_0_PADDW  = (0x00 << 6) | MMI_OPC_CLASS_MMI0,
2338     MMI_OPC_0_PSUBW  = (0x01 << 6) | MMI_OPC_CLASS_MMI0,
2339     MMI_OPC_0_PCGTW  = (0x02 << 6) | MMI_OPC_CLASS_MMI0,
2340     MMI_OPC_0_PMAXW  = (0x03 << 6) | MMI_OPC_CLASS_MMI0,
2341     MMI_OPC_0_PADDH  = (0x04 << 6) | MMI_OPC_CLASS_MMI0,
2342     MMI_OPC_0_PSUBH  = (0x05 << 6) | MMI_OPC_CLASS_MMI0,
2343     MMI_OPC_0_PCGTH  = (0x06 << 6) | MMI_OPC_CLASS_MMI0,
2344     MMI_OPC_0_PMAXH  = (0x07 << 6) | MMI_OPC_CLASS_MMI0,
2345     MMI_OPC_0_PADDB  = (0x08 << 6) | MMI_OPC_CLASS_MMI0,
2346     MMI_OPC_0_PSUBB  = (0x09 << 6) | MMI_OPC_CLASS_MMI0,
2347     MMI_OPC_0_PCGTB  = (0x0A << 6) | MMI_OPC_CLASS_MMI0,
2348     MMI_OPC_0_PADDSW = (0x10 << 6) | MMI_OPC_CLASS_MMI0,
2349     MMI_OPC_0_PSUBSW = (0x11 << 6) | MMI_OPC_CLASS_MMI0,
2350     MMI_OPC_0_PEXTLW = (0x12 << 6) | MMI_OPC_CLASS_MMI0,
2351     MMI_OPC_0_PPACW  = (0x13 << 6) | MMI_OPC_CLASS_MMI0,
2352     MMI_OPC_0_PADDSH = (0x14 << 6) | MMI_OPC_CLASS_MMI0,
2353     MMI_OPC_0_PSUBSH = (0x15 << 6) | MMI_OPC_CLASS_MMI0,
2354     MMI_OPC_0_PEXTLH = (0x16 << 6) | MMI_OPC_CLASS_MMI0,
2355     MMI_OPC_0_PPACH  = (0x17 << 6) | MMI_OPC_CLASS_MMI0,
2356     MMI_OPC_0_PADDSB = (0x18 << 6) | MMI_OPC_CLASS_MMI0,
2357     MMI_OPC_0_PSUBSB = (0x19 << 6) | MMI_OPC_CLASS_MMI0,
2358     MMI_OPC_0_PEXTLB = (0x1A << 6) | MMI_OPC_CLASS_MMI0,
2359     MMI_OPC_0_PPACB  = (0x1B << 6) | MMI_OPC_CLASS_MMI0,
2360     MMI_OPC_0_PEXT5  = (0x1E << 6) | MMI_OPC_CLASS_MMI0,
2361     MMI_OPC_0_PPAC5  = (0x1F << 6) | MMI_OPC_CLASS_MMI0,
2362 };
2363 
2364 /*
2365  * MMI instructions with opcode field = MMI and bits 5..0 = MMI1:
2366  *
2367  *  31    26                        10     6 5      0
2368  * +--------+----------------------+--------+--------+
2369  * |   MMI  |                      |function|  MMI1  |
2370  * +--------+----------------------+--------+--------+
2371  *
2372  * function  bits 7..6
2373  *     bits |   0   |   1   |   2   |   3
2374  *    10..8 |   00  |   01  |   10  |   11
2375  *   -------+-------+-------+-------+-------
2376  *    0 000 |   *   | PABSW | PCEQW | PMINW
2377  *    1 001 | PADSBH| PABSH | PCEQH | PMINH
2378  *    2 010 |   *   |   *   | PCEQB |   *
2379  *    3 011 |   *   |   *   |   *   |   *
2380  *    4 100 | PADDUW| PSUBUW| PEXTUW|   *
2381  *    5 101 | PADDUH| PSUBUH| PEXTUH|   *
2382  *    6 110 | PADDUB| PSUBUB| PEXTUB| QFSRV
2383  *    7 111 |   *   |   *   |   *   |   *
2384  */
2385 
2386 #define MASK_MMI1(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2387 enum {
2388     MMI_OPC_1_PABSW  = (0x01 << 6) | MMI_OPC_CLASS_MMI1,
2389     MMI_OPC_1_PCEQW  = (0x02 << 6) | MMI_OPC_CLASS_MMI1,
2390     MMI_OPC_1_PMINW  = (0x03 << 6) | MMI_OPC_CLASS_MMI1,
2391     MMI_OPC_1_PADSBH = (0x04 << 6) | MMI_OPC_CLASS_MMI1,
2392     MMI_OPC_1_PABSH  = (0x05 << 6) | MMI_OPC_CLASS_MMI1,
2393     MMI_OPC_1_PCEQH  = (0x06 << 6) | MMI_OPC_CLASS_MMI1,
2394     MMI_OPC_1_PMINH  = (0x07 << 6) | MMI_OPC_CLASS_MMI1,
2395     MMI_OPC_1_PCEQB  = (0x0A << 6) | MMI_OPC_CLASS_MMI1,
2396     MMI_OPC_1_PADDUW = (0x10 << 6) | MMI_OPC_CLASS_MMI1,
2397     MMI_OPC_1_PSUBUW = (0x11 << 6) | MMI_OPC_CLASS_MMI1,
2398     MMI_OPC_1_PEXTUW = (0x12 << 6) | MMI_OPC_CLASS_MMI1,
2399     MMI_OPC_1_PADDUH = (0x14 << 6) | MMI_OPC_CLASS_MMI1,
2400     MMI_OPC_1_PSUBUH = (0x15 << 6) | MMI_OPC_CLASS_MMI1,
2401     MMI_OPC_1_PEXTUH = (0x16 << 6) | MMI_OPC_CLASS_MMI1,
2402     MMI_OPC_1_PADDUB = (0x18 << 6) | MMI_OPC_CLASS_MMI1,
2403     MMI_OPC_1_PSUBUB = (0x19 << 6) | MMI_OPC_CLASS_MMI1,
2404     MMI_OPC_1_PEXTUB = (0x1A << 6) | MMI_OPC_CLASS_MMI1,
2405     MMI_OPC_1_QFSRV  = (0x1B << 6) | MMI_OPC_CLASS_MMI1,
2406 };
2407 
2408 /*
2409  * MMI instructions with opcode field = MMI and bits 5..0 = MMI2:
2410  *
2411  *  31    26                        10     6 5      0
2412  * +--------+----------------------+--------+--------+
2413  * |   MMI  |                      |function|  MMI2  |
2414  * +--------+----------------------+--------+--------+
2415  *
2416  * function  bits 7..6
2417  *     bits |   0   |   1   |   2   |   3
2418  *    10..8 |   00  |   01  |   10  |   11
2419  *   -------+-------+-------+-------+-------
2420  *    0 000 | PMADDW|   *   | PSLLVW| PSRLVW
2421  *    1 001 | PMSUBW|   *   |   *   |   *
2422  *    2 010 | PMFHI | PMFLO | PINTH |   *
2423  *    3 011 | PMULTW| PDIVW | PCPYLD|   *
2424  *    4 100 | PMADDH| PHMADH|  PAND |  PXOR
2425  *    5 101 | PMSUBH| PHMSBH|   *   |   *
2426  *    6 110 |   *   |   *   | PEXEH | PREVH
2427  *    7 111 | PMULTH| PDIVBW| PEXEW | PROT3W
2428  */
2429 
2430 #define MASK_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2431 enum {
2432     MMI_OPC_2_PMADDW = (0x00 << 6) | MMI_OPC_CLASS_MMI2,
2433     MMI_OPC_2_PSLLVW = (0x02 << 6) | MMI_OPC_CLASS_MMI2,
2434     MMI_OPC_2_PSRLVW = (0x03 << 6) | MMI_OPC_CLASS_MMI2,
2435     MMI_OPC_2_PMSUBW = (0x04 << 6) | MMI_OPC_CLASS_MMI2,
2436     MMI_OPC_2_PMFHI  = (0x08 << 6) | MMI_OPC_CLASS_MMI2,
2437     MMI_OPC_2_PMFLO  = (0x09 << 6) | MMI_OPC_CLASS_MMI2,
2438     MMI_OPC_2_PINTH  = (0x0A << 6) | MMI_OPC_CLASS_MMI2,
2439     MMI_OPC_2_PMULTW = (0x0C << 6) | MMI_OPC_CLASS_MMI2,
2440     MMI_OPC_2_PDIVW  = (0x0D << 6) | MMI_OPC_CLASS_MMI2,
2441     MMI_OPC_2_PCPYLD = (0x0E << 6) | MMI_OPC_CLASS_MMI2,
2442     MMI_OPC_2_PMADDH = (0x10 << 6) | MMI_OPC_CLASS_MMI2,
2443     MMI_OPC_2_PHMADH = (0x11 << 6) | MMI_OPC_CLASS_MMI2,
2444     MMI_OPC_2_PAND   = (0x12 << 6) | MMI_OPC_CLASS_MMI2,
2445     MMI_OPC_2_PXOR   = (0x13 << 6) | MMI_OPC_CLASS_MMI2,
2446     MMI_OPC_2_PMSUBH = (0x14 << 6) | MMI_OPC_CLASS_MMI2,
2447     MMI_OPC_2_PHMSBH = (0x15 << 6) | MMI_OPC_CLASS_MMI2,
2448     MMI_OPC_2_PEXEH  = (0x1A << 6) | MMI_OPC_CLASS_MMI2,
2449     MMI_OPC_2_PREVH  = (0x1B << 6) | MMI_OPC_CLASS_MMI2,
2450     MMI_OPC_2_PMULTH = (0x1C << 6) | MMI_OPC_CLASS_MMI2,
2451     MMI_OPC_2_PDIVBW = (0x1D << 6) | MMI_OPC_CLASS_MMI2,
2452     MMI_OPC_2_PEXEW  = (0x1E << 6) | MMI_OPC_CLASS_MMI2,
2453     MMI_OPC_2_PROT3W = (0x1F << 6) | MMI_OPC_CLASS_MMI2,
2454 };
2455 
2456 /*
2457  * MMI instructions with opcode field = MMI and bits 5..0 = MMI3:
2458  *
2459  *  31    26                        10     6 5      0
2460  * +--------+----------------------+--------+--------+
2461  * |   MMI  |                      |function|  MMI3  |
2462  * +--------+----------------------+--------+--------+
2463  *
2464  * function  bits 7..6
2465  *     bits |   0   |   1   |   2   |   3
2466  *    10..8 |   00  |   01  |   10  |   11
2467  *   -------+-------+-------+-------+-------
2468  *    0 000 |PMADDUW|   *   |   *   | PSRAVW
2469  *    1 001 |   *   |   *   |   *   |   *
2470  *    2 010 | PMTHI | PMTLO | PINTEH|   *
2471  *    3 011 |PMULTUW| PDIVUW| PCPYUD|   *
2472  *    4 100 |   *   |   *   |  POR  |  PNOR
2473  *    5 101 |   *   |   *   |   *   |   *
2474  *    6 110 |   *   |   *   | PEXCH | PCPYH
2475  *    7 111 |   *   |   *   | PEXCW |   *
2476  */
2477 
2478 #define MASK_MMI3(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2479 enum {
2480     MMI_OPC_3_PMADDUW = (0x00 << 6) | MMI_OPC_CLASS_MMI3,
2481     MMI_OPC_3_PSRAVW  = (0x03 << 6) | MMI_OPC_CLASS_MMI3,
2482     MMI_OPC_3_PMTHI   = (0x08 << 6) | MMI_OPC_CLASS_MMI3,
2483     MMI_OPC_3_PMTLO   = (0x09 << 6) | MMI_OPC_CLASS_MMI3,
2484     MMI_OPC_3_PINTEH  = (0x0A << 6) | MMI_OPC_CLASS_MMI3,
2485     MMI_OPC_3_PMULTUW = (0x0C << 6) | MMI_OPC_CLASS_MMI3,
2486     MMI_OPC_3_PDIVUW  = (0x0D << 6) | MMI_OPC_CLASS_MMI3,
2487     MMI_OPC_3_PCPYUD  = (0x0E << 6) | MMI_OPC_CLASS_MMI3,
2488     MMI_OPC_3_POR     = (0x12 << 6) | MMI_OPC_CLASS_MMI3,
2489     MMI_OPC_3_PNOR    = (0x13 << 6) | MMI_OPC_CLASS_MMI3,
2490     MMI_OPC_3_PEXCH   = (0x1A << 6) | MMI_OPC_CLASS_MMI3,
2491     MMI_OPC_3_PCPYH   = (0x1B << 6) | MMI_OPC_CLASS_MMI3,
2492     MMI_OPC_3_PEXCW   = (0x1E << 6) | MMI_OPC_CLASS_MMI3,
2493 };
2494 
2495 /* global register indices */
2496 static TCGv cpu_gpr[32], cpu_PC;
2497 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
2498 static TCGv cpu_dspctrl, btarget, bcond;
2499 static TCGv cpu_lladdr, cpu_llval;
2500 static TCGv_i32 hflags;
2501 static TCGv_i32 fpu_fcr0, fpu_fcr31;
2502 static TCGv_i64 fpu_f64[32];
2503 static TCGv_i64 msa_wr_d[64];
2504 
2505 #if defined(TARGET_MIPS64)
2506 /* Upper halves of R5900's 128-bit registers: MMRs (multimedia registers) */
2507 static TCGv_i64 cpu_mmr[32];
2508 #endif
2509 
2510 #if !defined(TARGET_MIPS64)
2511 /* MXU registers */
2512 static TCGv mxu_gpr[NUMBER_OF_MXU_REGISTERS - 1];
2513 static TCGv mxu_CR;
2514 #endif
2515 
2516 #include "exec/gen-icount.h"
2517 
2518 #define gen_helper_0e0i(name, arg) do {                           \
2519     TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
2520     gen_helper_##name(cpu_env, helper_tmp);                       \
2521     tcg_temp_free_i32(helper_tmp);                                \
2522     } while (0)
2523 
2524 #define gen_helper_0e1i(name, arg1, arg2) do {                    \
2525     TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
2526     gen_helper_##name(cpu_env, arg1, helper_tmp);                 \
2527     tcg_temp_free_i32(helper_tmp);                                \
2528     } while (0)
2529 
2530 #define gen_helper_1e0i(name, ret, arg1) do {                     \
2531     TCGv_i32 helper_tmp = tcg_const_i32(arg1);                    \
2532     gen_helper_##name(ret, cpu_env, helper_tmp);                  \
2533     tcg_temp_free_i32(helper_tmp);                                \
2534     } while (0)
2535 
2536 #define gen_helper_1e1i(name, ret, arg1, arg2) do {               \
2537     TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
2538     gen_helper_##name(ret, cpu_env, arg1, helper_tmp);            \
2539     tcg_temp_free_i32(helper_tmp);                                \
2540     } while (0)
2541 
2542 #define gen_helper_0e2i(name, arg1, arg2, arg3) do {              \
2543     TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
2544     gen_helper_##name(cpu_env, arg1, arg2, helper_tmp);           \
2545     tcg_temp_free_i32(helper_tmp);                                \
2546     } while (0)
2547 
2548 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do {         \
2549     TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
2550     gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp);      \
2551     tcg_temp_free_i32(helper_tmp);                                \
2552     } while (0)
2553 
2554 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do {        \
2555     TCGv_i32 helper_tmp = tcg_const_i32(arg4);                    \
2556     gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp);     \
2557     tcg_temp_free_i32(helper_tmp);                                \
2558     } while (0)
2559 
2560 typedef struct DisasContext {
2561     DisasContextBase base;
2562     target_ulong saved_pc;
2563     target_ulong page_start;
2564     uint32_t opcode;
2565     uint64_t insn_flags;
2566     int32_t CP0_Config1;
2567     int32_t CP0_Config2;
2568     int32_t CP0_Config3;
2569     int32_t CP0_Config5;
2570     /* Routine used to access memory */
2571     int mem_idx;
2572     MemOp default_tcg_memop_mask;
2573     uint32_t hflags, saved_hflags;
2574     target_ulong btarget;
2575     bool ulri;
2576     int kscrexist;
2577     bool rxi;
2578     int ie;
2579     bool bi;
2580     bool bp;
2581     uint64_t PAMask;
2582     bool mvh;
2583     bool eva;
2584     bool sc;
2585     int CP0_LLAddr_shift;
2586     bool ps;
2587     bool vp;
2588     bool cmgcr;
2589     bool mrp;
2590     bool nan2008;
2591     bool abs2008;
2592     bool saar;
2593     bool mi;
2594     int gi;
2595 } DisasContext;
2596 
2597 #define DISAS_STOP       DISAS_TARGET_0
2598 #define DISAS_EXIT       DISAS_TARGET_1
2599 
2600 static const char * const regnames[] = {
2601     "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2602     "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2603     "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2604     "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2605 };
2606 
2607 static const char * const regnames_HI[] = {
2608     "HI0", "HI1", "HI2", "HI3",
2609 };
2610 
2611 static const char * const regnames_LO[] = {
2612     "LO0", "LO1", "LO2", "LO3",
2613 };
2614 
2615 static const char * const fregnames[] = {
2616     "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
2617     "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
2618     "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2619     "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2620 };
2621 
2622 static const char * const msaregnames[] = {
2623     "w0.d0",  "w0.d1",  "w1.d0",  "w1.d1",
2624     "w2.d0",  "w2.d1",  "w3.d0",  "w3.d1",
2625     "w4.d0",  "w4.d1",  "w5.d0",  "w5.d1",
2626     "w6.d0",  "w6.d1",  "w7.d0",  "w7.d1",
2627     "w8.d0",  "w8.d1",  "w9.d0",  "w9.d1",
2628     "w10.d0", "w10.d1", "w11.d0", "w11.d1",
2629     "w12.d0", "w12.d1", "w13.d0", "w13.d1",
2630     "w14.d0", "w14.d1", "w15.d0", "w15.d1",
2631     "w16.d0", "w16.d1", "w17.d0", "w17.d1",
2632     "w18.d0", "w18.d1", "w19.d0", "w19.d1",
2633     "w20.d0", "w20.d1", "w21.d0", "w21.d1",
2634     "w22.d0", "w22.d1", "w23.d0", "w23.d1",
2635     "w24.d0", "w24.d1", "w25.d0", "w25.d1",
2636     "w26.d0", "w26.d1", "w27.d0", "w27.d1",
2637     "w28.d0", "w28.d1", "w29.d0", "w29.d1",
2638     "w30.d0", "w30.d1", "w31.d0", "w31.d1",
2639 };
2640 
2641 #if !defined(TARGET_MIPS64)
2642 static const char * const mxuregnames[] = {
2643     "XR1",  "XR2",  "XR3",  "XR4",  "XR5",  "XR6",  "XR7",  "XR8",
2644     "XR9",  "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
2645 };
2646 #endif
2647 
2648 #define LOG_DISAS(...)                                                        \
2649     do {                                                                      \
2650         if (MIPS_DEBUG_DISAS) {                                               \
2651             qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__);                 \
2652         }                                                                     \
2653     } while (0)
2654 
2655 #define MIPS_INVAL(op)                                                        \
2656     do {                                                                      \
2657         if (MIPS_DEBUG_DISAS) {                                               \
2658             qemu_log_mask(CPU_LOG_TB_IN_ASM,                                  \
2659                           TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
2660                           ctx->base.pc_next, ctx->opcode, op,                 \
2661                           ctx->opcode >> 26, ctx->opcode & 0x3F,              \
2662                           ((ctx->opcode >> 16) & 0x1F));                      \
2663         }                                                                     \
2664     } while (0)
2665 
2666 /* General purpose registers moves. */
gen_load_gpr(TCGv t,int reg)2667 static inline void gen_load_gpr(TCGv t, int reg)
2668 {
2669     if (reg == 0) {
2670         tcg_gen_movi_tl(t, 0);
2671     } else {
2672         tcg_gen_mov_tl(t, cpu_gpr[reg]);
2673     }
2674 }
2675 
gen_store_gpr(TCGv t,int reg)2676 static inline void gen_store_gpr(TCGv t, int reg)
2677 {
2678     if (reg != 0) {
2679         tcg_gen_mov_tl(cpu_gpr[reg], t);
2680     }
2681 }
2682 
2683 /* Moves to/from shadow registers. */
gen_load_srsgpr(int from,int to)2684 static inline void gen_load_srsgpr(int from, int to)
2685 {
2686     TCGv t0 = tcg_temp_new();
2687 
2688     if (from == 0) {
2689         tcg_gen_movi_tl(t0, 0);
2690     } else {
2691         TCGv_i32 t2 = tcg_temp_new_i32();
2692         TCGv_ptr addr = tcg_temp_new_ptr();
2693 
2694         tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2695         tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2696         tcg_gen_andi_i32(t2, t2, 0xf);
2697         tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2698         tcg_gen_ext_i32_ptr(addr, t2);
2699         tcg_gen_add_ptr(addr, cpu_env, addr);
2700 
2701         tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
2702         tcg_temp_free_ptr(addr);
2703         tcg_temp_free_i32(t2);
2704     }
2705     gen_store_gpr(t0, to);
2706     tcg_temp_free(t0);
2707 }
2708 
gen_store_srsgpr(int from,int to)2709 static inline void gen_store_srsgpr(int from, int to)
2710 {
2711     if (to != 0) {
2712         TCGv t0 = tcg_temp_new();
2713         TCGv_i32 t2 = tcg_temp_new_i32();
2714         TCGv_ptr addr = tcg_temp_new_ptr();
2715 
2716         gen_load_gpr(t0, from);
2717         tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2718         tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2719         tcg_gen_andi_i32(t2, t2, 0xf);
2720         tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2721         tcg_gen_ext_i32_ptr(addr, t2);
2722         tcg_gen_add_ptr(addr, cpu_env, addr);
2723 
2724         tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
2725         tcg_temp_free_ptr(addr);
2726         tcg_temp_free_i32(t2);
2727         tcg_temp_free(t0);
2728     }
2729 }
2730 
2731 #if !defined(TARGET_MIPS64)
2732 /* MXU General purpose registers moves. */
gen_load_mxu_gpr(TCGv t,unsigned int reg)2733 static inline void gen_load_mxu_gpr(TCGv t, unsigned int reg)
2734 {
2735     if (reg == 0) {
2736         tcg_gen_movi_tl(t, 0);
2737     } else if (reg <= 15) {
2738         tcg_gen_mov_tl(t, mxu_gpr[reg - 1]);
2739     }
2740 }
2741 
gen_store_mxu_gpr(TCGv t,unsigned int reg)2742 static inline void gen_store_mxu_gpr(TCGv t, unsigned int reg)
2743 {
2744     if (reg > 0 && reg <= 15) {
2745         tcg_gen_mov_tl(mxu_gpr[reg - 1], t);
2746     }
2747 }
2748 
2749 /* MXU control register moves. */
gen_load_mxu_cr(TCGv t)2750 static inline void gen_load_mxu_cr(TCGv t)
2751 {
2752     tcg_gen_mov_tl(t, mxu_CR);
2753 }
2754 
gen_store_mxu_cr(TCGv t)2755 static inline void gen_store_mxu_cr(TCGv t)
2756 {
2757     /* TODO: Add handling of RW rules for MXU_CR. */
2758     tcg_gen_mov_tl(mxu_CR, t);
2759 }
2760 #endif
2761 
2762 
2763 /* Tests */
gen_save_pc(target_ulong pc)2764 static inline void gen_save_pc(target_ulong pc)
2765 {
2766     tcg_gen_movi_tl(cpu_PC, pc);
2767 }
2768 
save_cpu_state(DisasContext * ctx,int do_save_pc)2769 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
2770 {
2771     LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
2772     if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
2773         gen_save_pc(ctx->base.pc_next);
2774         ctx->saved_pc = ctx->base.pc_next;
2775     }
2776     if (ctx->hflags != ctx->saved_hflags) {
2777         tcg_gen_movi_i32(hflags, ctx->hflags);
2778         ctx->saved_hflags = ctx->hflags;
2779         switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2780         case MIPS_HFLAG_BR:
2781             break;
2782         case MIPS_HFLAG_BC:
2783         case MIPS_HFLAG_BL:
2784         case MIPS_HFLAG_B:
2785             tcg_gen_movi_tl(btarget, ctx->btarget);
2786             break;
2787         }
2788     }
2789 }
2790 
restore_cpu_state(CPUMIPSState * env,DisasContext * ctx)2791 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
2792 {
2793     ctx->saved_hflags = ctx->hflags;
2794     switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2795     case MIPS_HFLAG_BR:
2796         break;
2797     case MIPS_HFLAG_BC:
2798     case MIPS_HFLAG_BL:
2799     case MIPS_HFLAG_B:
2800         ctx->btarget = env->btarget;
2801         break;
2802     }
2803 }
2804 
generate_exception_err(DisasContext * ctx,int excp,int err)2805 static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
2806 {
2807     TCGv_i32 texcp = tcg_const_i32(excp);
2808     TCGv_i32 terr = tcg_const_i32(err);
2809     save_cpu_state(ctx, 1);
2810     gen_helper_raise_exception_err(cpu_env, texcp, terr);
2811     tcg_temp_free_i32(terr);
2812     tcg_temp_free_i32(texcp);
2813     ctx->base.is_jmp = DISAS_NORETURN;
2814 }
2815 
generate_exception(DisasContext * ctx,int excp)2816 static inline void generate_exception(DisasContext *ctx, int excp)
2817 {
2818     gen_helper_0e0i(raise_exception, excp);
2819 }
2820 
generate_exception_end(DisasContext * ctx,int excp)2821 static inline void generate_exception_end(DisasContext *ctx, int excp)
2822 {
2823     generate_exception_err(ctx, excp, 0);
2824 }
2825 
2826 /* Floating point register moves. */
gen_load_fpr32(DisasContext * ctx,TCGv_i32 t,int reg)2827 static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2828 {
2829     if (ctx->hflags & MIPS_HFLAG_FRE) {
2830         generate_exception(ctx, EXCP_RI);
2831     }
2832     tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
2833 }
2834 
gen_store_fpr32(DisasContext * ctx,TCGv_i32 t,int reg)2835 static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2836 {
2837     TCGv_i64 t64;
2838     if (ctx->hflags & MIPS_HFLAG_FRE) {
2839         generate_exception(ctx, EXCP_RI);
2840     }
2841     t64 = tcg_temp_new_i64();
2842     tcg_gen_extu_i32_i64(t64, t);
2843     tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
2844     tcg_temp_free_i64(t64);
2845 }
2846 
gen_load_fpr32h(DisasContext * ctx,TCGv_i32 t,int reg)2847 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2848 {
2849     if (ctx->hflags & MIPS_HFLAG_F64) {
2850         tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
2851     } else {
2852         gen_load_fpr32(ctx, t, reg | 1);
2853     }
2854 }
2855 
gen_store_fpr32h(DisasContext * ctx,TCGv_i32 t,int reg)2856 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2857 {
2858     if (ctx->hflags & MIPS_HFLAG_F64) {
2859         TCGv_i64 t64 = tcg_temp_new_i64();
2860         tcg_gen_extu_i32_i64(t64, t);
2861         tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
2862         tcg_temp_free_i64(t64);
2863     } else {
2864         gen_store_fpr32(ctx, t, reg | 1);
2865     }
2866 }
2867 
gen_load_fpr64(DisasContext * ctx,TCGv_i64 t,int reg)2868 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2869 {
2870     if (ctx->hflags & MIPS_HFLAG_F64) {
2871         tcg_gen_mov_i64(t, fpu_f64[reg]);
2872     } else {
2873         tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
2874     }
2875 }
2876 
gen_store_fpr64(DisasContext * ctx,TCGv_i64 t,int reg)2877 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2878 {
2879     if (ctx->hflags & MIPS_HFLAG_F64) {
2880         tcg_gen_mov_i64(fpu_f64[reg], t);
2881     } else {
2882         TCGv_i64 t0;
2883         tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
2884         t0 = tcg_temp_new_i64();
2885         tcg_gen_shri_i64(t0, t, 32);
2886         tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
2887         tcg_temp_free_i64(t0);
2888     }
2889 }
2890 
get_fp_bit(int cc)2891 static inline int get_fp_bit(int cc)
2892 {
2893     if (cc) {
2894         return 24 + cc;
2895     } else {
2896         return 23;
2897     }
2898 }
2899 
2900 /* Addresses computation */
gen_op_addr_add(DisasContext * ctx,TCGv ret,TCGv arg0,TCGv arg1)2901 static inline void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0,
2902                                    TCGv arg1)
2903 {
2904     tcg_gen_add_tl(ret, arg0, arg1);
2905 
2906 #if defined(TARGET_MIPS64)
2907     if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2908         tcg_gen_ext32s_i64(ret, ret);
2909     }
2910 #endif
2911 }
2912 
gen_op_addr_addi(DisasContext * ctx,TCGv ret,TCGv base,target_long ofs)2913 static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
2914                                     target_long ofs)
2915 {
2916     tcg_gen_addi_tl(ret, base, ofs);
2917 
2918 #if defined(TARGET_MIPS64)
2919     if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2920         tcg_gen_ext32s_i64(ret, ret);
2921     }
2922 #endif
2923 }
2924 
2925 /* Addresses computation (translation time) */
addr_add(DisasContext * ctx,target_long base,target_long offset)2926 static target_long addr_add(DisasContext *ctx, target_long base,
2927                             target_long offset)
2928 {
2929     target_long sum = base + offset;
2930 
2931 #if defined(TARGET_MIPS64)
2932     if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2933         sum = (int32_t)sum;
2934     }
2935 #endif
2936     return sum;
2937 }
2938 
2939 /* Sign-extract the low 32-bits to a target_long.  */
gen_move_low32(TCGv ret,TCGv_i64 arg)2940 static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
2941 {
2942 #if defined(TARGET_MIPS64)
2943     tcg_gen_ext32s_i64(ret, arg);
2944 #else
2945     tcg_gen_extrl_i64_i32(ret, arg);
2946 #endif
2947 }
2948 
2949 /* Sign-extract the high 32-bits to a target_long.  */
gen_move_high32(TCGv ret,TCGv_i64 arg)2950 static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
2951 {
2952 #if defined(TARGET_MIPS64)
2953     tcg_gen_sari_i64(ret, arg, 32);
2954 #else
2955     tcg_gen_extrh_i64_i32(ret, arg);
2956 #endif
2957 }
2958 
check_cp0_enabled(DisasContext * ctx)2959 static inline void check_cp0_enabled(DisasContext *ctx)
2960 {
2961     if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
2962         generate_exception_err(ctx, EXCP_CpU, 0);
2963     }
2964 }
2965 
check_cp1_enabled(DisasContext * ctx)2966 static inline void check_cp1_enabled(DisasContext *ctx)
2967 {
2968     if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) {
2969         generate_exception_err(ctx, EXCP_CpU, 1);
2970     }
2971 }
2972 
2973 /*
2974  * Verify that the processor is running with COP1X instructions enabled.
2975  * This is associated with the nabla symbol in the MIPS32 and MIPS64
2976  * opcode tables.
2977  */
check_cop1x(DisasContext * ctx)2978 static inline void check_cop1x(DisasContext *ctx)
2979 {
2980     if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) {
2981         generate_exception_end(ctx, EXCP_RI);
2982     }
2983 }
2984 
2985 /*
2986  * Verify that the processor is running with 64-bit floating-point
2987  * operations enabled.
2988  */
check_cp1_64bitmode(DisasContext * ctx)2989 static inline void check_cp1_64bitmode(DisasContext *ctx)
2990 {
2991     if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X))) {
2992         generate_exception_end(ctx, EXCP_RI);
2993     }
2994 }
2995 
2996 /*
2997  * Verify if floating point register is valid; an operation is not defined
2998  * if bit 0 of any register specification is set and the FR bit in the
2999  * Status register equals zero, since the register numbers specify an
3000  * even-odd pair of adjacent coprocessor general registers. When the FR bit
3001  * in the Status register equals one, both even and odd register numbers
3002  * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
3003  *
3004  * Multiple 64 bit wide registers can be checked by calling
3005  * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
3006  */
check_cp1_registers(DisasContext * ctx,int regs)3007 static inline void check_cp1_registers(DisasContext *ctx, int regs)
3008 {
3009     if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) {
3010         generate_exception_end(ctx, EXCP_RI);
3011     }
3012 }
3013 
3014 /*
3015  * Verify that the processor is running with DSP instructions enabled.
3016  * This is enabled by CP0 Status register MX(24) bit.
3017  */
check_dsp(DisasContext * ctx)3018 static inline void check_dsp(DisasContext *ctx)
3019 {
3020     if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
3021         if (ctx->insn_flags & ASE_DSP) {
3022             generate_exception_end(ctx, EXCP_DSPDIS);
3023         } else {
3024             generate_exception_end(ctx, EXCP_RI);
3025         }
3026     }
3027 }
3028 
check_dsp_r2(DisasContext * ctx)3029 static inline void check_dsp_r2(DisasContext *ctx)
3030 {
3031     if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
3032         if (ctx->insn_flags & ASE_DSP) {
3033             generate_exception_end(ctx, EXCP_DSPDIS);
3034         } else {
3035             generate_exception_end(ctx, EXCP_RI);
3036         }
3037     }
3038 }
3039 
check_dsp_r3(DisasContext * ctx)3040 static inline void check_dsp_r3(DisasContext *ctx)
3041 {
3042     if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
3043         if (ctx->insn_flags & ASE_DSP) {
3044             generate_exception_end(ctx, EXCP_DSPDIS);
3045         } else {
3046             generate_exception_end(ctx, EXCP_RI);
3047         }
3048     }
3049 }
3050 
3051 /*
3052  * This code generates a "reserved instruction" exception if the
3053  * CPU does not support the instruction set corresponding to flags.
3054  */
check_insn(DisasContext * ctx,uint64_t flags)3055 static inline void check_insn(DisasContext *ctx, uint64_t flags)
3056 {
3057     if (unlikely(!(ctx->insn_flags & flags))) {
3058         generate_exception_end(ctx, EXCP_RI);
3059     }
3060 }
3061 
3062 /*
3063  * This code generates a "reserved instruction" exception if the
3064  * CPU has corresponding flag set which indicates that the instruction
3065  * has been removed.
3066  */
check_insn_opc_removed(DisasContext * ctx,uint64_t flags)3067 static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
3068 {
3069     if (unlikely(ctx->insn_flags & flags)) {
3070         generate_exception_end(ctx, EXCP_RI);
3071     }
3072 }
3073 
3074 /*
3075  * The Linux kernel traps certain reserved instruction exceptions to
3076  * emulate the corresponding instructions. QEMU is the kernel in user
3077  * mode, so those traps are emulated by accepting the instructions.
3078  *
3079  * A reserved instruction exception is generated for flagged CPUs if
3080  * QEMU runs in system mode.
3081  */
check_insn_opc_user_only(DisasContext * ctx,uint64_t flags)3082 static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
3083 {
3084 #ifndef CONFIG_USER_ONLY
3085     check_insn_opc_removed(ctx, flags);
3086 #endif
3087 }
3088 
3089 /*
3090  * This code generates a "reserved instruction" exception if the
3091  * CPU does not support 64-bit paired-single (PS) floating point data type.
3092  */
check_ps(DisasContext * ctx)3093 static inline void check_ps(DisasContext *ctx)
3094 {
3095     if (unlikely(!ctx->ps)) {
3096         generate_exception(ctx, EXCP_RI);
3097     }
3098     check_cp1_64bitmode(ctx);
3099 }
3100 
3101 #ifdef TARGET_MIPS64
3102 /*
3103  * This code generates a "reserved instruction" exception if 64-bit
3104  * instructions are not enabled.
3105  */
check_mips_64(DisasContext * ctx)3106 static inline void check_mips_64(DisasContext *ctx)
3107 {
3108     if (unlikely(!(ctx->hflags & MIPS_HFLAG_64))) {
3109         generate_exception_end(ctx, EXCP_RI);
3110     }
3111 }
3112 #endif
3113 
3114 #ifndef CONFIG_USER_ONLY
check_mvh(DisasContext * ctx)3115 static inline void check_mvh(DisasContext *ctx)
3116 {
3117     if (unlikely(!ctx->mvh)) {
3118         generate_exception(ctx, EXCP_RI);
3119     }
3120 }
3121 #endif
3122 
3123 /*
3124  * This code generates a "reserved instruction" exception if the
3125  * Config5 XNP bit is set.
3126  */
check_xnp(DisasContext * ctx)3127 static inline void check_xnp(DisasContext *ctx)
3128 {
3129     if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
3130         generate_exception_end(ctx, EXCP_RI);
3131     }
3132 }
3133 
3134 #ifndef CONFIG_USER_ONLY
3135 /*
3136  * This code generates a "reserved instruction" exception if the
3137  * Config3 PW bit is NOT set.
3138  */
check_pw(DisasContext * ctx)3139 static inline void check_pw(DisasContext *ctx)
3140 {
3141     if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
3142         generate_exception_end(ctx, EXCP_RI);
3143     }
3144 }
3145 #endif
3146 
3147 /*
3148  * This code generates a "reserved instruction" exception if the
3149  * Config3 MT bit is NOT set.
3150  */
check_mt(DisasContext * ctx)3151 static inline void check_mt(DisasContext *ctx)
3152 {
3153     if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3154         generate_exception_end(ctx, EXCP_RI);
3155     }
3156 }
3157 
3158 #ifndef CONFIG_USER_ONLY
3159 /*
3160  * This code generates a "coprocessor unusable" exception if CP0 is not
3161  * available, and, if that is not the case, generates a "reserved instruction"
3162  * exception if the Config5 MT bit is NOT set. This is needed for availability
3163  * control of some of MT ASE instructions.
3164  */
check_cp0_mt(DisasContext * ctx)3165 static inline void check_cp0_mt(DisasContext *ctx)
3166 {
3167     if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
3168         generate_exception_err(ctx, EXCP_CpU, 0);
3169     } else {
3170         if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3171             generate_exception_err(ctx, EXCP_RI, 0);
3172         }
3173     }
3174 }
3175 #endif
3176 
3177 /*
3178  * This code generates a "reserved instruction" exception if the
3179  * Config5 NMS bit is set.
3180  */
check_nms(DisasContext * ctx)3181 static inline void check_nms(DisasContext *ctx)
3182 {
3183     if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
3184         generate_exception_end(ctx, EXCP_RI);
3185     }
3186 }
3187 
3188 /*
3189  * This code generates a "reserved instruction" exception if the
3190  * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
3191  * Config2 TL, and Config5 L2C are unset.
3192  */
check_nms_dl_il_sl_tl_l2c(DisasContext * ctx)3193 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
3194 {
3195     if (unlikely((ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
3196                  !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
3197                  !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
3198                  !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
3199                  !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
3200                  !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))) {
3201         generate_exception_end(ctx, EXCP_RI);
3202     }
3203 }
3204 
3205 /*
3206  * This code generates a "reserved instruction" exception if the
3207  * Config5 EVA bit is NOT set.
3208  */
check_eva(DisasContext * ctx)3209 static inline void check_eva(DisasContext *ctx)
3210 {
3211     if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
3212         generate_exception_end(ctx, EXCP_RI);
3213     }
3214 }
3215 
3216 
3217 /*
3218  * Define small wrappers for gen_load_fpr* so that we have a uniform
3219  * calling interface for 32 and 64-bit FPRs.  No sense in changing
3220  * all callers for gen_load_fpr32 when we need the CTX parameter for
3221  * this one use.
3222  */
3223 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
3224 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
3225 #define FOP_CONDS(type, abs, fmt, ifmt, bits)                                 \
3226 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
3227                                                int ft, int fs, int cc)        \
3228 {                                                                             \
3229     TCGv_i##bits fp0 = tcg_temp_new_i##bits();                                \
3230     TCGv_i##bits fp1 = tcg_temp_new_i##bits();                                \
3231     switch (ifmt) {                                                           \
3232     case FMT_PS:                                                              \
3233         check_ps(ctx);                                                        \
3234         break;                                                                \
3235     case FMT_D:                                                               \
3236         if (abs) {                                                            \
3237             check_cop1x(ctx);                                                 \
3238         }                                                                     \
3239         check_cp1_registers(ctx, fs | ft);                                    \
3240         break;                                                                \
3241     case FMT_S:                                                               \
3242         if (abs) {                                                            \
3243             check_cop1x(ctx);                                                 \
3244         }                                                                     \
3245         break;                                                                \
3246     }                                                                         \
3247     gen_ldcmp_fpr##bits(ctx, fp0, fs);                                        \
3248     gen_ldcmp_fpr##bits(ctx, fp1, ft);                                        \
3249     switch (n) {                                                              \
3250     case  0:                                                                  \
3251         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc);         \
3252     break;                                                                    \
3253     case  1:                                                                  \
3254         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc);        \
3255     break;                                                                    \
3256     case  2:                                                                  \
3257         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc);        \
3258     break;                                                                    \
3259     case  3:                                                                  \
3260         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc);       \
3261     break;                                                                    \
3262     case  4:                                                                  \
3263         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc);       \
3264     break;                                                                    \
3265     case  5:                                                                  \
3266         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc);       \
3267     break;                                                                    \
3268     case  6:                                                                  \
3269         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc);       \
3270     break;                                                                    \
3271     case  7:                                                                  \
3272         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc);       \
3273     break;                                                                    \
3274     case  8:                                                                  \
3275         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc);        \
3276     break;                                                                    \
3277     case  9:                                                                  \
3278         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc);      \
3279     break;                                                                    \
3280     case 10:                                                                  \
3281         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc);       \
3282     break;                                                                    \
3283     case 11:                                                                  \
3284         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc);       \
3285     break;                                                                    \
3286     case 12:                                                                  \
3287         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc);        \
3288     break;                                                                    \
3289     case 13:                                                                  \
3290         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc);       \
3291     break;                                                                    \
3292     case 14:                                                                  \
3293         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc);        \
3294     break;                                                                    \
3295     case 15:                                                                  \
3296         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc);       \
3297     break;                                                                    \
3298     default:                                                                  \
3299         abort();                                                              \
3300     }                                                                         \
3301     tcg_temp_free_i##bits(fp0);                                               \
3302     tcg_temp_free_i##bits(fp1);                                               \
3303 }
3304 
3305 FOP_CONDS(, 0, d, FMT_D, 64)
3306 FOP_CONDS(abs, 1, d, FMT_D, 64)
3307 FOP_CONDS(, 0, s, FMT_S, 32)
3308 FOP_CONDS(abs, 1, s, FMT_S, 32)
3309 FOP_CONDS(, 0, ps, FMT_PS, 64)
3310 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
3311 #undef FOP_CONDS
3312 
3313 #define FOP_CONDNS(fmt, ifmt, bits, STORE)                              \
3314 static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n,         \
3315                                       int ft, int fs, int fd)           \
3316 {                                                                       \
3317     TCGv_i ## bits fp0 = tcg_temp_new_i ## bits();                      \
3318     TCGv_i ## bits fp1 = tcg_temp_new_i ## bits();                      \
3319     if (ifmt == FMT_D) {                                                \
3320         check_cp1_registers(ctx, fs | ft | fd);                         \
3321     }                                                                   \
3322     gen_ldcmp_fpr ## bits(ctx, fp0, fs);                                \
3323     gen_ldcmp_fpr ## bits(ctx, fp1, ft);                                \
3324     switch (n) {                                                        \
3325     case  0:                                                            \
3326         gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1);       \
3327         break;                                                          \
3328     case  1:                                                            \
3329         gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1);       \
3330         break;                                                          \
3331     case  2:                                                            \
3332         gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1);       \
3333         break;                                                          \
3334     case  3:                                                            \
3335         gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1);      \
3336         break;                                                          \
3337     case  4:                                                            \
3338         gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1);       \
3339         break;                                                          \
3340     case  5:                                                            \
3341         gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1);      \
3342         break;                                                          \
3343     case  6:                                                            \
3344         gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1);       \
3345         break;                                                          \
3346     case  7:                                                            \
3347         gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1);      \
3348         break;                                                          \
3349     case  8:                                                            \
3350         gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1);      \
3351         break;                                                          \
3352     case  9:                                                            \
3353         gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1);      \
3354         break;                                                          \
3355     case 10:                                                            \
3356         gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1);      \
3357         break;                                                          \
3358     case 11:                                                            \
3359         gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1);     \
3360         break;                                                          \
3361     case 12:                                                            \
3362         gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1);      \
3363         break;                                                          \
3364     case 13:                                                            \
3365         gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1);     \
3366         break;                                                          \
3367     case 14:                                                            \
3368         gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1);      \
3369         break;                                                          \
3370     case 15:                                                            \
3371         gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1);     \
3372         break;                                                          \
3373     case 17:                                                            \
3374         gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1);       \
3375         break;                                                          \
3376     case 18:                                                            \
3377         gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1);      \
3378         break;                                                          \
3379     case 19:                                                            \
3380         gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1);       \
3381         break;                                                          \
3382     case 25:                                                            \
3383         gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1);      \
3384         break;                                                          \
3385     case 26:                                                            \
3386         gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1);     \
3387         break;                                                          \
3388     case 27:                                                            \
3389         gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1);      \
3390         break;                                                          \
3391     default:                                                            \
3392         abort();                                                        \
3393     }                                                                   \
3394     STORE;                                                              \
3395     tcg_temp_free_i ## bits(fp0);                                       \
3396     tcg_temp_free_i ## bits(fp1);                                       \
3397 }
3398 
3399 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
3400 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3401 #undef FOP_CONDNS
3402 #undef gen_ldcmp_fpr32
3403 #undef gen_ldcmp_fpr64
3404 
3405 /* load/store instructions. */
3406 #ifdef CONFIG_USER_ONLY
3407 #define OP_LD_ATOMIC(insn, fname)                                          \
3408 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
3409                                 DisasContext *ctx)                         \
3410 {                                                                          \
3411     TCGv t0 = tcg_temp_new();                                              \
3412     tcg_gen_mov_tl(t0, arg1);                                              \
3413     tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
3414     tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));            \
3415     tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval));            \
3416     tcg_temp_free(t0);                                                     \
3417 }
3418 #else
3419 #define OP_LD_ATOMIC(insn, fname)                                          \
3420 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
3421                                 DisasContext *ctx)                         \
3422 {                                                                          \
3423     gen_helper_1e1i(insn, ret, arg1, mem_idx);                             \
3424 }
3425 #endif
3426 OP_LD_ATOMIC(ll, ld32s);
3427 #if defined(TARGET_MIPS64)
3428 OP_LD_ATOMIC(lld, ld64);
3429 #endif
3430 #undef OP_LD_ATOMIC
3431 
gen_base_offset_addr(DisasContext * ctx,TCGv addr,int base,int offset)3432 static void gen_base_offset_addr(DisasContext *ctx, TCGv addr,
3433                                  int base, int offset)
3434 {
3435     if (base == 0) {
3436         tcg_gen_movi_tl(addr, offset);
3437     } else if (offset == 0) {
3438         gen_load_gpr(addr, base);
3439     } else {
3440         tcg_gen_movi_tl(addr, offset);
3441         gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
3442     }
3443 }
3444 
pc_relative_pc(DisasContext * ctx)3445 static target_ulong pc_relative_pc(DisasContext *ctx)
3446 {
3447     target_ulong pc = ctx->base.pc_next;
3448 
3449     if (ctx->hflags & MIPS_HFLAG_BMASK) {
3450         int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
3451 
3452         pc -= branch_bytes;
3453     }
3454 
3455     pc &= ~(target_ulong)3;
3456     return pc;
3457 }
3458 
3459 /* Load */
gen_ld(DisasContext * ctx,uint32_t opc,int rt,int base,int offset)3460 static void gen_ld(DisasContext *ctx, uint32_t opc,
3461                    int rt, int base, int offset)
3462 {
3463     TCGv t0, t1, t2;
3464     int mem_idx = ctx->mem_idx;
3465 
3466     if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F |
3467                                       INSN_LOONGSON3A)) {
3468         /*
3469          * Loongson CPU uses a load to zero register for prefetch.
3470          * We emulate it as a NOP. On other CPU we must perform the
3471          * actual memory access.
3472          */
3473         return;
3474     }
3475 
3476     t0 = tcg_temp_new();
3477     gen_base_offset_addr(ctx, t0, base, offset);
3478 
3479     switch (opc) {
3480 #if defined(TARGET_MIPS64)
3481     case OPC_LWU:
3482         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
3483                            ctx->default_tcg_memop_mask);
3484         gen_store_gpr(t0, rt);
3485         break;
3486     case OPC_LD:
3487         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
3488                            ctx->default_tcg_memop_mask);
3489         gen_store_gpr(t0, rt);
3490         break;
3491     case OPC_LLD:
3492     case R6_OPC_LLD:
3493         op_ld_lld(t0, t0, mem_idx, ctx);
3494         gen_store_gpr(t0, rt);
3495         break;
3496     case OPC_LDL:
3497         t1 = tcg_temp_new();
3498         /*
3499          * Do a byte access to possibly trigger a page
3500          * fault with the unaligned address.
3501          */
3502         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3503         tcg_gen_andi_tl(t1, t0, 7);
3504 #ifndef TARGET_WORDS_BIGENDIAN
3505         tcg_gen_xori_tl(t1, t1, 7);
3506 #endif
3507         tcg_gen_shli_tl(t1, t1, 3);
3508         tcg_gen_andi_tl(t0, t0, ~7);
3509         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3510         tcg_gen_shl_tl(t0, t0, t1);
3511         t2 = tcg_const_tl(-1);
3512         tcg_gen_shl_tl(t2, t2, t1);
3513         gen_load_gpr(t1, rt);
3514         tcg_gen_andc_tl(t1, t1, t2);
3515         tcg_temp_free(t2);
3516         tcg_gen_or_tl(t0, t0, t1);
3517         tcg_temp_free(t1);
3518         gen_store_gpr(t0, rt);
3519         break;
3520     case OPC_LDR:
3521         t1 = tcg_temp_new();
3522         /*
3523          * Do a byte access to possibly trigger a page
3524          * fault with the unaligned address.
3525          */
3526         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3527         tcg_gen_andi_tl(t1, t0, 7);
3528 #ifdef TARGET_WORDS_BIGENDIAN
3529         tcg_gen_xori_tl(t1, t1, 7);
3530 #endif
3531         tcg_gen_shli_tl(t1, t1, 3);
3532         tcg_gen_andi_tl(t0, t0, ~7);
3533         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3534         tcg_gen_shr_tl(t0, t0, t1);
3535         tcg_gen_xori_tl(t1, t1, 63);
3536         t2 = tcg_const_tl(0xfffffffffffffffeull);
3537         tcg_gen_shl_tl(t2, t2, t1);
3538         gen_load_gpr(t1, rt);
3539         tcg_gen_and_tl(t1, t1, t2);
3540         tcg_temp_free(t2);
3541         tcg_gen_or_tl(t0, t0, t1);
3542         tcg_temp_free(t1);
3543         gen_store_gpr(t0, rt);
3544         break;
3545     case OPC_LDPC:
3546         t1 = tcg_const_tl(pc_relative_pc(ctx));
3547         gen_op_addr_add(ctx, t0, t0, t1);
3548         tcg_temp_free(t1);
3549         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3550         gen_store_gpr(t0, rt);
3551         break;
3552 #endif
3553     case OPC_LWPC:
3554         t1 = tcg_const_tl(pc_relative_pc(ctx));
3555         gen_op_addr_add(ctx, t0, t0, t1);
3556         tcg_temp_free(t1);
3557         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
3558         gen_store_gpr(t0, rt);
3559         break;
3560     case OPC_LWE:
3561         mem_idx = MIPS_HFLAG_UM;
3562         /* fall through */
3563     case OPC_LW:
3564         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
3565                            ctx->default_tcg_memop_mask);
3566         gen_store_gpr(t0, rt);
3567         break;
3568     case OPC_LHE:
3569         mem_idx = MIPS_HFLAG_UM;
3570         /* fall through */
3571     case OPC_LH:
3572         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
3573                            ctx->default_tcg_memop_mask);
3574         gen_store_gpr(t0, rt);
3575         break;
3576     case OPC_LHUE:
3577         mem_idx = MIPS_HFLAG_UM;
3578         /* fall through */
3579     case OPC_LHU:
3580         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
3581                            ctx->default_tcg_memop_mask);
3582         gen_store_gpr(t0, rt);
3583         break;
3584     case OPC_LBE:
3585         mem_idx = MIPS_HFLAG_UM;
3586         /* fall through */
3587     case OPC_LB:
3588         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
3589         gen_store_gpr(t0, rt);
3590         break;
3591     case OPC_LBUE:
3592         mem_idx = MIPS_HFLAG_UM;
3593         /* fall through */
3594     case OPC_LBU:
3595         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
3596         gen_store_gpr(t0, rt);
3597         break;
3598     case OPC_LWLE:
3599         mem_idx = MIPS_HFLAG_UM;
3600         /* fall through */
3601     case OPC_LWL:
3602         t1 = tcg_temp_new();
3603         /*
3604          * Do a byte access to possibly trigger a page
3605          * fault with the unaligned address.
3606          */
3607         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3608         tcg_gen_andi_tl(t1, t0, 3);
3609 #ifndef TARGET_WORDS_BIGENDIAN
3610         tcg_gen_xori_tl(t1, t1, 3);
3611 #endif
3612         tcg_gen_shli_tl(t1, t1, 3);
3613         tcg_gen_andi_tl(t0, t0, ~3);
3614         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3615         tcg_gen_shl_tl(t0, t0, t1);
3616         t2 = tcg_const_tl(-1);
3617         tcg_gen_shl_tl(t2, t2, t1);
3618         gen_load_gpr(t1, rt);
3619         tcg_gen_andc_tl(t1, t1, t2);
3620         tcg_temp_free(t2);
3621         tcg_gen_or_tl(t0, t0, t1);
3622         tcg_temp_free(t1);
3623         tcg_gen_ext32s_tl(t0, t0);
3624         gen_store_gpr(t0, rt);
3625         break;
3626     case OPC_LWRE:
3627         mem_idx = MIPS_HFLAG_UM;
3628         /* fall through */
3629     case OPC_LWR:
3630         t1 = tcg_temp_new();
3631         /*
3632          * Do a byte access to possibly trigger a page
3633          * fault with the unaligned address.
3634          */
3635         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3636         tcg_gen_andi_tl(t1, t0, 3);
3637 #ifdef TARGET_WORDS_BIGENDIAN
3638         tcg_gen_xori_tl(t1, t1, 3);
3639 #endif
3640         tcg_gen_shli_tl(t1, t1, 3);
3641         tcg_gen_andi_tl(t0, t0, ~3);
3642         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3643         tcg_gen_shr_tl(t0, t0, t1);
3644         tcg_gen_xori_tl(t1, t1, 31);
3645         t2 = tcg_const_tl(0xfffffffeull);
3646         tcg_gen_shl_tl(t2, t2, t1);
3647         gen_load_gpr(t1, rt);
3648         tcg_gen_and_tl(t1, t1, t2);
3649         tcg_temp_free(t2);
3650         tcg_gen_or_tl(t0, t0, t1);
3651         tcg_temp_free(t1);
3652         tcg_gen_ext32s_tl(t0, t0);
3653         gen_store_gpr(t0, rt);
3654         break;
3655     case OPC_LLE:
3656         mem_idx = MIPS_HFLAG_UM;
3657         /* fall through */
3658     case OPC_LL:
3659     case R6_OPC_LL:
3660         op_ld_ll(t0, t0, mem_idx, ctx);
3661         gen_store_gpr(t0, rt);
3662         break;
3663     }
3664     tcg_temp_free(t0);
3665 }
3666 
gen_llwp(DisasContext * ctx,uint32_t base,int16_t offset,uint32_t reg1,uint32_t reg2)3667 static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
3668                     uint32_t reg1, uint32_t reg2)
3669 {
3670     TCGv taddr = tcg_temp_new();
3671     TCGv_i64 tval = tcg_temp_new_i64();
3672     TCGv tmp1 = tcg_temp_new();
3673     TCGv tmp2 = tcg_temp_new();
3674 
3675     gen_base_offset_addr(ctx, taddr, base, offset);
3676     tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx);
3677 #ifdef TARGET_WORDS_BIGENDIAN
3678     tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
3679 #else
3680     tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
3681 #endif
3682     gen_store_gpr(tmp1, reg1);
3683     tcg_temp_free(tmp1);
3684     gen_store_gpr(tmp2, reg2);
3685     tcg_temp_free(tmp2);
3686     tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3687     tcg_temp_free_i64(tval);
3688     tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr));
3689     tcg_temp_free(taddr);
3690 }
3691 
3692 /* Store */
gen_st(DisasContext * ctx,uint32_t opc,int rt,int base,int offset)3693 static void gen_st(DisasContext *ctx, uint32_t opc, int rt,
3694                    int base, int offset)
3695 {
3696     TCGv t0 = tcg_temp_new();
3697     TCGv t1 = tcg_temp_new();
3698     int mem_idx = ctx->mem_idx;
3699 
3700     gen_base_offset_addr(ctx, t0, base, offset);
3701     gen_load_gpr(t1, rt);
3702     switch (opc) {
3703 #if defined(TARGET_MIPS64)
3704     case OPC_SD:
3705         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
3706                            ctx->default_tcg_memop_mask);
3707         break;
3708     case OPC_SDL:
3709         gen_helper_0e2i(sdl, t1, t0, mem_idx);
3710         break;
3711     case OPC_SDR:
3712         gen_helper_0e2i(sdr, t1, t0, mem_idx);
3713         break;
3714 #endif
3715     case OPC_SWE:
3716         mem_idx = MIPS_HFLAG_UM;
3717         /* fall through */
3718     case OPC_SW:
3719         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
3720                            ctx->default_tcg_memop_mask);
3721         break;
3722     case OPC_SHE:
3723         mem_idx = MIPS_HFLAG_UM;
3724         /* fall through */
3725     case OPC_SH:
3726         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
3727                            ctx->default_tcg_memop_mask);
3728         break;
3729     case OPC_SBE:
3730         mem_idx = MIPS_HFLAG_UM;
3731         /* fall through */
3732     case OPC_SB:
3733         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
3734         break;
3735     case OPC_SWLE:
3736         mem_idx = MIPS_HFLAG_UM;
3737         /* fall through */
3738     case OPC_SWL:
3739         gen_helper_0e2i(swl, t1, t0, mem_idx);
3740         break;
3741     case OPC_SWRE:
3742         mem_idx = MIPS_HFLAG_UM;
3743         /* fall through */
3744     case OPC_SWR:
3745         gen_helper_0e2i(swr, t1, t0, mem_idx);
3746         break;
3747     }
3748     tcg_temp_free(t0);
3749     tcg_temp_free(t1);
3750 }
3751 
3752 
3753 /* Store conditional */
gen_st_cond(DisasContext * ctx,int rt,int base,int offset,MemOp tcg_mo,bool eva)3754 static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset,
3755                         MemOp tcg_mo, bool eva)
3756 {
3757     TCGv addr, t0, val;
3758     TCGLabel *l1 = gen_new_label();
3759     TCGLabel *done = gen_new_label();
3760 
3761     t0 = tcg_temp_new();
3762     addr = tcg_temp_new();
3763     /* compare the address against that of the preceding LL */
3764     gen_base_offset_addr(ctx, addr, base, offset);
3765     tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1);
3766     tcg_temp_free(addr);
3767     tcg_gen_movi_tl(t0, 0);
3768     gen_store_gpr(t0, rt);
3769     tcg_gen_br(done);
3770 
3771     gen_set_label(l1);
3772     /* generate cmpxchg */
3773     val = tcg_temp_new();
3774     gen_load_gpr(val, rt);
3775     tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val,
3776                               eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo);
3777     tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval);
3778     gen_store_gpr(t0, rt);
3779     tcg_temp_free(val);
3780 
3781     gen_set_label(done);
3782     tcg_temp_free(t0);
3783 }
3784 
3785 
gen_scwp(DisasContext * ctx,uint32_t base,int16_t offset,uint32_t reg1,uint32_t reg2,bool eva)3786 static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
3787                     uint32_t reg1, uint32_t reg2, bool eva)
3788 {
3789     TCGv taddr = tcg_temp_local_new();
3790     TCGv lladdr = tcg_temp_local_new();
3791     TCGv_i64 tval = tcg_temp_new_i64();
3792     TCGv_i64 llval = tcg_temp_new_i64();
3793     TCGv_i64 val = tcg_temp_new_i64();
3794     TCGv tmp1 = tcg_temp_new();
3795     TCGv tmp2 = tcg_temp_new();
3796     TCGLabel *lab_fail = gen_new_label();
3797     TCGLabel *lab_done = gen_new_label();
3798 
3799     gen_base_offset_addr(ctx, taddr, base, offset);
3800 
3801     tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3802     tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail);
3803 
3804     gen_load_gpr(tmp1, reg1);
3805     gen_load_gpr(tmp2, reg2);
3806 
3807 #ifdef TARGET_WORDS_BIGENDIAN
3808     tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
3809 #else
3810     tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
3811 #endif
3812 
3813     tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3814     tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
3815                                eva ? MIPS_HFLAG_UM : ctx->mem_idx, MO_64);
3816     if (reg1 != 0) {
3817         tcg_gen_movi_tl(cpu_gpr[reg1], 1);
3818     }
3819     tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done);
3820 
3821     gen_set_label(lab_fail);
3822 
3823     if (reg1 != 0) {
3824         tcg_gen_movi_tl(cpu_gpr[reg1], 0);
3825     }
3826     gen_set_label(lab_done);
3827     tcg_gen_movi_tl(lladdr, -1);
3828     tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3829 }
3830 
3831 /* Load and store */
gen_flt_ldst(DisasContext * ctx,uint32_t opc,int ft,TCGv t0)3832 static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft,
3833                          TCGv t0)
3834 {
3835     /*
3836      * Don't do NOP if destination is zero: we must perform the actual
3837      * memory access.
3838      */
3839     switch (opc) {
3840     case OPC_LWC1:
3841         {
3842             TCGv_i32 fp0 = tcg_temp_new_i32();
3843             tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
3844                                 ctx->default_tcg_memop_mask);
3845             gen_store_fpr32(ctx, fp0, ft);
3846             tcg_temp_free_i32(fp0);
3847         }
3848         break;
3849     case OPC_SWC1:
3850         {
3851             TCGv_i32 fp0 = tcg_temp_new_i32();
3852             gen_load_fpr32(ctx, fp0, ft);
3853             tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
3854                                 ctx->default_tcg_memop_mask);
3855             tcg_temp_free_i32(fp0);
3856         }
3857         break;
3858     case OPC_LDC1:
3859         {
3860             TCGv_i64 fp0 = tcg_temp_new_i64();
3861             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3862                                 ctx->default_tcg_memop_mask);
3863             gen_store_fpr64(ctx, fp0, ft);
3864             tcg_temp_free_i64(fp0);
3865         }
3866         break;
3867     case OPC_SDC1:
3868         {
3869             TCGv_i64 fp0 = tcg_temp_new_i64();
3870             gen_load_fpr64(ctx, fp0, ft);
3871             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3872                                 ctx->default_tcg_memop_mask);
3873             tcg_temp_free_i64(fp0);
3874         }
3875         break;
3876     default:
3877         MIPS_INVAL("flt_ldst");
3878         generate_exception_end(ctx, EXCP_RI);
3879         break;
3880     }
3881 }
3882 
gen_cop1_ldst(DisasContext * ctx,uint32_t op,int rt,int rs,int16_t imm)3883 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
3884                           int rs, int16_t imm)
3885 {
3886     TCGv t0 = tcg_temp_new();
3887 
3888     if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3889         check_cp1_enabled(ctx);
3890         switch (op) {
3891         case OPC_LDC1:
3892         case OPC_SDC1:
3893             check_insn(ctx, ISA_MIPS2);
3894             /* Fallthrough */
3895         default:
3896             gen_base_offset_addr(ctx, t0, rs, imm);
3897             gen_flt_ldst(ctx, op, rt, t0);
3898         }
3899     } else {
3900         generate_exception_err(ctx, EXCP_CpU, 1);
3901     }
3902     tcg_temp_free(t0);
3903 }
3904 
3905 /* Arithmetic with immediate operand */
gen_arith_imm(DisasContext * ctx,uint32_t opc,int rt,int rs,int imm)3906 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
3907                           int rt, int rs, int imm)
3908 {
3909     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3910 
3911     if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
3912         /*
3913          * If no destination, treat it as a NOP.
3914          * For addi, we must generate the overflow exception when needed.
3915          */
3916         return;
3917     }
3918     switch (opc) {
3919     case OPC_ADDI:
3920         {
3921             TCGv t0 = tcg_temp_local_new();
3922             TCGv t1 = tcg_temp_new();
3923             TCGv t2 = tcg_temp_new();
3924             TCGLabel *l1 = gen_new_label();
3925 
3926             gen_load_gpr(t1, rs);
3927             tcg_gen_addi_tl(t0, t1, uimm);
3928             tcg_gen_ext32s_tl(t0, t0);
3929 
3930             tcg_gen_xori_tl(t1, t1, ~uimm);
3931             tcg_gen_xori_tl(t2, t0, uimm);
3932             tcg_gen_and_tl(t1, t1, t2);
3933             tcg_temp_free(t2);
3934             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3935             tcg_temp_free(t1);
3936             /* operands of same sign, result different sign */
3937             generate_exception(ctx, EXCP_OVERFLOW);
3938             gen_set_label(l1);
3939             tcg_gen_ext32s_tl(t0, t0);
3940             gen_store_gpr(t0, rt);
3941             tcg_temp_free(t0);
3942         }
3943         break;
3944     case OPC_ADDIU:
3945         if (rs != 0) {
3946             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3947             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3948         } else {
3949             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3950         }
3951         break;
3952 #if defined(TARGET_MIPS64)
3953     case OPC_DADDI:
3954         {
3955             TCGv t0 = tcg_temp_local_new();
3956             TCGv t1 = tcg_temp_new();
3957             TCGv t2 = tcg_temp_new();
3958             TCGLabel *l1 = gen_new_label();
3959 
3960             gen_load_gpr(t1, rs);
3961             tcg_gen_addi_tl(t0, t1, uimm);
3962 
3963             tcg_gen_xori_tl(t1, t1, ~uimm);
3964             tcg_gen_xori_tl(t2, t0, uimm);
3965             tcg_gen_and_tl(t1, t1, t2);
3966             tcg_temp_free(t2);
3967             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3968             tcg_temp_free(t1);
3969             /* operands of same sign, result different sign */
3970             generate_exception(ctx, EXCP_OVERFLOW);
3971             gen_set_label(l1);
3972             gen_store_gpr(t0, rt);
3973             tcg_temp_free(t0);
3974         }
3975         break;
3976     case OPC_DADDIU:
3977         if (rs != 0) {
3978             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3979         } else {
3980             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3981         }
3982         break;
3983 #endif
3984     }
3985 }
3986 
3987 /* Logic with immediate operand */
gen_logic_imm(DisasContext * ctx,uint32_t opc,int rt,int rs,int16_t imm)3988 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
3989                           int rt, int rs, int16_t imm)
3990 {
3991     target_ulong uimm;
3992 
3993     if (rt == 0) {
3994         /* If no destination, treat it as a NOP. */
3995         return;
3996     }
3997     uimm = (uint16_t)imm;
3998     switch (opc) {
3999     case OPC_ANDI:
4000         if (likely(rs != 0)) {
4001             tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
4002         } else {
4003             tcg_gen_movi_tl(cpu_gpr[rt], 0);
4004         }
4005         break;
4006     case OPC_ORI:
4007         if (rs != 0) {
4008             tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
4009         } else {
4010             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
4011         }
4012         break;
4013     case OPC_XORI:
4014         if (likely(rs != 0)) {
4015             tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
4016         } else {
4017             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
4018         }
4019         break;
4020     case OPC_LUI:
4021         if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
4022             /* OPC_AUI */
4023             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
4024             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
4025         } else {
4026             tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
4027         }
4028         break;
4029 
4030     default:
4031         break;
4032     }
4033 }
4034 
4035 /* Set on less than with immediate operand */
gen_slt_imm(DisasContext * ctx,uint32_t opc,int rt,int rs,int16_t imm)4036 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
4037                         int rt, int rs, int16_t imm)
4038 {
4039     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
4040     TCGv t0;
4041 
4042     if (rt == 0) {
4043         /* If no destination, treat it as a NOP. */
4044         return;
4045     }
4046     t0 = tcg_temp_new();
4047     gen_load_gpr(t0, rs);
4048     switch (opc) {
4049     case OPC_SLTI:
4050         tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
4051         break;
4052     case OPC_SLTIU:
4053         tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
4054         break;
4055     }
4056     tcg_temp_free(t0);
4057 }
4058 
4059 /* Shifts with immediate operand */
gen_shift_imm(DisasContext * ctx,uint32_t opc,int rt,int rs,int16_t imm)4060 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
4061                           int rt, int rs, int16_t imm)
4062 {
4063     target_ulong uimm = ((uint16_t)imm) & 0x1f;
4064     TCGv t0;
4065 
4066     if (rt == 0) {
4067         /* If no destination, treat it as a NOP. */
4068         return;
4069     }
4070 
4071     t0 = tcg_temp_new();
4072     gen_load_gpr(t0, rs);
4073     switch (opc) {
4074     case OPC_SLL:
4075         tcg_gen_shli_tl(t0, t0, uimm);
4076         tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
4077         break;
4078     case OPC_SRA:
4079         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
4080         break;
4081     case OPC_SRL:
4082         if (uimm != 0) {
4083             tcg_gen_ext32u_tl(t0, t0);
4084             tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
4085         } else {
4086             tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
4087         }
4088         break;
4089     case OPC_ROTR:
4090         if (uimm != 0) {
4091             TCGv_i32 t1 = tcg_temp_new_i32();
4092 
4093             tcg_gen_trunc_tl_i32(t1, t0);
4094             tcg_gen_rotri_i32(t1, t1, uimm);
4095             tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
4096             tcg_temp_free_i32(t1);
4097         } else {
4098             tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
4099         }
4100         break;
4101 #if defined(TARGET_MIPS64)
4102     case OPC_DSLL:
4103         tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
4104         break;
4105     case OPC_DSRA:
4106         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
4107         break;
4108     case OPC_DSRL:
4109         tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
4110         break;
4111     case OPC_DROTR:
4112         if (uimm != 0) {
4113             tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
4114         } else {
4115             tcg_gen_mov_tl(cpu_gpr[rt], t0);
4116         }
4117         break;
4118     case OPC_DSLL32:
4119         tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
4120         break;
4121     case OPC_DSRA32:
4122         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
4123         break;
4124     case OPC_DSRL32:
4125         tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
4126         break;
4127     case OPC_DROTR32:
4128         tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
4129         break;
4130 #endif
4131     }
4132     tcg_temp_free(t0);
4133 }
4134 
4135 /* Arithmetic */
gen_arith(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)4136 static void gen_arith(DisasContext *ctx, uint32_t opc,
4137                       int rd, int rs, int rt)
4138 {
4139     if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
4140        && opc != OPC_DADD && opc != OPC_DSUB) {
4141         /*
4142          * If no destination, treat it as a NOP.
4143          * For add & sub, we must generate the overflow exception when needed.
4144          */
4145         return;
4146     }
4147 
4148     switch (opc) {
4149     case OPC_ADD:
4150         {
4151             TCGv t0 = tcg_temp_local_new();
4152             TCGv t1 = tcg_temp_new();
4153             TCGv t2 = tcg_temp_new();
4154             TCGLabel *l1 = gen_new_label();
4155 
4156             gen_load_gpr(t1, rs);
4157             gen_load_gpr(t2, rt);
4158             tcg_gen_add_tl(t0, t1, t2);
4159             tcg_gen_ext32s_tl(t0, t0);
4160             tcg_gen_xor_tl(t1, t1, t2);
4161             tcg_gen_xor_tl(t2, t0, t2);
4162             tcg_gen_andc_tl(t1, t2, t1);
4163             tcg_temp_free(t2);
4164             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4165             tcg_temp_free(t1);
4166             /* operands of same sign, result different sign */
4167             generate_exception(ctx, EXCP_OVERFLOW);
4168             gen_set_label(l1);
4169             gen_store_gpr(t0, rd);
4170             tcg_temp_free(t0);
4171         }
4172         break;
4173     case OPC_ADDU:
4174         if (rs != 0 && rt != 0) {
4175             tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4176             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4177         } else if (rs == 0 && rt != 0) {
4178             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4179         } else if (rs != 0 && rt == 0) {
4180             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4181         } else {
4182             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4183         }
4184         break;
4185     case OPC_SUB:
4186         {
4187             TCGv t0 = tcg_temp_local_new();
4188             TCGv t1 = tcg_temp_new();
4189             TCGv t2 = tcg_temp_new();
4190             TCGLabel *l1 = gen_new_label();
4191 
4192             gen_load_gpr(t1, rs);
4193             gen_load_gpr(t2, rt);
4194             tcg_gen_sub_tl(t0, t1, t2);
4195             tcg_gen_ext32s_tl(t0, t0);
4196             tcg_gen_xor_tl(t2, t1, t2);
4197             tcg_gen_xor_tl(t1, t0, t1);
4198             tcg_gen_and_tl(t1, t1, t2);
4199             tcg_temp_free(t2);
4200             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4201             tcg_temp_free(t1);
4202             /*
4203              * operands of different sign, first operand and the result
4204              * of different sign
4205              */
4206             generate_exception(ctx, EXCP_OVERFLOW);
4207             gen_set_label(l1);
4208             gen_store_gpr(t0, rd);
4209             tcg_temp_free(t0);
4210         }
4211         break;
4212     case OPC_SUBU:
4213         if (rs != 0 && rt != 0) {
4214             tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4215             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4216         } else if (rs == 0 && rt != 0) {
4217             tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4218             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4219         } else if (rs != 0 && rt == 0) {
4220             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4221         } else {
4222             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4223         }
4224         break;
4225 #if defined(TARGET_MIPS64)
4226     case OPC_DADD:
4227         {
4228             TCGv t0 = tcg_temp_local_new();
4229             TCGv t1 = tcg_temp_new();
4230             TCGv t2 = tcg_temp_new();
4231             TCGLabel *l1 = gen_new_label();
4232 
4233             gen_load_gpr(t1, rs);
4234             gen_load_gpr(t2, rt);
4235             tcg_gen_add_tl(t0, t1, t2);
4236             tcg_gen_xor_tl(t1, t1, t2);
4237             tcg_gen_xor_tl(t2, t0, t2);
4238             tcg_gen_andc_tl(t1, t2, t1);
4239             tcg_temp_free(t2);
4240             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4241             tcg_temp_free(t1);
4242             /* operands of same sign, result different sign */
4243             generate_exception(ctx, EXCP_OVERFLOW);
4244             gen_set_label(l1);
4245             gen_store_gpr(t0, rd);
4246             tcg_temp_free(t0);
4247         }
4248         break;
4249     case OPC_DADDU:
4250         if (rs != 0 && rt != 0) {
4251             tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4252         } else if (rs == 0 && rt != 0) {
4253             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4254         } else if (rs != 0 && rt == 0) {
4255             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4256         } else {
4257             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4258         }
4259         break;
4260     case OPC_DSUB:
4261         {
4262             TCGv t0 = tcg_temp_local_new();
4263             TCGv t1 = tcg_temp_new();
4264             TCGv t2 = tcg_temp_new();
4265             TCGLabel *l1 = gen_new_label();
4266 
4267             gen_load_gpr(t1, rs);
4268             gen_load_gpr(t2, rt);
4269             tcg_gen_sub_tl(t0, t1, t2);
4270             tcg_gen_xor_tl(t2, t1, t2);
4271             tcg_gen_xor_tl(t1, t0, t1);
4272             tcg_gen_and_tl(t1, t1, t2);
4273             tcg_temp_free(t2);
4274             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4275             tcg_temp_free(t1);
4276             /*
4277              * Operands of different sign, first operand and result different
4278              * sign.
4279              */
4280             generate_exception(ctx, EXCP_OVERFLOW);
4281             gen_set_label(l1);
4282             gen_store_gpr(t0, rd);
4283             tcg_temp_free(t0);
4284         }
4285         break;
4286     case OPC_DSUBU:
4287         if (rs != 0 && rt != 0) {
4288             tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4289         } else if (rs == 0 && rt != 0) {
4290             tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4291         } else if (rs != 0 && rt == 0) {
4292             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4293         } else {
4294             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4295         }
4296         break;
4297 #endif
4298     case OPC_MUL:
4299         if (likely(rs != 0 && rt != 0)) {
4300             tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4301             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4302         } else {
4303             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4304         }
4305         break;
4306     }
4307 }
4308 
4309 /* Conditional move */
gen_cond_move(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)4310 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
4311                           int rd, int rs, int rt)
4312 {
4313     TCGv t0, t1, t2;
4314 
4315     if (rd == 0) {
4316         /* If no destination, treat it as a NOP. */
4317         return;
4318     }
4319 
4320     t0 = tcg_temp_new();
4321     gen_load_gpr(t0, rt);
4322     t1 = tcg_const_tl(0);
4323     t2 = tcg_temp_new();
4324     gen_load_gpr(t2, rs);
4325     switch (opc) {
4326     case OPC_MOVN:
4327         tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4328         break;
4329     case OPC_MOVZ:
4330         tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4331         break;
4332     case OPC_SELNEZ:
4333         tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
4334         break;
4335     case OPC_SELEQZ:
4336         tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
4337         break;
4338     }
4339     tcg_temp_free(t2);
4340     tcg_temp_free(t1);
4341     tcg_temp_free(t0);
4342 }
4343 
4344 /* Logic */
gen_logic(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)4345 static void gen_logic(DisasContext *ctx, uint32_t opc,
4346                       int rd, int rs, int rt)
4347 {
4348     if (rd == 0) {
4349         /* If no destination, treat it as a NOP. */
4350         return;
4351     }
4352 
4353     switch (opc) {
4354     case OPC_AND:
4355         if (likely(rs != 0 && rt != 0)) {
4356             tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4357         } else {
4358             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4359         }
4360         break;
4361     case OPC_NOR:
4362         if (rs != 0 && rt != 0) {
4363             tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4364         } else if (rs == 0 && rt != 0) {
4365             tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
4366         } else if (rs != 0 && rt == 0) {
4367             tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
4368         } else {
4369             tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
4370         }
4371         break;
4372     case OPC_OR:
4373         if (likely(rs != 0 && rt != 0)) {
4374             tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4375         } else if (rs == 0 && rt != 0) {
4376             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4377         } else if (rs != 0 && rt == 0) {
4378             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4379         } else {
4380             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4381         }
4382         break;
4383     case OPC_XOR:
4384         if (likely(rs != 0 && rt != 0)) {
4385             tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4386         } else if (rs == 0 && rt != 0) {
4387             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4388         } else if (rs != 0 && rt == 0) {
4389             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4390         } else {
4391             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4392         }
4393         break;
4394     }
4395 }
4396 
4397 /* Set on lower than */
gen_slt(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)4398 static void gen_slt(DisasContext *ctx, uint32_t opc,
4399                     int rd, int rs, int rt)
4400 {
4401     TCGv t0, t1;
4402 
4403     if (rd == 0) {
4404         /* If no destination, treat it as a NOP. */
4405         return;
4406     }
4407 
4408     t0 = tcg_temp_new();
4409     t1 = tcg_temp_new();
4410     gen_load_gpr(t0, rs);
4411     gen_load_gpr(t1, rt);
4412     switch (opc) {
4413     case OPC_SLT:
4414         tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
4415         break;
4416     case OPC_SLTU:
4417         tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
4418         break;
4419     }
4420     tcg_temp_free(t0);
4421     tcg_temp_free(t1);
4422 }
4423 
4424 /* Shifts */
gen_shift(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)4425 static void gen_shift(DisasContext *ctx, uint32_t opc,
4426                       int rd, int rs, int rt)
4427 {
4428     TCGv t0, t1;
4429 
4430     if (rd == 0) {
4431         /*
4432          * If no destination, treat it as a NOP.
4433          * For add & sub, we must generate the overflow exception when needed.
4434          */
4435         return;
4436     }
4437 
4438     t0 = tcg_temp_new();
4439     t1 = tcg_temp_new();
4440     gen_load_gpr(t0, rs);
4441     gen_load_gpr(t1, rt);
4442     switch (opc) {
4443     case OPC_SLLV:
4444         tcg_gen_andi_tl(t0, t0, 0x1f);
4445         tcg_gen_shl_tl(t0, t1, t0);
4446         tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4447         break;
4448     case OPC_SRAV:
4449         tcg_gen_andi_tl(t0, t0, 0x1f);
4450         tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4451         break;
4452     case OPC_SRLV:
4453         tcg_gen_ext32u_tl(t1, t1);
4454         tcg_gen_andi_tl(t0, t0, 0x1f);
4455         tcg_gen_shr_tl(t0, t1, t0);
4456         tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4457         break;
4458     case OPC_ROTRV:
4459         {
4460             TCGv_i32 t2 = tcg_temp_new_i32();
4461             TCGv_i32 t3 = tcg_temp_new_i32();
4462 
4463             tcg_gen_trunc_tl_i32(t2, t0);
4464             tcg_gen_trunc_tl_i32(t3, t1);
4465             tcg_gen_andi_i32(t2, t2, 0x1f);
4466             tcg_gen_rotr_i32(t2, t3, t2);
4467             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4468             tcg_temp_free_i32(t2);
4469             tcg_temp_free_i32(t3);
4470         }
4471         break;
4472 #if defined(TARGET_MIPS64)
4473     case OPC_DSLLV:
4474         tcg_gen_andi_tl(t0, t0, 0x3f);
4475         tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
4476         break;
4477     case OPC_DSRAV:
4478         tcg_gen_andi_tl(t0, t0, 0x3f);
4479         tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4480         break;
4481     case OPC_DSRLV:
4482         tcg_gen_andi_tl(t0, t0, 0x3f);
4483         tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
4484         break;
4485     case OPC_DROTRV:
4486         tcg_gen_andi_tl(t0, t0, 0x3f);
4487         tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
4488         break;
4489 #endif
4490     }
4491     tcg_temp_free(t0);
4492     tcg_temp_free(t1);
4493 }
4494 
4495 #if defined(TARGET_MIPS64)
4496 /* Copy GPR to and from TX79 HI1/LO1 register. */
gen_HILO1_tx79(DisasContext * ctx,uint32_t opc,int reg)4497 static void gen_HILO1_tx79(DisasContext *ctx, uint32_t opc, int reg)
4498 {
4499     if (reg == 0 && (opc == MMI_OPC_MFHI1 || opc == MMI_OPC_MFLO1)) {
4500         /* Treat as NOP. */
4501         return;
4502     }
4503 
4504     switch (opc) {
4505     case MMI_OPC_MFHI1:
4506         tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]);
4507         break;
4508     case MMI_OPC_MFLO1:
4509         tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[1]);
4510         break;
4511     case MMI_OPC_MTHI1:
4512         if (reg != 0) {
4513             tcg_gen_mov_tl(cpu_HI[1], cpu_gpr[reg]);
4514         } else {
4515             tcg_gen_movi_tl(cpu_HI[1], 0);
4516         }
4517         break;
4518     case MMI_OPC_MTLO1:
4519         if (reg != 0) {
4520             tcg_gen_mov_tl(cpu_LO[1], cpu_gpr[reg]);
4521         } else {
4522             tcg_gen_movi_tl(cpu_LO[1], 0);
4523         }
4524         break;
4525     default:
4526         MIPS_INVAL("mfthilo1 TX79");
4527         generate_exception_end(ctx, EXCP_RI);
4528         break;
4529     }
4530 }
4531 #endif
4532 
4533 /* Arithmetic on HI/LO registers */
gen_HILO(DisasContext * ctx,uint32_t opc,int acc,int reg)4534 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
4535 {
4536     if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
4537         /* Treat as NOP. */
4538         return;
4539     }
4540 
4541     if (acc != 0) {
4542         check_dsp(ctx);
4543     }
4544 
4545     switch (opc) {
4546     case OPC_MFHI:
4547 #if defined(TARGET_MIPS64)
4548         if (acc != 0) {
4549             tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
4550         } else
4551 #endif
4552         {
4553             tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
4554         }
4555         break;
4556     case OPC_MFLO:
4557 #if defined(TARGET_MIPS64)
4558         if (acc != 0) {
4559             tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
4560         } else
4561 #endif
4562         {
4563             tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
4564         }
4565         break;
4566     case OPC_MTHI:
4567         if (reg != 0) {
4568 #if defined(TARGET_MIPS64)
4569             if (acc != 0) {
4570                 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
4571             } else
4572 #endif
4573             {
4574                 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
4575             }
4576         } else {
4577             tcg_gen_movi_tl(cpu_HI[acc], 0);
4578         }
4579         break;
4580     case OPC_MTLO:
4581         if (reg != 0) {
4582 #if defined(TARGET_MIPS64)
4583             if (acc != 0) {
4584                 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
4585             } else
4586 #endif
4587             {
4588                 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
4589             }
4590         } else {
4591             tcg_gen_movi_tl(cpu_LO[acc], 0);
4592         }
4593         break;
4594     }
4595 }
4596 
gen_r6_ld(target_long addr,int reg,int memidx,MemOp memop)4597 static inline void gen_r6_ld(target_long addr, int reg, int memidx,
4598                              MemOp memop)
4599 {
4600     TCGv t0 = tcg_const_tl(addr);
4601     tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
4602     gen_store_gpr(t0, reg);
4603     tcg_temp_free(t0);
4604 }
4605 
gen_pcrel(DisasContext * ctx,int opc,target_ulong pc,int rs)4606 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
4607                              int rs)
4608 {
4609     target_long offset;
4610     target_long addr;
4611 
4612     switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
4613     case OPC_ADDIUPC:
4614         if (rs != 0) {
4615             offset = sextract32(ctx->opcode << 2, 0, 21);
4616             addr = addr_add(ctx, pc, offset);
4617             tcg_gen_movi_tl(cpu_gpr[rs], addr);
4618         }
4619         break;
4620     case R6_OPC_LWPC:
4621         offset = sextract32(ctx->opcode << 2, 0, 21);
4622         addr = addr_add(ctx, pc, offset);
4623         gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
4624         break;
4625 #if defined(TARGET_MIPS64)
4626     case OPC_LWUPC:
4627         check_mips_64(ctx);
4628         offset = sextract32(ctx->opcode << 2, 0, 21);
4629         addr = addr_add(ctx, pc, offset);
4630         gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
4631         break;
4632 #endif
4633     default:
4634         switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
4635         case OPC_AUIPC:
4636             if (rs != 0) {
4637                 offset = sextract32(ctx->opcode, 0, 16) << 16;
4638                 addr = addr_add(ctx, pc, offset);
4639                 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4640             }
4641             break;
4642         case OPC_ALUIPC:
4643             if (rs != 0) {
4644                 offset = sextract32(ctx->opcode, 0, 16) << 16;
4645                 addr = ~0xFFFF & addr_add(ctx, pc, offset);
4646                 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4647             }
4648             break;
4649 #if defined(TARGET_MIPS64)
4650         case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
4651         case R6_OPC_LDPC + (1 << 16):
4652         case R6_OPC_LDPC + (2 << 16):
4653         case R6_OPC_LDPC + (3 << 16):
4654             check_mips_64(ctx);
4655             offset = sextract32(ctx->opcode << 3, 0, 21);
4656             addr = addr_add(ctx, (pc & ~0x7), offset);
4657             gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
4658             break;
4659 #endif
4660         default:
4661             MIPS_INVAL("OPC_PCREL");
4662             generate_exception_end(ctx, EXCP_RI);
4663             break;
4664         }
4665         break;
4666     }
4667 }
4668 
gen_r6_muldiv(DisasContext * ctx,int opc,int rd,int rs,int rt)4669 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
4670 {
4671     TCGv t0, t1;
4672 
4673     if (rd == 0) {
4674         /* Treat as NOP. */
4675         return;
4676     }
4677 
4678     t0 = tcg_temp_new();
4679     t1 = tcg_temp_new();
4680 
4681     gen_load_gpr(t0, rs);
4682     gen_load_gpr(t1, rt);
4683 
4684     switch (opc) {
4685     case R6_OPC_DIV:
4686         {
4687             TCGv t2 = tcg_temp_new();
4688             TCGv t3 = tcg_temp_new();
4689             tcg_gen_ext32s_tl(t0, t0);
4690             tcg_gen_ext32s_tl(t1, t1);
4691             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4692             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4693             tcg_gen_and_tl(t2, t2, t3);
4694             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4695             tcg_gen_or_tl(t2, t2, t3);
4696             tcg_gen_movi_tl(t3, 0);
4697             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4698             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4699             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4700             tcg_temp_free(t3);
4701             tcg_temp_free(t2);
4702         }
4703         break;
4704     case R6_OPC_MOD:
4705         {
4706             TCGv t2 = tcg_temp_new();
4707             TCGv t3 = tcg_temp_new();
4708             tcg_gen_ext32s_tl(t0, t0);
4709             tcg_gen_ext32s_tl(t1, t1);
4710             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4711             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4712             tcg_gen_and_tl(t2, t2, t3);
4713             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4714             tcg_gen_or_tl(t2, t2, t3);
4715             tcg_gen_movi_tl(t3, 0);
4716             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4717             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4718             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4719             tcg_temp_free(t3);
4720             tcg_temp_free(t2);
4721         }
4722         break;
4723     case R6_OPC_DIVU:
4724         {
4725             TCGv t2 = tcg_const_tl(0);
4726             TCGv t3 = tcg_const_tl(1);
4727             tcg_gen_ext32u_tl(t0, t0);
4728             tcg_gen_ext32u_tl(t1, t1);
4729             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4730             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4731             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4732             tcg_temp_free(t3);
4733             tcg_temp_free(t2);
4734         }
4735         break;
4736     case R6_OPC_MODU:
4737         {
4738             TCGv t2 = tcg_const_tl(0);
4739             TCGv t3 = tcg_const_tl(1);
4740             tcg_gen_ext32u_tl(t0, t0);
4741             tcg_gen_ext32u_tl(t1, t1);
4742             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4743             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4744             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4745             tcg_temp_free(t3);
4746             tcg_temp_free(t2);
4747         }
4748         break;
4749     case R6_OPC_MUL:
4750         {
4751             TCGv_i32 t2 = tcg_temp_new_i32();
4752             TCGv_i32 t3 = tcg_temp_new_i32();
4753             tcg_gen_trunc_tl_i32(t2, t0);
4754             tcg_gen_trunc_tl_i32(t3, t1);
4755             tcg_gen_mul_i32(t2, t2, t3);
4756             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4757             tcg_temp_free_i32(t2);
4758             tcg_temp_free_i32(t3);
4759         }
4760         break;
4761     case R6_OPC_MUH:
4762         {
4763             TCGv_i32 t2 = tcg_temp_new_i32();
4764             TCGv_i32 t3 = tcg_temp_new_i32();
4765             tcg_gen_trunc_tl_i32(t2, t0);
4766             tcg_gen_trunc_tl_i32(t3, t1);
4767             tcg_gen_muls2_i32(t2, t3, t2, t3);
4768             tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4769             tcg_temp_free_i32(t2);
4770             tcg_temp_free_i32(t3);
4771         }
4772         break;
4773     case R6_OPC_MULU:
4774         {
4775             TCGv_i32 t2 = tcg_temp_new_i32();
4776             TCGv_i32 t3 = tcg_temp_new_i32();
4777             tcg_gen_trunc_tl_i32(t2, t0);
4778             tcg_gen_trunc_tl_i32(t3, t1);
4779             tcg_gen_mul_i32(t2, t2, t3);
4780             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4781             tcg_temp_free_i32(t2);
4782             tcg_temp_free_i32(t3);
4783         }
4784         break;
4785     case R6_OPC_MUHU:
4786         {
4787             TCGv_i32 t2 = tcg_temp_new_i32();
4788             TCGv_i32 t3 = tcg_temp_new_i32();
4789             tcg_gen_trunc_tl_i32(t2, t0);
4790             tcg_gen_trunc_tl_i32(t3, t1);
4791             tcg_gen_mulu2_i32(t2, t3, t2, t3);
4792             tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4793             tcg_temp_free_i32(t2);
4794             tcg_temp_free_i32(t3);
4795         }
4796         break;
4797 #if defined(TARGET_MIPS64)
4798     case R6_OPC_DDIV:
4799         {
4800             TCGv t2 = tcg_temp_new();
4801             TCGv t3 = tcg_temp_new();
4802             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4803             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4804             tcg_gen_and_tl(t2, t2, t3);
4805             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4806             tcg_gen_or_tl(t2, t2, t3);
4807             tcg_gen_movi_tl(t3, 0);
4808             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4809             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4810             tcg_temp_free(t3);
4811             tcg_temp_free(t2);
4812         }
4813         break;
4814     case R6_OPC_DMOD:
4815         {
4816             TCGv t2 = tcg_temp_new();
4817             TCGv t3 = tcg_temp_new();
4818             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4819             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4820             tcg_gen_and_tl(t2, t2, t3);
4821             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4822             tcg_gen_or_tl(t2, t2, t3);
4823             tcg_gen_movi_tl(t3, 0);
4824             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4825             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4826             tcg_temp_free(t3);
4827             tcg_temp_free(t2);
4828         }
4829         break;
4830     case R6_OPC_DDIVU:
4831         {
4832             TCGv t2 = tcg_const_tl(0);
4833             TCGv t3 = tcg_const_tl(1);
4834             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4835             tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
4836             tcg_temp_free(t3);
4837             tcg_temp_free(t2);
4838         }
4839         break;
4840     case R6_OPC_DMODU:
4841         {
4842             TCGv t2 = tcg_const_tl(0);
4843             TCGv t3 = tcg_const_tl(1);
4844             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4845             tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
4846             tcg_temp_free(t3);
4847             tcg_temp_free(t2);
4848         }
4849         break;
4850     case R6_OPC_DMUL:
4851         tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4852         break;
4853     case R6_OPC_DMUH:
4854         {
4855             TCGv t2 = tcg_temp_new();
4856             tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
4857             tcg_temp_free(t2);
4858         }
4859         break;
4860     case R6_OPC_DMULU:
4861         tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4862         break;
4863     case R6_OPC_DMUHU:
4864         {
4865             TCGv t2 = tcg_temp_new();
4866             tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
4867             tcg_temp_free(t2);
4868         }
4869         break;
4870 #endif
4871     default:
4872         MIPS_INVAL("r6 mul/div");
4873         generate_exception_end(ctx, EXCP_RI);
4874         goto out;
4875     }
4876  out:
4877     tcg_temp_free(t0);
4878     tcg_temp_free(t1);
4879 }
4880 
4881 #if defined(TARGET_MIPS64)
gen_div1_tx79(DisasContext * ctx,uint32_t opc,int rs,int rt)4882 static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
4883 {
4884     TCGv t0, t1;
4885 
4886     t0 = tcg_temp_new();
4887     t1 = tcg_temp_new();
4888 
4889     gen_load_gpr(t0, rs);
4890     gen_load_gpr(t1, rt);
4891 
4892     switch (opc) {
4893     case MMI_OPC_DIV1:
4894         {
4895             TCGv t2 = tcg_temp_new();
4896             TCGv t3 = tcg_temp_new();
4897             tcg_gen_ext32s_tl(t0, t0);
4898             tcg_gen_ext32s_tl(t1, t1);
4899             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4900             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4901             tcg_gen_and_tl(t2, t2, t3);
4902             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4903             tcg_gen_or_tl(t2, t2, t3);
4904             tcg_gen_movi_tl(t3, 0);
4905             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4906             tcg_gen_div_tl(cpu_LO[1], t0, t1);
4907             tcg_gen_rem_tl(cpu_HI[1], t0, t1);
4908             tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
4909             tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
4910             tcg_temp_free(t3);
4911             tcg_temp_free(t2);
4912         }
4913         break;
4914     case MMI_OPC_DIVU1:
4915         {
4916             TCGv t2 = tcg_const_tl(0);
4917             TCGv t3 = tcg_const_tl(1);
4918             tcg_gen_ext32u_tl(t0, t0);
4919             tcg_gen_ext32u_tl(t1, t1);
4920             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4921             tcg_gen_divu_tl(cpu_LO[1], t0, t1);
4922             tcg_gen_remu_tl(cpu_HI[1], t0, t1);
4923             tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
4924             tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
4925             tcg_temp_free(t3);
4926             tcg_temp_free(t2);
4927         }
4928         break;
4929     default:
4930         MIPS_INVAL("div1 TX79");
4931         generate_exception_end(ctx, EXCP_RI);
4932         goto out;
4933     }
4934  out:
4935     tcg_temp_free(t0);
4936     tcg_temp_free(t1);
4937 }
4938 #endif
4939 
gen_muldiv(DisasContext * ctx,uint32_t opc,int acc,int rs,int rt)4940 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
4941                        int acc, int rs, int rt)
4942 {
4943     TCGv t0, t1;
4944 
4945     t0 = tcg_temp_new();
4946     t1 = tcg_temp_new();
4947 
4948     gen_load_gpr(t0, rs);
4949     gen_load_gpr(t1, rt);
4950 
4951     if (acc != 0) {
4952         check_dsp(ctx);
4953     }
4954 
4955     switch (opc) {
4956     case OPC_DIV:
4957         {
4958             TCGv t2 = tcg_temp_new();
4959             TCGv t3 = tcg_temp_new();
4960             tcg_gen_ext32s_tl(t0, t0);
4961             tcg_gen_ext32s_tl(t1, t1);
4962             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4963             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4964             tcg_gen_and_tl(t2, t2, t3);
4965             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4966             tcg_gen_or_tl(t2, t2, t3);
4967             tcg_gen_movi_tl(t3, 0);
4968             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4969             tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4970             tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4971             tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4972             tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4973             tcg_temp_free(t3);
4974             tcg_temp_free(t2);
4975         }
4976         break;
4977     case OPC_DIVU:
4978         {
4979             TCGv t2 = tcg_const_tl(0);
4980             TCGv t3 = tcg_const_tl(1);
4981             tcg_gen_ext32u_tl(t0, t0);
4982             tcg_gen_ext32u_tl(t1, t1);
4983             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4984             tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
4985             tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
4986             tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4987             tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4988             tcg_temp_free(t3);
4989             tcg_temp_free(t2);
4990         }
4991         break;
4992     case OPC_MULT:
4993         {
4994             TCGv_i32 t2 = tcg_temp_new_i32();
4995             TCGv_i32 t3 = tcg_temp_new_i32();
4996             tcg_gen_trunc_tl_i32(t2, t0);
4997             tcg_gen_trunc_tl_i32(t3, t1);
4998             tcg_gen_muls2_i32(t2, t3, t2, t3);
4999             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
5000             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
5001             tcg_temp_free_i32(t2);
5002             tcg_temp_free_i32(t3);
5003         }
5004         break;
5005     case OPC_MULTU:
5006         {
5007             TCGv_i32 t2 = tcg_temp_new_i32();
5008             TCGv_i32 t3 = tcg_temp_new_i32();
5009             tcg_gen_trunc_tl_i32(t2, t0);
5010             tcg_gen_trunc_tl_i32(t3, t1);
5011             tcg_gen_mulu2_i32(t2, t3, t2, t3);
5012             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
5013             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
5014             tcg_temp_free_i32(t2);
5015             tcg_temp_free_i32(t3);
5016         }
5017         break;
5018 #if defined(TARGET_MIPS64)
5019     case OPC_DDIV:
5020         {
5021             TCGv t2 = tcg_temp_new();
5022             TCGv t3 = tcg_temp_new();
5023             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
5024             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
5025             tcg_gen_and_tl(t2, t2, t3);
5026             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
5027             tcg_gen_or_tl(t2, t2, t3);
5028             tcg_gen_movi_tl(t3, 0);
5029             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
5030             tcg_gen_div_tl(cpu_LO[acc], t0, t1);
5031             tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
5032             tcg_temp_free(t3);
5033             tcg_temp_free(t2);
5034         }
5035         break;
5036     case OPC_DDIVU:
5037         {
5038             TCGv t2 = tcg_const_tl(0);
5039             TCGv t3 = tcg_const_tl(1);
5040             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
5041             tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
5042             tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
5043             tcg_temp_free(t3);
5044             tcg_temp_free(t2);
5045         }
5046         break;
5047     case OPC_DMULT:
5048         tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
5049         break;
5050     case OPC_DMULTU:
5051         tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
5052         break;
5053 #endif
5054     case OPC_MADD:
5055         {
5056             TCGv_i64 t2 = tcg_temp_new_i64();
5057             TCGv_i64 t3 = tcg_temp_new_i64();
5058 
5059             tcg_gen_ext_tl_i64(t2, t0);
5060             tcg_gen_ext_tl_i64(t3, t1);
5061             tcg_gen_mul_i64(t2, t2, t3);
5062             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5063             tcg_gen_add_i64(t2, t2, t3);
5064             tcg_temp_free_i64(t3);
5065             gen_move_low32(cpu_LO[acc], t2);
5066             gen_move_high32(cpu_HI[acc], t2);
5067             tcg_temp_free_i64(t2);
5068         }
5069         break;
5070     case OPC_MADDU:
5071         {
5072             TCGv_i64 t2 = tcg_temp_new_i64();
5073             TCGv_i64 t3 = tcg_temp_new_i64();
5074 
5075             tcg_gen_ext32u_tl(t0, t0);
5076             tcg_gen_ext32u_tl(t1, t1);
5077             tcg_gen_extu_tl_i64(t2, t0);
5078             tcg_gen_extu_tl_i64(t3, t1);
5079             tcg_gen_mul_i64(t2, t2, t3);
5080             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5081             tcg_gen_add_i64(t2, t2, t3);
5082             tcg_temp_free_i64(t3);
5083             gen_move_low32(cpu_LO[acc], t2);
5084             gen_move_high32(cpu_HI[acc], t2);
5085             tcg_temp_free_i64(t2);
5086         }
5087         break;
5088     case OPC_MSUB:
5089         {
5090             TCGv_i64 t2 = tcg_temp_new_i64();
5091             TCGv_i64 t3 = tcg_temp_new_i64();
5092 
5093             tcg_gen_ext_tl_i64(t2, t0);
5094             tcg_gen_ext_tl_i64(t3, t1);
5095             tcg_gen_mul_i64(t2, t2, t3);
5096             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5097             tcg_gen_sub_i64(t2, t3, t2);
5098             tcg_temp_free_i64(t3);
5099             gen_move_low32(cpu_LO[acc], t2);
5100             gen_move_high32(cpu_HI[acc], t2);
5101             tcg_temp_free_i64(t2);
5102         }
5103         break;
5104     case OPC_MSUBU:
5105         {
5106             TCGv_i64 t2 = tcg_temp_new_i64();
5107             TCGv_i64 t3 = tcg_temp_new_i64();
5108 
5109             tcg_gen_ext32u_tl(t0, t0);
5110             tcg_gen_ext32u_tl(t1, t1);
5111             tcg_gen_extu_tl_i64(t2, t0);
5112             tcg_gen_extu_tl_i64(t3, t1);
5113             tcg_gen_mul_i64(t2, t2, t3);
5114             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5115             tcg_gen_sub_i64(t2, t3, t2);
5116             tcg_temp_free_i64(t3);
5117             gen_move_low32(cpu_LO[acc], t2);
5118             gen_move_high32(cpu_HI[acc], t2);
5119             tcg_temp_free_i64(t2);
5120         }
5121         break;
5122     default:
5123         MIPS_INVAL("mul/div");
5124         generate_exception_end(ctx, EXCP_RI);
5125         goto out;
5126     }
5127  out:
5128     tcg_temp_free(t0);
5129     tcg_temp_free(t1);
5130 }
5131 
5132 /*
5133  * These MULT[U] and MADD[U] instructions implemented in for example
5134  * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
5135  * architectures are special three-operand variants with the syntax
5136  *
5137  *     MULT[U][1] rd, rs, rt
5138  *
5139  * such that
5140  *
5141  *     (rd, LO, HI) <- rs * rt
5142  *
5143  * and
5144  *
5145  *     MADD[U][1] rd, rs, rt
5146  *
5147  * such that
5148  *
5149  *     (rd, LO, HI) <- (LO, HI) + rs * rt
5150  *
5151  * where the low-order 32-bits of the result is placed into both the
5152  * GPR rd and the special register LO. The high-order 32-bits of the
5153  * result is placed into the special register HI.
5154  *
5155  * If the GPR rd is omitted in assembly language, it is taken to be 0,
5156  * which is the zero register that always reads as 0.
5157  */
gen_mul_txx9(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)5158 static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
5159                          int rd, int rs, int rt)
5160 {
5161     TCGv t0 = tcg_temp_new();
5162     TCGv t1 = tcg_temp_new();
5163     int acc = 0;
5164 
5165     gen_load_gpr(t0, rs);
5166     gen_load_gpr(t1, rt);
5167 
5168     switch (opc) {
5169     case MMI_OPC_MULT1:
5170         acc = 1;
5171         /* Fall through */
5172     case OPC_MULT:
5173         {
5174             TCGv_i32 t2 = tcg_temp_new_i32();
5175             TCGv_i32 t3 = tcg_temp_new_i32();
5176             tcg_gen_trunc_tl_i32(t2, t0);
5177             tcg_gen_trunc_tl_i32(t3, t1);
5178             tcg_gen_muls2_i32(t2, t3, t2, t3);
5179             if (rd) {
5180                 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
5181             }
5182             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
5183             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
5184             tcg_temp_free_i32(t2);
5185             tcg_temp_free_i32(t3);
5186         }
5187         break;
5188     case MMI_OPC_MULTU1:
5189         acc = 1;
5190         /* Fall through */
5191     case OPC_MULTU:
5192         {
5193             TCGv_i32 t2 = tcg_temp_new_i32();
5194             TCGv_i32 t3 = tcg_temp_new_i32();
5195             tcg_gen_trunc_tl_i32(t2, t0);
5196             tcg_gen_trunc_tl_i32(t3, t1);
5197             tcg_gen_mulu2_i32(t2, t3, t2, t3);
5198             if (rd) {
5199                 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
5200             }
5201             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
5202             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
5203             tcg_temp_free_i32(t2);
5204             tcg_temp_free_i32(t3);
5205         }
5206         break;
5207     case MMI_OPC_MADD1:
5208         acc = 1;
5209         /* Fall through */
5210     case MMI_OPC_MADD:
5211         {
5212             TCGv_i64 t2 = tcg_temp_new_i64();
5213             TCGv_i64 t3 = tcg_temp_new_i64();
5214 
5215             tcg_gen_ext_tl_i64(t2, t0);
5216             tcg_gen_ext_tl_i64(t3, t1);
5217             tcg_gen_mul_i64(t2, t2, t3);
5218             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5219             tcg_gen_add_i64(t2, t2, t3);
5220             tcg_temp_free_i64(t3);
5221             gen_move_low32(cpu_LO[acc], t2);
5222             gen_move_high32(cpu_HI[acc], t2);
5223             if (rd) {
5224                 gen_move_low32(cpu_gpr[rd], t2);
5225             }
5226             tcg_temp_free_i64(t2);
5227         }
5228         break;
5229     case MMI_OPC_MADDU1:
5230         acc = 1;
5231         /* Fall through */
5232     case MMI_OPC_MADDU:
5233         {
5234             TCGv_i64 t2 = tcg_temp_new_i64();
5235             TCGv_i64 t3 = tcg_temp_new_i64();
5236 
5237             tcg_gen_ext32u_tl(t0, t0);
5238             tcg_gen_ext32u_tl(t1, t1);
5239             tcg_gen_extu_tl_i64(t2, t0);
5240             tcg_gen_extu_tl_i64(t3, t1);
5241             tcg_gen_mul_i64(t2, t2, t3);
5242             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5243             tcg_gen_add_i64(t2, t2, t3);
5244             tcg_temp_free_i64(t3);
5245             gen_move_low32(cpu_LO[acc], t2);
5246             gen_move_high32(cpu_HI[acc], t2);
5247             if (rd) {
5248                 gen_move_low32(cpu_gpr[rd], t2);
5249             }
5250             tcg_temp_free_i64(t2);
5251         }
5252         break;
5253     default:
5254         MIPS_INVAL("mul/madd TXx9");
5255         generate_exception_end(ctx, EXCP_RI);
5256         goto out;
5257     }
5258 
5259  out:
5260     tcg_temp_free(t0);
5261     tcg_temp_free(t1);
5262 }
5263 
gen_mul_vr54xx(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)5264 static void gen_mul_vr54xx(DisasContext *ctx, uint32_t opc,
5265                            int rd, int rs, int rt)
5266 {
5267     TCGv t0 = tcg_temp_new();
5268     TCGv t1 = tcg_temp_new();
5269 
5270     gen_load_gpr(t0, rs);
5271     gen_load_gpr(t1, rt);
5272 
5273     switch (opc) {
5274     case OPC_VR54XX_MULS:
5275         gen_helper_muls(t0, cpu_env, t0, t1);
5276         break;
5277     case OPC_VR54XX_MULSU:
5278         gen_helper_mulsu(t0, cpu_env, t0, t1);
5279         break;
5280     case OPC_VR54XX_MACC:
5281         gen_helper_macc(t0, cpu_env, t0, t1);
5282         break;
5283     case OPC_VR54XX_MACCU:
5284         gen_helper_maccu(t0, cpu_env, t0, t1);
5285         break;
5286     case OPC_VR54XX_MSAC:
5287         gen_helper_msac(t0, cpu_env, t0, t1);
5288         break;
5289     case OPC_VR54XX_MSACU:
5290         gen_helper_msacu(t0, cpu_env, t0, t1);
5291         break;
5292     case OPC_VR54XX_MULHI:
5293         gen_helper_mulhi(t0, cpu_env, t0, t1);
5294         break;
5295     case OPC_VR54XX_MULHIU:
5296         gen_helper_mulhiu(t0, cpu_env, t0, t1);
5297         break;
5298     case OPC_VR54XX_MULSHI:
5299         gen_helper_mulshi(t0, cpu_env, t0, t1);
5300         break;
5301     case OPC_VR54XX_MULSHIU:
5302         gen_helper_mulshiu(t0, cpu_env, t0, t1);
5303         break;
5304     case OPC_VR54XX_MACCHI:
5305         gen_helper_macchi(t0, cpu_env, t0, t1);
5306         break;
5307     case OPC_VR54XX_MACCHIU:
5308         gen_helper_macchiu(t0, cpu_env, t0, t1);
5309         break;
5310     case OPC_VR54XX_MSACHI:
5311         gen_helper_msachi(t0, cpu_env, t0, t1);
5312         break;
5313     case OPC_VR54XX_MSACHIU:
5314         gen_helper_msachiu(t0, cpu_env, t0, t1);
5315         break;
5316     default:
5317         MIPS_INVAL("mul vr54xx");
5318         generate_exception_end(ctx, EXCP_RI);
5319         goto out;
5320     }
5321     gen_store_gpr(t0, rd);
5322 
5323  out:
5324     tcg_temp_free(t0);
5325     tcg_temp_free(t1);
5326 }
5327 
gen_cl(DisasContext * ctx,uint32_t opc,int rd,int rs)5328 static void gen_cl(DisasContext *ctx, uint32_t opc,
5329                    int rd, int rs)
5330 {
5331     TCGv t0;
5332 
5333     if (rd == 0) {
5334         /* Treat as NOP. */
5335         return;
5336     }
5337     t0 = cpu_gpr[rd];
5338     gen_load_gpr(t0, rs);
5339 
5340     switch (opc) {
5341     case OPC_CLO:
5342     case R6_OPC_CLO:
5343 #if defined(TARGET_MIPS64)
5344     case OPC_DCLO:
5345     case R6_OPC_DCLO:
5346 #endif
5347         tcg_gen_not_tl(t0, t0);
5348         break;
5349     }
5350 
5351     switch (opc) {
5352     case OPC_CLO:
5353     case R6_OPC_CLO:
5354     case OPC_CLZ:
5355     case R6_OPC_CLZ:
5356         tcg_gen_ext32u_tl(t0, t0);
5357         tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
5358         tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
5359         break;
5360 #if defined(TARGET_MIPS64)
5361     case OPC_DCLO:
5362     case R6_OPC_DCLO:
5363     case OPC_DCLZ:
5364     case R6_OPC_DCLZ:
5365         tcg_gen_clzi_i64(t0, t0, 64);
5366         break;
5367 #endif
5368     }
5369 }
5370 
5371 /* Godson integer instructions */
gen_loongson_integer(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)5372 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
5373                                  int rd, int rs, int rt)
5374 {
5375     TCGv t0, t1;
5376 
5377     if (rd == 0) {
5378         /* Treat as NOP. */
5379         return;
5380     }
5381 
5382     switch (opc) {
5383     case OPC_MULT_G_2E:
5384     case OPC_MULT_G_2F:
5385     case OPC_MULTU_G_2E:
5386     case OPC_MULTU_G_2F:
5387 #if defined(TARGET_MIPS64)
5388     case OPC_DMULT_G_2E:
5389     case OPC_DMULT_G_2F:
5390     case OPC_DMULTU_G_2E:
5391     case OPC_DMULTU_G_2F:
5392 #endif
5393         t0 = tcg_temp_new();
5394         t1 = tcg_temp_new();
5395         break;
5396     default:
5397         t0 = tcg_temp_local_new();
5398         t1 = tcg_temp_local_new();
5399         break;
5400     }
5401 
5402     gen_load_gpr(t0, rs);
5403     gen_load_gpr(t1, rt);
5404 
5405     switch (opc) {
5406     case OPC_MULT_G_2E:
5407     case OPC_MULT_G_2F:
5408         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5409         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5410         break;
5411     case OPC_MULTU_G_2E:
5412     case OPC_MULTU_G_2F:
5413         tcg_gen_ext32u_tl(t0, t0);
5414         tcg_gen_ext32u_tl(t1, t1);
5415         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5416         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5417         break;
5418     case OPC_DIV_G_2E:
5419     case OPC_DIV_G_2F:
5420         {
5421             TCGLabel *l1 = gen_new_label();
5422             TCGLabel *l2 = gen_new_label();
5423             TCGLabel *l3 = gen_new_label();
5424             tcg_gen_ext32s_tl(t0, t0);
5425             tcg_gen_ext32s_tl(t1, t1);
5426             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5427             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5428             tcg_gen_br(l3);
5429             gen_set_label(l1);
5430             tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5431             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5432             tcg_gen_mov_tl(cpu_gpr[rd], t0);
5433             tcg_gen_br(l3);
5434             gen_set_label(l2);
5435             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5436             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5437             gen_set_label(l3);
5438         }
5439         break;
5440     case OPC_DIVU_G_2E:
5441     case OPC_DIVU_G_2F:
5442         {
5443             TCGLabel *l1 = gen_new_label();
5444             TCGLabel *l2 = gen_new_label();
5445             tcg_gen_ext32u_tl(t0, t0);
5446             tcg_gen_ext32u_tl(t1, t1);
5447             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5448             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5449             tcg_gen_br(l2);
5450             gen_set_label(l1);
5451             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5452             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5453             gen_set_label(l2);
5454         }
5455         break;
5456     case OPC_MOD_G_2E:
5457     case OPC_MOD_G_2F:
5458         {
5459             TCGLabel *l1 = gen_new_label();
5460             TCGLabel *l2 = gen_new_label();
5461             TCGLabel *l3 = gen_new_label();
5462             tcg_gen_ext32u_tl(t0, t0);
5463             tcg_gen_ext32u_tl(t1, t1);
5464             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5465             tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5466             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5467             gen_set_label(l1);
5468             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5469             tcg_gen_br(l3);
5470             gen_set_label(l2);
5471             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5472             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5473             gen_set_label(l3);
5474         }
5475         break;
5476     case OPC_MODU_G_2E:
5477     case OPC_MODU_G_2F:
5478         {
5479             TCGLabel *l1 = gen_new_label();
5480             TCGLabel *l2 = gen_new_label();
5481             tcg_gen_ext32u_tl(t0, t0);
5482             tcg_gen_ext32u_tl(t1, t1);
5483             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5484             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5485             tcg_gen_br(l2);
5486             gen_set_label(l1);
5487             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5488             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5489             gen_set_label(l2);
5490         }
5491         break;
5492 #if defined(TARGET_MIPS64)
5493     case OPC_DMULT_G_2E:
5494     case OPC_DMULT_G_2F:
5495         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5496         break;
5497     case OPC_DMULTU_G_2E:
5498     case OPC_DMULTU_G_2F:
5499         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5500         break;
5501     case OPC_DDIV_G_2E:
5502     case OPC_DDIV_G_2F:
5503         {
5504             TCGLabel *l1 = gen_new_label();
5505             TCGLabel *l2 = gen_new_label();
5506             TCGLabel *l3 = gen_new_label();
5507             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5508             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5509             tcg_gen_br(l3);
5510             gen_set_label(l1);
5511             tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5512             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5513             tcg_gen_mov_tl(cpu_gpr[rd], t0);
5514             tcg_gen_br(l3);
5515             gen_set_label(l2);
5516             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5517             gen_set_label(l3);
5518         }
5519         break;
5520     case OPC_DDIVU_G_2E:
5521     case OPC_DDIVU_G_2F:
5522         {
5523             TCGLabel *l1 = gen_new_label();
5524             TCGLabel *l2 = gen_new_label();
5525             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5526             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5527             tcg_gen_br(l2);
5528             gen_set_label(l1);
5529             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5530             gen_set_label(l2);
5531         }
5532         break;
5533     case OPC_DMOD_G_2E:
5534     case OPC_DMOD_G_2F:
5535         {
5536             TCGLabel *l1 = gen_new_label();
5537             TCGLabel *l2 = gen_new_label();
5538             TCGLabel *l3 = gen_new_label();
5539             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5540             tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5541             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5542             gen_set_label(l1);
5543             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5544             tcg_gen_br(l3);
5545             gen_set_label(l2);
5546             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5547             gen_set_label(l3);
5548         }
5549         break;
5550     case OPC_DMODU_G_2E:
5551     case OPC_DMODU_G_2F:
5552         {
5553             TCGLabel *l1 = gen_new_label();
5554             TCGLabel *l2 = gen_new_label();
5555             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5556             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5557             tcg_gen_br(l2);
5558             gen_set_label(l1);
5559             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5560             gen_set_label(l2);
5561         }
5562         break;
5563 #endif
5564     }
5565 
5566     tcg_temp_free(t0);
5567     tcg_temp_free(t1);
5568 }
5569 
5570 /* Loongson multimedia instructions */
gen_loongson_multimedia(DisasContext * ctx,int rd,int rs,int rt)5571 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
5572 {
5573     uint32_t opc, shift_max;
5574     TCGv_i64 t0, t1;
5575     TCGCond cond;
5576 
5577     opc = MASK_LMMI(ctx->opcode);
5578     switch (opc) {
5579     case OPC_ADD_CP2:
5580     case OPC_SUB_CP2:
5581     case OPC_DADD_CP2:
5582     case OPC_DSUB_CP2:
5583         t0 = tcg_temp_local_new_i64();
5584         t1 = tcg_temp_local_new_i64();
5585         break;
5586     default:
5587         t0 = tcg_temp_new_i64();
5588         t1 = tcg_temp_new_i64();
5589         break;
5590     }
5591 
5592     check_cp1_enabled(ctx);
5593     gen_load_fpr64(ctx, t0, rs);
5594     gen_load_fpr64(ctx, t1, rt);
5595 
5596     switch (opc) {
5597     case OPC_PADDSH:
5598         gen_helper_paddsh(t0, t0, t1);
5599         break;
5600     case OPC_PADDUSH:
5601         gen_helper_paddush(t0, t0, t1);
5602         break;
5603     case OPC_PADDH:
5604         gen_helper_paddh(t0, t0, t1);
5605         break;
5606     case OPC_PADDW:
5607         gen_helper_paddw(t0, t0, t1);
5608         break;
5609     case OPC_PADDSB:
5610         gen_helper_paddsb(t0, t0, t1);
5611         break;
5612     case OPC_PADDUSB:
5613         gen_helper_paddusb(t0, t0, t1);
5614         break;
5615     case OPC_PADDB:
5616         gen_helper_paddb(t0, t0, t1);
5617         break;
5618 
5619     case OPC_PSUBSH:
5620         gen_helper_psubsh(t0, t0, t1);
5621         break;
5622     case OPC_PSUBUSH:
5623         gen_helper_psubush(t0, t0, t1);
5624         break;
5625     case OPC_PSUBH:
5626         gen_helper_psubh(t0, t0, t1);
5627         break;
5628     case OPC_PSUBW:
5629         gen_helper_psubw(t0, t0, t1);
5630         break;
5631     case OPC_PSUBSB:
5632         gen_helper_psubsb(t0, t0, t1);
5633         break;
5634     case OPC_PSUBUSB:
5635         gen_helper_psubusb(t0, t0, t1);
5636         break;
5637     case OPC_PSUBB:
5638         gen_helper_psubb(t0, t0, t1);
5639         break;
5640 
5641     case OPC_PSHUFH:
5642         gen_helper_pshufh(t0, t0, t1);
5643         break;
5644     case OPC_PACKSSWH:
5645         gen_helper_packsswh(t0, t0, t1);
5646         break;
5647     case OPC_PACKSSHB:
5648         gen_helper_packsshb(t0, t0, t1);
5649         break;
5650     case OPC_PACKUSHB:
5651         gen_helper_packushb(t0, t0, t1);
5652         break;
5653 
5654     case OPC_PUNPCKLHW:
5655         gen_helper_punpcklhw(t0, t0, t1);
5656         break;
5657     case OPC_PUNPCKHHW:
5658         gen_helper_punpckhhw(t0, t0, t1);
5659         break;
5660     case OPC_PUNPCKLBH:
5661         gen_helper_punpcklbh(t0, t0, t1);
5662         break;
5663     case OPC_PUNPCKHBH:
5664         gen_helper_punpckhbh(t0, t0, t1);
5665         break;
5666     case OPC_PUNPCKLWD:
5667         gen_helper_punpcklwd(t0, t0, t1);
5668         break;
5669     case OPC_PUNPCKHWD:
5670         gen_helper_punpckhwd(t0, t0, t1);
5671         break;
5672 
5673     case OPC_PAVGH:
5674         gen_helper_pavgh(t0, t0, t1);
5675         break;
5676     case OPC_PAVGB:
5677         gen_helper_pavgb(t0, t0, t1);
5678         break;
5679     case OPC_PMAXSH:
5680         gen_helper_pmaxsh(t0, t0, t1);
5681         break;
5682     case OPC_PMINSH:
5683         gen_helper_pminsh(t0, t0, t1);
5684         break;
5685     case OPC_PMAXUB:
5686         gen_helper_pmaxub(t0, t0, t1);
5687         break;
5688     case OPC_PMINUB:
5689         gen_helper_pminub(t0, t0, t1);
5690         break;
5691 
5692     case OPC_PCMPEQW:
5693         gen_helper_pcmpeqw(t0, t0, t1);
5694         break;
5695     case OPC_PCMPGTW:
5696         gen_helper_pcmpgtw(t0, t0, t1);
5697         break;
5698     case OPC_PCMPEQH:
5699         gen_helper_pcmpeqh(t0, t0, t1);
5700         break;
5701     case OPC_PCMPGTH:
5702         gen_helper_pcmpgth(t0, t0, t1);
5703         break;
5704     case OPC_PCMPEQB:
5705         gen_helper_pcmpeqb(t0, t0, t1);
5706         break;
5707     case OPC_PCMPGTB:
5708         gen_helper_pcmpgtb(t0, t0, t1);
5709         break;
5710 
5711     case OPC_PSLLW:
5712         gen_helper_psllw(t0, t0, t1);
5713         break;
5714     case OPC_PSLLH:
5715         gen_helper_psllh(t0, t0, t1);
5716         break;
5717     case OPC_PSRLW:
5718         gen_helper_psrlw(t0, t0, t1);
5719         break;
5720     case OPC_PSRLH:
5721         gen_helper_psrlh(t0, t0, t1);
5722         break;
5723     case OPC_PSRAW:
5724         gen_helper_psraw(t0, t0, t1);
5725         break;
5726     case OPC_PSRAH:
5727         gen_helper_psrah(t0, t0, t1);
5728         break;
5729 
5730     case OPC_PMULLH:
5731         gen_helper_pmullh(t0, t0, t1);
5732         break;
5733     case OPC_PMULHH:
5734         gen_helper_pmulhh(t0, t0, t1);
5735         break;
5736     case OPC_PMULHUH:
5737         gen_helper_pmulhuh(t0, t0, t1);
5738         break;
5739     case OPC_PMADDHW:
5740         gen_helper_pmaddhw(t0, t0, t1);
5741         break;
5742 
5743     case OPC_PASUBUB:
5744         gen_helper_pasubub(t0, t0, t1);
5745         break;
5746     case OPC_BIADD:
5747         gen_helper_biadd(t0, t0);
5748         break;
5749     case OPC_PMOVMSKB:
5750         gen_helper_pmovmskb(t0, t0);
5751         break;
5752 
5753     case OPC_PADDD:
5754         tcg_gen_add_i64(t0, t0, t1);
5755         break;
5756     case OPC_PSUBD:
5757         tcg_gen_sub_i64(t0, t0, t1);
5758         break;
5759     case OPC_XOR_CP2:
5760         tcg_gen_xor_i64(t0, t0, t1);
5761         break;
5762     case OPC_NOR_CP2:
5763         tcg_gen_nor_i64(t0, t0, t1);
5764         break;
5765     case OPC_AND_CP2:
5766         tcg_gen_and_i64(t0, t0, t1);
5767         break;
5768     case OPC_OR_CP2:
5769         tcg_gen_or_i64(t0, t0, t1);
5770         break;
5771 
5772     case OPC_PANDN:
5773         tcg_gen_andc_i64(t0, t1, t0);
5774         break;
5775 
5776     case OPC_PINSRH_0:
5777         tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
5778         break;
5779     case OPC_PINSRH_1:
5780         tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
5781         break;
5782     case OPC_PINSRH_2:
5783         tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
5784         break;
5785     case OPC_PINSRH_3:
5786         tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
5787         break;
5788 
5789     case OPC_PEXTRH:
5790         tcg_gen_andi_i64(t1, t1, 3);
5791         tcg_gen_shli_i64(t1, t1, 4);
5792         tcg_gen_shr_i64(t0, t0, t1);
5793         tcg_gen_ext16u_i64(t0, t0);
5794         break;
5795 
5796     case OPC_ADDU_CP2:
5797         tcg_gen_add_i64(t0, t0, t1);
5798         tcg_gen_ext32s_i64(t0, t0);
5799         break;
5800     case OPC_SUBU_CP2:
5801         tcg_gen_sub_i64(t0, t0, t1);
5802         tcg_gen_ext32s_i64(t0, t0);
5803         break;
5804 
5805     case OPC_SLL_CP2:
5806         shift_max = 32;
5807         goto do_shift;
5808     case OPC_SRL_CP2:
5809         shift_max = 32;
5810         goto do_shift;
5811     case OPC_SRA_CP2:
5812         shift_max = 32;
5813         goto do_shift;
5814     case OPC_DSLL_CP2:
5815         shift_max = 64;
5816         goto do_shift;
5817     case OPC_DSRL_CP2:
5818         shift_max = 64;
5819         goto do_shift;
5820     case OPC_DSRA_CP2:
5821         shift_max = 64;
5822         goto do_shift;
5823     do_shift:
5824         /* Make sure shift count isn't TCG undefined behaviour.  */
5825         tcg_gen_andi_i64(t1, t1, shift_max - 1);
5826 
5827         switch (opc) {
5828         case OPC_SLL_CP2:
5829         case OPC_DSLL_CP2:
5830             tcg_gen_shl_i64(t0, t0, t1);
5831             break;
5832         case OPC_SRA_CP2:
5833         case OPC_DSRA_CP2:
5834             /*
5835              * Since SRA is UndefinedResult without sign-extended inputs,
5836              * we can treat SRA and DSRA the same.
5837              */
5838             tcg_gen_sar_i64(t0, t0, t1);
5839             break;
5840         case OPC_SRL_CP2:
5841             /* We want to shift in zeros for SRL; zero-extend first.  */
5842             tcg_gen_ext32u_i64(t0, t0);
5843             /* FALLTHRU */
5844         case OPC_DSRL_CP2:
5845             tcg_gen_shr_i64(t0, t0, t1);
5846             break;
5847         }
5848 
5849         if (shift_max == 32) {
5850             tcg_gen_ext32s_i64(t0, t0);
5851         }
5852 
5853         /* Shifts larger than MAX produce zero.  */
5854         tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
5855         tcg_gen_neg_i64(t1, t1);
5856         tcg_gen_and_i64(t0, t0, t1);
5857         break;
5858 
5859     case OPC_ADD_CP2:
5860     case OPC_DADD_CP2:
5861         {
5862             TCGv_i64 t2 = tcg_temp_new_i64();
5863             TCGLabel *lab = gen_new_label();
5864 
5865             tcg_gen_mov_i64(t2, t0);
5866             tcg_gen_add_i64(t0, t1, t2);
5867             if (opc == OPC_ADD_CP2) {
5868                 tcg_gen_ext32s_i64(t0, t0);
5869             }
5870             tcg_gen_xor_i64(t1, t1, t2);
5871             tcg_gen_xor_i64(t2, t2, t0);
5872             tcg_gen_andc_i64(t1, t2, t1);
5873             tcg_temp_free_i64(t2);
5874             tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5875             generate_exception(ctx, EXCP_OVERFLOW);
5876             gen_set_label(lab);
5877             break;
5878         }
5879 
5880     case OPC_SUB_CP2:
5881     case OPC_DSUB_CP2:
5882         {
5883             TCGv_i64 t2 = tcg_temp_new_i64();
5884             TCGLabel *lab = gen_new_label();
5885 
5886             tcg_gen_mov_i64(t2, t0);
5887             tcg_gen_sub_i64(t0, t1, t2);
5888             if (opc == OPC_SUB_CP2) {
5889                 tcg_gen_ext32s_i64(t0, t0);
5890             }
5891             tcg_gen_xor_i64(t1, t1, t2);
5892             tcg_gen_xor_i64(t2, t2, t0);
5893             tcg_gen_and_i64(t1, t1, t2);
5894             tcg_temp_free_i64(t2);
5895             tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5896             generate_exception(ctx, EXCP_OVERFLOW);
5897             gen_set_label(lab);
5898             break;
5899         }
5900 
5901     case OPC_PMULUW:
5902         tcg_gen_ext32u_i64(t0, t0);
5903         tcg_gen_ext32u_i64(t1, t1);
5904         tcg_gen_mul_i64(t0, t0, t1);
5905         break;
5906 
5907     case OPC_SEQU_CP2:
5908     case OPC_SEQ_CP2:
5909         cond = TCG_COND_EQ;
5910         goto do_cc_cond;
5911         break;
5912     case OPC_SLTU_CP2:
5913         cond = TCG_COND_LTU;
5914         goto do_cc_cond;
5915         break;
5916     case OPC_SLT_CP2:
5917         cond = TCG_COND_LT;
5918         goto do_cc_cond;
5919         break;
5920     case OPC_SLEU_CP2:
5921         cond = TCG_COND_LEU;
5922         goto do_cc_cond;
5923         break;
5924     case OPC_SLE_CP2:
5925         cond = TCG_COND_LE;
5926     do_cc_cond:
5927         {
5928             int cc = (ctx->opcode >> 8) & 0x7;
5929             TCGv_i64 t64 = tcg_temp_new_i64();
5930             TCGv_i32 t32 = tcg_temp_new_i32();
5931 
5932             tcg_gen_setcond_i64(cond, t64, t0, t1);
5933             tcg_gen_extrl_i64_i32(t32, t64);
5934             tcg_gen_deposit_i32(fpu_fcr31, fpu_fcr31, t32,
5935                                 get_fp_bit(cc), 1);
5936 
5937             tcg_temp_free_i32(t32);
5938             tcg_temp_free_i64(t64);
5939         }
5940         goto no_rd;
5941         break;
5942     default:
5943         MIPS_INVAL("loongson_cp2");
5944         generate_exception_end(ctx, EXCP_RI);
5945         return;
5946     }
5947 
5948     gen_store_fpr64(ctx, t0, rd);
5949 
5950 no_rd:
5951     tcg_temp_free_i64(t0);
5952     tcg_temp_free_i64(t1);
5953 }
5954 
gen_loongson_lswc2(DisasContext * ctx,int rt,int rs,int rd)5955 static void gen_loongson_lswc2(DisasContext *ctx, int rt,
5956                                int rs, int rd)
5957 {
5958     TCGv t0, t1, t2;
5959     TCGv_i32 fp0;
5960 #if defined(TARGET_MIPS64)
5961     int lsq_rt1 = ctx->opcode & 0x1f;
5962     int lsq_offset = sextract32(ctx->opcode, 6, 9) << 4;
5963 #endif
5964     int shf_offset = sextract32(ctx->opcode, 6, 8);
5965 
5966     t0 = tcg_temp_new();
5967 
5968     switch (MASK_LOONGSON_GSLSQ(ctx->opcode)) {
5969 #if defined(TARGET_MIPS64)
5970     case OPC_GSLQ:
5971         t1 = tcg_temp_new();
5972         gen_base_offset_addr(ctx, t0, rs, lsq_offset);
5973         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ |
5974                            ctx->default_tcg_memop_mask);
5975         gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
5976         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
5977                            ctx->default_tcg_memop_mask);
5978         gen_store_gpr(t1, rt);
5979         gen_store_gpr(t0, lsq_rt1);
5980         tcg_temp_free(t1);
5981         break;
5982     case OPC_GSLQC1:
5983         check_cp1_enabled(ctx);
5984         t1 = tcg_temp_new();
5985         gen_base_offset_addr(ctx, t0, rs, lsq_offset);
5986         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ |
5987                            ctx->default_tcg_memop_mask);
5988         gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
5989         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
5990                            ctx->default_tcg_memop_mask);
5991         gen_store_fpr64(ctx, t1, rt);
5992         gen_store_fpr64(ctx, t0, lsq_rt1);
5993         tcg_temp_free(t1);
5994         break;
5995     case OPC_GSSQ:
5996         t1 = tcg_temp_new();
5997         gen_base_offset_addr(ctx, t0, rs, lsq_offset);
5998         gen_load_gpr(t1, rt);
5999         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
6000                            ctx->default_tcg_memop_mask);
6001         gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
6002         gen_load_gpr(t1, lsq_rt1);
6003         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
6004                            ctx->default_tcg_memop_mask);
6005         tcg_temp_free(t1);
6006         break;
6007     case OPC_GSSQC1:
6008         check_cp1_enabled(ctx);
6009         t1 = tcg_temp_new();
6010         gen_base_offset_addr(ctx, t0, rs, lsq_offset);
6011         gen_load_fpr64(ctx, t1, rt);
6012         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
6013                            ctx->default_tcg_memop_mask);
6014         gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
6015         gen_load_fpr64(ctx, t1, lsq_rt1);
6016         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
6017                            ctx->default_tcg_memop_mask);
6018         tcg_temp_free(t1);
6019         break;
6020 #endif
6021     case OPC_GSSHFL:
6022         switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
6023         case OPC_GSLWLC1:
6024             check_cp1_enabled(ctx);
6025             gen_base_offset_addr(ctx, t0, rs, shf_offset);
6026             t1 = tcg_temp_new();
6027             tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
6028             tcg_gen_andi_tl(t1, t0, 3);
6029 #ifndef TARGET_WORDS_BIGENDIAN
6030             tcg_gen_xori_tl(t1, t1, 3);
6031 #endif
6032             tcg_gen_shli_tl(t1, t1, 3);
6033             tcg_gen_andi_tl(t0, t0, ~3);
6034             tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
6035             tcg_gen_shl_tl(t0, t0, t1);
6036             t2 = tcg_const_tl(-1);
6037             tcg_gen_shl_tl(t2, t2, t1);
6038             fp0 = tcg_temp_new_i32();
6039             gen_load_fpr32(ctx, fp0, rt);
6040             tcg_gen_ext_i32_tl(t1, fp0);
6041             tcg_gen_andc_tl(t1, t1, t2);
6042             tcg_temp_free(t2);
6043             tcg_gen_or_tl(t0, t0, t1);
6044             tcg_temp_free(t1);
6045 #if defined(TARGET_MIPS64)
6046             tcg_gen_extrl_i64_i32(fp0, t0);
6047 #else
6048             tcg_gen_ext32s_tl(fp0, t0);
6049 #endif
6050             gen_store_fpr32(ctx, fp0, rt);
6051             tcg_temp_free_i32(fp0);
6052             break;
6053         case OPC_GSLWRC1:
6054             check_cp1_enabled(ctx);
6055             gen_base_offset_addr(ctx, t0, rs, shf_offset);
6056             t1 = tcg_temp_new();
6057             tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
6058             tcg_gen_andi_tl(t1, t0, 3);
6059 #ifdef TARGET_WORDS_BIGENDIAN
6060             tcg_gen_xori_tl(t1, t1, 3);
6061 #endif
6062             tcg_gen_shli_tl(t1, t1, 3);
6063             tcg_gen_andi_tl(t0, t0, ~3);
6064             tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
6065             tcg_gen_shr_tl(t0, t0, t1);
6066             tcg_gen_xori_tl(t1, t1, 31);
6067             t2 = tcg_const_tl(0xfffffffeull);
6068             tcg_gen_shl_tl(t2, t2, t1);
6069             fp0 = tcg_temp_new_i32();
6070             gen_load_fpr32(ctx, fp0, rt);
6071             tcg_gen_ext_i32_tl(t1, fp0);
6072             tcg_gen_and_tl(t1, t1, t2);
6073             tcg_temp_free(t2);
6074             tcg_gen_or_tl(t0, t0, t1);
6075             tcg_temp_free(t1);
6076 #if defined(TARGET_MIPS64)
6077             tcg_gen_extrl_i64_i32(fp0, t0);
6078 #else
6079             tcg_gen_ext32s_tl(fp0, t0);
6080 #endif
6081             gen_store_fpr32(ctx, fp0, rt);
6082             tcg_temp_free_i32(fp0);
6083             break;
6084 #if defined(TARGET_MIPS64)
6085         case OPC_GSLDLC1:
6086             check_cp1_enabled(ctx);
6087             gen_base_offset_addr(ctx, t0, rs, shf_offset);
6088             t1 = tcg_temp_new();
6089             tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
6090             tcg_gen_andi_tl(t1, t0, 7);
6091 #ifndef TARGET_WORDS_BIGENDIAN
6092             tcg_gen_xori_tl(t1, t1, 7);
6093 #endif
6094             tcg_gen_shli_tl(t1, t1, 3);
6095             tcg_gen_andi_tl(t0, t0, ~7);
6096             tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
6097             tcg_gen_shl_tl(t0, t0, t1);
6098             t2 = tcg_const_tl(-1);
6099             tcg_gen_shl_tl(t2, t2, t1);
6100             gen_load_fpr64(ctx, t1, rt);
6101             tcg_gen_andc_tl(t1, t1, t2);
6102             tcg_temp_free(t2);
6103             tcg_gen_or_tl(t0, t0, t1);
6104             tcg_temp_free(t1);
6105             gen_store_fpr64(ctx, t0, rt);
6106             break;
6107         case OPC_GSLDRC1:
6108             check_cp1_enabled(ctx);
6109             gen_base_offset_addr(ctx, t0, rs, shf_offset);
6110             t1 = tcg_temp_new();
6111             tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
6112             tcg_gen_andi_tl(t1, t0, 7);
6113 #ifdef TARGET_WORDS_BIGENDIAN
6114             tcg_gen_xori_tl(t1, t1, 7);
6115 #endif
6116             tcg_gen_shli_tl(t1, t1, 3);
6117             tcg_gen_andi_tl(t0, t0, ~7);
6118             tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
6119             tcg_gen_shr_tl(t0, t0, t1);
6120             tcg_gen_xori_tl(t1, t1, 63);
6121             t2 = tcg_const_tl(0xfffffffffffffffeull);
6122             tcg_gen_shl_tl(t2, t2, t1);
6123             gen_load_fpr64(ctx, t1, rt);
6124             tcg_gen_and_tl(t1, t1, t2);
6125             tcg_temp_free(t2);
6126             tcg_gen_or_tl(t0, t0, t1);
6127             tcg_temp_free(t1);
6128             gen_store_fpr64(ctx, t0, rt);
6129             break;
6130 #endif
6131         default:
6132             MIPS_INVAL("loongson_gsshfl");
6133             generate_exception_end(ctx, EXCP_RI);
6134             break;
6135         }
6136         break;
6137     case OPC_GSSHFS:
6138         switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
6139         case OPC_GSSWLC1:
6140             check_cp1_enabled(ctx);
6141             t1 = tcg_temp_new();
6142             gen_base_offset_addr(ctx, t0, rs, shf_offset);
6143             fp0 = tcg_temp_new_i32();
6144             gen_load_fpr32(ctx, fp0, rt);
6145             tcg_gen_ext_i32_tl(t1, fp0);
6146             gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
6147             tcg_temp_free_i32(fp0);
6148             tcg_temp_free(t1);
6149             break;
6150         case OPC_GSSWRC1:
6151             check_cp1_enabled(ctx);
6152             t1 = tcg_temp_new();
6153             gen_base_offset_addr(ctx, t0, rs, shf_offset);
6154             fp0 = tcg_temp_new_i32();
6155             gen_load_fpr32(ctx, fp0, rt);
6156             tcg_gen_ext_i32_tl(t1, fp0);
6157             gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
6158             tcg_temp_free_i32(fp0);
6159             tcg_temp_free(t1);
6160             break;
6161 #if defined(TARGET_MIPS64)
6162         case OPC_GSSDLC1:
6163             check_cp1_enabled(ctx);
6164             t1 = tcg_temp_new();
6165             gen_base_offset_addr(ctx, t0, rs, shf_offset);
6166             gen_load_fpr64(ctx, t1, rt);
6167             gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
6168             tcg_temp_free(t1);
6169             break;
6170         case OPC_GSSDRC1:
6171             check_cp1_enabled(ctx);
6172             t1 = tcg_temp_new();
6173             gen_base_offset_addr(ctx, t0, rs, shf_offset);
6174             gen_load_fpr64(ctx, t1, rt);
6175             gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
6176             tcg_temp_free(t1);
6177             break;
6178 #endif
6179         default:
6180             MIPS_INVAL("loongson_gsshfs");
6181             generate_exception_end(ctx, EXCP_RI);
6182             break;
6183         }
6184         break;
6185     default:
6186         MIPS_INVAL("loongson_gslsq");
6187         generate_exception_end(ctx, EXCP_RI);
6188         break;
6189     }
6190     tcg_temp_free(t0);
6191 }
6192 
6193 /* Loongson EXT LDC2/SDC2 */
gen_loongson_lsdc2(DisasContext * ctx,int rt,int rs,int rd)6194 static void gen_loongson_lsdc2(DisasContext *ctx, int rt,
6195                                int rs, int rd)
6196 {
6197     int offset = sextract32(ctx->opcode, 3, 8);
6198     uint32_t opc = MASK_LOONGSON_LSDC2(ctx->opcode);
6199     TCGv t0, t1;
6200     TCGv_i32 fp0;
6201 
6202     /* Pre-conditions */
6203     switch (opc) {
6204     case OPC_GSLBX:
6205     case OPC_GSLHX:
6206     case OPC_GSLWX:
6207     case OPC_GSLDX:
6208         /* prefetch, implement as NOP */
6209         if (rt == 0) {
6210             return;
6211         }
6212         break;
6213     case OPC_GSSBX:
6214     case OPC_GSSHX:
6215     case OPC_GSSWX:
6216     case OPC_GSSDX:
6217         break;
6218     case OPC_GSLWXC1:
6219 #if defined(TARGET_MIPS64)
6220     case OPC_GSLDXC1:
6221 #endif
6222         check_cp1_enabled(ctx);
6223         /* prefetch, implement as NOP */
6224         if (rt == 0) {
6225             return;
6226         }
6227         break;
6228     case OPC_GSSWXC1:
6229 #if defined(TARGET_MIPS64)
6230     case OPC_GSSDXC1:
6231 #endif
6232         check_cp1_enabled(ctx);
6233         break;
6234     default:
6235         MIPS_INVAL("loongson_lsdc2");
6236         generate_exception_end(ctx, EXCP_RI);
6237         return;
6238         break;
6239     }
6240 
6241     t0 = tcg_temp_new();
6242 
6243     gen_base_offset_addr(ctx, t0, rs, offset);
6244     gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
6245 
6246     switch (opc) {
6247     case OPC_GSLBX:
6248         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
6249         gen_store_gpr(t0, rt);
6250         break;
6251     case OPC_GSLHX:
6252         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
6253                            ctx->default_tcg_memop_mask);
6254         gen_store_gpr(t0, rt);
6255         break;
6256     case OPC_GSLWX:
6257         gen_base_offset_addr(ctx, t0, rs, offset);
6258         if (rd) {
6259             gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
6260         }
6261         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
6262                            ctx->default_tcg_memop_mask);
6263         gen_store_gpr(t0, rt);
6264         break;
6265 #if defined(TARGET_MIPS64)
6266     case OPC_GSLDX:
6267         gen_base_offset_addr(ctx, t0, rs, offset);
6268         if (rd) {
6269             gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
6270         }
6271         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
6272                            ctx->default_tcg_memop_mask);
6273         gen_store_gpr(t0, rt);
6274         break;
6275 #endif
6276     case OPC_GSLWXC1:
6277         check_cp1_enabled(ctx);
6278         gen_base_offset_addr(ctx, t0, rs, offset);
6279         if (rd) {
6280             gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
6281         }
6282         fp0 = tcg_temp_new_i32();
6283         tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
6284                             ctx->default_tcg_memop_mask);
6285         gen_store_fpr32(ctx, fp0, rt);
6286         tcg_temp_free_i32(fp0);
6287         break;
6288 #if defined(TARGET_MIPS64)
6289     case OPC_GSLDXC1:
6290         check_cp1_enabled(ctx);
6291         gen_base_offset_addr(ctx, t0, rs, offset);
6292         if (rd) {
6293             gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
6294         }
6295         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
6296                            ctx->default_tcg_memop_mask);
6297         gen_store_fpr64(ctx, t0, rt);
6298         break;
6299 #endif
6300     case OPC_GSSBX:
6301         t1 = tcg_temp_new();
6302         gen_load_gpr(t1, rt);
6303         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_SB);
6304         tcg_temp_free(t1);
6305         break;
6306     case OPC_GSSHX:
6307         t1 = tcg_temp_new();
6308         gen_load_gpr(t1, rt);
6309         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
6310                            ctx->default_tcg_memop_mask);
6311         tcg_temp_free(t1);
6312         break;
6313     case OPC_GSSWX:
6314         t1 = tcg_temp_new();
6315         gen_load_gpr(t1, rt);
6316         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
6317                            ctx->default_tcg_memop_mask);
6318         tcg_temp_free(t1);
6319         break;
6320 #if defined(TARGET_MIPS64)
6321     case OPC_GSSDX:
6322         t1 = tcg_temp_new();
6323         gen_load_gpr(t1, rt);
6324         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
6325                            ctx->default_tcg_memop_mask);
6326         tcg_temp_free(t1);
6327         break;
6328 #endif
6329     case OPC_GSSWXC1:
6330         fp0 = tcg_temp_new_i32();
6331         gen_load_fpr32(ctx, fp0, rt);
6332         tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
6333                             ctx->default_tcg_memop_mask);
6334         tcg_temp_free_i32(fp0);
6335         break;
6336 #if defined(TARGET_MIPS64)
6337     case OPC_GSSDXC1:
6338         t1 = tcg_temp_new();
6339         gen_load_fpr64(ctx, t1, rt);
6340         tcg_gen_qemu_st_i64(t1, t0, ctx->mem_idx, MO_TEQ |
6341                             ctx->default_tcg_memop_mask);
6342         tcg_temp_free(t1);
6343         break;
6344 #endif
6345     default:
6346         break;
6347     }
6348 
6349     tcg_temp_free(t0);
6350 }
6351 
6352 /* Traps */
gen_trap(DisasContext * ctx,uint32_t opc,int rs,int rt,int16_t imm)6353 static void gen_trap(DisasContext *ctx, uint32_t opc,
6354                      int rs, int rt, int16_t imm)
6355 {
6356     int cond;
6357     TCGv t0 = tcg_temp_new();
6358     TCGv t1 = tcg_temp_new();
6359 
6360     cond = 0;
6361     /* Load needed operands */
6362     switch (opc) {
6363     case OPC_TEQ:
6364     case OPC_TGE:
6365     case OPC_TGEU:
6366     case OPC_TLT:
6367     case OPC_TLTU:
6368     case OPC_TNE:
6369         /* Compare two registers */
6370         if (rs != rt) {
6371             gen_load_gpr(t0, rs);
6372             gen_load_gpr(t1, rt);
6373             cond = 1;
6374         }
6375         break;
6376     case OPC_TEQI:
6377     case OPC_TGEI:
6378     case OPC_TGEIU:
6379     case OPC_TLTI:
6380     case OPC_TLTIU:
6381     case OPC_TNEI:
6382         /* Compare register to immediate */
6383         if (rs != 0 || imm != 0) {
6384             gen_load_gpr(t0, rs);
6385             tcg_gen_movi_tl(t1, (int32_t)imm);
6386             cond = 1;
6387         }
6388         break;
6389     }
6390     if (cond == 0) {
6391         switch (opc) {
6392         case OPC_TEQ:   /* rs == rs */
6393         case OPC_TEQI:  /* r0 == 0  */
6394         case OPC_TGE:   /* rs >= rs */
6395         case OPC_TGEI:  /* r0 >= 0  */
6396         case OPC_TGEU:  /* rs >= rs unsigned */
6397         case OPC_TGEIU: /* r0 >= 0  unsigned */
6398             /* Always trap */
6399             generate_exception_end(ctx, EXCP_TRAP);
6400             break;
6401         case OPC_TLT:   /* rs < rs           */
6402         case OPC_TLTI:  /* r0 < 0            */
6403         case OPC_TLTU:  /* rs < rs unsigned  */
6404         case OPC_TLTIU: /* r0 < 0  unsigned  */
6405         case OPC_TNE:   /* rs != rs          */
6406         case OPC_TNEI:  /* r0 != 0           */
6407             /* Never trap: treat as NOP. */
6408             break;
6409         }
6410     } else {
6411         TCGLabel *l1 = gen_new_label();
6412 
6413         switch (opc) {
6414         case OPC_TEQ:
6415         case OPC_TEQI:
6416             tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6417             break;
6418         case OPC_TGE:
6419         case OPC_TGEI:
6420             tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6421             break;
6422         case OPC_TGEU:
6423         case OPC_TGEIU:
6424             tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6425             break;
6426         case OPC_TLT:
6427         case OPC_TLTI:
6428             tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6429             break;
6430         case OPC_TLTU:
6431         case OPC_TLTIU:
6432             tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6433             break;
6434         case OPC_TNE:
6435         case OPC_TNEI:
6436             tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6437             break;
6438         }
6439         generate_exception(ctx, EXCP_TRAP);
6440         gen_set_label(l1);
6441     }
6442     tcg_temp_free(t0);
6443     tcg_temp_free(t1);
6444 }
6445 
use_goto_tb(DisasContext * ctx,target_ulong dest)6446 static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
6447 {
6448     if (unlikely(ctx->base.singlestep_enabled)) {
6449         return false;
6450     }
6451 
6452 #ifndef CONFIG_USER_ONLY
6453     return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
6454 #else
6455     return true;
6456 #endif
6457 }
6458 
gen_goto_tb(DisasContext * ctx,int n,target_ulong dest)6459 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
6460 {
6461     if (use_goto_tb(ctx, dest)) {
6462         tcg_gen_goto_tb(n);
6463         gen_save_pc(dest);
6464         tcg_gen_exit_tb(ctx->base.tb, n);
6465     } else {
6466         gen_save_pc(dest);
6467         if (ctx->base.singlestep_enabled) {
6468             save_cpu_state(ctx, 0);
6469             gen_helper_raise_exception_debug(cpu_env);
6470         }
6471         tcg_gen_lookup_and_goto_ptr();
6472     }
6473 }
6474 
6475 /* Branches (before delay slot) */
gen_compute_branch(DisasContext * ctx,uint32_t opc,int insn_bytes,int rs,int rt,int32_t offset,int delayslot_size)6476 static void gen_compute_branch(DisasContext *ctx, uint32_t opc,
6477                                int insn_bytes,
6478                                int rs, int rt, int32_t offset,
6479                                int delayslot_size)
6480 {
6481     target_ulong btgt = -1;
6482     int blink = 0;
6483     int bcond_compute = 0;
6484     TCGv t0 = tcg_temp_new();
6485     TCGv t1 = tcg_temp_new();
6486 
6487     if (ctx->hflags & MIPS_HFLAG_BMASK) {
6488 #ifdef MIPS_DEBUG_DISAS
6489         LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
6490                   TARGET_FMT_lx "\n", ctx->base.pc_next);
6491 #endif
6492         generate_exception_end(ctx, EXCP_RI);
6493         goto out;
6494     }
6495 
6496     /* Load needed operands */
6497     switch (opc) {
6498     case OPC_BEQ:
6499     case OPC_BEQL:
6500     case OPC_BNE:
6501     case OPC_BNEL:
6502         /* Compare two registers */
6503         if (rs != rt) {
6504             gen_load_gpr(t0, rs);
6505             gen_load_gpr(t1, rt);
6506             bcond_compute = 1;
6507         }
6508         btgt = ctx->base.pc_next + insn_bytes + offset;
6509         break;
6510     case OPC_BGEZ:
6511     case OPC_BGEZAL:
6512     case OPC_BGEZALL:
6513     case OPC_BGEZL:
6514     case OPC_BGTZ:
6515     case OPC_BGTZL:
6516     case OPC_BLEZ:
6517     case OPC_BLEZL:
6518     case OPC_BLTZ:
6519     case OPC_BLTZAL:
6520     case OPC_BLTZALL:
6521     case OPC_BLTZL:
6522         /* Compare to zero */
6523         if (rs != 0) {
6524             gen_load_gpr(t0, rs);
6525             bcond_compute = 1;
6526         }
6527         btgt = ctx->base.pc_next + insn_bytes + offset;
6528         break;
6529     case OPC_BPOSGE32:
6530 #if defined(TARGET_MIPS64)
6531     case OPC_BPOSGE64:
6532         tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
6533 #else
6534         tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
6535 #endif
6536         bcond_compute = 1;
6537         btgt = ctx->base.pc_next + insn_bytes + offset;
6538         break;
6539     case OPC_J:
6540     case OPC_JAL:
6541     case OPC_JALX:
6542         /* Jump to immediate */
6543         btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
6544             (uint32_t)offset;
6545         break;
6546     case OPC_JR:
6547     case OPC_JALR:
6548         /* Jump to register */
6549         if (offset != 0 && offset != 16) {
6550             /*
6551              * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6552              * others are reserved.
6553              */
6554             MIPS_INVAL("jump hint");
6555             generate_exception_end(ctx, EXCP_RI);
6556             goto out;
6557         }
6558         gen_load_gpr(btarget, rs);
6559         break;
6560     default:
6561         MIPS_INVAL("branch/jump");
6562         generate_exception_end(ctx, EXCP_RI);
6563         goto out;
6564     }
6565     if (bcond_compute == 0) {
6566         /* No condition to be computed */
6567         switch (opc) {
6568         case OPC_BEQ:     /* rx == rx        */
6569         case OPC_BEQL:    /* rx == rx likely */
6570         case OPC_BGEZ:    /* 0 >= 0          */
6571         case OPC_BGEZL:   /* 0 >= 0 likely   */
6572         case OPC_BLEZ:    /* 0 <= 0          */
6573         case OPC_BLEZL:   /* 0 <= 0 likely   */
6574             /* Always take */
6575             ctx->hflags |= MIPS_HFLAG_B;
6576             break;
6577         case OPC_BGEZAL:  /* 0 >= 0          */
6578         case OPC_BGEZALL: /* 0 >= 0 likely   */
6579             /* Always take and link */
6580             blink = 31;
6581             ctx->hflags |= MIPS_HFLAG_B;
6582             break;
6583         case OPC_BNE:     /* rx != rx        */
6584         case OPC_BGTZ:    /* 0 > 0           */
6585         case OPC_BLTZ:    /* 0 < 0           */
6586             /* Treat as NOP. */
6587             goto out;
6588         case OPC_BLTZAL:  /* 0 < 0           */
6589             /*
6590              * Handle as an unconditional branch to get correct delay
6591              * slot checking.
6592              */
6593             blink = 31;
6594             btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
6595             ctx->hflags |= MIPS_HFLAG_B;
6596             break;
6597         case OPC_BLTZALL: /* 0 < 0 likely */
6598             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
6599             /* Skip the instruction in the delay slot */
6600             ctx->base.pc_next += 4;
6601             goto out;
6602         case OPC_BNEL:    /* rx != rx likely */
6603         case OPC_BGTZL:   /* 0 > 0 likely */
6604         case OPC_BLTZL:   /* 0 < 0 likely */
6605             /* Skip the instruction in the delay slot */
6606             ctx->base.pc_next += 4;
6607             goto out;
6608         case OPC_J:
6609             ctx->hflags |= MIPS_HFLAG_B;
6610             break;
6611         case OPC_JALX:
6612             ctx->hflags |= MIPS_HFLAG_BX;
6613             /* Fallthrough */
6614         case OPC_JAL:
6615             blink = 31;
6616             ctx->hflags |= MIPS_HFLAG_B;
6617             break;
6618         case OPC_JR:
6619             ctx->hflags |= MIPS_HFLAG_BR;
6620             break;
6621         case OPC_JALR:
6622             blink = rt;
6623             ctx->hflags |= MIPS_HFLAG_BR;
6624             break;
6625         default:
6626             MIPS_INVAL("branch/jump");
6627             generate_exception_end(ctx, EXCP_RI);
6628             goto out;
6629         }
6630     } else {
6631         switch (opc) {
6632         case OPC_BEQ:
6633             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6634             goto not_likely;
6635         case OPC_BEQL:
6636             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6637             goto likely;
6638         case OPC_BNE:
6639             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6640             goto not_likely;
6641         case OPC_BNEL:
6642             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6643             goto likely;
6644         case OPC_BGEZ:
6645             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6646             goto not_likely;
6647         case OPC_BGEZL:
6648             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6649             goto likely;
6650         case OPC_BGEZAL:
6651             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6652             blink = 31;
6653             goto not_likely;
6654         case OPC_BGEZALL:
6655             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6656             blink = 31;
6657             goto likely;
6658         case OPC_BGTZ:
6659             tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6660             goto not_likely;
6661         case OPC_BGTZL:
6662             tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6663             goto likely;
6664         case OPC_BLEZ:
6665             tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6666             goto not_likely;
6667         case OPC_BLEZL:
6668             tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6669             goto likely;
6670         case OPC_BLTZ:
6671             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6672             goto not_likely;
6673         case OPC_BLTZL:
6674             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6675             goto likely;
6676         case OPC_BPOSGE32:
6677             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
6678             goto not_likely;
6679 #if defined(TARGET_MIPS64)
6680         case OPC_BPOSGE64:
6681             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
6682             goto not_likely;
6683 #endif
6684         case OPC_BLTZAL:
6685             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6686             blink = 31;
6687         not_likely:
6688             ctx->hflags |= MIPS_HFLAG_BC;
6689             break;
6690         case OPC_BLTZALL:
6691             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6692             blink = 31;
6693         likely:
6694             ctx->hflags |= MIPS_HFLAG_BL;
6695             break;
6696         default:
6697             MIPS_INVAL("conditional branch/jump");
6698             generate_exception_end(ctx, EXCP_RI);
6699             goto out;
6700         }
6701     }
6702 
6703     ctx->btarget = btgt;
6704 
6705     switch (delayslot_size) {
6706     case 2:
6707         ctx->hflags |= MIPS_HFLAG_BDS16;
6708         break;
6709     case 4:
6710         ctx->hflags |= MIPS_HFLAG_BDS32;
6711         break;
6712     }
6713 
6714     if (blink > 0) {
6715         int post_delay = insn_bytes + delayslot_size;
6716         int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
6717 
6718         tcg_gen_movi_tl(cpu_gpr[blink],
6719                         ctx->base.pc_next + post_delay + lowbit);
6720     }
6721 
6722  out:
6723     if (insn_bytes == 2) {
6724         ctx->hflags |= MIPS_HFLAG_B16;
6725     }
6726     tcg_temp_free(t0);
6727     tcg_temp_free(t1);
6728 }
6729 
6730 
6731 /* nanoMIPS Branches */
gen_compute_branch_nm(DisasContext * ctx,uint32_t opc,int insn_bytes,int rs,int rt,int32_t offset)6732 static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc,
6733                                 int insn_bytes,
6734                                 int rs, int rt, int32_t offset)
6735 {
6736     target_ulong btgt = -1;
6737     int bcond_compute = 0;
6738     TCGv t0 = tcg_temp_new();
6739     TCGv t1 = tcg_temp_new();
6740 
6741     /* Load needed operands */
6742     switch (opc) {
6743     case OPC_BEQ:
6744     case OPC_BNE:
6745         /* Compare two registers */
6746         if (rs != rt) {
6747             gen_load_gpr(t0, rs);
6748             gen_load_gpr(t1, rt);
6749             bcond_compute = 1;
6750         }
6751         btgt = ctx->base.pc_next + insn_bytes + offset;
6752         break;
6753     case OPC_BGEZAL:
6754         /* Compare to zero */
6755         if (rs != 0) {
6756             gen_load_gpr(t0, rs);
6757             bcond_compute = 1;
6758         }
6759         btgt = ctx->base.pc_next + insn_bytes + offset;
6760         break;
6761     case OPC_BPOSGE32:
6762         tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
6763         bcond_compute = 1;
6764         btgt = ctx->base.pc_next + insn_bytes + offset;
6765         break;
6766     case OPC_JR:
6767     case OPC_JALR:
6768         /* Jump to register */
6769         if (offset != 0 && offset != 16) {
6770             /*
6771              * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6772              * others are reserved.
6773              */
6774             MIPS_INVAL("jump hint");
6775             generate_exception_end(ctx, EXCP_RI);
6776             goto out;
6777         }
6778         gen_load_gpr(btarget, rs);
6779         break;
6780     default:
6781         MIPS_INVAL("branch/jump");
6782         generate_exception_end(ctx, EXCP_RI);
6783         goto out;
6784     }
6785     if (bcond_compute == 0) {
6786         /* No condition to be computed */
6787         switch (opc) {
6788         case OPC_BEQ:     /* rx == rx        */
6789             /* Always take */
6790             ctx->hflags |= MIPS_HFLAG_B;
6791             break;
6792         case OPC_BGEZAL:  /* 0 >= 0          */
6793             /* Always take and link */
6794             tcg_gen_movi_tl(cpu_gpr[31],
6795                             ctx->base.pc_next + insn_bytes);
6796             ctx->hflags |= MIPS_HFLAG_B;
6797             break;
6798         case OPC_BNE:     /* rx != rx        */
6799             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
6800             /* Skip the instruction in the delay slot */
6801             ctx->base.pc_next += 4;
6802             goto out;
6803         case OPC_JR:
6804             ctx->hflags |= MIPS_HFLAG_BR;
6805             break;
6806         case OPC_JALR:
6807             if (rt > 0) {
6808                 tcg_gen_movi_tl(cpu_gpr[rt],
6809                                 ctx->base.pc_next + insn_bytes);
6810             }
6811             ctx->hflags |= MIPS_HFLAG_BR;
6812             break;
6813         default:
6814             MIPS_INVAL("branch/jump");
6815             generate_exception_end(ctx, EXCP_RI);
6816             goto out;
6817         }
6818     } else {
6819         switch (opc) {
6820         case OPC_BEQ:
6821             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6822             goto not_likely;
6823         case OPC_BNE:
6824             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6825             goto not_likely;
6826         case OPC_BGEZAL:
6827             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6828             tcg_gen_movi_tl(cpu_gpr[31],
6829                             ctx->base.pc_next + insn_bytes);
6830             goto not_likely;
6831         case OPC_BPOSGE32:
6832             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
6833         not_likely:
6834             ctx->hflags |= MIPS_HFLAG_BC;
6835             break;
6836         default:
6837             MIPS_INVAL("conditional branch/jump");
6838             generate_exception_end(ctx, EXCP_RI);
6839             goto out;
6840         }
6841     }
6842 
6843     ctx->btarget = btgt;
6844 
6845  out:
6846     if (insn_bytes == 2) {
6847         ctx->hflags |= MIPS_HFLAG_B16;
6848     }
6849     tcg_temp_free(t0);
6850     tcg_temp_free(t1);
6851 }
6852 
6853 
6854 /* special3 bitfield operations */
gen_bitops(DisasContext * ctx,uint32_t opc,int rt,int rs,int lsb,int msb)6855 static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt,
6856                        int rs, int lsb, int msb)
6857 {
6858     TCGv t0 = tcg_temp_new();
6859     TCGv t1 = tcg_temp_new();
6860 
6861     gen_load_gpr(t1, rs);
6862     switch (opc) {
6863     case OPC_EXT:
6864         if (lsb + msb > 31) {
6865             goto fail;
6866         }
6867         if (msb != 31) {
6868             tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
6869         } else {
6870             /*
6871              * The two checks together imply that lsb == 0,
6872              * so this is a simple sign-extension.
6873              */
6874             tcg_gen_ext32s_tl(t0, t1);
6875         }
6876         break;
6877 #if defined(TARGET_MIPS64)
6878     case OPC_DEXTU:
6879         lsb += 32;
6880         goto do_dext;
6881     case OPC_DEXTM:
6882         msb += 32;
6883         goto do_dext;
6884     case OPC_DEXT:
6885     do_dext:
6886         if (lsb + msb > 63) {
6887             goto fail;
6888         }
6889         tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
6890         break;
6891 #endif
6892     case OPC_INS:
6893         if (lsb > msb) {
6894             goto fail;
6895         }
6896         gen_load_gpr(t0, rt);
6897         tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
6898         tcg_gen_ext32s_tl(t0, t0);
6899         break;
6900 #if defined(TARGET_MIPS64)
6901     case OPC_DINSU:
6902         lsb += 32;
6903         /* FALLTHRU */
6904     case OPC_DINSM:
6905         msb += 32;
6906         /* FALLTHRU */
6907     case OPC_DINS:
6908         if (lsb > msb) {
6909             goto fail;
6910         }
6911         gen_load_gpr(t0, rt);
6912         tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
6913         break;
6914 #endif
6915     default:
6916 fail:
6917         MIPS_INVAL("bitops");
6918         generate_exception_end(ctx, EXCP_RI);
6919         tcg_temp_free(t0);
6920         tcg_temp_free(t1);
6921         return;
6922     }
6923     gen_store_gpr(t0, rt);
6924     tcg_temp_free(t0);
6925     tcg_temp_free(t1);
6926 }
6927 
gen_bshfl(DisasContext * ctx,uint32_t op2,int rt,int rd)6928 static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd)
6929 {
6930     TCGv t0;
6931 
6932     if (rd == 0) {
6933         /* If no destination, treat it as a NOP. */
6934         return;
6935     }
6936 
6937     t0 = tcg_temp_new();
6938     gen_load_gpr(t0, rt);
6939     switch (op2) {
6940     case OPC_WSBH:
6941         {
6942             TCGv t1 = tcg_temp_new();
6943             TCGv t2 = tcg_const_tl(0x00FF00FF);
6944 
6945             tcg_gen_shri_tl(t1, t0, 8);
6946             tcg_gen_and_tl(t1, t1, t2);
6947             tcg_gen_and_tl(t0, t0, t2);
6948             tcg_gen_shli_tl(t0, t0, 8);
6949             tcg_gen_or_tl(t0, t0, t1);
6950             tcg_temp_free(t2);
6951             tcg_temp_free(t1);
6952             tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6953         }
6954         break;
6955     case OPC_SEB:
6956         tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
6957         break;
6958     case OPC_SEH:
6959         tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
6960         break;
6961 #if defined(TARGET_MIPS64)
6962     case OPC_DSBH:
6963         {
6964             TCGv t1 = tcg_temp_new();
6965             TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
6966 
6967             tcg_gen_shri_tl(t1, t0, 8);
6968             tcg_gen_and_tl(t1, t1, t2);
6969             tcg_gen_and_tl(t0, t0, t2);
6970             tcg_gen_shli_tl(t0, t0, 8);
6971             tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
6972             tcg_temp_free(t2);
6973             tcg_temp_free(t1);
6974         }
6975         break;
6976     case OPC_DSHD:
6977         {
6978             TCGv t1 = tcg_temp_new();
6979             TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
6980 
6981             tcg_gen_shri_tl(t1, t0, 16);
6982             tcg_gen_and_tl(t1, t1, t2);
6983             tcg_gen_and_tl(t0, t0, t2);
6984             tcg_gen_shli_tl(t0, t0, 16);
6985             tcg_gen_or_tl(t0, t0, t1);
6986             tcg_gen_shri_tl(t1, t0, 32);
6987             tcg_gen_shli_tl(t0, t0, 32);
6988             tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
6989             tcg_temp_free(t2);
6990             tcg_temp_free(t1);
6991         }
6992         break;
6993 #endif
6994     default:
6995         MIPS_INVAL("bsfhl");
6996         generate_exception_end(ctx, EXCP_RI);
6997         tcg_temp_free(t0);
6998         return;
6999     }
7000     tcg_temp_free(t0);
7001 }
7002 
gen_lsa(DisasContext * ctx,int opc,int rd,int rs,int rt,int imm2)7003 static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
7004                     int imm2)
7005 {
7006     TCGv t0;
7007     TCGv t1;
7008     if (rd == 0) {
7009         /* Treat as NOP. */
7010         return;
7011     }
7012     t0 = tcg_temp_new();
7013     t1 = tcg_temp_new();
7014     gen_load_gpr(t0, rs);
7015     gen_load_gpr(t1, rt);
7016     tcg_gen_shli_tl(t0, t0, imm2 + 1);
7017     tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
7018     if (opc == OPC_LSA) {
7019         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
7020     }
7021 
7022     tcg_temp_free(t1);
7023     tcg_temp_free(t0);
7024 
7025     return;
7026 }
7027 
gen_align_bits(DisasContext * ctx,int wordsz,int rd,int rs,int rt,int bits)7028 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
7029                            int rt, int bits)
7030 {
7031     TCGv t0;
7032     if (rd == 0) {
7033         /* Treat as NOP. */
7034         return;
7035     }
7036     t0 = tcg_temp_new();
7037     if (bits == 0 || bits == wordsz) {
7038         if (bits == 0) {
7039             gen_load_gpr(t0, rt);
7040         } else {
7041             gen_load_gpr(t0, rs);
7042         }
7043         switch (wordsz) {
7044         case 32:
7045             tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
7046             break;
7047 #if defined(TARGET_MIPS64)
7048         case 64:
7049             tcg_gen_mov_tl(cpu_gpr[rd], t0);
7050             break;
7051 #endif
7052         }
7053     } else {
7054         TCGv t1 = tcg_temp_new();
7055         gen_load_gpr(t0, rt);
7056         gen_load_gpr(t1, rs);
7057         switch (wordsz) {
7058         case 32:
7059             {
7060                 TCGv_i64 t2 = tcg_temp_new_i64();
7061                 tcg_gen_concat_tl_i64(t2, t1, t0);
7062                 tcg_gen_shri_i64(t2, t2, 32 - bits);
7063                 gen_move_low32(cpu_gpr[rd], t2);
7064                 tcg_temp_free_i64(t2);
7065             }
7066             break;
7067 #if defined(TARGET_MIPS64)
7068         case 64:
7069             tcg_gen_shli_tl(t0, t0, bits);
7070             tcg_gen_shri_tl(t1, t1, 64 - bits);
7071             tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
7072             break;
7073 #endif
7074         }
7075         tcg_temp_free(t1);
7076     }
7077 
7078     tcg_temp_free(t0);
7079 }
7080 
gen_align(DisasContext * ctx,int wordsz,int rd,int rs,int rt,int bp)7081 static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
7082                       int bp)
7083 {
7084     gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
7085 }
7086 
gen_ext(DisasContext * ctx,int wordsz,int rd,int rs,int rt,int shift)7087 static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
7088                     int shift)
7089 {
7090     gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift);
7091 }
7092 
gen_bitswap(DisasContext * ctx,int opc,int rd,int rt)7093 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
7094 {
7095     TCGv t0;
7096     if (rd == 0) {
7097         /* Treat as NOP. */
7098         return;
7099     }
7100     t0 = tcg_temp_new();
7101     gen_load_gpr(t0, rt);
7102     switch (opc) {
7103     case OPC_BITSWAP:
7104         gen_helper_bitswap(cpu_gpr[rd], t0);
7105         break;
7106 #if defined(TARGET_MIPS64)
7107     case OPC_DBITSWAP:
7108         gen_helper_dbitswap(cpu_gpr[rd], t0);
7109         break;
7110 #endif
7111     }
7112     tcg_temp_free(t0);
7113 }
7114 
7115 #ifndef CONFIG_USER_ONLY
7116 /* CP0 (MMU and control) */
gen_mthc0_entrylo(TCGv arg,target_ulong off)7117 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
7118 {
7119     TCGv_i64 t0 = tcg_temp_new_i64();
7120     TCGv_i64 t1 = tcg_temp_new_i64();
7121 
7122     tcg_gen_ext_tl_i64(t0, arg);
7123     tcg_gen_ld_i64(t1, cpu_env, off);
7124 #if defined(TARGET_MIPS64)
7125     tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
7126 #else
7127     tcg_gen_concat32_i64(t1, t1, t0);
7128 #endif
7129     tcg_gen_st_i64(t1, cpu_env, off);
7130     tcg_temp_free_i64(t1);
7131     tcg_temp_free_i64(t0);
7132 }
7133 
gen_mthc0_store64(TCGv arg,target_ulong off)7134 static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
7135 {
7136     TCGv_i64 t0 = tcg_temp_new_i64();
7137     TCGv_i64 t1 = tcg_temp_new_i64();
7138 
7139     tcg_gen_ext_tl_i64(t0, arg);
7140     tcg_gen_ld_i64(t1, cpu_env, off);
7141     tcg_gen_concat32_i64(t1, t1, t0);
7142     tcg_gen_st_i64(t1, cpu_env, off);
7143     tcg_temp_free_i64(t1);
7144     tcg_temp_free_i64(t0);
7145 }
7146 
gen_mfhc0_entrylo(TCGv arg,target_ulong off)7147 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
7148 {
7149     TCGv_i64 t0 = tcg_temp_new_i64();
7150 
7151     tcg_gen_ld_i64(t0, cpu_env, off);
7152 #if defined(TARGET_MIPS64)
7153     tcg_gen_shri_i64(t0, t0, 30);
7154 #else
7155     tcg_gen_shri_i64(t0, t0, 32);
7156 #endif
7157     gen_move_low32(arg, t0);
7158     tcg_temp_free_i64(t0);
7159 }
7160 
gen_mfhc0_load64(TCGv arg,target_ulong off,int shift)7161 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
7162 {
7163     TCGv_i64 t0 = tcg_temp_new_i64();
7164 
7165     tcg_gen_ld_i64(t0, cpu_env, off);
7166     tcg_gen_shri_i64(t0, t0, 32 + shift);
7167     gen_move_low32(arg, t0);
7168     tcg_temp_free_i64(t0);
7169 }
7170 
gen_mfc0_load32(TCGv arg,target_ulong off)7171 static inline void gen_mfc0_load32(TCGv arg, target_ulong off)
7172 {
7173     TCGv_i32 t0 = tcg_temp_new_i32();
7174 
7175     tcg_gen_ld_i32(t0, cpu_env, off);
7176     tcg_gen_ext_i32_tl(arg, t0);
7177     tcg_temp_free_i32(t0);
7178 }
7179 
gen_mfc0_load64(TCGv arg,target_ulong off)7180 static inline void gen_mfc0_load64(TCGv arg, target_ulong off)
7181 {
7182     tcg_gen_ld_tl(arg, cpu_env, off);
7183     tcg_gen_ext32s_tl(arg, arg);
7184 }
7185 
gen_mtc0_store32(TCGv arg,target_ulong off)7186 static inline void gen_mtc0_store32(TCGv arg, target_ulong off)
7187 {
7188     TCGv_i32 t0 = tcg_temp_new_i32();
7189 
7190     tcg_gen_trunc_tl_i32(t0, arg);
7191     tcg_gen_st_i32(t0, cpu_env, off);
7192     tcg_temp_free_i32(t0);
7193 }
7194 
7195 #define CP0_CHECK(c)                            \
7196     do {                                        \
7197         if (!(c)) {                             \
7198             goto cp0_unimplemented;             \
7199         }                                       \
7200     } while (0)
7201 
gen_mfhc0(DisasContext * ctx,TCGv arg,int reg,int sel)7202 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7203 {
7204     const char *register_name = "invalid";
7205 
7206     switch (reg) {
7207     case CP0_REGISTER_02:
7208         switch (sel) {
7209         case 0:
7210             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
7211             gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
7212             register_name = "EntryLo0";
7213             break;
7214         default:
7215             goto cp0_unimplemented;
7216         }
7217         break;
7218     case CP0_REGISTER_03:
7219         switch (sel) {
7220         case CP0_REG03__ENTRYLO1:
7221             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
7222             gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
7223             register_name = "EntryLo1";
7224             break;
7225         default:
7226             goto cp0_unimplemented;
7227         }
7228         break;
7229     case CP0_REGISTER_09:
7230         switch (sel) {
7231         case CP0_REG09__SAAR:
7232             CP0_CHECK(ctx->saar);
7233             gen_helper_mfhc0_saar(arg, cpu_env);
7234             register_name = "SAAR";
7235             break;
7236         default:
7237             goto cp0_unimplemented;
7238         }
7239         break;
7240     case CP0_REGISTER_17:
7241         switch (sel) {
7242         case CP0_REG17__LLADDR:
7243             gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr),
7244                              ctx->CP0_LLAddr_shift);
7245             register_name = "LLAddr";
7246             break;
7247         case CP0_REG17__MAAR:
7248             CP0_CHECK(ctx->mrp);
7249             gen_helper_mfhc0_maar(arg, cpu_env);
7250             register_name = "MAAR";
7251             break;
7252         default:
7253             goto cp0_unimplemented;
7254         }
7255         break;
7256     case CP0_REGISTER_19:
7257         switch (sel) {
7258         case CP0_REG19__WATCHHI0:
7259         case CP0_REG19__WATCHHI1:
7260         case CP0_REG19__WATCHHI2:
7261         case CP0_REG19__WATCHHI3:
7262         case CP0_REG19__WATCHHI4:
7263         case CP0_REG19__WATCHHI5:
7264         case CP0_REG19__WATCHHI6:
7265         case CP0_REG19__WATCHHI7:
7266             /* upper 32 bits are only available when Config5MI != 0 */
7267             CP0_CHECK(ctx->mi);
7268             gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_WatchHi[sel]), 0);
7269             register_name = "WatchHi";
7270             break;
7271         default:
7272             goto cp0_unimplemented;
7273         }
7274         break;
7275     case CP0_REGISTER_28:
7276         switch (sel) {
7277         case 0:
7278         case 2:
7279         case 4:
7280         case 6:
7281             gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
7282             register_name = "TagLo";
7283             break;
7284         default:
7285             goto cp0_unimplemented;
7286         }
7287         break;
7288     default:
7289         goto cp0_unimplemented;
7290     }
7291     trace_mips_translate_c0("mfhc0", register_name, reg, sel);
7292     return;
7293 
7294 cp0_unimplemented:
7295     qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n",
7296                   register_name, reg, sel);
7297     tcg_gen_movi_tl(arg, 0);
7298 }
7299 
gen_mthc0(DisasContext * ctx,TCGv arg,int reg,int sel)7300 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7301 {
7302     const char *register_name = "invalid";
7303     uint64_t mask = ctx->PAMask >> 36;
7304 
7305     switch (reg) {
7306     case CP0_REGISTER_02:
7307         switch (sel) {
7308         case 0:
7309             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
7310             tcg_gen_andi_tl(arg, arg, mask);
7311             gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
7312             register_name = "EntryLo0";
7313             break;
7314         default:
7315             goto cp0_unimplemented;
7316         }
7317         break;
7318     case CP0_REGISTER_03:
7319         switch (sel) {
7320         case CP0_REG03__ENTRYLO1:
7321             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
7322             tcg_gen_andi_tl(arg, arg, mask);
7323             gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
7324             register_name = "EntryLo1";
7325             break;
7326         default:
7327             goto cp0_unimplemented;
7328         }
7329         break;
7330     case CP0_REGISTER_09:
7331         switch (sel) {
7332         case CP0_REG09__SAAR:
7333             CP0_CHECK(ctx->saar);
7334             gen_helper_mthc0_saar(cpu_env, arg);
7335             register_name = "SAAR";
7336             break;
7337         default:
7338             goto cp0_unimplemented;
7339         }
7340         break;
7341     case CP0_REGISTER_17:
7342         switch (sel) {
7343         case CP0_REG17__LLADDR:
7344             /*
7345              * LLAddr is read-only (the only exception is bit 0 if LLB is
7346              * supported); the CP0_LLAddr_rw_bitmask does not seem to be
7347              * relevant for modern MIPS cores supporting MTHC0, therefore
7348              * treating MTHC0 to LLAddr as NOP.
7349              */
7350             register_name = "LLAddr";
7351             break;
7352         case CP0_REG17__MAAR:
7353             CP0_CHECK(ctx->mrp);
7354             gen_helper_mthc0_maar(cpu_env, arg);
7355             register_name = "MAAR";
7356             break;
7357         default:
7358             goto cp0_unimplemented;
7359         }
7360         break;
7361     case CP0_REGISTER_19:
7362         switch (sel) {
7363         case CP0_REG19__WATCHHI0:
7364         case CP0_REG19__WATCHHI1:
7365         case CP0_REG19__WATCHHI2:
7366         case CP0_REG19__WATCHHI3:
7367         case CP0_REG19__WATCHHI4:
7368         case CP0_REG19__WATCHHI5:
7369         case CP0_REG19__WATCHHI6:
7370         case CP0_REG19__WATCHHI7:
7371             /* upper 32 bits are only available when Config5MI != 0 */
7372             CP0_CHECK(ctx->mi);
7373             gen_helper_0e1i(mthc0_watchhi, arg, sel);
7374             register_name = "WatchHi";
7375             break;
7376         default:
7377             goto cp0_unimplemented;
7378         }
7379         break;
7380     case CP0_REGISTER_28:
7381         switch (sel) {
7382         case 0:
7383         case 2:
7384         case 4:
7385         case 6:
7386             tcg_gen_andi_tl(arg, arg, mask);
7387             gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
7388             register_name = "TagLo";
7389             break;
7390         default:
7391             goto cp0_unimplemented;
7392         }
7393         break;
7394     default:
7395         goto cp0_unimplemented;
7396     }
7397     trace_mips_translate_c0("mthc0", register_name, reg, sel);
7398 
7399 cp0_unimplemented:
7400     qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n",
7401                   register_name, reg, sel);
7402 }
7403 
gen_mfc0_unimplemented(DisasContext * ctx,TCGv arg)7404 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
7405 {
7406     if (ctx->insn_flags & ISA_MIPS32R6) {
7407         tcg_gen_movi_tl(arg, 0);
7408     } else {
7409         tcg_gen_movi_tl(arg, ~0);
7410     }
7411 }
7412 
gen_mfc0(DisasContext * ctx,TCGv arg,int reg,int sel)7413 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7414 {
7415     const char *register_name = "invalid";
7416 
7417     if (sel != 0) {
7418         check_insn(ctx, ISA_MIPS32);
7419     }
7420 
7421     switch (reg) {
7422     case CP0_REGISTER_00:
7423         switch (sel) {
7424         case CP0_REG00__INDEX:
7425             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7426             register_name = "Index";
7427             break;
7428         case CP0_REG00__MVPCONTROL:
7429             CP0_CHECK(ctx->insn_flags & ASE_MT);
7430             gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7431             register_name = "MVPControl";
7432             break;
7433         case CP0_REG00__MVPCONF0:
7434             CP0_CHECK(ctx->insn_flags & ASE_MT);
7435             gen_helper_mfc0_mvpconf0(arg, cpu_env);
7436             register_name = "MVPConf0";
7437             break;
7438         case CP0_REG00__MVPCONF1:
7439             CP0_CHECK(ctx->insn_flags & ASE_MT);
7440             gen_helper_mfc0_mvpconf1(arg, cpu_env);
7441             register_name = "MVPConf1";
7442             break;
7443         case CP0_REG00__VPCONTROL:
7444             CP0_CHECK(ctx->vp);
7445             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
7446             register_name = "VPControl";
7447             break;
7448         default:
7449             goto cp0_unimplemented;
7450         }
7451         break;
7452     case CP0_REGISTER_01:
7453         switch (sel) {
7454         case CP0_REG01__RANDOM:
7455             CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7456             gen_helper_mfc0_random(arg, cpu_env);
7457             register_name = "Random";
7458             break;
7459         case CP0_REG01__VPECONTROL:
7460             CP0_CHECK(ctx->insn_flags & ASE_MT);
7461             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7462             register_name = "VPEControl";
7463             break;
7464         case CP0_REG01__VPECONF0:
7465             CP0_CHECK(ctx->insn_flags & ASE_MT);
7466             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7467             register_name = "VPEConf0";
7468             break;
7469         case CP0_REG01__VPECONF1:
7470             CP0_CHECK(ctx->insn_flags & ASE_MT);
7471             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7472             register_name = "VPEConf1";
7473             break;
7474         case CP0_REG01__YQMASK:
7475             CP0_CHECK(ctx->insn_flags & ASE_MT);
7476             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7477             register_name = "YQMask";
7478             break;
7479         case CP0_REG01__VPESCHEDULE:
7480             CP0_CHECK(ctx->insn_flags & ASE_MT);
7481             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7482             register_name = "VPESchedule";
7483             break;
7484         case CP0_REG01__VPESCHEFBACK:
7485             CP0_CHECK(ctx->insn_flags & ASE_MT);
7486             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7487             register_name = "VPEScheFBack";
7488             break;
7489         case CP0_REG01__VPEOPT:
7490             CP0_CHECK(ctx->insn_flags & ASE_MT);
7491             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7492             register_name = "VPEOpt";
7493             break;
7494         default:
7495             goto cp0_unimplemented;
7496         }
7497         break;
7498     case CP0_REGISTER_02:
7499         switch (sel) {
7500         case CP0_REG02__ENTRYLO0:
7501             {
7502                 TCGv_i64 tmp = tcg_temp_new_i64();
7503                 tcg_gen_ld_i64(tmp, cpu_env,
7504                                offsetof(CPUMIPSState, CP0_EntryLo0));
7505 #if defined(TARGET_MIPS64)
7506                 if (ctx->rxi) {
7507                     /* Move RI/XI fields to bits 31:30 */
7508                     tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
7509                     tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
7510                 }
7511 #endif
7512                 gen_move_low32(arg, tmp);
7513                 tcg_temp_free_i64(tmp);
7514             }
7515             register_name = "EntryLo0";
7516             break;
7517         case CP0_REG02__TCSTATUS:
7518             CP0_CHECK(ctx->insn_flags & ASE_MT);
7519             gen_helper_mfc0_tcstatus(arg, cpu_env);
7520             register_name = "TCStatus";
7521             break;
7522         case CP0_REG02__TCBIND:
7523             CP0_CHECK(ctx->insn_flags & ASE_MT);
7524             gen_helper_mfc0_tcbind(arg, cpu_env);
7525             register_name = "TCBind";
7526             break;
7527         case CP0_REG02__TCRESTART:
7528             CP0_CHECK(ctx->insn_flags & ASE_MT);
7529             gen_helper_mfc0_tcrestart(arg, cpu_env);
7530             register_name = "TCRestart";
7531             break;
7532         case CP0_REG02__TCHALT:
7533             CP0_CHECK(ctx->insn_flags & ASE_MT);
7534             gen_helper_mfc0_tchalt(arg, cpu_env);
7535             register_name = "TCHalt";
7536             break;
7537         case CP0_REG02__TCCONTEXT:
7538             CP0_CHECK(ctx->insn_flags & ASE_MT);
7539             gen_helper_mfc0_tccontext(arg, cpu_env);
7540             register_name = "TCContext";
7541             break;
7542         case CP0_REG02__TCSCHEDULE:
7543             CP0_CHECK(ctx->insn_flags & ASE_MT);
7544             gen_helper_mfc0_tcschedule(arg, cpu_env);
7545             register_name = "TCSchedule";
7546             break;
7547         case CP0_REG02__TCSCHEFBACK:
7548             CP0_CHECK(ctx->insn_flags & ASE_MT);
7549             gen_helper_mfc0_tcschefback(arg, cpu_env);
7550             register_name = "TCScheFBack";
7551             break;
7552         default:
7553             goto cp0_unimplemented;
7554         }
7555         break;
7556     case CP0_REGISTER_03:
7557         switch (sel) {
7558         case CP0_REG03__ENTRYLO1:
7559             {
7560                 TCGv_i64 tmp = tcg_temp_new_i64();
7561                 tcg_gen_ld_i64(tmp, cpu_env,
7562                                offsetof(CPUMIPSState, CP0_EntryLo1));
7563 #if defined(TARGET_MIPS64)
7564                 if (ctx->rxi) {
7565                     /* Move RI/XI fields to bits 31:30 */
7566                     tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
7567                     tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
7568                 }
7569 #endif
7570                 gen_move_low32(arg, tmp);
7571                 tcg_temp_free_i64(tmp);
7572             }
7573             register_name = "EntryLo1";
7574             break;
7575         case CP0_REG03__GLOBALNUM:
7576             CP0_CHECK(ctx->vp);
7577             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
7578             register_name = "GlobalNumber";
7579             break;
7580         default:
7581             goto cp0_unimplemented;
7582         }
7583         break;
7584     case CP0_REGISTER_04:
7585         switch (sel) {
7586         case CP0_REG04__CONTEXT:
7587             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
7588             tcg_gen_ext32s_tl(arg, arg);
7589             register_name = "Context";
7590             break;
7591         case CP0_REG04__CONTEXTCONFIG:
7592             /* SmartMIPS ASE */
7593             /* gen_helper_mfc0_contextconfig(arg); */
7594             register_name = "ContextConfig";
7595             goto cp0_unimplemented;
7596         case CP0_REG04__USERLOCAL:
7597             CP0_CHECK(ctx->ulri);
7598             tcg_gen_ld_tl(arg, cpu_env,
7599                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7600             tcg_gen_ext32s_tl(arg, arg);
7601             register_name = "UserLocal";
7602             break;
7603         case CP0_REG04__MMID:
7604             CP0_CHECK(ctx->mi);
7605             gen_helper_mtc0_memorymapid(cpu_env, arg);
7606             register_name = "MMID";
7607             break;
7608         default:
7609             goto cp0_unimplemented;
7610         }
7611         break;
7612     case CP0_REGISTER_05:
7613         switch (sel) {
7614         case CP0_REG05__PAGEMASK:
7615             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
7616             register_name = "PageMask";
7617             break;
7618         case CP0_REG05__PAGEGRAIN:
7619             check_insn(ctx, ISA_MIPS32R2);
7620             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
7621             register_name = "PageGrain";
7622             break;
7623         case CP0_REG05__SEGCTL0:
7624             CP0_CHECK(ctx->sc);
7625             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
7626             tcg_gen_ext32s_tl(arg, arg);
7627             register_name = "SegCtl0";
7628             break;
7629         case CP0_REG05__SEGCTL1:
7630             CP0_CHECK(ctx->sc);
7631             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
7632             tcg_gen_ext32s_tl(arg, arg);
7633             register_name = "SegCtl1";
7634             break;
7635         case CP0_REG05__SEGCTL2:
7636             CP0_CHECK(ctx->sc);
7637             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
7638             tcg_gen_ext32s_tl(arg, arg);
7639             register_name = "SegCtl2";
7640             break;
7641         case CP0_REG05__PWBASE:
7642             check_pw(ctx);
7643             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
7644             register_name = "PWBase";
7645             break;
7646         case CP0_REG05__PWFIELD:
7647             check_pw(ctx);
7648             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
7649             register_name = "PWField";
7650             break;
7651         case CP0_REG05__PWSIZE:
7652             check_pw(ctx);
7653             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
7654             register_name = "PWSize";
7655             break;
7656         default:
7657             goto cp0_unimplemented;
7658         }
7659         break;
7660     case CP0_REGISTER_06:
7661         switch (sel) {
7662         case CP0_REG06__WIRED:
7663             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
7664             register_name = "Wired";
7665             break;
7666         case CP0_REG06__SRSCONF0:
7667             check_insn(ctx, ISA_MIPS32R2);
7668             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
7669             register_name = "SRSConf0";
7670             break;
7671         case CP0_REG06__SRSCONF1:
7672             check_insn(ctx, ISA_MIPS32R2);
7673             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
7674             register_name = "SRSConf1";
7675             break;
7676         case CP0_REG06__SRSCONF2:
7677             check_insn(ctx, ISA_MIPS32R2);
7678             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
7679             register_name = "SRSConf2";
7680             break;
7681         case CP0_REG06__SRSCONF3:
7682             check_insn(ctx, ISA_MIPS32R2);
7683             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
7684             register_name = "SRSConf3";
7685             break;
7686         case CP0_REG06__SRSCONF4:
7687             check_insn(ctx, ISA_MIPS32R2);
7688             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
7689             register_name = "SRSConf4";
7690             break;
7691         case CP0_REG06__PWCTL:
7692             check_pw(ctx);
7693             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
7694             register_name = "PWCtl";
7695             break;
7696         default:
7697             goto cp0_unimplemented;
7698         }
7699         break;
7700     case CP0_REGISTER_07:
7701         switch (sel) {
7702         case CP0_REG07__HWRENA:
7703             check_insn(ctx, ISA_MIPS32R2);
7704             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
7705             register_name = "HWREna";
7706             break;
7707         default:
7708             goto cp0_unimplemented;
7709         }
7710         break;
7711     case CP0_REGISTER_08:
7712         switch (sel) {
7713         case CP0_REG08__BADVADDR:
7714             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
7715             tcg_gen_ext32s_tl(arg, arg);
7716             register_name = "BadVAddr";
7717             break;
7718         case CP0_REG08__BADINSTR:
7719             CP0_CHECK(ctx->bi);
7720             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
7721             register_name = "BadInstr";
7722             break;
7723         case CP0_REG08__BADINSTRP:
7724             CP0_CHECK(ctx->bp);
7725             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
7726             register_name = "BadInstrP";
7727             break;
7728         case CP0_REG08__BADINSTRX:
7729             CP0_CHECK(ctx->bi);
7730             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
7731             tcg_gen_andi_tl(arg, arg, ~0xffff);
7732             register_name = "BadInstrX";
7733             break;
7734         default:
7735             goto cp0_unimplemented;
7736         }
7737         break;
7738     case CP0_REGISTER_09:
7739         switch (sel) {
7740         case CP0_REG09__COUNT:
7741             /* Mark as an IO operation because we read the time.  */
7742             if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7743                 gen_io_start();
7744             }
7745             gen_helper_mfc0_count(arg, cpu_env);
7746             /*
7747              * Break the TB to be able to take timer interrupts immediately
7748              * after reading count. DISAS_STOP isn't sufficient, we need to
7749              * ensure we break completely out of translated code.
7750              */
7751             gen_save_pc(ctx->base.pc_next + 4);
7752             ctx->base.is_jmp = DISAS_EXIT;
7753             register_name = "Count";
7754             break;
7755         case CP0_REG09__SAARI:
7756             CP0_CHECK(ctx->saar);
7757             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
7758             register_name = "SAARI";
7759             break;
7760         case CP0_REG09__SAAR:
7761             CP0_CHECK(ctx->saar);
7762             gen_helper_mfc0_saar(arg, cpu_env);
7763             register_name = "SAAR";
7764             break;
7765         default:
7766             goto cp0_unimplemented;
7767         }
7768         break;
7769     case CP0_REGISTER_10:
7770         switch (sel) {
7771         case CP0_REG10__ENTRYHI:
7772             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
7773             tcg_gen_ext32s_tl(arg, arg);
7774             register_name = "EntryHi";
7775             break;
7776         default:
7777             goto cp0_unimplemented;
7778         }
7779         break;
7780     case CP0_REGISTER_11:
7781         switch (sel) {
7782         case CP0_REG11__COMPARE:
7783             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
7784             register_name = "Compare";
7785             break;
7786         /* 6,7 are implementation dependent */
7787         default:
7788             goto cp0_unimplemented;
7789         }
7790         break;
7791     case CP0_REGISTER_12:
7792         switch (sel) {
7793         case CP0_REG12__STATUS:
7794             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
7795             register_name = "Status";
7796             break;
7797         case CP0_REG12__INTCTL:
7798             check_insn(ctx, ISA_MIPS32R2);
7799             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
7800             register_name = "IntCtl";
7801             break;
7802         case CP0_REG12__SRSCTL:
7803             check_insn(ctx, ISA_MIPS32R2);
7804             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
7805             register_name = "SRSCtl";
7806             break;
7807         case CP0_REG12__SRSMAP:
7808             check_insn(ctx, ISA_MIPS32R2);
7809             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7810             register_name = "SRSMap";
7811             break;
7812         default:
7813             goto cp0_unimplemented;
7814        }
7815         break;
7816     case CP0_REGISTER_13:
7817         switch (sel) {
7818         case CP0_REG13__CAUSE:
7819             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
7820             register_name = "Cause";
7821             break;
7822         default:
7823             goto cp0_unimplemented;
7824        }
7825         break;
7826     case CP0_REGISTER_14:
7827         switch (sel) {
7828         case CP0_REG14__EPC:
7829             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7830             tcg_gen_ext32s_tl(arg, arg);
7831             register_name = "EPC";
7832             break;
7833         default:
7834             goto cp0_unimplemented;
7835         }
7836         break;
7837     case CP0_REGISTER_15:
7838         switch (sel) {
7839         case CP0_REG15__PRID:
7840             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
7841             register_name = "PRid";
7842             break;
7843         case CP0_REG15__EBASE:
7844             check_insn(ctx, ISA_MIPS32R2);
7845             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
7846             tcg_gen_ext32s_tl(arg, arg);
7847             register_name = "EBase";
7848             break;
7849         case CP0_REG15__CMGCRBASE:
7850             check_insn(ctx, ISA_MIPS32R2);
7851             CP0_CHECK(ctx->cmgcr);
7852             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7853             tcg_gen_ext32s_tl(arg, arg);
7854             register_name = "CMGCRBase";
7855             break;
7856         default:
7857             goto cp0_unimplemented;
7858        }
7859         break;
7860     case CP0_REGISTER_16:
7861         switch (sel) {
7862         case CP0_REG16__CONFIG:
7863             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
7864             register_name = "Config";
7865             break;
7866         case CP0_REG16__CONFIG1:
7867             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
7868             register_name = "Config1";
7869             break;
7870         case CP0_REG16__CONFIG2:
7871             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7872             register_name = "Config2";
7873             break;
7874         case CP0_REG16__CONFIG3:
7875             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7876             register_name = "Config3";
7877             break;
7878         case CP0_REG16__CONFIG4:
7879             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7880             register_name = "Config4";
7881             break;
7882         case CP0_REG16__CONFIG5:
7883             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7884             register_name = "Config5";
7885             break;
7886         /* 6,7 are implementation dependent */
7887         case CP0_REG16__CONFIG6:
7888             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
7889             register_name = "Config6";
7890             break;
7891         case CP0_REG16__CONFIG7:
7892             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
7893             register_name = "Config7";
7894             break;
7895         default:
7896             goto cp0_unimplemented;
7897         }
7898         break;
7899     case CP0_REGISTER_17:
7900         switch (sel) {
7901         case CP0_REG17__LLADDR:
7902             gen_helper_mfc0_lladdr(arg, cpu_env);
7903             register_name = "LLAddr";
7904             break;
7905         case CP0_REG17__MAAR:
7906             CP0_CHECK(ctx->mrp);
7907             gen_helper_mfc0_maar(arg, cpu_env);
7908             register_name = "MAAR";
7909             break;
7910         case CP0_REG17__MAARI:
7911             CP0_CHECK(ctx->mrp);
7912             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7913             register_name = "MAARI";
7914             break;
7915         default:
7916             goto cp0_unimplemented;
7917         }
7918         break;
7919     case CP0_REGISTER_18:
7920         switch (sel) {
7921         case CP0_REG18__WATCHLO0:
7922         case CP0_REG18__WATCHLO1:
7923         case CP0_REG18__WATCHLO2:
7924         case CP0_REG18__WATCHLO3:
7925         case CP0_REG18__WATCHLO4:
7926         case CP0_REG18__WATCHLO5:
7927         case CP0_REG18__WATCHLO6:
7928         case CP0_REG18__WATCHLO7:
7929             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7930             gen_helper_1e0i(mfc0_watchlo, arg, sel);
7931             register_name = "WatchLo";
7932             break;
7933         default:
7934             goto cp0_unimplemented;
7935         }
7936         break;
7937     case CP0_REGISTER_19:
7938         switch (sel) {
7939         case CP0_REG19__WATCHHI0:
7940         case CP0_REG19__WATCHHI1:
7941         case CP0_REG19__WATCHHI2:
7942         case CP0_REG19__WATCHHI3:
7943         case CP0_REG19__WATCHHI4:
7944         case CP0_REG19__WATCHHI5:
7945         case CP0_REG19__WATCHHI6:
7946         case CP0_REG19__WATCHHI7:
7947             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7948             gen_helper_1e0i(mfc0_watchhi, arg, sel);
7949             register_name = "WatchHi";
7950             break;
7951         default:
7952             goto cp0_unimplemented;
7953         }
7954         break;
7955     case CP0_REGISTER_20:
7956         switch (sel) {
7957         case CP0_REG20__XCONTEXT:
7958 #if defined(TARGET_MIPS64)
7959             check_insn(ctx, ISA_MIPS3);
7960             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
7961             tcg_gen_ext32s_tl(arg, arg);
7962             register_name = "XContext";
7963             break;
7964 #endif
7965         default:
7966             goto cp0_unimplemented;
7967         }
7968         break;
7969     case CP0_REGISTER_21:
7970        /* Officially reserved, but sel 0 is used for R1x000 framemask */
7971         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7972         switch (sel) {
7973         case 0:
7974             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
7975             register_name = "Framemask";
7976             break;
7977         default:
7978             goto cp0_unimplemented;
7979         }
7980         break;
7981     case CP0_REGISTER_22:
7982         tcg_gen_movi_tl(arg, 0); /* unimplemented */
7983         register_name = "'Diagnostic"; /* implementation dependent */
7984         break;
7985     case CP0_REGISTER_23:
7986         switch (sel) {
7987         case CP0_REG23__DEBUG:
7988             gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
7989             register_name = "Debug";
7990             break;
7991         case CP0_REG23__TRACECONTROL:
7992             /* PDtrace support */
7993             /* gen_helper_mfc0_tracecontrol(arg);  */
7994             register_name = "TraceControl";
7995             goto cp0_unimplemented;
7996         case CP0_REG23__TRACECONTROL2:
7997             /* PDtrace support */
7998             /* gen_helper_mfc0_tracecontrol2(arg); */
7999             register_name = "TraceControl2";
8000             goto cp0_unimplemented;
8001         case CP0_REG23__USERTRACEDATA1:
8002             /* PDtrace support */
8003             /* gen_helper_mfc0_usertracedata1(arg);*/
8004             register_name = "UserTraceData1";
8005             goto cp0_unimplemented;
8006         case CP0_REG23__TRACEIBPC:
8007             /* PDtrace support */
8008             /* gen_helper_mfc0_traceibpc(arg);     */
8009             register_name = "TraceIBPC";
8010             goto cp0_unimplemented;
8011         case CP0_REG23__TRACEDBPC:
8012             /* PDtrace support */
8013             /* gen_helper_mfc0_tracedbpc(arg);     */
8014             register_name = "TraceDBPC";
8015             goto cp0_unimplemented;
8016         default:
8017             goto cp0_unimplemented;
8018         }
8019         break;
8020     case CP0_REGISTER_24:
8021         switch (sel) {
8022         case CP0_REG24__DEPC:
8023             /* EJTAG support */
8024             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8025             tcg_gen_ext32s_tl(arg, arg);
8026             register_name = "DEPC";
8027             break;
8028         default:
8029             goto cp0_unimplemented;
8030         }
8031         break;
8032     case CP0_REGISTER_25:
8033         switch (sel) {
8034         case CP0_REG25__PERFCTL0:
8035             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
8036             register_name = "Performance0";
8037             break;
8038         case CP0_REG25__PERFCNT0:
8039             /* gen_helper_mfc0_performance1(arg); */
8040             register_name = "Performance1";
8041             goto cp0_unimplemented;
8042         case CP0_REG25__PERFCTL1:
8043             /* gen_helper_mfc0_performance2(arg); */
8044             register_name = "Performance2";
8045             goto cp0_unimplemented;
8046         case CP0_REG25__PERFCNT1:
8047             /* gen_helper_mfc0_performance3(arg); */
8048             register_name = "Performance3";
8049             goto cp0_unimplemented;
8050         case CP0_REG25__PERFCTL2:
8051             /* gen_helper_mfc0_performance4(arg); */
8052             register_name = "Performance4";
8053             goto cp0_unimplemented;
8054         case CP0_REG25__PERFCNT2:
8055             /* gen_helper_mfc0_performance5(arg); */
8056             register_name = "Performance5";
8057             goto cp0_unimplemented;
8058         case CP0_REG25__PERFCTL3:
8059             /* gen_helper_mfc0_performance6(arg); */
8060             register_name = "Performance6";
8061             goto cp0_unimplemented;
8062         case CP0_REG25__PERFCNT3:
8063             /* gen_helper_mfc0_performance7(arg); */
8064             register_name = "Performance7";
8065             goto cp0_unimplemented;
8066         default:
8067             goto cp0_unimplemented;
8068         }
8069         break;
8070     case CP0_REGISTER_26:
8071         switch (sel) {
8072         case CP0_REG26__ERRCTL:
8073             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
8074             register_name = "ErrCtl";
8075             break;
8076         default:
8077             goto cp0_unimplemented;
8078         }
8079         break;
8080     case CP0_REGISTER_27:
8081         switch (sel) {
8082         case CP0_REG27__CACHERR:
8083             tcg_gen_movi_tl(arg, 0); /* unimplemented */
8084             register_name = "CacheErr";
8085             break;
8086         default:
8087             goto cp0_unimplemented;
8088         }
8089         break;
8090     case CP0_REGISTER_28:
8091         switch (sel) {
8092         case CP0_REG28__TAGLO:
8093         case CP0_REG28__TAGLO1:
8094         case CP0_REG28__TAGLO2:
8095         case CP0_REG28__TAGLO3:
8096             {
8097                 TCGv_i64 tmp = tcg_temp_new_i64();
8098                 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
8099                 gen_move_low32(arg, tmp);
8100                 tcg_temp_free_i64(tmp);
8101             }
8102             register_name = "TagLo";
8103             break;
8104         case CP0_REG28__DATALO:
8105         case CP0_REG28__DATALO1:
8106         case CP0_REG28__DATALO2:
8107         case CP0_REG28__DATALO3:
8108             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
8109             register_name = "DataLo";
8110             break;
8111         default:
8112             goto cp0_unimplemented;
8113         }
8114         break;
8115     case CP0_REGISTER_29:
8116         switch (sel) {
8117         case CP0_REG29__TAGHI:
8118         case CP0_REG29__TAGHI1:
8119         case CP0_REG29__TAGHI2:
8120         case CP0_REG29__TAGHI3:
8121             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
8122             register_name = "TagHi";
8123             break;
8124         case CP0_REG29__DATAHI:
8125         case CP0_REG29__DATAHI1:
8126         case CP0_REG29__DATAHI2:
8127         case CP0_REG29__DATAHI3:
8128             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
8129             register_name = "DataHi";
8130             break;
8131         default:
8132             goto cp0_unimplemented;
8133         }
8134         break;
8135     case CP0_REGISTER_30:
8136         switch (sel) {
8137         case CP0_REG30__ERROREPC:
8138             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8139             tcg_gen_ext32s_tl(arg, arg);
8140             register_name = "ErrorEPC";
8141             break;
8142         default:
8143             goto cp0_unimplemented;
8144         }
8145         break;
8146     case CP0_REGISTER_31:
8147         switch (sel) {
8148         case CP0_REG31__DESAVE:
8149             /* EJTAG support */
8150             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8151             register_name = "DESAVE";
8152             break;
8153         case CP0_REG31__KSCRATCH1:
8154         case CP0_REG31__KSCRATCH2:
8155         case CP0_REG31__KSCRATCH3:
8156         case CP0_REG31__KSCRATCH4:
8157         case CP0_REG31__KSCRATCH5:
8158         case CP0_REG31__KSCRATCH6:
8159             CP0_CHECK(ctx->kscrexist & (1 << sel));
8160             tcg_gen_ld_tl(arg, cpu_env,
8161                           offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
8162             tcg_gen_ext32s_tl(arg, arg);
8163             register_name = "KScratch";
8164             break;
8165         default:
8166             goto cp0_unimplemented;
8167         }
8168         break;
8169     default:
8170        goto cp0_unimplemented;
8171     }
8172     trace_mips_translate_c0("mfc0", register_name, reg, sel);
8173     return;
8174 
8175 cp0_unimplemented:
8176     qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n",
8177                   register_name, reg, sel);
8178     gen_mfc0_unimplemented(ctx, arg);
8179 }
8180 
gen_mtc0(DisasContext * ctx,TCGv arg,int reg,int sel)8181 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8182 {
8183     const char *register_name = "invalid";
8184 
8185     if (sel != 0) {
8186         check_insn(ctx, ISA_MIPS32);
8187     }
8188 
8189     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8190         gen_io_start();
8191     }
8192 
8193     switch (reg) {
8194     case CP0_REGISTER_00:
8195         switch (sel) {
8196         case CP0_REG00__INDEX:
8197             gen_helper_mtc0_index(cpu_env, arg);
8198             register_name = "Index";
8199             break;
8200         case CP0_REG00__MVPCONTROL:
8201             CP0_CHECK(ctx->insn_flags & ASE_MT);
8202             gen_helper_mtc0_mvpcontrol(cpu_env, arg);
8203             register_name = "MVPControl";
8204             break;
8205         case CP0_REG00__MVPCONF0:
8206             CP0_CHECK(ctx->insn_flags & ASE_MT);
8207             /* ignored */
8208             register_name = "MVPConf0";
8209             break;
8210         case CP0_REG00__MVPCONF1:
8211             CP0_CHECK(ctx->insn_flags & ASE_MT);
8212             /* ignored */
8213             register_name = "MVPConf1";
8214             break;
8215         case CP0_REG00__VPCONTROL:
8216             CP0_CHECK(ctx->vp);
8217             /* ignored */
8218             register_name = "VPControl";
8219             break;
8220         default:
8221             goto cp0_unimplemented;
8222         }
8223         break;
8224     case CP0_REGISTER_01:
8225         switch (sel) {
8226         case CP0_REG01__RANDOM:
8227             /* ignored */
8228             register_name = "Random";
8229             break;
8230         case CP0_REG01__VPECONTROL:
8231             CP0_CHECK(ctx->insn_flags & ASE_MT);
8232             gen_helper_mtc0_vpecontrol(cpu_env, arg);
8233             register_name = "VPEControl";
8234             break;
8235         case CP0_REG01__VPECONF0:
8236             CP0_CHECK(ctx->insn_flags & ASE_MT);
8237             gen_helper_mtc0_vpeconf0(cpu_env, arg);
8238             register_name = "VPEConf0";
8239             break;
8240         case CP0_REG01__VPECONF1:
8241             CP0_CHECK(ctx->insn_flags & ASE_MT);
8242             gen_helper_mtc0_vpeconf1(cpu_env, arg);
8243             register_name = "VPEConf1";
8244             break;
8245         case CP0_REG01__YQMASK:
8246             CP0_CHECK(ctx->insn_flags & ASE_MT);
8247             gen_helper_mtc0_yqmask(cpu_env, arg);
8248             register_name = "YQMask";
8249             break;
8250         case CP0_REG01__VPESCHEDULE:
8251             CP0_CHECK(ctx->insn_flags & ASE_MT);
8252             tcg_gen_st_tl(arg, cpu_env,
8253                           offsetof(CPUMIPSState, CP0_VPESchedule));
8254             register_name = "VPESchedule";
8255             break;
8256         case CP0_REG01__VPESCHEFBACK:
8257             CP0_CHECK(ctx->insn_flags & ASE_MT);
8258             tcg_gen_st_tl(arg, cpu_env,
8259                           offsetof(CPUMIPSState, CP0_VPEScheFBack));
8260             register_name = "VPEScheFBack";
8261             break;
8262         case CP0_REG01__VPEOPT:
8263             CP0_CHECK(ctx->insn_flags & ASE_MT);
8264             gen_helper_mtc0_vpeopt(cpu_env, arg);
8265             register_name = "VPEOpt";
8266             break;
8267         default:
8268             goto cp0_unimplemented;
8269         }
8270         break;
8271     case CP0_REGISTER_02:
8272         switch (sel) {
8273         case CP0_REG02__ENTRYLO0:
8274             gen_helper_mtc0_entrylo0(cpu_env, arg);
8275             register_name = "EntryLo0";
8276             break;
8277         case CP0_REG02__TCSTATUS:
8278             CP0_CHECK(ctx->insn_flags & ASE_MT);
8279             gen_helper_mtc0_tcstatus(cpu_env, arg);
8280             register_name = "TCStatus";
8281             break;
8282         case CP0_REG02__TCBIND:
8283             CP0_CHECK(ctx->insn_flags & ASE_MT);
8284             gen_helper_mtc0_tcbind(cpu_env, arg);
8285             register_name = "TCBind";
8286             break;
8287         case CP0_REG02__TCRESTART:
8288             CP0_CHECK(ctx->insn_flags & ASE_MT);
8289             gen_helper_mtc0_tcrestart(cpu_env, arg);
8290             register_name = "TCRestart";
8291             break;
8292         case CP0_REG02__TCHALT:
8293             CP0_CHECK(ctx->insn_flags & ASE_MT);
8294             gen_helper_mtc0_tchalt(cpu_env, arg);
8295             register_name = "TCHalt";
8296             break;
8297         case CP0_REG02__TCCONTEXT:
8298             CP0_CHECK(ctx->insn_flags & ASE_MT);
8299             gen_helper_mtc0_tccontext(cpu_env, arg);
8300             register_name = "TCContext";
8301             break;
8302         case CP0_REG02__TCSCHEDULE:
8303             CP0_CHECK(ctx->insn_flags & ASE_MT);
8304             gen_helper_mtc0_tcschedule(cpu_env, arg);
8305             register_name = "TCSchedule";
8306             break;
8307         case CP0_REG02__TCSCHEFBACK:
8308             CP0_CHECK(ctx->insn_flags & ASE_MT);
8309             gen_helper_mtc0_tcschefback(cpu_env, arg);
8310             register_name = "TCScheFBack";
8311             break;
8312         default:
8313             goto cp0_unimplemented;
8314         }
8315         break;
8316     case CP0_REGISTER_03:
8317         switch (sel) {
8318         case CP0_REG03__ENTRYLO1:
8319             gen_helper_mtc0_entrylo1(cpu_env, arg);
8320             register_name = "EntryLo1";
8321             break;
8322         case CP0_REG03__GLOBALNUM:
8323             CP0_CHECK(ctx->vp);
8324             /* ignored */
8325             register_name = "GlobalNumber";
8326             break;
8327         default:
8328             goto cp0_unimplemented;
8329         }
8330         break;
8331     case CP0_REGISTER_04:
8332         switch (sel) {
8333         case CP0_REG04__CONTEXT:
8334             gen_helper_mtc0_context(cpu_env, arg);
8335             register_name = "Context";
8336             break;
8337         case CP0_REG04__CONTEXTCONFIG:
8338             /* SmartMIPS ASE */
8339             /* gen_helper_mtc0_contextconfig(arg); */
8340             register_name = "ContextConfig";
8341             goto cp0_unimplemented;
8342         case CP0_REG04__USERLOCAL:
8343             CP0_CHECK(ctx->ulri);
8344             tcg_gen_st_tl(arg, cpu_env,
8345                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8346             register_name = "UserLocal";
8347             break;
8348         case CP0_REG04__MMID:
8349             CP0_CHECK(ctx->mi);
8350             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID));
8351             register_name = "MMID";
8352             break;
8353         default:
8354             goto cp0_unimplemented;
8355         }
8356         break;
8357     case CP0_REGISTER_05:
8358         switch (sel) {
8359         case CP0_REG05__PAGEMASK:
8360             gen_helper_mtc0_pagemask(cpu_env, arg);
8361             register_name = "PageMask";
8362             break;
8363         case CP0_REG05__PAGEGRAIN:
8364             check_insn(ctx, ISA_MIPS32R2);
8365             gen_helper_mtc0_pagegrain(cpu_env, arg);
8366             register_name = "PageGrain";
8367             ctx->base.is_jmp = DISAS_STOP;
8368             break;
8369         case CP0_REG05__SEGCTL0:
8370             CP0_CHECK(ctx->sc);
8371             gen_helper_mtc0_segctl0(cpu_env, arg);
8372             register_name = "SegCtl0";
8373             break;
8374         case CP0_REG05__SEGCTL1:
8375             CP0_CHECK(ctx->sc);
8376             gen_helper_mtc0_segctl1(cpu_env, arg);
8377             register_name = "SegCtl1";
8378             break;
8379         case CP0_REG05__SEGCTL2:
8380             CP0_CHECK(ctx->sc);
8381             gen_helper_mtc0_segctl2(cpu_env, arg);
8382             register_name = "SegCtl2";
8383             break;
8384         case CP0_REG05__PWBASE:
8385             check_pw(ctx);
8386             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
8387             register_name = "PWBase";
8388             break;
8389         case CP0_REG05__PWFIELD:
8390             check_pw(ctx);
8391             gen_helper_mtc0_pwfield(cpu_env, arg);
8392             register_name = "PWField";
8393             break;
8394         case CP0_REG05__PWSIZE:
8395             check_pw(ctx);
8396             gen_helper_mtc0_pwsize(cpu_env, arg);
8397             register_name = "PWSize";
8398             break;
8399         default:
8400             goto cp0_unimplemented;
8401         }
8402         break;
8403     case CP0_REGISTER_06:
8404         switch (sel) {
8405         case CP0_REG06__WIRED:
8406             gen_helper_mtc0_wired(cpu_env, arg);
8407             register_name = "Wired";
8408             break;
8409         case CP0_REG06__SRSCONF0:
8410             check_insn(ctx, ISA_MIPS32R2);
8411             gen_helper_mtc0_srsconf0(cpu_env, arg);
8412             register_name = "SRSConf0";
8413             break;
8414         case CP0_REG06__SRSCONF1:
8415             check_insn(ctx, ISA_MIPS32R2);
8416             gen_helper_mtc0_srsconf1(cpu_env, arg);
8417             register_name = "SRSConf1";
8418             break;
8419         case CP0_REG06__SRSCONF2:
8420             check_insn(ctx, ISA_MIPS32R2);
8421             gen_helper_mtc0_srsconf2(cpu_env, arg);
8422             register_name = "SRSConf2";
8423             break;
8424         case CP0_REG06__SRSCONF3:
8425             check_insn(ctx, ISA_MIPS32R2);
8426             gen_helper_mtc0_srsconf3(cpu_env, arg);
8427             register_name = "SRSConf3";
8428             break;
8429         case CP0_REG06__SRSCONF4:
8430             check_insn(ctx, ISA_MIPS32R2);
8431             gen_helper_mtc0_srsconf4(cpu_env, arg);
8432             register_name = "SRSConf4";
8433             break;
8434         case CP0_REG06__PWCTL:
8435             check_pw(ctx);
8436             gen_helper_mtc0_pwctl(cpu_env, arg);
8437             register_name = "PWCtl";
8438             break;
8439         default:
8440             goto cp0_unimplemented;
8441         }
8442         break;
8443     case CP0_REGISTER_07:
8444         switch (sel) {
8445         case CP0_REG07__HWRENA:
8446             check_insn(ctx, ISA_MIPS32R2);
8447             gen_helper_mtc0_hwrena(cpu_env, arg);
8448             ctx->base.is_jmp = DISAS_STOP;
8449             register_name = "HWREna";
8450             break;
8451         default:
8452             goto cp0_unimplemented;
8453         }
8454         break;
8455     case CP0_REGISTER_08:
8456         switch (sel) {
8457         case CP0_REG08__BADVADDR:
8458             /* ignored */
8459             register_name = "BadVAddr";
8460             break;
8461         case CP0_REG08__BADINSTR:
8462             /* ignored */
8463             register_name = "BadInstr";
8464             break;
8465         case CP0_REG08__BADINSTRP:
8466             /* ignored */
8467             register_name = "BadInstrP";
8468             break;
8469         case CP0_REG08__BADINSTRX:
8470             /* ignored */
8471             register_name = "BadInstrX";
8472             break;
8473         default:
8474             goto cp0_unimplemented;
8475         }
8476         break;
8477     case CP0_REGISTER_09:
8478         switch (sel) {
8479         case CP0_REG09__COUNT:
8480             gen_helper_mtc0_count(cpu_env, arg);
8481             register_name = "Count";
8482             break;
8483         case CP0_REG09__SAARI:
8484             CP0_CHECK(ctx->saar);
8485             gen_helper_mtc0_saari(cpu_env, arg);
8486             register_name = "SAARI";
8487             break;
8488         case CP0_REG09__SAAR:
8489             CP0_CHECK(ctx->saar);
8490             gen_helper_mtc0_saar(cpu_env, arg);
8491             register_name = "SAAR";
8492             break;
8493         default:
8494             goto cp0_unimplemented;
8495         }
8496         break;
8497     case CP0_REGISTER_10:
8498         switch (sel) {
8499         case CP0_REG10__ENTRYHI:
8500             gen_helper_mtc0_entryhi(cpu_env, arg);
8501             register_name = "EntryHi";
8502             break;
8503         default:
8504             goto cp0_unimplemented;
8505         }
8506         break;
8507     case CP0_REGISTER_11:
8508         switch (sel) {
8509         case CP0_REG11__COMPARE:
8510             gen_helper_mtc0_compare(cpu_env, arg);
8511             register_name = "Compare";
8512             break;
8513         /* 6,7 are implementation dependent */
8514         default:
8515             goto cp0_unimplemented;
8516         }
8517         break;
8518     case CP0_REGISTER_12:
8519         switch (sel) {
8520         case CP0_REG12__STATUS:
8521             save_cpu_state(ctx, 1);
8522             gen_helper_mtc0_status(cpu_env, arg);
8523             /* DISAS_STOP isn't good enough here, hflags may have changed. */
8524             gen_save_pc(ctx->base.pc_next + 4);
8525             ctx->base.is_jmp = DISAS_EXIT;
8526             register_name = "Status";
8527             break;
8528         case CP0_REG12__INTCTL:
8529             check_insn(ctx, ISA_MIPS32R2);
8530             gen_helper_mtc0_intctl(cpu_env, arg);
8531             /* Stop translation as we may have switched the execution mode */
8532             ctx->base.is_jmp = DISAS_STOP;
8533             register_name = "IntCtl";
8534             break;
8535         case CP0_REG12__SRSCTL:
8536             check_insn(ctx, ISA_MIPS32R2);
8537             gen_helper_mtc0_srsctl(cpu_env, arg);
8538             /* Stop translation as we may have switched the execution mode */
8539             ctx->base.is_jmp = DISAS_STOP;
8540             register_name = "SRSCtl";
8541             break;
8542         case CP0_REG12__SRSMAP:
8543             check_insn(ctx, ISA_MIPS32R2);
8544             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8545             /* Stop translation as we may have switched the execution mode */
8546             ctx->base.is_jmp = DISAS_STOP;
8547             register_name = "SRSMap";
8548             break;
8549         default:
8550             goto cp0_unimplemented;
8551         }
8552         break;
8553     case CP0_REGISTER_13:
8554         switch (sel) {
8555         case CP0_REG13__CAUSE:
8556             save_cpu_state(ctx, 1);
8557             gen_helper_mtc0_cause(cpu_env, arg);
8558             /*
8559              * Stop translation as we may have triggered an interrupt.
8560              * DISAS_STOP isn't sufficient, we need to ensure we break out of
8561              * translated code to check for pending interrupts.
8562              */
8563             gen_save_pc(ctx->base.pc_next + 4);
8564             ctx->base.is_jmp = DISAS_EXIT;
8565             register_name = "Cause";
8566             break;
8567         default:
8568             goto cp0_unimplemented;
8569         }
8570         break;
8571     case CP0_REGISTER_14:
8572         switch (sel) {
8573         case CP0_REG14__EPC:
8574             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
8575             register_name = "EPC";
8576             break;
8577         default:
8578             goto cp0_unimplemented;
8579         }
8580         break;
8581     case CP0_REGISTER_15:
8582         switch (sel) {
8583         case CP0_REG15__PRID:
8584             /* ignored */
8585             register_name = "PRid";
8586             break;
8587         case CP0_REG15__EBASE:
8588             check_insn(ctx, ISA_MIPS32R2);
8589             gen_helper_mtc0_ebase(cpu_env, arg);
8590             register_name = "EBase";
8591             break;
8592         default:
8593             goto cp0_unimplemented;
8594         }
8595         break;
8596     case CP0_REGISTER_16:
8597         switch (sel) {
8598         case CP0_REG16__CONFIG:
8599             gen_helper_mtc0_config0(cpu_env, arg);
8600             register_name = "Config";
8601             /* Stop translation as we may have switched the execution mode */
8602             ctx->base.is_jmp = DISAS_STOP;
8603             break;
8604         case CP0_REG16__CONFIG1:
8605             /* ignored, read only */
8606             register_name = "Config1";
8607             break;
8608         case CP0_REG16__CONFIG2:
8609             gen_helper_mtc0_config2(cpu_env, arg);
8610             register_name = "Config2";
8611             /* Stop translation as we may have switched the execution mode */
8612             ctx->base.is_jmp = DISAS_STOP;
8613             break;
8614         case CP0_REG16__CONFIG3:
8615             gen_helper_mtc0_config3(cpu_env, arg);
8616             register_name = "Config3";
8617             /* Stop translation as we may have switched the execution mode */
8618             ctx->base.is_jmp = DISAS_STOP;
8619             break;
8620         case CP0_REG16__CONFIG4:
8621             gen_helper_mtc0_config4(cpu_env, arg);
8622             register_name = "Config4";
8623             ctx->base.is_jmp = DISAS_STOP;
8624             break;
8625         case CP0_REG16__CONFIG5:
8626             gen_helper_mtc0_config5(cpu_env, arg);
8627             register_name = "Config5";
8628             /* Stop translation as we may have switched the execution mode */
8629             ctx->base.is_jmp = DISAS_STOP;
8630             break;
8631         /* 6,7 are implementation dependent */
8632         case CP0_REG16__CONFIG6:
8633             /* ignored */
8634             register_name = "Config6";
8635             break;
8636         case CP0_REG16__CONFIG7:
8637             /* ignored */
8638             register_name = "Config7";
8639             break;
8640         default:
8641             register_name = "Invalid config selector";
8642             goto cp0_unimplemented;
8643         }
8644         break;
8645     case CP0_REGISTER_17:
8646         switch (sel) {
8647         case CP0_REG17__LLADDR:
8648             gen_helper_mtc0_lladdr(cpu_env, arg);
8649             register_name = "LLAddr";
8650             break;
8651         case CP0_REG17__MAAR:
8652             CP0_CHECK(ctx->mrp);
8653             gen_helper_mtc0_maar(cpu_env, arg);
8654             register_name = "MAAR";
8655             break;
8656         case CP0_REG17__MAARI:
8657             CP0_CHECK(ctx->mrp);
8658             gen_helper_mtc0_maari(cpu_env, arg);
8659             register_name = "MAARI";
8660             break;
8661         default:
8662             goto cp0_unimplemented;
8663         }
8664         break;
8665     case CP0_REGISTER_18:
8666         switch (sel) {
8667         case CP0_REG18__WATCHLO0:
8668         case CP0_REG18__WATCHLO1:
8669         case CP0_REG18__WATCHLO2:
8670         case CP0_REG18__WATCHLO3:
8671         case CP0_REG18__WATCHLO4:
8672         case CP0_REG18__WATCHLO5:
8673         case CP0_REG18__WATCHLO6:
8674         case CP0_REG18__WATCHLO7:
8675             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8676             gen_helper_0e1i(mtc0_watchlo, arg, sel);
8677             register_name = "WatchLo";
8678             break;
8679         default:
8680             goto cp0_unimplemented;
8681         }
8682         break;
8683     case CP0_REGISTER_19:
8684         switch (sel) {
8685         case CP0_REG19__WATCHHI0:
8686         case CP0_REG19__WATCHHI1:
8687         case CP0_REG19__WATCHHI2:
8688         case CP0_REG19__WATCHHI3:
8689         case CP0_REG19__WATCHHI4:
8690         case CP0_REG19__WATCHHI5:
8691         case CP0_REG19__WATCHHI6:
8692         case CP0_REG19__WATCHHI7:
8693             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8694             gen_helper_0e1i(mtc0_watchhi, arg, sel);
8695             register_name = "WatchHi";
8696             break;
8697         default:
8698             goto cp0_unimplemented;
8699         }
8700         break;
8701     case CP0_REGISTER_20:
8702         switch (sel) {
8703         case CP0_REG20__XCONTEXT:
8704 #if defined(TARGET_MIPS64)
8705             check_insn(ctx, ISA_MIPS3);
8706             gen_helper_mtc0_xcontext(cpu_env, arg);
8707             register_name = "XContext";
8708             break;
8709 #endif
8710         default:
8711             goto cp0_unimplemented;
8712         }
8713         break;
8714     case CP0_REGISTER_21:
8715        /* Officially reserved, but sel 0 is used for R1x000 framemask */
8716         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8717         switch (sel) {
8718         case 0:
8719             gen_helper_mtc0_framemask(cpu_env, arg);
8720             register_name = "Framemask";
8721             break;
8722         default:
8723             goto cp0_unimplemented;
8724         }
8725         break;
8726     case CP0_REGISTER_22:
8727         /* ignored */
8728         register_name = "Diagnostic"; /* implementation dependent */
8729         break;
8730     case CP0_REGISTER_23:
8731         switch (sel) {
8732         case CP0_REG23__DEBUG:
8733             gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8734             /* DISAS_STOP isn't good enough here, hflags may have changed. */
8735             gen_save_pc(ctx->base.pc_next + 4);
8736             ctx->base.is_jmp = DISAS_EXIT;
8737             register_name = "Debug";
8738             break;
8739         case CP0_REG23__TRACECONTROL:
8740             /* PDtrace support */
8741             /* gen_helper_mtc0_tracecontrol(cpu_env, arg);  */
8742             register_name = "TraceControl";
8743             /* Stop translation as we may have switched the execution mode */
8744             ctx->base.is_jmp = DISAS_STOP;
8745             goto cp0_unimplemented;
8746         case CP0_REG23__TRACECONTROL2:
8747             /* PDtrace support */
8748             /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
8749             register_name = "TraceControl2";
8750             /* Stop translation as we may have switched the execution mode */
8751             ctx->base.is_jmp = DISAS_STOP;
8752             goto cp0_unimplemented;
8753         case CP0_REG23__USERTRACEDATA1:
8754             /* Stop translation as we may have switched the execution mode */
8755             ctx->base.is_jmp = DISAS_STOP;
8756             /* PDtrace support */
8757             /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
8758             register_name = "UserTraceData";
8759             /* Stop translation as we may have switched the execution mode */
8760             ctx->base.is_jmp = DISAS_STOP;
8761             goto cp0_unimplemented;
8762         case CP0_REG23__TRACEIBPC:
8763             /* PDtrace support */
8764             /* gen_helper_mtc0_traceibpc(cpu_env, arg);     */
8765             /* Stop translation as we may have switched the execution mode */
8766             ctx->base.is_jmp = DISAS_STOP;
8767             register_name = "TraceIBPC";
8768             goto cp0_unimplemented;
8769         case CP0_REG23__TRACEDBPC:
8770             /* PDtrace support */
8771             /* gen_helper_mtc0_tracedbpc(cpu_env, arg);     */
8772             /* Stop translation as we may have switched the execution mode */
8773             ctx->base.is_jmp = DISAS_STOP;
8774             register_name = "TraceDBPC";
8775             goto cp0_unimplemented;
8776         default:
8777             goto cp0_unimplemented;
8778         }
8779         break;
8780     case CP0_REGISTER_24:
8781         switch (sel) {
8782         case CP0_REG24__DEPC:
8783             /* EJTAG support */
8784             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8785             register_name = "DEPC";
8786             break;
8787         default:
8788             goto cp0_unimplemented;
8789         }
8790         break;
8791     case CP0_REGISTER_25:
8792         switch (sel) {
8793         case CP0_REG25__PERFCTL0:
8794             gen_helper_mtc0_performance0(cpu_env, arg);
8795             register_name = "Performance0";
8796             break;
8797         case CP0_REG25__PERFCNT0:
8798             /* gen_helper_mtc0_performance1(arg); */
8799             register_name = "Performance1";
8800             goto cp0_unimplemented;
8801         case CP0_REG25__PERFCTL1:
8802             /* gen_helper_mtc0_performance2(arg); */
8803             register_name = "Performance2";
8804             goto cp0_unimplemented;
8805         case CP0_REG25__PERFCNT1:
8806             /* gen_helper_mtc0_performance3(arg); */
8807             register_name = "Performance3";
8808             goto cp0_unimplemented;
8809         case CP0_REG25__PERFCTL2:
8810             /* gen_helper_mtc0_performance4(arg); */
8811             register_name = "Performance4";
8812             goto cp0_unimplemented;
8813         case CP0_REG25__PERFCNT2:
8814             /* gen_helper_mtc0_performance5(arg); */
8815             register_name = "Performance5";
8816             goto cp0_unimplemented;
8817         case CP0_REG25__PERFCTL3:
8818             /* gen_helper_mtc0_performance6(arg); */
8819             register_name = "Performance6";
8820             goto cp0_unimplemented;
8821         case CP0_REG25__PERFCNT3:
8822             /* gen_helper_mtc0_performance7(arg); */
8823             register_name = "Performance7";
8824             goto cp0_unimplemented;
8825         default:
8826             goto cp0_unimplemented;
8827         }
8828        break;
8829     case CP0_REGISTER_26:
8830         switch (sel) {
8831         case CP0_REG26__ERRCTL:
8832             gen_helper_mtc0_errctl(cpu_env, arg);
8833             ctx->base.is_jmp = DISAS_STOP;
8834             register_name = "ErrCtl";
8835             break;
8836         default:
8837             goto cp0_unimplemented;
8838         }
8839         break;
8840     case CP0_REGISTER_27:
8841         switch (sel) {
8842         case CP0_REG27__CACHERR:
8843             /* ignored */
8844             register_name = "CacheErr";
8845             break;
8846         default:
8847             goto cp0_unimplemented;
8848         }
8849        break;
8850     case CP0_REGISTER_28:
8851         switch (sel) {
8852         case CP0_REG28__TAGLO:
8853         case CP0_REG28__TAGLO1:
8854         case CP0_REG28__TAGLO2:
8855         case CP0_REG28__TAGLO3:
8856             gen_helper_mtc0_taglo(cpu_env, arg);
8857             register_name = "TagLo";
8858             break;
8859         case CP0_REG28__DATALO:
8860         case CP0_REG28__DATALO1:
8861         case CP0_REG28__DATALO2:
8862         case CP0_REG28__DATALO3:
8863             gen_helper_mtc0_datalo(cpu_env, arg);
8864             register_name = "DataLo";
8865             break;
8866         default:
8867             goto cp0_unimplemented;
8868         }
8869         break;
8870     case CP0_REGISTER_29:
8871         switch (sel) {
8872         case CP0_REG29__TAGHI:
8873         case CP0_REG29__TAGHI1:
8874         case CP0_REG29__TAGHI2:
8875         case CP0_REG29__TAGHI3:
8876             gen_helper_mtc0_taghi(cpu_env, arg);
8877             register_name = "TagHi";
8878             break;
8879         case CP0_REG29__DATAHI:
8880         case CP0_REG29__DATAHI1:
8881         case CP0_REG29__DATAHI2:
8882         case CP0_REG29__DATAHI3:
8883             gen_helper_mtc0_datahi(cpu_env, arg);
8884             register_name = "DataHi";
8885             break;
8886         default:
8887             register_name = "invalid sel";
8888             goto cp0_unimplemented;
8889         }
8890        break;
8891     case CP0_REGISTER_30:
8892         switch (sel) {
8893         case CP0_REG30__ERROREPC:
8894             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8895             register_name = "ErrorEPC";
8896             break;
8897         default:
8898             goto cp0_unimplemented;
8899         }
8900         break;
8901     case CP0_REGISTER_31:
8902         switch (sel) {
8903         case CP0_REG31__DESAVE:
8904             /* EJTAG support */
8905             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8906             register_name = "DESAVE";
8907             break;
8908         case CP0_REG31__KSCRATCH1:
8909         case CP0_REG31__KSCRATCH2:
8910         case CP0_REG31__KSCRATCH3:
8911         case CP0_REG31__KSCRATCH4:
8912         case CP0_REG31__KSCRATCH5:
8913         case CP0_REG31__KSCRATCH6:
8914             CP0_CHECK(ctx->kscrexist & (1 << sel));
8915             tcg_gen_st_tl(arg, cpu_env,
8916                           offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
8917             register_name = "KScratch";
8918             break;
8919         default:
8920             goto cp0_unimplemented;
8921         }
8922         break;
8923     default:
8924        goto cp0_unimplemented;
8925     }
8926     trace_mips_translate_c0("mtc0", register_name, reg, sel);
8927 
8928     /* For simplicity assume that all writes can cause interrupts.  */
8929     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8930         /*
8931          * DISAS_STOP isn't sufficient, we need to ensure we break out of
8932          * translated code to check for pending interrupts.
8933          */
8934         gen_save_pc(ctx->base.pc_next + 4);
8935         ctx->base.is_jmp = DISAS_EXIT;
8936     }
8937     return;
8938 
8939 cp0_unimplemented:
8940     qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n",
8941                   register_name, reg, sel);
8942 }
8943 
8944 #if defined(TARGET_MIPS64)
gen_dmfc0(DisasContext * ctx,TCGv arg,int reg,int sel)8945 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8946 {
8947     const char *register_name = "invalid";
8948 
8949     if (sel != 0) {
8950         check_insn(ctx, ISA_MIPS64);
8951     }
8952 
8953     switch (reg) {
8954     case CP0_REGISTER_00:
8955         switch (sel) {
8956         case CP0_REG00__INDEX:
8957             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
8958             register_name = "Index";
8959             break;
8960         case CP0_REG00__MVPCONTROL:
8961             CP0_CHECK(ctx->insn_flags & ASE_MT);
8962             gen_helper_mfc0_mvpcontrol(arg, cpu_env);
8963             register_name = "MVPControl";
8964             break;
8965         case CP0_REG00__MVPCONF0:
8966             CP0_CHECK(ctx->insn_flags & ASE_MT);
8967             gen_helper_mfc0_mvpconf0(arg, cpu_env);
8968             register_name = "MVPConf0";
8969             break;
8970         case CP0_REG00__MVPCONF1:
8971             CP0_CHECK(ctx->insn_flags & ASE_MT);
8972             gen_helper_mfc0_mvpconf1(arg, cpu_env);
8973             register_name = "MVPConf1";
8974             break;
8975         case CP0_REG00__VPCONTROL:
8976             CP0_CHECK(ctx->vp);
8977             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
8978             register_name = "VPControl";
8979             break;
8980         default:
8981             goto cp0_unimplemented;
8982         }
8983         break;
8984     case CP0_REGISTER_01:
8985         switch (sel) {
8986         case CP0_REG01__RANDOM:
8987             CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8988             gen_helper_mfc0_random(arg, cpu_env);
8989             register_name = "Random";
8990             break;
8991         case CP0_REG01__VPECONTROL:
8992             CP0_CHECK(ctx->insn_flags & ASE_MT);
8993             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
8994             register_name = "VPEControl";
8995             break;
8996         case CP0_REG01__VPECONF0:
8997             CP0_CHECK(ctx->insn_flags & ASE_MT);
8998             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
8999             register_name = "VPEConf0";
9000             break;
9001         case CP0_REG01__VPECONF1:
9002             CP0_CHECK(ctx->insn_flags & ASE_MT);
9003             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9004             register_name = "VPEConf1";
9005             break;
9006         case CP0_REG01__YQMASK:
9007             CP0_CHECK(ctx->insn_flags & ASE_MT);
9008             tcg_gen_ld_tl(arg, cpu_env,
9009                           offsetof(CPUMIPSState, CP0_YQMask));
9010             register_name = "YQMask";
9011             break;
9012         case CP0_REG01__VPESCHEDULE:
9013             CP0_CHECK(ctx->insn_flags & ASE_MT);
9014             tcg_gen_ld_tl(arg, cpu_env,
9015                           offsetof(CPUMIPSState, CP0_VPESchedule));
9016             register_name = "VPESchedule";
9017             break;
9018         case CP0_REG01__VPESCHEFBACK:
9019             CP0_CHECK(ctx->insn_flags & ASE_MT);
9020             tcg_gen_ld_tl(arg, cpu_env,
9021                           offsetof(CPUMIPSState, CP0_VPEScheFBack));
9022             register_name = "VPEScheFBack";
9023             break;
9024         case CP0_REG01__VPEOPT:
9025             CP0_CHECK(ctx->insn_flags & ASE_MT);
9026             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9027             register_name = "VPEOpt";
9028             break;
9029         default:
9030             goto cp0_unimplemented;
9031         }
9032         break;
9033     case CP0_REGISTER_02:
9034         switch (sel) {
9035         case CP0_REG02__ENTRYLO0:
9036             tcg_gen_ld_tl(arg, cpu_env,
9037                           offsetof(CPUMIPSState, CP0_EntryLo0));
9038             register_name = "EntryLo0";
9039             break;
9040         case CP0_REG02__TCSTATUS:
9041             CP0_CHECK(ctx->insn_flags & ASE_MT);
9042             gen_helper_mfc0_tcstatus(arg, cpu_env);
9043             register_name = "TCStatus";
9044             break;
9045         case CP0_REG02__TCBIND:
9046             CP0_CHECK(ctx->insn_flags & ASE_MT);
9047             gen_helper_mfc0_tcbind(arg, cpu_env);
9048             register_name = "TCBind";
9049             break;
9050         case CP0_REG02__TCRESTART:
9051             CP0_CHECK(ctx->insn_flags & ASE_MT);
9052             gen_helper_dmfc0_tcrestart(arg, cpu_env);
9053             register_name = "TCRestart";
9054             break;
9055         case CP0_REG02__TCHALT:
9056             CP0_CHECK(ctx->insn_flags & ASE_MT);
9057             gen_helper_dmfc0_tchalt(arg, cpu_env);
9058             register_name = "TCHalt";
9059             break;
9060         case CP0_REG02__TCCONTEXT:
9061             CP0_CHECK(ctx->insn_flags & ASE_MT);
9062             gen_helper_dmfc0_tccontext(arg, cpu_env);
9063             register_name = "TCContext";
9064             break;
9065         case CP0_REG02__TCSCHEDULE:
9066             CP0_CHECK(ctx->insn_flags & ASE_MT);
9067             gen_helper_dmfc0_tcschedule(arg, cpu_env);
9068             register_name = "TCSchedule";
9069             break;
9070         case CP0_REG02__TCSCHEFBACK:
9071             CP0_CHECK(ctx->insn_flags & ASE_MT);
9072             gen_helper_dmfc0_tcschefback(arg, cpu_env);
9073             register_name = "TCScheFBack";
9074             break;
9075         default:
9076             goto cp0_unimplemented;
9077         }
9078         break;
9079     case CP0_REGISTER_03:
9080         switch (sel) {
9081         case CP0_REG03__ENTRYLO1:
9082             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
9083             register_name = "EntryLo1";
9084             break;
9085         case CP0_REG03__GLOBALNUM:
9086             CP0_CHECK(ctx->vp);
9087             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
9088             register_name = "GlobalNumber";
9089             break;
9090         default:
9091             goto cp0_unimplemented;
9092         }
9093         break;
9094     case CP0_REGISTER_04:
9095         switch (sel) {
9096         case CP0_REG04__CONTEXT:
9097             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
9098             register_name = "Context";
9099             break;
9100         case CP0_REG04__CONTEXTCONFIG:
9101             /* SmartMIPS ASE */
9102             /* gen_helper_dmfc0_contextconfig(arg); */
9103             register_name = "ContextConfig";
9104             goto cp0_unimplemented;
9105         case CP0_REG04__USERLOCAL:
9106             CP0_CHECK(ctx->ulri);
9107             tcg_gen_ld_tl(arg, cpu_env,
9108                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
9109             register_name = "UserLocal";
9110             break;
9111         case CP0_REG04__MMID:
9112             CP0_CHECK(ctx->mi);
9113             gen_helper_mtc0_memorymapid(cpu_env, arg);
9114             register_name = "MMID";
9115             break;
9116         default:
9117             goto cp0_unimplemented;
9118         }
9119         break;
9120     case CP0_REGISTER_05:
9121         switch (sel) {
9122         case CP0_REG05__PAGEMASK:
9123             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
9124             register_name = "PageMask";
9125             break;
9126         case CP0_REG05__PAGEGRAIN:
9127             check_insn(ctx, ISA_MIPS32R2);
9128             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
9129             register_name = "PageGrain";
9130             break;
9131         case CP0_REG05__SEGCTL0:
9132             CP0_CHECK(ctx->sc);
9133             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
9134             register_name = "SegCtl0";
9135             break;
9136         case CP0_REG05__SEGCTL1:
9137             CP0_CHECK(ctx->sc);
9138             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
9139             register_name = "SegCtl1";
9140             break;
9141         case CP0_REG05__SEGCTL2:
9142             CP0_CHECK(ctx->sc);
9143             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
9144             register_name = "SegCtl2";
9145             break;
9146         case CP0_REG05__PWBASE:
9147             check_pw(ctx);
9148             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
9149             register_name = "PWBase";
9150             break;
9151         case CP0_REG05__PWFIELD:
9152             check_pw(ctx);
9153             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
9154             register_name = "PWField";
9155             break;
9156         case CP0_REG05__PWSIZE:
9157             check_pw(ctx);
9158             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
9159             register_name = "PWSize";
9160             break;
9161         default:
9162             goto cp0_unimplemented;
9163         }
9164         break;
9165     case CP0_REGISTER_06:
9166         switch (sel) {
9167         case CP0_REG06__WIRED:
9168             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
9169             register_name = "Wired";
9170             break;
9171         case CP0_REG06__SRSCONF0:
9172             check_insn(ctx, ISA_MIPS32R2);
9173             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
9174             register_name = "SRSConf0";
9175             break;
9176         case CP0_REG06__SRSCONF1:
9177             check_insn(ctx, ISA_MIPS32R2);
9178             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
9179             register_name = "SRSConf1";
9180             break;
9181         case CP0_REG06__SRSCONF2:
9182             check_insn(ctx, ISA_MIPS32R2);
9183             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
9184             register_name = "SRSConf2";
9185             break;
9186         case CP0_REG06__SRSCONF3:
9187             check_insn(ctx, ISA_MIPS32R2);
9188             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
9189             register_name = "SRSConf3";
9190             break;
9191         case CP0_REG06__SRSCONF4:
9192             check_insn(ctx, ISA_MIPS32R2);
9193             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
9194             register_name = "SRSConf4";
9195             break;
9196         case CP0_REG06__PWCTL:
9197             check_pw(ctx);
9198             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
9199             register_name = "PWCtl";
9200             break;
9201         default:
9202             goto cp0_unimplemented;
9203         }
9204         break;
9205     case CP0_REGISTER_07:
9206         switch (sel) {
9207         case CP0_REG07__HWRENA:
9208             check_insn(ctx, ISA_MIPS32R2);
9209             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
9210             register_name = "HWREna";
9211             break;
9212         default:
9213             goto cp0_unimplemented;
9214         }
9215         break;
9216     case CP0_REGISTER_08:
9217         switch (sel) {
9218         case CP0_REG08__BADVADDR:
9219             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
9220             register_name = "BadVAddr";
9221             break;
9222         case CP0_REG08__BADINSTR:
9223             CP0_CHECK(ctx->bi);
9224             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
9225             register_name = "BadInstr";
9226             break;
9227         case CP0_REG08__BADINSTRP:
9228             CP0_CHECK(ctx->bp);
9229             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
9230             register_name = "BadInstrP";
9231             break;
9232         case CP0_REG08__BADINSTRX:
9233             CP0_CHECK(ctx->bi);
9234             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
9235             tcg_gen_andi_tl(arg, arg, ~0xffff);
9236             register_name = "BadInstrX";
9237             break;
9238         default:
9239             goto cp0_unimplemented;
9240         }
9241         break;
9242     case CP0_REGISTER_09:
9243         switch (sel) {
9244         case CP0_REG09__COUNT:
9245             /* Mark as an IO operation because we read the time.  */
9246             if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
9247                 gen_io_start();
9248             }
9249             gen_helper_mfc0_count(arg, cpu_env);
9250             /*
9251              * Break the TB to be able to take timer interrupts immediately
9252              * after reading count. DISAS_STOP isn't sufficient, we need to
9253              * ensure we break completely out of translated code.
9254              */
9255             gen_save_pc(ctx->base.pc_next + 4);
9256             ctx->base.is_jmp = DISAS_EXIT;
9257             register_name = "Count";
9258             break;
9259         case CP0_REG09__SAARI:
9260             CP0_CHECK(ctx->saar);
9261             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
9262             register_name = "SAARI";
9263             break;
9264         case CP0_REG09__SAAR:
9265             CP0_CHECK(ctx->saar);
9266             gen_helper_dmfc0_saar(arg, cpu_env);
9267             register_name = "SAAR";
9268             break;
9269         default:
9270             goto cp0_unimplemented;
9271         }
9272         break;
9273     case CP0_REGISTER_10:
9274         switch (sel) {
9275         case CP0_REG10__ENTRYHI:
9276             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
9277             register_name = "EntryHi";
9278             break;
9279         default:
9280             goto cp0_unimplemented;
9281         }
9282         break;
9283     case CP0_REGISTER_11:
9284         switch (sel) {
9285         case CP0_REG11__COMPARE:
9286             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
9287             register_name = "Compare";
9288             break;
9289         /* 6,7 are implementation dependent */
9290         default:
9291             goto cp0_unimplemented;
9292         }
9293         break;
9294     case CP0_REGISTER_12:
9295         switch (sel) {
9296         case CP0_REG12__STATUS:
9297             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
9298             register_name = "Status";
9299             break;
9300         case CP0_REG12__INTCTL:
9301             check_insn(ctx, ISA_MIPS32R2);
9302             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
9303             register_name = "IntCtl";
9304             break;
9305         case CP0_REG12__SRSCTL:
9306             check_insn(ctx, ISA_MIPS32R2);
9307             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
9308             register_name = "SRSCtl";
9309             break;
9310         case CP0_REG12__SRSMAP:
9311             check_insn(ctx, ISA_MIPS32R2);
9312             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
9313             register_name = "SRSMap";
9314             break;
9315         default:
9316             goto cp0_unimplemented;
9317         }
9318         break;
9319     case CP0_REGISTER_13:
9320         switch (sel) {
9321         case CP0_REG13__CAUSE:
9322             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
9323             register_name = "Cause";
9324             break;
9325         default:
9326             goto cp0_unimplemented;
9327         }
9328         break;
9329     case CP0_REGISTER_14:
9330         switch (sel) {
9331         case CP0_REG14__EPC:
9332             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
9333             register_name = "EPC";
9334             break;
9335         default:
9336             goto cp0_unimplemented;
9337         }
9338         break;
9339     case CP0_REGISTER_15:
9340         switch (sel) {
9341         case CP0_REG15__PRID:
9342             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
9343             register_name = "PRid";
9344             break;
9345         case CP0_REG15__EBASE:
9346             check_insn(ctx, ISA_MIPS32R2);
9347             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
9348             register_name = "EBase";
9349             break;
9350         case CP0_REG15__CMGCRBASE:
9351             check_insn(ctx, ISA_MIPS32R2);
9352             CP0_CHECK(ctx->cmgcr);
9353             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
9354             register_name = "CMGCRBase";
9355             break;
9356         default:
9357             goto cp0_unimplemented;
9358         }
9359         break;
9360     case CP0_REGISTER_16:
9361         switch (sel) {
9362         case CP0_REG16__CONFIG:
9363             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9364             register_name = "Config";
9365             break;
9366         case CP0_REG16__CONFIG1:
9367             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9368             register_name = "Config1";
9369             break;
9370         case CP0_REG16__CONFIG2:
9371             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9372             register_name = "Config2";
9373             break;
9374         case CP0_REG16__CONFIG3:
9375             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9376             register_name = "Config3";
9377             break;
9378         case CP0_REG16__CONFIG4:
9379             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
9380             register_name = "Config4";
9381             break;
9382         case CP0_REG16__CONFIG5:
9383             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
9384             register_name = "Config5";
9385             break;
9386         /* 6,7 are implementation dependent */
9387         case CP0_REG16__CONFIG6:
9388             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
9389             register_name = "Config6";
9390             break;
9391         case CP0_REG16__CONFIG7:
9392             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
9393             register_name = "Config7";
9394             break;
9395         default:
9396             goto cp0_unimplemented;
9397         }
9398         break;
9399     case CP0_REGISTER_17:
9400         switch (sel) {
9401         case CP0_REG17__LLADDR:
9402             gen_helper_dmfc0_lladdr(arg, cpu_env);
9403             register_name = "LLAddr";
9404             break;
9405         case CP0_REG17__MAAR:
9406             CP0_CHECK(ctx->mrp);
9407             gen_helper_dmfc0_maar(arg, cpu_env);
9408             register_name = "MAAR";
9409             break;
9410         case CP0_REG17__MAARI:
9411             CP0_CHECK(ctx->mrp);
9412             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
9413             register_name = "MAARI";
9414             break;
9415         default:
9416             goto cp0_unimplemented;
9417         }
9418         break;
9419     case CP0_REGISTER_18:
9420         switch (sel) {
9421         case CP0_REG18__WATCHLO0:
9422         case CP0_REG18__WATCHLO1:
9423         case CP0_REG18__WATCHLO2:
9424         case CP0_REG18__WATCHLO3:
9425         case CP0_REG18__WATCHLO4:
9426         case CP0_REG18__WATCHLO5:
9427         case CP0_REG18__WATCHLO6:
9428         case CP0_REG18__WATCHLO7:
9429             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9430             gen_helper_1e0i(dmfc0_watchlo, arg, sel);
9431             register_name = "WatchLo";
9432             break;
9433         default:
9434             goto cp0_unimplemented;
9435         }
9436         break;
9437     case CP0_REGISTER_19:
9438         switch (sel) {
9439         case CP0_REG19__WATCHHI0:
9440         case CP0_REG19__WATCHHI1:
9441         case CP0_REG19__WATCHHI2:
9442         case CP0_REG19__WATCHHI3:
9443         case CP0_REG19__WATCHHI4:
9444         case CP0_REG19__WATCHHI5:
9445         case CP0_REG19__WATCHHI6:
9446         case CP0_REG19__WATCHHI7:
9447             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9448             gen_helper_1e0i(dmfc0_watchhi, arg, sel);
9449             register_name = "WatchHi";
9450             break;
9451         default:
9452             goto cp0_unimplemented;
9453         }
9454         break;
9455     case CP0_REGISTER_20:
9456         switch (sel) {
9457         case CP0_REG20__XCONTEXT:
9458             check_insn(ctx, ISA_MIPS3);
9459             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
9460             register_name = "XContext";
9461             break;
9462         default:
9463             goto cp0_unimplemented;
9464         }
9465         break;
9466     case CP0_REGISTER_21:
9467         /* Officially reserved, but sel 0 is used for R1x000 framemask */
9468         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9469         switch (sel) {
9470         case 0:
9471             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
9472             register_name = "Framemask";
9473             break;
9474         default:
9475             goto cp0_unimplemented;
9476         }
9477         break;
9478     case CP0_REGISTER_22:
9479         tcg_gen_movi_tl(arg, 0); /* unimplemented */
9480         register_name = "'Diagnostic"; /* implementation dependent */
9481         break;
9482     case CP0_REGISTER_23:
9483         switch (sel) {
9484         case CP0_REG23__DEBUG:
9485             gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
9486             register_name = "Debug";
9487             break;
9488         case CP0_REG23__TRACECONTROL:
9489             /* PDtrace support */
9490             /* gen_helper_dmfc0_tracecontrol(arg, cpu_env);  */
9491             register_name = "TraceControl";
9492             goto cp0_unimplemented;
9493         case CP0_REG23__TRACECONTROL2:
9494             /* PDtrace support */
9495             /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */
9496             register_name = "TraceControl2";
9497             goto cp0_unimplemented;
9498         case CP0_REG23__USERTRACEDATA1:
9499             /* PDtrace support */
9500             /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/
9501             register_name = "UserTraceData1";
9502             goto cp0_unimplemented;
9503         case CP0_REG23__TRACEIBPC:
9504             /* PDtrace support */
9505             /* gen_helper_dmfc0_traceibpc(arg, cpu_env);     */
9506             register_name = "TraceIBPC";
9507             goto cp0_unimplemented;
9508         case CP0_REG23__TRACEDBPC:
9509             /* PDtrace support */
9510             /* gen_helper_dmfc0_tracedbpc(arg, cpu_env);     */
9511             register_name = "TraceDBPC";
9512             goto cp0_unimplemented;
9513         default:
9514             goto cp0_unimplemented;
9515         }
9516         break;
9517     case CP0_REGISTER_24:
9518         switch (sel) {
9519         case CP0_REG24__DEPC:
9520             /* EJTAG support */
9521             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
9522             register_name = "DEPC";
9523             break;
9524         default:
9525             goto cp0_unimplemented;
9526         }
9527         break;
9528     case CP0_REGISTER_25:
9529         switch (sel) {
9530         case CP0_REG25__PERFCTL0:
9531             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
9532             register_name = "Performance0";
9533             break;
9534         case CP0_REG25__PERFCNT0:
9535             /* gen_helper_dmfc0_performance1(arg); */
9536             register_name = "Performance1";
9537             goto cp0_unimplemented;
9538         case CP0_REG25__PERFCTL1:
9539             /* gen_helper_dmfc0_performance2(arg); */
9540             register_name = "Performance2";
9541             goto cp0_unimplemented;
9542         case CP0_REG25__PERFCNT1:
9543             /* gen_helper_dmfc0_performance3(arg); */
9544             register_name = "Performance3";
9545             goto cp0_unimplemented;
9546         case CP0_REG25__PERFCTL2:
9547             /* gen_helper_dmfc0_performance4(arg); */
9548             register_name = "Performance4";
9549             goto cp0_unimplemented;
9550         case CP0_REG25__PERFCNT2:
9551             /* gen_helper_dmfc0_performance5(arg); */
9552             register_name = "Performance5";
9553             goto cp0_unimplemented;
9554         case CP0_REG25__PERFCTL3:
9555             /* gen_helper_dmfc0_performance6(arg); */
9556             register_name = "Performance6";
9557             goto cp0_unimplemented;
9558         case CP0_REG25__PERFCNT3:
9559             /* gen_helper_dmfc0_performance7(arg); */
9560             register_name = "Performance7";
9561             goto cp0_unimplemented;
9562         default:
9563             goto cp0_unimplemented;
9564         }
9565         break;
9566     case CP0_REGISTER_26:
9567         switch (sel) {
9568         case CP0_REG26__ERRCTL:
9569             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
9570             register_name = "ErrCtl";
9571             break;
9572         default:
9573             goto cp0_unimplemented;
9574         }
9575         break;
9576     case CP0_REGISTER_27:
9577         switch (sel) {
9578         /* ignored */
9579         case CP0_REG27__CACHERR:
9580             tcg_gen_movi_tl(arg, 0); /* unimplemented */
9581             register_name = "CacheErr";
9582             break;
9583         default:
9584             goto cp0_unimplemented;
9585         }
9586         break;
9587     case CP0_REGISTER_28:
9588         switch (sel) {
9589         case CP0_REG28__TAGLO:
9590         case CP0_REG28__TAGLO1:
9591         case CP0_REG28__TAGLO2:
9592         case CP0_REG28__TAGLO3:
9593             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9594             register_name = "TagLo";
9595             break;
9596         case CP0_REG28__DATALO:
9597         case CP0_REG28__DATALO1:
9598         case CP0_REG28__DATALO2:
9599         case CP0_REG28__DATALO3:
9600             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9601             register_name = "DataLo";
9602             break;
9603         default:
9604             goto cp0_unimplemented;
9605         }
9606         break;
9607     case CP0_REGISTER_29:
9608         switch (sel) {
9609         case CP0_REG29__TAGHI:
9610         case CP0_REG29__TAGHI1:
9611         case CP0_REG29__TAGHI2:
9612         case CP0_REG29__TAGHI3:
9613             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9614             register_name = "TagHi";
9615             break;
9616         case CP0_REG29__DATAHI:
9617         case CP0_REG29__DATAHI1:
9618         case CP0_REG29__DATAHI2:
9619         case CP0_REG29__DATAHI3:
9620             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9621             register_name = "DataHi";
9622             break;
9623         default:
9624             goto cp0_unimplemented;
9625         }
9626         break;
9627     case CP0_REGISTER_30:
9628         switch (sel) {
9629         case CP0_REG30__ERROREPC:
9630             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
9631             register_name = "ErrorEPC";
9632             break;
9633         default:
9634             goto cp0_unimplemented;
9635         }
9636         break;
9637     case CP0_REGISTER_31:
9638         switch (sel) {
9639         case CP0_REG31__DESAVE:
9640             /* EJTAG support */
9641             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
9642             register_name = "DESAVE";
9643             break;
9644         case CP0_REG31__KSCRATCH1:
9645         case CP0_REG31__KSCRATCH2:
9646         case CP0_REG31__KSCRATCH3:
9647         case CP0_REG31__KSCRATCH4:
9648         case CP0_REG31__KSCRATCH5:
9649         case CP0_REG31__KSCRATCH6:
9650             CP0_CHECK(ctx->kscrexist & (1 << sel));
9651             tcg_gen_ld_tl(arg, cpu_env,
9652                           offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
9653             register_name = "KScratch";
9654             break;
9655         default:
9656             goto cp0_unimplemented;
9657         }
9658         break;
9659     default:
9660         goto cp0_unimplemented;
9661     }
9662     trace_mips_translate_c0("dmfc0", register_name, reg, sel);
9663     return;
9664 
9665 cp0_unimplemented:
9666     qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n",
9667                   register_name, reg, sel);
9668     gen_mfc0_unimplemented(ctx, arg);
9669 }
9670 
gen_dmtc0(DisasContext * ctx,TCGv arg,int reg,int sel)9671 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9672 {
9673     const char *register_name = "invalid";
9674 
9675     if (sel != 0) {
9676         check_insn(ctx, ISA_MIPS64);
9677     }
9678 
9679     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
9680         gen_io_start();
9681     }
9682 
9683     switch (reg) {
9684     case CP0_REGISTER_00:
9685         switch (sel) {
9686         case CP0_REG00__INDEX:
9687             gen_helper_mtc0_index(cpu_env, arg);
9688             register_name = "Index";
9689             break;
9690         case CP0_REG00__MVPCONTROL:
9691             CP0_CHECK(ctx->insn_flags & ASE_MT);
9692             gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9693             register_name = "MVPControl";
9694             break;
9695         case CP0_REG00__MVPCONF0:
9696             CP0_CHECK(ctx->insn_flags & ASE_MT);
9697             /* ignored */
9698             register_name = "MVPConf0";
9699             break;
9700         case CP0_REG00__MVPCONF1:
9701             CP0_CHECK(ctx->insn_flags & ASE_MT);
9702             /* ignored */
9703             register_name = "MVPConf1";
9704             break;
9705         case CP0_REG00__VPCONTROL:
9706             CP0_CHECK(ctx->vp);
9707             /* ignored */
9708             register_name = "VPControl";
9709             break;
9710         default:
9711             goto cp0_unimplemented;
9712         }
9713         break;
9714     case CP0_REGISTER_01:
9715         switch (sel) {
9716         case CP0_REG01__RANDOM:
9717             /* ignored */
9718             register_name = "Random";
9719             break;
9720         case CP0_REG01__VPECONTROL:
9721             CP0_CHECK(ctx->insn_flags & ASE_MT);
9722             gen_helper_mtc0_vpecontrol(cpu_env, arg);
9723             register_name = "VPEControl";
9724             break;
9725         case CP0_REG01__VPECONF0:
9726             CP0_CHECK(ctx->insn_flags & ASE_MT);
9727             gen_helper_mtc0_vpeconf0(cpu_env, arg);
9728             register_name = "VPEConf0";
9729             break;
9730         case CP0_REG01__VPECONF1:
9731             CP0_CHECK(ctx->insn_flags & ASE_MT);
9732             gen_helper_mtc0_vpeconf1(cpu_env, arg);
9733             register_name = "VPEConf1";
9734             break;
9735         case CP0_REG01__YQMASK:
9736             CP0_CHECK(ctx->insn_flags & ASE_MT);
9737             gen_helper_mtc0_yqmask(cpu_env, arg);
9738             register_name = "YQMask";
9739             break;
9740         case CP0_REG01__VPESCHEDULE:
9741             CP0_CHECK(ctx->insn_flags & ASE_MT);
9742             tcg_gen_st_tl(arg, cpu_env,
9743                           offsetof(CPUMIPSState, CP0_VPESchedule));
9744             register_name = "VPESchedule";
9745             break;
9746         case CP0_REG01__VPESCHEFBACK:
9747             CP0_CHECK(ctx->insn_flags & ASE_MT);
9748             tcg_gen_st_tl(arg, cpu_env,
9749                           offsetof(CPUMIPSState, CP0_VPEScheFBack));
9750             register_name = "VPEScheFBack";
9751             break;
9752         case CP0_REG01__VPEOPT:
9753             CP0_CHECK(ctx->insn_flags & ASE_MT);
9754             gen_helper_mtc0_vpeopt(cpu_env, arg);
9755             register_name = "VPEOpt";
9756             break;
9757         default:
9758             goto cp0_unimplemented;
9759         }
9760         break;
9761     case CP0_REGISTER_02:
9762         switch (sel) {
9763         case CP0_REG02__ENTRYLO0:
9764             gen_helper_dmtc0_entrylo0(cpu_env, arg);
9765             register_name = "EntryLo0";
9766             break;
9767         case CP0_REG02__TCSTATUS:
9768             CP0_CHECK(ctx->insn_flags & ASE_MT);
9769             gen_helper_mtc0_tcstatus(cpu_env, arg);
9770             register_name = "TCStatus";
9771             break;
9772         case CP0_REG02__TCBIND:
9773             CP0_CHECK(ctx->insn_flags & ASE_MT);
9774             gen_helper_mtc0_tcbind(cpu_env, arg);
9775             register_name = "TCBind";
9776             break;
9777         case CP0_REG02__TCRESTART:
9778             CP0_CHECK(ctx->insn_flags & ASE_MT);
9779             gen_helper_mtc0_tcrestart(cpu_env, arg);
9780             register_name = "TCRestart";
9781             break;
9782         case CP0_REG02__TCHALT:
9783             CP0_CHECK(ctx->insn_flags & ASE_MT);
9784             gen_helper_mtc0_tchalt(cpu_env, arg);
9785             register_name = "TCHalt";
9786             break;
9787         case CP0_REG02__TCCONTEXT:
9788             CP0_CHECK(ctx->insn_flags & ASE_MT);
9789             gen_helper_mtc0_tccontext(cpu_env, arg);
9790             register_name = "TCContext";
9791             break;
9792         case CP0_REG02__TCSCHEDULE:
9793             CP0_CHECK(ctx->insn_flags & ASE_MT);
9794             gen_helper_mtc0_tcschedule(cpu_env, arg);
9795             register_name = "TCSchedule";
9796             break;
9797         case CP0_REG02__TCSCHEFBACK:
9798             CP0_CHECK(ctx->insn_flags & ASE_MT);
9799             gen_helper_mtc0_tcschefback(cpu_env, arg);
9800             register_name = "TCScheFBack";
9801             break;
9802         default:
9803             goto cp0_unimplemented;
9804         }
9805         break;
9806     case CP0_REGISTER_03:
9807         switch (sel) {
9808         case CP0_REG03__ENTRYLO1:
9809             gen_helper_dmtc0_entrylo1(cpu_env, arg);
9810             register_name = "EntryLo1";
9811             break;
9812         case CP0_REG03__GLOBALNUM:
9813             CP0_CHECK(ctx->vp);
9814             /* ignored */
9815             register_name = "GlobalNumber";
9816             break;
9817         default:
9818             goto cp0_unimplemented;
9819         }
9820         break;
9821     case CP0_REGISTER_04:
9822         switch (sel) {
9823         case CP0_REG04__CONTEXT:
9824             gen_helper_mtc0_context(cpu_env, arg);
9825             register_name = "Context";
9826             break;
9827         case CP0_REG04__CONTEXTCONFIG:
9828             /* SmartMIPS ASE */
9829             /* gen_helper_dmtc0_contextconfig(arg); */
9830             register_name = "ContextConfig";
9831             goto cp0_unimplemented;
9832         case CP0_REG04__USERLOCAL:
9833             CP0_CHECK(ctx->ulri);
9834             tcg_gen_st_tl(arg, cpu_env,
9835                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
9836             register_name = "UserLocal";
9837             break;
9838         case CP0_REG04__MMID:
9839             CP0_CHECK(ctx->mi);
9840             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID));
9841             register_name = "MMID";
9842             break;
9843         default:
9844             goto cp0_unimplemented;
9845         }
9846         break;
9847     case CP0_REGISTER_05:
9848         switch (sel) {
9849         case CP0_REG05__PAGEMASK:
9850             gen_helper_mtc0_pagemask(cpu_env, arg);
9851             register_name = "PageMask";
9852             break;
9853         case CP0_REG05__PAGEGRAIN:
9854             check_insn(ctx, ISA_MIPS32R2);
9855             gen_helper_mtc0_pagegrain(cpu_env, arg);
9856             register_name = "PageGrain";
9857             break;
9858         case CP0_REG05__SEGCTL0:
9859             CP0_CHECK(ctx->sc);
9860             gen_helper_mtc0_segctl0(cpu_env, arg);
9861             register_name = "SegCtl0";
9862             break;
9863         case CP0_REG05__SEGCTL1:
9864             CP0_CHECK(ctx->sc);
9865             gen_helper_mtc0_segctl1(cpu_env, arg);
9866             register_name = "SegCtl1";
9867             break;
9868         case CP0_REG05__SEGCTL2:
9869             CP0_CHECK(ctx->sc);
9870             gen_helper_mtc0_segctl2(cpu_env, arg);
9871             register_name = "SegCtl2";
9872             break;
9873         case CP0_REG05__PWBASE:
9874             check_pw(ctx);
9875             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
9876             register_name = "PWBase";
9877             break;
9878         case CP0_REG05__PWFIELD:
9879             check_pw(ctx);
9880             gen_helper_mtc0_pwfield(cpu_env, arg);
9881             register_name = "PWField";
9882             break;
9883         case CP0_REG05__PWSIZE:
9884             check_pw(ctx);
9885             gen_helper_mtc0_pwsize(cpu_env, arg);
9886             register_name = "PWSize";
9887             break;
9888         default:
9889             goto cp0_unimplemented;
9890         }
9891         break;
9892     case CP0_REGISTER_06:
9893         switch (sel) {
9894         case CP0_REG06__WIRED:
9895             gen_helper_mtc0_wired(cpu_env, arg);
9896             register_name = "Wired";
9897             break;
9898         case CP0_REG06__SRSCONF0:
9899             check_insn(ctx, ISA_MIPS32R2);
9900             gen_helper_mtc0_srsconf0(cpu_env, arg);
9901             register_name = "SRSConf0";
9902             break;
9903         case CP0_REG06__SRSCONF1:
9904             check_insn(ctx, ISA_MIPS32R2);
9905             gen_helper_mtc0_srsconf1(cpu_env, arg);
9906             register_name = "SRSConf1";
9907             break;
9908         case CP0_REG06__SRSCONF2:
9909             check_insn(ctx, ISA_MIPS32R2);
9910             gen_helper_mtc0_srsconf2(cpu_env, arg);
9911             register_name = "SRSConf2";
9912             break;
9913         case CP0_REG06__SRSCONF3:
9914             check_insn(ctx, ISA_MIPS32R2);
9915             gen_helper_mtc0_srsconf3(cpu_env, arg);
9916             register_name = "SRSConf3";
9917             break;
9918         case CP0_REG06__SRSCONF4:
9919             check_insn(ctx, ISA_MIPS32R2);
9920             gen_helper_mtc0_srsconf4(cpu_env, arg);
9921             register_name = "SRSConf4";
9922             break;
9923         case CP0_REG06__PWCTL:
9924             check_pw(ctx);
9925             gen_helper_mtc0_pwctl(cpu_env, arg);
9926             register_name = "PWCtl";
9927             break;
9928         default:
9929             goto cp0_unimplemented;
9930         }
9931         break;
9932     case CP0_REGISTER_07:
9933         switch (sel) {
9934         case CP0_REG07__HWRENA:
9935             check_insn(ctx, ISA_MIPS32R2);
9936             gen_helper_mtc0_hwrena(cpu_env, arg);
9937             ctx->base.is_jmp = DISAS_STOP;
9938             register_name = "HWREna";
9939             break;
9940         default:
9941             goto cp0_unimplemented;
9942         }
9943         break;
9944     case CP0_REGISTER_08:
9945         switch (sel) {
9946         case CP0_REG08__BADVADDR:
9947             /* ignored */
9948             register_name = "BadVAddr";
9949             break;
9950         case CP0_REG08__BADINSTR:
9951             /* ignored */
9952             register_name = "BadInstr";
9953             break;
9954         case CP0_REG08__BADINSTRP:
9955             /* ignored */
9956             register_name = "BadInstrP";
9957             break;
9958         case CP0_REG08__BADINSTRX:
9959             /* ignored */
9960             register_name = "BadInstrX";
9961             break;
9962         default:
9963             goto cp0_unimplemented;
9964         }
9965         break;
9966     case CP0_REGISTER_09:
9967         switch (sel) {
9968         case CP0_REG09__COUNT:
9969             gen_helper_mtc0_count(cpu_env, arg);
9970             register_name = "Count";
9971             break;
9972         case CP0_REG09__SAARI:
9973             CP0_CHECK(ctx->saar);
9974             gen_helper_mtc0_saari(cpu_env, arg);
9975             register_name = "SAARI";
9976             break;
9977         case CP0_REG09__SAAR:
9978             CP0_CHECK(ctx->saar);
9979             gen_helper_mtc0_saar(cpu_env, arg);
9980             register_name = "SAAR";
9981             break;
9982         default:
9983             goto cp0_unimplemented;
9984         }
9985         /* Stop translation as we may have switched the execution mode */
9986         ctx->base.is_jmp = DISAS_STOP;
9987         break;
9988     case CP0_REGISTER_10:
9989         switch (sel) {
9990         case CP0_REG10__ENTRYHI:
9991             gen_helper_mtc0_entryhi(cpu_env, arg);
9992             register_name = "EntryHi";
9993             break;
9994         default:
9995             goto cp0_unimplemented;
9996         }
9997         break;
9998     case CP0_REGISTER_11:
9999         switch (sel) {
10000         case CP0_REG11__COMPARE:
10001             gen_helper_mtc0_compare(cpu_env, arg);
10002             register_name = "Compare";
10003             break;
10004         /* 6,7 are implementation dependent */
10005         default:
10006             goto cp0_unimplemented;
10007         }
10008         /* Stop translation as we may have switched the execution mode */
10009         ctx->base.is_jmp = DISAS_STOP;
10010         break;
10011     case CP0_REGISTER_12:
10012         switch (sel) {
10013         case CP0_REG12__STATUS:
10014             save_cpu_state(ctx, 1);
10015             gen_helper_mtc0_status(cpu_env, arg);
10016             /* DISAS_STOP isn't good enough here, hflags may have changed. */
10017             gen_save_pc(ctx->base.pc_next + 4);
10018             ctx->base.is_jmp = DISAS_EXIT;
10019             register_name = "Status";
10020             break;
10021         case CP0_REG12__INTCTL:
10022             check_insn(ctx, ISA_MIPS32R2);
10023             gen_helper_mtc0_intctl(cpu_env, arg);
10024             /* Stop translation as we may have switched the execution mode */
10025             ctx->base.is_jmp = DISAS_STOP;
10026             register_name = "IntCtl";
10027             break;
10028         case CP0_REG12__SRSCTL:
10029             check_insn(ctx, ISA_MIPS32R2);
10030             gen_helper_mtc0_srsctl(cpu_env, arg);
10031             /* Stop translation as we may have switched the execution mode */
10032             ctx->base.is_jmp = DISAS_STOP;
10033             register_name = "SRSCtl";
10034             break;
10035         case CP0_REG12__SRSMAP:
10036             check_insn(ctx, ISA_MIPS32R2);
10037             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
10038             /* Stop translation as we may have switched the execution mode */
10039             ctx->base.is_jmp = DISAS_STOP;
10040             register_name = "SRSMap";
10041             break;
10042         default:
10043             goto cp0_unimplemented;
10044         }
10045         break;
10046     case CP0_REGISTER_13:
10047         switch (sel) {
10048         case CP0_REG13__CAUSE:
10049             save_cpu_state(ctx, 1);
10050             gen_helper_mtc0_cause(cpu_env, arg);
10051             /*
10052              * Stop translation as we may have triggered an interrupt.
10053              * DISAS_STOP isn't sufficient, we need to ensure we break out of
10054              * translated code to check for pending interrupts.
10055              */
10056             gen_save_pc(ctx->base.pc_next + 4);
10057             ctx->base.is_jmp = DISAS_EXIT;
10058             register_name = "Cause";
10059             break;
10060         default:
10061             goto cp0_unimplemented;
10062         }
10063         break;
10064     case CP0_REGISTER_14:
10065         switch (sel) {
10066         case CP0_REG14__EPC:
10067             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
10068             register_name = "EPC";
10069             break;
10070         default:
10071             goto cp0_unimplemented;
10072         }
10073         break;
10074     case CP0_REGISTER_15:
10075         switch (sel) {
10076         case CP0_REG15__PRID:
10077             /* ignored */
10078             register_name = "PRid";
10079             break;
10080         case CP0_REG15__EBASE:
10081             check_insn(ctx, ISA_MIPS32R2);
10082             gen_helper_mtc0_ebase(cpu_env, arg);
10083             register_name = "EBase";
10084             break;
10085         default:
10086             goto cp0_unimplemented;
10087         }
10088         break;
10089     case CP0_REGISTER_16:
10090         switch (sel) {
10091         case CP0_REG16__CONFIG:
10092             gen_helper_mtc0_config0(cpu_env, arg);
10093             register_name = "Config";
10094             /* Stop translation as we may have switched the execution mode */
10095             ctx->base.is_jmp = DISAS_STOP;
10096             break;
10097         case CP0_REG16__CONFIG1:
10098             /* ignored, read only */
10099             register_name = "Config1";
10100             break;
10101         case CP0_REG16__CONFIG2:
10102             gen_helper_mtc0_config2(cpu_env, arg);
10103             register_name = "Config2";
10104             /* Stop translation as we may have switched the execution mode */
10105             ctx->base.is_jmp = DISAS_STOP;
10106             break;
10107         case CP0_REG16__CONFIG3:
10108             gen_helper_mtc0_config3(cpu_env, arg);
10109             register_name = "Config3";
10110             /* Stop translation as we may have switched the execution mode */
10111             ctx->base.is_jmp = DISAS_STOP;
10112             break;
10113         case CP0_REG16__CONFIG4:
10114             /* currently ignored */
10115             register_name = "Config4";
10116             break;
10117         case CP0_REG16__CONFIG5:
10118             gen_helper_mtc0_config5(cpu_env, arg);
10119             register_name = "Config5";
10120             /* Stop translation as we may have switched the execution mode */
10121             ctx->base.is_jmp = DISAS_STOP;
10122             break;
10123         /* 6,7 are implementation dependent */
10124         default:
10125             register_name = "Invalid config selector";
10126             goto cp0_unimplemented;
10127         }
10128         break;
10129     case CP0_REGISTER_17:
10130         switch (sel) {
10131         case CP0_REG17__LLADDR:
10132             gen_helper_mtc0_lladdr(cpu_env, arg);
10133             register_name = "LLAddr";
10134             break;
10135         case CP0_REG17__MAAR:
10136             CP0_CHECK(ctx->mrp);
10137             gen_helper_mtc0_maar(cpu_env, arg);
10138             register_name = "MAAR";
10139             break;
10140         case CP0_REG17__MAARI:
10141             CP0_CHECK(ctx->mrp);
10142             gen_helper_mtc0_maari(cpu_env, arg);
10143             register_name = "MAARI";
10144             break;
10145         default:
10146             goto cp0_unimplemented;
10147         }
10148         break;
10149     case CP0_REGISTER_18:
10150         switch (sel) {
10151         case CP0_REG18__WATCHLO0:
10152         case CP0_REG18__WATCHLO1:
10153         case CP0_REG18__WATCHLO2:
10154         case CP0_REG18__WATCHLO3:
10155         case CP0_REG18__WATCHLO4:
10156         case CP0_REG18__WATCHLO5:
10157         case CP0_REG18__WATCHLO6:
10158         case CP0_REG18__WATCHLO7:
10159             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
10160             gen_helper_0e1i(mtc0_watchlo, arg, sel);
10161             register_name = "WatchLo";
10162             break;
10163         default:
10164             goto cp0_unimplemented;
10165         }
10166         break;
10167     case CP0_REGISTER_19:
10168         switch (sel) {
10169         case CP0_REG19__WATCHHI0:
10170         case CP0_REG19__WATCHHI1:
10171         case CP0_REG19__WATCHHI2:
10172         case CP0_REG19__WATCHHI3:
10173         case CP0_REG19__WATCHHI4:
10174         case CP0_REG19__WATCHHI5:
10175         case CP0_REG19__WATCHHI6:
10176         case CP0_REG19__WATCHHI7:
10177             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
10178             gen_helper_0e1i(mtc0_watchhi, arg, sel);
10179             register_name = "WatchHi";
10180             break;
10181         default:
10182             goto cp0_unimplemented;
10183         }
10184         break;
10185     case CP0_REGISTER_20:
10186         switch (sel) {
10187         case CP0_REG20__XCONTEXT:
10188             check_insn(ctx, ISA_MIPS3);
10189             gen_helper_mtc0_xcontext(cpu_env, arg);
10190             register_name = "XContext";
10191             break;
10192         default:
10193             goto cp0_unimplemented;
10194         }
10195         break;
10196     case CP0_REGISTER_21:
10197        /* Officially reserved, but sel 0 is used for R1x000 framemask */
10198         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
10199         switch (sel) {
10200         case 0:
10201             gen_helper_mtc0_framemask(cpu_env, arg);
10202             register_name = "Framemask";
10203             break;
10204         default:
10205             goto cp0_unimplemented;
10206         }
10207         break;
10208     case CP0_REGISTER_22:
10209         /* ignored */
10210         register_name = "Diagnostic"; /* implementation dependent */
10211         break;
10212     case CP0_REGISTER_23:
10213         switch (sel) {
10214         case CP0_REG23__DEBUG:
10215             gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
10216             /* DISAS_STOP isn't good enough here, hflags may have changed. */
10217             gen_save_pc(ctx->base.pc_next + 4);
10218             ctx->base.is_jmp = DISAS_EXIT;
10219             register_name = "Debug";
10220             break;
10221         case CP0_REG23__TRACECONTROL:
10222             /* PDtrace support */
10223             /* gen_helper_mtc0_tracecontrol(cpu_env, arg);  */
10224             /* Stop translation as we may have switched the execution mode */
10225             ctx->base.is_jmp = DISAS_STOP;
10226             register_name = "TraceControl";
10227             goto cp0_unimplemented;
10228         case CP0_REG23__TRACECONTROL2:
10229             /* PDtrace support */
10230             /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
10231             /* Stop translation as we may have switched the execution mode */
10232             ctx->base.is_jmp = DISAS_STOP;
10233             register_name = "TraceControl2";
10234             goto cp0_unimplemented;
10235         case CP0_REG23__USERTRACEDATA1:
10236             /* PDtrace support */
10237             /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
10238             /* Stop translation as we may have switched the execution mode */
10239             ctx->base.is_jmp = DISAS_STOP;
10240             register_name = "UserTraceData1";
10241             goto cp0_unimplemented;
10242         case CP0_REG23__TRACEIBPC:
10243             /* PDtrace support */
10244             /* gen_helper_mtc0_traceibpc(cpu_env, arg);     */
10245             /* Stop translation as we may have switched the execution mode */
10246             ctx->base.is_jmp = DISAS_STOP;
10247             register_name = "TraceIBPC";
10248             goto cp0_unimplemented;
10249         case CP0_REG23__TRACEDBPC:
10250             /* PDtrace support */
10251             /* gen_helper_mtc0_tracedbpc(cpu_env, arg);     */
10252             /* Stop translation as we may have switched the execution mode */
10253             ctx->base.is_jmp = DISAS_STOP;
10254             register_name = "TraceDBPC";
10255             goto cp0_unimplemented;
10256         default:
10257             goto cp0_unimplemented;
10258         }
10259         break;
10260     case CP0_REGISTER_24:
10261         switch (sel) {
10262         case CP0_REG24__DEPC:
10263             /* EJTAG support */
10264             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
10265             register_name = "DEPC";
10266             break;
10267         default:
10268             goto cp0_unimplemented;
10269         }
10270         break;
10271     case CP0_REGISTER_25:
10272         switch (sel) {
10273         case CP0_REG25__PERFCTL0:
10274             gen_helper_mtc0_performance0(cpu_env, arg);
10275             register_name = "Performance0";
10276             break;
10277         case CP0_REG25__PERFCNT0:
10278             /* gen_helper_mtc0_performance1(cpu_env, arg); */
10279             register_name = "Performance1";
10280             goto cp0_unimplemented;
10281         case CP0_REG25__PERFCTL1:
10282             /* gen_helper_mtc0_performance2(cpu_env, arg); */
10283             register_name = "Performance2";
10284             goto cp0_unimplemented;
10285         case CP0_REG25__PERFCNT1:
10286             /* gen_helper_mtc0_performance3(cpu_env, arg); */
10287             register_name = "Performance3";
10288             goto cp0_unimplemented;
10289         case CP0_REG25__PERFCTL2:
10290             /* gen_helper_mtc0_performance4(cpu_env, arg); */
10291             register_name = "Performance4";
10292             goto cp0_unimplemented;
10293         case CP0_REG25__PERFCNT2:
10294             /* gen_helper_mtc0_performance5(cpu_env, arg); */
10295             register_name = "Performance5";
10296             goto cp0_unimplemented;
10297         case CP0_REG25__PERFCTL3:
10298             /* gen_helper_mtc0_performance6(cpu_env, arg); */
10299             register_name = "Performance6";
10300             goto cp0_unimplemented;
10301         case CP0_REG25__PERFCNT3:
10302             /* gen_helper_mtc0_performance7(cpu_env, arg); */
10303             register_name = "Performance7";
10304             goto cp0_unimplemented;
10305         default:
10306             goto cp0_unimplemented;
10307         }
10308         break;
10309     case CP0_REGISTER_26:
10310         switch (sel) {
10311         case CP0_REG26__ERRCTL:
10312             gen_helper_mtc0_errctl(cpu_env, arg);
10313             ctx->base.is_jmp = DISAS_STOP;
10314             register_name = "ErrCtl";
10315             break;
10316         default:
10317             goto cp0_unimplemented;
10318         }
10319         break;
10320     case CP0_REGISTER_27:
10321         switch (sel) {
10322         case CP0_REG27__CACHERR:
10323             /* ignored */
10324             register_name = "CacheErr";
10325             break;
10326         default:
10327             goto cp0_unimplemented;
10328         }
10329         break;
10330     case CP0_REGISTER_28:
10331         switch (sel) {
10332         case CP0_REG28__TAGLO:
10333         case CP0_REG28__TAGLO1:
10334         case CP0_REG28__TAGLO2:
10335         case CP0_REG28__TAGLO3:
10336             gen_helper_mtc0_taglo(cpu_env, arg);
10337             register_name = "TagLo";
10338             break;
10339         case CP0_REG28__DATALO:
10340         case CP0_REG28__DATALO1:
10341         case CP0_REG28__DATALO2:
10342         case CP0_REG28__DATALO3:
10343             gen_helper_mtc0_datalo(cpu_env, arg);
10344             register_name = "DataLo";
10345             break;
10346         default:
10347             goto cp0_unimplemented;
10348         }
10349         break;
10350     case CP0_REGISTER_29:
10351         switch (sel) {
10352         case CP0_REG29__TAGHI:
10353         case CP0_REG29__TAGHI1:
10354         case CP0_REG29__TAGHI2:
10355         case CP0_REG29__TAGHI3:
10356             gen_helper_mtc0_taghi(cpu_env, arg);
10357             register_name = "TagHi";
10358             break;
10359         case CP0_REG29__DATAHI:
10360         case CP0_REG29__DATAHI1:
10361         case CP0_REG29__DATAHI2:
10362         case CP0_REG29__DATAHI3:
10363             gen_helper_mtc0_datahi(cpu_env, arg);
10364             register_name = "DataHi";
10365             break;
10366         default:
10367             register_name = "invalid sel";
10368             goto cp0_unimplemented;
10369         }
10370         break;
10371     case CP0_REGISTER_30:
10372         switch (sel) {
10373         case CP0_REG30__ERROREPC:
10374             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
10375             register_name = "ErrorEPC";
10376             break;
10377         default:
10378             goto cp0_unimplemented;
10379         }
10380         break;
10381     case CP0_REGISTER_31:
10382         switch (sel) {
10383         case CP0_REG31__DESAVE:
10384             /* EJTAG support */
10385             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
10386             register_name = "DESAVE";
10387             break;
10388         case CP0_REG31__KSCRATCH1:
10389         case CP0_REG31__KSCRATCH2:
10390         case CP0_REG31__KSCRATCH3:
10391         case CP0_REG31__KSCRATCH4:
10392         case CP0_REG31__KSCRATCH5:
10393         case CP0_REG31__KSCRATCH6:
10394             CP0_CHECK(ctx->kscrexist & (1 << sel));
10395             tcg_gen_st_tl(arg, cpu_env,
10396                           offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
10397             register_name = "KScratch";
10398             break;
10399         default:
10400             goto cp0_unimplemented;
10401         }
10402         break;
10403     default:
10404         goto cp0_unimplemented;
10405     }
10406     trace_mips_translate_c0("dmtc0", register_name, reg, sel);
10407 
10408     /* For simplicity assume that all writes can cause interrupts.  */
10409     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
10410         /*
10411          * DISAS_STOP isn't sufficient, we need to ensure we break out of
10412          * translated code to check for pending interrupts.
10413          */
10414         gen_save_pc(ctx->base.pc_next + 4);
10415         ctx->base.is_jmp = DISAS_EXIT;
10416     }
10417     return;
10418 
10419 cp0_unimplemented:
10420     qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n",
10421                   register_name, reg, sel);
10422 }
10423 #endif /* TARGET_MIPS64 */
10424 
gen_mftr(CPUMIPSState * env,DisasContext * ctx,int rt,int rd,int u,int sel,int h)10425 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
10426                      int u, int sel, int h)
10427 {
10428     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
10429     TCGv t0 = tcg_temp_local_new();
10430 
10431     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
10432         ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
10433          (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
10434         tcg_gen_movi_tl(t0, -1);
10435     } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
10436                (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
10437         tcg_gen_movi_tl(t0, -1);
10438     } else if (u == 0) {
10439         switch (rt) {
10440         case 1:
10441             switch (sel) {
10442             case 1:
10443                 gen_helper_mftc0_vpecontrol(t0, cpu_env);
10444                 break;
10445             case 2:
10446                 gen_helper_mftc0_vpeconf0(t0, cpu_env);
10447                 break;
10448             default:
10449                 goto die;
10450                 break;
10451             }
10452             break;
10453         case 2:
10454             switch (sel) {
10455             case 1:
10456                 gen_helper_mftc0_tcstatus(t0, cpu_env);
10457                 break;
10458             case 2:
10459                 gen_helper_mftc0_tcbind(t0, cpu_env);
10460                 break;
10461             case 3:
10462                 gen_helper_mftc0_tcrestart(t0, cpu_env);
10463                 break;
10464             case 4:
10465                 gen_helper_mftc0_tchalt(t0, cpu_env);
10466                 break;
10467             case 5:
10468                 gen_helper_mftc0_tccontext(t0, cpu_env);
10469                 break;
10470             case 6:
10471                 gen_helper_mftc0_tcschedule(t0, cpu_env);
10472                 break;
10473             case 7:
10474                 gen_helper_mftc0_tcschefback(t0, cpu_env);
10475                 break;
10476             default:
10477                 gen_mfc0(ctx, t0, rt, sel);
10478                 break;
10479             }
10480             break;
10481         case 10:
10482             switch (sel) {
10483             case 0:
10484                 gen_helper_mftc0_entryhi(t0, cpu_env);
10485                 break;
10486             default:
10487                 gen_mfc0(ctx, t0, rt, sel);
10488                 break;
10489             }
10490             break;
10491         case 12:
10492             switch (sel) {
10493             case 0:
10494                 gen_helper_mftc0_status(t0, cpu_env);
10495                 break;
10496             default:
10497                 gen_mfc0(ctx, t0, rt, sel);
10498                 break;
10499             }
10500             break;
10501         case 13:
10502             switch (sel) {
10503             case 0:
10504                 gen_helper_mftc0_cause(t0, cpu_env);
10505                 break;
10506             default:
10507                 goto die;
10508                 break;
10509             }
10510             break;
10511         case 14:
10512             switch (sel) {
10513             case 0:
10514                 gen_helper_mftc0_epc(t0, cpu_env);
10515                 break;
10516             default:
10517                 goto die;
10518                 break;
10519             }
10520             break;
10521         case 15:
10522             switch (sel) {
10523             case 1:
10524                 gen_helper_mftc0_ebase(t0, cpu_env);
10525                 break;
10526             default:
10527                 goto die;
10528                 break;
10529             }
10530             break;
10531         case 16:
10532             switch (sel) {
10533             case 0:
10534             case 1:
10535             case 2:
10536             case 3:
10537             case 4:
10538             case 5:
10539             case 6:
10540             case 7:
10541                 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
10542                 break;
10543             default:
10544                 goto die;
10545                 break;
10546             }
10547             break;
10548         case 23:
10549             switch (sel) {
10550             case 0:
10551                 gen_helper_mftc0_debug(t0, cpu_env);
10552                 break;
10553             default:
10554                 gen_mfc0(ctx, t0, rt, sel);
10555                 break;
10556             }
10557             break;
10558         default:
10559             gen_mfc0(ctx, t0, rt, sel);
10560         }
10561     } else {
10562         switch (sel) {
10563         /* GPR registers. */
10564         case 0:
10565             gen_helper_1e0i(mftgpr, t0, rt);
10566             break;
10567         /* Auxiliary CPU registers */
10568         case 1:
10569             switch (rt) {
10570             case 0:
10571                 gen_helper_1e0i(mftlo, t0, 0);
10572                 break;
10573             case 1:
10574                 gen_helper_1e0i(mfthi, t0, 0);
10575                 break;
10576             case 2:
10577                 gen_helper_1e0i(mftacx, t0, 0);
10578                 break;
10579             case 4:
10580                 gen_helper_1e0i(mftlo, t0, 1);
10581                 break;
10582             case 5:
10583                 gen_helper_1e0i(mfthi, t0, 1);
10584                 break;
10585             case 6:
10586                 gen_helper_1e0i(mftacx, t0, 1);
10587                 break;
10588             case 8:
10589                 gen_helper_1e0i(mftlo, t0, 2);
10590                 break;
10591             case 9:
10592                 gen_helper_1e0i(mfthi, t0, 2);
10593                 break;
10594             case 10:
10595                 gen_helper_1e0i(mftacx, t0, 2);
10596                 break;
10597             case 12:
10598                 gen_helper_1e0i(mftlo, t0, 3);
10599                 break;
10600             case 13:
10601                 gen_helper_1e0i(mfthi, t0, 3);
10602                 break;
10603             case 14:
10604                 gen_helper_1e0i(mftacx, t0, 3);
10605                 break;
10606             case 16:
10607                 gen_helper_mftdsp(t0, cpu_env);
10608                 break;
10609             default:
10610                 goto die;
10611             }
10612             break;
10613         /* Floating point (COP1). */
10614         case 2:
10615             /* XXX: For now we support only a single FPU context. */
10616             if (h == 0) {
10617                 TCGv_i32 fp0 = tcg_temp_new_i32();
10618 
10619                 gen_load_fpr32(ctx, fp0, rt);
10620                 tcg_gen_ext_i32_tl(t0, fp0);
10621                 tcg_temp_free_i32(fp0);
10622             } else {
10623                 TCGv_i32 fp0 = tcg_temp_new_i32();
10624 
10625                 gen_load_fpr32h(ctx, fp0, rt);
10626                 tcg_gen_ext_i32_tl(t0, fp0);
10627                 tcg_temp_free_i32(fp0);
10628             }
10629             break;
10630         case 3:
10631             /* XXX: For now we support only a single FPU context. */
10632             gen_helper_1e0i(cfc1, t0, rt);
10633             break;
10634         /* COP2: Not implemented. */
10635         case 4:
10636         case 5:
10637             /* fall through */
10638         default:
10639             goto die;
10640         }
10641     }
10642     trace_mips_translate_tr("mftr", rt, u, sel, h);
10643     gen_store_gpr(t0, rd);
10644     tcg_temp_free(t0);
10645     return;
10646 
10647 die:
10648     tcg_temp_free(t0);
10649     LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
10650     generate_exception_end(ctx, EXCP_RI);
10651 }
10652 
gen_mttr(CPUMIPSState * env,DisasContext * ctx,int rd,int rt,int u,int sel,int h)10653 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
10654                      int u, int sel, int h)
10655 {
10656     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
10657     TCGv t0 = tcg_temp_local_new();
10658 
10659     gen_load_gpr(t0, rt);
10660     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
10661         ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
10662          (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
10663         /* NOP */
10664         ;
10665     } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
10666              (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
10667         /* NOP */
10668         ;
10669     } else if (u == 0) {
10670         switch (rd) {
10671         case 1:
10672             switch (sel) {
10673             case 1:
10674                 gen_helper_mttc0_vpecontrol(cpu_env, t0);
10675                 break;
10676             case 2:
10677                 gen_helper_mttc0_vpeconf0(cpu_env, t0);
10678                 break;
10679             default:
10680                 goto die;
10681                 break;
10682             }
10683             break;
10684         case 2:
10685             switch (sel) {
10686             case 1:
10687                 gen_helper_mttc0_tcstatus(cpu_env, t0);
10688                 break;
10689             case 2:
10690                 gen_helper_mttc0_tcbind(cpu_env, t0);
10691                 break;
10692             case 3:
10693                 gen_helper_mttc0_tcrestart(cpu_env, t0);
10694                 break;
10695             case 4:
10696                 gen_helper_mttc0_tchalt(cpu_env, t0);
10697                 break;
10698             case 5:
10699                 gen_helper_mttc0_tccontext(cpu_env, t0);
10700                 break;
10701             case 6:
10702                 gen_helper_mttc0_tcschedule(cpu_env, t0);
10703                 break;
10704             case 7:
10705                 gen_helper_mttc0_tcschefback(cpu_env, t0);
10706                 break;
10707             default:
10708                 gen_mtc0(ctx, t0, rd, sel);
10709                 break;
10710             }
10711             break;
10712         case 10:
10713             switch (sel) {
10714             case 0:
10715                 gen_helper_mttc0_entryhi(cpu_env, t0);
10716                 break;
10717             default:
10718                 gen_mtc0(ctx, t0, rd, sel);
10719                 break;
10720             }
10721             break;
10722         case 12:
10723             switch (sel) {
10724             case 0:
10725                 gen_helper_mttc0_status(cpu_env, t0);
10726                 break;
10727             default:
10728                 gen_mtc0(ctx, t0, rd, sel);
10729                 break;
10730             }
10731             break;
10732         case 13:
10733             switch (sel) {
10734             case 0:
10735                 gen_helper_mttc0_cause(cpu_env, t0);
10736                 break;
10737             default:
10738                 goto die;
10739                 break;
10740             }
10741             break;
10742         case 15:
10743             switch (sel) {
10744             case 1:
10745                 gen_helper_mttc0_ebase(cpu_env, t0);
10746                 break;
10747             default:
10748                 goto die;
10749                 break;
10750             }
10751             break;
10752         case 23:
10753             switch (sel) {
10754             case 0:
10755                 gen_helper_mttc0_debug(cpu_env, t0);
10756                 break;
10757             default:
10758                 gen_mtc0(ctx, t0, rd, sel);
10759                 break;
10760             }
10761             break;
10762         default:
10763             gen_mtc0(ctx, t0, rd, sel);
10764         }
10765     } else {
10766         switch (sel) {
10767         /* GPR registers. */
10768         case 0:
10769             gen_helper_0e1i(mttgpr, t0, rd);
10770             break;
10771         /* Auxiliary CPU registers */
10772         case 1:
10773             switch (rd) {
10774             case 0:
10775                 gen_helper_0e1i(mttlo, t0, 0);
10776                 break;
10777             case 1:
10778                 gen_helper_0e1i(mtthi, t0, 0);
10779                 break;
10780             case 2:
10781                 gen_helper_0e1i(mttacx, t0, 0);
10782                 break;
10783             case 4:
10784                 gen_helper_0e1i(mttlo, t0, 1);
10785                 break;
10786             case 5:
10787                 gen_helper_0e1i(mtthi, t0, 1);
10788                 break;
10789             case 6:
10790                 gen_helper_0e1i(mttacx, t0, 1);
10791                 break;
10792             case 8:
10793                 gen_helper_0e1i(mttlo, t0, 2);
10794                 break;
10795             case 9:
10796                 gen_helper_0e1i(mtthi, t0, 2);
10797                 break;
10798             case 10:
10799                 gen_helper_0e1i(mttacx, t0, 2);
10800                 break;
10801             case 12:
10802                 gen_helper_0e1i(mttlo, t0, 3);
10803                 break;
10804             case 13:
10805                 gen_helper_0e1i(mtthi, t0, 3);
10806                 break;
10807             case 14:
10808                 gen_helper_0e1i(mttacx, t0, 3);
10809                 break;
10810             case 16:
10811                 gen_helper_mttdsp(cpu_env, t0);
10812                 break;
10813             default:
10814                 goto die;
10815             }
10816             break;
10817         /* Floating point (COP1). */
10818         case 2:
10819             /* XXX: For now we support only a single FPU context. */
10820             if (h == 0) {
10821                 TCGv_i32 fp0 = tcg_temp_new_i32();
10822 
10823                 tcg_gen_trunc_tl_i32(fp0, t0);
10824                 gen_store_fpr32(ctx, fp0, rd);
10825                 tcg_temp_free_i32(fp0);
10826             } else {
10827                 TCGv_i32 fp0 = tcg_temp_new_i32();
10828 
10829                 tcg_gen_trunc_tl_i32(fp0, t0);
10830                 gen_store_fpr32h(ctx, fp0, rd);
10831                 tcg_temp_free_i32(fp0);
10832             }
10833             break;
10834         case 3:
10835             /* XXX: For now we support only a single FPU context. */
10836             {
10837                 TCGv_i32 fs_tmp = tcg_const_i32(rd);
10838 
10839                 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10840                 tcg_temp_free_i32(fs_tmp);
10841             }
10842             /* Stop translation as we may have changed hflags */
10843             ctx->base.is_jmp = DISAS_STOP;
10844             break;
10845         /* COP2: Not implemented. */
10846         case 4:
10847         case 5:
10848             /* fall through */
10849         default:
10850             goto die;
10851         }
10852     }
10853     trace_mips_translate_tr("mttr", rd, u, sel, h);
10854     tcg_temp_free(t0);
10855     return;
10856 
10857 die:
10858     tcg_temp_free(t0);
10859     LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
10860     generate_exception_end(ctx, EXCP_RI);
10861 }
10862 
gen_cp0(CPUMIPSState * env,DisasContext * ctx,uint32_t opc,int rt,int rd)10863 static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
10864                     int rt, int rd)
10865 {
10866     const char *opn = "ldst";
10867 
10868     check_cp0_enabled(ctx);
10869     switch (opc) {
10870     case OPC_MFC0:
10871         if (rt == 0) {
10872             /* Treat as NOP. */
10873             return;
10874         }
10875         gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10876         opn = "mfc0";
10877         break;
10878     case OPC_MTC0:
10879         {
10880             TCGv t0 = tcg_temp_new();
10881 
10882             gen_load_gpr(t0, rt);
10883             gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
10884             tcg_temp_free(t0);
10885         }
10886         opn = "mtc0";
10887         break;
10888 #if defined(TARGET_MIPS64)
10889     case OPC_DMFC0:
10890         check_insn(ctx, ISA_MIPS3);
10891         if (rt == 0) {
10892             /* Treat as NOP. */
10893             return;
10894         }
10895         gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10896         opn = "dmfc0";
10897         break;
10898     case OPC_DMTC0:
10899         check_insn(ctx, ISA_MIPS3);
10900         {
10901             TCGv t0 = tcg_temp_new();
10902 
10903             gen_load_gpr(t0, rt);
10904             gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
10905             tcg_temp_free(t0);
10906         }
10907         opn = "dmtc0";
10908         break;
10909 #endif
10910     case OPC_MFHC0:
10911         check_mvh(ctx);
10912         if (rt == 0) {
10913             /* Treat as NOP. */
10914             return;
10915         }
10916         gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10917         opn = "mfhc0";
10918         break;
10919     case OPC_MTHC0:
10920         check_mvh(ctx);
10921         {
10922             TCGv t0 = tcg_temp_new();
10923             gen_load_gpr(t0, rt);
10924             gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
10925             tcg_temp_free(t0);
10926         }
10927         opn = "mthc0";
10928         break;
10929     case OPC_MFTR:
10930         check_cp0_enabled(ctx);
10931         if (rd == 0) {
10932             /* Treat as NOP. */
10933             return;
10934         }
10935         gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
10936                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
10937         opn = "mftr";
10938         break;
10939     case OPC_MTTR:
10940         check_cp0_enabled(ctx);
10941         gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
10942                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
10943         opn = "mttr";
10944         break;
10945     case OPC_TLBWI:
10946         opn = "tlbwi";
10947         if (!env->tlb->helper_tlbwi) {
10948             goto die;
10949         }
10950         gen_helper_tlbwi(cpu_env);
10951         break;
10952     case OPC_TLBINV:
10953         opn = "tlbinv";
10954         if (ctx->ie >= 2) {
10955             if (!env->tlb->helper_tlbinv) {
10956                 goto die;
10957             }
10958             gen_helper_tlbinv(cpu_env);
10959         } /* treat as nop if TLBINV not supported */
10960         break;
10961     case OPC_TLBINVF:
10962         opn = "tlbinvf";
10963         if (ctx->ie >= 2) {
10964             if (!env->tlb->helper_tlbinvf) {
10965                 goto die;
10966             }
10967             gen_helper_tlbinvf(cpu_env);
10968         } /* treat as nop if TLBINV not supported */
10969         break;
10970     case OPC_TLBWR:
10971         opn = "tlbwr";
10972         if (!env->tlb->helper_tlbwr) {
10973             goto die;
10974         }
10975         gen_helper_tlbwr(cpu_env);
10976         break;
10977     case OPC_TLBP:
10978         opn = "tlbp";
10979         if (!env->tlb->helper_tlbp) {
10980             goto die;
10981         }
10982         gen_helper_tlbp(cpu_env);
10983         break;
10984     case OPC_TLBR:
10985         opn = "tlbr";
10986         if (!env->tlb->helper_tlbr) {
10987             goto die;
10988         }
10989         gen_helper_tlbr(cpu_env);
10990         break;
10991     case OPC_ERET: /* OPC_ERETNC */
10992         if ((ctx->insn_flags & ISA_MIPS32R6) &&
10993             (ctx->hflags & MIPS_HFLAG_BMASK)) {
10994             goto die;
10995         } else {
10996             int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
10997             if (ctx->opcode & (1 << bit_shift)) {
10998                 /* OPC_ERETNC */
10999                 opn = "eretnc";
11000                 check_insn(ctx, ISA_MIPS32R5);
11001                 gen_helper_eretnc(cpu_env);
11002             } else {
11003                 /* OPC_ERET */
11004                 opn = "eret";
11005                 check_insn(ctx, ISA_MIPS2);
11006                 gen_helper_eret(cpu_env);
11007             }
11008             ctx->base.is_jmp = DISAS_EXIT;
11009         }
11010         break;
11011     case OPC_DERET:
11012         opn = "deret";
11013         check_insn(ctx, ISA_MIPS32);
11014         if ((ctx->insn_flags & ISA_MIPS32R6) &&
11015             (ctx->hflags & MIPS_HFLAG_BMASK)) {
11016             goto die;
11017         }
11018         if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11019             MIPS_INVAL(opn);
11020             generate_exception_end(ctx, EXCP_RI);
11021         } else {
11022             gen_helper_deret(cpu_env);
11023             ctx->base.is_jmp = DISAS_EXIT;
11024         }
11025         break;
11026     case OPC_WAIT:
11027         opn = "wait";
11028         check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
11029         if ((ctx->insn_flags & ISA_MIPS32R6) &&
11030             (ctx->hflags & MIPS_HFLAG_BMASK)) {
11031             goto die;
11032         }
11033         /* If we get an exception, we want to restart at next instruction */
11034         ctx->base.pc_next += 4;
11035         save_cpu_state(ctx, 1);
11036         ctx->base.pc_next -= 4;
11037         gen_helper_wait(cpu_env);
11038         ctx->base.is_jmp = DISAS_NORETURN;
11039         break;
11040     default:
11041  die:
11042         MIPS_INVAL(opn);
11043         generate_exception_end(ctx, EXCP_RI);
11044         return;
11045     }
11046     (void)opn; /* avoid a compiler warning */
11047 }
11048 #endif /* !CONFIG_USER_ONLY */
11049 
11050 /* CP1 Branches (before delay slot) */
gen_compute_branch1(DisasContext * ctx,uint32_t op,int32_t cc,int32_t offset)11051 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
11052                                 int32_t cc, int32_t offset)
11053 {
11054     target_ulong btarget;
11055     TCGv_i32 t0 = tcg_temp_new_i32();
11056 
11057     if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11058         generate_exception_end(ctx, EXCP_RI);
11059         goto out;
11060     }
11061 
11062     if (cc != 0) {
11063         check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
11064     }
11065 
11066     btarget = ctx->base.pc_next + 4 + offset;
11067 
11068     switch (op) {
11069     case OPC_BC1F:
11070         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
11071         tcg_gen_not_i32(t0, t0);
11072         tcg_gen_andi_i32(t0, t0, 1);
11073         tcg_gen_extu_i32_tl(bcond, t0);
11074         goto not_likely;
11075     case OPC_BC1FL:
11076         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
11077         tcg_gen_not_i32(t0, t0);
11078         tcg_gen_andi_i32(t0, t0, 1);
11079         tcg_gen_extu_i32_tl(bcond, t0);
11080         goto likely;
11081     case OPC_BC1T:
11082         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
11083         tcg_gen_andi_i32(t0, t0, 1);
11084         tcg_gen_extu_i32_tl(bcond, t0);
11085         goto not_likely;
11086     case OPC_BC1TL:
11087         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
11088         tcg_gen_andi_i32(t0, t0, 1);
11089         tcg_gen_extu_i32_tl(bcond, t0);
11090     likely:
11091         ctx->hflags |= MIPS_HFLAG_BL;
11092         break;
11093     case OPC_BC1FANY2:
11094         {
11095             TCGv_i32 t1 = tcg_temp_new_i32();
11096             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
11097             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
11098             tcg_gen_nand_i32(t0, t0, t1);
11099             tcg_temp_free_i32(t1);
11100             tcg_gen_andi_i32(t0, t0, 1);
11101             tcg_gen_extu_i32_tl(bcond, t0);
11102         }
11103         goto not_likely;
11104     case OPC_BC1TANY2:
11105         {
11106             TCGv_i32 t1 = tcg_temp_new_i32();
11107             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
11108             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
11109             tcg_gen_or_i32(t0, t0, t1);
11110             tcg_temp_free_i32(t1);
11111             tcg_gen_andi_i32(t0, t0, 1);
11112             tcg_gen_extu_i32_tl(bcond, t0);
11113         }
11114         goto not_likely;
11115     case OPC_BC1FANY4:
11116         {
11117             TCGv_i32 t1 = tcg_temp_new_i32();
11118             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
11119             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
11120             tcg_gen_and_i32(t0, t0, t1);
11121             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
11122             tcg_gen_and_i32(t0, t0, t1);
11123             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
11124             tcg_gen_nand_i32(t0, t0, t1);
11125             tcg_temp_free_i32(t1);
11126             tcg_gen_andi_i32(t0, t0, 1);
11127             tcg_gen_extu_i32_tl(bcond, t0);
11128         }
11129         goto not_likely;
11130     case OPC_BC1TANY4:
11131         {
11132             TCGv_i32 t1 = tcg_temp_new_i32();
11133             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
11134             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
11135             tcg_gen_or_i32(t0, t0, t1);
11136             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
11137             tcg_gen_or_i32(t0, t0, t1);
11138             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
11139             tcg_gen_or_i32(t0, t0, t1);
11140             tcg_temp_free_i32(t1);
11141             tcg_gen_andi_i32(t0, t0, 1);
11142             tcg_gen_extu_i32_tl(bcond, t0);
11143         }
11144     not_likely:
11145         ctx->hflags |= MIPS_HFLAG_BC;
11146         break;
11147     default:
11148         MIPS_INVAL("cp1 cond branch");
11149         generate_exception_end(ctx, EXCP_RI);
11150         goto out;
11151     }
11152     ctx->btarget = btarget;
11153     ctx->hflags |= MIPS_HFLAG_BDS32;
11154  out:
11155     tcg_temp_free_i32(t0);
11156 }
11157 
11158 /* R6 CP1 Branches */
gen_compute_branch1_r6(DisasContext * ctx,uint32_t op,int32_t ft,int32_t offset,int delayslot_size)11159 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
11160                                    int32_t ft, int32_t offset,
11161                                    int delayslot_size)
11162 {
11163     target_ulong btarget;
11164     TCGv_i64 t0 = tcg_temp_new_i64();
11165 
11166     if (ctx->hflags & MIPS_HFLAG_BMASK) {
11167 #ifdef MIPS_DEBUG_DISAS
11168         LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
11169                   "\n", ctx->base.pc_next);
11170 #endif
11171         generate_exception_end(ctx, EXCP_RI);
11172         goto out;
11173     }
11174 
11175     gen_load_fpr64(ctx, t0, ft);
11176     tcg_gen_andi_i64(t0, t0, 1);
11177 
11178     btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11179 
11180     switch (op) {
11181     case OPC_BC1EQZ:
11182         tcg_gen_xori_i64(t0, t0, 1);
11183         ctx->hflags |= MIPS_HFLAG_BC;
11184         break;
11185     case OPC_BC1NEZ:
11186         /* t0 already set */
11187         ctx->hflags |= MIPS_HFLAG_BC;
11188         break;
11189     default:
11190         MIPS_INVAL("cp1 cond branch");
11191         generate_exception_end(ctx, EXCP_RI);
11192         goto out;
11193     }
11194 
11195     tcg_gen_trunc_i64_tl(bcond, t0);
11196 
11197     ctx->btarget = btarget;
11198 
11199     switch (delayslot_size) {
11200     case 2:
11201         ctx->hflags |= MIPS_HFLAG_BDS16;
11202         break;
11203     case 4:
11204         ctx->hflags |= MIPS_HFLAG_BDS32;
11205         break;
11206     }
11207 
11208 out:
11209     tcg_temp_free_i64(t0);
11210 }
11211 
11212 /* Coprocessor 1 (FPU) */
11213 
11214 #define FOP(func, fmt) (((fmt) << 21) | (func))
11215 
11216 enum fopcode {
11217     OPC_ADD_S = FOP(0, FMT_S),
11218     OPC_SUB_S = FOP(1, FMT_S),
11219     OPC_MUL_S = FOP(2, FMT_S),
11220     OPC_DIV_S = FOP(3, FMT_S),
11221     OPC_SQRT_S = FOP(4, FMT_S),
11222     OPC_ABS_S = FOP(5, FMT_S),
11223     OPC_MOV_S = FOP(6, FMT_S),
11224     OPC_NEG_S = FOP(7, FMT_S),
11225     OPC_ROUND_L_S = FOP(8, FMT_S),
11226     OPC_TRUNC_L_S = FOP(9, FMT_S),
11227     OPC_CEIL_L_S = FOP(10, FMT_S),
11228     OPC_FLOOR_L_S = FOP(11, FMT_S),
11229     OPC_ROUND_W_S = FOP(12, FMT_S),
11230     OPC_TRUNC_W_S = FOP(13, FMT_S),
11231     OPC_CEIL_W_S = FOP(14, FMT_S),
11232     OPC_FLOOR_W_S = FOP(15, FMT_S),
11233     OPC_SEL_S = FOP(16, FMT_S),
11234     OPC_MOVCF_S = FOP(17, FMT_S),
11235     OPC_MOVZ_S = FOP(18, FMT_S),
11236     OPC_MOVN_S = FOP(19, FMT_S),
11237     OPC_SELEQZ_S = FOP(20, FMT_S),
11238     OPC_RECIP_S = FOP(21, FMT_S),
11239     OPC_RSQRT_S = FOP(22, FMT_S),
11240     OPC_SELNEZ_S = FOP(23, FMT_S),
11241     OPC_MADDF_S = FOP(24, FMT_S),
11242     OPC_MSUBF_S = FOP(25, FMT_S),
11243     OPC_RINT_S = FOP(26, FMT_S),
11244     OPC_CLASS_S = FOP(27, FMT_S),
11245     OPC_MIN_S = FOP(28, FMT_S),
11246     OPC_RECIP2_S = FOP(28, FMT_S),
11247     OPC_MINA_S = FOP(29, FMT_S),
11248     OPC_RECIP1_S = FOP(29, FMT_S),
11249     OPC_MAX_S = FOP(30, FMT_S),
11250     OPC_RSQRT1_S = FOP(30, FMT_S),
11251     OPC_MAXA_S = FOP(31, FMT_S),
11252     OPC_RSQRT2_S = FOP(31, FMT_S),
11253     OPC_CVT_D_S = FOP(33, FMT_S),
11254     OPC_CVT_W_S = FOP(36, FMT_S),
11255     OPC_CVT_L_S = FOP(37, FMT_S),
11256     OPC_CVT_PS_S = FOP(38, FMT_S),
11257     OPC_CMP_F_S = FOP(48, FMT_S),
11258     OPC_CMP_UN_S = FOP(49, FMT_S),
11259     OPC_CMP_EQ_S = FOP(50, FMT_S),
11260     OPC_CMP_UEQ_S = FOP(51, FMT_S),
11261     OPC_CMP_OLT_S = FOP(52, FMT_S),
11262     OPC_CMP_ULT_S = FOP(53, FMT_S),
11263     OPC_CMP_OLE_S = FOP(54, FMT_S),
11264     OPC_CMP_ULE_S = FOP(55, FMT_S),
11265     OPC_CMP_SF_S = FOP(56, FMT_S),
11266     OPC_CMP_NGLE_S = FOP(57, FMT_S),
11267     OPC_CMP_SEQ_S = FOP(58, FMT_S),
11268     OPC_CMP_NGL_S = FOP(59, FMT_S),
11269     OPC_CMP_LT_S = FOP(60, FMT_S),
11270     OPC_CMP_NGE_S = FOP(61, FMT_S),
11271     OPC_CMP_LE_S = FOP(62, FMT_S),
11272     OPC_CMP_NGT_S = FOP(63, FMT_S),
11273 
11274     OPC_ADD_D = FOP(0, FMT_D),
11275     OPC_SUB_D = FOP(1, FMT_D),
11276     OPC_MUL_D = FOP(2, FMT_D),
11277     OPC_DIV_D = FOP(3, FMT_D),
11278     OPC_SQRT_D = FOP(4, FMT_D),
11279     OPC_ABS_D = FOP(5, FMT_D),
11280     OPC_MOV_D = FOP(6, FMT_D),
11281     OPC_NEG_D = FOP(7, FMT_D),
11282     OPC_ROUND_L_D = FOP(8, FMT_D),
11283     OPC_TRUNC_L_D = FOP(9, FMT_D),
11284     OPC_CEIL_L_D = FOP(10, FMT_D),
11285     OPC_FLOOR_L_D = FOP(11, FMT_D),
11286     OPC_ROUND_W_D = FOP(12, FMT_D),
11287     OPC_TRUNC_W_D = FOP(13, FMT_D),
11288     OPC_CEIL_W_D = FOP(14, FMT_D),
11289     OPC_FLOOR_W_D = FOP(15, FMT_D),
11290     OPC_SEL_D = FOP(16, FMT_D),
11291     OPC_MOVCF_D = FOP(17, FMT_D),
11292     OPC_MOVZ_D = FOP(18, FMT_D),
11293     OPC_MOVN_D = FOP(19, FMT_D),
11294     OPC_SELEQZ_D = FOP(20, FMT_D),
11295     OPC_RECIP_D = FOP(21, FMT_D),
11296     OPC_RSQRT_D = FOP(22, FMT_D),
11297     OPC_SELNEZ_D = FOP(23, FMT_D),
11298     OPC_MADDF_D = FOP(24, FMT_D),
11299     OPC_MSUBF_D = FOP(25, FMT_D),
11300     OPC_RINT_D = FOP(26, FMT_D),
11301     OPC_CLASS_D = FOP(27, FMT_D),
11302     OPC_MIN_D = FOP(28, FMT_D),
11303     OPC_RECIP2_D = FOP(28, FMT_D),
11304     OPC_MINA_D = FOP(29, FMT_D),
11305     OPC_RECIP1_D = FOP(29, FMT_D),
11306     OPC_MAX_D = FOP(30, FMT_D),
11307     OPC_RSQRT1_D = FOP(30, FMT_D),
11308     OPC_MAXA_D = FOP(31, FMT_D),
11309     OPC_RSQRT2_D = FOP(31, FMT_D),
11310     OPC_CVT_S_D = FOP(32, FMT_D),
11311     OPC_CVT_W_D = FOP(36, FMT_D),
11312     OPC_CVT_L_D = FOP(37, FMT_D),
11313     OPC_CMP_F_D = FOP(48, FMT_D),
11314     OPC_CMP_UN_D = FOP(49, FMT_D),
11315     OPC_CMP_EQ_D = FOP(50, FMT_D),
11316     OPC_CMP_UEQ_D = FOP(51, FMT_D),
11317     OPC_CMP_OLT_D = FOP(52, FMT_D),
11318     OPC_CMP_ULT_D = FOP(53, FMT_D),
11319     OPC_CMP_OLE_D = FOP(54, FMT_D),
11320     OPC_CMP_ULE_D = FOP(55, FMT_D),
11321     OPC_CMP_SF_D = FOP(56, FMT_D),
11322     OPC_CMP_NGLE_D = FOP(57, FMT_D),
11323     OPC_CMP_SEQ_D = FOP(58, FMT_D),
11324     OPC_CMP_NGL_D = FOP(59, FMT_D),
11325     OPC_CMP_LT_D = FOP(60, FMT_D),
11326     OPC_CMP_NGE_D = FOP(61, FMT_D),
11327     OPC_CMP_LE_D = FOP(62, FMT_D),
11328     OPC_CMP_NGT_D = FOP(63, FMT_D),
11329 
11330     OPC_CVT_S_W = FOP(32, FMT_W),
11331     OPC_CVT_D_W = FOP(33, FMT_W),
11332     OPC_CVT_S_L = FOP(32, FMT_L),
11333     OPC_CVT_D_L = FOP(33, FMT_L),
11334     OPC_CVT_PS_PW = FOP(38, FMT_W),
11335 
11336     OPC_ADD_PS = FOP(0, FMT_PS),
11337     OPC_SUB_PS = FOP(1, FMT_PS),
11338     OPC_MUL_PS = FOP(2, FMT_PS),
11339     OPC_DIV_PS = FOP(3, FMT_PS),
11340     OPC_ABS_PS = FOP(5, FMT_PS),
11341     OPC_MOV_PS = FOP(6, FMT_PS),
11342     OPC_NEG_PS = FOP(7, FMT_PS),
11343     OPC_MOVCF_PS = FOP(17, FMT_PS),
11344     OPC_MOVZ_PS = FOP(18, FMT_PS),
11345     OPC_MOVN_PS = FOP(19, FMT_PS),
11346     OPC_ADDR_PS = FOP(24, FMT_PS),
11347     OPC_MULR_PS = FOP(26, FMT_PS),
11348     OPC_RECIP2_PS = FOP(28, FMT_PS),
11349     OPC_RECIP1_PS = FOP(29, FMT_PS),
11350     OPC_RSQRT1_PS = FOP(30, FMT_PS),
11351     OPC_RSQRT2_PS = FOP(31, FMT_PS),
11352 
11353     OPC_CVT_S_PU = FOP(32, FMT_PS),
11354     OPC_CVT_PW_PS = FOP(36, FMT_PS),
11355     OPC_CVT_S_PL = FOP(40, FMT_PS),
11356     OPC_PLL_PS = FOP(44, FMT_PS),
11357     OPC_PLU_PS = FOP(45, FMT_PS),
11358     OPC_PUL_PS = FOP(46, FMT_PS),
11359     OPC_PUU_PS = FOP(47, FMT_PS),
11360     OPC_CMP_F_PS = FOP(48, FMT_PS),
11361     OPC_CMP_UN_PS = FOP(49, FMT_PS),
11362     OPC_CMP_EQ_PS = FOP(50, FMT_PS),
11363     OPC_CMP_UEQ_PS = FOP(51, FMT_PS),
11364     OPC_CMP_OLT_PS = FOP(52, FMT_PS),
11365     OPC_CMP_ULT_PS = FOP(53, FMT_PS),
11366     OPC_CMP_OLE_PS = FOP(54, FMT_PS),
11367     OPC_CMP_ULE_PS = FOP(55, FMT_PS),
11368     OPC_CMP_SF_PS = FOP(56, FMT_PS),
11369     OPC_CMP_NGLE_PS = FOP(57, FMT_PS),
11370     OPC_CMP_SEQ_PS = FOP(58, FMT_PS),
11371     OPC_CMP_NGL_PS = FOP(59, FMT_PS),
11372     OPC_CMP_LT_PS = FOP(60, FMT_PS),
11373     OPC_CMP_NGE_PS = FOP(61, FMT_PS),
11374     OPC_CMP_LE_PS = FOP(62, FMT_PS),
11375     OPC_CMP_NGT_PS = FOP(63, FMT_PS),
11376 };
11377 
11378 enum r6_f_cmp_op {
11379     R6_OPC_CMP_AF_S   = FOP(0, FMT_W),
11380     R6_OPC_CMP_UN_S   = FOP(1, FMT_W),
11381     R6_OPC_CMP_EQ_S   = FOP(2, FMT_W),
11382     R6_OPC_CMP_UEQ_S  = FOP(3, FMT_W),
11383     R6_OPC_CMP_LT_S   = FOP(4, FMT_W),
11384     R6_OPC_CMP_ULT_S  = FOP(5, FMT_W),
11385     R6_OPC_CMP_LE_S   = FOP(6, FMT_W),
11386     R6_OPC_CMP_ULE_S  = FOP(7, FMT_W),
11387     R6_OPC_CMP_SAF_S  = FOP(8, FMT_W),
11388     R6_OPC_CMP_SUN_S  = FOP(9, FMT_W),
11389     R6_OPC_CMP_SEQ_S  = FOP(10, FMT_W),
11390     R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
11391     R6_OPC_CMP_SLT_S  = FOP(12, FMT_W),
11392     R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
11393     R6_OPC_CMP_SLE_S  = FOP(14, FMT_W),
11394     R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
11395     R6_OPC_CMP_OR_S   = FOP(17, FMT_W),
11396     R6_OPC_CMP_UNE_S  = FOP(18, FMT_W),
11397     R6_OPC_CMP_NE_S   = FOP(19, FMT_W),
11398     R6_OPC_CMP_SOR_S  = FOP(25, FMT_W),
11399     R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
11400     R6_OPC_CMP_SNE_S  = FOP(27, FMT_W),
11401 
11402     R6_OPC_CMP_AF_D   = FOP(0, FMT_L),
11403     R6_OPC_CMP_UN_D   = FOP(1, FMT_L),
11404     R6_OPC_CMP_EQ_D   = FOP(2, FMT_L),
11405     R6_OPC_CMP_UEQ_D  = FOP(3, FMT_L),
11406     R6_OPC_CMP_LT_D   = FOP(4, FMT_L),
11407     R6_OPC_CMP_ULT_D  = FOP(5, FMT_L),
11408     R6_OPC_CMP_LE_D   = FOP(6, FMT_L),
11409     R6_OPC_CMP_ULE_D  = FOP(7, FMT_L),
11410     R6_OPC_CMP_SAF_D  = FOP(8, FMT_L),
11411     R6_OPC_CMP_SUN_D  = FOP(9, FMT_L),
11412     R6_OPC_CMP_SEQ_D  = FOP(10, FMT_L),
11413     R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
11414     R6_OPC_CMP_SLT_D  = FOP(12, FMT_L),
11415     R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
11416     R6_OPC_CMP_SLE_D  = FOP(14, FMT_L),
11417     R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
11418     R6_OPC_CMP_OR_D   = FOP(17, FMT_L),
11419     R6_OPC_CMP_UNE_D  = FOP(18, FMT_L),
11420     R6_OPC_CMP_NE_D   = FOP(19, FMT_L),
11421     R6_OPC_CMP_SOR_D  = FOP(25, FMT_L),
11422     R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
11423     R6_OPC_CMP_SNE_D  = FOP(27, FMT_L),
11424 };
11425 
gen_cp1(DisasContext * ctx,uint32_t opc,int rt,int fs)11426 static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs)
11427 {
11428     TCGv t0 = tcg_temp_new();
11429 
11430     switch (opc) {
11431     case OPC_MFC1:
11432         {
11433             TCGv_i32 fp0 = tcg_temp_new_i32();
11434 
11435             gen_load_fpr32(ctx, fp0, fs);
11436             tcg_gen_ext_i32_tl(t0, fp0);
11437             tcg_temp_free_i32(fp0);
11438         }
11439         gen_store_gpr(t0, rt);
11440         break;
11441     case OPC_MTC1:
11442         gen_load_gpr(t0, rt);
11443         {
11444             TCGv_i32 fp0 = tcg_temp_new_i32();
11445 
11446             tcg_gen_trunc_tl_i32(fp0, t0);
11447             gen_store_fpr32(ctx, fp0, fs);
11448             tcg_temp_free_i32(fp0);
11449         }
11450         break;
11451     case OPC_CFC1:
11452         gen_helper_1e0i(cfc1, t0, fs);
11453         gen_store_gpr(t0, rt);
11454         break;
11455     case OPC_CTC1:
11456         gen_load_gpr(t0, rt);
11457         save_cpu_state(ctx, 0);
11458         {
11459             TCGv_i32 fs_tmp = tcg_const_i32(fs);
11460 
11461             gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
11462             tcg_temp_free_i32(fs_tmp);
11463         }
11464         /* Stop translation as we may have changed hflags */
11465         ctx->base.is_jmp = DISAS_STOP;
11466         break;
11467 #if defined(TARGET_MIPS64)
11468     case OPC_DMFC1:
11469         gen_load_fpr64(ctx, t0, fs);
11470         gen_store_gpr(t0, rt);
11471         break;
11472     case OPC_DMTC1:
11473         gen_load_gpr(t0, rt);
11474         gen_store_fpr64(ctx, t0, fs);
11475         break;
11476 #endif
11477     case OPC_MFHC1:
11478         {
11479             TCGv_i32 fp0 = tcg_temp_new_i32();
11480 
11481             gen_load_fpr32h(ctx, fp0, fs);
11482             tcg_gen_ext_i32_tl(t0, fp0);
11483             tcg_temp_free_i32(fp0);
11484         }
11485         gen_store_gpr(t0, rt);
11486         break;
11487     case OPC_MTHC1:
11488         gen_load_gpr(t0, rt);
11489         {
11490             TCGv_i32 fp0 = tcg_temp_new_i32();
11491 
11492             tcg_gen_trunc_tl_i32(fp0, t0);
11493             gen_store_fpr32h(ctx, fp0, fs);
11494             tcg_temp_free_i32(fp0);
11495         }
11496         break;
11497     default:
11498         MIPS_INVAL("cp1 move");
11499         generate_exception_end(ctx, EXCP_RI);
11500         goto out;
11501     }
11502 
11503  out:
11504     tcg_temp_free(t0);
11505 }
11506 
gen_movci(DisasContext * ctx,int rd,int rs,int cc,int tf)11507 static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf)
11508 {
11509     TCGLabel *l1;
11510     TCGCond cond;
11511     TCGv_i32 t0;
11512 
11513     if (rd == 0) {
11514         /* Treat as NOP. */
11515         return;
11516     }
11517 
11518     if (tf) {
11519         cond = TCG_COND_EQ;
11520     } else {
11521         cond = TCG_COND_NE;
11522     }
11523 
11524     l1 = gen_new_label();
11525     t0 = tcg_temp_new_i32();
11526     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
11527     tcg_gen_brcondi_i32(cond, t0, 0, l1);
11528     tcg_temp_free_i32(t0);
11529     if (rs == 0) {
11530         tcg_gen_movi_tl(cpu_gpr[rd], 0);
11531     } else {
11532         tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
11533     }
11534     gen_set_label(l1);
11535 }
11536 
gen_movcf_s(DisasContext * ctx,int fs,int fd,int cc,int tf)11537 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
11538                                int tf)
11539 {
11540     int cond;
11541     TCGv_i32 t0 = tcg_temp_new_i32();
11542     TCGLabel *l1 = gen_new_label();
11543 
11544     if (tf) {
11545         cond = TCG_COND_EQ;
11546     } else {
11547         cond = TCG_COND_NE;
11548     }
11549 
11550     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
11551     tcg_gen_brcondi_i32(cond, t0, 0, l1);
11552     gen_load_fpr32(ctx, t0, fs);
11553     gen_store_fpr32(ctx, t0, fd);
11554     gen_set_label(l1);
11555     tcg_temp_free_i32(t0);
11556 }
11557 
gen_movcf_d(DisasContext * ctx,int fs,int fd,int cc,int tf)11558 static inline void gen_movcf_d(DisasContext *ctx, int fs, int fd, int cc,
11559                                int tf)
11560 {
11561     int cond;
11562     TCGv_i32 t0 = tcg_temp_new_i32();
11563     TCGv_i64 fp0;
11564     TCGLabel *l1 = gen_new_label();
11565 
11566     if (tf) {
11567         cond = TCG_COND_EQ;
11568     } else {
11569         cond = TCG_COND_NE;
11570     }
11571 
11572     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
11573     tcg_gen_brcondi_i32(cond, t0, 0, l1);
11574     tcg_temp_free_i32(t0);
11575     fp0 = tcg_temp_new_i64();
11576     gen_load_fpr64(ctx, fp0, fs);
11577     gen_store_fpr64(ctx, fp0, fd);
11578     tcg_temp_free_i64(fp0);
11579     gen_set_label(l1);
11580 }
11581 
gen_movcf_ps(DisasContext * ctx,int fs,int fd,int cc,int tf)11582 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
11583                                 int cc, int tf)
11584 {
11585     int cond;
11586     TCGv_i32 t0 = tcg_temp_new_i32();
11587     TCGLabel *l1 = gen_new_label();
11588     TCGLabel *l2 = gen_new_label();
11589 
11590     if (tf) {
11591         cond = TCG_COND_EQ;
11592     } else {
11593         cond = TCG_COND_NE;
11594     }
11595 
11596     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
11597     tcg_gen_brcondi_i32(cond, t0, 0, l1);
11598     gen_load_fpr32(ctx, t0, fs);
11599     gen_store_fpr32(ctx, t0, fd);
11600     gen_set_label(l1);
11601 
11602     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc + 1));
11603     tcg_gen_brcondi_i32(cond, t0, 0, l2);
11604     gen_load_fpr32h(ctx, t0, fs);
11605     gen_store_fpr32h(ctx, t0, fd);
11606     tcg_temp_free_i32(t0);
11607     gen_set_label(l2);
11608 }
11609 
gen_sel_s(DisasContext * ctx,enum fopcode op1,int fd,int ft,int fs)11610 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
11611                       int fs)
11612 {
11613     TCGv_i32 t1 = tcg_const_i32(0);
11614     TCGv_i32 fp0 = tcg_temp_new_i32();
11615     TCGv_i32 fp1 = tcg_temp_new_i32();
11616     TCGv_i32 fp2 = tcg_temp_new_i32();
11617     gen_load_fpr32(ctx, fp0, fd);
11618     gen_load_fpr32(ctx, fp1, ft);
11619     gen_load_fpr32(ctx, fp2, fs);
11620 
11621     switch (op1) {
11622     case OPC_SEL_S:
11623         tcg_gen_andi_i32(fp0, fp0, 1);
11624         tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
11625         break;
11626     case OPC_SELEQZ_S:
11627         tcg_gen_andi_i32(fp1, fp1, 1);
11628         tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
11629         break;
11630     case OPC_SELNEZ_S:
11631         tcg_gen_andi_i32(fp1, fp1, 1);
11632         tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
11633         break;
11634     default:
11635         MIPS_INVAL("gen_sel_s");
11636         generate_exception_end(ctx, EXCP_RI);
11637         break;
11638     }
11639 
11640     gen_store_fpr32(ctx, fp0, fd);
11641     tcg_temp_free_i32(fp2);
11642     tcg_temp_free_i32(fp1);
11643     tcg_temp_free_i32(fp0);
11644     tcg_temp_free_i32(t1);
11645 }
11646 
gen_sel_d(DisasContext * ctx,enum fopcode op1,int fd,int ft,int fs)11647 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
11648                       int fs)
11649 {
11650     TCGv_i64 t1 = tcg_const_i64(0);
11651     TCGv_i64 fp0 = tcg_temp_new_i64();
11652     TCGv_i64 fp1 = tcg_temp_new_i64();
11653     TCGv_i64 fp2 = tcg_temp_new_i64();
11654     gen_load_fpr64(ctx, fp0, fd);
11655     gen_load_fpr64(ctx, fp1, ft);
11656     gen_load_fpr64(ctx, fp2, fs);
11657 
11658     switch (op1) {
11659     case OPC_SEL_D:
11660         tcg_gen_andi_i64(fp0, fp0, 1);
11661         tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
11662         break;
11663     case OPC_SELEQZ_D:
11664         tcg_gen_andi_i64(fp1, fp1, 1);
11665         tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
11666         break;
11667     case OPC_SELNEZ_D:
11668         tcg_gen_andi_i64(fp1, fp1, 1);
11669         tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
11670         break;
11671     default:
11672         MIPS_INVAL("gen_sel_d");
11673         generate_exception_end(ctx, EXCP_RI);
11674         break;
11675     }
11676 
11677     gen_store_fpr64(ctx, fp0, fd);
11678     tcg_temp_free_i64(fp2);
11679     tcg_temp_free_i64(fp1);
11680     tcg_temp_free_i64(fp0);
11681     tcg_temp_free_i64(t1);
11682 }
11683 
gen_farith(DisasContext * ctx,enum fopcode op1,int ft,int fs,int fd,int cc)11684 static void gen_farith(DisasContext *ctx, enum fopcode op1,
11685                        int ft, int fs, int fd, int cc)
11686 {
11687     uint32_t func = ctx->opcode & 0x3f;
11688     switch (op1) {
11689     case OPC_ADD_S:
11690         {
11691             TCGv_i32 fp0 = tcg_temp_new_i32();
11692             TCGv_i32 fp1 = tcg_temp_new_i32();
11693 
11694             gen_load_fpr32(ctx, fp0, fs);
11695             gen_load_fpr32(ctx, fp1, ft);
11696             gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
11697             tcg_temp_free_i32(fp1);
11698             gen_store_fpr32(ctx, fp0, fd);
11699             tcg_temp_free_i32(fp0);
11700         }
11701         break;
11702     case OPC_SUB_S:
11703         {
11704             TCGv_i32 fp0 = tcg_temp_new_i32();
11705             TCGv_i32 fp1 = tcg_temp_new_i32();
11706 
11707             gen_load_fpr32(ctx, fp0, fs);
11708             gen_load_fpr32(ctx, fp1, ft);
11709             gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
11710             tcg_temp_free_i32(fp1);
11711             gen_store_fpr32(ctx, fp0, fd);
11712             tcg_temp_free_i32(fp0);
11713         }
11714         break;
11715     case OPC_MUL_S:
11716         {
11717             TCGv_i32 fp0 = tcg_temp_new_i32();
11718             TCGv_i32 fp1 = tcg_temp_new_i32();
11719 
11720             gen_load_fpr32(ctx, fp0, fs);
11721             gen_load_fpr32(ctx, fp1, ft);
11722             gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
11723             tcg_temp_free_i32(fp1);
11724             gen_store_fpr32(ctx, fp0, fd);
11725             tcg_temp_free_i32(fp0);
11726         }
11727         break;
11728     case OPC_DIV_S:
11729         {
11730             TCGv_i32 fp0 = tcg_temp_new_i32();
11731             TCGv_i32 fp1 = tcg_temp_new_i32();
11732 
11733             gen_load_fpr32(ctx, fp0, fs);
11734             gen_load_fpr32(ctx, fp1, ft);
11735             gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
11736             tcg_temp_free_i32(fp1);
11737             gen_store_fpr32(ctx, fp0, fd);
11738             tcg_temp_free_i32(fp0);
11739         }
11740         break;
11741     case OPC_SQRT_S:
11742         {
11743             TCGv_i32 fp0 = tcg_temp_new_i32();
11744 
11745             gen_load_fpr32(ctx, fp0, fs);
11746             gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
11747             gen_store_fpr32(ctx, fp0, fd);
11748             tcg_temp_free_i32(fp0);
11749         }
11750         break;
11751     case OPC_ABS_S:
11752         {
11753             TCGv_i32 fp0 = tcg_temp_new_i32();
11754 
11755             gen_load_fpr32(ctx, fp0, fs);
11756             if (ctx->abs2008) {
11757                 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
11758             } else {
11759                 gen_helper_float_abs_s(fp0, fp0);
11760             }
11761             gen_store_fpr32(ctx, fp0, fd);
11762             tcg_temp_free_i32(fp0);
11763         }
11764         break;
11765     case OPC_MOV_S:
11766         {
11767             TCGv_i32 fp0 = tcg_temp_new_i32();
11768 
11769             gen_load_fpr32(ctx, fp0, fs);
11770             gen_store_fpr32(ctx, fp0, fd);
11771             tcg_temp_free_i32(fp0);
11772         }
11773         break;
11774     case OPC_NEG_S:
11775         {
11776             TCGv_i32 fp0 = tcg_temp_new_i32();
11777 
11778             gen_load_fpr32(ctx, fp0, fs);
11779             if (ctx->abs2008) {
11780                 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
11781             } else {
11782                 gen_helper_float_chs_s(fp0, fp0);
11783             }
11784             gen_store_fpr32(ctx, fp0, fd);
11785             tcg_temp_free_i32(fp0);
11786         }
11787         break;
11788     case OPC_ROUND_L_S:
11789         check_cp1_64bitmode(ctx);
11790         {
11791             TCGv_i32 fp32 = tcg_temp_new_i32();
11792             TCGv_i64 fp64 = tcg_temp_new_i64();
11793 
11794             gen_load_fpr32(ctx, fp32, fs);
11795             if (ctx->nan2008) {
11796                 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
11797             } else {
11798                 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
11799             }
11800             tcg_temp_free_i32(fp32);
11801             gen_store_fpr64(ctx, fp64, fd);
11802             tcg_temp_free_i64(fp64);
11803         }
11804         break;
11805     case OPC_TRUNC_L_S:
11806         check_cp1_64bitmode(ctx);
11807         {
11808             TCGv_i32 fp32 = tcg_temp_new_i32();
11809             TCGv_i64 fp64 = tcg_temp_new_i64();
11810 
11811             gen_load_fpr32(ctx, fp32, fs);
11812             if (ctx->nan2008) {
11813                 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
11814             } else {
11815                 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
11816             }
11817             tcg_temp_free_i32(fp32);
11818             gen_store_fpr64(ctx, fp64, fd);
11819             tcg_temp_free_i64(fp64);
11820         }
11821         break;
11822     case OPC_CEIL_L_S:
11823         check_cp1_64bitmode(ctx);
11824         {
11825             TCGv_i32 fp32 = tcg_temp_new_i32();
11826             TCGv_i64 fp64 = tcg_temp_new_i64();
11827 
11828             gen_load_fpr32(ctx, fp32, fs);
11829             if (ctx->nan2008) {
11830                 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
11831             } else {
11832                 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
11833             }
11834             tcg_temp_free_i32(fp32);
11835             gen_store_fpr64(ctx, fp64, fd);
11836             tcg_temp_free_i64(fp64);
11837         }
11838         break;
11839     case OPC_FLOOR_L_S:
11840         check_cp1_64bitmode(ctx);
11841         {
11842             TCGv_i32 fp32 = tcg_temp_new_i32();
11843             TCGv_i64 fp64 = tcg_temp_new_i64();
11844 
11845             gen_load_fpr32(ctx, fp32, fs);
11846             if (ctx->nan2008) {
11847                 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
11848             } else {
11849                 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
11850             }
11851             tcg_temp_free_i32(fp32);
11852             gen_store_fpr64(ctx, fp64, fd);
11853             tcg_temp_free_i64(fp64);
11854         }
11855         break;
11856     case OPC_ROUND_W_S:
11857         {
11858             TCGv_i32 fp0 = tcg_temp_new_i32();
11859 
11860             gen_load_fpr32(ctx, fp0, fs);
11861             if (ctx->nan2008) {
11862                 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
11863             } else {
11864                 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
11865             }
11866             gen_store_fpr32(ctx, fp0, fd);
11867             tcg_temp_free_i32(fp0);
11868         }
11869         break;
11870     case OPC_TRUNC_W_S:
11871         {
11872             TCGv_i32 fp0 = tcg_temp_new_i32();
11873 
11874             gen_load_fpr32(ctx, fp0, fs);
11875             if (ctx->nan2008) {
11876                 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
11877             } else {
11878                 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
11879             }
11880             gen_store_fpr32(ctx, fp0, fd);
11881             tcg_temp_free_i32(fp0);
11882         }
11883         break;
11884     case OPC_CEIL_W_S:
11885         {
11886             TCGv_i32 fp0 = tcg_temp_new_i32();
11887 
11888             gen_load_fpr32(ctx, fp0, fs);
11889             if (ctx->nan2008) {
11890                 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
11891             } else {
11892                 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
11893             }
11894             gen_store_fpr32(ctx, fp0, fd);
11895             tcg_temp_free_i32(fp0);
11896         }
11897         break;
11898     case OPC_FLOOR_W_S:
11899         {
11900             TCGv_i32 fp0 = tcg_temp_new_i32();
11901 
11902             gen_load_fpr32(ctx, fp0, fs);
11903             if (ctx->nan2008) {
11904                 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
11905             } else {
11906                 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
11907             }
11908             gen_store_fpr32(ctx, fp0, fd);
11909             tcg_temp_free_i32(fp0);
11910         }
11911         break;
11912     case OPC_SEL_S:
11913         check_insn(ctx, ISA_MIPS32R6);
11914         gen_sel_s(ctx, op1, fd, ft, fs);
11915         break;
11916     case OPC_SELEQZ_S:
11917         check_insn(ctx, ISA_MIPS32R6);
11918         gen_sel_s(ctx, op1, fd, ft, fs);
11919         break;
11920     case OPC_SELNEZ_S:
11921         check_insn(ctx, ISA_MIPS32R6);
11922         gen_sel_s(ctx, op1, fd, ft, fs);
11923         break;
11924     case OPC_MOVCF_S:
11925         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11926         gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11927         break;
11928     case OPC_MOVZ_S:
11929         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11930         {
11931             TCGLabel *l1 = gen_new_label();
11932             TCGv_i32 fp0;
11933 
11934             if (ft != 0) {
11935                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11936             }
11937             fp0 = tcg_temp_new_i32();
11938             gen_load_fpr32(ctx, fp0, fs);
11939             gen_store_fpr32(ctx, fp0, fd);
11940             tcg_temp_free_i32(fp0);
11941             gen_set_label(l1);
11942         }
11943         break;
11944     case OPC_MOVN_S:
11945         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11946         {
11947             TCGLabel *l1 = gen_new_label();
11948             TCGv_i32 fp0;
11949 
11950             if (ft != 0) {
11951                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11952                 fp0 = tcg_temp_new_i32();
11953                 gen_load_fpr32(ctx, fp0, fs);
11954                 gen_store_fpr32(ctx, fp0, fd);
11955                 tcg_temp_free_i32(fp0);
11956                 gen_set_label(l1);
11957             }
11958         }
11959         break;
11960     case OPC_RECIP_S:
11961         {
11962             TCGv_i32 fp0 = tcg_temp_new_i32();
11963 
11964             gen_load_fpr32(ctx, fp0, fs);
11965             gen_helper_float_recip_s(fp0, cpu_env, fp0);
11966             gen_store_fpr32(ctx, fp0, fd);
11967             tcg_temp_free_i32(fp0);
11968         }
11969         break;
11970     case OPC_RSQRT_S:
11971         {
11972             TCGv_i32 fp0 = tcg_temp_new_i32();
11973 
11974             gen_load_fpr32(ctx, fp0, fs);
11975             gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
11976             gen_store_fpr32(ctx, fp0, fd);
11977             tcg_temp_free_i32(fp0);
11978         }
11979         break;
11980     case OPC_MADDF_S:
11981         check_insn(ctx, ISA_MIPS32R6);
11982         {
11983             TCGv_i32 fp0 = tcg_temp_new_i32();
11984             TCGv_i32 fp1 = tcg_temp_new_i32();
11985             TCGv_i32 fp2 = tcg_temp_new_i32();
11986             gen_load_fpr32(ctx, fp0, fs);
11987             gen_load_fpr32(ctx, fp1, ft);
11988             gen_load_fpr32(ctx, fp2, fd);
11989             gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
11990             gen_store_fpr32(ctx, fp2, fd);
11991             tcg_temp_free_i32(fp2);
11992             tcg_temp_free_i32(fp1);
11993             tcg_temp_free_i32(fp0);
11994         }
11995         break;
11996     case OPC_MSUBF_S:
11997         check_insn(ctx, ISA_MIPS32R6);
11998         {
11999             TCGv_i32 fp0 = tcg_temp_new_i32();
12000             TCGv_i32 fp1 = tcg_temp_new_i32();
12001             TCGv_i32 fp2 = tcg_temp_new_i32();
12002             gen_load_fpr32(ctx, fp0, fs);
12003             gen_load_fpr32(ctx, fp1, ft);
12004             gen_load_fpr32(ctx, fp2, fd);
12005             gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
12006             gen_store_fpr32(ctx, fp2, fd);
12007             tcg_temp_free_i32(fp2);
12008             tcg_temp_free_i32(fp1);
12009             tcg_temp_free_i32(fp0);
12010         }
12011         break;
12012     case OPC_RINT_S:
12013         check_insn(ctx, ISA_MIPS32R6);
12014         {
12015             TCGv_i32 fp0 = tcg_temp_new_i32();
12016             gen_load_fpr32(ctx, fp0, fs);
12017             gen_helper_float_rint_s(fp0, cpu_env, fp0);
12018             gen_store_fpr32(ctx, fp0, fd);
12019             tcg_temp_free_i32(fp0);
12020         }
12021         break;
12022     case OPC_CLASS_S:
12023         check_insn(ctx, ISA_MIPS32R6);
12024         {
12025             TCGv_i32 fp0 = tcg_temp_new_i32();
12026             gen_load_fpr32(ctx, fp0, fs);
12027             gen_helper_float_class_s(fp0, cpu_env, fp0);
12028             gen_store_fpr32(ctx, fp0, fd);
12029             tcg_temp_free_i32(fp0);
12030         }
12031         break;
12032     case OPC_MIN_S: /* OPC_RECIP2_S */
12033         if (ctx->insn_flags & ISA_MIPS32R6) {
12034             /* OPC_MIN_S */
12035             TCGv_i32 fp0 = tcg_temp_new_i32();
12036             TCGv_i32 fp1 = tcg_temp_new_i32();
12037             TCGv_i32 fp2 = tcg_temp_new_i32();
12038             gen_load_fpr32(ctx, fp0, fs);
12039             gen_load_fpr32(ctx, fp1, ft);
12040             gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
12041             gen_store_fpr32(ctx, fp2, fd);
12042             tcg_temp_free_i32(fp2);
12043             tcg_temp_free_i32(fp1);
12044             tcg_temp_free_i32(fp0);
12045         } else {
12046             /* OPC_RECIP2_S */
12047             check_cp1_64bitmode(ctx);
12048             {
12049                 TCGv_i32 fp0 = tcg_temp_new_i32();
12050                 TCGv_i32 fp1 = tcg_temp_new_i32();
12051 
12052                 gen_load_fpr32(ctx, fp0, fs);
12053                 gen_load_fpr32(ctx, fp1, ft);
12054                 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
12055                 tcg_temp_free_i32(fp1);
12056                 gen_store_fpr32(ctx, fp0, fd);
12057                 tcg_temp_free_i32(fp0);
12058             }
12059         }
12060         break;
12061     case OPC_MINA_S: /* OPC_RECIP1_S */
12062         if (ctx->insn_flags & ISA_MIPS32R6) {
12063             /* OPC_MINA_S */
12064             TCGv_i32 fp0 = tcg_temp_new_i32();
12065             TCGv_i32 fp1 = tcg_temp_new_i32();
12066             TCGv_i32 fp2 = tcg_temp_new_i32();
12067             gen_load_fpr32(ctx, fp0, fs);
12068             gen_load_fpr32(ctx, fp1, ft);
12069             gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
12070             gen_store_fpr32(ctx, fp2, fd);
12071             tcg_temp_free_i32(fp2);
12072             tcg_temp_free_i32(fp1);
12073             tcg_temp_free_i32(fp0);
12074         } else {
12075             /* OPC_RECIP1_S */
12076             check_cp1_64bitmode(ctx);
12077             {
12078                 TCGv_i32 fp0 = tcg_temp_new_i32();
12079 
12080                 gen_load_fpr32(ctx, fp0, fs);
12081                 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
12082                 gen_store_fpr32(ctx, fp0, fd);
12083                 tcg_temp_free_i32(fp0);
12084             }
12085         }
12086         break;
12087     case OPC_MAX_S: /* OPC_RSQRT1_S */
12088         if (ctx->insn_flags & ISA_MIPS32R6) {
12089             /* OPC_MAX_S */
12090             TCGv_i32 fp0 = tcg_temp_new_i32();
12091             TCGv_i32 fp1 = tcg_temp_new_i32();
12092             gen_load_fpr32(ctx, fp0, fs);
12093             gen_load_fpr32(ctx, fp1, ft);
12094             gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
12095             gen_store_fpr32(ctx, fp1, fd);
12096             tcg_temp_free_i32(fp1);
12097             tcg_temp_free_i32(fp0);
12098         } else {
12099             /* OPC_RSQRT1_S */
12100             check_cp1_64bitmode(ctx);
12101             {
12102                 TCGv_i32 fp0 = tcg_temp_new_i32();
12103 
12104                 gen_load_fpr32(ctx, fp0, fs);
12105                 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
12106                 gen_store_fpr32(ctx, fp0, fd);
12107                 tcg_temp_free_i32(fp0);
12108             }
12109         }
12110         break;
12111     case OPC_MAXA_S: /* OPC_RSQRT2_S */
12112         if (ctx->insn_flags & ISA_MIPS32R6) {
12113             /* OPC_MAXA_S */
12114             TCGv_i32 fp0 = tcg_temp_new_i32();
12115             TCGv_i32 fp1 = tcg_temp_new_i32();
12116             gen_load_fpr32(ctx, fp0, fs);
12117             gen_load_fpr32(ctx, fp1, ft);
12118             gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
12119             gen_store_fpr32(ctx, fp1, fd);
12120             tcg_temp_free_i32(fp1);
12121             tcg_temp_free_i32(fp0);
12122         } else {
12123             /* OPC_RSQRT2_S */
12124             check_cp1_64bitmode(ctx);
12125             {
12126                 TCGv_i32 fp0 = tcg_temp_new_i32();
12127                 TCGv_i32 fp1 = tcg_temp_new_i32();
12128 
12129                 gen_load_fpr32(ctx, fp0, fs);
12130                 gen_load_fpr32(ctx, fp1, ft);
12131                 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
12132                 tcg_temp_free_i32(fp1);
12133                 gen_store_fpr32(ctx, fp0, fd);
12134                 tcg_temp_free_i32(fp0);
12135             }
12136         }
12137         break;
12138     case OPC_CVT_D_S:
12139         check_cp1_registers(ctx, fd);
12140         {
12141             TCGv_i32 fp32 = tcg_temp_new_i32();
12142             TCGv_i64 fp64 = tcg_temp_new_i64();
12143 
12144             gen_load_fpr32(ctx, fp32, fs);
12145             gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
12146             tcg_temp_free_i32(fp32);
12147             gen_store_fpr64(ctx, fp64, fd);
12148             tcg_temp_free_i64(fp64);
12149         }
12150         break;
12151     case OPC_CVT_W_S:
12152         {
12153             TCGv_i32 fp0 = tcg_temp_new_i32();
12154 
12155             gen_load_fpr32(ctx, fp0, fs);
12156             if (ctx->nan2008) {
12157                 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
12158             } else {
12159                 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
12160             }
12161             gen_store_fpr32(ctx, fp0, fd);
12162             tcg_temp_free_i32(fp0);
12163         }
12164         break;
12165     case OPC_CVT_L_S:
12166         check_cp1_64bitmode(ctx);
12167         {
12168             TCGv_i32 fp32 = tcg_temp_new_i32();
12169             TCGv_i64 fp64 = tcg_temp_new_i64();
12170 
12171             gen_load_fpr32(ctx, fp32, fs);
12172             if (ctx->nan2008) {
12173                 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
12174             } else {
12175                 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
12176             }
12177             tcg_temp_free_i32(fp32);
12178             gen_store_fpr64(ctx, fp64, fd);
12179             tcg_temp_free_i64(fp64);
12180         }
12181         break;
12182     case OPC_CVT_PS_S:
12183         check_ps(ctx);
12184         {
12185             TCGv_i64 fp64 = tcg_temp_new_i64();
12186             TCGv_i32 fp32_0 = tcg_temp_new_i32();
12187             TCGv_i32 fp32_1 = tcg_temp_new_i32();
12188 
12189             gen_load_fpr32(ctx, fp32_0, fs);
12190             gen_load_fpr32(ctx, fp32_1, ft);
12191             tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
12192             tcg_temp_free_i32(fp32_1);
12193             tcg_temp_free_i32(fp32_0);
12194             gen_store_fpr64(ctx, fp64, fd);
12195             tcg_temp_free_i64(fp64);
12196         }
12197         break;
12198     case OPC_CMP_F_S:
12199     case OPC_CMP_UN_S:
12200     case OPC_CMP_EQ_S:
12201     case OPC_CMP_UEQ_S:
12202     case OPC_CMP_OLT_S:
12203     case OPC_CMP_ULT_S:
12204     case OPC_CMP_OLE_S:
12205     case OPC_CMP_ULE_S:
12206     case OPC_CMP_SF_S:
12207     case OPC_CMP_NGLE_S:
12208     case OPC_CMP_SEQ_S:
12209     case OPC_CMP_NGL_S:
12210     case OPC_CMP_LT_S:
12211     case OPC_CMP_NGE_S:
12212     case OPC_CMP_LE_S:
12213     case OPC_CMP_NGT_S:
12214         check_insn_opc_removed(ctx, ISA_MIPS32R6);
12215         if (ctx->opcode & (1 << 6)) {
12216             gen_cmpabs_s(ctx, func - 48, ft, fs, cc);
12217         } else {
12218             gen_cmp_s(ctx, func - 48, ft, fs, cc);
12219         }
12220         break;
12221     case OPC_ADD_D:
12222         check_cp1_registers(ctx, fs | ft | fd);
12223         {
12224             TCGv_i64 fp0 = tcg_temp_new_i64();
12225             TCGv_i64 fp1 = tcg_temp_new_i64();
12226 
12227             gen_load_fpr64(ctx, fp0, fs);
12228             gen_load_fpr64(ctx, fp1, ft);
12229             gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
12230             tcg_temp_free_i64(fp1);
12231             gen_store_fpr64(ctx, fp0, fd);
12232             tcg_temp_free_i64(fp0);
12233         }
12234         break;
12235     case OPC_SUB_D:
12236         check_cp1_registers(ctx, fs | ft | fd);
12237         {
12238             TCGv_i64 fp0 = tcg_temp_new_i64();
12239             TCGv_i64 fp1 = tcg_temp_new_i64();
12240 
12241             gen_load_fpr64(ctx, fp0, fs);
12242             gen_load_fpr64(ctx, fp1, ft);
12243             gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
12244             tcg_temp_free_i64(fp1);
12245             gen_store_fpr64(ctx, fp0, fd);
12246             tcg_temp_free_i64(fp0);
12247         }
12248         break;
12249     case OPC_MUL_D:
12250         check_cp1_registers(ctx, fs | ft | fd);
12251         {
12252             TCGv_i64 fp0 = tcg_temp_new_i64();
12253             TCGv_i64 fp1 = tcg_temp_new_i64();
12254 
12255             gen_load_fpr64(ctx, fp0, fs);
12256             gen_load_fpr64(ctx, fp1, ft);
12257             gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
12258             tcg_temp_free_i64(fp1);
12259             gen_store_fpr64(ctx, fp0, fd);
12260             tcg_temp_free_i64(fp0);
12261         }
12262         break;
12263     case OPC_DIV_D:
12264         check_cp1_registers(ctx, fs | ft | fd);
12265         {
12266             TCGv_i64 fp0 = tcg_temp_new_i64();
12267             TCGv_i64 fp1 = tcg_temp_new_i64();
12268 
12269             gen_load_fpr64(ctx, fp0, fs);
12270             gen_load_fpr64(ctx, fp1, ft);
12271             gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
12272             tcg_temp_free_i64(fp1);
12273             gen_store_fpr64(ctx, fp0, fd);
12274             tcg_temp_free_i64(fp0);
12275         }
12276         break;
12277     case OPC_SQRT_D:
12278         check_cp1_registers(ctx, fs | fd);
12279         {
12280             TCGv_i64 fp0 = tcg_temp_new_i64();
12281 
12282             gen_load_fpr64(ctx, fp0, fs);
12283             gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
12284             gen_store_fpr64(ctx, fp0, fd);
12285             tcg_temp_free_i64(fp0);
12286         }
12287         break;
12288     case OPC_ABS_D:
12289         check_cp1_registers(ctx, fs | fd);
12290         {
12291             TCGv_i64 fp0 = tcg_temp_new_i64();
12292 
12293             gen_load_fpr64(ctx, fp0, fs);
12294             if (ctx->abs2008) {
12295                 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
12296             } else {
12297                 gen_helper_float_abs_d(fp0, fp0);
12298             }
12299             gen_store_fpr64(ctx, fp0, fd);
12300             tcg_temp_free_i64(fp0);
12301         }
12302         break;
12303     case OPC_MOV_D:
12304         check_cp1_registers(ctx, fs | fd);
12305         {
12306             TCGv_i64 fp0 = tcg_temp_new_i64();
12307 
12308             gen_load_fpr64(ctx, fp0, fs);
12309             gen_store_fpr64(ctx, fp0, fd);
12310             tcg_temp_free_i64(fp0);
12311         }
12312         break;
12313     case OPC_NEG_D:
12314         check_cp1_registers(ctx, fs | fd);
12315         {
12316             TCGv_i64 fp0 = tcg_temp_new_i64();
12317 
12318             gen_load_fpr64(ctx, fp0, fs);
12319             if (ctx->abs2008) {
12320                 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
12321             } else {
12322                 gen_helper_float_chs_d(fp0, fp0);
12323             }
12324             gen_store_fpr64(ctx, fp0, fd);
12325             tcg_temp_free_i64(fp0);
12326         }
12327         break;
12328     case OPC_ROUND_L_D:
12329         check_cp1_64bitmode(ctx);
12330         {
12331             TCGv_i64 fp0 = tcg_temp_new_i64();
12332 
12333             gen_load_fpr64(ctx, fp0, fs);
12334             if (ctx->nan2008) {
12335                 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
12336             } else {
12337                 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
12338             }
12339             gen_store_fpr64(ctx, fp0, fd);
12340             tcg_temp_free_i64(fp0);
12341         }
12342         break;
12343     case OPC_TRUNC_L_D:
12344         check_cp1_64bitmode(ctx);
12345         {
12346             TCGv_i64 fp0 = tcg_temp_new_i64();
12347 
12348             gen_load_fpr64(ctx, fp0, fs);
12349             if (ctx->nan2008) {
12350                 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
12351             } else {
12352                 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
12353             }
12354             gen_store_fpr64(ctx, fp0, fd);
12355             tcg_temp_free_i64(fp0);
12356         }
12357         break;
12358     case OPC_CEIL_L_D:
12359         check_cp1_64bitmode(ctx);
12360         {
12361             TCGv_i64 fp0 = tcg_temp_new_i64();
12362 
12363             gen_load_fpr64(ctx, fp0, fs);
12364             if (ctx->nan2008) {
12365                 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
12366             } else {
12367                 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
12368             }
12369             gen_store_fpr64(ctx, fp0, fd);
12370             tcg_temp_free_i64(fp0);
12371         }
12372         break;
12373     case OPC_FLOOR_L_D:
12374         check_cp1_64bitmode(ctx);
12375         {
12376             TCGv_i64 fp0 = tcg_temp_new_i64();
12377 
12378             gen_load_fpr64(ctx, fp0, fs);
12379             if (ctx->nan2008) {
12380                 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
12381             } else {
12382                 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
12383             }
12384             gen_store_fpr64(ctx, fp0, fd);
12385             tcg_temp_free_i64(fp0);
12386         }
12387         break;
12388     case OPC_ROUND_W_D:
12389         check_cp1_registers(ctx, fs);
12390         {
12391             TCGv_i32 fp32 = tcg_temp_new_i32();
12392             TCGv_i64 fp64 = tcg_temp_new_i64();
12393 
12394             gen_load_fpr64(ctx, fp64, fs);
12395             if (ctx->nan2008) {
12396                 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
12397             } else {
12398                 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
12399             }
12400             tcg_temp_free_i64(fp64);
12401             gen_store_fpr32(ctx, fp32, fd);
12402             tcg_temp_free_i32(fp32);
12403         }
12404         break;
12405     case OPC_TRUNC_W_D:
12406         check_cp1_registers(ctx, fs);
12407         {
12408             TCGv_i32 fp32 = tcg_temp_new_i32();
12409             TCGv_i64 fp64 = tcg_temp_new_i64();
12410 
12411             gen_load_fpr64(ctx, fp64, fs);
12412             if (ctx->nan2008) {
12413                 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
12414             } else {
12415                 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
12416             }
12417             tcg_temp_free_i64(fp64);
12418             gen_store_fpr32(ctx, fp32, fd);
12419             tcg_temp_free_i32(fp32);
12420         }
12421         break;
12422     case OPC_CEIL_W_D:
12423         check_cp1_registers(ctx, fs);
12424         {
12425             TCGv_i32 fp32 = tcg_temp_new_i32();
12426             TCGv_i64 fp64 = tcg_temp_new_i64();
12427 
12428             gen_load_fpr64(ctx, fp64, fs);
12429             if (ctx->nan2008) {
12430                 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
12431             } else {
12432                 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
12433             }
12434             tcg_temp_free_i64(fp64);
12435             gen_store_fpr32(ctx, fp32, fd);
12436             tcg_temp_free_i32(fp32);
12437         }
12438         break;
12439     case OPC_FLOOR_W_D:
12440         check_cp1_registers(ctx, fs);
12441         {
12442             TCGv_i32 fp32 = tcg_temp_new_i32();
12443             TCGv_i64 fp64 = tcg_temp_new_i64();
12444 
12445             gen_load_fpr64(ctx, fp64, fs);
12446             if (ctx->nan2008) {
12447                 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
12448             } else {
12449                 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
12450             }
12451             tcg_temp_free_i64(fp64);
12452             gen_store_fpr32(ctx, fp32, fd);
12453             tcg_temp_free_i32(fp32);
12454         }
12455         break;
12456     case OPC_SEL_D:
12457         check_insn(ctx, ISA_MIPS32R6);
12458         gen_sel_d(ctx, op1, fd, ft, fs);
12459         break;
12460     case OPC_SELEQZ_D:
12461         check_insn(ctx, ISA_MIPS32R6);
12462         gen_sel_d(ctx, op1, fd, ft, fs);
12463         break;
12464     case OPC_SELNEZ_D:
12465         check_insn(ctx, ISA_MIPS32R6);
12466         gen_sel_d(ctx, op1, fd, ft, fs);
12467         break;
12468     case OPC_MOVCF_D:
12469         check_insn_opc_removed(ctx, ISA_MIPS32R6);
12470         gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
12471         break;
12472     case OPC_MOVZ_D:
12473         check_insn_opc_removed(ctx, ISA_MIPS32R6);
12474         {
12475             TCGLabel *l1 = gen_new_label();
12476             TCGv_i64 fp0;
12477 
12478             if (ft != 0) {
12479                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
12480             }
12481             fp0 = tcg_temp_new_i64();
12482             gen_load_fpr64(ctx, fp0, fs);
12483             gen_store_fpr64(ctx, fp0, fd);
12484             tcg_temp_free_i64(fp0);
12485             gen_set_label(l1);
12486         }
12487         break;
12488     case OPC_MOVN_D:
12489         check_insn_opc_removed(ctx, ISA_MIPS32R6);
12490         {
12491             TCGLabel *l1 = gen_new_label();
12492             TCGv_i64 fp0;
12493 
12494             if (ft != 0) {
12495                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
12496                 fp0 = tcg_temp_new_i64();
12497                 gen_load_fpr64(ctx, fp0, fs);
12498                 gen_store_fpr64(ctx, fp0, fd);
12499                 tcg_temp_free_i64(fp0);
12500                 gen_set_label(l1);
12501             }
12502         }
12503         break;
12504     case OPC_RECIP_D:
12505         check_cp1_registers(ctx, fs | fd);
12506         {
12507             TCGv_i64 fp0 = tcg_temp_new_i64();
12508 
12509             gen_load_fpr64(ctx, fp0, fs);
12510             gen_helper_float_recip_d(fp0, cpu_env, fp0);
12511             gen_store_fpr64(ctx, fp0, fd);
12512             tcg_temp_free_i64(fp0);
12513         }
12514         break;
12515     case OPC_RSQRT_D:
12516         check_cp1_registers(ctx, fs | fd);
12517         {
12518             TCGv_i64 fp0 = tcg_temp_new_i64();
12519 
12520             gen_load_fpr64(ctx, fp0, fs);
12521             gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
12522             gen_store_fpr64(ctx, fp0, fd);
12523             tcg_temp_free_i64(fp0);
12524         }
12525         break;
12526     case OPC_MADDF_D:
12527         check_insn(ctx, ISA_MIPS32R6);
12528         {
12529             TCGv_i64 fp0 = tcg_temp_new_i64();
12530             TCGv_i64 fp1 = tcg_temp_new_i64();
12531             TCGv_i64 fp2 = tcg_temp_new_i64();
12532             gen_load_fpr64(ctx, fp0, fs);
12533             gen_load_fpr64(ctx, fp1, ft);
12534             gen_load_fpr64(ctx, fp2, fd);
12535             gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
12536             gen_store_fpr64(ctx, fp2, fd);
12537             tcg_temp_free_i64(fp2);
12538             tcg_temp_free_i64(fp1);
12539             tcg_temp_free_i64(fp0);
12540         }
12541         break;
12542     case OPC_MSUBF_D:
12543         check_insn(ctx, ISA_MIPS32R6);
12544         {
12545             TCGv_i64 fp0 = tcg_temp_new_i64();
12546             TCGv_i64 fp1 = tcg_temp_new_i64();
12547             TCGv_i64 fp2 = tcg_temp_new_i64();
12548             gen_load_fpr64(ctx, fp0, fs);
12549             gen_load_fpr64(ctx, fp1, ft);
12550             gen_load_fpr64(ctx, fp2, fd);
12551             gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
12552             gen_store_fpr64(ctx, fp2, fd);
12553             tcg_temp_free_i64(fp2);
12554             tcg_temp_free_i64(fp1);
12555             tcg_temp_free_i64(fp0);
12556         }
12557         break;
12558     case OPC_RINT_D:
12559         check_insn(ctx, ISA_MIPS32R6);
12560         {
12561             TCGv_i64 fp0 = tcg_temp_new_i64();
12562             gen_load_fpr64(ctx, fp0, fs);
12563             gen_helper_float_rint_d(fp0, cpu_env, fp0);
12564             gen_store_fpr64(ctx, fp0, fd);
12565             tcg_temp_free_i64(fp0);
12566         }
12567         break;
12568     case OPC_CLASS_D:
12569         check_insn(ctx, ISA_MIPS32R6);
12570         {
12571             TCGv_i64 fp0 = tcg_temp_new_i64();
12572             gen_load_fpr64(ctx, fp0, fs);
12573             gen_helper_float_class_d(fp0, cpu_env, fp0);
12574             gen_store_fpr64(ctx, fp0, fd);
12575             tcg_temp_free_i64(fp0);
12576         }
12577         break;
12578     case OPC_MIN_D: /* OPC_RECIP2_D */
12579         if (ctx->insn_flags & ISA_MIPS32R6) {
12580             /* OPC_MIN_D */
12581             TCGv_i64 fp0 = tcg_temp_new_i64();
12582             TCGv_i64 fp1 = tcg_temp_new_i64();
12583             gen_load_fpr64(ctx, fp0, fs);
12584             gen_load_fpr64(ctx, fp1, ft);
12585             gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
12586             gen_store_fpr64(ctx, fp1, fd);
12587             tcg_temp_free_i64(fp1);
12588             tcg_temp_free_i64(fp0);
12589         } else {
12590             /* OPC_RECIP2_D */
12591             check_cp1_64bitmode(ctx);
12592             {
12593                 TCGv_i64 fp0 = tcg_temp_new_i64();
12594                 TCGv_i64 fp1 = tcg_temp_new_i64();
12595 
12596                 gen_load_fpr64(ctx, fp0, fs);
12597                 gen_load_fpr64(ctx, fp1, ft);
12598                 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
12599                 tcg_temp_free_i64(fp1);
12600                 gen_store_fpr64(ctx, fp0, fd);
12601                 tcg_temp_free_i64(fp0);
12602             }
12603         }
12604         break;
12605     case OPC_MINA_D: /* OPC_RECIP1_D */
12606         if (ctx->insn_flags & ISA_MIPS32R6) {
12607             /* OPC_MINA_D */
12608             TCGv_i64 fp0 = tcg_temp_new_i64();
12609             TCGv_i64 fp1 = tcg_temp_new_i64();
12610             gen_load_fpr64(ctx, fp0, fs);
12611             gen_load_fpr64(ctx, fp1, ft);
12612             gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
12613             gen_store_fpr64(ctx, fp1, fd);
12614             tcg_temp_free_i64(fp1);
12615             tcg_temp_free_i64(fp0);
12616         } else {
12617             /* OPC_RECIP1_D */
12618             check_cp1_64bitmode(ctx);
12619             {
12620                 TCGv_i64 fp0 = tcg_temp_new_i64();
12621 
12622                 gen_load_fpr64(ctx, fp0, fs);
12623                 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
12624                 gen_store_fpr64(ctx, fp0, fd);
12625                 tcg_temp_free_i64(fp0);
12626             }
12627         }
12628         break;
12629     case OPC_MAX_D: /*  OPC_RSQRT1_D */
12630         if (ctx->insn_flags & ISA_MIPS32R6) {
12631             /* OPC_MAX_D */
12632             TCGv_i64 fp0 = tcg_temp_new_i64();
12633             TCGv_i64 fp1 = tcg_temp_new_i64();
12634             gen_load_fpr64(ctx, fp0, fs);
12635             gen_load_fpr64(ctx, fp1, ft);
12636             gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
12637             gen_store_fpr64(ctx, fp1, fd);
12638             tcg_temp_free_i64(fp1);
12639             tcg_temp_free_i64(fp0);
12640         } else {
12641             /* OPC_RSQRT1_D */
12642             check_cp1_64bitmode(ctx);
12643             {
12644                 TCGv_i64 fp0 = tcg_temp_new_i64();
12645 
12646                 gen_load_fpr64(ctx, fp0, fs);
12647                 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
12648                 gen_store_fpr64(ctx, fp0, fd);
12649                 tcg_temp_free_i64(fp0);
12650             }
12651         }
12652         break;
12653     case OPC_MAXA_D: /* OPC_RSQRT2_D */
12654         if (ctx->insn_flags & ISA_MIPS32R6) {
12655             /* OPC_MAXA_D */
12656             TCGv_i64 fp0 = tcg_temp_new_i64();
12657             TCGv_i64 fp1 = tcg_temp_new_i64();
12658             gen_load_fpr64(ctx, fp0, fs);
12659             gen_load_fpr64(ctx, fp1, ft);
12660             gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
12661             gen_store_fpr64(ctx, fp1, fd);
12662             tcg_temp_free_i64(fp1);
12663             tcg_temp_free_i64(fp0);
12664         } else {
12665             /* OPC_RSQRT2_D */
12666             check_cp1_64bitmode(ctx);
12667             {
12668                 TCGv_i64 fp0 = tcg_temp_new_i64();
12669                 TCGv_i64 fp1 = tcg_temp_new_i64();
12670 
12671                 gen_load_fpr64(ctx, fp0, fs);
12672                 gen_load_fpr64(ctx, fp1, ft);
12673                 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
12674                 tcg_temp_free_i64(fp1);
12675                 gen_store_fpr64(ctx, fp0, fd);
12676                 tcg_temp_free_i64(fp0);
12677             }
12678         }
12679         break;
12680     case OPC_CMP_F_D:
12681     case OPC_CMP_UN_D:
12682     case OPC_CMP_EQ_D:
12683     case OPC_CMP_UEQ_D:
12684     case OPC_CMP_OLT_D:
12685     case OPC_CMP_ULT_D:
12686     case OPC_CMP_OLE_D:
12687     case OPC_CMP_ULE_D:
12688     case OPC_CMP_SF_D:
12689     case OPC_CMP_NGLE_D:
12690     case OPC_CMP_SEQ_D:
12691     case OPC_CMP_NGL_D:
12692     case OPC_CMP_LT_D:
12693     case OPC_CMP_NGE_D:
12694     case OPC_CMP_LE_D:
12695     case OPC_CMP_NGT_D:
12696         check_insn_opc_removed(ctx, ISA_MIPS32R6);
12697         if (ctx->opcode & (1 << 6)) {
12698             gen_cmpabs_d(ctx, func - 48, ft, fs, cc);
12699         } else {
12700             gen_cmp_d(ctx, func - 48, ft, fs, cc);
12701         }
12702         break;
12703     case OPC_CVT_S_D:
12704         check_cp1_registers(ctx, fs);
12705         {
12706             TCGv_i32 fp32 = tcg_temp_new_i32();
12707             TCGv_i64 fp64 = tcg_temp_new_i64();
12708 
12709             gen_load_fpr64(ctx, fp64, fs);
12710             gen_helper_float_cvts_d(fp32, cpu_env, fp64);
12711             tcg_temp_free_i64(fp64);
12712             gen_store_fpr32(ctx, fp32, fd);
12713             tcg_temp_free_i32(fp32);
12714         }
12715         break;
12716     case OPC_CVT_W_D:
12717         check_cp1_registers(ctx, fs);
12718         {
12719             TCGv_i32 fp32 = tcg_temp_new_i32();
12720             TCGv_i64 fp64 = tcg_temp_new_i64();
12721 
12722             gen_load_fpr64(ctx, fp64, fs);
12723             if (ctx->nan2008) {
12724                 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
12725             } else {
12726                 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
12727             }
12728             tcg_temp_free_i64(fp64);
12729             gen_store_fpr32(ctx, fp32, fd);
12730             tcg_temp_free_i32(fp32);
12731         }
12732         break;
12733     case OPC_CVT_L_D:
12734         check_cp1_64bitmode(ctx);
12735         {
12736             TCGv_i64 fp0 = tcg_temp_new_i64();
12737 
12738             gen_load_fpr64(ctx, fp0, fs);
12739             if (ctx->nan2008) {
12740                 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
12741             } else {
12742                 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
12743             }
12744             gen_store_fpr64(ctx, fp0, fd);
12745             tcg_temp_free_i64(fp0);
12746         }
12747         break;
12748     case OPC_CVT_S_W:
12749         {
12750             TCGv_i32 fp0 = tcg_temp_new_i32();
12751 
12752             gen_load_fpr32(ctx, fp0, fs);
12753             gen_helper_float_cvts_w(fp0, cpu_env, fp0);
12754             gen_store_fpr32(ctx, fp0, fd);
12755             tcg_temp_free_i32(fp0);
12756         }
12757         break;
12758     case OPC_CVT_D_W:
12759         check_cp1_registers(ctx, fd);
12760         {
12761             TCGv_i32 fp32 = tcg_temp_new_i32();
12762             TCGv_i64 fp64 = tcg_temp_new_i64();
12763 
12764             gen_load_fpr32(ctx, fp32, fs);
12765             gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
12766             tcg_temp_free_i32(fp32);
12767             gen_store_fpr64(ctx, fp64, fd);
12768             tcg_temp_free_i64(fp64);
12769         }
12770         break;
12771     case OPC_CVT_S_L:
12772         check_cp1_64bitmode(ctx);
12773         {
12774             TCGv_i32 fp32 = tcg_temp_new_i32();
12775             TCGv_i64 fp64 = tcg_temp_new_i64();
12776 
12777             gen_load_fpr64(ctx, fp64, fs);
12778             gen_helper_float_cvts_l(fp32, cpu_env, fp64);
12779             tcg_temp_free_i64(fp64);
12780             gen_store_fpr32(ctx, fp32, fd);
12781             tcg_temp_free_i32(fp32);
12782         }
12783         break;
12784     case OPC_CVT_D_L:
12785         check_cp1_64bitmode(ctx);
12786         {
12787             TCGv_i64 fp0 = tcg_temp_new_i64();
12788 
12789             gen_load_fpr64(ctx, fp0, fs);
12790             gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
12791             gen_store_fpr64(ctx, fp0, fd);
12792             tcg_temp_free_i64(fp0);
12793         }
12794         break;
12795     case OPC_CVT_PS_PW:
12796         check_ps(ctx);
12797         {
12798             TCGv_i64 fp0 = tcg_temp_new_i64();
12799 
12800             gen_load_fpr64(ctx, fp0, fs);
12801             gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
12802             gen_store_fpr64(ctx, fp0, fd);
12803             tcg_temp_free_i64(fp0);
12804         }
12805         break;
12806     case OPC_ADD_PS:
12807         check_ps(ctx);
12808         {
12809             TCGv_i64 fp0 = tcg_temp_new_i64();
12810             TCGv_i64 fp1 = tcg_temp_new_i64();
12811 
12812             gen_load_fpr64(ctx, fp0, fs);
12813             gen_load_fpr64(ctx, fp1, ft);
12814             gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
12815             tcg_temp_free_i64(fp1);
12816             gen_store_fpr64(ctx, fp0, fd);
12817             tcg_temp_free_i64(fp0);
12818         }
12819         break;
12820     case OPC_SUB_PS:
12821         check_ps(ctx);
12822         {
12823             TCGv_i64 fp0 = tcg_temp_new_i64();
12824             TCGv_i64 fp1 = tcg_temp_new_i64();
12825 
12826             gen_load_fpr64(ctx, fp0, fs);
12827             gen_load_fpr64(ctx, fp1, ft);
12828             gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
12829             tcg_temp_free_i64(fp1);
12830             gen_store_fpr64(ctx, fp0, fd);
12831             tcg_temp_free_i64(fp0);
12832         }
12833         break;
12834     case OPC_MUL_PS:
12835         check_ps(ctx);
12836         {
12837             TCGv_i64 fp0 = tcg_temp_new_i64();
12838             TCGv_i64 fp1 = tcg_temp_new_i64();
12839 
12840             gen_load_fpr64(ctx, fp0, fs);
12841             gen_load_fpr64(ctx, fp1, ft);
12842             gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
12843             tcg_temp_free_i64(fp1);
12844             gen_store_fpr64(ctx, fp0, fd);
12845             tcg_temp_free_i64(fp0);
12846         }
12847         break;
12848     case OPC_ABS_PS:
12849         check_ps(ctx);
12850         {
12851             TCGv_i64 fp0 = tcg_temp_new_i64();
12852 
12853             gen_load_fpr64(ctx, fp0, fs);
12854             gen_helper_float_abs_ps(fp0, fp0);
12855             gen_store_fpr64(ctx, fp0, fd);
12856             tcg_temp_free_i64(fp0);
12857         }
12858         break;
12859     case OPC_MOV_PS:
12860         check_ps(ctx);
12861         {
12862             TCGv_i64 fp0 = tcg_temp_new_i64();
12863 
12864             gen_load_fpr64(ctx, fp0, fs);
12865             gen_store_fpr64(ctx, fp0, fd);
12866             tcg_temp_free_i64(fp0);
12867         }
12868         break;
12869     case OPC_NEG_PS:
12870         check_ps(ctx);
12871         {
12872             TCGv_i64 fp0 = tcg_temp_new_i64();
12873 
12874             gen_load_fpr64(ctx, fp0, fs);
12875             gen_helper_float_chs_ps(fp0, fp0);
12876             gen_store_fpr64(ctx, fp0, fd);
12877             tcg_temp_free_i64(fp0);
12878         }
12879         break;
12880     case OPC_MOVCF_PS:
12881         check_ps(ctx);
12882         gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
12883         break;
12884     case OPC_MOVZ_PS:
12885         check_ps(ctx);
12886         {
12887             TCGLabel *l1 = gen_new_label();
12888             TCGv_i64 fp0;
12889 
12890             if (ft != 0) {
12891                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
12892             }
12893             fp0 = tcg_temp_new_i64();
12894             gen_load_fpr64(ctx, fp0, fs);
12895             gen_store_fpr64(ctx, fp0, fd);
12896             tcg_temp_free_i64(fp0);
12897             gen_set_label(l1);
12898         }
12899         break;
12900     case OPC_MOVN_PS:
12901         check_ps(ctx);
12902         {
12903             TCGLabel *l1 = gen_new_label();
12904             TCGv_i64 fp0;
12905 
12906             if (ft != 0) {
12907                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
12908                 fp0 = tcg_temp_new_i64();
12909                 gen_load_fpr64(ctx, fp0, fs);
12910                 gen_store_fpr64(ctx, fp0, fd);
12911                 tcg_temp_free_i64(fp0);
12912                 gen_set_label(l1);
12913             }
12914         }
12915         break;
12916     case OPC_ADDR_PS:
12917         check_ps(ctx);
12918         {
12919             TCGv_i64 fp0 = tcg_temp_new_i64();
12920             TCGv_i64 fp1 = tcg_temp_new_i64();
12921 
12922             gen_load_fpr64(ctx, fp0, ft);
12923             gen_load_fpr64(ctx, fp1, fs);
12924             gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
12925             tcg_temp_free_i64(fp1);
12926             gen_store_fpr64(ctx, fp0, fd);
12927             tcg_temp_free_i64(fp0);
12928         }
12929         break;
12930     case OPC_MULR_PS:
12931         check_ps(ctx);
12932         {
12933             TCGv_i64 fp0 = tcg_temp_new_i64();
12934             TCGv_i64 fp1 = tcg_temp_new_i64();
12935 
12936             gen_load_fpr64(ctx, fp0, ft);
12937             gen_load_fpr64(ctx, fp1, fs);
12938             gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
12939             tcg_temp_free_i64(fp1);
12940             gen_store_fpr64(ctx, fp0, fd);
12941             tcg_temp_free_i64(fp0);
12942         }
12943         break;
12944     case OPC_RECIP2_PS:
12945         check_ps(ctx);
12946         {
12947             TCGv_i64 fp0 = tcg_temp_new_i64();
12948             TCGv_i64 fp1 = tcg_temp_new_i64();
12949 
12950             gen_load_fpr64(ctx, fp0, fs);
12951             gen_load_fpr64(ctx, fp1, ft);
12952             gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
12953             tcg_temp_free_i64(fp1);
12954             gen_store_fpr64(ctx, fp0, fd);
12955             tcg_temp_free_i64(fp0);
12956         }
12957         break;
12958     case OPC_RECIP1_PS:
12959         check_ps(ctx);
12960         {
12961             TCGv_i64 fp0 = tcg_temp_new_i64();
12962 
12963             gen_load_fpr64(ctx, fp0, fs);
12964             gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
12965             gen_store_fpr64(ctx, fp0, fd);
12966             tcg_temp_free_i64(fp0);
12967         }
12968         break;
12969     case OPC_RSQRT1_PS:
12970         check_ps(ctx);
12971         {
12972             TCGv_i64 fp0 = tcg_temp_new_i64();
12973 
12974             gen_load_fpr64(ctx, fp0, fs);
12975             gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
12976             gen_store_fpr64(ctx, fp0, fd);
12977             tcg_temp_free_i64(fp0);
12978         }
12979         break;
12980     case OPC_RSQRT2_PS:
12981         check_ps(ctx);
12982         {
12983             TCGv_i64 fp0 = tcg_temp_new_i64();
12984             TCGv_i64 fp1 = tcg_temp_new_i64();
12985 
12986             gen_load_fpr64(ctx, fp0, fs);
12987             gen_load_fpr64(ctx, fp1, ft);
12988             gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
12989             tcg_temp_free_i64(fp1);
12990             gen_store_fpr64(ctx, fp0, fd);
12991             tcg_temp_free_i64(fp0);
12992         }
12993         break;
12994     case OPC_CVT_S_PU:
12995         check_cp1_64bitmode(ctx);
12996         {
12997             TCGv_i32 fp0 = tcg_temp_new_i32();
12998 
12999             gen_load_fpr32h(ctx, fp0, fs);
13000             gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
13001             gen_store_fpr32(ctx, fp0, fd);
13002             tcg_temp_free_i32(fp0);
13003         }
13004         break;
13005     case OPC_CVT_PW_PS:
13006         check_ps(ctx);
13007         {
13008             TCGv_i64 fp0 = tcg_temp_new_i64();
13009 
13010             gen_load_fpr64(ctx, fp0, fs);
13011             gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
13012             gen_store_fpr64(ctx, fp0, fd);
13013             tcg_temp_free_i64(fp0);
13014         }
13015         break;
13016     case OPC_CVT_S_PL:
13017         check_cp1_64bitmode(ctx);
13018         {
13019             TCGv_i32 fp0 = tcg_temp_new_i32();
13020 
13021             gen_load_fpr32(ctx, fp0, fs);
13022             gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
13023             gen_store_fpr32(ctx, fp0, fd);
13024             tcg_temp_free_i32(fp0);
13025         }
13026         break;
13027     case OPC_PLL_PS:
13028         check_ps(ctx);
13029         {
13030             TCGv_i32 fp0 = tcg_temp_new_i32();
13031             TCGv_i32 fp1 = tcg_temp_new_i32();
13032 
13033             gen_load_fpr32(ctx, fp0, fs);
13034             gen_load_fpr32(ctx, fp1, ft);
13035             gen_store_fpr32h(ctx, fp0, fd);
13036             gen_store_fpr32(ctx, fp1, fd);
13037             tcg_temp_free_i32(fp0);
13038             tcg_temp_free_i32(fp1);
13039         }
13040         break;
13041     case OPC_PLU_PS:
13042         check_ps(ctx);
13043         {
13044             TCGv_i32 fp0 = tcg_temp_new_i32();
13045             TCGv_i32 fp1 = tcg_temp_new_i32();
13046 
13047             gen_load_fpr32(ctx, fp0, fs);
13048             gen_load_fpr32h(ctx, fp1, ft);
13049             gen_store_fpr32(ctx, fp1, fd);
13050             gen_store_fpr32h(ctx, fp0, fd);
13051             tcg_temp_free_i32(fp0);
13052             tcg_temp_free_i32(fp1);
13053         }
13054         break;
13055     case OPC_PUL_PS:
13056         check_ps(ctx);
13057         {
13058             TCGv_i32 fp0 = tcg_temp_new_i32();
13059             TCGv_i32 fp1 = tcg_temp_new_i32();
13060 
13061             gen_load_fpr32h(ctx, fp0, fs);
13062             gen_load_fpr32(ctx, fp1, ft);
13063             gen_store_fpr32(ctx, fp1, fd);
13064             gen_store_fpr32h(ctx, fp0, fd);
13065             tcg_temp_free_i32(fp0);
13066             tcg_temp_free_i32(fp1);
13067         }
13068         break;
13069     case OPC_PUU_PS:
13070         check_ps(ctx);
13071         {
13072             TCGv_i32 fp0 = tcg_temp_new_i32();
13073             TCGv_i32 fp1 = tcg_temp_new_i32();
13074 
13075             gen_load_fpr32h(ctx, fp0, fs);
13076             gen_load_fpr32h(ctx, fp1, ft);
13077             gen_store_fpr32(ctx, fp1, fd);
13078             gen_store_fpr32h(ctx, fp0, fd);
13079             tcg_temp_free_i32(fp0);
13080             tcg_temp_free_i32(fp1);
13081         }
13082         break;
13083     case OPC_CMP_F_PS:
13084     case OPC_CMP_UN_PS:
13085     case OPC_CMP_EQ_PS:
13086     case OPC_CMP_UEQ_PS:
13087     case OPC_CMP_OLT_PS:
13088     case OPC_CMP_ULT_PS:
13089     case OPC_CMP_OLE_PS:
13090     case OPC_CMP_ULE_PS:
13091     case OPC_CMP_SF_PS:
13092     case OPC_CMP_NGLE_PS:
13093     case OPC_CMP_SEQ_PS:
13094     case OPC_CMP_NGL_PS:
13095     case OPC_CMP_LT_PS:
13096     case OPC_CMP_NGE_PS:
13097     case OPC_CMP_LE_PS:
13098     case OPC_CMP_NGT_PS:
13099         if (ctx->opcode & (1 << 6)) {
13100             gen_cmpabs_ps(ctx, func - 48, ft, fs, cc);
13101         } else {
13102             gen_cmp_ps(ctx, func - 48, ft, fs, cc);
13103         }
13104         break;
13105     default:
13106         MIPS_INVAL("farith");
13107         generate_exception_end(ctx, EXCP_RI);
13108         return;
13109     }
13110 }
13111 
13112 /* Coprocessor 3 (FPU) */
gen_flt3_ldst(DisasContext * ctx,uint32_t opc,int fd,int fs,int base,int index)13113 static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc,
13114                           int fd, int fs, int base, int index)
13115 {
13116     TCGv t0 = tcg_temp_new();
13117 
13118     if (base == 0) {
13119         gen_load_gpr(t0, index);
13120     } else if (index == 0) {
13121         gen_load_gpr(t0, base);
13122     } else {
13123         gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
13124     }
13125     /*
13126      * Don't do NOP if destination is zero: we must perform the actual
13127      * memory access.
13128      */
13129     switch (opc) {
13130     case OPC_LWXC1:
13131         check_cop1x(ctx);
13132         {
13133             TCGv_i32 fp0 = tcg_temp_new_i32();
13134 
13135             tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
13136             tcg_gen_trunc_tl_i32(fp0, t0);
13137             gen_store_fpr32(ctx, fp0, fd);
13138             tcg_temp_free_i32(fp0);
13139         }
13140         break;
13141     case OPC_LDXC1:
13142         check_cop1x(ctx);
13143         check_cp1_registers(ctx, fd);
13144         {
13145             TCGv_i64 fp0 = tcg_temp_new_i64();
13146             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
13147             gen_store_fpr64(ctx, fp0, fd);
13148             tcg_temp_free_i64(fp0);
13149         }
13150         break;
13151     case OPC_LUXC1:
13152         check_cp1_64bitmode(ctx);
13153         tcg_gen_andi_tl(t0, t0, ~0x7);
13154         {
13155             TCGv_i64 fp0 = tcg_temp_new_i64();
13156 
13157             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
13158             gen_store_fpr64(ctx, fp0, fd);
13159             tcg_temp_free_i64(fp0);
13160         }
13161         break;
13162     case OPC_SWXC1:
13163         check_cop1x(ctx);
13164         {
13165             TCGv_i32 fp0 = tcg_temp_new_i32();
13166             gen_load_fpr32(ctx, fp0, fs);
13167             tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
13168             tcg_temp_free_i32(fp0);
13169         }
13170         break;
13171     case OPC_SDXC1:
13172         check_cop1x(ctx);
13173         check_cp1_registers(ctx, fs);
13174         {
13175             TCGv_i64 fp0 = tcg_temp_new_i64();
13176             gen_load_fpr64(ctx, fp0, fs);
13177             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
13178             tcg_temp_free_i64(fp0);
13179         }
13180         break;
13181     case OPC_SUXC1:
13182         check_cp1_64bitmode(ctx);
13183         tcg_gen_andi_tl(t0, t0, ~0x7);
13184         {
13185             TCGv_i64 fp0 = tcg_temp_new_i64();
13186             gen_load_fpr64(ctx, fp0, fs);
13187             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
13188             tcg_temp_free_i64(fp0);
13189         }
13190         break;
13191     }
13192     tcg_temp_free(t0);
13193 }
13194 
gen_flt3_arith(DisasContext * ctx,uint32_t opc,int fd,int fr,int fs,int ft)13195 static void gen_flt3_arith(DisasContext *ctx, uint32_t opc,
13196                            int fd, int fr, int fs, int ft)
13197 {
13198     switch (opc) {
13199     case OPC_ALNV_PS:
13200         check_ps(ctx);
13201         {
13202             TCGv t0 = tcg_temp_local_new();
13203             TCGv_i32 fp = tcg_temp_new_i32();
13204             TCGv_i32 fph = tcg_temp_new_i32();
13205             TCGLabel *l1 = gen_new_label();
13206             TCGLabel *l2 = gen_new_label();
13207 
13208             gen_load_gpr(t0, fr);
13209             tcg_gen_andi_tl(t0, t0, 0x7);
13210 
13211             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
13212             gen_load_fpr32(ctx, fp, fs);
13213             gen_load_fpr32h(ctx, fph, fs);
13214             gen_store_fpr32(ctx, fp, fd);
13215             gen_store_fpr32h(ctx, fph, fd);
13216             tcg_gen_br(l2);
13217             gen_set_label(l1);
13218             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
13219             tcg_temp_free(t0);
13220 #ifdef TARGET_WORDS_BIGENDIAN
13221             gen_load_fpr32(ctx, fp, fs);
13222             gen_load_fpr32h(ctx, fph, ft);
13223             gen_store_fpr32h(ctx, fp, fd);
13224             gen_store_fpr32(ctx, fph, fd);
13225 #else
13226             gen_load_fpr32h(ctx, fph, fs);
13227             gen_load_fpr32(ctx, fp, ft);
13228             gen_store_fpr32(ctx, fph, fd);
13229             gen_store_fpr32h(ctx, fp, fd);
13230 #endif
13231             gen_set_label(l2);
13232             tcg_temp_free_i32(fp);
13233             tcg_temp_free_i32(fph);
13234         }
13235         break;
13236     case OPC_MADD_S:
13237         check_cop1x(ctx);
13238         {
13239             TCGv_i32 fp0 = tcg_temp_new_i32();
13240             TCGv_i32 fp1 = tcg_temp_new_i32();
13241             TCGv_i32 fp2 = tcg_temp_new_i32();
13242 
13243             gen_load_fpr32(ctx, fp0, fs);
13244             gen_load_fpr32(ctx, fp1, ft);
13245             gen_load_fpr32(ctx, fp2, fr);
13246             gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
13247             tcg_temp_free_i32(fp0);
13248             tcg_temp_free_i32(fp1);
13249             gen_store_fpr32(ctx, fp2, fd);
13250             tcg_temp_free_i32(fp2);
13251         }
13252         break;
13253     case OPC_MADD_D:
13254         check_cop1x(ctx);
13255         check_cp1_registers(ctx, fd | fs | ft | fr);
13256         {
13257             TCGv_i64 fp0 = tcg_temp_new_i64();
13258             TCGv_i64 fp1 = tcg_temp_new_i64();
13259             TCGv_i64 fp2 = tcg_temp_new_i64();
13260 
13261             gen_load_fpr64(ctx, fp0, fs);
13262             gen_load_fpr64(ctx, fp1, ft);
13263             gen_load_fpr64(ctx, fp2, fr);
13264             gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
13265             tcg_temp_free_i64(fp0);
13266             tcg_temp_free_i64(fp1);
13267             gen_store_fpr64(ctx, fp2, fd);
13268             tcg_temp_free_i64(fp2);
13269         }
13270         break;
13271     case OPC_MADD_PS:
13272         check_ps(ctx);
13273         {
13274             TCGv_i64 fp0 = tcg_temp_new_i64();
13275             TCGv_i64 fp1 = tcg_temp_new_i64();
13276             TCGv_i64 fp2 = tcg_temp_new_i64();
13277 
13278             gen_load_fpr64(ctx, fp0, fs);
13279             gen_load_fpr64(ctx, fp1, ft);
13280             gen_load_fpr64(ctx, fp2, fr);
13281             gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
13282             tcg_temp_free_i64(fp0);
13283             tcg_temp_free_i64(fp1);
13284             gen_store_fpr64(ctx, fp2, fd);
13285             tcg_temp_free_i64(fp2);
13286         }
13287         break;
13288     case OPC_MSUB_S:
13289         check_cop1x(ctx);
13290         {
13291             TCGv_i32 fp0 = tcg_temp_new_i32();
13292             TCGv_i32 fp1 = tcg_temp_new_i32();
13293             TCGv_i32 fp2 = tcg_temp_new_i32();
13294 
13295             gen_load_fpr32(ctx, fp0, fs);
13296             gen_load_fpr32(ctx, fp1, ft);
13297             gen_load_fpr32(ctx, fp2, fr);
13298             gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
13299             tcg_temp_free_i32(fp0);
13300             tcg_temp_free_i32(fp1);
13301             gen_store_fpr32(ctx, fp2, fd);
13302             tcg_temp_free_i32(fp2);
13303         }
13304         break;
13305     case OPC_MSUB_D:
13306         check_cop1x(ctx);
13307         check_cp1_registers(ctx, fd | fs | ft | fr);
13308         {
13309             TCGv_i64 fp0 = tcg_temp_new_i64();
13310             TCGv_i64 fp1 = tcg_temp_new_i64();
13311             TCGv_i64 fp2 = tcg_temp_new_i64();
13312 
13313             gen_load_fpr64(ctx, fp0, fs);
13314             gen_load_fpr64(ctx, fp1, ft);
13315             gen_load_fpr64(ctx, fp2, fr);
13316             gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
13317             tcg_temp_free_i64(fp0);
13318             tcg_temp_free_i64(fp1);
13319             gen_store_fpr64(ctx, fp2, fd);
13320             tcg_temp_free_i64(fp2);
13321         }
13322         break;
13323     case OPC_MSUB_PS:
13324         check_ps(ctx);
13325         {
13326             TCGv_i64 fp0 = tcg_temp_new_i64();
13327             TCGv_i64 fp1 = tcg_temp_new_i64();
13328             TCGv_i64 fp2 = tcg_temp_new_i64();
13329 
13330             gen_load_fpr64(ctx, fp0, fs);
13331             gen_load_fpr64(ctx, fp1, ft);
13332             gen_load_fpr64(ctx, fp2, fr);
13333             gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
13334             tcg_temp_free_i64(fp0);
13335             tcg_temp_free_i64(fp1);
13336             gen_store_fpr64(ctx, fp2, fd);
13337             tcg_temp_free_i64(fp2);
13338         }
13339         break;
13340     case OPC_NMADD_S:
13341         check_cop1x(ctx);
13342         {
13343             TCGv_i32 fp0 = tcg_temp_new_i32();
13344             TCGv_i32 fp1 = tcg_temp_new_i32();
13345             TCGv_i32 fp2 = tcg_temp_new_i32();
13346 
13347             gen_load_fpr32(ctx, fp0, fs);
13348             gen_load_fpr32(ctx, fp1, ft);
13349             gen_load_fpr32(ctx, fp2, fr);
13350             gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
13351             tcg_temp_free_i32(fp0);
13352             tcg_temp_free_i32(fp1);
13353             gen_store_fpr32(ctx, fp2, fd);
13354             tcg_temp_free_i32(fp2);
13355         }
13356         break;
13357     case OPC_NMADD_D:
13358         check_cop1x(ctx);
13359         check_cp1_registers(ctx, fd | fs | ft | fr);
13360         {
13361             TCGv_i64 fp0 = tcg_temp_new_i64();
13362             TCGv_i64 fp1 = tcg_temp_new_i64();
13363             TCGv_i64 fp2 = tcg_temp_new_i64();
13364 
13365             gen_load_fpr64(ctx, fp0, fs);
13366             gen_load_fpr64(ctx, fp1, ft);
13367             gen_load_fpr64(ctx, fp2, fr);
13368             gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
13369             tcg_temp_free_i64(fp0);
13370             tcg_temp_free_i64(fp1);
13371             gen_store_fpr64(ctx, fp2, fd);
13372             tcg_temp_free_i64(fp2);
13373         }
13374         break;
13375     case OPC_NMADD_PS:
13376         check_ps(ctx);
13377         {
13378             TCGv_i64 fp0 = tcg_temp_new_i64();
13379             TCGv_i64 fp1 = tcg_temp_new_i64();
13380             TCGv_i64 fp2 = tcg_temp_new_i64();
13381 
13382             gen_load_fpr64(ctx, fp0, fs);
13383             gen_load_fpr64(ctx, fp1, ft);
13384             gen_load_fpr64(ctx, fp2, fr);
13385             gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
13386             tcg_temp_free_i64(fp0);
13387             tcg_temp_free_i64(fp1);
13388             gen_store_fpr64(ctx, fp2, fd);
13389             tcg_temp_free_i64(fp2);
13390         }
13391         break;
13392     case OPC_NMSUB_S:
13393         check_cop1x(ctx);
13394         {
13395             TCGv_i32 fp0 = tcg_temp_new_i32();
13396             TCGv_i32 fp1 = tcg_temp_new_i32();
13397             TCGv_i32 fp2 = tcg_temp_new_i32();
13398 
13399             gen_load_fpr32(ctx, fp0, fs);
13400             gen_load_fpr32(ctx, fp1, ft);
13401             gen_load_fpr32(ctx, fp2, fr);
13402             gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
13403             tcg_temp_free_i32(fp0);
13404             tcg_temp_free_i32(fp1);
13405             gen_store_fpr32(ctx, fp2, fd);
13406             tcg_temp_free_i32(fp2);
13407         }
13408         break;
13409     case OPC_NMSUB_D:
13410         check_cop1x(ctx);
13411         check_cp1_registers(ctx, fd | fs | ft | fr);
13412         {
13413             TCGv_i64 fp0 = tcg_temp_new_i64();
13414             TCGv_i64 fp1 = tcg_temp_new_i64();
13415             TCGv_i64 fp2 = tcg_temp_new_i64();
13416 
13417             gen_load_fpr64(ctx, fp0, fs);
13418             gen_load_fpr64(ctx, fp1, ft);
13419             gen_load_fpr64(ctx, fp2, fr);
13420             gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
13421             tcg_temp_free_i64(fp0);
13422             tcg_temp_free_i64(fp1);
13423             gen_store_fpr64(ctx, fp2, fd);
13424             tcg_temp_free_i64(fp2);
13425         }
13426         break;
13427     case OPC_NMSUB_PS:
13428         check_ps(ctx);
13429         {
13430             TCGv_i64 fp0 = tcg_temp_new_i64();
13431             TCGv_i64 fp1 = tcg_temp_new_i64();
13432             TCGv_i64 fp2 = tcg_temp_new_i64();
13433 
13434             gen_load_fpr64(ctx, fp0, fs);
13435             gen_load_fpr64(ctx, fp1, ft);
13436             gen_load_fpr64(ctx, fp2, fr);
13437             gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
13438             tcg_temp_free_i64(fp0);
13439             tcg_temp_free_i64(fp1);
13440             gen_store_fpr64(ctx, fp2, fd);
13441             tcg_temp_free_i64(fp2);
13442         }
13443         break;
13444     default:
13445         MIPS_INVAL("flt3_arith");
13446         generate_exception_end(ctx, EXCP_RI);
13447         return;
13448     }
13449 }
13450 
gen_rdhwr(DisasContext * ctx,int rt,int rd,int sel)13451 static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
13452 {
13453     TCGv t0;
13454 
13455 #if !defined(CONFIG_USER_ONLY)
13456     /*
13457      * The Linux kernel will emulate rdhwr if it's not supported natively.
13458      * Therefore only check the ISA in system mode.
13459      */
13460     check_insn(ctx, ISA_MIPS32R2);
13461 #endif
13462     t0 = tcg_temp_new();
13463 
13464     switch (rd) {
13465     case 0:
13466         gen_helper_rdhwr_cpunum(t0, cpu_env);
13467         gen_store_gpr(t0, rt);
13468         break;
13469     case 1:
13470         gen_helper_rdhwr_synci_step(t0, cpu_env);
13471         gen_store_gpr(t0, rt);
13472         break;
13473     case 2:
13474         if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
13475             gen_io_start();
13476         }
13477         gen_helper_rdhwr_cc(t0, cpu_env);
13478         gen_store_gpr(t0, rt);
13479         /*
13480          * Break the TB to be able to take timer interrupts immediately
13481          * after reading count. DISAS_STOP isn't sufficient, we need to ensure
13482          * we break completely out of translated code.
13483          */
13484         gen_save_pc(ctx->base.pc_next + 4);
13485         ctx->base.is_jmp = DISAS_EXIT;
13486         break;
13487     case 3:
13488         gen_helper_rdhwr_ccres(t0, cpu_env);
13489         gen_store_gpr(t0, rt);
13490         break;
13491     case 4:
13492         check_insn(ctx, ISA_MIPS32R6);
13493         if (sel != 0) {
13494             /*
13495              * Performance counter registers are not implemented other than
13496              * control register 0.
13497              */
13498             generate_exception(ctx, EXCP_RI);
13499         }
13500         gen_helper_rdhwr_performance(t0, cpu_env);
13501         gen_store_gpr(t0, rt);
13502         break;
13503     case 5:
13504         check_insn(ctx, ISA_MIPS32R6);
13505         gen_helper_rdhwr_xnp(t0, cpu_env);
13506         gen_store_gpr(t0, rt);
13507         break;
13508     case 29:
13509 #if defined(CONFIG_USER_ONLY)
13510         tcg_gen_ld_tl(t0, cpu_env,
13511                       offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
13512         gen_store_gpr(t0, rt);
13513         break;
13514 #else
13515         if ((ctx->hflags & MIPS_HFLAG_CP0) ||
13516             (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
13517             tcg_gen_ld_tl(t0, cpu_env,
13518                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
13519             gen_store_gpr(t0, rt);
13520         } else {
13521             generate_exception_end(ctx, EXCP_RI);
13522         }
13523         break;
13524 #endif
13525     default:            /* Invalid */
13526         MIPS_INVAL("rdhwr");
13527         generate_exception_end(ctx, EXCP_RI);
13528         break;
13529     }
13530     tcg_temp_free(t0);
13531 }
13532 
clear_branch_hflags(DisasContext * ctx)13533 static inline void clear_branch_hflags(DisasContext *ctx)
13534 {
13535     ctx->hflags &= ~MIPS_HFLAG_BMASK;
13536     if (ctx->base.is_jmp == DISAS_NEXT) {
13537         save_cpu_state(ctx, 0);
13538     } else {
13539         /*
13540          * It is not safe to save ctx->hflags as hflags may be changed
13541          * in execution time by the instruction in delay / forbidden slot.
13542          */
13543         tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
13544     }
13545 }
13546 
gen_branch(DisasContext * ctx,int insn_bytes)13547 static void gen_branch(DisasContext *ctx, int insn_bytes)
13548 {
13549     if (ctx->hflags & MIPS_HFLAG_BMASK) {
13550         int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
13551         /* Branches completion */
13552         clear_branch_hflags(ctx);
13553         ctx->base.is_jmp = DISAS_NORETURN;
13554         /* FIXME: Need to clear can_do_io.  */
13555         switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
13556         case MIPS_HFLAG_FBNSLOT:
13557             gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
13558             break;
13559         case MIPS_HFLAG_B:
13560             /* unconditional branch */
13561             if (proc_hflags & MIPS_HFLAG_BX) {
13562                 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
13563             }
13564             gen_goto_tb(ctx, 0, ctx->btarget);
13565             break;
13566         case MIPS_HFLAG_BL:
13567             /* blikely taken case */
13568             gen_goto_tb(ctx, 0, ctx->btarget);
13569             break;
13570         case MIPS_HFLAG_BC:
13571             /* Conditional branch */
13572             {
13573                 TCGLabel *l1 = gen_new_label();
13574 
13575                 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
13576                 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
13577                 gen_set_label(l1);
13578                 gen_goto_tb(ctx, 0, ctx->btarget);
13579             }
13580             break;
13581         case MIPS_HFLAG_BR:
13582             /* unconditional branch to register */
13583             if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
13584                 TCGv t0 = tcg_temp_new();
13585                 TCGv_i32 t1 = tcg_temp_new_i32();
13586 
13587                 tcg_gen_andi_tl(t0, btarget, 0x1);
13588                 tcg_gen_trunc_tl_i32(t1, t0);
13589                 tcg_temp_free(t0);
13590                 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
13591                 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
13592                 tcg_gen_or_i32(hflags, hflags, t1);
13593                 tcg_temp_free_i32(t1);
13594 
13595                 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
13596             } else {
13597                 tcg_gen_mov_tl(cpu_PC, btarget);
13598             }
13599             if (ctx->base.singlestep_enabled) {
13600                 save_cpu_state(ctx, 0);
13601                 gen_helper_raise_exception_debug(cpu_env);
13602             }
13603             tcg_gen_lookup_and_goto_ptr();
13604             break;
13605         default:
13606             fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
13607             abort();
13608         }
13609     }
13610 }
13611 
13612 /* Compact Branches */
gen_compute_compact_branch(DisasContext * ctx,uint32_t opc,int rs,int rt,int32_t offset)13613 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
13614                                        int rs, int rt, int32_t offset)
13615 {
13616     int bcond_compute = 0;
13617     TCGv t0 = tcg_temp_new();
13618     TCGv t1 = tcg_temp_new();
13619     int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
13620 
13621     if (ctx->hflags & MIPS_HFLAG_BMASK) {
13622 #ifdef MIPS_DEBUG_DISAS
13623         LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
13624                   "\n", ctx->base.pc_next);
13625 #endif
13626         generate_exception_end(ctx, EXCP_RI);
13627         goto out;
13628     }
13629 
13630     /* Load needed operands and calculate btarget */
13631     switch (opc) {
13632     /* compact branch */
13633     case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
13634     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
13635         gen_load_gpr(t0, rs);
13636         gen_load_gpr(t1, rt);
13637         bcond_compute = 1;
13638         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
13639         if (rs <= rt && rs == 0) {
13640             /* OPC_BEQZALC, OPC_BNEZALC */
13641             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
13642         }
13643         break;
13644     case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
13645     case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
13646         gen_load_gpr(t0, rs);
13647         gen_load_gpr(t1, rt);
13648         bcond_compute = 1;
13649         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
13650         break;
13651     case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
13652     case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
13653         if (rs == 0 || rs == rt) {
13654             /* OPC_BLEZALC, OPC_BGEZALC */
13655             /* OPC_BGTZALC, OPC_BLTZALC */
13656             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
13657         }
13658         gen_load_gpr(t0, rs);
13659         gen_load_gpr(t1, rt);
13660         bcond_compute = 1;
13661         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
13662         break;
13663     case OPC_BC:
13664     case OPC_BALC:
13665         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
13666         break;
13667     case OPC_BEQZC:
13668     case OPC_BNEZC:
13669         if (rs != 0) {
13670             /* OPC_BEQZC, OPC_BNEZC */
13671             gen_load_gpr(t0, rs);
13672             bcond_compute = 1;
13673             ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
13674         } else {
13675             /* OPC_JIC, OPC_JIALC */
13676             TCGv tbase = tcg_temp_new();
13677             TCGv toffset = tcg_temp_new();
13678 
13679             gen_load_gpr(tbase, rt);
13680             tcg_gen_movi_tl(toffset, offset);
13681             gen_op_addr_add(ctx, btarget, tbase, toffset);
13682             tcg_temp_free(tbase);
13683             tcg_temp_free(toffset);
13684         }
13685         break;
13686     default:
13687         MIPS_INVAL("Compact branch/jump");
13688         generate_exception_end(ctx, EXCP_RI);
13689         goto out;
13690     }
13691 
13692     if (bcond_compute == 0) {
13693         /* Uncoditional compact branch */
13694         switch (opc) {
13695         case OPC_JIALC:
13696             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
13697             /* Fallthrough */
13698         case OPC_JIC:
13699             ctx->hflags |= MIPS_HFLAG_BR;
13700             break;
13701         case OPC_BALC:
13702             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
13703             /* Fallthrough */
13704         case OPC_BC:
13705             ctx->hflags |= MIPS_HFLAG_B;
13706             break;
13707         default:
13708             MIPS_INVAL("Compact branch/jump");
13709             generate_exception_end(ctx, EXCP_RI);
13710             goto out;
13711         }
13712 
13713         /* Generating branch here as compact branches don't have delay slot */
13714         gen_branch(ctx, 4);
13715     } else {
13716         /* Conditional compact branch */
13717         TCGLabel *fs = gen_new_label();
13718         save_cpu_state(ctx, 0);
13719 
13720         switch (opc) {
13721         case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
13722             if (rs == 0 && rt != 0) {
13723                 /* OPC_BLEZALC */
13724                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
13725             } else if (rs != 0 && rt != 0 && rs == rt) {
13726                 /* OPC_BGEZALC */
13727                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
13728             } else {
13729                 /* OPC_BGEUC */
13730                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
13731             }
13732             break;
13733         case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
13734             if (rs == 0 && rt != 0) {
13735                 /* OPC_BGTZALC */
13736                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
13737             } else if (rs != 0 && rt != 0 && rs == rt) {
13738                 /* OPC_BLTZALC */
13739                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
13740             } else {
13741                 /* OPC_BLTUC */
13742                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
13743             }
13744             break;
13745         case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
13746             if (rs == 0 && rt != 0) {
13747                 /* OPC_BLEZC */
13748                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
13749             } else if (rs != 0 && rt != 0 && rs == rt) {
13750                 /* OPC_BGEZC */
13751                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
13752             } else {
13753                 /* OPC_BGEC */
13754                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
13755             }
13756             break;
13757         case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
13758             if (rs == 0 && rt != 0) {
13759                 /* OPC_BGTZC */
13760                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
13761             } else if (rs != 0 && rt != 0 && rs == rt) {
13762                 /* OPC_BLTZC */
13763                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
13764             } else {
13765                 /* OPC_BLTC */
13766                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
13767             }
13768             break;
13769         case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
13770         case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
13771             if (rs >= rt) {
13772                 /* OPC_BOVC, OPC_BNVC */
13773                 TCGv t2 = tcg_temp_new();
13774                 TCGv t3 = tcg_temp_new();
13775                 TCGv t4 = tcg_temp_new();
13776                 TCGv input_overflow = tcg_temp_new();
13777 
13778                 gen_load_gpr(t0, rs);
13779                 gen_load_gpr(t1, rt);
13780                 tcg_gen_ext32s_tl(t2, t0);
13781                 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
13782                 tcg_gen_ext32s_tl(t3, t1);
13783                 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
13784                 tcg_gen_or_tl(input_overflow, input_overflow, t4);
13785 
13786                 tcg_gen_add_tl(t4, t2, t3);
13787                 tcg_gen_ext32s_tl(t4, t4);
13788                 tcg_gen_xor_tl(t2, t2, t3);
13789                 tcg_gen_xor_tl(t3, t4, t3);
13790                 tcg_gen_andc_tl(t2, t3, t2);
13791                 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
13792                 tcg_gen_or_tl(t4, t4, input_overflow);
13793                 if (opc == OPC_BOVC) {
13794                     /* OPC_BOVC */
13795                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
13796                 } else {
13797                     /* OPC_BNVC */
13798                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
13799                 }
13800                 tcg_temp_free(input_overflow);
13801                 tcg_temp_free(t4);
13802                 tcg_temp_free(t3);
13803                 tcg_temp_free(t2);
13804             } else if (rs < rt && rs == 0) {
13805                 /* OPC_BEQZALC, OPC_BNEZALC */
13806                 if (opc == OPC_BEQZALC) {
13807                     /* OPC_BEQZALC */
13808                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
13809                 } else {
13810                     /* OPC_BNEZALC */
13811                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
13812                 }
13813             } else {
13814                 /* OPC_BEQC, OPC_BNEC */
13815                 if (opc == OPC_BEQC) {
13816                     /* OPC_BEQC */
13817                     tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
13818                 } else {
13819                     /* OPC_BNEC */
13820                     tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
13821                 }
13822             }
13823             break;
13824         case OPC_BEQZC:
13825             tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
13826             break;
13827         case OPC_BNEZC:
13828             tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
13829             break;
13830         default:
13831             MIPS_INVAL("Compact conditional branch/jump");
13832             generate_exception_end(ctx, EXCP_RI);
13833             goto out;
13834         }
13835 
13836         /* Generating branch here as compact branches don't have delay slot */
13837         gen_goto_tb(ctx, 1, ctx->btarget);
13838         gen_set_label(fs);
13839 
13840         ctx->hflags |= MIPS_HFLAG_FBNSLOT;
13841     }
13842 
13843 out:
13844     tcg_temp_free(t0);
13845     tcg_temp_free(t1);
13846 }
13847 
13848 /* ISA extensions (ASEs) */
13849 /* MIPS16 extension to MIPS32 */
13850 
13851 /* MIPS16 major opcodes */
13852 enum {
13853   M16_OPC_ADDIUSP = 0x00,
13854   M16_OPC_ADDIUPC = 0x01,
13855   M16_OPC_B = 0x02,
13856   M16_OPC_JAL = 0x03,
13857   M16_OPC_BEQZ = 0x04,
13858   M16_OPC_BNEQZ = 0x05,
13859   M16_OPC_SHIFT = 0x06,
13860   M16_OPC_LD = 0x07,
13861   M16_OPC_RRIA = 0x08,
13862   M16_OPC_ADDIU8 = 0x09,
13863   M16_OPC_SLTI = 0x0a,
13864   M16_OPC_SLTIU = 0x0b,
13865   M16_OPC_I8 = 0x0c,
13866   M16_OPC_LI = 0x0d,
13867   M16_OPC_CMPI = 0x0e,
13868   M16_OPC_SD = 0x0f,
13869   M16_OPC_LB = 0x10,
13870   M16_OPC_LH = 0x11,
13871   M16_OPC_LWSP = 0x12,
13872   M16_OPC_LW = 0x13,
13873   M16_OPC_LBU = 0x14,
13874   M16_OPC_LHU = 0x15,
13875   M16_OPC_LWPC = 0x16,
13876   M16_OPC_LWU = 0x17,
13877   M16_OPC_SB = 0x18,
13878   M16_OPC_SH = 0x19,
13879   M16_OPC_SWSP = 0x1a,
13880   M16_OPC_SW = 0x1b,
13881   M16_OPC_RRR = 0x1c,
13882   M16_OPC_RR = 0x1d,
13883   M16_OPC_EXTEND = 0x1e,
13884   M16_OPC_I64 = 0x1f
13885 };
13886 
13887 /* I8 funct field */
13888 enum {
13889   I8_BTEQZ = 0x0,
13890   I8_BTNEZ = 0x1,
13891   I8_SWRASP = 0x2,
13892   I8_ADJSP = 0x3,
13893   I8_SVRS = 0x4,
13894   I8_MOV32R = 0x5,
13895   I8_MOVR32 = 0x7
13896 };
13897 
13898 /* RRR f field */
13899 enum {
13900   RRR_DADDU = 0x0,
13901   RRR_ADDU = 0x1,
13902   RRR_DSUBU = 0x2,
13903   RRR_SUBU = 0x3
13904 };
13905 
13906 /* RR funct field */
13907 enum {
13908   RR_JR = 0x00,
13909   RR_SDBBP = 0x01,
13910   RR_SLT = 0x02,
13911   RR_SLTU = 0x03,
13912   RR_SLLV = 0x04,
13913   RR_BREAK = 0x05,
13914   RR_SRLV = 0x06,
13915   RR_SRAV = 0x07,
13916   RR_DSRL = 0x08,
13917   RR_CMP = 0x0a,
13918   RR_NEG = 0x0b,
13919   RR_AND = 0x0c,
13920   RR_OR = 0x0d,
13921   RR_XOR = 0x0e,
13922   RR_NOT = 0x0f,
13923   RR_MFHI = 0x10,
13924   RR_CNVT = 0x11,
13925   RR_MFLO = 0x12,
13926   RR_DSRA = 0x13,
13927   RR_DSLLV = 0x14,
13928   RR_DSRLV = 0x16,
13929   RR_DSRAV = 0x17,
13930   RR_MULT = 0x18,
13931   RR_MULTU = 0x19,
13932   RR_DIV = 0x1a,
13933   RR_DIVU = 0x1b,
13934   RR_DMULT = 0x1c,
13935   RR_DMULTU = 0x1d,
13936   RR_DDIV = 0x1e,
13937   RR_DDIVU = 0x1f
13938 };
13939 
13940 /* I64 funct field */
13941 enum {
13942   I64_LDSP = 0x0,
13943   I64_SDSP = 0x1,
13944   I64_SDRASP = 0x2,
13945   I64_DADJSP = 0x3,
13946   I64_LDPC = 0x4,
13947   I64_DADDIU5 = 0x5,
13948   I64_DADDIUPC = 0x6,
13949   I64_DADDIUSP = 0x7
13950 };
13951 
13952 /* RR ry field for CNVT */
13953 enum {
13954   RR_RY_CNVT_ZEB = 0x0,
13955   RR_RY_CNVT_ZEH = 0x1,
13956   RR_RY_CNVT_ZEW = 0x2,
13957   RR_RY_CNVT_SEB = 0x4,
13958   RR_RY_CNVT_SEH = 0x5,
13959   RR_RY_CNVT_SEW = 0x6,
13960 };
13961 
xlat(int r)13962 static int xlat(int r)
13963 {
13964   static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13965 
13966   return map[r];
13967 }
13968 
gen_mips16_save(DisasContext * ctx,int xsregs,int aregs,int do_ra,int do_s0,int do_s1,int framesize)13969 static void gen_mips16_save(DisasContext *ctx,
13970                             int xsregs, int aregs,
13971                             int do_ra, int do_s0, int do_s1,
13972                             int framesize)
13973 {
13974     TCGv t0 = tcg_temp_new();
13975     TCGv t1 = tcg_temp_new();
13976     TCGv t2 = tcg_temp_new();
13977     int args, astatic;
13978 
13979     switch (aregs) {
13980     case 0:
13981     case 1:
13982     case 2:
13983     case 3:
13984     case 11:
13985         args = 0;
13986         break;
13987     case 4:
13988     case 5:
13989     case 6:
13990     case 7:
13991         args = 1;
13992         break;
13993     case 8:
13994     case 9:
13995     case 10:
13996         args = 2;
13997         break;
13998     case 12:
13999     case 13:
14000         args = 3;
14001         break;
14002     case 14:
14003         args = 4;
14004         break;
14005     default:
14006         generate_exception_end(ctx, EXCP_RI);
14007         return;
14008     }
14009 
14010     switch (args) {
14011     case 4:
14012         gen_base_offset_addr(ctx, t0, 29, 12);
14013         gen_load_gpr(t1, 7);
14014         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
14015         /* Fall through */
14016     case 3:
14017         gen_base_offset_addr(ctx, t0, 29, 8);
14018         gen_load_gpr(t1, 6);
14019         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
14020         /* Fall through */
14021     case 2:
14022         gen_base_offset_addr(ctx, t0, 29, 4);
14023         gen_load_gpr(t1, 5);
14024         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
14025         /* Fall through */
14026     case 1:
14027         gen_base_offset_addr(ctx, t0, 29, 0);
14028         gen_load_gpr(t1, 4);
14029         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
14030     }
14031 
14032     gen_load_gpr(t0, 29);
14033 
14034 #define DECR_AND_STORE(reg) do {                                 \
14035         tcg_gen_movi_tl(t2, -4);                                 \
14036         gen_op_addr_add(ctx, t0, t0, t2);                        \
14037         gen_load_gpr(t1, reg);                                   \
14038         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
14039     } while (0)
14040 
14041     if (do_ra) {
14042         DECR_AND_STORE(31);
14043     }
14044 
14045     switch (xsregs) {
14046     case 7:
14047         DECR_AND_STORE(30);
14048         /* Fall through */
14049     case 6:
14050         DECR_AND_STORE(23);
14051         /* Fall through */
14052     case 5:
14053         DECR_AND_STORE(22);
14054         /* Fall through */
14055     case 4:
14056         DECR_AND_STORE(21);
14057         /* Fall through */
14058     case 3:
14059         DECR_AND_STORE(20);
14060         /* Fall through */
14061     case 2:
14062         DECR_AND_STORE(19);
14063         /* Fall through */
14064     case 1:
14065         DECR_AND_STORE(18);
14066     }
14067 
14068     if (do_s1) {
14069         DECR_AND_STORE(17);
14070     }
14071     if (do_s0) {
14072         DECR_AND_STORE(16);
14073     }
14074 
14075     switch (aregs) {
14076     case 0:
14077     case 4:
14078     case 8:
14079     case 12:
14080     case 14:
14081         astatic = 0;
14082         break;
14083     case 1:
14084     case 5:
14085     case 9:
14086     case 13:
14087         astatic = 1;
14088         break;
14089     case 2:
14090     case 6:
14091     case 10:
14092         astatic = 2;
14093         break;
14094     case 3:
14095     case 7:
14096         astatic = 3;
14097         break;
14098     case 11:
14099         astatic = 4;
14100         break;
14101     default:
14102         generate_exception_end(ctx, EXCP_RI);
14103         return;
14104     }
14105 
14106     if (astatic > 0) {
14107         DECR_AND_STORE(7);
14108         if (astatic > 1) {
14109             DECR_AND_STORE(6);
14110             if (astatic > 2) {
14111                 DECR_AND_STORE(5);
14112                 if (astatic > 3) {
14113                     DECR_AND_STORE(4);
14114                 }
14115             }
14116         }
14117     }
14118 #undef DECR_AND_STORE
14119 
14120     tcg_gen_movi_tl(t2, -framesize);
14121     gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
14122     tcg_temp_free(t0);
14123     tcg_temp_free(t1);
14124     tcg_temp_free(t2);
14125 }
14126 
gen_mips16_restore(DisasContext * ctx,int xsregs,int aregs,int do_ra,int do_s0,int do_s1,int framesize)14127 static void gen_mips16_restore(DisasContext *ctx,
14128                                int xsregs, int aregs,
14129                                int do_ra, int do_s0, int do_s1,
14130                                int framesize)
14131 {
14132     int astatic;
14133     TCGv t0 = tcg_temp_new();
14134     TCGv t1 = tcg_temp_new();
14135     TCGv t2 = tcg_temp_new();
14136 
14137     tcg_gen_movi_tl(t2, framesize);
14138     gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
14139 
14140 #define DECR_AND_LOAD(reg) do {                            \
14141         tcg_gen_movi_tl(t2, -4);                           \
14142         gen_op_addr_add(ctx, t0, t0, t2);                  \
14143         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
14144         gen_store_gpr(t1, reg);                            \
14145     } while (0)
14146 
14147     if (do_ra) {
14148         DECR_AND_LOAD(31);
14149     }
14150 
14151     switch (xsregs) {
14152     case 7:
14153         DECR_AND_LOAD(30);
14154         /* Fall through */
14155     case 6:
14156         DECR_AND_LOAD(23);
14157         /* Fall through */
14158     case 5:
14159         DECR_AND_LOAD(22);
14160         /* Fall through */
14161     case 4:
14162         DECR_AND_LOAD(21);
14163         /* Fall through */
14164     case 3:
14165         DECR_AND_LOAD(20);
14166         /* Fall through */
14167     case 2:
14168         DECR_AND_LOAD(19);
14169         /* Fall through */
14170     case 1:
14171         DECR_AND_LOAD(18);
14172     }
14173 
14174     if (do_s1) {
14175         DECR_AND_LOAD(17);
14176     }
14177     if (do_s0) {
14178         DECR_AND_LOAD(16);
14179     }
14180 
14181     switch (aregs) {
14182     case 0:
14183     case 4:
14184     case 8:
14185     case 12:
14186     case 14:
14187         astatic = 0;
14188         break;
14189     case 1:
14190     case 5:
14191     case 9:
14192     case 13:
14193         astatic = 1;
14194         break;
14195     case 2:
14196     case 6:
14197     case 10:
14198         astatic = 2;
14199         break;
14200     case 3:
14201     case 7:
14202         astatic = 3;
14203         break;
14204     case 11:
14205         astatic = 4;
14206         break;
14207     default:
14208         generate_exception_end(ctx, EXCP_RI);
14209         return;
14210     }
14211 
14212     if (astatic > 0) {
14213         DECR_AND_LOAD(7);
14214         if (astatic > 1) {
14215             DECR_AND_LOAD(6);
14216             if (astatic > 2) {
14217                 DECR_AND_LOAD(5);
14218                 if (astatic > 3) {
14219                     DECR_AND_LOAD(4);
14220                 }
14221             }
14222         }
14223     }
14224 #undef DECR_AND_LOAD
14225 
14226     tcg_gen_movi_tl(t2, framesize);
14227     gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
14228     tcg_temp_free(t0);
14229     tcg_temp_free(t1);
14230     tcg_temp_free(t2);
14231 }
14232 
gen_addiupc(DisasContext * ctx,int rx,int imm,int is_64_bit,int extended)14233 static void gen_addiupc(DisasContext *ctx, int rx, int imm,
14234                         int is_64_bit, int extended)
14235 {
14236     TCGv t0;
14237 
14238     if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
14239         generate_exception_end(ctx, EXCP_RI);
14240         return;
14241     }
14242 
14243     t0 = tcg_temp_new();
14244 
14245     tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
14246     tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
14247     if (!is_64_bit) {
14248         tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14249     }
14250 
14251     tcg_temp_free(t0);
14252 }
14253 
gen_cache_operation(DisasContext * ctx,uint32_t op,int base,int16_t offset)14254 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
14255                                 int16_t offset)
14256 {
14257     TCGv_i32 t0 = tcg_const_i32(op);
14258     TCGv t1 = tcg_temp_new();
14259     gen_base_offset_addr(ctx, t1, base, offset);
14260     gen_helper_cache(cpu_env, t1, t0);
14261 }
14262 
14263 #if defined(TARGET_MIPS64)
decode_i64_mips16(DisasContext * ctx,int ry,int funct,int16_t offset,int extended)14264 static void decode_i64_mips16(DisasContext *ctx,
14265                               int ry, int funct, int16_t offset,
14266                               int extended)
14267 {
14268     switch (funct) {
14269     case I64_LDSP:
14270         check_insn(ctx, ISA_MIPS3);
14271         check_mips_64(ctx);
14272         offset = extended ? offset : offset << 3;
14273         gen_ld(ctx, OPC_LD, ry, 29, offset);
14274         break;
14275     case I64_SDSP:
14276         check_insn(ctx, ISA_MIPS3);
14277         check_mips_64(ctx);
14278         offset = extended ? offset : offset << 3;
14279         gen_st(ctx, OPC_SD, ry, 29, offset);
14280         break;
14281     case I64_SDRASP:
14282         check_insn(ctx, ISA_MIPS3);
14283         check_mips_64(ctx);
14284         offset = extended ? offset : (ctx->opcode & 0xff) << 3;
14285         gen_st(ctx, OPC_SD, 31, 29, offset);
14286         break;
14287     case I64_DADJSP:
14288         check_insn(ctx, ISA_MIPS3);
14289         check_mips_64(ctx);
14290         offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
14291         gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
14292         break;
14293     case I64_LDPC:
14294         check_insn(ctx, ISA_MIPS3);
14295         check_mips_64(ctx);
14296         if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
14297             generate_exception_end(ctx, EXCP_RI);
14298         } else {
14299             offset = extended ? offset : offset << 3;
14300             gen_ld(ctx, OPC_LDPC, ry, 0, offset);
14301         }
14302         break;
14303     case I64_DADDIU5:
14304         check_insn(ctx, ISA_MIPS3);
14305         check_mips_64(ctx);
14306         offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
14307         gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
14308         break;
14309     case I64_DADDIUPC:
14310         check_insn(ctx, ISA_MIPS3);
14311         check_mips_64(ctx);
14312         offset = extended ? offset : offset << 2;
14313         gen_addiupc(ctx, ry, offset, 1, extended);
14314         break;
14315     case I64_DADDIUSP:
14316         check_insn(ctx, ISA_MIPS3);
14317         check_mips_64(ctx);
14318         offset = extended ? offset : offset << 2;
14319         gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
14320         break;
14321     }
14322 }
14323 #endif
14324 
decode_extended_mips16_opc(CPUMIPSState * env,DisasContext * ctx)14325 static int decode_extended_mips16_opc(CPUMIPSState *env, DisasContext *ctx)
14326 {
14327     int extend = cpu_lduw_code(env, ctx->base.pc_next + 2);
14328     int op, rx, ry, funct, sa;
14329     int16_t imm, offset;
14330 
14331     ctx->opcode = (ctx->opcode << 16) | extend;
14332     op = (ctx->opcode >> 11) & 0x1f;
14333     sa = (ctx->opcode >> 22) & 0x1f;
14334     funct = (ctx->opcode >> 8) & 0x7;
14335     rx = xlat((ctx->opcode >> 8) & 0x7);
14336     ry = xlat((ctx->opcode >> 5) & 0x7);
14337     offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
14338                               | ((ctx->opcode >> 21) & 0x3f) << 5
14339                               | (ctx->opcode & 0x1f));
14340 
14341     /*
14342      * The extended opcodes cleverly reuse the opcodes from their 16-bit
14343      * counterparts.
14344      */
14345     switch (op) {
14346     case M16_OPC_ADDIUSP:
14347         gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
14348         break;
14349     case M16_OPC_ADDIUPC:
14350         gen_addiupc(ctx, rx, imm, 0, 1);
14351         break;
14352     case M16_OPC_B:
14353         gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
14354         /* No delay slot, so just process as a normal instruction */
14355         break;
14356     case M16_OPC_BEQZ:
14357         gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
14358         /* No delay slot, so just process as a normal instruction */
14359         break;
14360     case M16_OPC_BNEQZ:
14361         gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
14362         /* No delay slot, so just process as a normal instruction */
14363         break;
14364     case M16_OPC_SHIFT:
14365         switch (ctx->opcode & 0x3) {
14366         case 0x0:
14367             gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
14368             break;
14369         case 0x1:
14370 #if defined(TARGET_MIPS64)
14371             check_mips_64(ctx);
14372             gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
14373 #else
14374             generate_exception_end(ctx, EXCP_RI);
14375 #endif
14376             break;
14377         case 0x2:
14378             gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
14379             break;
14380         case 0x3:
14381             gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
14382             break;
14383         }
14384         break;
14385 #if defined(TARGET_MIPS64)
14386     case M16_OPC_LD:
14387         check_insn(ctx, ISA_MIPS3);
14388         check_mips_64(ctx);
14389         gen_ld(ctx, OPC_LD, ry, rx, offset);
14390         break;
14391 #endif
14392     case M16_OPC_RRIA:
14393         imm = ctx->opcode & 0xf;
14394         imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
14395         imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
14396         imm = (int16_t) (imm << 1) >> 1;
14397         if ((ctx->opcode >> 4) & 0x1) {
14398 #if defined(TARGET_MIPS64)
14399             check_mips_64(ctx);
14400             gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
14401 #else
14402             generate_exception_end(ctx, EXCP_RI);
14403 #endif
14404         } else {
14405             gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
14406         }
14407         break;
14408     case M16_OPC_ADDIU8:
14409         gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
14410         break;
14411     case M16_OPC_SLTI:
14412         gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
14413         break;
14414     case M16_OPC_SLTIU:
14415         gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
14416         break;
14417     case M16_OPC_I8:
14418         switch (funct) {
14419         case I8_BTEQZ:
14420             gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
14421             break;
14422         case I8_BTNEZ:
14423             gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
14424             break;
14425         case I8_SWRASP:
14426             gen_st(ctx, OPC_SW, 31, 29, imm);
14427             break;
14428         case I8_ADJSP:
14429             gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
14430             break;
14431         case I8_SVRS:
14432             check_insn(ctx, ISA_MIPS32);
14433             {
14434                 int xsregs = (ctx->opcode >> 24) & 0x7;
14435                 int aregs = (ctx->opcode >> 16) & 0xf;
14436                 int do_ra = (ctx->opcode >> 6) & 0x1;
14437                 int do_s0 = (ctx->opcode >> 5) & 0x1;
14438                 int do_s1 = (ctx->opcode >> 4) & 0x1;
14439                 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
14440                                  | (ctx->opcode & 0xf)) << 3;
14441 
14442                 if (ctx->opcode & (1 << 7)) {
14443                     gen_mips16_save(ctx, xsregs, aregs,
14444                                     do_ra, do_s0, do_s1,
14445                                     framesize);
14446                 } else {
14447                     gen_mips16_restore(ctx, xsregs, aregs,
14448                                        do_ra, do_s0, do_s1,
14449                                        framesize);
14450                 }
14451             }
14452             break;
14453         default:
14454             generate_exception_end(ctx, EXCP_RI);
14455             break;
14456         }
14457         break;
14458     case M16_OPC_LI:
14459         tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
14460         break;
14461     case M16_OPC_CMPI:
14462         tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
14463         break;
14464 #if defined(TARGET_MIPS64)
14465     case M16_OPC_SD:
14466         check_insn(ctx, ISA_MIPS3);
14467         check_mips_64(ctx);
14468         gen_st(ctx, OPC_SD, ry, rx, offset);
14469         break;
14470 #endif
14471     case M16_OPC_LB:
14472         gen_ld(ctx, OPC_LB, ry, rx, offset);
14473         break;
14474     case M16_OPC_LH:
14475         gen_ld(ctx, OPC_LH, ry, rx, offset);
14476         break;
14477     case M16_OPC_LWSP:
14478         gen_ld(ctx, OPC_LW, rx, 29, offset);
14479         break;
14480     case M16_OPC_LW:
14481         gen_ld(ctx, OPC_LW, ry, rx, offset);
14482         break;
14483     case M16_OPC_LBU:
14484         gen_ld(ctx, OPC_LBU, ry, rx, offset);
14485         break;
14486     case M16_OPC_LHU:
14487         gen_ld(ctx, OPC_LHU, ry, rx, offset);
14488         break;
14489     case M16_OPC_LWPC:
14490         gen_ld(ctx, OPC_LWPC, rx, 0, offset);
14491         break;
14492 #if defined(TARGET_MIPS64)
14493     case M16_OPC_LWU:
14494         check_insn(ctx, ISA_MIPS3);
14495         check_mips_64(ctx);
14496         gen_ld(ctx, OPC_LWU, ry, rx, offset);
14497         break;
14498 #endif
14499     case M16_OPC_SB:
14500         gen_st(ctx, OPC_SB, ry, rx, offset);
14501         break;
14502     case M16_OPC_SH:
14503         gen_st(ctx, OPC_SH, ry, rx, offset);
14504         break;
14505     case M16_OPC_SWSP:
14506         gen_st(ctx, OPC_SW, rx, 29, offset);
14507         break;
14508     case M16_OPC_SW:
14509         gen_st(ctx, OPC_SW, ry, rx, offset);
14510         break;
14511 #if defined(TARGET_MIPS64)
14512     case M16_OPC_I64:
14513         decode_i64_mips16(ctx, ry, funct, offset, 1);
14514         break;
14515 #endif
14516     default:
14517         generate_exception_end(ctx, EXCP_RI);
14518         break;
14519     }
14520 
14521     return 4;
14522 }
14523 
is_uhi(int sdbbp_code)14524 static inline bool is_uhi(int sdbbp_code)
14525 {
14526 #ifdef CONFIG_USER_ONLY
14527     return false;
14528 #else
14529     return semihosting_enabled() && sdbbp_code == 1;
14530 #endif
14531 }
14532 
14533 #ifdef CONFIG_USER_ONLY
14534 /* The above should dead-code away any calls to this..*/
gen_helper_do_semihosting(void * env)14535 static inline void gen_helper_do_semihosting(void *env)
14536 {
14537     g_assert_not_reached();
14538 }
14539 #endif
14540 
decode_mips16_opc(CPUMIPSState * env,DisasContext * ctx)14541 static int decode_mips16_opc(CPUMIPSState *env, DisasContext *ctx)
14542 {
14543     int rx, ry;
14544     int sa;
14545     int op, cnvt_op, op1, offset;
14546     int funct;
14547     int n_bytes;
14548 
14549     op = (ctx->opcode >> 11) & 0x1f;
14550     sa = (ctx->opcode >> 2) & 0x7;
14551     sa = sa == 0 ? 8 : sa;
14552     rx = xlat((ctx->opcode >> 8) & 0x7);
14553     cnvt_op = (ctx->opcode >> 5) & 0x7;
14554     ry = xlat((ctx->opcode >> 5) & 0x7);
14555     op1 = offset = ctx->opcode & 0x1f;
14556 
14557     n_bytes = 2;
14558 
14559     switch (op) {
14560     case M16_OPC_ADDIUSP:
14561         {
14562             int16_t imm = ((uint8_t) ctx->opcode) << 2;
14563 
14564             gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
14565         }
14566         break;
14567     case M16_OPC_ADDIUPC:
14568         gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
14569         break;
14570     case M16_OPC_B:
14571         offset = (ctx->opcode & 0x7ff) << 1;
14572         offset = (int16_t)(offset << 4) >> 4;
14573         gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
14574         /* No delay slot, so just process as a normal instruction */
14575         break;
14576     case M16_OPC_JAL:
14577         offset = cpu_lduw_code(env, ctx->base.pc_next + 2);
14578         offset = (((ctx->opcode & 0x1f) << 21)
14579                   | ((ctx->opcode >> 5) & 0x1f) << 16
14580                   | offset) << 2;
14581         op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
14582         gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
14583         n_bytes = 4;
14584         break;
14585     case M16_OPC_BEQZ:
14586         gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
14587                            ((int8_t)ctx->opcode) << 1, 0);
14588         /* No delay slot, so just process as a normal instruction */
14589         break;
14590     case M16_OPC_BNEQZ:
14591         gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
14592                            ((int8_t)ctx->opcode) << 1, 0);
14593         /* No delay slot, so just process as a normal instruction */
14594         break;
14595     case M16_OPC_SHIFT:
14596         switch (ctx->opcode & 0x3) {
14597         case 0x0:
14598             gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
14599             break;
14600         case 0x1:
14601 #if defined(TARGET_MIPS64)
14602             check_insn(ctx, ISA_MIPS3);
14603             check_mips_64(ctx);
14604             gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
14605 #else
14606             generate_exception_end(ctx, EXCP_RI);
14607 #endif
14608             break;
14609         case 0x2:
14610             gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
14611             break;
14612         case 0x3:
14613             gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
14614             break;
14615         }
14616         break;
14617 #if defined(TARGET_MIPS64)
14618     case M16_OPC_LD:
14619         check_insn(ctx, ISA_MIPS3);
14620         check_mips_64(ctx);
14621         gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
14622         break;
14623 #endif
14624     case M16_OPC_RRIA:
14625         {
14626             int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
14627 
14628             if ((ctx->opcode >> 4) & 1) {
14629 #if defined(TARGET_MIPS64)
14630                 check_insn(ctx, ISA_MIPS3);
14631                 check_mips_64(ctx);
14632                 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
14633 #else
14634                 generate_exception_end(ctx, EXCP_RI);
14635 #endif
14636             } else {
14637                 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
14638             }
14639         }
14640         break;
14641     case M16_OPC_ADDIU8:
14642         {
14643             int16_t imm = (int8_t) ctx->opcode;
14644 
14645             gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
14646         }
14647         break;
14648     case M16_OPC_SLTI:
14649         {
14650             int16_t imm = (uint8_t) ctx->opcode;
14651             gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
14652         }
14653         break;
14654     case M16_OPC_SLTIU:
14655         {
14656             int16_t imm = (uint8_t) ctx->opcode;
14657             gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
14658         }
14659         break;
14660     case M16_OPC_I8:
14661         {
14662             int reg32;
14663 
14664             funct = (ctx->opcode >> 8) & 0x7;
14665             switch (funct) {
14666             case I8_BTEQZ:
14667                 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
14668                                    ((int8_t)ctx->opcode) << 1, 0);
14669                 break;
14670             case I8_BTNEZ:
14671                 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
14672                                    ((int8_t)ctx->opcode) << 1, 0);
14673                 break;
14674             case I8_SWRASP:
14675                 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
14676                 break;
14677             case I8_ADJSP:
14678                 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
14679                               ((int8_t)ctx->opcode) << 3);
14680                 break;
14681             case I8_SVRS:
14682                 check_insn(ctx, ISA_MIPS32);
14683                 {
14684                     int do_ra = ctx->opcode & (1 << 6);
14685                     int do_s0 = ctx->opcode & (1 << 5);
14686                     int do_s1 = ctx->opcode & (1 << 4);
14687                     int framesize = ctx->opcode & 0xf;
14688 
14689                     if (framesize == 0) {
14690                         framesize = 128;
14691                     } else {
14692                         framesize = framesize << 3;
14693                     }
14694 
14695                     if (ctx->opcode & (1 << 7)) {
14696                         gen_mips16_save(ctx, 0, 0,
14697                                         do_ra, do_s0, do_s1, framesize);
14698                     } else {
14699                         gen_mips16_restore(ctx, 0, 0,
14700                                            do_ra, do_s0, do_s1, framesize);
14701                     }
14702                 }
14703                 break;
14704             case I8_MOV32R:
14705                 {
14706                     int rz = xlat(ctx->opcode & 0x7);
14707 
14708                     reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
14709                         ((ctx->opcode >> 5) & 0x7);
14710                     gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
14711                 }
14712                 break;
14713             case I8_MOVR32:
14714                 reg32 = ctx->opcode & 0x1f;
14715                 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
14716                 break;
14717             default:
14718                 generate_exception_end(ctx, EXCP_RI);
14719                 break;
14720             }
14721         }
14722         break;
14723     case M16_OPC_LI:
14724         {
14725             int16_t imm = (uint8_t) ctx->opcode;
14726 
14727             gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
14728         }
14729         break;
14730     case M16_OPC_CMPI:
14731         {
14732             int16_t imm = (uint8_t) ctx->opcode;
14733             gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
14734         }
14735         break;
14736 #if defined(TARGET_MIPS64)
14737     case M16_OPC_SD:
14738         check_insn(ctx, ISA_MIPS3);
14739         check_mips_64(ctx);
14740         gen_st(ctx, OPC_SD, ry, rx, offset << 3);
14741         break;
14742 #endif
14743     case M16_OPC_LB:
14744         gen_ld(ctx, OPC_LB, ry, rx, offset);
14745         break;
14746     case M16_OPC_LH:
14747         gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
14748         break;
14749     case M16_OPC_LWSP:
14750         gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
14751         break;
14752     case M16_OPC_LW:
14753         gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
14754         break;
14755     case M16_OPC_LBU:
14756         gen_ld(ctx, OPC_LBU, ry, rx, offset);
14757         break;
14758     case M16_OPC_LHU:
14759         gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
14760         break;
14761     case M16_OPC_LWPC:
14762         gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
14763         break;
14764 #if defined(TARGET_MIPS64)
14765     case M16_OPC_LWU:
14766         check_insn(ctx, ISA_MIPS3);
14767         check_mips_64(ctx);
14768         gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
14769         break;
14770 #endif
14771     case M16_OPC_SB:
14772         gen_st(ctx, OPC_SB, ry, rx, offset);
14773         break;
14774     case M16_OPC_SH:
14775         gen_st(ctx, OPC_SH, ry, rx, offset << 1);
14776         break;
14777     case M16_OPC_SWSP:
14778         gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
14779         break;
14780     case M16_OPC_SW:
14781         gen_st(ctx, OPC_SW, ry, rx, offset << 2);
14782         break;
14783     case M16_OPC_RRR:
14784         {
14785             int rz = xlat((ctx->opcode >> 2) & 0x7);
14786             int mips32_op;
14787 
14788             switch (ctx->opcode & 0x3) {
14789             case RRR_ADDU:
14790                 mips32_op = OPC_ADDU;
14791                 break;
14792             case RRR_SUBU:
14793                 mips32_op = OPC_SUBU;
14794                 break;
14795 #if defined(TARGET_MIPS64)
14796             case RRR_DADDU:
14797                 mips32_op = OPC_DADDU;
14798                 check_insn(ctx, ISA_MIPS3);
14799                 check_mips_64(ctx);
14800                 break;
14801             case RRR_DSUBU:
14802                 mips32_op = OPC_DSUBU;
14803                 check_insn(ctx, ISA_MIPS3);
14804                 check_mips_64(ctx);
14805                 break;
14806 #endif
14807             default:
14808                 generate_exception_end(ctx, EXCP_RI);
14809                 goto done;
14810             }
14811 
14812             gen_arith(ctx, mips32_op, rz, rx, ry);
14813         done:
14814             ;
14815         }
14816         break;
14817     case M16_OPC_RR:
14818         switch (op1) {
14819         case RR_JR:
14820             {
14821                 int nd = (ctx->opcode >> 7) & 0x1;
14822                 int link = (ctx->opcode >> 6) & 0x1;
14823                 int ra = (ctx->opcode >> 5) & 0x1;
14824 
14825                 if (nd) {
14826                     check_insn(ctx, ISA_MIPS32);
14827                 }
14828 
14829                 if (link) {
14830                     op = OPC_JALR;
14831                 } else {
14832                     op = OPC_JR;
14833                 }
14834 
14835                 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
14836                                    (nd ? 0 : 2));
14837             }
14838             break;
14839         case RR_SDBBP:
14840             if (is_uhi(extract32(ctx->opcode, 5, 6))) {
14841                 gen_helper_do_semihosting(cpu_env);
14842             } else {
14843                 /*
14844                  * XXX: not clear which exception should be raised
14845                  *      when in debug mode...
14846                  */
14847                 check_insn(ctx, ISA_MIPS32);
14848                 generate_exception_end(ctx, EXCP_DBp);
14849             }
14850             break;
14851         case RR_SLT:
14852             gen_slt(ctx, OPC_SLT, 24, rx, ry);
14853             break;
14854         case RR_SLTU:
14855             gen_slt(ctx, OPC_SLTU, 24, rx, ry);
14856             break;
14857         case RR_BREAK:
14858             generate_exception_end(ctx, EXCP_BREAK);
14859             break;
14860         case RR_SLLV:
14861             gen_shift(ctx, OPC_SLLV, ry, rx, ry);
14862             break;
14863         case RR_SRLV:
14864             gen_shift(ctx, OPC_SRLV, ry, rx, ry);
14865             break;
14866         case RR_SRAV:
14867             gen_shift(ctx, OPC_SRAV, ry, rx, ry);
14868             break;
14869 #if defined(TARGET_MIPS64)
14870         case RR_DSRL:
14871             check_insn(ctx, ISA_MIPS3);
14872             check_mips_64(ctx);
14873             gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
14874             break;
14875 #endif
14876         case RR_CMP:
14877             gen_logic(ctx, OPC_XOR, 24, rx, ry);
14878             break;
14879         case RR_NEG:
14880             gen_arith(ctx, OPC_SUBU, rx, 0, ry);
14881             break;
14882         case RR_AND:
14883             gen_logic(ctx, OPC_AND, rx, rx, ry);
14884             break;
14885         case RR_OR:
14886             gen_logic(ctx, OPC_OR, rx, rx, ry);
14887             break;
14888         case RR_XOR:
14889             gen_logic(ctx, OPC_XOR, rx, rx, ry);
14890             break;
14891         case RR_NOT:
14892             gen_logic(ctx, OPC_NOR, rx, ry, 0);
14893             break;
14894         case RR_MFHI:
14895             gen_HILO(ctx, OPC_MFHI, 0, rx);
14896             break;
14897         case RR_CNVT:
14898             check_insn(ctx, ISA_MIPS32);
14899             switch (cnvt_op) {
14900             case RR_RY_CNVT_ZEB:
14901                 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14902                 break;
14903             case RR_RY_CNVT_ZEH:
14904                 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14905                 break;
14906             case RR_RY_CNVT_SEB:
14907                 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14908                 break;
14909             case RR_RY_CNVT_SEH:
14910                 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14911                 break;
14912 #if defined(TARGET_MIPS64)
14913             case RR_RY_CNVT_ZEW:
14914                 check_insn(ctx, ISA_MIPS64);
14915                 check_mips_64(ctx);
14916                 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14917                 break;
14918             case RR_RY_CNVT_SEW:
14919                 check_insn(ctx, ISA_MIPS64);
14920                 check_mips_64(ctx);
14921                 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14922                 break;
14923 #endif
14924             default:
14925                 generate_exception_end(ctx, EXCP_RI);
14926                 break;
14927             }
14928             break;
14929         case RR_MFLO:
14930             gen_HILO(ctx, OPC_MFLO, 0, rx);
14931             break;
14932 #if defined(TARGET_MIPS64)
14933         case RR_DSRA:
14934             check_insn(ctx, ISA_MIPS3);
14935             check_mips_64(ctx);
14936             gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
14937             break;
14938         case RR_DSLLV:
14939             check_insn(ctx, ISA_MIPS3);
14940             check_mips_64(ctx);
14941             gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
14942             break;
14943         case RR_DSRLV:
14944             check_insn(ctx, ISA_MIPS3);
14945             check_mips_64(ctx);
14946             gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
14947             break;
14948         case RR_DSRAV:
14949             check_insn(ctx, ISA_MIPS3);
14950             check_mips_64(ctx);
14951             gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
14952             break;
14953 #endif
14954         case RR_MULT:
14955             gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
14956             break;
14957         case RR_MULTU:
14958             gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
14959             break;
14960         case RR_DIV:
14961             gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
14962             break;
14963         case RR_DIVU:
14964             gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
14965             break;
14966 #if defined(TARGET_MIPS64)
14967         case RR_DMULT:
14968             check_insn(ctx, ISA_MIPS3);
14969             check_mips_64(ctx);
14970             gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
14971             break;
14972         case RR_DMULTU:
14973             check_insn(ctx, ISA_MIPS3);
14974             check_mips_64(ctx);
14975             gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
14976             break;
14977         case RR_DDIV:
14978             check_insn(ctx, ISA_MIPS3);
14979             check_mips_64(ctx);
14980             gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
14981             break;
14982         case RR_DDIVU:
14983             check_insn(ctx, ISA_MIPS3);
14984             check_mips_64(ctx);
14985             gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
14986             break;
14987 #endif
14988         default:
14989             generate_exception_end(ctx, EXCP_RI);
14990             break;
14991         }
14992         break;
14993     case M16_OPC_EXTEND:
14994         decode_extended_mips16_opc(env, ctx);
14995         n_bytes = 4;
14996         break;
14997 #if defined(TARGET_MIPS64)
14998     case M16_OPC_I64:
14999         funct = (ctx->opcode >> 8) & 0x7;
15000         decode_i64_mips16(ctx, ry, funct, offset, 0);
15001         break;
15002 #endif
15003     default:
15004         generate_exception_end(ctx, EXCP_RI);
15005         break;
15006     }
15007 
15008     return n_bytes;
15009 }
15010 
15011 /* microMIPS extension to MIPS32/MIPS64 */
15012 
15013 /*
15014  * microMIPS32/microMIPS64 major opcodes
15015  *
15016  * 1. MIPS Architecture for Programmers Volume II-B:
15017  *      The microMIPS32 Instruction Set (Revision 3.05)
15018  *
15019  *    Table 6.2 microMIPS32 Encoding of Major Opcode Field
15020  *
15021  * 2. MIPS Architecture For Programmers Volume II-A:
15022  *      The MIPS64 Instruction Set (Revision 3.51)
15023  */
15024 
15025 enum {
15026     POOL32A = 0x00,
15027     POOL16A = 0x01,
15028     LBU16 = 0x02,
15029     MOVE16 = 0x03,
15030     ADDI32 = 0x04,
15031     R6_LUI = 0x04,
15032     AUI = 0x04,
15033     LBU32 = 0x05,
15034     SB32 = 0x06,
15035     LB32 = 0x07,
15036 
15037     POOL32B = 0x08,
15038     POOL16B = 0x09,
15039     LHU16 = 0x0a,
15040     ANDI16 = 0x0b,
15041     ADDIU32 = 0x0c,
15042     LHU32 = 0x0d,
15043     SH32 = 0x0e,
15044     LH32 = 0x0f,
15045 
15046     POOL32I = 0x10,
15047     POOL16C = 0x11,
15048     LWSP16 = 0x12,
15049     POOL16D = 0x13,
15050     ORI32 = 0x14,
15051     POOL32F = 0x15,
15052     POOL32S = 0x16,  /* MIPS64 */
15053     DADDIU32 = 0x17, /* MIPS64 */
15054 
15055     POOL32C = 0x18,
15056     LWGP16 = 0x19,
15057     LW16 = 0x1a,
15058     POOL16E = 0x1b,
15059     XORI32 = 0x1c,
15060     JALS32 = 0x1d,
15061     BOVC = 0x1d,
15062     BEQC = 0x1d,
15063     BEQZALC = 0x1d,
15064     ADDIUPC = 0x1e,
15065     PCREL = 0x1e,
15066     BNVC = 0x1f,
15067     BNEC = 0x1f,
15068     BNEZALC = 0x1f,
15069 
15070     R6_BEQZC = 0x20,
15071     JIC = 0x20,
15072     POOL16F = 0x21,
15073     SB16 = 0x22,
15074     BEQZ16 = 0x23,
15075     BEQZC16 = 0x23,
15076     SLTI32 = 0x24,
15077     BEQ32 = 0x25,
15078     BC = 0x25,
15079     SWC132 = 0x26,
15080     LWC132 = 0x27,
15081 
15082     /* 0x29 is reserved */
15083     RES_29 = 0x29,
15084     R6_BNEZC = 0x28,
15085     JIALC = 0x28,
15086     SH16 = 0x2a,
15087     BNEZ16 = 0x2b,
15088     BNEZC16 = 0x2b,
15089     SLTIU32 = 0x2c,
15090     BNE32 = 0x2d,
15091     BALC = 0x2d,
15092     SDC132 = 0x2e,
15093     LDC132 = 0x2f,
15094 
15095     /* 0x31 is reserved */
15096     RES_31 = 0x31,
15097     BLEZALC = 0x30,
15098     BGEZALC = 0x30,
15099     BGEUC = 0x30,
15100     SWSP16 = 0x32,
15101     B16 = 0x33,
15102     BC16 = 0x33,
15103     ANDI32 = 0x34,
15104     J32 = 0x35,
15105     BGTZC = 0x35,
15106     BLTZC = 0x35,
15107     BLTC = 0x35,
15108     SD32 = 0x36, /* MIPS64 */
15109     LD32 = 0x37, /* MIPS64 */
15110 
15111     /* 0x39 is reserved */
15112     RES_39 = 0x39,
15113     BGTZALC = 0x38,
15114     BLTZALC = 0x38,
15115     BLTUC = 0x38,
15116     SW16 = 0x3a,
15117     LI16 = 0x3b,
15118     JALX32 = 0x3c,
15119     JAL32 = 0x3d,
15120     BLEZC = 0x3d,
15121     BGEZC = 0x3d,
15122     BGEC = 0x3d,
15123     SW32 = 0x3e,
15124     LW32 = 0x3f
15125 };
15126 
15127 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
15128 enum {
15129     ADDIUPC_00 = 0x00,
15130     ADDIUPC_01 = 0x01,
15131     ADDIUPC_02 = 0x02,
15132     ADDIUPC_03 = 0x03,
15133     ADDIUPC_04 = 0x04,
15134     ADDIUPC_05 = 0x05,
15135     ADDIUPC_06 = 0x06,
15136     ADDIUPC_07 = 0x07,
15137     AUIPC = 0x1e,
15138     ALUIPC = 0x1f,
15139     LWPC_08 = 0x08,
15140     LWPC_09 = 0x09,
15141     LWPC_0A = 0x0A,
15142     LWPC_0B = 0x0B,
15143     LWPC_0C = 0x0C,
15144     LWPC_0D = 0x0D,
15145     LWPC_0E = 0x0E,
15146     LWPC_0F = 0x0F,
15147 };
15148 
15149 /* POOL32A encoding of minor opcode field */
15150 
15151 enum {
15152     /*
15153      * These opcodes are distinguished only by bits 9..6; those bits are
15154      * what are recorded below.
15155      */
15156     SLL32 = 0x0,
15157     SRL32 = 0x1,
15158     SRA = 0x2,
15159     ROTR = 0x3,
15160     SELEQZ = 0x5,
15161     SELNEZ = 0x6,
15162     R6_RDHWR = 0x7,
15163 
15164     SLLV = 0x0,
15165     SRLV = 0x1,
15166     SRAV = 0x2,
15167     ROTRV = 0x3,
15168     ADD = 0x4,
15169     ADDU32 = 0x5,
15170     SUB = 0x6,
15171     SUBU32 = 0x7,
15172     MUL = 0x8,
15173     AND = 0x9,
15174     OR32 = 0xa,
15175     NOR = 0xb,
15176     XOR32 = 0xc,
15177     SLT = 0xd,
15178     SLTU = 0xe,
15179 
15180     MOVN = 0x0,
15181     R6_MUL  = 0x0,
15182     MOVZ = 0x1,
15183     MUH  = 0x1,
15184     MULU = 0x2,
15185     MUHU = 0x3,
15186     LWXS = 0x4,
15187     R6_DIV  = 0x4,
15188     MOD  = 0x5,
15189     R6_DIVU = 0x6,
15190     MODU = 0x7,
15191 
15192     /* The following can be distinguished by their lower 6 bits. */
15193     BREAK32 = 0x07,
15194     INS = 0x0c,
15195     LSA = 0x0f,
15196     ALIGN = 0x1f,
15197     EXT = 0x2c,
15198     POOL32AXF = 0x3c,
15199     SIGRIE = 0x3f
15200 };
15201 
15202 /* POOL32AXF encoding of minor opcode field extension */
15203 
15204 /*
15205  * 1. MIPS Architecture for Programmers Volume II-B:
15206  *      The microMIPS32 Instruction Set (Revision 3.05)
15207  *
15208  *    Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
15209  *
15210  * 2. MIPS Architecture for Programmers VolumeIV-e:
15211  *      The MIPS DSP Application-Specific Extension
15212  *        to the microMIPS32 Architecture (Revision 2.34)
15213  *
15214  *    Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
15215  */
15216 
15217 enum {
15218     /* bits 11..6 */
15219     TEQ = 0x00,
15220     TGE = 0x08,
15221     TGEU = 0x10,
15222     TLT = 0x20,
15223     TLTU = 0x28,
15224     TNE = 0x30,
15225 
15226     MFC0 = 0x03,
15227     MTC0 = 0x0b,
15228 
15229     /* begin of microMIPS32 DSP */
15230 
15231     /* bits 13..12 for 0x01 */
15232     MFHI_ACC = 0x0,
15233     MFLO_ACC = 0x1,
15234     MTHI_ACC = 0x2,
15235     MTLO_ACC = 0x3,
15236 
15237     /* bits 13..12 for 0x2a */
15238     MADD_ACC = 0x0,
15239     MADDU_ACC = 0x1,
15240     MSUB_ACC = 0x2,
15241     MSUBU_ACC = 0x3,
15242 
15243     /* bits 13..12 for 0x32 */
15244     MULT_ACC = 0x0,
15245     MULTU_ACC = 0x1,
15246 
15247     /* end of microMIPS32 DSP */
15248 
15249     /* bits 15..12 for 0x2c */
15250     BITSWAP = 0x0,
15251     SEB = 0x2,
15252     SEH = 0x3,
15253     CLO = 0x4,
15254     CLZ = 0x5,
15255     RDHWR = 0x6,
15256     WSBH = 0x7,
15257     MULT = 0x8,
15258     MULTU = 0x9,
15259     DIV = 0xa,
15260     DIVU = 0xb,
15261     MADD = 0xc,
15262     MADDU = 0xd,
15263     MSUB = 0xe,
15264     MSUBU = 0xf,
15265 
15266     /* bits 15..12 for 0x34 */
15267     MFC2 = 0x4,
15268     MTC2 = 0x5,
15269     MFHC2 = 0x8,
15270     MTHC2 = 0x9,
15271     CFC2 = 0xc,
15272     CTC2 = 0xd,
15273 
15274     /* bits 15..12 for 0x3c */
15275     JALR = 0x0,
15276     JR = 0x0,                   /* alias */
15277     JALRC = 0x0,
15278     JRC = 0x0,
15279     JALR_HB = 0x1,
15280     JALRC_HB = 0x1,
15281     JALRS = 0x4,
15282     JALRS_HB = 0x5,
15283 
15284     /* bits 15..12 for 0x05 */
15285     RDPGPR = 0xe,
15286     WRPGPR = 0xf,
15287 
15288     /* bits 15..12 for 0x0d */
15289     TLBP = 0x0,
15290     TLBR = 0x1,
15291     TLBWI = 0x2,
15292     TLBWR = 0x3,
15293     TLBINV = 0x4,
15294     TLBINVF = 0x5,
15295     WAIT = 0x9,
15296     IRET = 0xd,
15297     DERET = 0xe,
15298     ERET = 0xf,
15299 
15300     /* bits 15..12 for 0x15 */
15301     DMT = 0x0,
15302     DVPE = 0x1,
15303     EMT = 0x2,
15304     EVPE = 0x3,
15305 
15306     /* bits 15..12 for 0x1d */
15307     DI = 0x4,
15308     EI = 0x5,
15309 
15310     /* bits 15..12 for 0x2d */
15311     SYNC = 0x6,
15312     SYSCALL = 0x8,
15313     SDBBP = 0xd,
15314 
15315     /* bits 15..12 for 0x35 */
15316     MFHI32 = 0x0,
15317     MFLO32 = 0x1,
15318     MTHI32 = 0x2,
15319     MTLO32 = 0x3,
15320 };
15321 
15322 /* POOL32B encoding of minor opcode field (bits 15..12) */
15323 
15324 enum {
15325     LWC2 = 0x0,
15326     LWP = 0x1,
15327     LDP = 0x4,
15328     LWM32 = 0x5,
15329     CACHE = 0x6,
15330     LDM = 0x7,
15331     SWC2 = 0x8,
15332     SWP = 0x9,
15333     SDP = 0xc,
15334     SWM32 = 0xd,
15335     SDM = 0xf
15336 };
15337 
15338 /* POOL32C encoding of minor opcode field (bits 15..12) */
15339 
15340 enum {
15341     LWL = 0x0,
15342     SWL = 0x8,
15343     LWR = 0x1,
15344     SWR = 0x9,
15345     PREF = 0x2,
15346     ST_EVA = 0xa,
15347     LL = 0x3,
15348     SC = 0xb,
15349     LDL = 0x4,
15350     SDL = 0xc,
15351     LDR = 0x5,
15352     SDR = 0xd,
15353     LD_EVA = 0x6,
15354     LWU = 0xe,
15355     LLD = 0x7,
15356     SCD = 0xf
15357 };
15358 
15359 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
15360 
15361 enum {
15362     LBUE = 0x0,
15363     LHUE = 0x1,
15364     LWLE = 0x2,
15365     LWRE = 0x3,
15366     LBE = 0x4,
15367     LHE = 0x5,
15368     LLE = 0x6,
15369     LWE = 0x7,
15370 };
15371 
15372 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
15373 
15374 enum {
15375     SWLE = 0x0,
15376     SWRE = 0x1,
15377     PREFE = 0x2,
15378     CACHEE = 0x3,
15379     SBE = 0x4,
15380     SHE = 0x5,
15381     SCE = 0x6,
15382     SWE = 0x7,
15383 };
15384 
15385 /* POOL32F encoding of minor opcode field (bits 5..0) */
15386 
15387 enum {
15388     /* These are the bit 7..6 values */
15389     ADD_FMT = 0x0,
15390 
15391     SUB_FMT = 0x1,
15392 
15393     MUL_FMT = 0x2,
15394 
15395     DIV_FMT = 0x3,
15396 
15397     /* These are the bit 8..6 values */
15398     MOVN_FMT = 0x0,
15399     RSQRT2_FMT = 0x0,
15400     MOVF_FMT = 0x0,
15401     RINT_FMT = 0x0,
15402     SELNEZ_FMT = 0x0,
15403 
15404     MOVZ_FMT = 0x1,
15405     LWXC1 = 0x1,
15406     MOVT_FMT = 0x1,
15407     CLASS_FMT = 0x1,
15408     SELEQZ_FMT = 0x1,
15409 
15410     PLL_PS = 0x2,
15411     SWXC1 = 0x2,
15412     SEL_FMT = 0x2,
15413 
15414     PLU_PS = 0x3,
15415     LDXC1 = 0x3,
15416 
15417     MOVN_FMT_04 = 0x4,
15418     PUL_PS = 0x4,
15419     SDXC1 = 0x4,
15420     RECIP2_FMT = 0x4,
15421 
15422     MOVZ_FMT_05 = 0x05,
15423     PUU_PS = 0x5,
15424     LUXC1 = 0x5,
15425 
15426     CVT_PS_S = 0x6,
15427     SUXC1 = 0x6,
15428     ADDR_PS = 0x6,
15429     PREFX = 0x6,
15430     MADDF_FMT = 0x6,
15431 
15432     MULR_PS = 0x7,
15433     MSUBF_FMT = 0x7,
15434 
15435     MADD_S = 0x01,
15436     MADD_D = 0x09,
15437     MADD_PS = 0x11,
15438     ALNV_PS = 0x19,
15439     MSUB_S = 0x21,
15440     MSUB_D = 0x29,
15441     MSUB_PS = 0x31,
15442 
15443     NMADD_S = 0x02,
15444     NMADD_D = 0x0a,
15445     NMADD_PS = 0x12,
15446     NMSUB_S = 0x22,
15447     NMSUB_D = 0x2a,
15448     NMSUB_PS = 0x32,
15449 
15450     MIN_FMT = 0x3,
15451     MAX_FMT = 0xb,
15452     MINA_FMT = 0x23,
15453     MAXA_FMT = 0x2b,
15454     POOL32FXF = 0x3b,
15455 
15456     CABS_COND_FMT = 0x1c,              /* MIPS3D */
15457     C_COND_FMT = 0x3c,
15458 
15459     CMP_CONDN_S = 0x5,
15460     CMP_CONDN_D = 0x15
15461 };
15462 
15463 /* POOL32Fxf encoding of minor opcode extension field */
15464 
15465 enum {
15466     CVT_L = 0x04,
15467     RSQRT_FMT = 0x08,
15468     FLOOR_L = 0x0c,
15469     CVT_PW_PS = 0x1c,
15470     CVT_W = 0x24,
15471     SQRT_FMT = 0x28,
15472     FLOOR_W = 0x2c,
15473     CVT_PS_PW = 0x3c,
15474     CFC1 = 0x40,
15475     RECIP_FMT = 0x48,
15476     CEIL_L = 0x4c,
15477     CTC1 = 0x60,
15478     CEIL_W = 0x6c,
15479     MFC1 = 0x80,
15480     CVT_S_PL = 0x84,
15481     TRUNC_L = 0x8c,
15482     MTC1 = 0xa0,
15483     CVT_S_PU = 0xa4,
15484     TRUNC_W = 0xac,
15485     MFHC1 = 0xc0,
15486     ROUND_L = 0xcc,
15487     MTHC1 = 0xe0,
15488     ROUND_W = 0xec,
15489 
15490     MOV_FMT = 0x01,
15491     MOVF = 0x05,
15492     ABS_FMT = 0x0d,
15493     RSQRT1_FMT = 0x1d,
15494     MOVT = 0x25,
15495     NEG_FMT = 0x2d,
15496     CVT_D = 0x4d,
15497     RECIP1_FMT = 0x5d,
15498     CVT_S = 0x6d
15499 };
15500 
15501 /* POOL32I encoding of minor opcode field (bits 25..21) */
15502 
15503 enum {
15504     BLTZ = 0x00,
15505     BLTZAL = 0x01,
15506     BGEZ = 0x02,
15507     BGEZAL = 0x03,
15508     BLEZ = 0x04,
15509     BNEZC = 0x05,
15510     BGTZ = 0x06,
15511     BEQZC = 0x07,
15512     TLTI = 0x08,
15513     BC1EQZC = 0x08,
15514     TGEI = 0x09,
15515     BC1NEZC = 0x09,
15516     TLTIU = 0x0a,
15517     BC2EQZC = 0x0a,
15518     TGEIU = 0x0b,
15519     BC2NEZC = 0x0a,
15520     TNEI = 0x0c,
15521     R6_SYNCI = 0x0c,
15522     LUI = 0x0d,
15523     TEQI = 0x0e,
15524     SYNCI = 0x10,
15525     BLTZALS = 0x11,
15526     BGEZALS = 0x13,
15527     BC2F = 0x14,
15528     BC2T = 0x15,
15529     BPOSGE64 = 0x1a,
15530     BPOSGE32 = 0x1b,
15531     /* These overlap and are distinguished by bit16 of the instruction */
15532     BC1F = 0x1c,
15533     BC1T = 0x1d,
15534     BC1ANY2F = 0x1c,
15535     BC1ANY2T = 0x1d,
15536     BC1ANY4F = 0x1e,
15537     BC1ANY4T = 0x1f
15538 };
15539 
15540 /* POOL16A encoding of minor opcode field */
15541 
15542 enum {
15543     ADDU16 = 0x0,
15544     SUBU16 = 0x1
15545 };
15546 
15547 /* POOL16B encoding of minor opcode field */
15548 
15549 enum {
15550     SLL16 = 0x0,
15551     SRL16 = 0x1
15552 };
15553 
15554 /* POOL16C encoding of minor opcode field */
15555 
15556 enum {
15557     NOT16 = 0x00,
15558     XOR16 = 0x04,
15559     AND16 = 0x08,
15560     OR16 = 0x0c,
15561     LWM16 = 0x10,
15562     SWM16 = 0x14,
15563     JR16 = 0x18,
15564     JRC16 = 0x1a,
15565     JALR16 = 0x1c,
15566     JALR16S = 0x1e,
15567     MFHI16 = 0x20,
15568     MFLO16 = 0x24,
15569     BREAK16 = 0x28,
15570     SDBBP16 = 0x2c,
15571     JRADDIUSP = 0x30
15572 };
15573 
15574 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
15575 
15576 enum {
15577     R6_NOT16    = 0x00,
15578     R6_AND16    = 0x01,
15579     R6_LWM16    = 0x02,
15580     R6_JRC16    = 0x03,
15581     MOVEP       = 0x04,
15582     MOVEP_05    = 0x05,
15583     MOVEP_06    = 0x06,
15584     MOVEP_07    = 0x07,
15585     R6_XOR16    = 0x08,
15586     R6_OR16     = 0x09,
15587     R6_SWM16    = 0x0a,
15588     JALRC16     = 0x0b,
15589     MOVEP_0C    = 0x0c,
15590     MOVEP_0D    = 0x0d,
15591     MOVEP_0E    = 0x0e,
15592     MOVEP_0F    = 0x0f,
15593     JRCADDIUSP  = 0x13,
15594     R6_BREAK16  = 0x1b,
15595     R6_SDBBP16  = 0x3b
15596 };
15597 
15598 /* POOL16D encoding of minor opcode field */
15599 
15600 enum {
15601     ADDIUS5 = 0x0,
15602     ADDIUSP = 0x1
15603 };
15604 
15605 /* POOL16E encoding of minor opcode field */
15606 
15607 enum {
15608     ADDIUR2 = 0x0,
15609     ADDIUR1SP = 0x1
15610 };
15611 
mmreg(int r)15612 static int mmreg(int r)
15613 {
15614     static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
15615 
15616     return map[r];
15617 }
15618 
15619 /* Used for 16-bit store instructions.  */
mmreg2(int r)15620 static int mmreg2(int r)
15621 {
15622     static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
15623 
15624     return map[r];
15625 }
15626 
15627 #define uMIPS_RD(op) ((op >> 7) & 0x7)
15628 #define uMIPS_RS(op) ((op >> 4) & 0x7)
15629 #define uMIPS_RS2(op) uMIPS_RS(op)
15630 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
15631 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
15632 #define uMIPS_RS5(op) (op & 0x1f)
15633 
15634 /* Signed immediate */
15635 #define SIMM(op, start, width)                                          \
15636     ((int32_t)(((op >> start) & ((~0U) >> (32 - width)))                \
15637                << (32 - width))                                         \
15638      >> (32 - width))
15639 /* Zero-extended immediate */
15640 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32 - width)))
15641 
gen_addiur1sp(DisasContext * ctx)15642 static void gen_addiur1sp(DisasContext *ctx)
15643 {
15644     int rd = mmreg(uMIPS_RD(ctx->opcode));
15645 
15646     gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
15647 }
15648 
gen_addiur2(DisasContext * ctx)15649 static void gen_addiur2(DisasContext *ctx)
15650 {
15651     static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
15652     int rd = mmreg(uMIPS_RD(ctx->opcode));
15653     int rs = mmreg(uMIPS_RS(ctx->opcode));
15654 
15655     gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
15656 }
15657 
gen_addiusp(DisasContext * ctx)15658 static void gen_addiusp(DisasContext *ctx)
15659 {
15660     int encoded = ZIMM(ctx->opcode, 1, 9);
15661     int decoded;
15662 
15663     if (encoded <= 1) {
15664         decoded = 256 + encoded;
15665     } else if (encoded <= 255) {
15666         decoded = encoded;
15667     } else if (encoded <= 509) {
15668         decoded = encoded - 512;
15669     } else {
15670         decoded = encoded - 768;
15671     }
15672 
15673     gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
15674 }
15675 
gen_addius5(DisasContext * ctx)15676 static void gen_addius5(DisasContext *ctx)
15677 {
15678     int imm = SIMM(ctx->opcode, 1, 4);
15679     int rd = (ctx->opcode >> 5) & 0x1f;
15680 
15681     gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
15682 }
15683 
gen_andi16(DisasContext * ctx)15684 static void gen_andi16(DisasContext *ctx)
15685 {
15686     static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
15687                                  31, 32, 63, 64, 255, 32768, 65535 };
15688     int rd = mmreg(uMIPS_RD(ctx->opcode));
15689     int rs = mmreg(uMIPS_RS(ctx->opcode));
15690     int encoded = ZIMM(ctx->opcode, 0, 4);
15691 
15692     gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
15693 }
15694 
gen_ldst_multiple(DisasContext * ctx,uint32_t opc,int reglist,int base,int16_t offset)15695 static void gen_ldst_multiple(DisasContext *ctx, uint32_t opc, int reglist,
15696                               int base, int16_t offset)
15697 {
15698     TCGv t0, t1;
15699     TCGv_i32 t2;
15700 
15701     if (ctx->hflags & MIPS_HFLAG_BMASK) {
15702         generate_exception_end(ctx, EXCP_RI);
15703         return;
15704     }
15705 
15706     t0 = tcg_temp_new();
15707 
15708     gen_base_offset_addr(ctx, t0, base, offset);
15709 
15710     t1 = tcg_const_tl(reglist);
15711     t2 = tcg_const_i32(ctx->mem_idx);
15712 
15713     save_cpu_state(ctx, 1);
15714     switch (opc) {
15715     case LWM32:
15716         gen_helper_lwm(cpu_env, t0, t1, t2);
15717         break;
15718     case SWM32:
15719         gen_helper_swm(cpu_env, t0, t1, t2);
15720         break;
15721 #ifdef TARGET_MIPS64
15722     case LDM:
15723         gen_helper_ldm(cpu_env, t0, t1, t2);
15724         break;
15725     case SDM:
15726         gen_helper_sdm(cpu_env, t0, t1, t2);
15727         break;
15728 #endif
15729     }
15730     tcg_temp_free(t0);
15731     tcg_temp_free(t1);
15732     tcg_temp_free_i32(t2);
15733 }
15734 
15735 
gen_pool16c_insn(DisasContext * ctx)15736 static void gen_pool16c_insn(DisasContext *ctx)
15737 {
15738     int rd = mmreg((ctx->opcode >> 3) & 0x7);
15739     int rs = mmreg(ctx->opcode & 0x7);
15740 
15741     switch (((ctx->opcode) >> 4) & 0x3f) {
15742     case NOT16 + 0:
15743     case NOT16 + 1:
15744     case NOT16 + 2:
15745     case NOT16 + 3:
15746         gen_logic(ctx, OPC_NOR, rd, rs, 0);
15747         break;
15748     case XOR16 + 0:
15749     case XOR16 + 1:
15750     case XOR16 + 2:
15751     case XOR16 + 3:
15752         gen_logic(ctx, OPC_XOR, rd, rd, rs);
15753         break;
15754     case AND16 + 0:
15755     case AND16 + 1:
15756     case AND16 + 2:
15757     case AND16 + 3:
15758         gen_logic(ctx, OPC_AND, rd, rd, rs);
15759         break;
15760     case OR16 + 0:
15761     case OR16 + 1:
15762     case OR16 + 2:
15763     case OR16 + 3:
15764         gen_logic(ctx, OPC_OR, rd, rd, rs);
15765         break;
15766     case LWM16 + 0:
15767     case LWM16 + 1:
15768     case LWM16 + 2:
15769     case LWM16 + 3:
15770         {
15771             static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
15772             int offset = ZIMM(ctx->opcode, 0, 4);
15773 
15774             gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
15775                               29, offset << 2);
15776         }
15777         break;
15778     case SWM16 + 0:
15779     case SWM16 + 1:
15780     case SWM16 + 2:
15781     case SWM16 + 3:
15782         {
15783             static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
15784             int offset = ZIMM(ctx->opcode, 0, 4);
15785 
15786             gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
15787                               29, offset << 2);
15788         }
15789         break;
15790     case JR16 + 0:
15791     case JR16 + 1:
15792         {
15793             int reg = ctx->opcode & 0x1f;
15794 
15795             gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
15796         }
15797         break;
15798     case JRC16 + 0:
15799     case JRC16 + 1:
15800         {
15801             int reg = ctx->opcode & 0x1f;
15802             gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
15803             /*
15804              * Let normal delay slot handling in our caller take us
15805              * to the branch target.
15806              */
15807         }
15808         break;
15809     case JALR16 + 0:
15810     case JALR16 + 1:
15811         gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
15812         ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15813         break;
15814     case JALR16S + 0:
15815     case JALR16S + 1:
15816         gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
15817         ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15818         break;
15819     case MFHI16 + 0:
15820     case MFHI16 + 1:
15821         gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
15822         break;
15823     case MFLO16 + 0:
15824     case MFLO16 + 1:
15825         gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
15826         break;
15827     case BREAK16:
15828         generate_exception_end(ctx, EXCP_BREAK);
15829         break;
15830     case SDBBP16:
15831         if (is_uhi(extract32(ctx->opcode, 0, 4))) {
15832             gen_helper_do_semihosting(cpu_env);
15833         } else {
15834             /*
15835              * XXX: not clear which exception should be raised
15836              *      when in debug mode...
15837              */
15838             check_insn(ctx, ISA_MIPS32);
15839             generate_exception_end(ctx, EXCP_DBp);
15840         }
15841         break;
15842     case JRADDIUSP + 0:
15843     case JRADDIUSP + 1:
15844         {
15845             int imm = ZIMM(ctx->opcode, 0, 5);
15846             gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
15847             gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
15848             /*
15849              * Let normal delay slot handling in our caller take us
15850              * to the branch target.
15851              */
15852         }
15853         break;
15854     default:
15855         generate_exception_end(ctx, EXCP_RI);
15856         break;
15857     }
15858 }
15859 
gen_movep(DisasContext * ctx,int enc_dest,int enc_rt,int enc_rs)15860 static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
15861                              int enc_rs)
15862 {
15863     int rd, rs, re, rt;
15864     static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
15865     static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
15866     static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
15867     rd = rd_enc[enc_dest];
15868     re = re_enc[enc_dest];
15869     rs = rs_rt_enc[enc_rs];
15870     rt = rs_rt_enc[enc_rt];
15871     if (rs) {
15872         tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
15873     } else {
15874         tcg_gen_movi_tl(cpu_gpr[rd], 0);
15875     }
15876     if (rt) {
15877         tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
15878     } else {
15879         tcg_gen_movi_tl(cpu_gpr[re], 0);
15880     }
15881 }
15882 
gen_pool16c_r6_insn(DisasContext * ctx)15883 static void gen_pool16c_r6_insn(DisasContext *ctx)
15884 {
15885     int rt = mmreg((ctx->opcode >> 7) & 0x7);
15886     int rs = mmreg((ctx->opcode >> 4) & 0x7);
15887 
15888     switch (ctx->opcode & 0xf) {
15889     case R6_NOT16:
15890         gen_logic(ctx, OPC_NOR, rt, rs, 0);
15891         break;
15892     case R6_AND16:
15893         gen_logic(ctx, OPC_AND, rt, rt, rs);
15894         break;
15895     case R6_LWM16:
15896         {
15897             int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
15898             int offset = extract32(ctx->opcode, 4, 4);
15899             gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
15900         }
15901         break;
15902     case R6_JRC16: /* JRCADDIUSP */
15903         if ((ctx->opcode >> 4) & 1) {
15904             /* JRCADDIUSP */
15905             int imm = extract32(ctx->opcode, 5, 5);
15906             gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
15907             gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
15908         } else {
15909             /* JRC16 */
15910             rs = extract32(ctx->opcode, 5, 5);
15911             gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
15912         }
15913         break;
15914     case MOVEP:
15915     case MOVEP_05:
15916     case MOVEP_06:
15917     case MOVEP_07:
15918     case MOVEP_0C:
15919     case MOVEP_0D:
15920     case MOVEP_0E:
15921     case MOVEP_0F:
15922         {
15923             int enc_dest = uMIPS_RD(ctx->opcode);
15924             int enc_rt = uMIPS_RS2(ctx->opcode);
15925             int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
15926             gen_movep(ctx, enc_dest, enc_rt, enc_rs);
15927         }
15928         break;
15929     case R6_XOR16:
15930         gen_logic(ctx, OPC_XOR, rt, rt, rs);
15931         break;
15932     case R6_OR16:
15933         gen_logic(ctx, OPC_OR, rt, rt, rs);
15934         break;
15935     case R6_SWM16:
15936         {
15937             int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
15938             int offset = extract32(ctx->opcode, 4, 4);
15939             gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
15940         }
15941         break;
15942     case JALRC16: /* BREAK16, SDBBP16 */
15943         switch (ctx->opcode & 0x3f) {
15944         case JALRC16:
15945         case JALRC16 + 0x20:
15946             /* JALRC16 */
15947             gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
15948                                31, 0, 0);
15949             break;
15950         case R6_BREAK16:
15951             /* BREAK16 */
15952             generate_exception(ctx, EXCP_BREAK);
15953             break;
15954         case R6_SDBBP16:
15955             /* SDBBP16 */
15956             if (is_uhi(extract32(ctx->opcode, 6, 4))) {
15957                 gen_helper_do_semihosting(cpu_env);
15958             } else {
15959                 if (ctx->hflags & MIPS_HFLAG_SBRI) {
15960                     generate_exception(ctx, EXCP_RI);
15961                 } else {
15962                     generate_exception(ctx, EXCP_DBp);
15963                 }
15964             }
15965             break;
15966         }
15967         break;
15968     default:
15969         generate_exception(ctx, EXCP_RI);
15970         break;
15971     }
15972 }
15973 
gen_ldxs(DisasContext * ctx,int base,int index,int rd)15974 static void gen_ldxs(DisasContext *ctx, int base, int index, int rd)
15975 {
15976     TCGv t0 = tcg_temp_new();
15977     TCGv t1 = tcg_temp_new();
15978 
15979     gen_load_gpr(t0, base);
15980 
15981     if (index != 0) {
15982         gen_load_gpr(t1, index);
15983         tcg_gen_shli_tl(t1, t1, 2);
15984         gen_op_addr_add(ctx, t0, t1, t0);
15985     }
15986 
15987     tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15988     gen_store_gpr(t1, rd);
15989 
15990     tcg_temp_free(t0);
15991     tcg_temp_free(t1);
15992 }
15993 
gen_ldst_pair(DisasContext * ctx,uint32_t opc,int rd,int base,int16_t offset)15994 static void gen_ldst_pair(DisasContext *ctx, uint32_t opc, int rd,
15995                           int base, int16_t offset)
15996 {
15997     TCGv t0, t1;
15998 
15999     if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
16000         generate_exception_end(ctx, EXCP_RI);
16001         return;
16002     }
16003 
16004     t0 = tcg_temp_new();
16005     t1 = tcg_temp_new();
16006 
16007     gen_base_offset_addr(ctx, t0, base, offset);
16008 
16009     switch (opc) {
16010     case LWP:
16011         if (rd == base) {
16012             generate_exception_end(ctx, EXCP_RI);
16013             return;
16014         }
16015         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
16016         gen_store_gpr(t1, rd);
16017         tcg_gen_movi_tl(t1, 4);
16018         gen_op_addr_add(ctx, t0, t0, t1);
16019         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
16020         gen_store_gpr(t1, rd + 1);
16021         break;
16022     case SWP:
16023         gen_load_gpr(t1, rd);
16024         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
16025         tcg_gen_movi_tl(t1, 4);
16026         gen_op_addr_add(ctx, t0, t0, t1);
16027         gen_load_gpr(t1, rd + 1);
16028         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
16029         break;
16030 #ifdef TARGET_MIPS64
16031     case LDP:
16032         if (rd == base) {
16033             generate_exception_end(ctx, EXCP_RI);
16034             return;
16035         }
16036         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
16037         gen_store_gpr(t1, rd);
16038         tcg_gen_movi_tl(t1, 8);
16039         gen_op_addr_add(ctx, t0, t0, t1);
16040         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
16041         gen_store_gpr(t1, rd + 1);
16042         break;
16043     case SDP:
16044         gen_load_gpr(t1, rd);
16045         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
16046         tcg_gen_movi_tl(t1, 8);
16047         gen_op_addr_add(ctx, t0, t0, t1);
16048         gen_load_gpr(t1, rd + 1);
16049         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
16050         break;
16051 #endif
16052     }
16053     tcg_temp_free(t0);
16054     tcg_temp_free(t1);
16055 }
16056 
gen_sync(int stype)16057 static void gen_sync(int stype)
16058 {
16059     TCGBar tcg_mo = TCG_BAR_SC;
16060 
16061     switch (stype) {
16062     case 0x4: /* SYNC_WMB */
16063         tcg_mo |= TCG_MO_ST_ST;
16064         break;
16065     case 0x10: /* SYNC_MB */
16066         tcg_mo |= TCG_MO_ALL;
16067         break;
16068     case 0x11: /* SYNC_ACQUIRE */
16069         tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
16070         break;
16071     case 0x12: /* SYNC_RELEASE */
16072         tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
16073         break;
16074     case 0x13: /* SYNC_RMB */
16075         tcg_mo |= TCG_MO_LD_LD;
16076         break;
16077     default:
16078         tcg_mo |= TCG_MO_ALL;
16079         break;
16080     }
16081 
16082     tcg_gen_mb(tcg_mo);
16083 }
16084 
gen_pool32axf(CPUMIPSState * env,DisasContext * ctx,int rt,int rs)16085 static void gen_pool32axf(CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
16086 {
16087     int extension = (ctx->opcode >> 6) & 0x3f;
16088     int minor = (ctx->opcode >> 12) & 0xf;
16089     uint32_t mips32_op;
16090 
16091     switch (extension) {
16092     case TEQ:
16093         mips32_op = OPC_TEQ;
16094         goto do_trap;
16095     case TGE:
16096         mips32_op = OPC_TGE;
16097         goto do_trap;
16098     case TGEU:
16099         mips32_op = OPC_TGEU;
16100         goto do_trap;
16101     case TLT:
16102         mips32_op = OPC_TLT;
16103         goto do_trap;
16104     case TLTU:
16105         mips32_op = OPC_TLTU;
16106         goto do_trap;
16107     case TNE:
16108         mips32_op = OPC_TNE;
16109     do_trap:
16110         gen_trap(ctx, mips32_op, rs, rt, -1);
16111         break;
16112 #ifndef CONFIG_USER_ONLY
16113     case MFC0:
16114     case MFC0 + 32:
16115         check_cp0_enabled(ctx);
16116         if (rt == 0) {
16117             /* Treat as NOP. */
16118             break;
16119         }
16120         gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
16121         break;
16122     case MTC0:
16123     case MTC0 + 32:
16124         check_cp0_enabled(ctx);
16125         {
16126             TCGv t0 = tcg_temp_new();
16127 
16128             gen_load_gpr(t0, rt);
16129             gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
16130             tcg_temp_free(t0);
16131         }
16132         break;
16133 #endif
16134     case 0x2a:
16135         switch (minor & 3) {
16136         case MADD_ACC:
16137             gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
16138             break;
16139         case MADDU_ACC:
16140             gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
16141             break;
16142         case MSUB_ACC:
16143             gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
16144             break;
16145         case MSUBU_ACC:
16146             gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
16147             break;
16148         default:
16149             goto pool32axf_invalid;
16150         }
16151         break;
16152     case 0x32:
16153         switch (minor & 3) {
16154         case MULT_ACC:
16155             gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
16156             break;
16157         case MULTU_ACC:
16158             gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
16159             break;
16160         default:
16161             goto pool32axf_invalid;
16162         }
16163         break;
16164     case 0x2c:
16165         switch (minor) {
16166         case BITSWAP:
16167             check_insn(ctx, ISA_MIPS32R6);
16168             gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
16169             break;
16170         case SEB:
16171             gen_bshfl(ctx, OPC_SEB, rs, rt);
16172             break;
16173         case SEH:
16174             gen_bshfl(ctx, OPC_SEH, rs, rt);
16175             break;
16176         case CLO:
16177             mips32_op = OPC_CLO;
16178             goto do_cl;
16179         case CLZ:
16180             mips32_op = OPC_CLZ;
16181         do_cl:
16182             check_insn(ctx, ISA_MIPS32);
16183             gen_cl(ctx, mips32_op, rt, rs);
16184             break;
16185         case RDHWR:
16186             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16187             gen_rdhwr(ctx, rt, rs, 0);
16188             break;
16189         case WSBH:
16190             gen_bshfl(ctx, OPC_WSBH, rs, rt);
16191             break;
16192         case MULT:
16193             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16194             mips32_op = OPC_MULT;
16195             goto do_mul;
16196         case MULTU:
16197             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16198             mips32_op = OPC_MULTU;
16199             goto do_mul;
16200         case DIV:
16201             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16202             mips32_op = OPC_DIV;
16203             goto do_div;
16204         case DIVU:
16205             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16206             mips32_op = OPC_DIVU;
16207             goto do_div;
16208         do_div:
16209             check_insn(ctx, ISA_MIPS32);
16210             gen_muldiv(ctx, mips32_op, 0, rs, rt);
16211             break;
16212         case MADD:
16213             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16214             mips32_op = OPC_MADD;
16215             goto do_mul;
16216         case MADDU:
16217             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16218             mips32_op = OPC_MADDU;
16219             goto do_mul;
16220         case MSUB:
16221             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16222             mips32_op = OPC_MSUB;
16223             goto do_mul;
16224         case MSUBU:
16225             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16226             mips32_op = OPC_MSUBU;
16227         do_mul:
16228             check_insn(ctx, ISA_MIPS32);
16229             gen_muldiv(ctx, mips32_op, 0, rs, rt);
16230             break;
16231         default:
16232             goto pool32axf_invalid;
16233         }
16234         break;
16235     case 0x34:
16236         switch (minor) {
16237         case MFC2:
16238         case MTC2:
16239         case MFHC2:
16240         case MTHC2:
16241         case CFC2:
16242         case CTC2:
16243             generate_exception_err(ctx, EXCP_CpU, 2);
16244             break;
16245         default:
16246             goto pool32axf_invalid;
16247         }
16248         break;
16249     case 0x3c:
16250         switch (minor) {
16251         case JALR:    /* JALRC */
16252         case JALR_HB: /* JALRC_HB */
16253             if (ctx->insn_flags & ISA_MIPS32R6) {
16254                 /* JALRC, JALRC_HB */
16255                 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
16256             } else {
16257                 /* JALR, JALR_HB */
16258                 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
16259                 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16260             }
16261             break;
16262         case JALRS:
16263         case JALRS_HB:
16264             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16265             gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
16266             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16267             break;
16268         default:
16269             goto pool32axf_invalid;
16270         }
16271         break;
16272     case 0x05:
16273         switch (minor) {
16274         case RDPGPR:
16275             check_cp0_enabled(ctx);
16276             check_insn(ctx, ISA_MIPS32R2);
16277             gen_load_srsgpr(rs, rt);
16278             break;
16279         case WRPGPR:
16280             check_cp0_enabled(ctx);
16281             check_insn(ctx, ISA_MIPS32R2);
16282             gen_store_srsgpr(rs, rt);
16283             break;
16284         default:
16285             goto pool32axf_invalid;
16286         }
16287         break;
16288 #ifndef CONFIG_USER_ONLY
16289     case 0x0d:
16290         switch (minor) {
16291         case TLBP:
16292             mips32_op = OPC_TLBP;
16293             goto do_cp0;
16294         case TLBR:
16295             mips32_op = OPC_TLBR;
16296             goto do_cp0;
16297         case TLBWI:
16298             mips32_op = OPC_TLBWI;
16299             goto do_cp0;
16300         case TLBWR:
16301             mips32_op = OPC_TLBWR;
16302             goto do_cp0;
16303         case TLBINV:
16304             mips32_op = OPC_TLBINV;
16305             goto do_cp0;
16306         case TLBINVF:
16307             mips32_op = OPC_TLBINVF;
16308             goto do_cp0;
16309         case WAIT:
16310             mips32_op = OPC_WAIT;
16311             goto do_cp0;
16312         case DERET:
16313             mips32_op = OPC_DERET;
16314             goto do_cp0;
16315         case ERET:
16316             mips32_op = OPC_ERET;
16317         do_cp0:
16318             gen_cp0(env, ctx, mips32_op, rt, rs);
16319             break;
16320         default:
16321             goto pool32axf_invalid;
16322         }
16323         break;
16324     case 0x1d:
16325         switch (minor) {
16326         case DI:
16327             check_cp0_enabled(ctx);
16328             {
16329                 TCGv t0 = tcg_temp_new();
16330 
16331                 save_cpu_state(ctx, 1);
16332                 gen_helper_di(t0, cpu_env);
16333                 gen_store_gpr(t0, rs);
16334                 /*
16335                  * Stop translation as we may have switched the execution
16336                  * mode.
16337                  */
16338                 ctx->base.is_jmp = DISAS_STOP;
16339                 tcg_temp_free(t0);
16340             }
16341             break;
16342         case EI:
16343             check_cp0_enabled(ctx);
16344             {
16345                 TCGv t0 = tcg_temp_new();
16346 
16347                 save_cpu_state(ctx, 1);
16348                 gen_helper_ei(t0, cpu_env);
16349                 gen_store_gpr(t0, rs);
16350                 /*
16351                  * DISAS_STOP isn't sufficient, we need to ensure we break out
16352                  * of translated code to check for pending interrupts.
16353                  */
16354                 gen_save_pc(ctx->base.pc_next + 4);
16355                 ctx->base.is_jmp = DISAS_EXIT;
16356                 tcg_temp_free(t0);
16357             }
16358             break;
16359         default:
16360             goto pool32axf_invalid;
16361         }
16362         break;
16363 #endif
16364     case 0x2d:
16365         switch (minor) {
16366         case SYNC:
16367             gen_sync(extract32(ctx->opcode, 16, 5));
16368             break;
16369         case SYSCALL:
16370             generate_exception_end(ctx, EXCP_SYSCALL);
16371             break;
16372         case SDBBP:
16373             if (is_uhi(extract32(ctx->opcode, 16, 10))) {
16374                 gen_helper_do_semihosting(cpu_env);
16375             } else {
16376                 check_insn(ctx, ISA_MIPS32);
16377                 if (ctx->hflags & MIPS_HFLAG_SBRI) {
16378                     generate_exception_end(ctx, EXCP_RI);
16379                 } else {
16380                     generate_exception_end(ctx, EXCP_DBp);
16381                 }
16382             }
16383             break;
16384         default:
16385             goto pool32axf_invalid;
16386         }
16387         break;
16388     case 0x01:
16389         switch (minor & 3) {
16390         case MFHI_ACC:
16391             gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
16392             break;
16393         case MFLO_ACC:
16394             gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
16395             break;
16396         case MTHI_ACC:
16397             gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
16398             break;
16399         case MTLO_ACC:
16400             gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
16401             break;
16402         default:
16403             goto pool32axf_invalid;
16404         }
16405         break;
16406     case 0x35:
16407         check_insn_opc_removed(ctx, ISA_MIPS32R6);
16408         switch (minor) {
16409         case MFHI32:
16410             gen_HILO(ctx, OPC_MFHI, 0, rs);
16411             break;
16412         case MFLO32:
16413             gen_HILO(ctx, OPC_MFLO, 0, rs);
16414             break;
16415         case MTHI32:
16416             gen_HILO(ctx, OPC_MTHI, 0, rs);
16417             break;
16418         case MTLO32:
16419             gen_HILO(ctx, OPC_MTLO, 0, rs);
16420             break;
16421         default:
16422             goto pool32axf_invalid;
16423         }
16424         break;
16425     default:
16426     pool32axf_invalid:
16427         MIPS_INVAL("pool32axf");
16428         generate_exception_end(ctx, EXCP_RI);
16429         break;
16430     }
16431 }
16432 
16433 /*
16434  * Values for microMIPS fmt field.  Variable-width, depending on which
16435  * formats the instruction supports.
16436  */
16437 enum {
16438     FMT_SD_S = 0,
16439     FMT_SD_D = 1,
16440 
16441     FMT_SDPS_S = 0,
16442     FMT_SDPS_D = 1,
16443     FMT_SDPS_PS = 2,
16444 
16445     FMT_SWL_S = 0,
16446     FMT_SWL_W = 1,
16447     FMT_SWL_L = 2,
16448 
16449     FMT_DWL_D = 0,
16450     FMT_DWL_W = 1,
16451     FMT_DWL_L = 2
16452 };
16453 
gen_pool32fxf(DisasContext * ctx,int rt,int rs)16454 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
16455 {
16456     int extension = (ctx->opcode >> 6) & 0x3ff;
16457     uint32_t mips32_op;
16458 
16459 #define FLOAT_1BIT_FMT(opc, fmt)    ((fmt << 8) | opc)
16460 #define FLOAT_2BIT_FMT(opc, fmt)    ((fmt << 7) | opc)
16461 #define COND_FLOAT_MOV(opc, cond)   ((cond << 7) | opc)
16462 
16463     switch (extension) {
16464     case FLOAT_1BIT_FMT(CFC1, 0):
16465         mips32_op = OPC_CFC1;
16466         goto do_cp1;
16467     case FLOAT_1BIT_FMT(CTC1, 0):
16468         mips32_op = OPC_CTC1;
16469         goto do_cp1;
16470     case FLOAT_1BIT_FMT(MFC1, 0):
16471         mips32_op = OPC_MFC1;
16472         goto do_cp1;
16473     case FLOAT_1BIT_FMT(MTC1, 0):
16474         mips32_op = OPC_MTC1;
16475         goto do_cp1;
16476     case FLOAT_1BIT_FMT(MFHC1, 0):
16477         mips32_op = OPC_MFHC1;
16478         goto do_cp1;
16479     case FLOAT_1BIT_FMT(MTHC1, 0):
16480         mips32_op = OPC_MTHC1;
16481     do_cp1:
16482         gen_cp1(ctx, mips32_op, rt, rs);
16483         break;
16484 
16485         /* Reciprocal square root */
16486     case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
16487         mips32_op = OPC_RSQRT_S;
16488         goto do_unaryfp;
16489     case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
16490         mips32_op = OPC_RSQRT_D;
16491         goto do_unaryfp;
16492 
16493         /* Square root */
16494     case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
16495         mips32_op = OPC_SQRT_S;
16496         goto do_unaryfp;
16497     case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
16498         mips32_op = OPC_SQRT_D;
16499         goto do_unaryfp;
16500 
16501         /* Reciprocal */
16502     case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
16503         mips32_op = OPC_RECIP_S;
16504         goto do_unaryfp;
16505     case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
16506         mips32_op = OPC_RECIP_D;
16507         goto do_unaryfp;
16508 
16509         /* Floor */
16510     case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
16511         mips32_op = OPC_FLOOR_L_S;
16512         goto do_unaryfp;
16513     case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
16514         mips32_op = OPC_FLOOR_L_D;
16515         goto do_unaryfp;
16516     case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
16517         mips32_op = OPC_FLOOR_W_S;
16518         goto do_unaryfp;
16519     case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
16520         mips32_op = OPC_FLOOR_W_D;
16521         goto do_unaryfp;
16522 
16523         /* Ceiling */
16524     case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
16525         mips32_op = OPC_CEIL_L_S;
16526         goto do_unaryfp;
16527     case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
16528         mips32_op = OPC_CEIL_L_D;
16529         goto do_unaryfp;
16530     case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
16531         mips32_op = OPC_CEIL_W_S;
16532         goto do_unaryfp;
16533     case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
16534         mips32_op = OPC_CEIL_W_D;
16535         goto do_unaryfp;
16536 
16537         /* Truncation */
16538     case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
16539         mips32_op = OPC_TRUNC_L_S;
16540         goto do_unaryfp;
16541     case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
16542         mips32_op = OPC_TRUNC_L_D;
16543         goto do_unaryfp;
16544     case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
16545         mips32_op = OPC_TRUNC_W_S;
16546         goto do_unaryfp;
16547     case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
16548         mips32_op = OPC_TRUNC_W_D;
16549         goto do_unaryfp;
16550 
16551         /* Round */
16552     case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
16553         mips32_op = OPC_ROUND_L_S;
16554         goto do_unaryfp;
16555     case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
16556         mips32_op = OPC_ROUND_L_D;
16557         goto do_unaryfp;
16558     case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
16559         mips32_op = OPC_ROUND_W_S;
16560         goto do_unaryfp;
16561     case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
16562         mips32_op = OPC_ROUND_W_D;
16563         goto do_unaryfp;
16564 
16565         /* Integer to floating-point conversion */
16566     case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
16567         mips32_op = OPC_CVT_L_S;
16568         goto do_unaryfp;
16569     case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
16570         mips32_op = OPC_CVT_L_D;
16571         goto do_unaryfp;
16572     case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
16573         mips32_op = OPC_CVT_W_S;
16574         goto do_unaryfp;
16575     case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
16576         mips32_op = OPC_CVT_W_D;
16577         goto do_unaryfp;
16578 
16579         /* Paired-foo conversions */
16580     case FLOAT_1BIT_FMT(CVT_S_PL, 0):
16581         mips32_op = OPC_CVT_S_PL;
16582         goto do_unaryfp;
16583     case FLOAT_1BIT_FMT(CVT_S_PU, 0):
16584         mips32_op = OPC_CVT_S_PU;
16585         goto do_unaryfp;
16586     case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
16587         mips32_op = OPC_CVT_PW_PS;
16588         goto do_unaryfp;
16589     case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
16590         mips32_op = OPC_CVT_PS_PW;
16591         goto do_unaryfp;
16592 
16593         /* Floating-point moves */
16594     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
16595         mips32_op = OPC_MOV_S;
16596         goto do_unaryfp;
16597     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
16598         mips32_op = OPC_MOV_D;
16599         goto do_unaryfp;
16600     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
16601         mips32_op = OPC_MOV_PS;
16602         goto do_unaryfp;
16603 
16604         /* Absolute value */
16605     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
16606         mips32_op = OPC_ABS_S;
16607         goto do_unaryfp;
16608     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
16609         mips32_op = OPC_ABS_D;
16610         goto do_unaryfp;
16611     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
16612         mips32_op = OPC_ABS_PS;
16613         goto do_unaryfp;
16614 
16615         /* Negation */
16616     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
16617         mips32_op = OPC_NEG_S;
16618         goto do_unaryfp;
16619     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
16620         mips32_op = OPC_NEG_D;
16621         goto do_unaryfp;
16622     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
16623         mips32_op = OPC_NEG_PS;
16624         goto do_unaryfp;
16625 
16626         /* Reciprocal square root step */
16627     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
16628         mips32_op = OPC_RSQRT1_S;
16629         goto do_unaryfp;
16630     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
16631         mips32_op = OPC_RSQRT1_D;
16632         goto do_unaryfp;
16633     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
16634         mips32_op = OPC_RSQRT1_PS;
16635         goto do_unaryfp;
16636 
16637         /* Reciprocal step */
16638     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
16639         mips32_op = OPC_RECIP1_S;
16640         goto do_unaryfp;
16641     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
16642         mips32_op = OPC_RECIP1_S;
16643         goto do_unaryfp;
16644     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
16645         mips32_op = OPC_RECIP1_PS;
16646         goto do_unaryfp;
16647 
16648         /* Conversions from double */
16649     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
16650         mips32_op = OPC_CVT_D_S;
16651         goto do_unaryfp;
16652     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
16653         mips32_op = OPC_CVT_D_W;
16654         goto do_unaryfp;
16655     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
16656         mips32_op = OPC_CVT_D_L;
16657         goto do_unaryfp;
16658 
16659         /* Conversions from single */
16660     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
16661         mips32_op = OPC_CVT_S_D;
16662         goto do_unaryfp;
16663     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
16664         mips32_op = OPC_CVT_S_W;
16665         goto do_unaryfp;
16666     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
16667         mips32_op = OPC_CVT_S_L;
16668     do_unaryfp:
16669         gen_farith(ctx, mips32_op, -1, rs, rt, 0);
16670         break;
16671 
16672         /* Conditional moves on floating-point codes */
16673     case COND_FLOAT_MOV(MOVT, 0):
16674     case COND_FLOAT_MOV(MOVT, 1):
16675     case COND_FLOAT_MOV(MOVT, 2):
16676     case COND_FLOAT_MOV(MOVT, 3):
16677     case COND_FLOAT_MOV(MOVT, 4):
16678     case COND_FLOAT_MOV(MOVT, 5):
16679     case COND_FLOAT_MOV(MOVT, 6):
16680     case COND_FLOAT_MOV(MOVT, 7):
16681         check_insn_opc_removed(ctx, ISA_MIPS32R6);
16682         gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
16683         break;
16684     case COND_FLOAT_MOV(MOVF, 0):
16685     case COND_FLOAT_MOV(MOVF, 1):
16686     case COND_FLOAT_MOV(MOVF, 2):
16687     case COND_FLOAT_MOV(MOVF, 3):
16688     case COND_FLOAT_MOV(MOVF, 4):
16689     case COND_FLOAT_MOV(MOVF, 5):
16690     case COND_FLOAT_MOV(MOVF, 6):
16691     case COND_FLOAT_MOV(MOVF, 7):
16692         check_insn_opc_removed(ctx, ISA_MIPS32R6);
16693         gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
16694         break;
16695     default:
16696         MIPS_INVAL("pool32fxf");
16697         generate_exception_end(ctx, EXCP_RI);
16698         break;
16699     }
16700 }
16701 
decode_micromips32_opc(CPUMIPSState * env,DisasContext * ctx)16702 static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
16703 {
16704     int32_t offset;
16705     uint16_t insn;
16706     int rt, rs, rd, rr;
16707     int16_t imm;
16708     uint32_t op, minor, minor2, mips32_op;
16709     uint32_t cond, fmt, cc;
16710 
16711     insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
16712     ctx->opcode = (ctx->opcode << 16) | insn;
16713 
16714     rt = (ctx->opcode >> 21) & 0x1f;
16715     rs = (ctx->opcode >> 16) & 0x1f;
16716     rd = (ctx->opcode >> 11) & 0x1f;
16717     rr = (ctx->opcode >> 6) & 0x1f;
16718     imm = (int16_t) ctx->opcode;
16719 
16720     op = (ctx->opcode >> 26) & 0x3f;
16721     switch (op) {
16722     case POOL32A:
16723         minor = ctx->opcode & 0x3f;
16724         switch (minor) {
16725         case 0x00:
16726             minor = (ctx->opcode >> 6) & 0xf;
16727             switch (minor) {
16728             case SLL32:
16729                 mips32_op = OPC_SLL;
16730                 goto do_shifti;
16731             case SRA:
16732                 mips32_op = OPC_SRA;
16733                 goto do_shifti;
16734             case SRL32:
16735                 mips32_op = OPC_SRL;
16736                 goto do_shifti;
16737             case ROTR:
16738                 mips32_op = OPC_ROTR;
16739             do_shifti:
16740                 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
16741                 break;
16742             case SELEQZ:
16743                 check_insn(ctx, ISA_MIPS32R6);
16744                 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
16745                 break;
16746             case SELNEZ:
16747                 check_insn(ctx, ISA_MIPS32R6);
16748                 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
16749                 break;
16750             case R6_RDHWR:
16751                 check_insn(ctx, ISA_MIPS32R6);
16752                 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
16753                 break;
16754             default:
16755                 goto pool32a_invalid;
16756             }
16757             break;
16758         case 0x10:
16759             minor = (ctx->opcode >> 6) & 0xf;
16760             switch (minor) {
16761                 /* Arithmetic */
16762             case ADD:
16763                 mips32_op = OPC_ADD;
16764                 goto do_arith;
16765             case ADDU32:
16766                 mips32_op = OPC_ADDU;
16767                 goto do_arith;
16768             case SUB:
16769                 mips32_op = OPC_SUB;
16770                 goto do_arith;
16771             case SUBU32:
16772                 mips32_op = OPC_SUBU;
16773                 goto do_arith;
16774             case MUL:
16775                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16776                 mips32_op = OPC_MUL;
16777             do_arith:
16778                 gen_arith(ctx, mips32_op, rd, rs, rt);
16779                 break;
16780                 /* Shifts */
16781             case SLLV:
16782                 mips32_op = OPC_SLLV;
16783                 goto do_shift;
16784             case SRLV:
16785                 mips32_op = OPC_SRLV;
16786                 goto do_shift;
16787             case SRAV:
16788                 mips32_op = OPC_SRAV;
16789                 goto do_shift;
16790             case ROTRV:
16791                 mips32_op = OPC_ROTRV;
16792             do_shift:
16793                 gen_shift(ctx, mips32_op, rd, rs, rt);
16794                 break;
16795                 /* Logical operations */
16796             case AND:
16797                 mips32_op = OPC_AND;
16798                 goto do_logic;
16799             case OR32:
16800                 mips32_op = OPC_OR;
16801                 goto do_logic;
16802             case NOR:
16803                 mips32_op = OPC_NOR;
16804                 goto do_logic;
16805             case XOR32:
16806                 mips32_op = OPC_XOR;
16807             do_logic:
16808                 gen_logic(ctx, mips32_op, rd, rs, rt);
16809                 break;
16810                 /* Set less than */
16811             case SLT:
16812                 mips32_op = OPC_SLT;
16813                 goto do_slt;
16814             case SLTU:
16815                 mips32_op = OPC_SLTU;
16816             do_slt:
16817                 gen_slt(ctx, mips32_op, rd, rs, rt);
16818                 break;
16819             default:
16820                 goto pool32a_invalid;
16821             }
16822             break;
16823         case 0x18:
16824             minor = (ctx->opcode >> 6) & 0xf;
16825             switch (minor) {
16826                 /* Conditional moves */
16827             case MOVN: /* MUL */
16828                 if (ctx->insn_flags & ISA_MIPS32R6) {
16829                     /* MUL */
16830                     gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
16831                 } else {
16832                     /* MOVN */
16833                     gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
16834                 }
16835                 break;
16836             case MOVZ: /* MUH */
16837                 if (ctx->insn_flags & ISA_MIPS32R6) {
16838                     /* MUH */
16839                     gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
16840                 } else {
16841                     /* MOVZ */
16842                     gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
16843                 }
16844                 break;
16845             case MULU:
16846                 check_insn(ctx, ISA_MIPS32R6);
16847                 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
16848                 break;
16849             case MUHU:
16850                 check_insn(ctx, ISA_MIPS32R6);
16851                 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
16852                 break;
16853             case LWXS: /* DIV */
16854                 if (ctx->insn_flags & ISA_MIPS32R6) {
16855                     /* DIV */
16856                     gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
16857                 } else {
16858                     /* LWXS */
16859                     gen_ldxs(ctx, rs, rt, rd);
16860                 }
16861                 break;
16862             case MOD:
16863                 check_insn(ctx, ISA_MIPS32R6);
16864                 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
16865                 break;
16866             case R6_DIVU:
16867                 check_insn(ctx, ISA_MIPS32R6);
16868                 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
16869                 break;
16870             case MODU:
16871                 check_insn(ctx, ISA_MIPS32R6);
16872                 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
16873                 break;
16874             default:
16875                 goto pool32a_invalid;
16876             }
16877             break;
16878         case INS:
16879             gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
16880             return;
16881         case LSA:
16882             check_insn(ctx, ISA_MIPS32R6);
16883             gen_lsa(ctx, OPC_LSA, rd, rs, rt,
16884                     extract32(ctx->opcode, 9, 2));
16885             break;
16886         case ALIGN:
16887             check_insn(ctx, ISA_MIPS32R6);
16888             gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2));
16889             break;
16890         case EXT:
16891             gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
16892             return;
16893         case POOL32AXF:
16894             gen_pool32axf(env, ctx, rt, rs);
16895             break;
16896         case BREAK32:
16897             generate_exception_end(ctx, EXCP_BREAK);
16898             break;
16899         case SIGRIE:
16900             check_insn(ctx, ISA_MIPS32R6);
16901             generate_exception_end(ctx, EXCP_RI);
16902             break;
16903         default:
16904         pool32a_invalid:
16905                 MIPS_INVAL("pool32a");
16906                 generate_exception_end(ctx, EXCP_RI);
16907                 break;
16908         }
16909         break;
16910     case POOL32B:
16911         minor = (ctx->opcode >> 12) & 0xf;
16912         switch (minor) {
16913         case CACHE:
16914             check_cp0_enabled(ctx);
16915             if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
16916                 gen_cache_operation(ctx, rt, rs, imm);
16917             }
16918             break;
16919         case LWC2:
16920         case SWC2:
16921             /* COP2: Not implemented. */
16922             generate_exception_err(ctx, EXCP_CpU, 2);
16923             break;
16924 #ifdef TARGET_MIPS64
16925         case LDP:
16926         case SDP:
16927             check_insn(ctx, ISA_MIPS3);
16928             check_mips_64(ctx);
16929 #endif
16930             /* fall through */
16931         case LWP:
16932         case SWP:
16933             gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
16934             break;
16935 #ifdef TARGET_MIPS64
16936         case LDM:
16937         case SDM:
16938             check_insn(ctx, ISA_MIPS3);
16939             check_mips_64(ctx);
16940 #endif
16941             /* fall through */
16942         case LWM32:
16943         case SWM32:
16944             gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
16945             break;
16946         default:
16947             MIPS_INVAL("pool32b");
16948             generate_exception_end(ctx, EXCP_RI);
16949             break;
16950         }
16951         break;
16952     case POOL32F:
16953         if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
16954             minor = ctx->opcode & 0x3f;
16955             check_cp1_enabled(ctx);
16956             switch (minor) {
16957             case ALNV_PS:
16958                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16959                 mips32_op = OPC_ALNV_PS;
16960                 goto do_madd;
16961             case MADD_S:
16962                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16963                 mips32_op = OPC_MADD_S;
16964                 goto do_madd;
16965             case MADD_D:
16966                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16967                 mips32_op = OPC_MADD_D;
16968                 goto do_madd;
16969             case MADD_PS:
16970                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16971                 mips32_op = OPC_MADD_PS;
16972                 goto do_madd;
16973             case MSUB_S:
16974                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16975                 mips32_op = OPC_MSUB_S;
16976                 goto do_madd;
16977             case MSUB_D:
16978                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16979                 mips32_op = OPC_MSUB_D;
16980                 goto do_madd;
16981             case MSUB_PS:
16982                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16983                 mips32_op = OPC_MSUB_PS;
16984                 goto do_madd;
16985             case NMADD_S:
16986                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16987                 mips32_op = OPC_NMADD_S;
16988                 goto do_madd;
16989             case NMADD_D:
16990                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16991                 mips32_op = OPC_NMADD_D;
16992                 goto do_madd;
16993             case NMADD_PS:
16994                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16995                 mips32_op = OPC_NMADD_PS;
16996                 goto do_madd;
16997             case NMSUB_S:
16998                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16999                 mips32_op = OPC_NMSUB_S;
17000                 goto do_madd;
17001             case NMSUB_D:
17002                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17003                 mips32_op = OPC_NMSUB_D;
17004                 goto do_madd;
17005             case NMSUB_PS:
17006                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17007                 mips32_op = OPC_NMSUB_PS;
17008             do_madd:
17009                 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
17010                 break;
17011             case CABS_COND_FMT:
17012                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17013                 cond = (ctx->opcode >> 6) & 0xf;
17014                 cc = (ctx->opcode >> 13) & 0x7;
17015                 fmt = (ctx->opcode >> 10) & 0x3;
17016                 switch (fmt) {
17017                 case 0x0:
17018                     gen_cmpabs_s(ctx, cond, rt, rs, cc);
17019                     break;
17020                 case 0x1:
17021                     gen_cmpabs_d(ctx, cond, rt, rs, cc);
17022                     break;
17023                 case 0x2:
17024                     gen_cmpabs_ps(ctx, cond, rt, rs, cc);
17025                     break;
17026                 default:
17027                     goto pool32f_invalid;
17028                 }
17029                 break;
17030             case C_COND_FMT:
17031                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17032                 cond = (ctx->opcode >> 6) & 0xf;
17033                 cc = (ctx->opcode >> 13) & 0x7;
17034                 fmt = (ctx->opcode >> 10) & 0x3;
17035                 switch (fmt) {
17036                 case 0x0:
17037                     gen_cmp_s(ctx, cond, rt, rs, cc);
17038                     break;
17039                 case 0x1:
17040                     gen_cmp_d(ctx, cond, rt, rs, cc);
17041                     break;
17042                 case 0x2:
17043                     gen_cmp_ps(ctx, cond, rt, rs, cc);
17044                     break;
17045                 default:
17046                     goto pool32f_invalid;
17047                 }
17048                 break;
17049             case CMP_CONDN_S:
17050                 check_insn(ctx, ISA_MIPS32R6);
17051                 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
17052                 break;
17053             case CMP_CONDN_D:
17054                 check_insn(ctx, ISA_MIPS32R6);
17055                 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
17056                 break;
17057             case POOL32FXF:
17058                 gen_pool32fxf(ctx, rt, rs);
17059                 break;
17060             case 0x00:
17061                 /* PLL foo */
17062                 switch ((ctx->opcode >> 6) & 0x7) {
17063                 case PLL_PS:
17064                     mips32_op = OPC_PLL_PS;
17065                     goto do_ps;
17066                 case PLU_PS:
17067                     mips32_op = OPC_PLU_PS;
17068                     goto do_ps;
17069                 case PUL_PS:
17070                     mips32_op = OPC_PUL_PS;
17071                     goto do_ps;
17072                 case PUU_PS:
17073                     mips32_op = OPC_PUU_PS;
17074                     goto do_ps;
17075                 case CVT_PS_S:
17076                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
17077                     mips32_op = OPC_CVT_PS_S;
17078                 do_ps:
17079                     gen_farith(ctx, mips32_op, rt, rs, rd, 0);
17080                     break;
17081                 default:
17082                     goto pool32f_invalid;
17083                 }
17084                 break;
17085             case MIN_FMT:
17086                 check_insn(ctx, ISA_MIPS32R6);
17087                 switch ((ctx->opcode >> 9) & 0x3) {
17088                 case FMT_SDPS_S:
17089                     gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
17090                     break;
17091                 case FMT_SDPS_D:
17092                     gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
17093                     break;
17094                 default:
17095                     goto pool32f_invalid;
17096                 }
17097                 break;
17098             case 0x08:
17099                 /* [LS][WDU]XC1 */
17100                 switch ((ctx->opcode >> 6) & 0x7) {
17101                 case LWXC1:
17102                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
17103                     mips32_op = OPC_LWXC1;
17104                     goto do_ldst_cp1;
17105                 case SWXC1:
17106                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
17107                     mips32_op = OPC_SWXC1;
17108                     goto do_ldst_cp1;
17109                 case LDXC1:
17110                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
17111                     mips32_op = OPC_LDXC1;
17112                     goto do_ldst_cp1;
17113                 case SDXC1:
17114                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
17115                     mips32_op = OPC_SDXC1;
17116                     goto do_ldst_cp1;
17117                 case LUXC1:
17118                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
17119                     mips32_op = OPC_LUXC1;
17120                     goto do_ldst_cp1;
17121                 case SUXC1:
17122                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
17123                     mips32_op = OPC_SUXC1;
17124                 do_ldst_cp1:
17125                     gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
17126                     break;
17127                 default:
17128                     goto pool32f_invalid;
17129                 }
17130                 break;
17131             case MAX_FMT:
17132                 check_insn(ctx, ISA_MIPS32R6);
17133                 switch ((ctx->opcode >> 9) & 0x3) {
17134                 case FMT_SDPS_S:
17135                     gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
17136                     break;
17137                 case FMT_SDPS_D:
17138                     gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
17139                     break;
17140                 default:
17141                     goto pool32f_invalid;
17142                 }
17143                 break;
17144             case 0x18:
17145                 /* 3D insns */
17146                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17147                 fmt = (ctx->opcode >> 9) & 0x3;
17148                 switch ((ctx->opcode >> 6) & 0x7) {
17149                 case RSQRT2_FMT:
17150                     switch (fmt) {
17151                     case FMT_SDPS_S:
17152                         mips32_op = OPC_RSQRT2_S;
17153                         goto do_3d;
17154                     case FMT_SDPS_D:
17155                         mips32_op = OPC_RSQRT2_D;
17156                         goto do_3d;
17157                     case FMT_SDPS_PS:
17158                         mips32_op = OPC_RSQRT2_PS;
17159                         goto do_3d;
17160                     default:
17161                         goto pool32f_invalid;
17162                     }
17163                     break;
17164                 case RECIP2_FMT:
17165                     switch (fmt) {
17166                     case FMT_SDPS_S:
17167                         mips32_op = OPC_RECIP2_S;
17168                         goto do_3d;
17169                     case FMT_SDPS_D:
17170                         mips32_op = OPC_RECIP2_D;
17171                         goto do_3d;
17172                     case FMT_SDPS_PS:
17173                         mips32_op = OPC_RECIP2_PS;
17174                         goto do_3d;
17175                     default:
17176                         goto pool32f_invalid;
17177                     }
17178                     break;
17179                 case ADDR_PS:
17180                     mips32_op = OPC_ADDR_PS;
17181                     goto do_3d;
17182                 case MULR_PS:
17183                     mips32_op = OPC_MULR_PS;
17184                 do_3d:
17185                     gen_farith(ctx, mips32_op, rt, rs, rd, 0);
17186                     break;
17187                 default:
17188                     goto pool32f_invalid;
17189                 }
17190                 break;
17191             case 0x20:
17192                 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
17193                 cc = (ctx->opcode >> 13) & 0x7;
17194                 fmt = (ctx->opcode >> 9) & 0x3;
17195                 switch ((ctx->opcode >> 6) & 0x7) {
17196                 case MOVF_FMT: /* RINT_FMT */
17197                     if (ctx->insn_flags & ISA_MIPS32R6) {
17198                         /* RINT_FMT */
17199                         switch (fmt) {
17200                         case FMT_SDPS_S:
17201                             gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
17202                             break;
17203                         case FMT_SDPS_D:
17204                             gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
17205                             break;
17206                         default:
17207                             goto pool32f_invalid;
17208                         }
17209                     } else {
17210                         /* MOVF_FMT */
17211                         switch (fmt) {
17212                         case FMT_SDPS_S:
17213                             gen_movcf_s(ctx, rs, rt, cc, 0);
17214                             break;
17215                         case FMT_SDPS_D:
17216                             gen_movcf_d(ctx, rs, rt, cc, 0);
17217                             break;
17218                         case FMT_SDPS_PS:
17219                             check_ps(ctx);
17220                             gen_movcf_ps(ctx, rs, rt, cc, 0);
17221                             break;
17222                         default:
17223                             goto pool32f_invalid;
17224                         }
17225                     }
17226                     break;
17227                 case MOVT_FMT: /* CLASS_FMT */
17228                     if (ctx->insn_flags & ISA_MIPS32R6) {
17229                         /* CLASS_FMT */
17230                         switch (fmt) {
17231                         case FMT_SDPS_S:
17232                             gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
17233                             break;
17234                         case FMT_SDPS_D:
17235                             gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
17236                             break;
17237                         default:
17238                             goto pool32f_invalid;
17239                         }
17240                     } else {
17241                         /* MOVT_FMT */
17242                         switch (fmt) {
17243                         case FMT_SDPS_S:
17244                             gen_movcf_s(ctx, rs, rt, cc, 1);
17245                             break;
17246                         case FMT_SDPS_D:
17247                             gen_movcf_d(ctx, rs, rt, cc, 1);
17248                             break;
17249                         case FMT_SDPS_PS:
17250                             check_ps(ctx);
17251                             gen_movcf_ps(ctx, rs, rt, cc, 1);
17252                             break;
17253                         default:
17254                             goto pool32f_invalid;
17255                         }
17256                     }
17257                     break;
17258                 case PREFX:
17259                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
17260                     break;
17261                 default:
17262                     goto pool32f_invalid;
17263                 }
17264                 break;
17265 #define FINSN_3ARG_SDPS(prfx)                           \
17266                 switch ((ctx->opcode >> 8) & 0x3) {     \
17267                 case FMT_SDPS_S:                        \
17268                     mips32_op = OPC_##prfx##_S;         \
17269                     goto do_fpop;                       \
17270                 case FMT_SDPS_D:                        \
17271                     mips32_op = OPC_##prfx##_D;         \
17272                     goto do_fpop;                       \
17273                 case FMT_SDPS_PS:                       \
17274                     check_ps(ctx);                      \
17275                     mips32_op = OPC_##prfx##_PS;        \
17276                     goto do_fpop;                       \
17277                 default:                                \
17278                     goto pool32f_invalid;               \
17279                 }
17280             case MINA_FMT:
17281                 check_insn(ctx, ISA_MIPS32R6);
17282                 switch ((ctx->opcode >> 9) & 0x3) {
17283                 case FMT_SDPS_S:
17284                     gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
17285                     break;
17286                 case FMT_SDPS_D:
17287                     gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
17288                     break;
17289                 default:
17290                     goto pool32f_invalid;
17291                 }
17292                 break;
17293             case MAXA_FMT:
17294                 check_insn(ctx, ISA_MIPS32R6);
17295                 switch ((ctx->opcode >> 9) & 0x3) {
17296                 case FMT_SDPS_S:
17297                     gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
17298                     break;
17299                 case FMT_SDPS_D:
17300                     gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
17301                     break;
17302                 default:
17303                     goto pool32f_invalid;
17304                 }
17305                 break;
17306             case 0x30:
17307                 /* regular FP ops */
17308                 switch ((ctx->opcode >> 6) & 0x3) {
17309                 case ADD_FMT:
17310                     FINSN_3ARG_SDPS(ADD);
17311                     break;
17312                 case SUB_FMT:
17313                     FINSN_3ARG_SDPS(SUB);
17314                     break;
17315                 case MUL_FMT:
17316                     FINSN_3ARG_SDPS(MUL);
17317                     break;
17318                 case DIV_FMT:
17319                     fmt = (ctx->opcode >> 8) & 0x3;
17320                     if (fmt == 1) {
17321                         mips32_op = OPC_DIV_D;
17322                     } else if (fmt == 0) {
17323                         mips32_op = OPC_DIV_S;
17324                     } else {
17325                         goto pool32f_invalid;
17326                     }
17327                     goto do_fpop;
17328                 default:
17329                     goto pool32f_invalid;
17330                 }
17331                 break;
17332             case 0x38:
17333                 /* cmovs */
17334                 switch ((ctx->opcode >> 6) & 0x7) {
17335                 case MOVN_FMT: /* SELEQZ_FMT */
17336                     if (ctx->insn_flags & ISA_MIPS32R6) {
17337                         /* SELEQZ_FMT */
17338                         switch ((ctx->opcode >> 9) & 0x3) {
17339                         case FMT_SDPS_S:
17340                             gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
17341                             break;
17342                         case FMT_SDPS_D:
17343                             gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
17344                             break;
17345                         default:
17346                             goto pool32f_invalid;
17347                         }
17348                     } else {
17349                         /* MOVN_FMT */
17350                         FINSN_3ARG_SDPS(MOVN);
17351                     }
17352                     break;
17353                 case MOVN_FMT_04:
17354                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
17355                     FINSN_3ARG_SDPS(MOVN);
17356                     break;
17357                 case MOVZ_FMT: /* SELNEZ_FMT */
17358                     if (ctx->insn_flags & ISA_MIPS32R6) {
17359                         /* SELNEZ_FMT */
17360                         switch ((ctx->opcode >> 9) & 0x3) {
17361                         case FMT_SDPS_S:
17362                             gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
17363                             break;
17364                         case FMT_SDPS_D:
17365                             gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
17366                             break;
17367                         default:
17368                             goto pool32f_invalid;
17369                         }
17370                     } else {
17371                         /* MOVZ_FMT */
17372                         FINSN_3ARG_SDPS(MOVZ);
17373                     }
17374                     break;
17375                 case MOVZ_FMT_05:
17376                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
17377                     FINSN_3ARG_SDPS(MOVZ);
17378                     break;
17379                 case SEL_FMT:
17380                     check_insn(ctx, ISA_MIPS32R6);
17381                     switch ((ctx->opcode >> 9) & 0x3) {
17382                     case FMT_SDPS_S:
17383                         gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
17384                         break;
17385                     case FMT_SDPS_D:
17386                         gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
17387                         break;
17388                     default:
17389                         goto pool32f_invalid;
17390                     }
17391                     break;
17392                 case MADDF_FMT:
17393                     check_insn(ctx, ISA_MIPS32R6);
17394                     switch ((ctx->opcode >> 9) & 0x3) {
17395                     case FMT_SDPS_S:
17396                         mips32_op = OPC_MADDF_S;
17397                         goto do_fpop;
17398                     case FMT_SDPS_D:
17399                         mips32_op = OPC_MADDF_D;
17400                         goto do_fpop;
17401                     default:
17402                         goto pool32f_invalid;
17403                     }
17404                     break;
17405                 case MSUBF_FMT:
17406                     check_insn(ctx, ISA_MIPS32R6);
17407                     switch ((ctx->opcode >> 9) & 0x3) {
17408                     case FMT_SDPS_S:
17409                         mips32_op = OPC_MSUBF_S;
17410                         goto do_fpop;
17411                     case FMT_SDPS_D:
17412                         mips32_op = OPC_MSUBF_D;
17413                         goto do_fpop;
17414                     default:
17415                         goto pool32f_invalid;
17416                     }
17417                     break;
17418                 default:
17419                     goto pool32f_invalid;
17420                 }
17421                 break;
17422             do_fpop:
17423                 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
17424                 break;
17425             default:
17426             pool32f_invalid:
17427                 MIPS_INVAL("pool32f");
17428                 generate_exception_end(ctx, EXCP_RI);
17429                 break;
17430             }
17431         } else {
17432             generate_exception_err(ctx, EXCP_CpU, 1);
17433         }
17434         break;
17435     case POOL32I:
17436         minor = (ctx->opcode >> 21) & 0x1f;
17437         switch (minor) {
17438         case BLTZ:
17439             check_insn_opc_removed(ctx, ISA_MIPS32R6);
17440             gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
17441             break;
17442         case BLTZAL:
17443             check_insn_opc_removed(ctx, ISA_MIPS32R6);
17444             gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
17445             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17446             break;
17447         case BLTZALS:
17448             check_insn_opc_removed(ctx, ISA_MIPS32R6);
17449             gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
17450             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17451             break;
17452         case BGEZ:
17453             check_insn_opc_removed(ctx, ISA_MIPS32R6);
17454             gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
17455             break;
17456         case BGEZAL:
17457             check_insn_opc_removed(ctx, ISA_MIPS32R6);
17458             gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
17459             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17460             break;
17461         case BGEZALS:
17462             check_insn_opc_removed(ctx, ISA_MIPS32R6);
17463             gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
17464             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17465             break;
17466         case BLEZ:
17467             check_insn_opc_removed(ctx, ISA_MIPS32R6);
17468             gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
17469             break;
17470         case BGTZ:
17471             check_insn_opc_removed(ctx, ISA_MIPS32R6);
17472             gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
17473             break;
17474 
17475             /* Traps */
17476         case TLTI: /* BC1EQZC */
17477             if (ctx->insn_flags & ISA_MIPS32R6) {
17478                 /* BC1EQZC */
17479                 check_cp1_enabled(ctx);
17480                 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
17481             } else {
17482                 /* TLTI */
17483                 mips32_op = OPC_TLTI;
17484                 goto do_trapi;
17485             }
17486             break;
17487         case TGEI: /* BC1NEZC */
17488             if (ctx->insn_flags & ISA_MIPS32R6) {
17489                 /* BC1NEZC */
17490                 check_cp1_enabled(ctx);
17491                 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
17492             } else {
17493                 /* TGEI */
17494                 mips32_op = OPC_TGEI;
17495                 goto do_trapi;
17496             }
17497             break;
17498         case TLTIU:
17499             check_insn_opc_removed(ctx, ISA_MIPS32R6);
17500             mips32_op = OPC_TLTIU;
17501             goto do_trapi;
17502         case TGEIU:
17503             check_insn_opc_removed(ctx, ISA_MIPS32R6);
17504             mips32_op = OPC_TGEIU;
17505             goto do_trapi;
17506         case TNEI: /* SYNCI */
17507             if (ctx->insn_flags & ISA_MIPS32R6) {
17508                 /* SYNCI */
17509                 /*
17510                  * Break the TB to be able to sync copied instructions
17511                  * immediately.
17512                  */
17513                 ctx->base.is_jmp = DISAS_STOP;
17514             } else {
17515                 /* TNEI */
17516                 mips32_op = OPC_TNEI;
17517                 goto do_trapi;
17518             }
17519             break;
17520         case TEQI:
17521             check_insn_opc_removed(ctx, ISA_MIPS32R6);
17522             mips32_op = OPC_TEQI;
17523         do_trapi:
17524             gen_trap(ctx, mips32_op, rs, -1, imm);
17525             break;
17526 
17527         case BNEZC:
17528         case BEQZC:
17529             check_insn_opc_removed(ctx, ISA_MIPS32R6);
17530             gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
17531                                4, rs, 0, imm << 1, 0);
17532             /*
17533              * Compact branches don't have a delay slot, so just let
17534              * the normal delay slot handling take us to the branch
17535              * target.
17536              */
17537             break;
17538         case LUI:
17539             check_insn_opc_removed(ctx, ISA_MIPS32R6);
17540             gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
17541             break;
17542         case SYNCI:
17543             check_insn_opc_removed(ctx, ISA_MIPS32R6);
17544             /*
17545              * Break the TB to be able to sync copied instructions
17546              * immediately.
17547              */
17548             ctx->base.is_jmp = DISAS_STOP;
17549             break;
17550         case BC2F:
17551         case BC2T:
17552             check_insn_opc_removed(ctx, ISA_MIPS32R6);
17553             /* COP2: Not implemented. */
17554             generate_exception_err(ctx, EXCP_CpU, 2);
17555             break;
17556         case BC1F:
17557             check_insn_opc_removed(ctx, ISA_MIPS32R6);
17558             mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
17559             goto do_cp1branch;
17560         case BC1T:
17561             check_insn_opc_removed(ctx, ISA_MIPS32R6);
17562             mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
17563             goto do_cp1branch;
17564         case BC1ANY4F:
17565             check_insn_opc_removed(ctx, ISA_MIPS32R6);
17566             mips32_op = OPC_BC1FANY4;
17567             goto do_cp1mips3d;
17568         case BC1ANY4T:
17569             check_insn_opc_removed(ctx, ISA_MIPS32R6);
17570             mips32_op = OPC_BC1TANY4;
17571         do_cp1mips3d:
17572             check_cop1x(ctx);
17573             check_insn(ctx, ASE_MIPS3D);
17574             /* Fall through */
17575         do_cp1branch:
17576             if (env->CP0_Config1 & (1 << CP0C1_FP)) {
17577                 check_cp1_enabled(ctx);
17578                 gen_compute_branch1(ctx, mips32_op,
17579                                     (ctx->opcode >> 18) & 0x7, imm << 1);
17580             } else {
17581                 generate_exception_err(ctx, EXCP_CpU, 1);
17582             }
17583             break;
17584         case BPOSGE64:
17585         case BPOSGE32:
17586             /* MIPS DSP: not implemented */
17587             /* Fall through */
17588         default:
17589             MIPS_INVAL("pool32i");
17590             generate_exception_end(ctx, EXCP_RI);
17591             break;
17592         }
17593         break;
17594     case POOL32C:
17595         minor = (ctx->opcode >> 12) & 0xf;
17596         offset = sextract32(ctx->opcode, 0,
17597                             (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
17598         switch (minor) {
17599         case LWL:
17600             check_insn_opc_removed(ctx, ISA_MIPS32R6);
17601             mips32_op = OPC_LWL;
17602             goto do_ld_lr;
17603         case SWL:
17604             check_insn_opc_removed(ctx, ISA_MIPS32R6);
17605             mips32_op = OPC_SWL;
17606             goto do_st_lr;
17607         case LWR:
17608             check_insn_opc_removed(ctx, ISA_MIPS32R6);
17609             mips32_op = OPC_LWR;
17610             goto do_ld_lr;
17611         case SWR:
17612             check_insn_opc_removed(ctx, ISA_MIPS32R6);
17613             mips32_op = OPC_SWR;
17614             goto do_st_lr;
17615 #if defined(TARGET_MIPS64)
17616         case LDL:
17617             check_insn(ctx, ISA_MIPS3);
17618             check_mips_64(ctx);
17619             check_insn_opc_removed(ctx, ISA_MIPS32R6);
17620             mips32_op = OPC_LDL;
17621             goto do_ld_lr;
17622         case SDL:
17623             check_insn(ctx, ISA_MIPS3);
17624             check_mips_64(ctx);
17625             check_insn_opc_removed(ctx, ISA_MIPS32R6);
17626             mips32_op = OPC_SDL;
17627             goto do_st_lr;
17628         case LDR:
17629             check_insn(ctx, ISA_MIPS3);
17630             check_mips_64(ctx);
17631             check_insn_opc_removed(ctx, ISA_MIPS32R6);
17632             mips32_op = OPC_LDR;
17633             goto do_ld_lr;
17634         case SDR:
17635             check_insn(ctx, ISA_MIPS3);
17636             check_mips_64(ctx);
17637             check_insn_opc_removed(ctx, ISA_MIPS32R6);
17638             mips32_op = OPC_SDR;
17639             goto do_st_lr;
17640         case LWU:
17641             check_insn(ctx, ISA_MIPS3);
17642             check_mips_64(ctx);
17643             mips32_op = OPC_LWU;
17644             goto do_ld_lr;
17645         case LLD:
17646             check_insn(ctx, ISA_MIPS3);
17647             check_mips_64(ctx);
17648             mips32_op = OPC_LLD;
17649             goto do_ld_lr;
17650 #endif
17651         case LL:
17652             mips32_op = OPC_LL;
17653             goto do_ld_lr;
17654         do_ld_lr:
17655             gen_ld(ctx, mips32_op, rt, rs, offset);
17656             break;
17657         do_st_lr:
17658             gen_st(ctx, mips32_op, rt, rs, offset);
17659             break;
17660         case SC:
17661             gen_st_cond(ctx, rt, rs, offset, MO_TESL, false);
17662             break;
17663 #if defined(TARGET_MIPS64)
17664         case SCD:
17665             check_insn(ctx, ISA_MIPS3);
17666             check_mips_64(ctx);
17667             gen_st_cond(ctx, rt, rs, offset, MO_TEQ, false);
17668             break;
17669 #endif
17670         case LD_EVA:
17671             if (!ctx->eva) {
17672                 MIPS_INVAL("pool32c ld-eva");
17673                 generate_exception_end(ctx, EXCP_RI);
17674                 break;
17675             }
17676             check_cp0_enabled(ctx);
17677 
17678             minor2 = (ctx->opcode >> 9) & 0x7;
17679             offset = sextract32(ctx->opcode, 0, 9);
17680             switch (minor2) {
17681             case LBUE:
17682                 mips32_op = OPC_LBUE;
17683                 goto do_ld_lr;
17684             case LHUE:
17685                 mips32_op = OPC_LHUE;
17686                 goto do_ld_lr;
17687             case LWLE:
17688                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17689                 mips32_op = OPC_LWLE;
17690                 goto do_ld_lr;
17691             case LWRE:
17692                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17693                 mips32_op = OPC_LWRE;
17694                 goto do_ld_lr;
17695             case LBE:
17696                 mips32_op = OPC_LBE;
17697                 goto do_ld_lr;
17698             case LHE:
17699                 mips32_op = OPC_LHE;
17700                 goto do_ld_lr;
17701             case LLE:
17702                 mips32_op = OPC_LLE;
17703                 goto do_ld_lr;
17704             case LWE:
17705                 mips32_op = OPC_LWE;
17706                 goto do_ld_lr;
17707             };
17708             break;
17709         case ST_EVA:
17710             if (!ctx->eva) {
17711                 MIPS_INVAL("pool32c st-eva");
17712                 generate_exception_end(ctx, EXCP_RI);
17713                 break;
17714             }
17715             check_cp0_enabled(ctx);
17716 
17717             minor2 = (ctx->opcode >> 9) & 0x7;
17718             offset = sextract32(ctx->opcode, 0, 9);
17719             switch (minor2) {
17720             case SWLE:
17721                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17722                 mips32_op = OPC_SWLE;
17723                 goto do_st_lr;
17724             case SWRE:
17725                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17726                 mips32_op = OPC_SWRE;
17727                 goto do_st_lr;
17728             case PREFE:
17729                 /* Treat as no-op */
17730                 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
17731                     /* hint codes 24-31 are reserved and signal RI */
17732                     generate_exception(ctx, EXCP_RI);
17733                 }
17734                 break;
17735             case CACHEE:
17736                 /* Treat as no-op */
17737                 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
17738                     gen_cache_operation(ctx, rt, rs, offset);
17739                 }
17740                 break;
17741             case SBE:
17742                 mips32_op = OPC_SBE;
17743                 goto do_st_lr;
17744             case SHE:
17745                 mips32_op = OPC_SHE;
17746                 goto do_st_lr;
17747             case SCE:
17748                 gen_st_cond(ctx, rt, rs, offset, MO_TESL, true);
17749                 break;
17750             case SWE:
17751                 mips32_op = OPC_SWE;
17752                 goto do_st_lr;
17753             };
17754             break;
17755         case PREF:
17756             /* Treat as no-op */
17757             if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
17758                 /* hint codes 24-31 are reserved and signal RI */
17759                 generate_exception(ctx, EXCP_RI);
17760             }
17761             break;
17762         default:
17763             MIPS_INVAL("pool32c");
17764             generate_exception_end(ctx, EXCP_RI);
17765             break;
17766         }
17767         break;
17768     case ADDI32: /* AUI, LUI */
17769         if (ctx->insn_flags & ISA_MIPS32R6) {
17770             /* AUI, LUI */
17771             gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
17772         } else {
17773             /* ADDI32 */
17774             mips32_op = OPC_ADDI;
17775             goto do_addi;
17776         }
17777         break;
17778     case ADDIU32:
17779         mips32_op = OPC_ADDIU;
17780     do_addi:
17781         gen_arith_imm(ctx, mips32_op, rt, rs, imm);
17782         break;
17783 
17784         /* Logical operations */
17785     case ORI32:
17786         mips32_op = OPC_ORI;
17787         goto do_logici;
17788     case XORI32:
17789         mips32_op = OPC_XORI;
17790         goto do_logici;
17791     case ANDI32:
17792         mips32_op = OPC_ANDI;
17793     do_logici:
17794         gen_logic_imm(ctx, mips32_op, rt, rs, imm);
17795         break;
17796 
17797         /* Set less than immediate */
17798     case SLTI32:
17799         mips32_op = OPC_SLTI;
17800         goto do_slti;
17801     case SLTIU32:
17802         mips32_op = OPC_SLTIU;
17803     do_slti:
17804         gen_slt_imm(ctx, mips32_op, rt, rs, imm);
17805         break;
17806     case JALX32:
17807         check_insn_opc_removed(ctx, ISA_MIPS32R6);
17808         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
17809         gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
17810         ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17811         break;
17812     case JALS32: /* BOVC, BEQC, BEQZALC */
17813         if (ctx->insn_flags & ISA_MIPS32R6) {
17814             if (rs >= rt) {
17815                 /* BOVC */
17816                 mips32_op = OPC_BOVC;
17817             } else if (rs < rt && rs == 0) {
17818                 /* BEQZALC */
17819                 mips32_op = OPC_BEQZALC;
17820             } else {
17821                 /* BEQC */
17822                 mips32_op = OPC_BEQC;
17823             }
17824             gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17825         } else {
17826             /* JALS32 */
17827             offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
17828             gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
17829             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17830         }
17831         break;
17832     case BEQ32: /* BC */
17833         if (ctx->insn_flags & ISA_MIPS32R6) {
17834             /* BC */
17835             gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
17836                                        sextract32(ctx->opcode << 1, 0, 27));
17837         } else {
17838             /* BEQ32 */
17839             gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
17840         }
17841         break;
17842     case BNE32: /* BALC */
17843         if (ctx->insn_flags & ISA_MIPS32R6) {
17844             /* BALC */
17845             gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
17846                                        sextract32(ctx->opcode << 1, 0, 27));
17847         } else {
17848             /* BNE32 */
17849             gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
17850         }
17851         break;
17852     case J32: /* BGTZC, BLTZC, BLTC */
17853         if (ctx->insn_flags & ISA_MIPS32R6) {
17854             if (rs == 0 && rt != 0) {
17855                 /* BGTZC */
17856                 mips32_op = OPC_BGTZC;
17857             } else if (rs != 0 && rt != 0 && rs == rt) {
17858                 /* BLTZC */
17859                 mips32_op = OPC_BLTZC;
17860             } else {
17861                 /* BLTC */
17862                 mips32_op = OPC_BLTC;
17863             }
17864             gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17865         } else {
17866             /* J32 */
17867             gen_compute_branch(ctx, OPC_J, 4, rt, rs,
17868                                (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
17869         }
17870         break;
17871     case JAL32: /* BLEZC, BGEZC, BGEC */
17872         if (ctx->insn_flags & ISA_MIPS32R6) {
17873             if (rs == 0 && rt != 0) {
17874                 /* BLEZC */
17875                 mips32_op = OPC_BLEZC;
17876             } else if (rs != 0 && rt != 0 && rs == rt) {
17877                 /* BGEZC */
17878                 mips32_op = OPC_BGEZC;
17879             } else {
17880                 /* BGEC */
17881                 mips32_op = OPC_BGEC;
17882             }
17883             gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17884         } else {
17885             /* JAL32 */
17886             gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
17887                                (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
17888             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17889         }
17890         break;
17891         /* Floating point (COP1) */
17892     case LWC132:
17893         mips32_op = OPC_LWC1;
17894         goto do_cop1;
17895     case LDC132:
17896         mips32_op = OPC_LDC1;
17897         goto do_cop1;
17898     case SWC132:
17899         mips32_op = OPC_SWC1;
17900         goto do_cop1;
17901     case SDC132:
17902         mips32_op = OPC_SDC1;
17903     do_cop1:
17904         gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
17905         break;
17906     case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17907         if (ctx->insn_flags & ISA_MIPS32R6) {
17908             /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17909             switch ((ctx->opcode >> 16) & 0x1f) {
17910             case ADDIUPC_00:
17911             case ADDIUPC_01:
17912             case ADDIUPC_02:
17913             case ADDIUPC_03:
17914             case ADDIUPC_04:
17915             case ADDIUPC_05:
17916             case ADDIUPC_06:
17917             case ADDIUPC_07:
17918                 gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
17919                 break;
17920             case AUIPC:
17921                 gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
17922                 break;
17923             case ALUIPC:
17924                 gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
17925                 break;
17926             case LWPC_08:
17927             case LWPC_09:
17928             case LWPC_0A:
17929             case LWPC_0B:
17930             case LWPC_0C:
17931             case LWPC_0D:
17932             case LWPC_0E:
17933             case LWPC_0F:
17934                 gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
17935                 break;
17936             default:
17937                 generate_exception(ctx, EXCP_RI);
17938                 break;
17939             }
17940         } else {
17941             /* ADDIUPC */
17942             int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
17943             offset = SIMM(ctx->opcode, 0, 23) << 2;
17944 
17945             gen_addiupc(ctx, reg, offset, 0, 0);
17946         }
17947         break;
17948     case BNVC: /* BNEC, BNEZALC */
17949         check_insn(ctx, ISA_MIPS32R6);
17950         if (rs >= rt) {
17951             /* BNVC */
17952             mips32_op = OPC_BNVC;
17953         } else if (rs < rt && rs == 0) {
17954             /* BNEZALC */
17955             mips32_op = OPC_BNEZALC;
17956         } else {
17957             /* BNEC */
17958             mips32_op = OPC_BNEC;
17959         }
17960         gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17961         break;
17962     case R6_BNEZC: /* JIALC */
17963         check_insn(ctx, ISA_MIPS32R6);
17964         if (rt != 0) {
17965             /* BNEZC */
17966             gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
17967                                        sextract32(ctx->opcode << 1, 0, 22));
17968         } else {
17969             /* JIALC */
17970             gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
17971         }
17972         break;
17973     case R6_BEQZC: /* JIC */
17974         check_insn(ctx, ISA_MIPS32R6);
17975         if (rt != 0) {
17976             /* BEQZC */
17977             gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
17978                                        sextract32(ctx->opcode << 1, 0, 22));
17979         } else {
17980             /* JIC */
17981             gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
17982         }
17983         break;
17984     case BLEZALC: /* BGEZALC, BGEUC */
17985         check_insn(ctx, ISA_MIPS32R6);
17986         if (rs == 0 && rt != 0) {
17987             /* BLEZALC */
17988             mips32_op = OPC_BLEZALC;
17989         } else if (rs != 0 && rt != 0 && rs == rt) {
17990             /* BGEZALC */
17991             mips32_op = OPC_BGEZALC;
17992         } else {
17993             /* BGEUC */
17994             mips32_op = OPC_BGEUC;
17995         }
17996         gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17997         break;
17998     case BGTZALC: /* BLTZALC, BLTUC */
17999         check_insn(ctx, ISA_MIPS32R6);
18000         if (rs == 0 && rt != 0) {
18001             /* BGTZALC */
18002             mips32_op = OPC_BGTZALC;
18003         } else if (rs != 0 && rt != 0 && rs == rt) {
18004             /* BLTZALC */
18005             mips32_op = OPC_BLTZALC;
18006         } else {
18007             /* BLTUC */
18008             mips32_op = OPC_BLTUC;
18009         }
18010         gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
18011         break;
18012         /* Loads and stores */
18013     case LB32:
18014         mips32_op = OPC_LB;
18015         goto do_ld;
18016     case LBU32:
18017         mips32_op = OPC_LBU;
18018         goto do_ld;
18019     case LH32:
18020         mips32_op = OPC_LH;
18021         goto do_ld;
18022     case LHU32:
18023         mips32_op = OPC_LHU;
18024         goto do_ld;
18025     case LW32:
18026         mips32_op = OPC_LW;
18027         goto do_ld;
18028 #ifdef TARGET_MIPS64
18029     case LD32:
18030         check_insn(ctx, ISA_MIPS3);
18031         check_mips_64(ctx);
18032         mips32_op = OPC_LD;
18033         goto do_ld;
18034     case SD32:
18035         check_insn(ctx, ISA_MIPS3);
18036         check_mips_64(ctx);
18037         mips32_op = OPC_SD;
18038         goto do_st;
18039 #endif
18040     case SB32:
18041         mips32_op = OPC_SB;
18042         goto do_st;
18043     case SH32:
18044         mips32_op = OPC_SH;
18045         goto do_st;
18046     case SW32:
18047         mips32_op = OPC_SW;
18048         goto do_st;
18049     do_ld:
18050         gen_ld(ctx, mips32_op, rt, rs, imm);
18051         break;
18052     do_st:
18053         gen_st(ctx, mips32_op, rt, rs, imm);
18054         break;
18055     default:
18056         generate_exception_end(ctx, EXCP_RI);
18057         break;
18058     }
18059 }
18060 
decode_micromips_opc(CPUMIPSState * env,DisasContext * ctx)18061 static int decode_micromips_opc(CPUMIPSState *env, DisasContext *ctx)
18062 {
18063     uint32_t op;
18064 
18065     /* make sure instructions are on a halfword boundary */
18066     if (ctx->base.pc_next & 0x1) {
18067         env->CP0_BadVAddr = ctx->base.pc_next;
18068         generate_exception_end(ctx, EXCP_AdEL);
18069         return 2;
18070     }
18071 
18072     op = (ctx->opcode >> 10) & 0x3f;
18073     /* Enforce properly-sized instructions in a delay slot */
18074     if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
18075         switch (op & 0x7) { /* MSB-3..MSB-5 */
18076         case 0:
18077         /* POOL32A, POOL32B, POOL32I, POOL32C */
18078         case 4:
18079         /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
18080         case 5:
18081         /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
18082         case 6:
18083         /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
18084         case 7:
18085         /* LB32, LH32, LWC132, LDC132, LW32 */
18086             if (ctx->hflags & MIPS_HFLAG_BDS16) {
18087                 generate_exception_end(ctx, EXCP_RI);
18088                 return 2;
18089             }
18090             break;
18091         case 1:
18092         /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
18093         case 2:
18094         /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
18095         case 3:
18096         /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
18097             if (ctx->hflags & MIPS_HFLAG_BDS32) {
18098                 generate_exception_end(ctx, EXCP_RI);
18099                 return 2;
18100             }
18101             break;
18102         }
18103     }
18104 
18105     switch (op) {
18106     case POOL16A:
18107         {
18108             int rd = mmreg(uMIPS_RD(ctx->opcode));
18109             int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
18110             int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
18111             uint32_t opc = 0;
18112 
18113             switch (ctx->opcode & 0x1) {
18114             case ADDU16:
18115                 opc = OPC_ADDU;
18116                 break;
18117             case SUBU16:
18118                 opc = OPC_SUBU;
18119                 break;
18120             }
18121             if (ctx->insn_flags & ISA_MIPS32R6) {
18122                 /*
18123                  * In the Release 6, the register number location in
18124                  * the instruction encoding has changed.
18125                  */
18126                 gen_arith(ctx, opc, rs1, rd, rs2);
18127             } else {
18128                 gen_arith(ctx, opc, rd, rs1, rs2);
18129             }
18130         }
18131         break;
18132     case POOL16B:
18133         {
18134             int rd = mmreg(uMIPS_RD(ctx->opcode));
18135             int rs = mmreg(uMIPS_RS(ctx->opcode));
18136             int amount = (ctx->opcode >> 1) & 0x7;
18137             uint32_t opc = 0;
18138             amount = amount == 0 ? 8 : amount;
18139 
18140             switch (ctx->opcode & 0x1) {
18141             case SLL16:
18142                 opc = OPC_SLL;
18143                 break;
18144             case SRL16:
18145                 opc = OPC_SRL;
18146                 break;
18147             }
18148 
18149             gen_shift_imm(ctx, opc, rd, rs, amount);
18150         }
18151         break;
18152     case POOL16C:
18153         if (ctx->insn_flags & ISA_MIPS32R6) {
18154             gen_pool16c_r6_insn(ctx);
18155         } else {
18156             gen_pool16c_insn(ctx);
18157         }
18158         break;
18159     case LWGP16:
18160         {
18161             int rd = mmreg(uMIPS_RD(ctx->opcode));
18162             int rb = 28;            /* GP */
18163             int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
18164 
18165             gen_ld(ctx, OPC_LW, rd, rb, offset);
18166         }
18167         break;
18168     case POOL16F:
18169         check_insn_opc_removed(ctx, ISA_MIPS32R6);
18170         if (ctx->opcode & 1) {
18171             generate_exception_end(ctx, EXCP_RI);
18172         } else {
18173             /* MOVEP */
18174             int enc_dest = uMIPS_RD(ctx->opcode);
18175             int enc_rt = uMIPS_RS2(ctx->opcode);
18176             int enc_rs = uMIPS_RS1(ctx->opcode);
18177             gen_movep(ctx, enc_dest, enc_rt, enc_rs);
18178         }
18179         break;
18180     case LBU16:
18181         {
18182             int rd = mmreg(uMIPS_RD(ctx->opcode));
18183             int rb = mmreg(uMIPS_RS(ctx->opcode));
18184             int16_t offset = ZIMM(ctx->opcode, 0, 4);
18185             offset = (offset == 0xf ? -1 : offset);
18186 
18187             gen_ld(ctx, OPC_LBU, rd, rb, offset);
18188         }
18189         break;
18190     case LHU16:
18191         {
18192             int rd = mmreg(uMIPS_RD(ctx->opcode));
18193             int rb = mmreg(uMIPS_RS(ctx->opcode));
18194             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
18195 
18196             gen_ld(ctx, OPC_LHU, rd, rb, offset);
18197         }
18198         break;
18199     case LWSP16:
18200         {
18201             int rd = (ctx->opcode >> 5) & 0x1f;
18202             int rb = 29;            /* SP */
18203             int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
18204 
18205             gen_ld(ctx, OPC_LW, rd, rb, offset);
18206         }
18207         break;
18208     case LW16:
18209         {
18210             int rd = mmreg(uMIPS_RD(ctx->opcode));
18211             int rb = mmreg(uMIPS_RS(ctx->opcode));
18212             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
18213 
18214             gen_ld(ctx, OPC_LW, rd, rb, offset);
18215         }
18216         break;
18217     case SB16:
18218         {
18219             int rd = mmreg2(uMIPS_RD(ctx->opcode));
18220             int rb = mmreg(uMIPS_RS(ctx->opcode));
18221             int16_t offset = ZIMM(ctx->opcode, 0, 4);
18222 
18223             gen_st(ctx, OPC_SB, rd, rb, offset);
18224         }
18225         break;
18226     case SH16:
18227         {
18228             int rd = mmreg2(uMIPS_RD(ctx->opcode));
18229             int rb = mmreg(uMIPS_RS(ctx->opcode));
18230             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
18231 
18232             gen_st(ctx, OPC_SH, rd, rb, offset);
18233         }
18234         break;
18235     case SWSP16:
18236         {
18237             int rd = (ctx->opcode >> 5) & 0x1f;
18238             int rb = 29;            /* SP */
18239             int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
18240 
18241             gen_st(ctx, OPC_SW, rd, rb, offset);
18242         }
18243         break;
18244     case SW16:
18245         {
18246             int rd = mmreg2(uMIPS_RD(ctx->opcode));
18247             int rb = mmreg(uMIPS_RS(ctx->opcode));
18248             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
18249 
18250             gen_st(ctx, OPC_SW, rd, rb, offset);
18251         }
18252         break;
18253     case MOVE16:
18254         {
18255             int rd = uMIPS_RD5(ctx->opcode);
18256             int rs = uMIPS_RS5(ctx->opcode);
18257 
18258             gen_arith(ctx, OPC_ADDU, rd, rs, 0);
18259         }
18260         break;
18261     case ANDI16:
18262         gen_andi16(ctx);
18263         break;
18264     case POOL16D:
18265         switch (ctx->opcode & 0x1) {
18266         case ADDIUS5:
18267             gen_addius5(ctx);
18268             break;
18269         case ADDIUSP:
18270             gen_addiusp(ctx);
18271             break;
18272         }
18273         break;
18274     case POOL16E:
18275         switch (ctx->opcode & 0x1) {
18276         case ADDIUR2:
18277             gen_addiur2(ctx);
18278             break;
18279         case ADDIUR1SP:
18280             gen_addiur1sp(ctx);
18281             break;
18282         }
18283         break;
18284     case B16: /* BC16 */
18285         gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
18286                            sextract32(ctx->opcode, 0, 10) << 1,
18287                            (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
18288         break;
18289     case BNEZ16: /* BNEZC16 */
18290     case BEQZ16: /* BEQZC16 */
18291         gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
18292                            mmreg(uMIPS_RD(ctx->opcode)),
18293                            0, sextract32(ctx->opcode, 0, 7) << 1,
18294                            (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
18295 
18296         break;
18297     case LI16:
18298         {
18299             int reg = mmreg(uMIPS_RD(ctx->opcode));
18300             int imm = ZIMM(ctx->opcode, 0, 7);
18301 
18302             imm = (imm == 0x7f ? -1 : imm);
18303             tcg_gen_movi_tl(cpu_gpr[reg], imm);
18304         }
18305         break;
18306     case RES_29:
18307     case RES_31:
18308     case RES_39:
18309         generate_exception_end(ctx, EXCP_RI);
18310         break;
18311     default:
18312         decode_micromips32_opc(env, ctx);
18313         return 4;
18314     }
18315 
18316     return 2;
18317 }
18318 
18319 /*
18320  *
18321  * nanoMIPS opcodes
18322  *
18323  */
18324 
18325 /* MAJOR, P16, and P32 pools opcodes */
18326 enum {
18327     NM_P_ADDIU      = 0x00,
18328     NM_ADDIUPC      = 0x01,
18329     NM_MOVE_BALC    = 0x02,
18330     NM_P16_MV       = 0x04,
18331     NM_LW16         = 0x05,
18332     NM_BC16         = 0x06,
18333     NM_P16_SR       = 0x07,
18334 
18335     NM_POOL32A      = 0x08,
18336     NM_P_BAL        = 0x0a,
18337     NM_P16_SHIFT    = 0x0c,
18338     NM_LWSP16       = 0x0d,
18339     NM_BALC16       = 0x0e,
18340     NM_P16_4X4      = 0x0f,
18341 
18342     NM_P_GP_W       = 0x10,
18343     NM_P_GP_BH      = 0x11,
18344     NM_P_J          = 0x12,
18345     NM_P16C         = 0x14,
18346     NM_LWGP16       = 0x15,
18347     NM_P16_LB       = 0x17,
18348 
18349     NM_P48I         = 0x18,
18350     NM_P16_A1       = 0x1c,
18351     NM_LW4X4        = 0x1d,
18352     NM_P16_LH       = 0x1f,
18353 
18354     NM_P_U12        = 0x20,
18355     NM_P_LS_U12     = 0x21,
18356     NM_P_BR1        = 0x22,
18357     NM_P16_A2       = 0x24,
18358     NM_SW16         = 0x25,
18359     NM_BEQZC16      = 0x26,
18360 
18361     NM_POOL32F      = 0x28,
18362     NM_P_LS_S9      = 0x29,
18363     NM_P_BR2        = 0x2a,
18364 
18365     NM_P16_ADDU     = 0x2c,
18366     NM_SWSP16       = 0x2d,
18367     NM_BNEZC16      = 0x2e,
18368     NM_MOVEP        = 0x2f,
18369 
18370     NM_POOL32S      = 0x30,
18371     NM_P_BRI        = 0x32,
18372     NM_LI16         = 0x34,
18373     NM_SWGP16       = 0x35,
18374     NM_P16_BR       = 0x36,
18375 
18376     NM_P_LUI        = 0x38,
18377     NM_ANDI16       = 0x3c,
18378     NM_SW4X4        = 0x3d,
18379     NM_MOVEPREV     = 0x3f,
18380 };
18381 
18382 /* POOL32A instruction pool */
18383 enum {
18384     NM_POOL32A0    = 0x00,
18385     NM_SPECIAL2    = 0x01,
18386     NM_COP2_1      = 0x02,
18387     NM_UDI         = 0x03,
18388     NM_POOL32A5    = 0x05,
18389     NM_POOL32A7    = 0x07,
18390 };
18391 
18392 /* P.GP.W instruction pool */
18393 enum {
18394     NM_ADDIUGP_W = 0x00,
18395     NM_LWGP      = 0x02,
18396     NM_SWGP      = 0x03,
18397 };
18398 
18399 /* P48I instruction pool */
18400 enum {
18401     NM_LI48        = 0x00,
18402     NM_ADDIU48     = 0x01,
18403     NM_ADDIUGP48   = 0x02,
18404     NM_ADDIUPC48   = 0x03,
18405     NM_LWPC48      = 0x0b,
18406     NM_SWPC48      = 0x0f,
18407 };
18408 
18409 /* P.U12 instruction pool */
18410 enum {
18411     NM_ORI      = 0x00,
18412     NM_XORI     = 0x01,
18413     NM_ANDI     = 0x02,
18414     NM_P_SR     = 0x03,
18415     NM_SLTI     = 0x04,
18416     NM_SLTIU    = 0x05,
18417     NM_SEQI     = 0x06,
18418     NM_ADDIUNEG = 0x08,
18419     NM_P_SHIFT  = 0x0c,
18420     NM_P_ROTX   = 0x0d,
18421     NM_P_INS    = 0x0e,
18422     NM_P_EXT    = 0x0f,
18423 };
18424 
18425 /* POOL32F instruction pool */
18426 enum {
18427     NM_POOL32F_0   = 0x00,
18428     NM_POOL32F_3   = 0x03,
18429     NM_POOL32F_5   = 0x05,
18430 };
18431 
18432 /* POOL32S instruction pool */
18433 enum {
18434     NM_POOL32S_0   = 0x00,
18435     NM_POOL32S_4   = 0x04,
18436 };
18437 
18438 /* P.LUI instruction pool */
18439 enum {
18440     NM_LUI      = 0x00,
18441     NM_ALUIPC   = 0x01,
18442 };
18443 
18444 /* P.GP.BH instruction pool */
18445 enum {
18446     NM_LBGP      = 0x00,
18447     NM_SBGP      = 0x01,
18448     NM_LBUGP     = 0x02,
18449     NM_ADDIUGP_B = 0x03,
18450     NM_P_GP_LH   = 0x04,
18451     NM_P_GP_SH   = 0x05,
18452     NM_P_GP_CP1  = 0x06,
18453 };
18454 
18455 /* P.LS.U12 instruction pool */
18456 enum {
18457     NM_LB        = 0x00,
18458     NM_SB        = 0x01,
18459     NM_LBU       = 0x02,
18460     NM_P_PREFU12 = 0x03,
18461     NM_LH        = 0x04,
18462     NM_SH        = 0x05,
18463     NM_LHU       = 0x06,
18464     NM_LWU       = 0x07,
18465     NM_LW        = 0x08,
18466     NM_SW        = 0x09,
18467     NM_LWC1      = 0x0a,
18468     NM_SWC1      = 0x0b,
18469     NM_LDC1      = 0x0e,
18470     NM_SDC1      = 0x0f,
18471 };
18472 
18473 /* P.LS.S9 instruction pool */
18474 enum {
18475     NM_P_LS_S0         = 0x00,
18476     NM_P_LS_S1         = 0x01,
18477     NM_P_LS_E0         = 0x02,
18478     NM_P_LS_WM         = 0x04,
18479     NM_P_LS_UAWM       = 0x05,
18480 };
18481 
18482 /* P.BAL instruction pool */
18483 enum {
18484     NM_BC       = 0x00,
18485     NM_BALC     = 0x01,
18486 };
18487 
18488 /* P.J instruction pool */
18489 enum {
18490     NM_JALRC    = 0x00,
18491     NM_JALRC_HB = 0x01,
18492     NM_P_BALRSC = 0x08,
18493 };
18494 
18495 /* P.BR1 instruction pool */
18496 enum {
18497     NM_BEQC     = 0x00,
18498     NM_P_BR3A   = 0x01,
18499     NM_BGEC     = 0x02,
18500     NM_BGEUC    = 0x03,
18501 };
18502 
18503 /* P.BR2 instruction pool */
18504 enum {
18505     NM_BNEC     = 0x00,
18506     NM_BLTC     = 0x02,
18507     NM_BLTUC    = 0x03,
18508 };
18509 
18510 /* P.BRI instruction pool */
18511 enum {
18512     NM_BEQIC    = 0x00,
18513     NM_BBEQZC   = 0x01,
18514     NM_BGEIC    = 0x02,
18515     NM_BGEIUC   = 0x03,
18516     NM_BNEIC    = 0x04,
18517     NM_BBNEZC   = 0x05,
18518     NM_BLTIC    = 0x06,
18519     NM_BLTIUC   = 0x07,
18520 };
18521 
18522 /* P16.SHIFT instruction pool */
18523 enum {
18524     NM_SLL16    = 0x00,
18525     NM_SRL16    = 0x01,
18526 };
18527 
18528 /* POOL16C instruction pool */
18529 enum {
18530     NM_POOL16C_0  = 0x00,
18531     NM_LWXS16     = 0x01,
18532 };
18533 
18534 /* P16.A1 instruction pool */
18535 enum {
18536     NM_ADDIUR1SP = 0x01,
18537 };
18538 
18539 /* P16.A2 instruction pool */
18540 enum {
18541     NM_ADDIUR2  = 0x00,
18542     NM_P_ADDIURS5  = 0x01,
18543 };
18544 
18545 /* P16.ADDU instruction pool */
18546 enum {
18547     NM_ADDU16     = 0x00,
18548     NM_SUBU16     = 0x01,
18549 };
18550 
18551 /* P16.SR instruction pool */
18552 enum {
18553     NM_SAVE16        = 0x00,
18554     NM_RESTORE_JRC16 = 0x01,
18555 };
18556 
18557 /* P16.4X4 instruction pool */
18558 enum {
18559     NM_ADDU4X4      = 0x00,
18560     NM_MUL4X4       = 0x01,
18561 };
18562 
18563 /* P16.LB instruction pool */
18564 enum {
18565     NM_LB16       = 0x00,
18566     NM_SB16       = 0x01,
18567     NM_LBU16      = 0x02,
18568 };
18569 
18570 /* P16.LH  instruction pool */
18571 enum {
18572     NM_LH16     = 0x00,
18573     NM_SH16     = 0x01,
18574     NM_LHU16    = 0x02,
18575 };
18576 
18577 /* P.RI instruction pool */
18578 enum {
18579     NM_SIGRIE       = 0x00,
18580     NM_P_SYSCALL    = 0x01,
18581     NM_BREAK        = 0x02,
18582     NM_SDBBP        = 0x03,
18583 };
18584 
18585 /* POOL32A0 instruction pool */
18586 enum {
18587     NM_P_TRAP   = 0x00,
18588     NM_SEB      = 0x01,
18589     NM_SLLV     = 0x02,
18590     NM_MUL      = 0x03,
18591     NM_MFC0     = 0x06,
18592     NM_MFHC0    = 0x07,
18593     NM_SEH      = 0x09,
18594     NM_SRLV     = 0x0a,
18595     NM_MUH      = 0x0b,
18596     NM_MTC0     = 0x0e,
18597     NM_MTHC0    = 0x0f,
18598     NM_SRAV     = 0x12,
18599     NM_MULU     = 0x13,
18600     NM_ROTRV    = 0x1a,
18601     NM_MUHU     = 0x1b,
18602     NM_ADD      = 0x22,
18603     NM_DIV      = 0x23,
18604     NM_ADDU     = 0x2a,
18605     NM_MOD      = 0x2b,
18606     NM_SUB      = 0x32,
18607     NM_DIVU     = 0x33,
18608     NM_RDHWR    = 0x38,
18609     NM_SUBU     = 0x3a,
18610     NM_MODU     = 0x3b,
18611     NM_P_CMOVE  = 0x42,
18612     NM_FORK     = 0x45,
18613     NM_MFTR     = 0x46,
18614     NM_MFHTR    = 0x47,
18615     NM_AND      = 0x4a,
18616     NM_YIELD    = 0x4d,
18617     NM_MTTR     = 0x4e,
18618     NM_MTHTR    = 0x4f,
18619     NM_OR       = 0x52,
18620     NM_D_E_MT_VPE = 0x56,
18621     NM_NOR      = 0x5a,
18622     NM_XOR      = 0x62,
18623     NM_SLT      = 0x6a,
18624     NM_P_SLTU   = 0x72,
18625     NM_SOV      = 0x7a,
18626 };
18627 
18628 /* CRC32 instruction pool */
18629 enum {
18630     NM_CRC32B   = 0x00,
18631     NM_CRC32H   = 0x01,
18632     NM_CRC32W   = 0x02,
18633     NM_CRC32CB  = 0x04,
18634     NM_CRC32CH  = 0x05,
18635     NM_CRC32CW  = 0x06,
18636 };
18637 
18638 /* POOL32A5 instruction pool */
18639 enum {
18640     NM_CMP_EQ_PH        = 0x00,
18641     NM_CMP_LT_PH        = 0x08,
18642     NM_CMP_LE_PH        = 0x10,
18643     NM_CMPGU_EQ_QB      = 0x18,
18644     NM_CMPGU_LT_QB      = 0x20,
18645     NM_CMPGU_LE_QB      = 0x28,
18646     NM_CMPGDU_EQ_QB     = 0x30,
18647     NM_CMPGDU_LT_QB     = 0x38,
18648     NM_CMPGDU_LE_QB     = 0x40,
18649     NM_CMPU_EQ_QB       = 0x48,
18650     NM_CMPU_LT_QB       = 0x50,
18651     NM_CMPU_LE_QB       = 0x58,
18652     NM_ADDQ_S_W         = 0x60,
18653     NM_SUBQ_S_W         = 0x68,
18654     NM_ADDSC            = 0x70,
18655     NM_ADDWC            = 0x78,
18656 
18657     NM_ADDQ_S_PH   = 0x01,
18658     NM_ADDQH_R_PH  = 0x09,
18659     NM_ADDQH_R_W   = 0x11,
18660     NM_ADDU_S_QB   = 0x19,
18661     NM_ADDU_S_PH   = 0x21,
18662     NM_ADDUH_R_QB  = 0x29,
18663     NM_SHRAV_R_PH  = 0x31,
18664     NM_SHRAV_R_QB  = 0x39,
18665     NM_SUBQ_S_PH   = 0x41,
18666     NM_SUBQH_R_PH  = 0x49,
18667     NM_SUBQH_R_W   = 0x51,
18668     NM_SUBU_S_QB   = 0x59,
18669     NM_SUBU_S_PH   = 0x61,
18670     NM_SUBUH_R_QB  = 0x69,
18671     NM_SHLLV_S_PH  = 0x71,
18672     NM_PRECR_SRA_R_PH_W = 0x79,
18673 
18674     NM_MULEU_S_PH_QBL   = 0x12,
18675     NM_MULEU_S_PH_QBR   = 0x1a,
18676     NM_MULQ_RS_PH       = 0x22,
18677     NM_MULQ_S_PH        = 0x2a,
18678     NM_MULQ_RS_W        = 0x32,
18679     NM_MULQ_S_W         = 0x3a,
18680     NM_APPEND           = 0x42,
18681     NM_MODSUB           = 0x52,
18682     NM_SHRAV_R_W        = 0x5a,
18683     NM_SHRLV_PH         = 0x62,
18684     NM_SHRLV_QB         = 0x6a,
18685     NM_SHLLV_QB         = 0x72,
18686     NM_SHLLV_S_W        = 0x7a,
18687 
18688     NM_SHILO            = 0x03,
18689 
18690     NM_MULEQ_S_W_PHL    = 0x04,
18691     NM_MULEQ_S_W_PHR    = 0x0c,
18692 
18693     NM_MUL_S_PH         = 0x05,
18694     NM_PRECR_QB_PH      = 0x0d,
18695     NM_PRECRQ_QB_PH     = 0x15,
18696     NM_PRECRQ_PH_W      = 0x1d,
18697     NM_PRECRQ_RS_PH_W   = 0x25,
18698     NM_PRECRQU_S_QB_PH  = 0x2d,
18699     NM_PACKRL_PH        = 0x35,
18700     NM_PICK_QB          = 0x3d,
18701     NM_PICK_PH          = 0x45,
18702 
18703     NM_SHRA_R_W         = 0x5e,
18704     NM_SHRA_R_PH        = 0x66,
18705     NM_SHLL_S_PH        = 0x76,
18706     NM_SHLL_S_W         = 0x7e,
18707 
18708     NM_REPL_PH          = 0x07
18709 };
18710 
18711 /* POOL32A7 instruction pool */
18712 enum {
18713     NM_P_LSX        = 0x00,
18714     NM_LSA          = 0x01,
18715     NM_EXTW         = 0x03,
18716     NM_POOL32AXF    = 0x07,
18717 };
18718 
18719 /* P.SR instruction pool */
18720 enum {
18721     NM_PP_SR           = 0x00,
18722     NM_P_SR_F          = 0x01,
18723 };
18724 
18725 /* P.SHIFT instruction pool */
18726 enum {
18727     NM_P_SLL        = 0x00,
18728     NM_SRL          = 0x02,
18729     NM_SRA          = 0x04,
18730     NM_ROTR         = 0x06,
18731 };
18732 
18733 /* P.ROTX instruction pool */
18734 enum {
18735     NM_ROTX         = 0x00,
18736 };
18737 
18738 /* P.INS instruction pool */
18739 enum {
18740     NM_INS          = 0x00,
18741 };
18742 
18743 /* P.EXT instruction pool */
18744 enum {
18745     NM_EXT          = 0x00,
18746 };
18747 
18748 /* POOL32F_0 (fmt) instruction pool */
18749 enum {
18750     NM_RINT_S              = 0x04,
18751     NM_RINT_D              = 0x44,
18752     NM_ADD_S               = 0x06,
18753     NM_SELEQZ_S            = 0x07,
18754     NM_SELEQZ_D            = 0x47,
18755     NM_CLASS_S             = 0x0c,
18756     NM_CLASS_D             = 0x4c,
18757     NM_SUB_S               = 0x0e,
18758     NM_SELNEZ_S            = 0x0f,
18759     NM_SELNEZ_D            = 0x4f,
18760     NM_MUL_S               = 0x16,
18761     NM_SEL_S               = 0x17,
18762     NM_SEL_D               = 0x57,
18763     NM_DIV_S               = 0x1e,
18764     NM_ADD_D               = 0x26,
18765     NM_SUB_D               = 0x2e,
18766     NM_MUL_D               = 0x36,
18767     NM_MADDF_S             = 0x37,
18768     NM_MADDF_D             = 0x77,
18769     NM_DIV_D               = 0x3e,
18770     NM_MSUBF_S             = 0x3f,
18771     NM_MSUBF_D             = 0x7f,
18772 };
18773 
18774 /* POOL32F_3  instruction pool */
18775 enum {
18776     NM_MIN_FMT         = 0x00,
18777     NM_MAX_FMT         = 0x01,
18778     NM_MINA_FMT        = 0x04,
18779     NM_MAXA_FMT        = 0x05,
18780     NM_POOL32FXF       = 0x07,
18781 };
18782 
18783 /* POOL32F_5  instruction pool */
18784 enum {
18785     NM_CMP_CONDN_S     = 0x00,
18786     NM_CMP_CONDN_D     = 0x02,
18787 };
18788 
18789 /* P.GP.LH instruction pool */
18790 enum {
18791     NM_LHGP    = 0x00,
18792     NM_LHUGP   = 0x01,
18793 };
18794 
18795 /* P.GP.SH instruction pool */
18796 enum {
18797     NM_SHGP    = 0x00,
18798 };
18799 
18800 /* P.GP.CP1 instruction pool */
18801 enum {
18802     NM_LWC1GP       = 0x00,
18803     NM_SWC1GP       = 0x01,
18804     NM_LDC1GP       = 0x02,
18805     NM_SDC1GP       = 0x03,
18806 };
18807 
18808 /* P.LS.S0 instruction pool */
18809 enum {
18810     NM_LBS9     = 0x00,
18811     NM_LHS9     = 0x04,
18812     NM_LWS9     = 0x08,
18813     NM_LDS9     = 0x0c,
18814 
18815     NM_SBS9     = 0x01,
18816     NM_SHS9     = 0x05,
18817     NM_SWS9     = 0x09,
18818     NM_SDS9     = 0x0d,
18819 
18820     NM_LBUS9    = 0x02,
18821     NM_LHUS9    = 0x06,
18822     NM_LWC1S9   = 0x0a,
18823     NM_LDC1S9   = 0x0e,
18824 
18825     NM_P_PREFS9 = 0x03,
18826     NM_LWUS9    = 0x07,
18827     NM_SWC1S9   = 0x0b,
18828     NM_SDC1S9   = 0x0f,
18829 };
18830 
18831 /* P.LS.S1 instruction pool */
18832 enum {
18833     NM_ASET_ACLR = 0x02,
18834     NM_UALH      = 0x04,
18835     NM_UASH      = 0x05,
18836     NM_CACHE     = 0x07,
18837     NM_P_LL      = 0x0a,
18838     NM_P_SC      = 0x0b,
18839 };
18840 
18841 /* P.LS.E0 instruction pool */
18842 enum {
18843     NM_LBE      = 0x00,
18844     NM_SBE      = 0x01,
18845     NM_LBUE     = 0x02,
18846     NM_P_PREFE  = 0x03,
18847     NM_LHE      = 0x04,
18848     NM_SHE      = 0x05,
18849     NM_LHUE     = 0x06,
18850     NM_CACHEE   = 0x07,
18851     NM_LWE      = 0x08,
18852     NM_SWE      = 0x09,
18853     NM_P_LLE    = 0x0a,
18854     NM_P_SCE    = 0x0b,
18855 };
18856 
18857 /* P.PREFE instruction pool */
18858 enum {
18859     NM_SYNCIE   = 0x00,
18860     NM_PREFE    = 0x01,
18861 };
18862 
18863 /* P.LLE instruction pool */
18864 enum {
18865     NM_LLE      = 0x00,
18866     NM_LLWPE    = 0x01,
18867 };
18868 
18869 /* P.SCE instruction pool */
18870 enum {
18871     NM_SCE      = 0x00,
18872     NM_SCWPE    = 0x01,
18873 };
18874 
18875 /* P.LS.WM instruction pool */
18876 enum {
18877     NM_LWM       = 0x00,
18878     NM_SWM       = 0x01,
18879 };
18880 
18881 /* P.LS.UAWM instruction pool */
18882 enum {
18883     NM_UALWM       = 0x00,
18884     NM_UASWM       = 0x01,
18885 };
18886 
18887 /* P.BR3A instruction pool */
18888 enum {
18889     NM_BC1EQZC          = 0x00,
18890     NM_BC1NEZC          = 0x01,
18891     NM_BC2EQZC          = 0x02,
18892     NM_BC2NEZC          = 0x03,
18893     NM_BPOSGE32C        = 0x04,
18894 };
18895 
18896 /* P16.RI instruction pool */
18897 enum {
18898     NM_P16_SYSCALL  = 0x01,
18899     NM_BREAK16      = 0x02,
18900     NM_SDBBP16      = 0x03,
18901 };
18902 
18903 /* POOL16C_0 instruction pool */
18904 enum {
18905     NM_POOL16C_00      = 0x00,
18906 };
18907 
18908 /* P16.JRC instruction pool */
18909 enum {
18910     NM_JRC          = 0x00,
18911     NM_JALRC16      = 0x01,
18912 };
18913 
18914 /* P.SYSCALL instruction pool */
18915 enum {
18916     NM_SYSCALL      = 0x00,
18917     NM_HYPCALL      = 0x01,
18918 };
18919 
18920 /* P.TRAP instruction pool */
18921 enum {
18922     NM_TEQ          = 0x00,
18923     NM_TNE          = 0x01,
18924 };
18925 
18926 /* P.CMOVE instruction pool */
18927 enum {
18928     NM_MOVZ            = 0x00,
18929     NM_MOVN            = 0x01,
18930 };
18931 
18932 /* POOL32Axf instruction pool */
18933 enum {
18934     NM_POOL32AXF_1 = 0x01,
18935     NM_POOL32AXF_2 = 0x02,
18936     NM_POOL32AXF_4 = 0x04,
18937     NM_POOL32AXF_5 = 0x05,
18938     NM_POOL32AXF_7 = 0x07,
18939 };
18940 
18941 /* POOL32Axf_1 instruction pool */
18942 enum {
18943     NM_POOL32AXF_1_0 = 0x00,
18944     NM_POOL32AXF_1_1 = 0x01,
18945     NM_POOL32AXF_1_3 = 0x03,
18946     NM_POOL32AXF_1_4 = 0x04,
18947     NM_POOL32AXF_1_5 = 0x05,
18948     NM_POOL32AXF_1_7 = 0x07,
18949 };
18950 
18951 /* POOL32Axf_2 instruction pool */
18952 enum {
18953     NM_POOL32AXF_2_0_7     = 0x00,
18954     NM_POOL32AXF_2_8_15    = 0x01,
18955     NM_POOL32AXF_2_16_23   = 0x02,
18956     NM_POOL32AXF_2_24_31   = 0x03,
18957 };
18958 
18959 /* POOL32Axf_7 instruction pool */
18960 enum {
18961     NM_SHRA_R_QB    = 0x0,
18962     NM_SHRL_PH      = 0x1,
18963     NM_REPL_QB      = 0x2,
18964 };
18965 
18966 /* POOL32Axf_1_0 instruction pool */
18967 enum {
18968     NM_MFHI = 0x0,
18969     NM_MFLO = 0x1,
18970     NM_MTHI = 0x2,
18971     NM_MTLO = 0x3,
18972 };
18973 
18974 /* POOL32Axf_1_1 instruction pool */
18975 enum {
18976     NM_MTHLIP = 0x0,
18977     NM_SHILOV = 0x1,
18978 };
18979 
18980 /* POOL32Axf_1_3 instruction pool */
18981 enum {
18982     NM_RDDSP    = 0x0,
18983     NM_WRDSP    = 0x1,
18984     NM_EXTP     = 0x2,
18985     NM_EXTPDP   = 0x3,
18986 };
18987 
18988 /* POOL32Axf_1_4 instruction pool */
18989 enum {
18990     NM_SHLL_QB  = 0x0,
18991     NM_SHRL_QB  = 0x1,
18992 };
18993 
18994 /* POOL32Axf_1_5 instruction pool */
18995 enum {
18996     NM_MAQ_S_W_PHR   = 0x0,
18997     NM_MAQ_S_W_PHL   = 0x1,
18998     NM_MAQ_SA_W_PHR  = 0x2,
18999     NM_MAQ_SA_W_PHL  = 0x3,
19000 };
19001 
19002 /* POOL32Axf_1_7 instruction pool */
19003 enum {
19004     NM_EXTR_W       = 0x0,
19005     NM_EXTR_R_W     = 0x1,
19006     NM_EXTR_RS_W    = 0x2,
19007     NM_EXTR_S_H     = 0x3,
19008 };
19009 
19010 /* POOL32Axf_2_0_7 instruction pool */
19011 enum {
19012     NM_DPA_W_PH     = 0x0,
19013     NM_DPAQ_S_W_PH  = 0x1,
19014     NM_DPS_W_PH     = 0x2,
19015     NM_DPSQ_S_W_PH  = 0x3,
19016     NM_BALIGN       = 0x4,
19017     NM_MADD         = 0x5,
19018     NM_MULT         = 0x6,
19019     NM_EXTRV_W      = 0x7,
19020 };
19021 
19022 /* POOL32Axf_2_8_15 instruction pool */
19023 enum {
19024     NM_DPAX_W_PH    = 0x0,
19025     NM_DPAQ_SA_L_W  = 0x1,
19026     NM_DPSX_W_PH    = 0x2,
19027     NM_DPSQ_SA_L_W  = 0x3,
19028     NM_MADDU        = 0x5,
19029     NM_MULTU        = 0x6,
19030     NM_EXTRV_R_W    = 0x7,
19031 };
19032 
19033 /* POOL32Axf_2_16_23 instruction pool */
19034 enum {
19035     NM_DPAU_H_QBL       = 0x0,
19036     NM_DPAQX_S_W_PH     = 0x1,
19037     NM_DPSU_H_QBL       = 0x2,
19038     NM_DPSQX_S_W_PH     = 0x3,
19039     NM_EXTPV            = 0x4,
19040     NM_MSUB             = 0x5,
19041     NM_MULSA_W_PH       = 0x6,
19042     NM_EXTRV_RS_W       = 0x7,
19043 };
19044 
19045 /* POOL32Axf_2_24_31 instruction pool */
19046 enum {
19047     NM_DPAU_H_QBR       = 0x0,
19048     NM_DPAQX_SA_W_PH    = 0x1,
19049     NM_DPSU_H_QBR       = 0x2,
19050     NM_DPSQX_SA_W_PH    = 0x3,
19051     NM_EXTPDPV          = 0x4,
19052     NM_MSUBU            = 0x5,
19053     NM_MULSAQ_S_W_PH    = 0x6,
19054     NM_EXTRV_S_H        = 0x7,
19055 };
19056 
19057 /* POOL32Axf_{4, 5} instruction pool */
19058 enum {
19059     NM_CLO      = 0x25,
19060     NM_CLZ      = 0x2d,
19061 
19062     NM_TLBP     = 0x01,
19063     NM_TLBR     = 0x09,
19064     NM_TLBWI    = 0x11,
19065     NM_TLBWR    = 0x19,
19066     NM_TLBINV   = 0x03,
19067     NM_TLBINVF  = 0x0b,
19068     NM_DI       = 0x23,
19069     NM_EI       = 0x2b,
19070     NM_RDPGPR   = 0x70,
19071     NM_WRPGPR   = 0x78,
19072     NM_WAIT     = 0x61,
19073     NM_DERET    = 0x71,
19074     NM_ERETX    = 0x79,
19075 
19076     /* nanoMIPS DSP instructions */
19077     NM_ABSQ_S_QB        = 0x00,
19078     NM_ABSQ_S_PH        = 0x08,
19079     NM_ABSQ_S_W         = 0x10,
19080     NM_PRECEQ_W_PHL     = 0x28,
19081     NM_PRECEQ_W_PHR     = 0x30,
19082     NM_PRECEQU_PH_QBL   = 0x38,
19083     NM_PRECEQU_PH_QBR   = 0x48,
19084     NM_PRECEU_PH_QBL    = 0x58,
19085     NM_PRECEU_PH_QBR    = 0x68,
19086     NM_PRECEQU_PH_QBLA  = 0x39,
19087     NM_PRECEQU_PH_QBRA  = 0x49,
19088     NM_PRECEU_PH_QBLA   = 0x59,
19089     NM_PRECEU_PH_QBRA   = 0x69,
19090     NM_REPLV_PH         = 0x01,
19091     NM_REPLV_QB         = 0x09,
19092     NM_BITREV           = 0x18,
19093     NM_INSV             = 0x20,
19094     NM_RADDU_W_QB       = 0x78,
19095 
19096     NM_BITSWAP          = 0x05,
19097     NM_WSBH             = 0x3d,
19098 };
19099 
19100 /* PP.SR instruction pool */
19101 enum {
19102     NM_SAVE         = 0x00,
19103     NM_RESTORE      = 0x02,
19104     NM_RESTORE_JRC  = 0x03,
19105 };
19106 
19107 /* P.SR.F instruction pool */
19108 enum {
19109     NM_SAVEF        = 0x00,
19110     NM_RESTOREF     = 0x01,
19111 };
19112 
19113 /* P16.SYSCALL  instruction pool */
19114 enum {
19115     NM_SYSCALL16     = 0x00,
19116     NM_HYPCALL16     = 0x01,
19117 };
19118 
19119 /* POOL16C_00 instruction pool */
19120 enum {
19121     NM_NOT16           = 0x00,
19122     NM_XOR16           = 0x01,
19123     NM_AND16           = 0x02,
19124     NM_OR16            = 0x03,
19125 };
19126 
19127 /* PP.LSX and PP.LSXS instruction pool */
19128 enum {
19129     NM_LBX      = 0x00,
19130     NM_LHX      = 0x04,
19131     NM_LWX      = 0x08,
19132     NM_LDX      = 0x0c,
19133 
19134     NM_SBX      = 0x01,
19135     NM_SHX      = 0x05,
19136     NM_SWX      = 0x09,
19137     NM_SDX      = 0x0d,
19138 
19139     NM_LBUX     = 0x02,
19140     NM_LHUX     = 0x06,
19141     NM_LWC1X    = 0x0a,
19142     NM_LDC1X    = 0x0e,
19143 
19144     NM_LWUX     = 0x07,
19145     NM_SWC1X    = 0x0b,
19146     NM_SDC1X    = 0x0f,
19147 
19148     NM_LHXS     = 0x04,
19149     NM_LWXS     = 0x08,
19150     NM_LDXS     = 0x0c,
19151 
19152     NM_SHXS     = 0x05,
19153     NM_SWXS     = 0x09,
19154     NM_SDXS     = 0x0d,
19155 
19156     NM_LHUXS    = 0x06,
19157     NM_LWC1XS   = 0x0a,
19158     NM_LDC1XS   = 0x0e,
19159 
19160     NM_LWUXS    = 0x07,
19161     NM_SWC1XS   = 0x0b,
19162     NM_SDC1XS   = 0x0f,
19163 };
19164 
19165 /* ERETx instruction pool */
19166 enum {
19167     NM_ERET     = 0x00,
19168     NM_ERETNC   = 0x01,
19169 };
19170 
19171 /* POOL32FxF_{0, 1} insturction pool */
19172 enum {
19173     NM_CFC1     = 0x40,
19174     NM_CTC1     = 0x60,
19175     NM_MFC1     = 0x80,
19176     NM_MTC1     = 0xa0,
19177     NM_MFHC1    = 0xc0,
19178     NM_MTHC1    = 0xe0,
19179 
19180     NM_CVT_S_PL = 0x84,
19181     NM_CVT_S_PU = 0xa4,
19182 
19183     NM_CVT_L_S     = 0x004,
19184     NM_CVT_L_D     = 0x104,
19185     NM_CVT_W_S     = 0x024,
19186     NM_CVT_W_D     = 0x124,
19187 
19188     NM_RSQRT_S     = 0x008,
19189     NM_RSQRT_D     = 0x108,
19190 
19191     NM_SQRT_S      = 0x028,
19192     NM_SQRT_D      = 0x128,
19193 
19194     NM_RECIP_S     = 0x048,
19195     NM_RECIP_D     = 0x148,
19196 
19197     NM_FLOOR_L_S   = 0x00c,
19198     NM_FLOOR_L_D   = 0x10c,
19199 
19200     NM_FLOOR_W_S   = 0x02c,
19201     NM_FLOOR_W_D   = 0x12c,
19202 
19203     NM_CEIL_L_S    = 0x04c,
19204     NM_CEIL_L_D    = 0x14c,
19205     NM_CEIL_W_S    = 0x06c,
19206     NM_CEIL_W_D    = 0x16c,
19207     NM_TRUNC_L_S   = 0x08c,
19208     NM_TRUNC_L_D   = 0x18c,
19209     NM_TRUNC_W_S   = 0x0ac,
19210     NM_TRUNC_W_D   = 0x1ac,
19211     NM_ROUND_L_S   = 0x0cc,
19212     NM_ROUND_L_D   = 0x1cc,
19213     NM_ROUND_W_S   = 0x0ec,
19214     NM_ROUND_W_D   = 0x1ec,
19215 
19216     NM_MOV_S       = 0x01,
19217     NM_MOV_D       = 0x81,
19218     NM_ABS_S       = 0x0d,
19219     NM_ABS_D       = 0x8d,
19220     NM_NEG_S       = 0x2d,
19221     NM_NEG_D       = 0xad,
19222     NM_CVT_D_S     = 0x04d,
19223     NM_CVT_D_W     = 0x0cd,
19224     NM_CVT_D_L     = 0x14d,
19225     NM_CVT_S_D     = 0x06d,
19226     NM_CVT_S_W     = 0x0ed,
19227     NM_CVT_S_L     = 0x16d,
19228 };
19229 
19230 /* P.LL instruction pool */
19231 enum {
19232     NM_LL       = 0x00,
19233     NM_LLWP     = 0x01,
19234 };
19235 
19236 /* P.SC instruction pool */
19237 enum {
19238     NM_SC       = 0x00,
19239     NM_SCWP     = 0x01,
19240 };
19241 
19242 /* P.DVP instruction pool */
19243 enum {
19244     NM_DVP      = 0x00,
19245     NM_EVP      = 0x01,
19246 };
19247 
19248 
19249 /*
19250  *
19251  * nanoMIPS decoding engine
19252  *
19253  */
19254 
19255 
19256 /* extraction utilities */
19257 
19258 #define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7)
19259 #define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7)
19260 #define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7)
19261 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
19262 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
19263 
19264 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
decode_gpr_gpr3(int r)19265 static inline int decode_gpr_gpr3(int r)
19266 {
19267     static const int map[] = { 16, 17, 18, 19,  4,  5,  6,  7 };
19268 
19269     return map[r & 0x7];
19270 }
19271 
19272 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
decode_gpr_gpr3_src_store(int r)19273 static inline int decode_gpr_gpr3_src_store(int r)
19274 {
19275     static const int map[] = {  0, 17, 18, 19,  4,  5,  6,  7 };
19276 
19277     return map[r & 0x7];
19278 }
19279 
19280 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
decode_gpr_gpr4(int r)19281 static inline int decode_gpr_gpr4(int r)
19282 {
19283     static const int map[] = {  8,  9, 10, 11,  4,  5,  6,  7,
19284                                16, 17, 18, 19, 20, 21, 22, 23 };
19285 
19286     return map[r & 0xf];
19287 }
19288 
19289 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
decode_gpr_gpr4_zero(int r)19290 static inline int decode_gpr_gpr4_zero(int r)
19291 {
19292     static const int map[] = {  8,  9, 10,  0,  4,  5,  6,  7,
19293                                16, 17, 18, 19, 20, 21, 22, 23 };
19294 
19295     return map[r & 0xf];
19296 }
19297 
19298 
gen_adjust_sp(DisasContext * ctx,int u)19299 static void gen_adjust_sp(DisasContext *ctx, int u)
19300 {
19301     gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u);
19302 }
19303 
gen_save(DisasContext * ctx,uint8_t rt,uint8_t count,uint8_t gp,uint16_t u)19304 static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count,
19305                      uint8_t gp, uint16_t u)
19306 {
19307     int counter = 0;
19308     TCGv va = tcg_temp_new();
19309     TCGv t0 = tcg_temp_new();
19310 
19311     while (counter != count) {
19312         bool use_gp = gp && (counter == count - 1);
19313         int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
19314         int this_offset = -((counter + 1) << 2);
19315         gen_base_offset_addr(ctx, va, 29, this_offset);
19316         gen_load_gpr(t0, this_rt);
19317         tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx,
19318                            (MO_TEUL | ctx->default_tcg_memop_mask));
19319         counter++;
19320     }
19321 
19322     /* adjust stack pointer */
19323     gen_adjust_sp(ctx, -u);
19324 
19325     tcg_temp_free(t0);
19326     tcg_temp_free(va);
19327 }
19328 
gen_restore(DisasContext * ctx,uint8_t rt,uint8_t count,uint8_t gp,uint16_t u)19329 static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count,
19330                         uint8_t gp, uint16_t u)
19331 {
19332     int counter = 0;
19333     TCGv va = tcg_temp_new();
19334     TCGv t0 = tcg_temp_new();
19335 
19336     while (counter != count) {
19337         bool use_gp = gp && (counter == count - 1);
19338         int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
19339         int this_offset = u - ((counter + 1) << 2);
19340         gen_base_offset_addr(ctx, va, 29, this_offset);
19341         tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL |
19342                         ctx->default_tcg_memop_mask);
19343         tcg_gen_ext32s_tl(t0, t0);
19344         gen_store_gpr(t0, this_rt);
19345         counter++;
19346     }
19347 
19348     /* adjust stack pointer */
19349     gen_adjust_sp(ctx, u);
19350 
19351     tcg_temp_free(t0);
19352     tcg_temp_free(va);
19353 }
19354 
gen_pool16c_nanomips_insn(DisasContext * ctx)19355 static void gen_pool16c_nanomips_insn(DisasContext *ctx)
19356 {
19357     int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode));
19358     int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
19359 
19360     switch (extract32(ctx->opcode, 2, 2)) {
19361     case NM_NOT16:
19362         gen_logic(ctx, OPC_NOR, rt, rs, 0);
19363         break;
19364     case NM_AND16:
19365         gen_logic(ctx, OPC_AND, rt, rt, rs);
19366         break;
19367     case NM_XOR16:
19368         gen_logic(ctx, OPC_XOR, rt, rt, rs);
19369         break;
19370     case NM_OR16:
19371         gen_logic(ctx, OPC_OR, rt, rt, rs);
19372         break;
19373     }
19374 }
19375 
gen_pool32a0_nanomips_insn(CPUMIPSState * env,DisasContext * ctx)19376 static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
19377 {
19378     int rt = extract32(ctx->opcode, 21, 5);
19379     int rs = extract32(ctx->opcode, 16, 5);
19380     int rd = extract32(ctx->opcode, 11, 5);
19381 
19382     switch (extract32(ctx->opcode, 3, 7)) {
19383     case NM_P_TRAP:
19384         switch (extract32(ctx->opcode, 10, 1)) {
19385         case NM_TEQ:
19386             check_nms(ctx);
19387             gen_trap(ctx, OPC_TEQ, rs, rt, -1);
19388             break;
19389         case NM_TNE:
19390             check_nms(ctx);
19391             gen_trap(ctx, OPC_TNE, rs, rt, -1);
19392             break;
19393         }
19394         break;
19395     case NM_RDHWR:
19396         check_nms(ctx);
19397         gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
19398         break;
19399     case NM_SEB:
19400         check_nms(ctx);
19401         gen_bshfl(ctx, OPC_SEB, rs, rt);
19402         break;
19403     case NM_SEH:
19404         gen_bshfl(ctx, OPC_SEH, rs, rt);
19405         break;
19406     case NM_SLLV:
19407         gen_shift(ctx, OPC_SLLV, rd, rt, rs);
19408         break;
19409     case NM_SRLV:
19410         gen_shift(ctx, OPC_SRLV, rd, rt, rs);
19411         break;
19412     case NM_SRAV:
19413         gen_shift(ctx, OPC_SRAV, rd, rt, rs);
19414         break;
19415     case NM_ROTRV:
19416         gen_shift(ctx, OPC_ROTRV, rd, rt, rs);
19417         break;
19418     case NM_ADD:
19419         gen_arith(ctx, OPC_ADD, rd, rs, rt);
19420         break;
19421     case NM_ADDU:
19422         gen_arith(ctx, OPC_ADDU, rd, rs, rt);
19423         break;
19424     case NM_SUB:
19425         check_nms(ctx);
19426         gen_arith(ctx, OPC_SUB, rd, rs, rt);
19427         break;
19428     case NM_SUBU:
19429         gen_arith(ctx, OPC_SUBU, rd, rs, rt);
19430         break;
19431     case NM_P_CMOVE:
19432         switch (extract32(ctx->opcode, 10, 1)) {
19433         case NM_MOVZ:
19434             gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
19435             break;
19436         case NM_MOVN:
19437             gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
19438             break;
19439         }
19440         break;
19441     case NM_AND:
19442         gen_logic(ctx, OPC_AND, rd, rs, rt);
19443         break;
19444     case NM_OR:
19445         gen_logic(ctx, OPC_OR, rd, rs, rt);
19446         break;
19447     case NM_NOR:
19448         gen_logic(ctx, OPC_NOR, rd, rs, rt);
19449         break;
19450     case NM_XOR:
19451         gen_logic(ctx, OPC_XOR, rd, rs, rt);
19452         break;
19453     case NM_SLT:
19454         gen_slt(ctx, OPC_SLT, rd, rs, rt);
19455         break;
19456     case NM_P_SLTU:
19457         if (rd == 0) {
19458             /* P_DVP */
19459 #ifndef CONFIG_USER_ONLY
19460             TCGv t0 = tcg_temp_new();
19461             switch (extract32(ctx->opcode, 10, 1)) {
19462             case NM_DVP:
19463                 if (ctx->vp) {
19464                     check_cp0_enabled(ctx);
19465                     gen_helper_dvp(t0, cpu_env);
19466                     gen_store_gpr(t0, rt);
19467                 }
19468                 break;
19469             case NM_EVP:
19470                 if (ctx->vp) {
19471                     check_cp0_enabled(ctx);
19472                     gen_helper_evp(t0, cpu_env);
19473                     gen_store_gpr(t0, rt);
19474                 }
19475                 break;
19476             }
19477             tcg_temp_free(t0);
19478 #endif
19479         } else {
19480             gen_slt(ctx, OPC_SLTU, rd, rs, rt);
19481         }
19482         break;
19483     case NM_SOV:
19484         {
19485             TCGv t0 = tcg_temp_new();
19486             TCGv t1 = tcg_temp_new();
19487             TCGv t2 = tcg_temp_new();
19488 
19489             gen_load_gpr(t1, rs);
19490             gen_load_gpr(t2, rt);
19491             tcg_gen_add_tl(t0, t1, t2);
19492             tcg_gen_ext32s_tl(t0, t0);
19493             tcg_gen_xor_tl(t1, t1, t2);
19494             tcg_gen_xor_tl(t2, t0, t2);
19495             tcg_gen_andc_tl(t1, t2, t1);
19496 
19497             /* operands of same sign, result different sign */
19498             tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0);
19499             gen_store_gpr(t0, rd);
19500 
19501             tcg_temp_free(t0);
19502             tcg_temp_free(t1);
19503             tcg_temp_free(t2);
19504         }
19505         break;
19506     case NM_MUL:
19507         gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
19508         break;
19509     case NM_MUH:
19510         gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
19511         break;
19512     case NM_MULU:
19513         gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
19514         break;
19515     case NM_MUHU:
19516         gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
19517         break;
19518     case NM_DIV:
19519         gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
19520         break;
19521     case NM_MOD:
19522         gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
19523         break;
19524     case NM_DIVU:
19525         gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
19526         break;
19527     case NM_MODU:
19528         gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
19529         break;
19530 #ifndef CONFIG_USER_ONLY
19531     case NM_MFC0:
19532         check_cp0_enabled(ctx);
19533         if (rt == 0) {
19534             /* Treat as NOP. */
19535             break;
19536         }
19537         gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3));
19538         break;
19539     case NM_MTC0:
19540         check_cp0_enabled(ctx);
19541         {
19542             TCGv t0 = tcg_temp_new();
19543 
19544             gen_load_gpr(t0, rt);
19545             gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3));
19546             tcg_temp_free(t0);
19547         }
19548         break;
19549     case NM_D_E_MT_VPE:
19550         {
19551             uint8_t sc = extract32(ctx->opcode, 10, 1);
19552             TCGv t0 = tcg_temp_new();
19553 
19554             switch (sc) {
19555             case 0:
19556                 if (rs == 1) {
19557                     /* DMT */
19558                     check_cp0_mt(ctx);
19559                     gen_helper_dmt(t0);
19560                     gen_store_gpr(t0, rt);
19561                 } else if (rs == 0) {
19562                     /* DVPE */
19563                     check_cp0_mt(ctx);
19564                     gen_helper_dvpe(t0, cpu_env);
19565                     gen_store_gpr(t0, rt);
19566                 } else {
19567                     generate_exception_end(ctx, EXCP_RI);
19568                 }
19569                 break;
19570             case 1:
19571                 if (rs == 1) {
19572                     /* EMT */
19573                     check_cp0_mt(ctx);
19574                     gen_helper_emt(t0);
19575                     gen_store_gpr(t0, rt);
19576                 } else if (rs == 0) {
19577                     /* EVPE */
19578                     check_cp0_mt(ctx);
19579                     gen_helper_evpe(t0, cpu_env);
19580                     gen_store_gpr(t0, rt);
19581                 } else {
19582                     generate_exception_end(ctx, EXCP_RI);
19583                 }
19584                 break;
19585             }
19586 
19587             tcg_temp_free(t0);
19588         }
19589         break;
19590     case NM_FORK:
19591         check_mt(ctx);
19592         {
19593             TCGv t0 = tcg_temp_new();
19594             TCGv t1 = tcg_temp_new();
19595 
19596             gen_load_gpr(t0, rt);
19597             gen_load_gpr(t1, rs);
19598             gen_helper_fork(t0, t1);
19599             tcg_temp_free(t0);
19600             tcg_temp_free(t1);
19601         }
19602         break;
19603     case NM_MFTR:
19604     case NM_MFHTR:
19605         check_cp0_enabled(ctx);
19606         if (rd == 0) {
19607             /* Treat as NOP. */
19608             return;
19609         }
19610         gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
19611                  extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
19612         break;
19613     case NM_MTTR:
19614     case NM_MTHTR:
19615         check_cp0_enabled(ctx);
19616         gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
19617                  extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
19618         break;
19619     case NM_YIELD:
19620         check_mt(ctx);
19621         {
19622             TCGv t0 = tcg_temp_new();
19623 
19624             gen_load_gpr(t0, rs);
19625             gen_helper_yield(t0, cpu_env, t0);
19626             gen_store_gpr(t0, rt);
19627             tcg_temp_free(t0);
19628         }
19629         break;
19630 #endif
19631     default:
19632         generate_exception_end(ctx, EXCP_RI);
19633         break;
19634     }
19635 }
19636 
19637 /* dsp */
gen_pool32axf_1_5_nanomips_insn(DisasContext * ctx,uint32_t opc,int ret,int v1,int v2)19638 static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc,
19639                                             int ret, int v1, int v2)
19640 {
19641     TCGv_i32 t0;
19642     TCGv v0_t;
19643     TCGv v1_t;
19644 
19645     t0 = tcg_temp_new_i32();
19646 
19647     v0_t = tcg_temp_new();
19648     v1_t = tcg_temp_new();
19649 
19650     tcg_gen_movi_i32(t0, v2 >> 3);
19651 
19652     gen_load_gpr(v0_t, ret);
19653     gen_load_gpr(v1_t, v1);
19654 
19655     switch (opc) {
19656     case NM_MAQ_S_W_PHR:
19657         check_dsp(ctx);
19658         gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env);
19659         break;
19660     case NM_MAQ_S_W_PHL:
19661         check_dsp(ctx);
19662         gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env);
19663         break;
19664     case NM_MAQ_SA_W_PHR:
19665         check_dsp(ctx);
19666         gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env);
19667         break;
19668     case NM_MAQ_SA_W_PHL:
19669         check_dsp(ctx);
19670         gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env);
19671         break;
19672     default:
19673         generate_exception_end(ctx, EXCP_RI);
19674         break;
19675     }
19676 
19677     tcg_temp_free_i32(t0);
19678 
19679     tcg_temp_free(v0_t);
19680     tcg_temp_free(v1_t);
19681 }
19682 
19683 
gen_pool32axf_1_nanomips_insn(DisasContext * ctx,uint32_t opc,int ret,int v1,int v2)19684 static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc,
19685                                     int ret, int v1, int v2)
19686 {
19687     int16_t imm;
19688     TCGv t0 = tcg_temp_new();
19689     TCGv t1 = tcg_temp_new();
19690     TCGv v0_t = tcg_temp_new();
19691 
19692     gen_load_gpr(v0_t, v1);
19693 
19694     switch (opc) {
19695     case NM_POOL32AXF_1_0:
19696         check_dsp(ctx);
19697         switch (extract32(ctx->opcode, 12, 2)) {
19698         case NM_MFHI:
19699             gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret);
19700             break;
19701         case NM_MFLO:
19702             gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret);
19703             break;
19704         case NM_MTHI:
19705             gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1);
19706             break;
19707         case NM_MTLO:
19708             gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1);
19709             break;
19710         }
19711         break;
19712     case NM_POOL32AXF_1_1:
19713         check_dsp(ctx);
19714         switch (extract32(ctx->opcode, 12, 2)) {
19715         case NM_MTHLIP:
19716             tcg_gen_movi_tl(t0, v2);
19717             gen_helper_mthlip(t0, v0_t, cpu_env);
19718             break;
19719         case NM_SHILOV:
19720             tcg_gen_movi_tl(t0, v2 >> 3);
19721             gen_helper_shilo(t0, v0_t, cpu_env);
19722             break;
19723         default:
19724             generate_exception_end(ctx, EXCP_RI);
19725             break;
19726         }
19727         break;
19728     case NM_POOL32AXF_1_3:
19729         check_dsp(ctx);
19730         imm = extract32(ctx->opcode, 14, 7);
19731         switch (extract32(ctx->opcode, 12, 2)) {
19732         case NM_RDDSP:
19733             tcg_gen_movi_tl(t0, imm);
19734             gen_helper_rddsp(t0, t0, cpu_env);
19735             gen_store_gpr(t0, ret);
19736             break;
19737         case NM_WRDSP:
19738             gen_load_gpr(t0, ret);
19739             tcg_gen_movi_tl(t1, imm);
19740             gen_helper_wrdsp(t0, t1, cpu_env);
19741             break;
19742         case NM_EXTP:
19743             tcg_gen_movi_tl(t0, v2 >> 3);
19744             tcg_gen_movi_tl(t1, v1);
19745             gen_helper_extp(t0, t0, t1, cpu_env);
19746             gen_store_gpr(t0, ret);
19747             break;
19748         case NM_EXTPDP:
19749             tcg_gen_movi_tl(t0, v2 >> 3);
19750             tcg_gen_movi_tl(t1, v1);
19751             gen_helper_extpdp(t0, t0, t1, cpu_env);
19752             gen_store_gpr(t0, ret);
19753             break;
19754         }
19755         break;
19756     case NM_POOL32AXF_1_4:
19757         check_dsp(ctx);
19758         tcg_gen_movi_tl(t0, v2 >> 2);
19759         switch (extract32(ctx->opcode, 12, 1)) {
19760         case NM_SHLL_QB:
19761             gen_helper_shll_qb(t0, t0, v0_t, cpu_env);
19762             gen_store_gpr(t0, ret);
19763             break;
19764         case NM_SHRL_QB:
19765             gen_helper_shrl_qb(t0, t0, v0_t);
19766             gen_store_gpr(t0, ret);
19767             break;
19768         }
19769         break;
19770     case NM_POOL32AXF_1_5:
19771         opc = extract32(ctx->opcode, 12, 2);
19772         gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2);
19773         break;
19774     case NM_POOL32AXF_1_7:
19775         check_dsp(ctx);
19776         tcg_gen_movi_tl(t0, v2 >> 3);
19777         tcg_gen_movi_tl(t1, v1);
19778         switch (extract32(ctx->opcode, 12, 2)) {
19779         case NM_EXTR_W:
19780             gen_helper_extr_w(t0, t0, t1, cpu_env);
19781             gen_store_gpr(t0, ret);
19782             break;
19783         case NM_EXTR_R_W:
19784             gen_helper_extr_r_w(t0, t0, t1, cpu_env);
19785             gen_store_gpr(t0, ret);
19786             break;
19787         case NM_EXTR_RS_W:
19788             gen_helper_extr_rs_w(t0, t0, t1, cpu_env);
19789             gen_store_gpr(t0, ret);
19790             break;
19791         case NM_EXTR_S_H:
19792             gen_helper_extr_s_h(t0, t0, t1, cpu_env);
19793             gen_store_gpr(t0, ret);
19794             break;
19795         }
19796         break;
19797     default:
19798         generate_exception_end(ctx, EXCP_RI);
19799         break;
19800     }
19801 
19802     tcg_temp_free(t0);
19803     tcg_temp_free(t1);
19804     tcg_temp_free(v0_t);
19805 }
19806 
gen_pool32axf_2_multiply(DisasContext * ctx,uint32_t opc,TCGv v0,TCGv v1,int rd)19807 static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc,
19808                                     TCGv v0, TCGv v1, int rd)
19809 {
19810     TCGv_i32 t0;
19811 
19812     t0 = tcg_temp_new_i32();
19813 
19814     tcg_gen_movi_i32(t0, rd >> 3);
19815 
19816     switch (opc) {
19817     case NM_POOL32AXF_2_0_7:
19818         switch (extract32(ctx->opcode, 9, 3)) {
19819         case NM_DPA_W_PH:
19820             check_dsp_r2(ctx);
19821             gen_helper_dpa_w_ph(t0, v1, v0, cpu_env);
19822             break;
19823         case NM_DPAQ_S_W_PH:
19824             check_dsp(ctx);
19825             gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env);
19826             break;
19827         case NM_DPS_W_PH:
19828             check_dsp_r2(ctx);
19829             gen_helper_dps_w_ph(t0, v1, v0, cpu_env);
19830             break;
19831         case NM_DPSQ_S_W_PH:
19832             check_dsp(ctx);
19833             gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env);
19834             break;
19835         default:
19836             generate_exception_end(ctx, EXCP_RI);
19837             break;
19838         }
19839         break;
19840     case NM_POOL32AXF_2_8_15:
19841         switch (extract32(ctx->opcode, 9, 3)) {
19842         case NM_DPAX_W_PH:
19843             check_dsp_r2(ctx);
19844             gen_helper_dpax_w_ph(t0, v0, v1, cpu_env);
19845             break;
19846         case NM_DPAQ_SA_L_W:
19847             check_dsp(ctx);
19848             gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env);
19849             break;
19850         case NM_DPSX_W_PH:
19851             check_dsp_r2(ctx);
19852             gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env);
19853             break;
19854         case NM_DPSQ_SA_L_W:
19855             check_dsp(ctx);
19856             gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env);
19857             break;
19858         default:
19859             generate_exception_end(ctx, EXCP_RI);
19860             break;
19861         }
19862         break;
19863     case NM_POOL32AXF_2_16_23:
19864         switch (extract32(ctx->opcode, 9, 3)) {
19865         case NM_DPAU_H_QBL:
19866             check_dsp(ctx);
19867             gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env);
19868             break;
19869         case NM_DPAQX_S_W_PH:
19870             check_dsp_r2(ctx);
19871             gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env);
19872             break;
19873         case NM_DPSU_H_QBL:
19874             check_dsp(ctx);
19875             gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env);
19876             break;
19877         case NM_DPSQX_S_W_PH:
19878             check_dsp_r2(ctx);
19879             gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env);
19880             break;
19881         case NM_MULSA_W_PH:
19882             check_dsp_r2(ctx);
19883             gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env);
19884             break;
19885         default:
19886             generate_exception_end(ctx, EXCP_RI);
19887             break;
19888         }
19889         break;
19890     case NM_POOL32AXF_2_24_31:
19891         switch (extract32(ctx->opcode, 9, 3)) {
19892         case NM_DPAU_H_QBR:
19893             check_dsp(ctx);
19894             gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env);
19895             break;
19896         case NM_DPAQX_SA_W_PH:
19897             check_dsp_r2(ctx);
19898             gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env);
19899             break;
19900         case NM_DPSU_H_QBR:
19901             check_dsp(ctx);
19902             gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env);
19903             break;
19904         case NM_DPSQX_SA_W_PH:
19905             check_dsp_r2(ctx);
19906             gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env);
19907             break;
19908         case NM_MULSAQ_S_W_PH:
19909             check_dsp(ctx);
19910             gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env);
19911             break;
19912         default:
19913             generate_exception_end(ctx, EXCP_RI);
19914             break;
19915         }
19916         break;
19917     default:
19918         generate_exception_end(ctx, EXCP_RI);
19919         break;
19920     }
19921 
19922     tcg_temp_free_i32(t0);
19923 }
19924 
gen_pool32axf_2_nanomips_insn(DisasContext * ctx,uint32_t opc,int rt,int rs,int rd)19925 static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc,
19926                                           int rt, int rs, int rd)
19927 {
19928     int ret = rt;
19929     TCGv t0 = tcg_temp_new();
19930     TCGv t1 = tcg_temp_new();
19931     TCGv v0_t = tcg_temp_new();
19932     TCGv v1_t = tcg_temp_new();
19933 
19934     gen_load_gpr(v0_t, rt);
19935     gen_load_gpr(v1_t, rs);
19936 
19937     switch (opc) {
19938     case NM_POOL32AXF_2_0_7:
19939         switch (extract32(ctx->opcode, 9, 3)) {
19940         case NM_DPA_W_PH:
19941         case NM_DPAQ_S_W_PH:
19942         case NM_DPS_W_PH:
19943         case NM_DPSQ_S_W_PH:
19944             gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19945             break;
19946         case NM_BALIGN:
19947             check_dsp_r2(ctx);
19948             if (rt != 0) {
19949                 gen_load_gpr(t0, rs);
19950                 rd &= 3;
19951                 if (rd != 0 && rd != 2) {
19952                     tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd);
19953                     tcg_gen_ext32u_tl(t0, t0);
19954                     tcg_gen_shri_tl(t0, t0, 8 * (4 - rd));
19955                     tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
19956                 }
19957                 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
19958             }
19959             break;
19960         case NM_MADD:
19961             check_dsp(ctx);
19962             {
19963                 int acc = extract32(ctx->opcode, 14, 2);
19964                 TCGv_i64 t2 = tcg_temp_new_i64();
19965                 TCGv_i64 t3 = tcg_temp_new_i64();
19966 
19967                 gen_load_gpr(t0, rt);
19968                 gen_load_gpr(t1, rs);
19969                 tcg_gen_ext_tl_i64(t2, t0);
19970                 tcg_gen_ext_tl_i64(t3, t1);
19971                 tcg_gen_mul_i64(t2, t2, t3);
19972                 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19973                 tcg_gen_add_i64(t2, t2, t3);
19974                 tcg_temp_free_i64(t3);
19975                 gen_move_low32(cpu_LO[acc], t2);
19976                 gen_move_high32(cpu_HI[acc], t2);
19977                 tcg_temp_free_i64(t2);
19978             }
19979             break;
19980         case NM_MULT:
19981             check_dsp(ctx);
19982             {
19983                 int acc = extract32(ctx->opcode, 14, 2);
19984                 TCGv_i32 t2 = tcg_temp_new_i32();
19985                 TCGv_i32 t3 = tcg_temp_new_i32();
19986 
19987                 gen_load_gpr(t0, rs);
19988                 gen_load_gpr(t1, rt);
19989                 tcg_gen_trunc_tl_i32(t2, t0);
19990                 tcg_gen_trunc_tl_i32(t3, t1);
19991                 tcg_gen_muls2_i32(t2, t3, t2, t3);
19992                 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
19993                 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
19994                 tcg_temp_free_i32(t2);
19995                 tcg_temp_free_i32(t3);
19996             }
19997             break;
19998         case NM_EXTRV_W:
19999             check_dsp(ctx);
20000             gen_load_gpr(v1_t, rs);
20001             tcg_gen_movi_tl(t0, rd >> 3);
20002             gen_helper_extr_w(t0, t0, v1_t, cpu_env);
20003             gen_store_gpr(t0, ret);
20004             break;
20005         }
20006         break;
20007     case NM_POOL32AXF_2_8_15:
20008         switch (extract32(ctx->opcode, 9, 3)) {
20009         case NM_DPAX_W_PH:
20010         case NM_DPAQ_SA_L_W:
20011         case NM_DPSX_W_PH:
20012         case NM_DPSQ_SA_L_W:
20013             gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
20014             break;
20015         case NM_MADDU:
20016             check_dsp(ctx);
20017             {
20018                 int acc = extract32(ctx->opcode, 14, 2);
20019                 TCGv_i64 t2 = tcg_temp_new_i64();
20020                 TCGv_i64 t3 = tcg_temp_new_i64();
20021 
20022                 gen_load_gpr(t0, rs);
20023                 gen_load_gpr(t1, rt);
20024                 tcg_gen_ext32u_tl(t0, t0);
20025                 tcg_gen_ext32u_tl(t1, t1);
20026                 tcg_gen_extu_tl_i64(t2, t0);
20027                 tcg_gen_extu_tl_i64(t3, t1);
20028                 tcg_gen_mul_i64(t2, t2, t3);
20029                 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
20030                 tcg_gen_add_i64(t2, t2, t3);
20031                 tcg_temp_free_i64(t3);
20032                 gen_move_low32(cpu_LO[acc], t2);
20033                 gen_move_high32(cpu_HI[acc], t2);
20034                 tcg_temp_free_i64(t2);
20035             }
20036             break;
20037         case NM_MULTU:
20038             check_dsp(ctx);
20039             {
20040                 int acc = extract32(ctx->opcode, 14, 2);
20041                 TCGv_i32 t2 = tcg_temp_new_i32();
20042                 TCGv_i32 t3 = tcg_temp_new_i32();
20043 
20044                 gen_load_gpr(t0, rs);
20045                 gen_load_gpr(t1, rt);
20046                 tcg_gen_trunc_tl_i32(t2, t0);
20047                 tcg_gen_trunc_tl_i32(t3, t1);
20048                 tcg_gen_mulu2_i32(t2, t3, t2, t3);
20049                 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
20050                 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
20051                 tcg_temp_free_i32(t2);
20052                 tcg_temp_free_i32(t3);
20053             }
20054             break;
20055         case NM_EXTRV_R_W:
20056             check_dsp(ctx);
20057             tcg_gen_movi_tl(t0, rd >> 3);
20058             gen_helper_extr_r_w(t0, t0, v1_t, cpu_env);
20059             gen_store_gpr(t0, ret);
20060             break;
20061         default:
20062             generate_exception_end(ctx, EXCP_RI);
20063             break;
20064         }
20065         break;
20066     case NM_POOL32AXF_2_16_23:
20067         switch (extract32(ctx->opcode, 9, 3)) {
20068         case NM_DPAU_H_QBL:
20069         case NM_DPAQX_S_W_PH:
20070         case NM_DPSU_H_QBL:
20071         case NM_DPSQX_S_W_PH:
20072         case NM_MULSA_W_PH:
20073             gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
20074             break;
20075         case NM_EXTPV:
20076             check_dsp(ctx);
20077             tcg_gen_movi_tl(t0, rd >> 3);
20078             gen_helper_extp(t0, t0, v1_t, cpu_env);
20079             gen_store_gpr(t0, ret);
20080             break;
20081         case NM_MSUB:
20082             check_dsp(ctx);
20083             {
20084                 int acc = extract32(ctx->opcode, 14, 2);
20085                 TCGv_i64 t2 = tcg_temp_new_i64();
20086                 TCGv_i64 t3 = tcg_temp_new_i64();
20087 
20088                 gen_load_gpr(t0, rs);
20089                 gen_load_gpr(t1, rt);
20090                 tcg_gen_ext_tl_i64(t2, t0);
20091                 tcg_gen_ext_tl_i64(t3, t1);
20092                 tcg_gen_mul_i64(t2, t2, t3);
20093                 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
20094                 tcg_gen_sub_i64(t2, t3, t2);
20095                 tcg_temp_free_i64(t3);
20096                 gen_move_low32(cpu_LO[acc], t2);
20097                 gen_move_high32(cpu_HI[acc], t2);
20098                 tcg_temp_free_i64(t2);
20099             }
20100             break;
20101         case NM_EXTRV_RS_W:
20102             check_dsp(ctx);
20103             tcg_gen_movi_tl(t0, rd >> 3);
20104             gen_helper_extr_rs_w(t0, t0, v1_t, cpu_env);
20105             gen_store_gpr(t0, ret);
20106             break;
20107         }
20108         break;
20109     case NM_POOL32AXF_2_24_31:
20110         switch (extract32(ctx->opcode, 9, 3)) {
20111         case NM_DPAU_H_QBR:
20112         case NM_DPAQX_SA_W_PH:
20113         case NM_DPSU_H_QBR:
20114         case NM_DPSQX_SA_W_PH:
20115         case NM_MULSAQ_S_W_PH:
20116             gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
20117             break;
20118         case NM_EXTPDPV:
20119             check_dsp(ctx);
20120             tcg_gen_movi_tl(t0, rd >> 3);
20121             gen_helper_extpdp(t0, t0, v1_t, cpu_env);
20122             gen_store_gpr(t0, ret);
20123             break;
20124         case NM_MSUBU:
20125             check_dsp(ctx);
20126             {
20127                 int acc = extract32(ctx->opcode, 14, 2);
20128                 TCGv_i64 t2 = tcg_temp_new_i64();
20129                 TCGv_i64 t3 = tcg_temp_new_i64();
20130 
20131                 gen_load_gpr(t0, rs);
20132                 gen_load_gpr(t1, rt);
20133                 tcg_gen_ext32u_tl(t0, t0);
20134                 tcg_gen_ext32u_tl(t1, t1);
20135                 tcg_gen_extu_tl_i64(t2, t0);
20136                 tcg_gen_extu_tl_i64(t3, t1);
20137                 tcg_gen_mul_i64(t2, t2, t3);
20138                 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
20139                 tcg_gen_sub_i64(t2, t3, t2);
20140                 tcg_temp_free_i64(t3);
20141                 gen_move_low32(cpu_LO[acc], t2);
20142                 gen_move_high32(cpu_HI[acc], t2);
20143                 tcg_temp_free_i64(t2);
20144             }
20145             break;
20146         case NM_EXTRV_S_H:
20147             check_dsp(ctx);
20148             tcg_gen_movi_tl(t0, rd >> 3);
20149             gen_helper_extr_s_h(t0, t0, v0_t, cpu_env);
20150             gen_store_gpr(t0, ret);
20151             break;
20152         }
20153         break;
20154     default:
20155         generate_exception_end(ctx, EXCP_RI);
20156         break;
20157     }
20158 
20159     tcg_temp_free(t0);
20160     tcg_temp_free(t1);
20161 
20162     tcg_temp_free(v0_t);
20163     tcg_temp_free(v1_t);
20164 }
20165 
gen_pool32axf_4_nanomips_insn(DisasContext * ctx,uint32_t opc,int rt,int rs)20166 static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc,
20167                                           int rt, int rs)
20168 {
20169     int ret = rt;
20170     TCGv t0 = tcg_temp_new();
20171     TCGv v0_t = tcg_temp_new();
20172 
20173     gen_load_gpr(v0_t, rs);
20174 
20175     switch (opc) {
20176     case NM_ABSQ_S_QB:
20177         check_dsp_r2(ctx);
20178         gen_helper_absq_s_qb(v0_t, v0_t, cpu_env);
20179         gen_store_gpr(v0_t, ret);
20180         break;
20181     case NM_ABSQ_S_PH:
20182         check_dsp(ctx);
20183         gen_helper_absq_s_ph(v0_t, v0_t, cpu_env);
20184         gen_store_gpr(v0_t, ret);
20185         break;
20186     case NM_ABSQ_S_W:
20187         check_dsp(ctx);
20188         gen_helper_absq_s_w(v0_t, v0_t, cpu_env);
20189         gen_store_gpr(v0_t, ret);
20190         break;
20191     case NM_PRECEQ_W_PHL:
20192         check_dsp(ctx);
20193         tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000);
20194         tcg_gen_ext32s_tl(v0_t, v0_t);
20195         gen_store_gpr(v0_t, ret);
20196         break;
20197     case NM_PRECEQ_W_PHR:
20198         check_dsp(ctx);
20199         tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF);
20200         tcg_gen_shli_tl(v0_t, v0_t, 16);
20201         tcg_gen_ext32s_tl(v0_t, v0_t);
20202         gen_store_gpr(v0_t, ret);
20203         break;
20204     case NM_PRECEQU_PH_QBL:
20205         check_dsp(ctx);
20206         gen_helper_precequ_ph_qbl(v0_t, v0_t);
20207         gen_store_gpr(v0_t, ret);
20208         break;
20209     case NM_PRECEQU_PH_QBR:
20210         check_dsp(ctx);
20211         gen_helper_precequ_ph_qbr(v0_t, v0_t);
20212         gen_store_gpr(v0_t, ret);
20213         break;
20214     case NM_PRECEQU_PH_QBLA:
20215         check_dsp(ctx);
20216         gen_helper_precequ_ph_qbla(v0_t, v0_t);
20217         gen_store_gpr(v0_t, ret);
20218         break;
20219     case NM_PRECEQU_PH_QBRA:
20220         check_dsp(ctx);
20221         gen_helper_precequ_ph_qbra(v0_t, v0_t);
20222         gen_store_gpr(v0_t, ret);
20223         break;
20224     case NM_PRECEU_PH_QBL:
20225         check_dsp(ctx);
20226         gen_helper_preceu_ph_qbl(v0_t, v0_t);
20227         gen_store_gpr(v0_t, ret);
20228         break;
20229     case NM_PRECEU_PH_QBR:
20230         check_dsp(ctx);
20231         gen_helper_preceu_ph_qbr(v0_t, v0_t);
20232         gen_store_gpr(v0_t, ret);
20233         break;
20234     case NM_PRECEU_PH_QBLA:
20235         check_dsp(ctx);
20236         gen_helper_preceu_ph_qbla(v0_t, v0_t);
20237         gen_store_gpr(v0_t, ret);
20238         break;
20239     case NM_PRECEU_PH_QBRA:
20240         check_dsp(ctx);
20241         gen_helper_preceu_ph_qbra(v0_t, v0_t);
20242         gen_store_gpr(v0_t, ret);
20243         break;
20244     case NM_REPLV_PH:
20245         check_dsp(ctx);
20246         tcg_gen_ext16u_tl(v0_t, v0_t);
20247         tcg_gen_shli_tl(t0, v0_t, 16);
20248         tcg_gen_or_tl(v0_t, v0_t, t0);
20249         tcg_gen_ext32s_tl(v0_t, v0_t);
20250         gen_store_gpr(v0_t, ret);
20251         break;
20252     case NM_REPLV_QB:
20253         check_dsp(ctx);
20254         tcg_gen_ext8u_tl(v0_t, v0_t);
20255         tcg_gen_shli_tl(t0, v0_t, 8);
20256         tcg_gen_or_tl(v0_t, v0_t, t0);
20257         tcg_gen_shli_tl(t0, v0_t, 16);
20258         tcg_gen_or_tl(v0_t, v0_t, t0);
20259         tcg_gen_ext32s_tl(v0_t, v0_t);
20260         gen_store_gpr(v0_t, ret);
20261         break;
20262     case NM_BITREV:
20263         check_dsp(ctx);
20264         gen_helper_bitrev(v0_t, v0_t);
20265         gen_store_gpr(v0_t, ret);
20266         break;
20267     case NM_INSV:
20268         check_dsp(ctx);
20269         {
20270             TCGv tv0 = tcg_temp_new();
20271 
20272             gen_load_gpr(tv0, rt);
20273             gen_helper_insv(v0_t, cpu_env, v0_t, tv0);
20274             gen_store_gpr(v0_t, ret);
20275             tcg_temp_free(tv0);
20276         }
20277         break;
20278     case NM_RADDU_W_QB:
20279         check_dsp(ctx);
20280         gen_helper_raddu_w_qb(v0_t, v0_t);
20281         gen_store_gpr(v0_t, ret);
20282         break;
20283     case NM_BITSWAP:
20284         gen_bitswap(ctx, OPC_BITSWAP, ret, rs);
20285         break;
20286     case NM_CLO:
20287         check_nms(ctx);
20288         gen_cl(ctx, OPC_CLO, ret, rs);
20289         break;
20290     case NM_CLZ:
20291         check_nms(ctx);
20292         gen_cl(ctx, OPC_CLZ, ret, rs);
20293         break;
20294     case NM_WSBH:
20295         gen_bshfl(ctx, OPC_WSBH, ret, rs);
20296         break;
20297     default:
20298         generate_exception_end(ctx, EXCP_RI);
20299         break;
20300     }
20301 
20302     tcg_temp_free(v0_t);
20303     tcg_temp_free(t0);
20304 }
20305 
gen_pool32axf_7_nanomips_insn(DisasContext * ctx,uint32_t opc,int rt,int rs,int rd)20306 static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc,
20307                                           int rt, int rs, int rd)
20308 {
20309     TCGv t0 = tcg_temp_new();
20310     TCGv rs_t = tcg_temp_new();
20311 
20312     gen_load_gpr(rs_t, rs);
20313 
20314     switch (opc) {
20315     case NM_SHRA_R_QB:
20316         check_dsp_r2(ctx);
20317         tcg_gen_movi_tl(t0, rd >> 2);
20318         switch (extract32(ctx->opcode, 12, 1)) {
20319         case 0:
20320             /* NM_SHRA_QB */
20321             gen_helper_shra_qb(t0, t0, rs_t);
20322             gen_store_gpr(t0, rt);
20323             break;
20324         case 1:
20325             /* NM_SHRA_R_QB */
20326             gen_helper_shra_r_qb(t0, t0, rs_t);
20327             gen_store_gpr(t0, rt);
20328             break;
20329         }
20330         break;
20331     case NM_SHRL_PH:
20332         check_dsp_r2(ctx);
20333         tcg_gen_movi_tl(t0, rd >> 1);
20334         gen_helper_shrl_ph(t0, t0, rs_t);
20335         gen_store_gpr(t0, rt);
20336         break;
20337     case NM_REPL_QB:
20338         check_dsp(ctx);
20339         {
20340             int16_t imm;
20341             target_long result;
20342             imm = extract32(ctx->opcode, 13, 8);
20343             result = (uint32_t)imm << 24 |
20344                      (uint32_t)imm << 16 |
20345                      (uint32_t)imm << 8  |
20346                      (uint32_t)imm;
20347             result = (int32_t)result;
20348             tcg_gen_movi_tl(t0, result);
20349             gen_store_gpr(t0, rt);
20350         }
20351         break;
20352     default:
20353         generate_exception_end(ctx, EXCP_RI);
20354         break;
20355     }
20356     tcg_temp_free(t0);
20357     tcg_temp_free(rs_t);
20358 }
20359 
20360 
gen_pool32axf_nanomips_insn(CPUMIPSState * env,DisasContext * ctx)20361 static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
20362 {
20363     int rt = extract32(ctx->opcode, 21, 5);
20364     int rs = extract32(ctx->opcode, 16, 5);
20365     int rd = extract32(ctx->opcode, 11, 5);
20366 
20367     switch (extract32(ctx->opcode, 6, 3)) {
20368     case NM_POOL32AXF_1:
20369         {
20370             int32_t op1 = extract32(ctx->opcode, 9, 3);
20371             gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd);
20372         }
20373         break;
20374     case NM_POOL32AXF_2:
20375         {
20376             int32_t op1 = extract32(ctx->opcode, 12, 2);
20377             gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd);
20378         }
20379         break;
20380     case NM_POOL32AXF_4:
20381         {
20382             int32_t op1 = extract32(ctx->opcode, 9, 7);
20383             gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs);
20384         }
20385         break;
20386     case NM_POOL32AXF_5:
20387         switch (extract32(ctx->opcode, 9, 7)) {
20388 #ifndef CONFIG_USER_ONLY
20389         case NM_TLBP:
20390             gen_cp0(env, ctx, OPC_TLBP, 0, 0);
20391             break;
20392         case NM_TLBR:
20393             gen_cp0(env, ctx, OPC_TLBR, 0, 0);
20394             break;
20395         case NM_TLBWI:
20396             gen_cp0(env, ctx, OPC_TLBWI, 0, 0);
20397             break;
20398         case NM_TLBWR:
20399             gen_cp0(env, ctx, OPC_TLBWR, 0, 0);
20400             break;
20401         case NM_TLBINV:
20402             gen_cp0(env, ctx, OPC_TLBINV, 0, 0);
20403             break;
20404         case NM_TLBINVF:
20405             gen_cp0(env, ctx, OPC_TLBINVF, 0, 0);
20406             break;
20407         case NM_DI:
20408             check_cp0_enabled(ctx);
20409             {
20410                 TCGv t0 = tcg_temp_new();
20411 
20412                 save_cpu_state(ctx, 1);
20413                 gen_helper_di(t0, cpu_env);
20414                 gen_store_gpr(t0, rt);
20415             /* Stop translation as we may have switched the execution mode */
20416                 ctx->base.is_jmp = DISAS_STOP;
20417                 tcg_temp_free(t0);
20418             }
20419             break;
20420         case NM_EI:
20421             check_cp0_enabled(ctx);
20422             {
20423                 TCGv t0 = tcg_temp_new();
20424 
20425                 save_cpu_state(ctx, 1);
20426                 gen_helper_ei(t0, cpu_env);
20427                 gen_store_gpr(t0, rt);
20428             /* Stop translation as we may have switched the execution mode */
20429                 ctx->base.is_jmp = DISAS_STOP;
20430                 tcg_temp_free(t0);
20431             }
20432             break;
20433         case NM_RDPGPR:
20434             gen_load_srsgpr(rs, rt);
20435             break;
20436         case NM_WRPGPR:
20437             gen_store_srsgpr(rs, rt);
20438             break;
20439         case NM_WAIT:
20440             gen_cp0(env, ctx, OPC_WAIT, 0, 0);
20441             break;
20442         case NM_DERET:
20443             gen_cp0(env, ctx, OPC_DERET, 0, 0);
20444             break;
20445         case NM_ERETX:
20446             gen_cp0(env, ctx, OPC_ERET, 0, 0);
20447             break;
20448 #endif
20449         default:
20450             generate_exception_end(ctx, EXCP_RI);
20451             break;
20452         }
20453         break;
20454     case NM_POOL32AXF_7:
20455         {
20456             int32_t op1 = extract32(ctx->opcode, 9, 3);
20457             gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd);
20458         }
20459         break;
20460     default:
20461         generate_exception_end(ctx, EXCP_RI);
20462         break;
20463     }
20464 }
20465 
20466 /* Immediate Value Compact Branches */
gen_compute_imm_branch(DisasContext * ctx,uint32_t opc,int rt,int32_t imm,int32_t offset)20467 static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc,
20468                                    int rt, int32_t imm, int32_t offset)
20469 {
20470     TCGCond cond = TCG_COND_ALWAYS;
20471     TCGv t0 = tcg_temp_new();
20472     TCGv t1 = tcg_temp_new();
20473 
20474     gen_load_gpr(t0, rt);
20475     tcg_gen_movi_tl(t1, imm);
20476     ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
20477 
20478     /* Load needed operands and calculate btarget */
20479     switch (opc) {
20480     case NM_BEQIC:
20481         if (rt == 0 && imm == 0) {
20482             /* Unconditional branch */
20483         } else if (rt == 0 && imm != 0) {
20484             /* Treat as NOP */
20485             goto out;
20486         } else {
20487             cond = TCG_COND_EQ;
20488         }
20489         break;
20490     case NM_BBEQZC:
20491     case NM_BBNEZC:
20492         check_nms(ctx);
20493         if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) {
20494             generate_exception_end(ctx, EXCP_RI);
20495             goto out;
20496         } else if (rt == 0 && opc == NM_BBEQZC) {
20497             /* Unconditional branch */
20498         } else if (rt == 0 && opc == NM_BBNEZC) {
20499             /* Treat as NOP */
20500             goto out;
20501         } else {
20502             tcg_gen_shri_tl(t0, t0, imm);
20503             tcg_gen_andi_tl(t0, t0, 1);
20504             tcg_gen_movi_tl(t1, 0);
20505             if (opc == NM_BBEQZC) {
20506                 cond = TCG_COND_EQ;
20507             } else {
20508                 cond = TCG_COND_NE;
20509             }
20510         }
20511         break;
20512     case NM_BNEIC:
20513         if (rt == 0 && imm == 0) {
20514             /* Treat as NOP */
20515             goto out;
20516         } else if (rt == 0 && imm != 0) {
20517             /* Unconditional branch */
20518         } else {
20519             cond = TCG_COND_NE;
20520         }
20521         break;
20522     case NM_BGEIC:
20523         if (rt == 0 && imm == 0) {
20524             /* Unconditional branch */
20525         } else  {
20526             cond = TCG_COND_GE;
20527         }
20528         break;
20529     case NM_BLTIC:
20530         cond = TCG_COND_LT;
20531         break;
20532     case NM_BGEIUC:
20533         if (rt == 0 && imm == 0) {
20534             /* Unconditional branch */
20535         } else  {
20536             cond = TCG_COND_GEU;
20537         }
20538         break;
20539     case NM_BLTIUC:
20540         cond = TCG_COND_LTU;
20541         break;
20542     default:
20543         MIPS_INVAL("Immediate Value Compact branch");
20544         generate_exception_end(ctx, EXCP_RI);
20545         goto out;
20546     }
20547 
20548     /* branch completion */
20549     clear_branch_hflags(ctx);
20550     ctx->base.is_jmp = DISAS_NORETURN;
20551 
20552     if (cond == TCG_COND_ALWAYS) {
20553         /* Uncoditional compact branch */
20554         gen_goto_tb(ctx, 0, ctx->btarget);
20555     } else {
20556         /* Conditional compact branch */
20557         TCGLabel *fs = gen_new_label();
20558 
20559         tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs);
20560 
20561         gen_goto_tb(ctx, 1, ctx->btarget);
20562         gen_set_label(fs);
20563 
20564         gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
20565     }
20566 
20567 out:
20568     tcg_temp_free(t0);
20569     tcg_temp_free(t1);
20570 }
20571 
20572 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
gen_compute_nanomips_pbalrsc_branch(DisasContext * ctx,int rs,int rt)20573 static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs,
20574                                                 int rt)
20575 {
20576     TCGv t0 = tcg_temp_new();
20577     TCGv t1 = tcg_temp_new();
20578 
20579     /* load rs */
20580     gen_load_gpr(t0, rs);
20581 
20582     /* link */
20583     if (rt != 0) {
20584         tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4);
20585     }
20586 
20587     /* calculate btarget */
20588     tcg_gen_shli_tl(t0, t0, 1);
20589     tcg_gen_movi_tl(t1, ctx->base.pc_next + 4);
20590     gen_op_addr_add(ctx, btarget, t1, t0);
20591 
20592     /* branch completion */
20593     clear_branch_hflags(ctx);
20594     ctx->base.is_jmp = DISAS_NORETURN;
20595 
20596     /* unconditional branch to register */
20597     tcg_gen_mov_tl(cpu_PC, btarget);
20598     tcg_gen_lookup_and_goto_ptr();
20599 
20600     tcg_temp_free(t0);
20601     tcg_temp_free(t1);
20602 }
20603 
20604 /* nanoMIPS Branches */
gen_compute_compact_branch_nm(DisasContext * ctx,uint32_t opc,int rs,int rt,int32_t offset)20605 static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc,
20606                                        int rs, int rt, int32_t offset)
20607 {
20608     int bcond_compute = 0;
20609     TCGv t0 = tcg_temp_new();
20610     TCGv t1 = tcg_temp_new();
20611 
20612     /* Load needed operands and calculate btarget */
20613     switch (opc) {
20614     /* compact branch */
20615     case OPC_BGEC:
20616     case OPC_BLTC:
20617         gen_load_gpr(t0, rs);
20618         gen_load_gpr(t1, rt);
20619         bcond_compute = 1;
20620         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
20621         break;
20622     case OPC_BGEUC:
20623     case OPC_BLTUC:
20624         if (rs == 0 || rs == rt) {
20625             /* OPC_BLEZALC, OPC_BGEZALC */
20626             /* OPC_BGTZALC, OPC_BLTZALC */
20627             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4);
20628         }
20629         gen_load_gpr(t0, rs);
20630         gen_load_gpr(t1, rt);
20631         bcond_compute = 1;
20632         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
20633         break;
20634     case OPC_BC:
20635         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
20636         break;
20637     case OPC_BEQZC:
20638         if (rs != 0) {
20639             /* OPC_BEQZC, OPC_BNEZC */
20640             gen_load_gpr(t0, rs);
20641             bcond_compute = 1;
20642             ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
20643         } else {
20644             /* OPC_JIC, OPC_JIALC */
20645             TCGv tbase = tcg_temp_new();
20646             TCGv toffset = tcg_temp_new();
20647 
20648             gen_load_gpr(tbase, rt);
20649             tcg_gen_movi_tl(toffset, offset);
20650             gen_op_addr_add(ctx, btarget, tbase, toffset);
20651             tcg_temp_free(tbase);
20652             tcg_temp_free(toffset);
20653         }
20654         break;
20655     default:
20656         MIPS_INVAL("Compact branch/jump");
20657         generate_exception_end(ctx, EXCP_RI);
20658         goto out;
20659     }
20660 
20661     if (bcond_compute == 0) {
20662         /* Uncoditional compact branch */
20663         switch (opc) {
20664         case OPC_BC:
20665             gen_goto_tb(ctx, 0, ctx->btarget);
20666             break;
20667         default:
20668             MIPS_INVAL("Compact branch/jump");
20669             generate_exception_end(ctx, EXCP_RI);
20670             goto out;
20671         }
20672     } else {
20673         /* Conditional compact branch */
20674         TCGLabel *fs = gen_new_label();
20675 
20676         switch (opc) {
20677         case OPC_BGEUC:
20678             if (rs == 0 && rt != 0) {
20679                 /* OPC_BLEZALC */
20680                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
20681             } else if (rs != 0 && rt != 0 && rs == rt) {
20682                 /* OPC_BGEZALC */
20683                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
20684             } else {
20685                 /* OPC_BGEUC */
20686                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
20687             }
20688             break;
20689         case OPC_BLTUC:
20690             if (rs == 0 && rt != 0) {
20691                 /* OPC_BGTZALC */
20692                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
20693             } else if (rs != 0 && rt != 0 && rs == rt) {
20694                 /* OPC_BLTZALC */
20695                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
20696             } else {
20697                 /* OPC_BLTUC */
20698                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
20699             }
20700             break;
20701         case OPC_BGEC:
20702             if (rs == 0 && rt != 0) {
20703                 /* OPC_BLEZC */
20704                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
20705             } else if (rs != 0 && rt != 0 && rs == rt) {
20706                 /* OPC_BGEZC */
20707                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
20708             } else {
20709                 /* OPC_BGEC */
20710                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
20711             }
20712             break;
20713         case OPC_BLTC:
20714             if (rs == 0 && rt != 0) {
20715                 /* OPC_BGTZC */
20716                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
20717             } else if (rs != 0 && rt != 0 && rs == rt) {
20718                 /* OPC_BLTZC */
20719                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
20720             } else {
20721                 /* OPC_BLTC */
20722                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
20723             }
20724             break;
20725         case OPC_BEQZC:
20726             tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
20727             break;
20728         default:
20729             MIPS_INVAL("Compact conditional branch/jump");
20730             generate_exception_end(ctx, EXCP_RI);
20731             goto out;
20732         }
20733 
20734         /* branch completion */
20735         clear_branch_hflags(ctx);
20736         ctx->base.is_jmp = DISAS_NORETURN;
20737 
20738         /* Generating branch here as compact branches don't have delay slot */
20739         gen_goto_tb(ctx, 1, ctx->btarget);
20740         gen_set_label(fs);
20741 
20742         gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
20743     }
20744 
20745 out:
20746     tcg_temp_free(t0);
20747     tcg_temp_free(t1);
20748 }
20749 
20750 
20751 /* nanoMIPS CP1 Branches */
gen_compute_branch_cp1_nm(DisasContext * ctx,uint32_t op,int32_t ft,int32_t offset)20752 static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op,
20753                                    int32_t ft, int32_t offset)
20754 {
20755     target_ulong btarget;
20756     TCGv_i64 t0 = tcg_temp_new_i64();
20757 
20758     gen_load_fpr64(ctx, t0, ft);
20759     tcg_gen_andi_i64(t0, t0, 1);
20760 
20761     btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
20762 
20763     switch (op) {
20764     case NM_BC1EQZC:
20765         tcg_gen_xori_i64(t0, t0, 1);
20766         ctx->hflags |= MIPS_HFLAG_BC;
20767         break;
20768     case NM_BC1NEZC:
20769         /* t0 already set */
20770         ctx->hflags |= MIPS_HFLAG_BC;
20771         break;
20772     default:
20773         MIPS_INVAL("cp1 cond branch");
20774         generate_exception_end(ctx, EXCP_RI);
20775         goto out;
20776     }
20777 
20778     tcg_gen_trunc_i64_tl(bcond, t0);
20779 
20780     ctx->btarget = btarget;
20781 
20782 out:
20783     tcg_temp_free_i64(t0);
20784 }
20785 
20786 
gen_p_lsx(DisasContext * ctx,int rd,int rs,int rt)20787 static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt)
20788 {
20789     TCGv t0, t1;
20790     t0 = tcg_temp_new();
20791     t1 = tcg_temp_new();
20792 
20793     gen_load_gpr(t0, rs);
20794     gen_load_gpr(t1, rt);
20795 
20796     if ((extract32(ctx->opcode, 6, 1)) == 1) {
20797         /* PP.LSXS instructions require shifting */
20798         switch (extract32(ctx->opcode, 7, 4)) {
20799         case NM_SHXS:
20800             check_nms(ctx);
20801             /* fall through */
20802         case NM_LHXS:
20803         case NM_LHUXS:
20804             tcg_gen_shli_tl(t0, t0, 1);
20805             break;
20806         case NM_SWXS:
20807             check_nms(ctx);
20808             /* fall through */
20809         case NM_LWXS:
20810         case NM_LWC1XS:
20811         case NM_SWC1XS:
20812             tcg_gen_shli_tl(t0, t0, 2);
20813             break;
20814         case NM_LDC1XS:
20815         case NM_SDC1XS:
20816             tcg_gen_shli_tl(t0, t0, 3);
20817             break;
20818         }
20819     }
20820     gen_op_addr_add(ctx, t0, t0, t1);
20821 
20822     switch (extract32(ctx->opcode, 7, 4)) {
20823     case NM_LBX:
20824         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20825                            MO_SB);
20826         gen_store_gpr(t0, rd);
20827         break;
20828     case NM_LHX:
20829     /*case NM_LHXS:*/
20830         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20831                            MO_TESW);
20832         gen_store_gpr(t0, rd);
20833         break;
20834     case NM_LWX:
20835     /*case NM_LWXS:*/
20836         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20837                            MO_TESL);
20838         gen_store_gpr(t0, rd);
20839         break;
20840     case NM_LBUX:
20841         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20842                            MO_UB);
20843         gen_store_gpr(t0, rd);
20844         break;
20845     case NM_LHUX:
20846     /*case NM_LHUXS:*/
20847         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20848                            MO_TEUW);
20849         gen_store_gpr(t0, rd);
20850         break;
20851     case NM_SBX:
20852         check_nms(ctx);
20853         gen_load_gpr(t1, rd);
20854         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20855                            MO_8);
20856         break;
20857     case NM_SHX:
20858     /*case NM_SHXS:*/
20859         check_nms(ctx);
20860         gen_load_gpr(t1, rd);
20861         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20862                            MO_TEUW);
20863         break;
20864     case NM_SWX:
20865     /*case NM_SWXS:*/
20866         check_nms(ctx);
20867         gen_load_gpr(t1, rd);
20868         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20869                            MO_TEUL);
20870         break;
20871     case NM_LWC1X:
20872     /*case NM_LWC1XS:*/
20873     case NM_LDC1X:
20874     /*case NM_LDC1XS:*/
20875     case NM_SWC1X:
20876     /*case NM_SWC1XS:*/
20877     case NM_SDC1X:
20878     /*case NM_SDC1XS:*/
20879         if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
20880             check_cp1_enabled(ctx);
20881             switch (extract32(ctx->opcode, 7, 4)) {
20882             case NM_LWC1X:
20883             /*case NM_LWC1XS:*/
20884                 gen_flt_ldst(ctx, OPC_LWC1, rd, t0);
20885                 break;
20886             case NM_LDC1X:
20887             /*case NM_LDC1XS:*/
20888                 gen_flt_ldst(ctx, OPC_LDC1, rd, t0);
20889                 break;
20890             case NM_SWC1X:
20891             /*case NM_SWC1XS:*/
20892                 gen_flt_ldst(ctx, OPC_SWC1, rd, t0);
20893                 break;
20894             case NM_SDC1X:
20895             /*case NM_SDC1XS:*/
20896                 gen_flt_ldst(ctx, OPC_SDC1, rd, t0);
20897                 break;
20898             }
20899         } else {
20900             generate_exception_err(ctx, EXCP_CpU, 1);
20901         }
20902         break;
20903     default:
20904         generate_exception_end(ctx, EXCP_RI);
20905         break;
20906     }
20907 
20908     tcg_temp_free(t0);
20909     tcg_temp_free(t1);
20910 }
20911 
gen_pool32f_nanomips_insn(DisasContext * ctx)20912 static void gen_pool32f_nanomips_insn(DisasContext *ctx)
20913 {
20914     int rt, rs, rd;
20915 
20916     rt = extract32(ctx->opcode, 21, 5);
20917     rs = extract32(ctx->opcode, 16, 5);
20918     rd = extract32(ctx->opcode, 11, 5);
20919 
20920     if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) {
20921         generate_exception_end(ctx, EXCP_RI);
20922         return;
20923     }
20924     check_cp1_enabled(ctx);
20925     switch (extract32(ctx->opcode, 0, 3)) {
20926     case NM_POOL32F_0:
20927         switch (extract32(ctx->opcode, 3, 7)) {
20928         case NM_RINT_S:
20929             gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
20930             break;
20931         case NM_RINT_D:
20932             gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
20933             break;
20934         case NM_CLASS_S:
20935             gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
20936             break;
20937         case NM_CLASS_D:
20938             gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
20939             break;
20940         case NM_ADD_S:
20941             gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0);
20942             break;
20943         case NM_ADD_D:
20944             gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0);
20945             break;
20946         case NM_SUB_S:
20947             gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0);
20948             break;
20949         case NM_SUB_D:
20950             gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0);
20951             break;
20952         case NM_MUL_S:
20953             gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0);
20954             break;
20955         case NM_MUL_D:
20956             gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0);
20957             break;
20958         case NM_DIV_S:
20959             gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0);
20960             break;
20961         case NM_DIV_D:
20962             gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0);
20963             break;
20964         case NM_SELEQZ_S:
20965             gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
20966             break;
20967         case NM_SELEQZ_D:
20968             gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
20969             break;
20970         case NM_SELNEZ_S:
20971             gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
20972             break;
20973         case NM_SELNEZ_D:
20974             gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
20975             break;
20976         case NM_SEL_S:
20977             gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
20978             break;
20979         case NM_SEL_D:
20980             gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
20981             break;
20982         case NM_MADDF_S:
20983             gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0);
20984             break;
20985         case NM_MADDF_D:
20986             gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0);
20987             break;
20988         case NM_MSUBF_S:
20989             gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0);
20990             break;
20991         case NM_MSUBF_D:
20992             gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0);
20993             break;
20994         default:
20995             generate_exception_end(ctx, EXCP_RI);
20996             break;
20997         }
20998         break;
20999     case NM_POOL32F_3:
21000         switch (extract32(ctx->opcode, 3, 3)) {
21001         case NM_MIN_FMT:
21002             switch (extract32(ctx->opcode, 9, 1)) {
21003             case FMT_SDPS_S:
21004                 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
21005                 break;
21006             case FMT_SDPS_D:
21007                 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
21008                 break;
21009             }
21010             break;
21011         case NM_MAX_FMT:
21012             switch (extract32(ctx->opcode, 9, 1)) {
21013             case FMT_SDPS_S:
21014                 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
21015                 break;
21016             case FMT_SDPS_D:
21017                 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
21018                 break;
21019             }
21020             break;
21021         case NM_MINA_FMT:
21022             switch (extract32(ctx->opcode, 9, 1)) {
21023             case FMT_SDPS_S:
21024                 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
21025                 break;
21026             case FMT_SDPS_D:
21027                 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
21028                 break;
21029             }
21030             break;
21031         case NM_MAXA_FMT:
21032             switch (extract32(ctx->opcode, 9, 1)) {
21033             case FMT_SDPS_S:
21034                 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
21035                 break;
21036             case FMT_SDPS_D:
21037                 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
21038                 break;
21039             }
21040             break;
21041         case NM_POOL32FXF:
21042             switch (extract32(ctx->opcode, 6, 8)) {
21043             case NM_CFC1:
21044                 gen_cp1(ctx, OPC_CFC1, rt, rs);
21045                 break;
21046             case NM_CTC1:
21047                 gen_cp1(ctx, OPC_CTC1, rt, rs);
21048                 break;
21049             case NM_MFC1:
21050                 gen_cp1(ctx, OPC_MFC1, rt, rs);
21051                 break;
21052             case NM_MTC1:
21053                 gen_cp1(ctx, OPC_MTC1, rt, rs);
21054                 break;
21055             case NM_MFHC1:
21056                 gen_cp1(ctx, OPC_MFHC1, rt, rs);
21057                 break;
21058             case NM_MTHC1:
21059                 gen_cp1(ctx, OPC_MTHC1, rt, rs);
21060                 break;
21061             case NM_CVT_S_PL:
21062                 gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0);
21063                 break;
21064             case NM_CVT_S_PU:
21065                 gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0);
21066                 break;
21067             default:
21068                 switch (extract32(ctx->opcode, 6, 9)) {
21069                 case NM_CVT_L_S:
21070                     gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0);
21071                     break;
21072                 case NM_CVT_L_D:
21073                     gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0);
21074                     break;
21075                 case NM_CVT_W_S:
21076                     gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0);
21077                     break;
21078                 case NM_CVT_W_D:
21079                     gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0);
21080                     break;
21081                 case NM_RSQRT_S:
21082                     gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0);
21083                     break;
21084                 case NM_RSQRT_D:
21085                     gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0);
21086                     break;
21087                 case NM_SQRT_S:
21088                     gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0);
21089                     break;
21090                 case NM_SQRT_D:
21091                     gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0);
21092                     break;
21093                 case NM_RECIP_S:
21094                     gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0);
21095                     break;
21096                 case NM_RECIP_D:
21097                     gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0);
21098                     break;
21099                 case NM_FLOOR_L_S:
21100                     gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0);
21101                     break;
21102                 case NM_FLOOR_L_D:
21103                     gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0);
21104                     break;
21105                 case NM_FLOOR_W_S:
21106                     gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0);
21107                     break;
21108                 case NM_FLOOR_W_D:
21109                     gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0);
21110                     break;
21111                 case NM_CEIL_L_S:
21112                     gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0);
21113                     break;
21114                 case NM_CEIL_L_D:
21115                     gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0);
21116                     break;
21117                 case NM_CEIL_W_S:
21118                     gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0);
21119                     break;
21120                 case NM_CEIL_W_D:
21121                     gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0);
21122                     break;
21123                 case NM_TRUNC_L_S:
21124                     gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0);
21125                     break;
21126                 case NM_TRUNC_L_D:
21127                     gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0);
21128                     break;
21129                 case NM_TRUNC_W_S:
21130                     gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0);
21131                     break;
21132                 case NM_TRUNC_W_D:
21133                     gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0);
21134                     break;
21135                 case NM_ROUND_L_S:
21136                     gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0);
21137                     break;
21138                 case NM_ROUND_L_D:
21139                     gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0);
21140                     break;
21141                 case NM_ROUND_W_S:
21142                     gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0);
21143                     break;
21144                 case NM_ROUND_W_D:
21145                     gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0);
21146                     break;
21147                 case NM_MOV_S:
21148                     gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0);
21149                     break;
21150                 case NM_MOV_D:
21151                     gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0);
21152                     break;
21153                 case NM_ABS_S:
21154                     gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0);
21155                     break;
21156                 case NM_ABS_D:
21157                     gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0);
21158                     break;
21159                 case NM_NEG_S:
21160                     gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0);
21161                     break;
21162                 case NM_NEG_D:
21163                     gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0);
21164                     break;
21165                 case NM_CVT_D_S:
21166                     gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0);
21167                     break;
21168                 case NM_CVT_D_W:
21169                     gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0);
21170                     break;
21171                 case NM_CVT_D_L:
21172                     gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0);
21173                     break;
21174                 case NM_CVT_S_D:
21175                     gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0);
21176                     break;
21177                 case NM_CVT_S_W:
21178                     gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0);
21179                     break;
21180                 case NM_CVT_S_L:
21181                     gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0);
21182                     break;
21183                 default:
21184                     generate_exception_end(ctx, EXCP_RI);
21185                     break;
21186                 }
21187                 break;
21188             }
21189             break;
21190         }
21191         break;
21192     case NM_POOL32F_5:
21193         switch (extract32(ctx->opcode, 3, 3)) {
21194         case NM_CMP_CONDN_S:
21195             gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
21196             break;
21197         case NM_CMP_CONDN_D:
21198             gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
21199             break;
21200         default:
21201             generate_exception_end(ctx, EXCP_RI);
21202             break;
21203         }
21204         break;
21205     default:
21206         generate_exception_end(ctx, EXCP_RI);
21207         break;
21208     }
21209 }
21210 
gen_pool32a5_nanomips_insn(DisasContext * ctx,int opc,int rd,int rs,int rt)21211 static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc,
21212                                        int rd, int rs, int rt)
21213 {
21214     int ret = rd;
21215     TCGv t0 = tcg_temp_new();
21216     TCGv v1_t = tcg_temp_new();
21217     TCGv v2_t = tcg_temp_new();
21218 
21219     gen_load_gpr(v1_t, rs);
21220     gen_load_gpr(v2_t, rt);
21221 
21222     switch (opc) {
21223     case NM_CMP_EQ_PH:
21224         check_dsp(ctx);
21225         gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
21226         break;
21227     case NM_CMP_LT_PH:
21228         check_dsp(ctx);
21229         gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
21230         break;
21231     case NM_CMP_LE_PH:
21232         check_dsp(ctx);
21233         gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
21234         break;
21235     case NM_CMPU_EQ_QB:
21236         check_dsp(ctx);
21237         gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
21238         break;
21239     case NM_CMPU_LT_QB:
21240         check_dsp(ctx);
21241         gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
21242         break;
21243     case NM_CMPU_LE_QB:
21244         check_dsp(ctx);
21245         gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
21246         break;
21247     case NM_CMPGU_EQ_QB:
21248         check_dsp(ctx);
21249         gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
21250         gen_store_gpr(v1_t, ret);
21251         break;
21252     case NM_CMPGU_LT_QB:
21253         check_dsp(ctx);
21254         gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
21255         gen_store_gpr(v1_t, ret);
21256         break;
21257     case NM_CMPGU_LE_QB:
21258         check_dsp(ctx);
21259         gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
21260         gen_store_gpr(v1_t, ret);
21261         break;
21262     case NM_CMPGDU_EQ_QB:
21263         check_dsp_r2(ctx);
21264         gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
21265         tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
21266         gen_store_gpr(v1_t, ret);
21267         break;
21268     case NM_CMPGDU_LT_QB:
21269         check_dsp_r2(ctx);
21270         gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
21271         tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
21272         gen_store_gpr(v1_t, ret);
21273         break;
21274     case NM_CMPGDU_LE_QB:
21275         check_dsp_r2(ctx);
21276         gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
21277         tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
21278         gen_store_gpr(v1_t, ret);
21279         break;
21280     case NM_PACKRL_PH:
21281         check_dsp(ctx);
21282         gen_helper_packrl_ph(v1_t, v1_t, v2_t);
21283         gen_store_gpr(v1_t, ret);
21284         break;
21285     case NM_PICK_QB:
21286         check_dsp(ctx);
21287         gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env);
21288         gen_store_gpr(v1_t, ret);
21289         break;
21290     case NM_PICK_PH:
21291         check_dsp(ctx);
21292         gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env);
21293         gen_store_gpr(v1_t, ret);
21294         break;
21295     case NM_ADDQ_S_W:
21296         check_dsp(ctx);
21297         gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env);
21298         gen_store_gpr(v1_t, ret);
21299         break;
21300     case NM_SUBQ_S_W:
21301         check_dsp(ctx);
21302         gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env);
21303         gen_store_gpr(v1_t, ret);
21304         break;
21305     case NM_ADDSC:
21306         check_dsp(ctx);
21307         gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env);
21308         gen_store_gpr(v1_t, ret);
21309         break;
21310     case NM_ADDWC:
21311         check_dsp(ctx);
21312         gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env);
21313         gen_store_gpr(v1_t, ret);
21314         break;
21315     case NM_ADDQ_S_PH:
21316         check_dsp(ctx);
21317         switch (extract32(ctx->opcode, 10, 1)) {
21318         case 0:
21319             /* ADDQ_PH */
21320             gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env);
21321             gen_store_gpr(v1_t, ret);
21322             break;
21323         case 1:
21324             /* ADDQ_S_PH */
21325             gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env);
21326             gen_store_gpr(v1_t, ret);
21327             break;
21328         }
21329         break;
21330     case NM_ADDQH_R_PH:
21331         check_dsp_r2(ctx);
21332         switch (extract32(ctx->opcode, 10, 1)) {
21333         case 0:
21334             /* ADDQH_PH */
21335             gen_helper_addqh_ph(v1_t, v1_t, v2_t);
21336             gen_store_gpr(v1_t, ret);
21337             break;
21338         case 1:
21339             /* ADDQH_R_PH */
21340             gen_helper_addqh_r_ph(v1_t, v1_t, v2_t);
21341             gen_store_gpr(v1_t, ret);
21342             break;
21343         }
21344         break;
21345     case NM_ADDQH_R_W:
21346         check_dsp_r2(ctx);
21347         switch (extract32(ctx->opcode, 10, 1)) {
21348         case 0:
21349             /* ADDQH_W */
21350             gen_helper_addqh_w(v1_t, v1_t, v2_t);
21351             gen_store_gpr(v1_t, ret);
21352             break;
21353         case 1:
21354             /* ADDQH_R_W */
21355             gen_helper_addqh_r_w(v1_t, v1_t, v2_t);
21356             gen_store_gpr(v1_t, ret);
21357             break;
21358         }
21359         break;
21360     case NM_ADDU_S_QB:
21361         check_dsp(ctx);
21362         switch (extract32(ctx->opcode, 10, 1)) {
21363         case 0:
21364             /* ADDU_QB */
21365             gen_helper_addu_qb(v1_t, v1_t, v2_t, cpu_env);
21366             gen_store_gpr(v1_t, ret);
21367             break;
21368         case 1:
21369             /* ADDU_S_QB */
21370             gen_helper_addu_s_qb(v1_t, v1_t, v2_t, cpu_env);
21371             gen_store_gpr(v1_t, ret);
21372             break;
21373         }
21374         break;
21375     case NM_ADDU_S_PH:
21376         check_dsp_r2(ctx);
21377         switch (extract32(ctx->opcode, 10, 1)) {
21378         case 0:
21379             /* ADDU_PH */
21380             gen_helper_addu_ph(v1_t, v1_t, v2_t, cpu_env);
21381             gen_store_gpr(v1_t, ret);
21382             break;
21383         case 1:
21384             /* ADDU_S_PH */
21385             gen_helper_addu_s_ph(v1_t, v1_t, v2_t, cpu_env);
21386             gen_store_gpr(v1_t, ret);
21387             break;
21388         }
21389         break;
21390     case NM_ADDUH_R_QB:
21391         check_dsp_r2(ctx);
21392         switch (extract32(ctx->opcode, 10, 1)) {
21393         case 0:
21394             /* ADDUH_QB */
21395             gen_helper_adduh_qb(v1_t, v1_t, v2_t);
21396             gen_store_gpr(v1_t, ret);
21397             break;
21398         case 1:
21399             /* ADDUH_R_QB */
21400             gen_helper_adduh_r_qb(v1_t, v1_t, v2_t);
21401             gen_store_gpr(v1_t, ret);
21402             break;
21403         }
21404         break;
21405     case NM_SHRAV_R_PH:
21406         check_dsp(ctx);
21407         switch (extract32(ctx->opcode, 10, 1)) {
21408         case 0:
21409             /* SHRAV_PH */
21410             gen_helper_shra_ph(v1_t, v1_t, v2_t);
21411             gen_store_gpr(v1_t, ret);
21412             break;
21413         case 1:
21414             /* SHRAV_R_PH */
21415             gen_helper_shra_r_ph(v1_t, v1_t, v2_t);
21416             gen_store_gpr(v1_t, ret);
21417             break;
21418         }
21419         break;
21420     case NM_SHRAV_R_QB:
21421         check_dsp_r2(ctx);
21422         switch (extract32(ctx->opcode, 10, 1)) {
21423         case 0:
21424             /* SHRAV_QB */
21425             gen_helper_shra_qb(v1_t, v1_t, v2_t);
21426             gen_store_gpr(v1_t, ret);
21427             break;
21428         case 1:
21429             /* SHRAV_R_QB */
21430             gen_helper_shra_r_qb(v1_t, v1_t, v2_t);
21431             gen_store_gpr(v1_t, ret);
21432             break;
21433         }
21434         break;
21435     case NM_SUBQ_S_PH:
21436         check_dsp(ctx);
21437         switch (extract32(ctx->opcode, 10, 1)) {
21438         case 0:
21439             /* SUBQ_PH */
21440             gen_helper_subq_ph(v1_t, v1_t, v2_t, cpu_env);
21441             gen_store_gpr(v1_t, ret);
21442             break;
21443         case 1:
21444             /* SUBQ_S_PH */
21445             gen_helper_subq_s_ph(v1_t, v1_t, v2_t, cpu_env);
21446             gen_store_gpr(v1_t, ret);
21447             break;
21448         }
21449         break;
21450     case NM_SUBQH_R_PH:
21451         check_dsp_r2(ctx);
21452         switch (extract32(ctx->opcode, 10, 1)) {
21453         case 0:
21454             /* SUBQH_PH */
21455             gen_helper_subqh_ph(v1_t, v1_t, v2_t);
21456             gen_store_gpr(v1_t, ret);
21457             break;
21458         case 1:
21459             /* SUBQH_R_PH */
21460             gen_helper_subqh_r_ph(v1_t, v1_t, v2_t);
21461             gen_store_gpr(v1_t, ret);
21462             break;
21463         }
21464         break;
21465     case NM_SUBQH_R_W:
21466         check_dsp_r2(ctx);
21467         switch (extract32(ctx->opcode, 10, 1)) {
21468         case 0:
21469             /* SUBQH_W */
21470             gen_helper_subqh_w(v1_t, v1_t, v2_t);
21471             gen_store_gpr(v1_t, ret);
21472             break;
21473         case 1:
21474             /* SUBQH_R_W */
21475             gen_helper_subqh_r_w(v1_t, v1_t, v2_t);
21476             gen_store_gpr(v1_t, ret);
21477             break;
21478         }
21479         break;
21480     case NM_SUBU_S_QB:
21481         check_dsp(ctx);
21482         switch (extract32(ctx->opcode, 10, 1)) {
21483         case 0:
21484             /* SUBU_QB */
21485             gen_helper_subu_qb(v1_t, v1_t, v2_t, cpu_env);
21486             gen_store_gpr(v1_t, ret);
21487             break;
21488         case 1:
21489             /* SUBU_S_QB */
21490             gen_helper_subu_s_qb(v1_t, v1_t, v2_t, cpu_env);
21491             gen_store_gpr(v1_t, ret);
21492             break;
21493         }
21494         break;
21495     case NM_SUBU_S_PH:
21496         check_dsp_r2(ctx);
21497         switch (extract32(ctx->opcode, 10, 1)) {
21498         case 0:
21499             /* SUBU_PH */
21500             gen_helper_subu_ph(v1_t, v1_t, v2_t, cpu_env);
21501             gen_store_gpr(v1_t, ret);
21502             break;
21503         case 1:
21504             /* SUBU_S_PH */
21505             gen_helper_subu_s_ph(v1_t, v1_t, v2_t, cpu_env);
21506             gen_store_gpr(v1_t, ret);
21507             break;
21508         }
21509         break;
21510     case NM_SUBUH_R_QB:
21511         check_dsp_r2(ctx);
21512         switch (extract32(ctx->opcode, 10, 1)) {
21513         case 0:
21514             /* SUBUH_QB */
21515             gen_helper_subuh_qb(v1_t, v1_t, v2_t);
21516             gen_store_gpr(v1_t, ret);
21517             break;
21518         case 1:
21519             /* SUBUH_R_QB */
21520             gen_helper_subuh_r_qb(v1_t, v1_t, v2_t);
21521             gen_store_gpr(v1_t, ret);
21522             break;
21523         }
21524         break;
21525     case NM_SHLLV_S_PH:
21526         check_dsp(ctx);
21527         switch (extract32(ctx->opcode, 10, 1)) {
21528         case 0:
21529             /* SHLLV_PH */
21530             gen_helper_shll_ph(v1_t, v1_t, v2_t, cpu_env);
21531             gen_store_gpr(v1_t, ret);
21532             break;
21533         case 1:
21534             /* SHLLV_S_PH */
21535             gen_helper_shll_s_ph(v1_t, v1_t, v2_t, cpu_env);
21536             gen_store_gpr(v1_t, ret);
21537             break;
21538         }
21539         break;
21540     case NM_PRECR_SRA_R_PH_W:
21541         check_dsp_r2(ctx);
21542         switch (extract32(ctx->opcode, 10, 1)) {
21543         case 0:
21544             /* PRECR_SRA_PH_W */
21545             {
21546                 TCGv_i32 sa_t = tcg_const_i32(rd);
21547                 gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t,
21548                                           cpu_gpr[rt]);
21549                 gen_store_gpr(v1_t, rt);
21550                 tcg_temp_free_i32(sa_t);
21551             }
21552             break;
21553         case 1:
21554             /* PRECR_SRA_R_PH_W */
21555             {
21556                 TCGv_i32 sa_t = tcg_const_i32(rd);
21557                 gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t,
21558                                             cpu_gpr[rt]);
21559                 gen_store_gpr(v1_t, rt);
21560                 tcg_temp_free_i32(sa_t);
21561             }
21562             break;
21563        }
21564         break;
21565     case NM_MULEU_S_PH_QBL:
21566         check_dsp(ctx);
21567         gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, cpu_env);
21568         gen_store_gpr(v1_t, ret);
21569         break;
21570     case NM_MULEU_S_PH_QBR:
21571         check_dsp(ctx);
21572         gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, cpu_env);
21573         gen_store_gpr(v1_t, ret);
21574         break;
21575     case NM_MULQ_RS_PH:
21576         check_dsp(ctx);
21577         gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, cpu_env);
21578         gen_store_gpr(v1_t, ret);
21579         break;
21580     case NM_MULQ_S_PH:
21581         check_dsp_r2(ctx);
21582         gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, cpu_env);
21583         gen_store_gpr(v1_t, ret);
21584         break;
21585     case NM_MULQ_RS_W:
21586         check_dsp_r2(ctx);
21587         gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, cpu_env);
21588         gen_store_gpr(v1_t, ret);
21589         break;
21590     case NM_MULQ_S_W:
21591         check_dsp_r2(ctx);
21592         gen_helper_mulq_s_w(v1_t, v1_t, v2_t, cpu_env);
21593         gen_store_gpr(v1_t, ret);
21594         break;
21595     case NM_APPEND:
21596         check_dsp_r2(ctx);
21597         gen_load_gpr(t0, rs);
21598         if (rd != 0) {
21599             tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd);
21600         }
21601         tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
21602         break;
21603     case NM_MODSUB:
21604         check_dsp(ctx);
21605         gen_helper_modsub(v1_t, v1_t, v2_t);
21606         gen_store_gpr(v1_t, ret);
21607         break;
21608     case NM_SHRAV_R_W:
21609         check_dsp(ctx);
21610         gen_helper_shra_r_w(v1_t, v1_t, v2_t);
21611         gen_store_gpr(v1_t, ret);
21612         break;
21613     case NM_SHRLV_PH:
21614         check_dsp_r2(ctx);
21615         gen_helper_shrl_ph(v1_t, v1_t, v2_t);
21616         gen_store_gpr(v1_t, ret);
21617         break;
21618     case NM_SHRLV_QB:
21619         check_dsp(ctx);
21620         gen_helper_shrl_qb(v1_t, v1_t, v2_t);
21621         gen_store_gpr(v1_t, ret);
21622         break;
21623     case NM_SHLLV_QB:
21624         check_dsp(ctx);
21625         gen_helper_shll_qb(v1_t, v1_t, v2_t, cpu_env);
21626         gen_store_gpr(v1_t, ret);
21627         break;
21628     case NM_SHLLV_S_W:
21629         check_dsp(ctx);
21630         gen_helper_shll_s_w(v1_t, v1_t, v2_t, cpu_env);
21631         gen_store_gpr(v1_t, ret);
21632         break;
21633     case NM_SHILO:
21634         check_dsp(ctx);
21635         {
21636             TCGv tv0 = tcg_temp_new();
21637             TCGv tv1 = tcg_temp_new();
21638             int16_t imm = extract32(ctx->opcode, 16, 7);
21639 
21640             tcg_gen_movi_tl(tv0, rd >> 3);
21641             tcg_gen_movi_tl(tv1, imm);
21642             gen_helper_shilo(tv0, tv1, cpu_env);
21643         }
21644         break;
21645     case NM_MULEQ_S_W_PHL:
21646         check_dsp(ctx);
21647         gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, cpu_env);
21648         gen_store_gpr(v1_t, ret);
21649         break;
21650     case NM_MULEQ_S_W_PHR:
21651         check_dsp(ctx);
21652         gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, cpu_env);
21653         gen_store_gpr(v1_t, ret);
21654         break;
21655     case NM_MUL_S_PH:
21656         check_dsp_r2(ctx);
21657         switch (extract32(ctx->opcode, 10, 1)) {
21658         case 0:
21659             /* MUL_PH */
21660             gen_helper_mul_ph(v1_t, v1_t, v2_t, cpu_env);
21661             gen_store_gpr(v1_t, ret);
21662             break;
21663         case 1:
21664             /* MUL_S_PH */
21665             gen_helper_mul_s_ph(v1_t, v1_t, v2_t, cpu_env);
21666             gen_store_gpr(v1_t, ret);
21667             break;
21668         }
21669         break;
21670     case NM_PRECR_QB_PH:
21671         check_dsp_r2(ctx);
21672         gen_helper_precr_qb_ph(v1_t, v1_t, v2_t);
21673         gen_store_gpr(v1_t, ret);
21674         break;
21675     case NM_PRECRQ_QB_PH:
21676         check_dsp(ctx);
21677         gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t);
21678         gen_store_gpr(v1_t, ret);
21679         break;
21680     case NM_PRECRQ_PH_W:
21681         check_dsp(ctx);
21682         gen_helper_precrq_ph_w(v1_t, v1_t, v2_t);
21683         gen_store_gpr(v1_t, ret);
21684         break;
21685     case NM_PRECRQ_RS_PH_W:
21686         check_dsp(ctx);
21687         gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, cpu_env);
21688         gen_store_gpr(v1_t, ret);
21689         break;
21690     case NM_PRECRQU_S_QB_PH:
21691         check_dsp(ctx);
21692         gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, cpu_env);
21693         gen_store_gpr(v1_t, ret);
21694         break;
21695     case NM_SHRA_R_W:
21696         check_dsp(ctx);
21697         tcg_gen_movi_tl(t0, rd);
21698         gen_helper_shra_r_w(v1_t, t0, v1_t);
21699         gen_store_gpr(v1_t, rt);
21700         break;
21701     case NM_SHRA_R_PH:
21702         check_dsp(ctx);
21703         tcg_gen_movi_tl(t0, rd >> 1);
21704         switch (extract32(ctx->opcode, 10, 1)) {
21705         case 0:
21706             /* SHRA_PH */
21707             gen_helper_shra_ph(v1_t, t0, v1_t);
21708             gen_store_gpr(v1_t, rt);
21709             break;
21710         case 1:
21711             /* SHRA_R_PH */
21712             gen_helper_shra_r_ph(v1_t, t0, v1_t);
21713             gen_store_gpr(v1_t, rt);
21714             break;
21715         }
21716         break;
21717     case NM_SHLL_S_PH:
21718         check_dsp(ctx);
21719         tcg_gen_movi_tl(t0, rd >> 1);
21720         switch (extract32(ctx->opcode, 10, 2)) {
21721         case 0:
21722             /* SHLL_PH */
21723             gen_helper_shll_ph(v1_t, t0, v1_t, cpu_env);
21724             gen_store_gpr(v1_t, rt);
21725             break;
21726         case 2:
21727             /* SHLL_S_PH */
21728             gen_helper_shll_s_ph(v1_t, t0, v1_t, cpu_env);
21729             gen_store_gpr(v1_t, rt);
21730             break;
21731         default:
21732             generate_exception_end(ctx, EXCP_RI);
21733             break;
21734         }
21735         break;
21736     case NM_SHLL_S_W:
21737         check_dsp(ctx);
21738         tcg_gen_movi_tl(t0, rd);
21739         gen_helper_shll_s_w(v1_t, t0, v1_t, cpu_env);
21740         gen_store_gpr(v1_t, rt);
21741         break;
21742     case NM_REPL_PH:
21743         check_dsp(ctx);
21744         {
21745             int16_t imm;
21746             imm = sextract32(ctx->opcode, 11, 11);
21747             imm = (int16_t)(imm << 6) >> 6;
21748             if (rt != 0) {
21749                 tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm));
21750             }
21751         }
21752         break;
21753     default:
21754         generate_exception_end(ctx, EXCP_RI);
21755         break;
21756     }
21757 }
21758 
decode_nanomips_32_48_opc(CPUMIPSState * env,DisasContext * ctx)21759 static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
21760 {
21761     uint16_t insn;
21762     uint32_t op;
21763     int rt, rs, rd;
21764     int offset;
21765     int imm;
21766 
21767     insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
21768     ctx->opcode = (ctx->opcode << 16) | insn;
21769 
21770     rt = extract32(ctx->opcode, 21, 5);
21771     rs = extract32(ctx->opcode, 16, 5);
21772     rd = extract32(ctx->opcode, 11, 5);
21773 
21774     op = extract32(ctx->opcode, 26, 6);
21775     switch (op) {
21776     case NM_P_ADDIU:
21777         if (rt == 0) {
21778             /* P.RI */
21779             switch (extract32(ctx->opcode, 19, 2)) {
21780             case NM_SIGRIE:
21781             default:
21782                 generate_exception_end(ctx, EXCP_RI);
21783                 break;
21784             case NM_P_SYSCALL:
21785                 if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) {
21786                     generate_exception_end(ctx, EXCP_SYSCALL);
21787                 } else {
21788                     generate_exception_end(ctx, EXCP_RI);
21789                 }
21790                 break;
21791             case NM_BREAK:
21792                 generate_exception_end(ctx, EXCP_BREAK);
21793                 break;
21794             case NM_SDBBP:
21795                 if (is_uhi(extract32(ctx->opcode, 0, 19))) {
21796                     gen_helper_do_semihosting(cpu_env);
21797                 } else {
21798                     if (ctx->hflags & MIPS_HFLAG_SBRI) {
21799                         generate_exception_end(ctx, EXCP_RI);
21800                     } else {
21801                         generate_exception_end(ctx, EXCP_DBp);
21802                     }
21803                 }
21804                 break;
21805             }
21806         } else {
21807             /* NM_ADDIU */
21808             imm = extract32(ctx->opcode, 0, 16);
21809             if (rs != 0) {
21810                 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm);
21811             } else {
21812                 tcg_gen_movi_tl(cpu_gpr[rt], imm);
21813             }
21814             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
21815         }
21816         break;
21817     case NM_ADDIUPC:
21818         if (rt != 0) {
21819             offset = sextract32(ctx->opcode, 0, 1) << 21 |
21820                      extract32(ctx->opcode, 1, 20) << 1;
21821             target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset);
21822             tcg_gen_movi_tl(cpu_gpr[rt], addr);
21823         }
21824         break;
21825     case NM_POOL32A:
21826         switch (ctx->opcode & 0x07) {
21827         case NM_POOL32A0:
21828             gen_pool32a0_nanomips_insn(env, ctx);
21829             break;
21830         case NM_POOL32A5:
21831             {
21832                 int32_t op1 = extract32(ctx->opcode, 3, 7);
21833                 gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt);
21834             }
21835             break;
21836         case NM_POOL32A7:
21837             switch (extract32(ctx->opcode, 3, 3)) {
21838             case NM_P_LSX:
21839                 gen_p_lsx(ctx, rd, rs, rt);
21840                 break;
21841             case NM_LSA:
21842                 /*
21843                  * In nanoMIPS, the shift field directly encodes the shift
21844                  * amount, meaning that the supported shift values are in
21845                  * the range 0 to 3 (instead of 1 to 4 in MIPSR6).
21846                  */
21847                 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
21848                         extract32(ctx->opcode, 9, 2) - 1);
21849                 break;
21850             case NM_EXTW:
21851                 gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5));
21852                 break;
21853             case NM_POOL32AXF:
21854                 gen_pool32axf_nanomips_insn(env, ctx);
21855                 break;
21856             default:
21857                 generate_exception_end(ctx, EXCP_RI);
21858                 break;
21859             }
21860             break;
21861         default:
21862             generate_exception_end(ctx, EXCP_RI);
21863             break;
21864         }
21865         break;
21866     case NM_P_GP_W:
21867         switch (ctx->opcode & 0x03) {
21868         case NM_ADDIUGP_W:
21869             if (rt != 0) {
21870                 offset = extract32(ctx->opcode, 0, 21);
21871                 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset);
21872             }
21873             break;
21874         case NM_LWGP:
21875             gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
21876             break;
21877         case NM_SWGP:
21878             gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
21879             break;
21880         default:
21881             generate_exception_end(ctx, EXCP_RI);
21882             break;
21883         }
21884         break;
21885     case NM_P48I:
21886         {
21887             insn = cpu_lduw_code(env, ctx->base.pc_next + 4);
21888             target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16;
21889             switch (extract32(ctx->opcode, 16, 5)) {
21890             case NM_LI48:
21891                 check_nms(ctx);
21892                 if (rt != 0) {
21893                     tcg_gen_movi_tl(cpu_gpr[rt], addr_off);
21894                 }
21895                 break;
21896             case NM_ADDIU48:
21897                 check_nms(ctx);
21898                 if (rt != 0) {
21899                     tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off);
21900                     tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
21901                 }
21902                 break;
21903             case NM_ADDIUGP48:
21904                 check_nms(ctx);
21905                 if (rt != 0) {
21906                     gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_off);
21907                 }
21908                 break;
21909             case NM_ADDIUPC48:
21910                 check_nms(ctx);
21911                 if (rt != 0) {
21912                     target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21913                                                 addr_off);
21914 
21915                     tcg_gen_movi_tl(cpu_gpr[rt], addr);
21916                 }
21917                 break;
21918             case NM_LWPC48:
21919                 check_nms(ctx);
21920                 if (rt != 0) {
21921                     TCGv t0;
21922                     t0 = tcg_temp_new();
21923 
21924                     target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21925                                                 addr_off);
21926 
21927                     tcg_gen_movi_tl(t0, addr);
21928                     tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_TESL);
21929                     tcg_temp_free(t0);
21930                 }
21931                 break;
21932             case NM_SWPC48:
21933                 check_nms(ctx);
21934                 {
21935                     TCGv t0, t1;
21936                     t0 = tcg_temp_new();
21937                     t1 = tcg_temp_new();
21938 
21939                     target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21940                                                 addr_off);
21941 
21942                     tcg_gen_movi_tl(t0, addr);
21943                     gen_load_gpr(t1, rt);
21944 
21945                     tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
21946 
21947                     tcg_temp_free(t0);
21948                     tcg_temp_free(t1);
21949                 }
21950                 break;
21951             default:
21952                 generate_exception_end(ctx, EXCP_RI);
21953                 break;
21954             }
21955             return 6;
21956         }
21957     case NM_P_U12:
21958         switch (extract32(ctx->opcode, 12, 4)) {
21959         case NM_ORI:
21960             gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12));
21961             break;
21962         case NM_XORI:
21963             gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12));
21964             break;
21965         case NM_ANDI:
21966             gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12));
21967             break;
21968         case NM_P_SR:
21969             switch (extract32(ctx->opcode, 20, 1)) {
21970             case NM_PP_SR:
21971                 switch (ctx->opcode & 3) {
21972                 case NM_SAVE:
21973                     gen_save(ctx, rt, extract32(ctx->opcode, 16, 4),
21974                              extract32(ctx->opcode, 2, 1),
21975                              extract32(ctx->opcode, 3, 9) << 3);
21976                     break;
21977                 case NM_RESTORE:
21978                 case NM_RESTORE_JRC:
21979                     gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4),
21980                                 extract32(ctx->opcode, 2, 1),
21981                                 extract32(ctx->opcode, 3, 9) << 3);
21982                     if ((ctx->opcode & 3) == NM_RESTORE_JRC) {
21983                         gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
21984                     }
21985                     break;
21986                 default:
21987                     generate_exception_end(ctx, EXCP_RI);
21988                     break;
21989                 }
21990                 break;
21991             case NM_P_SR_F:
21992                 generate_exception_end(ctx, EXCP_RI);
21993                 break;
21994             }
21995             break;
21996         case NM_SLTI:
21997             gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12));
21998             break;
21999         case NM_SLTIU:
22000             gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12));
22001             break;
22002         case NM_SEQI:
22003             {
22004                 TCGv t0 = tcg_temp_new();
22005 
22006                 imm = extract32(ctx->opcode, 0, 12);
22007                 gen_load_gpr(t0, rs);
22008                 tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm);
22009                 gen_store_gpr(t0, rt);
22010 
22011                 tcg_temp_free(t0);
22012             }
22013             break;
22014         case NM_ADDIUNEG:
22015             imm = (int16_t) extract32(ctx->opcode, 0, 12);
22016             gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm);
22017             break;
22018         case NM_P_SHIFT:
22019             {
22020                 int shift = extract32(ctx->opcode, 0, 5);
22021                 switch (extract32(ctx->opcode, 5, 4)) {
22022                 case NM_P_SLL:
22023                     if (rt == 0 && shift == 0) {
22024                         /* NOP */
22025                     } else if (rt == 0 && shift == 3) {
22026                         /* EHB - treat as NOP */
22027                     } else if (rt == 0 && shift == 5) {
22028                         /* PAUSE - treat as NOP */
22029                     } else if (rt == 0 && shift == 6) {
22030                         /* SYNC */
22031                         gen_sync(extract32(ctx->opcode, 16, 5));
22032                     } else {
22033                         /* SLL */
22034                         gen_shift_imm(ctx, OPC_SLL, rt, rs,
22035                                       extract32(ctx->opcode, 0, 5));
22036                     }
22037                     break;
22038                 case NM_SRL:
22039                     gen_shift_imm(ctx, OPC_SRL, rt, rs,
22040                                   extract32(ctx->opcode, 0, 5));
22041                     break;
22042                 case NM_SRA:
22043                     gen_shift_imm(ctx, OPC_SRA, rt, rs,
22044                                   extract32(ctx->opcode, 0, 5));
22045                     break;
22046                 case NM_ROTR:
22047                     gen_shift_imm(ctx, OPC_ROTR, rt, rs,
22048                                   extract32(ctx->opcode, 0, 5));
22049                     break;
22050                 }
22051             }
22052             break;
22053         case NM_P_ROTX:
22054             check_nms(ctx);
22055             if (rt != 0) {
22056                 TCGv t0 = tcg_temp_new();
22057                 TCGv_i32 shift = tcg_const_i32(extract32(ctx->opcode, 0, 5));
22058                 TCGv_i32 shiftx = tcg_const_i32(extract32(ctx->opcode, 7, 4)
22059                                                 << 1);
22060                 TCGv_i32 stripe = tcg_const_i32(extract32(ctx->opcode, 6, 1));
22061 
22062                 gen_load_gpr(t0, rs);
22063                 gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe);
22064                 tcg_temp_free(t0);
22065 
22066                 tcg_temp_free_i32(shift);
22067                 tcg_temp_free_i32(shiftx);
22068                 tcg_temp_free_i32(stripe);
22069             }
22070             break;
22071         case NM_P_INS:
22072             switch (((ctx->opcode >> 10) & 2) |
22073                     (extract32(ctx->opcode, 5, 1))) {
22074             case NM_INS:
22075                 check_nms(ctx);
22076                 gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5),
22077                            extract32(ctx->opcode, 6, 5));
22078                 break;
22079             default:
22080                 generate_exception_end(ctx, EXCP_RI);
22081                 break;
22082             }
22083             break;
22084         case NM_P_EXT:
22085             switch (((ctx->opcode >> 10) & 2) |
22086                     (extract32(ctx->opcode, 5, 1))) {
22087             case NM_EXT:
22088                 check_nms(ctx);
22089                 gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5),
22090                            extract32(ctx->opcode, 6, 5));
22091                 break;
22092             default:
22093                 generate_exception_end(ctx, EXCP_RI);
22094                 break;
22095             }
22096             break;
22097         default:
22098             generate_exception_end(ctx, EXCP_RI);
22099             break;
22100         }
22101         break;
22102     case NM_POOL32F:
22103         gen_pool32f_nanomips_insn(ctx);
22104         break;
22105     case NM_POOL32S:
22106         break;
22107     case NM_P_LUI:
22108         switch (extract32(ctx->opcode, 1, 1)) {
22109         case NM_LUI:
22110             if (rt != 0) {
22111                 tcg_gen_movi_tl(cpu_gpr[rt],
22112                                 sextract32(ctx->opcode, 0, 1) << 31 |
22113                                 extract32(ctx->opcode, 2, 10) << 21 |
22114                                 extract32(ctx->opcode, 12, 9) << 12);
22115             }
22116             break;
22117         case NM_ALUIPC:
22118             if (rt != 0) {
22119                 offset = sextract32(ctx->opcode, 0, 1) << 31 |
22120                          extract32(ctx->opcode, 2, 10) << 21 |
22121                          extract32(ctx->opcode, 12, 9) << 12;
22122                 target_long addr;
22123                 addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset);
22124                 tcg_gen_movi_tl(cpu_gpr[rt], addr);
22125             }
22126             break;
22127         }
22128         break;
22129     case NM_P_GP_BH:
22130         {
22131             uint32_t u = extract32(ctx->opcode, 0, 18);
22132 
22133             switch (extract32(ctx->opcode, 18, 3)) {
22134             case NM_LBGP:
22135                 gen_ld(ctx, OPC_LB, rt, 28, u);
22136                 break;
22137             case NM_SBGP:
22138                 gen_st(ctx, OPC_SB, rt, 28, u);
22139                 break;
22140             case NM_LBUGP:
22141                 gen_ld(ctx, OPC_LBU, rt, 28, u);
22142                 break;
22143             case NM_ADDIUGP_B:
22144                 if (rt != 0) {
22145                     gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u);
22146                 }
22147                 break;
22148             case NM_P_GP_LH:
22149                 u &= ~1;
22150                 switch (ctx->opcode & 1) {
22151                 case NM_LHGP:
22152                     gen_ld(ctx, OPC_LH, rt, 28, u);
22153                     break;
22154                 case NM_LHUGP:
22155                     gen_ld(ctx, OPC_LHU, rt, 28, u);
22156                     break;
22157                 }
22158                 break;
22159             case NM_P_GP_SH:
22160                 u &= ~1;
22161                 switch (ctx->opcode & 1) {
22162                 case NM_SHGP:
22163                     gen_st(ctx, OPC_SH, rt, 28, u);
22164                     break;
22165                 default:
22166                     generate_exception_end(ctx, EXCP_RI);
22167                     break;
22168                 }
22169                 break;
22170             case NM_P_GP_CP1:
22171                 u &= ~0x3;
22172                 switch (ctx->opcode & 0x3) {
22173                 case NM_LWC1GP:
22174                     gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u);
22175                     break;
22176                 case NM_LDC1GP:
22177                     gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u);
22178                     break;
22179                 case NM_SWC1GP:
22180                     gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u);
22181                     break;
22182                 case NM_SDC1GP:
22183                     gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u);
22184                     break;
22185                 }
22186                 break;
22187             default:
22188                 generate_exception_end(ctx, EXCP_RI);
22189                 break;
22190             }
22191         }
22192         break;
22193     case NM_P_LS_U12:
22194         {
22195             uint32_t u = extract32(ctx->opcode, 0, 12);
22196 
22197             switch (extract32(ctx->opcode, 12, 4)) {
22198             case NM_P_PREFU12:
22199                 if (rt == 31) {
22200                     /* SYNCI */
22201                     /*
22202                      * Break the TB to be able to sync copied instructions
22203                      * immediately.
22204                      */
22205                     ctx->base.is_jmp = DISAS_STOP;
22206                 } else {
22207                     /* PREF */
22208                     /* Treat as NOP. */
22209                 }
22210                 break;
22211             case NM_LB:
22212                 gen_ld(ctx, OPC_LB, rt, rs, u);
22213                 break;
22214             case NM_LH:
22215                 gen_ld(ctx, OPC_LH, rt, rs, u);
22216                 break;
22217             case NM_LW:
22218                 gen_ld(ctx, OPC_LW, rt, rs, u);
22219                 break;
22220             case NM_LBU:
22221                 gen_ld(ctx, OPC_LBU, rt, rs, u);
22222                 break;
22223             case NM_LHU:
22224                 gen_ld(ctx, OPC_LHU, rt, rs, u);
22225                 break;
22226             case NM_SB:
22227                 gen_st(ctx, OPC_SB, rt, rs, u);
22228                 break;
22229             case NM_SH:
22230                 gen_st(ctx, OPC_SH, rt, rs, u);
22231                 break;
22232             case NM_SW:
22233                 gen_st(ctx, OPC_SW, rt, rs, u);
22234                 break;
22235             case NM_LWC1:
22236                 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u);
22237                 break;
22238             case NM_LDC1:
22239                 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u);
22240                 break;
22241             case NM_SWC1:
22242                 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u);
22243                 break;
22244             case NM_SDC1:
22245                 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u);
22246                 break;
22247             default:
22248                 generate_exception_end(ctx, EXCP_RI);
22249                 break;
22250             }
22251         }
22252         break;
22253     case NM_P_LS_S9:
22254         {
22255             int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) |
22256                         extract32(ctx->opcode, 0, 8);
22257 
22258             switch (extract32(ctx->opcode, 8, 3)) {
22259             case NM_P_LS_S0:
22260                 switch (extract32(ctx->opcode, 11, 4)) {
22261                 case NM_LBS9:
22262                     gen_ld(ctx, OPC_LB, rt, rs, s);
22263                     break;
22264                 case NM_LHS9:
22265                     gen_ld(ctx, OPC_LH, rt, rs, s);
22266                     break;
22267                 case NM_LWS9:
22268                     gen_ld(ctx, OPC_LW, rt, rs, s);
22269                     break;
22270                 case NM_LBUS9:
22271                     gen_ld(ctx, OPC_LBU, rt, rs, s);
22272                     break;
22273                 case NM_LHUS9:
22274                     gen_ld(ctx, OPC_LHU, rt, rs, s);
22275                     break;
22276                 case NM_SBS9:
22277                     gen_st(ctx, OPC_SB, rt, rs, s);
22278                     break;
22279                 case NM_SHS9:
22280                     gen_st(ctx, OPC_SH, rt, rs, s);
22281                     break;
22282                 case NM_SWS9:
22283                     gen_st(ctx, OPC_SW, rt, rs, s);
22284                     break;
22285                 case NM_LWC1S9:
22286                     gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s);
22287                     break;
22288                 case NM_LDC1S9:
22289                     gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s);
22290                     break;
22291                 case NM_SWC1S9:
22292                     gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s);
22293                     break;
22294                 case NM_SDC1S9:
22295                     gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s);
22296                     break;
22297                 case NM_P_PREFS9:
22298                     if (rt == 31) {
22299                         /* SYNCI */
22300                         /*
22301                          * Break the TB to be able to sync copied instructions
22302                          * immediately.
22303                          */
22304                         ctx->base.is_jmp = DISAS_STOP;
22305                     } else {
22306                         /* PREF */
22307                         /* Treat as NOP. */
22308                     }
22309                     break;
22310                 default:
22311                     generate_exception_end(ctx, EXCP_RI);
22312                     break;
22313                 }
22314                 break;
22315             case NM_P_LS_S1:
22316                 switch (extract32(ctx->opcode, 11, 4)) {
22317                 case NM_UALH:
22318                 case NM_UASH:
22319                     check_nms(ctx);
22320                     {
22321                         TCGv t0 = tcg_temp_new();
22322                         TCGv t1 = tcg_temp_new();
22323 
22324                         gen_base_offset_addr(ctx, t0, rs, s);
22325 
22326                         switch (extract32(ctx->opcode, 11, 4)) {
22327                         case NM_UALH:
22328                             tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
22329                                                MO_UNALN);
22330                             gen_store_gpr(t0, rt);
22331                             break;
22332                         case NM_UASH:
22333                             gen_load_gpr(t1, rt);
22334                             tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
22335                                                MO_UNALN);
22336                             break;
22337                         }
22338                         tcg_temp_free(t0);
22339                         tcg_temp_free(t1);
22340                     }
22341                     break;
22342                 case NM_P_LL:
22343                     switch (ctx->opcode & 0x03) {
22344                     case NM_LL:
22345                         gen_ld(ctx, OPC_LL, rt, rs, s);
22346                         break;
22347                     case NM_LLWP:
22348                         check_xnp(ctx);
22349                         gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
22350                         break;
22351                     }
22352                     break;
22353                 case NM_P_SC:
22354                     switch (ctx->opcode & 0x03) {
22355                     case NM_SC:
22356                         gen_st_cond(ctx, rt, rs, s, MO_TESL, false);
22357                         break;
22358                     case NM_SCWP:
22359                         check_xnp(ctx);
22360                         gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5),
22361                                  false);
22362                         break;
22363                     }
22364                     break;
22365                 case NM_CACHE:
22366                     check_cp0_enabled(ctx);
22367                     if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
22368                         gen_cache_operation(ctx, rt, rs, s);
22369                     }
22370                     break;
22371                 }
22372                 break;
22373             case NM_P_LS_E0:
22374                 switch (extract32(ctx->opcode, 11, 4)) {
22375                 case NM_LBE:
22376                     check_eva(ctx);
22377                     check_cp0_enabled(ctx);
22378                     gen_ld(ctx, OPC_LBE, rt, rs, s);
22379                     break;
22380                 case NM_SBE:
22381                     check_eva(ctx);
22382                     check_cp0_enabled(ctx);
22383                     gen_st(ctx, OPC_SBE, rt, rs, s);
22384                     break;
22385                 case NM_LBUE:
22386                     check_eva(ctx);
22387                     check_cp0_enabled(ctx);
22388                     gen_ld(ctx, OPC_LBUE, rt, rs, s);
22389                     break;
22390                 case NM_P_PREFE:
22391                     if (rt == 31) {
22392                         /* case NM_SYNCIE */
22393                         check_eva(ctx);
22394                         check_cp0_enabled(ctx);
22395                         /*
22396                          * Break the TB to be able to sync copied instructions
22397                          * immediately.
22398                          */
22399                         ctx->base.is_jmp = DISAS_STOP;
22400                     } else {
22401                         /* case NM_PREFE */
22402                         check_eva(ctx);
22403                         check_cp0_enabled(ctx);
22404                         /* Treat as NOP. */
22405                     }
22406                     break;
22407                 case NM_LHE:
22408                     check_eva(ctx);
22409                     check_cp0_enabled(ctx);
22410                     gen_ld(ctx, OPC_LHE, rt, rs, s);
22411                     break;
22412                 case NM_SHE:
22413                     check_eva(ctx);
22414                     check_cp0_enabled(ctx);
22415                     gen_st(ctx, OPC_SHE, rt, rs, s);
22416                     break;
22417                 case NM_LHUE:
22418                     check_eva(ctx);
22419                     check_cp0_enabled(ctx);
22420                     gen_ld(ctx, OPC_LHUE, rt, rs, s);
22421                     break;
22422                 case NM_CACHEE:
22423                     check_nms_dl_il_sl_tl_l2c(ctx);
22424                     gen_cache_operation(ctx, rt, rs, s);
22425                     break;
22426                 case NM_LWE:
22427                     check_eva(ctx);
22428                     check_cp0_enabled(ctx);
22429                     gen_ld(ctx, OPC_LWE, rt, rs, s);
22430                     break;
22431                 case NM_SWE:
22432                     check_eva(ctx);
22433                     check_cp0_enabled(ctx);
22434                     gen_st(ctx, OPC_SWE, rt, rs, s);
22435                     break;
22436                 case NM_P_LLE:
22437                     switch (extract32(ctx->opcode, 2, 2)) {
22438                     case NM_LLE:
22439                         check_xnp(ctx);
22440                         check_eva(ctx);
22441                         check_cp0_enabled(ctx);
22442                         gen_ld(ctx, OPC_LLE, rt, rs, s);
22443                         break;
22444                     case NM_LLWPE:
22445                         check_xnp(ctx);
22446                         check_eva(ctx);
22447                         check_cp0_enabled(ctx);
22448                         gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
22449                         break;
22450                     default:
22451                         generate_exception_end(ctx, EXCP_RI);
22452                         break;
22453                     }
22454                     break;
22455                 case NM_P_SCE:
22456                     switch (extract32(ctx->opcode, 2, 2)) {
22457                     case NM_SCE:
22458                         check_xnp(ctx);
22459                         check_eva(ctx);
22460                         check_cp0_enabled(ctx);
22461                         gen_st_cond(ctx, rt, rs, s, MO_TESL, true);
22462                         break;
22463                     case NM_SCWPE:
22464                         check_xnp(ctx);
22465                         check_eva(ctx);
22466                         check_cp0_enabled(ctx);
22467                         gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5),
22468                                  true);
22469                         break;
22470                     default:
22471                         generate_exception_end(ctx, EXCP_RI);
22472                         break;
22473                     }
22474                     break;
22475                 }
22476                 break;
22477             case NM_P_LS_WM:
22478             case NM_P_LS_UAWM:
22479                 check_nms(ctx);
22480                 {
22481                     int count = extract32(ctx->opcode, 12, 3);
22482                     int counter = 0;
22483 
22484                     offset = sextract32(ctx->opcode, 15, 1) << 8 |
22485                              extract32(ctx->opcode, 0, 8);
22486                     TCGv va = tcg_temp_new();
22487                     TCGv t1 = tcg_temp_new();
22488                     MemOp memop = (extract32(ctx->opcode, 8, 3)) ==
22489                                       NM_P_LS_UAWM ? MO_UNALN : 0;
22490 
22491                     count = (count == 0) ? 8 : count;
22492                     while (counter != count) {
22493                         int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10);
22494                         int this_offset = offset + (counter << 2);
22495 
22496                         gen_base_offset_addr(ctx, va, rs, this_offset);
22497 
22498                         switch (extract32(ctx->opcode, 11, 1)) {
22499                         case NM_LWM:
22500                             tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx,
22501                                                memop | MO_TESL);
22502                             gen_store_gpr(t1, this_rt);
22503                             if ((this_rt == rs) &&
22504                                 (counter != (count - 1))) {
22505                                 /* UNPREDICTABLE */
22506                             }
22507                             break;
22508                         case NM_SWM:
22509                             this_rt = (rt == 0) ? 0 : this_rt;
22510                             gen_load_gpr(t1, this_rt);
22511                             tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx,
22512                                                memop | MO_TEUL);
22513                             break;
22514                         }
22515                         counter++;
22516                     }
22517                     tcg_temp_free(va);
22518                     tcg_temp_free(t1);
22519                 }
22520                 break;
22521             default:
22522                 generate_exception_end(ctx, EXCP_RI);
22523                 break;
22524             }
22525         }
22526         break;
22527     case NM_MOVE_BALC:
22528         check_nms(ctx);
22529         {
22530             TCGv t0 = tcg_temp_new();
22531             int32_t s = sextract32(ctx->opcode, 0, 1) << 21 |
22532                         extract32(ctx->opcode, 1, 20) << 1;
22533             rd = (extract32(ctx->opcode, 24, 1)) == 0 ? 4 : 5;
22534             rt = decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3 |
22535                             extract32(ctx->opcode, 21, 3));
22536             gen_load_gpr(t0, rt);
22537             tcg_gen_mov_tl(cpu_gpr[rd], t0);
22538             gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
22539             tcg_temp_free(t0);
22540         }
22541         break;
22542     case NM_P_BAL:
22543         {
22544             int32_t s = sextract32(ctx->opcode, 0, 1) << 25 |
22545                         extract32(ctx->opcode, 1, 24) << 1;
22546 
22547             if ((extract32(ctx->opcode, 25, 1)) == 0) {
22548                 /* BC */
22549                 gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s);
22550             } else {
22551                 /* BALC */
22552                 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
22553             }
22554         }
22555         break;
22556     case NM_P_J:
22557         switch (extract32(ctx->opcode, 12, 4)) {
22558         case NM_JALRC:
22559         case NM_JALRC_HB:
22560             gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0);
22561             break;
22562         case NM_P_BALRSC:
22563             gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt);
22564             break;
22565         default:
22566             generate_exception_end(ctx, EXCP_RI);
22567             break;
22568         }
22569         break;
22570     case NM_P_BR1:
22571         {
22572             int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
22573                         extract32(ctx->opcode, 1, 13) << 1;
22574             switch (extract32(ctx->opcode, 14, 2)) {
22575             case NM_BEQC:
22576                 check_nms(ctx);
22577                 gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s);
22578                 break;
22579             case NM_P_BR3A:
22580                 s = sextract32(ctx->opcode, 0, 1) << 14 |
22581                     extract32(ctx->opcode, 1, 13) << 1;
22582                 check_cp1_enabled(ctx);
22583                 switch (extract32(ctx->opcode, 16, 5)) {
22584                 case NM_BC1EQZC:
22585                     gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s);
22586                     break;
22587                 case NM_BC1NEZC:
22588                     gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s);
22589                     break;
22590                 case NM_BPOSGE32C:
22591                     check_dsp_r3(ctx);
22592                     {
22593                         int32_t imm = extract32(ctx->opcode, 1, 13) |
22594                                       extract32(ctx->opcode, 0, 1) << 13;
22595 
22596                         gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2,
22597                                               imm);
22598                     }
22599                     break;
22600                 default:
22601                     generate_exception_end(ctx, EXCP_RI);
22602                     break;
22603                 }
22604                 break;
22605             case NM_BGEC:
22606                 if (rs == rt) {
22607                     gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s);
22608                 } else {
22609                     gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s);
22610                 }
22611                 break;
22612             case NM_BGEUC:
22613                 if (rs == rt || rt == 0) {
22614                     gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s);
22615                 } else if (rs == 0) {
22616                     gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s);
22617                 } else {
22618                     gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, s);
22619                 }
22620                 break;
22621             }
22622         }
22623         break;
22624     case NM_P_BR2:
22625         {
22626             int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
22627                         extract32(ctx->opcode, 1, 13) << 1;
22628             switch (extract32(ctx->opcode, 14, 2)) {
22629             case NM_BNEC:
22630                 check_nms(ctx);
22631                 gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s);
22632                 break;
22633             case NM_BLTC:
22634                 if (rs != 0 && rt != 0 && rs == rt) {
22635                     /* NOP */
22636                     ctx->hflags |= MIPS_HFLAG_FBNSLOT;
22637                 } else {
22638                     gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s);
22639                 }
22640                 break;
22641             case NM_BLTUC:
22642                 if (rs == 0 || rs == rt) {
22643                     /* NOP */
22644                     ctx->hflags |= MIPS_HFLAG_FBNSLOT;
22645                 } else {
22646                     gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, s);
22647                 }
22648                 break;
22649             default:
22650                 generate_exception_end(ctx, EXCP_RI);
22651                 break;
22652             }
22653         }
22654         break;
22655     case NM_P_BRI:
22656         {
22657             int32_t s = sextract32(ctx->opcode, 0, 1) << 11 |
22658                         extract32(ctx->opcode, 1, 10) << 1;
22659             uint32_t u = extract32(ctx->opcode, 11, 7);
22660 
22661             gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3),
22662                                    rt, u, s);
22663         }
22664         break;
22665     default:
22666         generate_exception_end(ctx, EXCP_RI);
22667         break;
22668     }
22669     return 4;
22670 }
22671 
decode_nanomips_opc(CPUMIPSState * env,DisasContext * ctx)22672 static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
22673 {
22674     uint32_t op;
22675     int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode));
22676     int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
22677     int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx->opcode));
22678     int offset;
22679     int imm;
22680 
22681     /* make sure instructions are on a halfword boundary */
22682     if (ctx->base.pc_next & 0x1) {
22683         TCGv tmp = tcg_const_tl(ctx->base.pc_next);
22684         tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
22685         tcg_temp_free(tmp);
22686         generate_exception_end(ctx, EXCP_AdEL);
22687         return 2;
22688     }
22689 
22690     op = extract32(ctx->opcode, 10, 6);
22691     switch (op) {
22692     case NM_P16_MV:
22693         rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22694         if (rt != 0) {
22695             /* MOVE */
22696             rs = NANOMIPS_EXTRACT_RS5(ctx->opcode);
22697             gen_arith(ctx, OPC_ADDU, rt, rs, 0);
22698         } else {
22699             /* P16.RI */
22700             switch (extract32(ctx->opcode, 3, 2)) {
22701             case NM_P16_SYSCALL:
22702                 if (extract32(ctx->opcode, 2, 1) == 0) {
22703                     generate_exception_end(ctx, EXCP_SYSCALL);
22704                 } else {
22705                     generate_exception_end(ctx, EXCP_RI);
22706                 }
22707                 break;
22708             case NM_BREAK16:
22709                 generate_exception_end(ctx, EXCP_BREAK);
22710                 break;
22711             case NM_SDBBP16:
22712                 if (is_uhi(extract32(ctx->opcode, 0, 3))) {
22713                     gen_helper_do_semihosting(cpu_env);
22714                 } else {
22715                     if (ctx->hflags & MIPS_HFLAG_SBRI) {
22716                         generate_exception_end(ctx, EXCP_RI);
22717                     } else {
22718                         generate_exception_end(ctx, EXCP_DBp);
22719                     }
22720                 }
22721                 break;
22722             default:
22723                 generate_exception_end(ctx, EXCP_RI);
22724                 break;
22725             }
22726         }
22727         break;
22728     case NM_P16_SHIFT:
22729         {
22730             int shift = extract32(ctx->opcode, 0, 3);
22731             uint32_t opc = 0;
22732             shift = (shift == 0) ? 8 : shift;
22733 
22734             switch (extract32(ctx->opcode, 3, 1)) {
22735             case NM_SLL16:
22736                 opc = OPC_SLL;
22737                 break;
22738             case NM_SRL16:
22739                 opc = OPC_SRL;
22740                 break;
22741             }
22742             gen_shift_imm(ctx, opc, rt, rs, shift);
22743         }
22744         break;
22745     case NM_P16C:
22746         switch (ctx->opcode & 1) {
22747         case NM_POOL16C_0:
22748             gen_pool16c_nanomips_insn(ctx);
22749             break;
22750         case NM_LWXS16:
22751             gen_ldxs(ctx, rt, rs, rd);
22752             break;
22753         }
22754         break;
22755     case NM_P16_A1:
22756         switch (extract32(ctx->opcode, 6, 1)) {
22757         case NM_ADDIUR1SP:
22758             imm = extract32(ctx->opcode, 0, 6) << 2;
22759             gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm);
22760             break;
22761         default:
22762             generate_exception_end(ctx, EXCP_RI);
22763             break;
22764         }
22765         break;
22766     case NM_P16_A2:
22767         switch (extract32(ctx->opcode, 3, 1)) {
22768         case NM_ADDIUR2:
22769             imm = extract32(ctx->opcode, 0, 3) << 2;
22770             gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm);
22771             break;
22772         case NM_P_ADDIURS5:
22773             rt = extract32(ctx->opcode, 5, 5);
22774             if (rt != 0) {
22775                 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
22776                 imm = (sextract32(ctx->opcode, 4, 1) << 3) |
22777                       (extract32(ctx->opcode, 0, 3));
22778                 gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm);
22779             }
22780             break;
22781         }
22782         break;
22783     case NM_P16_ADDU:
22784         switch (ctx->opcode & 0x1) {
22785         case NM_ADDU16:
22786             gen_arith(ctx, OPC_ADDU, rd, rs, rt);
22787             break;
22788         case NM_SUBU16:
22789             gen_arith(ctx, OPC_SUBU, rd, rs, rt);
22790             break;
22791         }
22792         break;
22793     case NM_P16_4X4:
22794         rt = (extract32(ctx->opcode, 9, 1) << 3) |
22795               extract32(ctx->opcode, 5, 3);
22796         rs = (extract32(ctx->opcode, 4, 1) << 3) |
22797               extract32(ctx->opcode, 0, 3);
22798         rt = decode_gpr_gpr4(rt);
22799         rs = decode_gpr_gpr4(rs);
22800         switch ((extract32(ctx->opcode, 7, 2) & 0x2) |
22801                 (extract32(ctx->opcode, 3, 1))) {
22802         case NM_ADDU4X4:
22803             check_nms(ctx);
22804             gen_arith(ctx, OPC_ADDU, rt, rs, rt);
22805             break;
22806         case NM_MUL4X4:
22807             check_nms(ctx);
22808             gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt);
22809             break;
22810         default:
22811             generate_exception_end(ctx, EXCP_RI);
22812             break;
22813         }
22814         break;
22815     case NM_LI16:
22816         {
22817             int imm = extract32(ctx->opcode, 0, 7);
22818             imm = (imm == 0x7f ? -1 : imm);
22819             if (rt != 0) {
22820                 tcg_gen_movi_tl(cpu_gpr[rt], imm);
22821             }
22822         }
22823         break;
22824     case NM_ANDI16:
22825         {
22826             uint32_t u = extract32(ctx->opcode, 0, 4);
22827             u = (u == 12) ? 0xff :
22828                 (u == 13) ? 0xffff : u;
22829             gen_logic_imm(ctx, OPC_ANDI, rt, rs, u);
22830         }
22831         break;
22832     case NM_P16_LB:
22833         offset = extract32(ctx->opcode, 0, 2);
22834         switch (extract32(ctx->opcode, 2, 2)) {
22835         case NM_LB16:
22836             gen_ld(ctx, OPC_LB, rt, rs, offset);
22837             break;
22838         case NM_SB16:
22839             rt = decode_gpr_gpr3_src_store(
22840                      NANOMIPS_EXTRACT_RT3(ctx->opcode));
22841             gen_st(ctx, OPC_SB, rt, rs, offset);
22842             break;
22843         case NM_LBU16:
22844             gen_ld(ctx, OPC_LBU, rt, rs, offset);
22845             break;
22846         default:
22847             generate_exception_end(ctx, EXCP_RI);
22848             break;
22849         }
22850         break;
22851     case NM_P16_LH:
22852         offset = extract32(ctx->opcode, 1, 2) << 1;
22853         switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) {
22854         case NM_LH16:
22855             gen_ld(ctx, OPC_LH, rt, rs, offset);
22856             break;
22857         case NM_SH16:
22858             rt = decode_gpr_gpr3_src_store(
22859                      NANOMIPS_EXTRACT_RT3(ctx->opcode));
22860             gen_st(ctx, OPC_SH, rt, rs, offset);
22861             break;
22862         case NM_LHU16:
22863             gen_ld(ctx, OPC_LHU, rt, rs, offset);
22864             break;
22865         default:
22866             generate_exception_end(ctx, EXCP_RI);
22867             break;
22868         }
22869         break;
22870     case NM_LW16:
22871         offset = extract32(ctx->opcode, 0, 4) << 2;
22872         gen_ld(ctx, OPC_LW, rt, rs, offset);
22873         break;
22874     case NM_LWSP16:
22875         rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22876         offset = extract32(ctx->opcode, 0, 5) << 2;
22877         gen_ld(ctx, OPC_LW, rt, 29, offset);
22878         break;
22879     case NM_LW4X4:
22880         check_nms(ctx);
22881         rt = (extract32(ctx->opcode, 9, 1) << 3) |
22882              extract32(ctx->opcode, 5, 3);
22883         rs = (extract32(ctx->opcode, 4, 1) << 3) |
22884              extract32(ctx->opcode, 0, 3);
22885         offset = (extract32(ctx->opcode, 3, 1) << 3) |
22886                  (extract32(ctx->opcode, 8, 1) << 2);
22887         rt = decode_gpr_gpr4(rt);
22888         rs = decode_gpr_gpr4(rs);
22889         gen_ld(ctx, OPC_LW, rt, rs, offset);
22890         break;
22891     case NM_SW4X4:
22892         check_nms(ctx);
22893         rt = (extract32(ctx->opcode, 9, 1) << 3) |
22894              extract32(ctx->opcode, 5, 3);
22895         rs = (extract32(ctx->opcode, 4, 1) << 3) |
22896              extract32(ctx->opcode, 0, 3);
22897         offset = (extract32(ctx->opcode, 3, 1) << 3) |
22898                  (extract32(ctx->opcode, 8, 1) << 2);
22899         rt = decode_gpr_gpr4_zero(rt);
22900         rs = decode_gpr_gpr4(rs);
22901         gen_st(ctx, OPC_SW, rt, rs, offset);
22902         break;
22903     case NM_LWGP16:
22904         offset = extract32(ctx->opcode, 0, 7) << 2;
22905         gen_ld(ctx, OPC_LW, rt, 28, offset);
22906         break;
22907     case NM_SWSP16:
22908         rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22909         offset = extract32(ctx->opcode, 0, 5) << 2;
22910         gen_st(ctx, OPC_SW, rt, 29, offset);
22911         break;
22912     case NM_SW16:
22913         rt = decode_gpr_gpr3_src_store(
22914                  NANOMIPS_EXTRACT_RT3(ctx->opcode));
22915         rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
22916         offset = extract32(ctx->opcode, 0, 4) << 2;
22917         gen_st(ctx, OPC_SW, rt, rs, offset);
22918         break;
22919     case NM_SWGP16:
22920         rt = decode_gpr_gpr3_src_store(
22921                  NANOMIPS_EXTRACT_RT3(ctx->opcode));
22922         offset = extract32(ctx->opcode, 0, 7) << 2;
22923         gen_st(ctx, OPC_SW, rt, 28, offset);
22924         break;
22925     case NM_BC16:
22926         gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0,
22927                            (sextract32(ctx->opcode, 0, 1) << 10) |
22928                            (extract32(ctx->opcode, 1, 9) << 1));
22929         break;
22930     case NM_BALC16:
22931         gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0,
22932                            (sextract32(ctx->opcode, 0, 1) << 10) |
22933                            (extract32(ctx->opcode, 1, 9) << 1));
22934         break;
22935     case NM_BEQZC16:
22936         gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0,
22937                            (sextract32(ctx->opcode, 0, 1) << 7) |
22938                            (extract32(ctx->opcode, 1, 6) << 1));
22939         break;
22940     case NM_BNEZC16:
22941         gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0,
22942                            (sextract32(ctx->opcode, 0, 1) << 7) |
22943                            (extract32(ctx->opcode, 1, 6) << 1));
22944         break;
22945     case NM_P16_BR:
22946         switch (ctx->opcode & 0xf) {
22947         case 0:
22948             /* P16.JRC */
22949             switch (extract32(ctx->opcode, 4, 1)) {
22950             case NM_JRC:
22951                 gen_compute_branch_nm(ctx, OPC_JR, 2,
22952                                    extract32(ctx->opcode, 5, 5), 0, 0);
22953                 break;
22954             case NM_JALRC16:
22955                 gen_compute_branch_nm(ctx, OPC_JALR, 2,
22956                                    extract32(ctx->opcode, 5, 5), 31, 0);
22957                 break;
22958             }
22959             break;
22960         default:
22961             {
22962                 /* P16.BRI */
22963                 uint32_t opc = extract32(ctx->opcode, 4, 3) <
22964                                extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE;
22965                 gen_compute_branch_nm(ctx, opc, 2, rs, rt,
22966                                    extract32(ctx->opcode, 0, 4) << 1);
22967             }
22968             break;
22969         }
22970         break;
22971     case NM_P16_SR:
22972         {
22973             int count = extract32(ctx->opcode, 0, 4);
22974             int u = extract32(ctx->opcode, 4, 4) << 4;
22975 
22976             rt = 30 + extract32(ctx->opcode, 9, 1);
22977             switch (extract32(ctx->opcode, 8, 1)) {
22978             case NM_SAVE16:
22979                 gen_save(ctx, rt, count, 0, u);
22980                 break;
22981             case NM_RESTORE_JRC16:
22982                 gen_restore(ctx, rt, count, 0, u);
22983                 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
22984                 break;
22985             }
22986         }
22987         break;
22988     case NM_MOVEP:
22989     case NM_MOVEPREV:
22990         check_nms(ctx);
22991         {
22992             static const int gpr2reg1[] = {4, 5, 6, 7};
22993             static const int gpr2reg2[] = {5, 6, 7, 8};
22994             int re;
22995             int rd2 = extract32(ctx->opcode, 3, 1) << 1 |
22996                       extract32(ctx->opcode, 8, 1);
22997             int r1 = gpr2reg1[rd2];
22998             int r2 = gpr2reg2[rd2];
22999             int r3 = extract32(ctx->opcode, 4, 1) << 3 |
23000                      extract32(ctx->opcode, 0, 3);
23001             int r4 = extract32(ctx->opcode, 9, 1) << 3 |
23002                      extract32(ctx->opcode, 5, 3);
23003             TCGv t0 = tcg_temp_new();
23004             TCGv t1 = tcg_temp_new();
23005             if (op == NM_MOVEP) {
23006                 rd = r1;
23007                 re = r2;
23008                 rs = decode_gpr_gpr4_zero(r3);
23009                 rt = decode_gpr_gpr4_zero(r4);
23010             } else {
23011                 rd = decode_gpr_gpr4(r3);
23012                 re = decode_gpr_gpr4(r4);
23013                 rs = r1;
23014                 rt = r2;
23015             }
23016             gen_load_gpr(t0, rs);
23017             gen_load_gpr(t1, rt);
23018             tcg_gen_mov_tl(cpu_gpr[rd], t0);
23019             tcg_gen_mov_tl(cpu_gpr[re], t1);
23020             tcg_temp_free(t0);
23021             tcg_temp_free(t1);
23022         }
23023         break;
23024     default:
23025         return decode_nanomips_32_48_opc(env, ctx);
23026     }
23027 
23028     return 2;
23029 }
23030 
23031 
23032 /* SmartMIPS extension to MIPS32 */
23033 
23034 #if defined(TARGET_MIPS64)
23035 
23036 /* MDMX extension to MIPS64 */
23037 
23038 #endif
23039 
23040 /* MIPSDSP functions. */
gen_mipsdsp_ld(DisasContext * ctx,uint32_t opc,int rd,int base,int offset)23041 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
23042                            int rd, int base, int offset)
23043 {
23044     TCGv t0;
23045 
23046     check_dsp(ctx);
23047     t0 = tcg_temp_new();
23048 
23049     if (base == 0) {
23050         gen_load_gpr(t0, offset);
23051     } else if (offset == 0) {
23052         gen_load_gpr(t0, base);
23053     } else {
23054         gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
23055     }
23056 
23057     switch (opc) {
23058     case OPC_LBUX:
23059         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
23060         gen_store_gpr(t0, rd);
23061         break;
23062     case OPC_LHX:
23063         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
23064         gen_store_gpr(t0, rd);
23065         break;
23066     case OPC_LWX:
23067         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
23068         gen_store_gpr(t0, rd);
23069         break;
23070 #if defined(TARGET_MIPS64)
23071     case OPC_LDX:
23072         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
23073         gen_store_gpr(t0, rd);
23074         break;
23075 #endif
23076     }
23077     tcg_temp_free(t0);
23078 }
23079 
gen_mipsdsp_arith(DisasContext * ctx,uint32_t op1,uint32_t op2,int ret,int v1,int v2)23080 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
23081                               int ret, int v1, int v2)
23082 {
23083     TCGv v1_t;
23084     TCGv v2_t;
23085 
23086     if (ret == 0) {
23087         /* Treat as NOP. */
23088         return;
23089     }
23090 
23091     v1_t = tcg_temp_new();
23092     v2_t = tcg_temp_new();
23093 
23094     gen_load_gpr(v1_t, v1);
23095     gen_load_gpr(v2_t, v2);
23096 
23097     switch (op1) {
23098     /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
23099     case OPC_MULT_G_2E:
23100         check_dsp_r2(ctx);
23101         switch (op2) {
23102         case OPC_ADDUH_QB:
23103             gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
23104             break;
23105         case OPC_ADDUH_R_QB:
23106             gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
23107             break;
23108         case OPC_ADDQH_PH:
23109             gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
23110             break;
23111         case OPC_ADDQH_R_PH:
23112             gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
23113             break;
23114         case OPC_ADDQH_W:
23115             gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
23116             break;
23117         case OPC_ADDQH_R_W:
23118             gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
23119             break;
23120         case OPC_SUBUH_QB:
23121             gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
23122             break;
23123         case OPC_SUBUH_R_QB:
23124             gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
23125             break;
23126         case OPC_SUBQH_PH:
23127             gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
23128             break;
23129         case OPC_SUBQH_R_PH:
23130             gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
23131             break;
23132         case OPC_SUBQH_W:
23133             gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
23134             break;
23135         case OPC_SUBQH_R_W:
23136             gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
23137             break;
23138         }
23139         break;
23140     case OPC_ABSQ_S_PH_DSP:
23141         switch (op2) {
23142         case OPC_ABSQ_S_QB:
23143             check_dsp_r2(ctx);
23144             gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
23145             break;
23146         case OPC_ABSQ_S_PH:
23147             check_dsp(ctx);
23148             gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
23149             break;
23150         case OPC_ABSQ_S_W:
23151             check_dsp(ctx);
23152             gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
23153             break;
23154         case OPC_PRECEQ_W_PHL:
23155             check_dsp(ctx);
23156             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
23157             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23158             break;
23159         case OPC_PRECEQ_W_PHR:
23160             check_dsp(ctx);
23161             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
23162             tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
23163             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23164             break;
23165         case OPC_PRECEQU_PH_QBL:
23166             check_dsp(ctx);
23167             gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
23168             break;
23169         case OPC_PRECEQU_PH_QBR:
23170             check_dsp(ctx);
23171             gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
23172             break;
23173         case OPC_PRECEQU_PH_QBLA:
23174             check_dsp(ctx);
23175             gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
23176             break;
23177         case OPC_PRECEQU_PH_QBRA:
23178             check_dsp(ctx);
23179             gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
23180             break;
23181         case OPC_PRECEU_PH_QBL:
23182             check_dsp(ctx);
23183             gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
23184             break;
23185         case OPC_PRECEU_PH_QBR:
23186             check_dsp(ctx);
23187             gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
23188             break;
23189         case OPC_PRECEU_PH_QBLA:
23190             check_dsp(ctx);
23191             gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
23192             break;
23193         case OPC_PRECEU_PH_QBRA:
23194             check_dsp(ctx);
23195             gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
23196             break;
23197         }
23198         break;
23199     case OPC_ADDU_QB_DSP:
23200         switch (op2) {
23201         case OPC_ADDQ_PH:
23202             check_dsp(ctx);
23203             gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23204             break;
23205         case OPC_ADDQ_S_PH:
23206             check_dsp(ctx);
23207             gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23208             break;
23209         case OPC_ADDQ_S_W:
23210             check_dsp(ctx);
23211             gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23212             break;
23213         case OPC_ADDU_QB:
23214             check_dsp(ctx);
23215             gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23216             break;
23217         case OPC_ADDU_S_QB:
23218             check_dsp(ctx);
23219             gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23220             break;
23221         case OPC_ADDU_PH:
23222             check_dsp_r2(ctx);
23223             gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23224             break;
23225         case OPC_ADDU_S_PH:
23226             check_dsp_r2(ctx);
23227             gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23228             break;
23229         case OPC_SUBQ_PH:
23230             check_dsp(ctx);
23231             gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23232             break;
23233         case OPC_SUBQ_S_PH:
23234             check_dsp(ctx);
23235             gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23236             break;
23237         case OPC_SUBQ_S_W:
23238             check_dsp(ctx);
23239             gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23240             break;
23241         case OPC_SUBU_QB:
23242             check_dsp(ctx);
23243             gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23244             break;
23245         case OPC_SUBU_S_QB:
23246             check_dsp(ctx);
23247             gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23248             break;
23249         case OPC_SUBU_PH:
23250             check_dsp_r2(ctx);
23251             gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23252             break;
23253         case OPC_SUBU_S_PH:
23254             check_dsp_r2(ctx);
23255             gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23256             break;
23257         case OPC_ADDSC:
23258             check_dsp(ctx);
23259             gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23260             break;
23261         case OPC_ADDWC:
23262             check_dsp(ctx);
23263             gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23264             break;
23265         case OPC_MODSUB:
23266             check_dsp(ctx);
23267             gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
23268             break;
23269         case OPC_RADDU_W_QB:
23270             check_dsp(ctx);
23271             gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
23272             break;
23273         }
23274         break;
23275     case OPC_CMPU_EQ_QB_DSP:
23276         switch (op2) {
23277         case OPC_PRECR_QB_PH:
23278             check_dsp_r2(ctx);
23279             gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
23280             break;
23281         case OPC_PRECRQ_QB_PH:
23282             check_dsp(ctx);
23283             gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
23284             break;
23285         case OPC_PRECR_SRA_PH_W:
23286             check_dsp_r2(ctx);
23287             {
23288                 TCGv_i32 sa_t = tcg_const_i32(v2);
23289                 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
23290                                           cpu_gpr[ret]);
23291                 tcg_temp_free_i32(sa_t);
23292                 break;
23293             }
23294         case OPC_PRECR_SRA_R_PH_W:
23295             check_dsp_r2(ctx);
23296             {
23297                 TCGv_i32 sa_t = tcg_const_i32(v2);
23298                 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
23299                                             cpu_gpr[ret]);
23300                 tcg_temp_free_i32(sa_t);
23301                 break;
23302             }
23303         case OPC_PRECRQ_PH_W:
23304             check_dsp(ctx);
23305             gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
23306             break;
23307         case OPC_PRECRQ_RS_PH_W:
23308             check_dsp(ctx);
23309             gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23310             break;
23311         case OPC_PRECRQU_S_QB_PH:
23312             check_dsp(ctx);
23313             gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23314             break;
23315         }
23316         break;
23317 #ifdef TARGET_MIPS64
23318     case OPC_ABSQ_S_QH_DSP:
23319         switch (op2) {
23320         case OPC_PRECEQ_L_PWL:
23321             check_dsp(ctx);
23322             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
23323             break;
23324         case OPC_PRECEQ_L_PWR:
23325             check_dsp(ctx);
23326             tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
23327             break;
23328         case OPC_PRECEQ_PW_QHL:
23329             check_dsp(ctx);
23330             gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
23331             break;
23332         case OPC_PRECEQ_PW_QHR:
23333             check_dsp(ctx);
23334             gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
23335             break;
23336         case OPC_PRECEQ_PW_QHLA:
23337             check_dsp(ctx);
23338             gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
23339             break;
23340         case OPC_PRECEQ_PW_QHRA:
23341             check_dsp(ctx);
23342             gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
23343             break;
23344         case OPC_PRECEQU_QH_OBL:
23345             check_dsp(ctx);
23346             gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
23347             break;
23348         case OPC_PRECEQU_QH_OBR:
23349             check_dsp(ctx);
23350             gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
23351             break;
23352         case OPC_PRECEQU_QH_OBLA:
23353             check_dsp(ctx);
23354             gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
23355             break;
23356         case OPC_PRECEQU_QH_OBRA:
23357             check_dsp(ctx);
23358             gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
23359             break;
23360         case OPC_PRECEU_QH_OBL:
23361             check_dsp(ctx);
23362             gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
23363             break;
23364         case OPC_PRECEU_QH_OBR:
23365             check_dsp(ctx);
23366             gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
23367             break;
23368         case OPC_PRECEU_QH_OBLA:
23369             check_dsp(ctx);
23370             gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
23371             break;
23372         case OPC_PRECEU_QH_OBRA:
23373             check_dsp(ctx);
23374             gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
23375             break;
23376         case OPC_ABSQ_S_OB:
23377             check_dsp_r2(ctx);
23378             gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
23379             break;
23380         case OPC_ABSQ_S_PW:
23381             check_dsp(ctx);
23382             gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
23383             break;
23384         case OPC_ABSQ_S_QH:
23385             check_dsp(ctx);
23386             gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
23387             break;
23388         }
23389         break;
23390     case OPC_ADDU_OB_DSP:
23391         switch (op2) {
23392         case OPC_RADDU_L_OB:
23393             check_dsp(ctx);
23394             gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
23395             break;
23396         case OPC_SUBQ_PW:
23397             check_dsp(ctx);
23398             gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23399             break;
23400         case OPC_SUBQ_S_PW:
23401             check_dsp(ctx);
23402             gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23403             break;
23404         case OPC_SUBQ_QH:
23405             check_dsp(ctx);
23406             gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23407             break;
23408         case OPC_SUBQ_S_QH:
23409             check_dsp(ctx);
23410             gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23411             break;
23412         case OPC_SUBU_OB:
23413             check_dsp(ctx);
23414             gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23415             break;
23416         case OPC_SUBU_S_OB:
23417             check_dsp(ctx);
23418             gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23419             break;
23420         case OPC_SUBU_QH:
23421             check_dsp_r2(ctx);
23422             gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23423             break;
23424         case OPC_SUBU_S_QH:
23425             check_dsp_r2(ctx);
23426             gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23427             break;
23428         case OPC_SUBUH_OB:
23429             check_dsp_r2(ctx);
23430             gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
23431             break;
23432         case OPC_SUBUH_R_OB:
23433             check_dsp_r2(ctx);
23434             gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
23435             break;
23436         case OPC_ADDQ_PW:
23437             check_dsp(ctx);
23438             gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23439             break;
23440         case OPC_ADDQ_S_PW:
23441             check_dsp(ctx);
23442             gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23443             break;
23444         case OPC_ADDQ_QH:
23445             check_dsp(ctx);
23446             gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23447             break;
23448         case OPC_ADDQ_S_QH:
23449             check_dsp(ctx);
23450             gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23451             break;
23452         case OPC_ADDU_OB:
23453             check_dsp(ctx);
23454             gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23455             break;
23456         case OPC_ADDU_S_OB:
23457             check_dsp(ctx);
23458             gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23459             break;
23460         case OPC_ADDU_QH:
23461             check_dsp_r2(ctx);
23462             gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23463             break;
23464         case OPC_ADDU_S_QH:
23465             check_dsp_r2(ctx);
23466             gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23467             break;
23468         case OPC_ADDUH_OB:
23469             check_dsp_r2(ctx);
23470             gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
23471             break;
23472         case OPC_ADDUH_R_OB:
23473             check_dsp_r2(ctx);
23474             gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
23475             break;
23476         }
23477         break;
23478     case OPC_CMPU_EQ_OB_DSP:
23479         switch (op2) {
23480         case OPC_PRECR_OB_QH:
23481             check_dsp_r2(ctx);
23482             gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
23483             break;
23484         case OPC_PRECR_SRA_QH_PW:
23485             check_dsp_r2(ctx);
23486             {
23487                 TCGv_i32 ret_t = tcg_const_i32(ret);
23488                 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
23489                 tcg_temp_free_i32(ret_t);
23490                 break;
23491             }
23492         case OPC_PRECR_SRA_R_QH_PW:
23493             check_dsp_r2(ctx);
23494             {
23495                 TCGv_i32 sa_v = tcg_const_i32(ret);
23496                 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
23497                 tcg_temp_free_i32(sa_v);
23498                 break;
23499             }
23500         case OPC_PRECRQ_OB_QH:
23501             check_dsp(ctx);
23502             gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
23503             break;
23504         case OPC_PRECRQ_PW_L:
23505             check_dsp(ctx);
23506             gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
23507             break;
23508         case OPC_PRECRQ_QH_PW:
23509             check_dsp(ctx);
23510             gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
23511             break;
23512         case OPC_PRECRQ_RS_QH_PW:
23513             check_dsp(ctx);
23514             gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23515             break;
23516         case OPC_PRECRQU_S_OB_QH:
23517             check_dsp(ctx);
23518             gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23519             break;
23520         }
23521         break;
23522 #endif
23523     }
23524 
23525     tcg_temp_free(v1_t);
23526     tcg_temp_free(v2_t);
23527 }
23528 
gen_mipsdsp_shift(DisasContext * ctx,uint32_t opc,int ret,int v1,int v2)23529 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
23530                               int ret, int v1, int v2)
23531 {
23532     uint32_t op2;
23533     TCGv t0;
23534     TCGv v1_t;
23535     TCGv v2_t;
23536 
23537     if (ret == 0) {
23538         /* Treat as NOP. */
23539         return;
23540     }
23541 
23542     t0 = tcg_temp_new();
23543     v1_t = tcg_temp_new();
23544     v2_t = tcg_temp_new();
23545 
23546     tcg_gen_movi_tl(t0, v1);
23547     gen_load_gpr(v1_t, v1);
23548     gen_load_gpr(v2_t, v2);
23549 
23550     switch (opc) {
23551     case OPC_SHLL_QB_DSP:
23552         {
23553             op2 = MASK_SHLL_QB(ctx->opcode);
23554             switch (op2) {
23555             case OPC_SHLL_QB:
23556                 check_dsp(ctx);
23557                 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
23558                 break;
23559             case OPC_SHLLV_QB:
23560                 check_dsp(ctx);
23561                 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23562                 break;
23563             case OPC_SHLL_PH:
23564                 check_dsp(ctx);
23565                 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
23566                 break;
23567             case OPC_SHLLV_PH:
23568                 check_dsp(ctx);
23569                 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23570                 break;
23571             case OPC_SHLL_S_PH:
23572                 check_dsp(ctx);
23573                 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
23574                 break;
23575             case OPC_SHLLV_S_PH:
23576                 check_dsp(ctx);
23577                 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23578                 break;
23579             case OPC_SHLL_S_W:
23580                 check_dsp(ctx);
23581                 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
23582                 break;
23583             case OPC_SHLLV_S_W:
23584                 check_dsp(ctx);
23585                 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23586                 break;
23587             case OPC_SHRL_QB:
23588                 check_dsp(ctx);
23589                 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
23590                 break;
23591             case OPC_SHRLV_QB:
23592                 check_dsp(ctx);
23593                 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
23594                 break;
23595             case OPC_SHRL_PH:
23596                 check_dsp_r2(ctx);
23597                 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
23598                 break;
23599             case OPC_SHRLV_PH:
23600                 check_dsp_r2(ctx);
23601                 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
23602                 break;
23603             case OPC_SHRA_QB:
23604                 check_dsp_r2(ctx);
23605                 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
23606                 break;
23607             case OPC_SHRA_R_QB:
23608                 check_dsp_r2(ctx);
23609                 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
23610                 break;
23611             case OPC_SHRAV_QB:
23612                 check_dsp_r2(ctx);
23613                 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
23614                 break;
23615             case OPC_SHRAV_R_QB:
23616                 check_dsp_r2(ctx);
23617                 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
23618                 break;
23619             case OPC_SHRA_PH:
23620                 check_dsp(ctx);
23621                 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
23622                 break;
23623             case OPC_SHRA_R_PH:
23624                 check_dsp(ctx);
23625                 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
23626                 break;
23627             case OPC_SHRAV_PH:
23628                 check_dsp(ctx);
23629                 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
23630                 break;
23631             case OPC_SHRAV_R_PH:
23632                 check_dsp(ctx);
23633                 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
23634                 break;
23635             case OPC_SHRA_R_W:
23636                 check_dsp(ctx);
23637                 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
23638                 break;
23639             case OPC_SHRAV_R_W:
23640                 check_dsp(ctx);
23641                 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
23642                 break;
23643             default:            /* Invalid */
23644                 MIPS_INVAL("MASK SHLL.QB");
23645                 generate_exception_end(ctx, EXCP_RI);
23646                 break;
23647             }
23648             break;
23649         }
23650 #ifdef TARGET_MIPS64
23651     case OPC_SHLL_OB_DSP:
23652         op2 = MASK_SHLL_OB(ctx->opcode);
23653         switch (op2) {
23654         case OPC_SHLL_PW:
23655             check_dsp(ctx);
23656             gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
23657             break;
23658         case OPC_SHLLV_PW:
23659             check_dsp(ctx);
23660             gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
23661             break;
23662         case OPC_SHLL_S_PW:
23663             check_dsp(ctx);
23664             gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
23665             break;
23666         case OPC_SHLLV_S_PW:
23667             check_dsp(ctx);
23668             gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
23669             break;
23670         case OPC_SHLL_OB:
23671             check_dsp(ctx);
23672             gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
23673             break;
23674         case OPC_SHLLV_OB:
23675             check_dsp(ctx);
23676             gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
23677             break;
23678         case OPC_SHLL_QH:
23679             check_dsp(ctx);
23680             gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
23681             break;
23682         case OPC_SHLLV_QH:
23683             check_dsp(ctx);
23684             gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
23685             break;
23686         case OPC_SHLL_S_QH:
23687             check_dsp(ctx);
23688             gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
23689             break;
23690         case OPC_SHLLV_S_QH:
23691             check_dsp(ctx);
23692             gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
23693             break;
23694         case OPC_SHRA_OB:
23695             check_dsp_r2(ctx);
23696             gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
23697             break;
23698         case OPC_SHRAV_OB:
23699             check_dsp_r2(ctx);
23700             gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
23701             break;
23702         case OPC_SHRA_R_OB:
23703             check_dsp_r2(ctx);
23704             gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
23705             break;
23706         case OPC_SHRAV_R_OB:
23707             check_dsp_r2(ctx);
23708             gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
23709             break;
23710         case OPC_SHRA_PW:
23711             check_dsp(ctx);
23712             gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
23713             break;
23714         case OPC_SHRAV_PW:
23715             check_dsp(ctx);
23716             gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
23717             break;
23718         case OPC_SHRA_R_PW:
23719             check_dsp(ctx);
23720             gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
23721             break;
23722         case OPC_SHRAV_R_PW:
23723             check_dsp(ctx);
23724             gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
23725             break;
23726         case OPC_SHRA_QH:
23727             check_dsp(ctx);
23728             gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
23729             break;
23730         case OPC_SHRAV_QH:
23731             check_dsp(ctx);
23732             gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
23733             break;
23734         case OPC_SHRA_R_QH:
23735             check_dsp(ctx);
23736             gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
23737             break;
23738         case OPC_SHRAV_R_QH:
23739             check_dsp(ctx);
23740             gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
23741             break;
23742         case OPC_SHRL_OB:
23743             check_dsp(ctx);
23744             gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
23745             break;
23746         case OPC_SHRLV_OB:
23747             check_dsp(ctx);
23748             gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
23749             break;
23750         case OPC_SHRL_QH:
23751             check_dsp_r2(ctx);
23752             gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
23753             break;
23754         case OPC_SHRLV_QH:
23755             check_dsp_r2(ctx);
23756             gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
23757             break;
23758         default:            /* Invalid */
23759             MIPS_INVAL("MASK SHLL.OB");
23760             generate_exception_end(ctx, EXCP_RI);
23761             break;
23762         }
23763         break;
23764 #endif
23765     }
23766 
23767     tcg_temp_free(t0);
23768     tcg_temp_free(v1_t);
23769     tcg_temp_free(v2_t);
23770 }
23771 
gen_mipsdsp_multiply(DisasContext * ctx,uint32_t op1,uint32_t op2,int ret,int v1,int v2,int check_ret)23772 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
23773                                  int ret, int v1, int v2, int check_ret)
23774 {
23775     TCGv_i32 t0;
23776     TCGv v1_t;
23777     TCGv v2_t;
23778 
23779     if ((ret == 0) && (check_ret == 1)) {
23780         /* Treat as NOP. */
23781         return;
23782     }
23783 
23784     t0 = tcg_temp_new_i32();
23785     v1_t = tcg_temp_new();
23786     v2_t = tcg_temp_new();
23787 
23788     tcg_gen_movi_i32(t0, ret);
23789     gen_load_gpr(v1_t, v1);
23790     gen_load_gpr(v2_t, v2);
23791 
23792     switch (op1) {
23793     /*
23794      * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
23795      * the same mask and op1.
23796      */
23797     case OPC_MULT_G_2E:
23798         check_dsp_r2(ctx);
23799         switch (op2) {
23800         case  OPC_MUL_PH:
23801             gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23802             break;
23803         case  OPC_MUL_S_PH:
23804             gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23805             break;
23806         case OPC_MULQ_S_W:
23807             gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23808             break;
23809         case OPC_MULQ_RS_W:
23810             gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23811             break;
23812         }
23813         break;
23814     case OPC_DPA_W_PH_DSP:
23815         switch (op2) {
23816         case OPC_DPAU_H_QBL:
23817             check_dsp(ctx);
23818             gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
23819             break;
23820         case OPC_DPAU_H_QBR:
23821             check_dsp(ctx);
23822             gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
23823             break;
23824         case OPC_DPSU_H_QBL:
23825             check_dsp(ctx);
23826             gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
23827             break;
23828         case OPC_DPSU_H_QBR:
23829             check_dsp(ctx);
23830             gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
23831             break;
23832         case OPC_DPA_W_PH:
23833             check_dsp_r2(ctx);
23834             gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
23835             break;
23836         case OPC_DPAX_W_PH:
23837             check_dsp_r2(ctx);
23838             gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
23839             break;
23840         case OPC_DPAQ_S_W_PH:
23841             check_dsp(ctx);
23842             gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23843             break;
23844         case OPC_DPAQX_S_W_PH:
23845             check_dsp_r2(ctx);
23846             gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
23847             break;
23848         case OPC_DPAQX_SA_W_PH:
23849             check_dsp_r2(ctx);
23850             gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
23851             break;
23852         case OPC_DPS_W_PH:
23853             check_dsp_r2(ctx);
23854             gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
23855             break;
23856         case OPC_DPSX_W_PH:
23857             check_dsp_r2(ctx);
23858             gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
23859             break;
23860         case OPC_DPSQ_S_W_PH:
23861             check_dsp(ctx);
23862             gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23863             break;
23864         case OPC_DPSQX_S_W_PH:
23865             check_dsp_r2(ctx);
23866             gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
23867             break;
23868         case OPC_DPSQX_SA_W_PH:
23869             check_dsp_r2(ctx);
23870             gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
23871             break;
23872         case OPC_MULSAQ_S_W_PH:
23873             check_dsp(ctx);
23874             gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23875             break;
23876         case OPC_DPAQ_SA_L_W:
23877             check_dsp(ctx);
23878             gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
23879             break;
23880         case OPC_DPSQ_SA_L_W:
23881             check_dsp(ctx);
23882             gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
23883             break;
23884         case OPC_MAQ_S_W_PHL:
23885             check_dsp(ctx);
23886             gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
23887             break;
23888         case OPC_MAQ_S_W_PHR:
23889             check_dsp(ctx);
23890             gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
23891             break;
23892         case OPC_MAQ_SA_W_PHL:
23893             check_dsp(ctx);
23894             gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
23895             break;
23896         case OPC_MAQ_SA_W_PHR:
23897             check_dsp(ctx);
23898             gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
23899             break;
23900         case OPC_MULSA_W_PH:
23901             check_dsp_r2(ctx);
23902             gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
23903             break;
23904         }
23905         break;
23906 #ifdef TARGET_MIPS64
23907     case OPC_DPAQ_W_QH_DSP:
23908         {
23909             int ac = ret & 0x03;
23910             tcg_gen_movi_i32(t0, ac);
23911 
23912             switch (op2) {
23913             case OPC_DMADD:
23914                 check_dsp(ctx);
23915                 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
23916                 break;
23917             case OPC_DMADDU:
23918                 check_dsp(ctx);
23919                 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
23920                 break;
23921             case OPC_DMSUB:
23922                 check_dsp(ctx);
23923                 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
23924                 break;
23925             case OPC_DMSUBU:
23926                 check_dsp(ctx);
23927                 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
23928                 break;
23929             case OPC_DPA_W_QH:
23930                 check_dsp_r2(ctx);
23931                 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
23932                 break;
23933             case OPC_DPAQ_S_W_QH:
23934                 check_dsp(ctx);
23935                 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23936                 break;
23937             case OPC_DPAQ_SA_L_PW:
23938                 check_dsp(ctx);
23939                 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
23940                 break;
23941             case OPC_DPAU_H_OBL:
23942                 check_dsp(ctx);
23943                 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
23944                 break;
23945             case OPC_DPAU_H_OBR:
23946                 check_dsp(ctx);
23947                 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
23948                 break;
23949             case OPC_DPS_W_QH:
23950                 check_dsp_r2(ctx);
23951                 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
23952                 break;
23953             case OPC_DPSQ_S_W_QH:
23954                 check_dsp(ctx);
23955                 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23956                 break;
23957             case OPC_DPSQ_SA_L_PW:
23958                 check_dsp(ctx);
23959                 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
23960                 break;
23961             case OPC_DPSU_H_OBL:
23962                 check_dsp(ctx);
23963                 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
23964                 break;
23965             case OPC_DPSU_H_OBR:
23966                 check_dsp(ctx);
23967                 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
23968                 break;
23969             case OPC_MAQ_S_L_PWL:
23970                 check_dsp(ctx);
23971                 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
23972                 break;
23973             case OPC_MAQ_S_L_PWR:
23974                 check_dsp(ctx);
23975                 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
23976                 break;
23977             case OPC_MAQ_S_W_QHLL:
23978                 check_dsp(ctx);
23979                 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
23980                 break;
23981             case OPC_MAQ_SA_W_QHLL:
23982                 check_dsp(ctx);
23983                 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
23984                 break;
23985             case OPC_MAQ_S_W_QHLR:
23986                 check_dsp(ctx);
23987                 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
23988                 break;
23989             case OPC_MAQ_SA_W_QHLR:
23990                 check_dsp(ctx);
23991                 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
23992                 break;
23993             case OPC_MAQ_S_W_QHRL:
23994                 check_dsp(ctx);
23995                 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
23996                 break;
23997             case OPC_MAQ_SA_W_QHRL:
23998                 check_dsp(ctx);
23999                 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
24000                 break;
24001             case OPC_MAQ_S_W_QHRR:
24002                 check_dsp(ctx);
24003                 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
24004                 break;
24005             case OPC_MAQ_SA_W_QHRR:
24006                 check_dsp(ctx);
24007                 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
24008                 break;
24009             case OPC_MULSAQ_S_L_PW:
24010                 check_dsp(ctx);
24011                 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
24012                 break;
24013             case OPC_MULSAQ_S_W_QH:
24014                 check_dsp(ctx);
24015                 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
24016                 break;
24017             }
24018         }
24019         break;
24020 #endif
24021     case OPC_ADDU_QB_DSP:
24022         switch (op2) {
24023         case OPC_MULEU_S_PH_QBL:
24024             check_dsp(ctx);
24025             gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
24026             break;
24027         case OPC_MULEU_S_PH_QBR:
24028             check_dsp(ctx);
24029             gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
24030             break;
24031         case OPC_MULQ_RS_PH:
24032             check_dsp(ctx);
24033             gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
24034             break;
24035         case OPC_MULEQ_S_W_PHL:
24036             check_dsp(ctx);
24037             gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
24038             break;
24039         case OPC_MULEQ_S_W_PHR:
24040             check_dsp(ctx);
24041             gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
24042             break;
24043         case OPC_MULQ_S_PH:
24044             check_dsp_r2(ctx);
24045             gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
24046             break;
24047         }
24048         break;
24049 #ifdef TARGET_MIPS64
24050     case OPC_ADDU_OB_DSP:
24051         switch (op2) {
24052         case OPC_MULEQ_S_PW_QHL:
24053             check_dsp(ctx);
24054             gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
24055             break;
24056         case OPC_MULEQ_S_PW_QHR:
24057             check_dsp(ctx);
24058             gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
24059             break;
24060         case OPC_MULEU_S_QH_OBL:
24061             check_dsp(ctx);
24062             gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
24063             break;
24064         case OPC_MULEU_S_QH_OBR:
24065             check_dsp(ctx);
24066             gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
24067             break;
24068         case OPC_MULQ_RS_QH:
24069             check_dsp(ctx);
24070             gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
24071             break;
24072         }
24073         break;
24074 #endif
24075     }
24076 
24077     tcg_temp_free_i32(t0);
24078     tcg_temp_free(v1_t);
24079     tcg_temp_free(v2_t);
24080 }
24081 
gen_mipsdsp_bitinsn(DisasContext * ctx,uint32_t op1,uint32_t op2,int ret,int val)24082 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
24083                                 int ret, int val)
24084 {
24085     int16_t imm;
24086     TCGv t0;
24087     TCGv val_t;
24088 
24089     if (ret == 0) {
24090         /* Treat as NOP. */
24091         return;
24092     }
24093 
24094     t0 = tcg_temp_new();
24095     val_t = tcg_temp_new();
24096     gen_load_gpr(val_t, val);
24097 
24098     switch (op1) {
24099     case OPC_ABSQ_S_PH_DSP:
24100         switch (op2) {
24101         case OPC_BITREV:
24102             check_dsp(ctx);
24103             gen_helper_bitrev(cpu_gpr[ret], val_t);
24104             break;
24105         case OPC_REPL_QB:
24106             check_dsp(ctx);
24107             {
24108                 target_long result;
24109                 imm = (ctx->opcode >> 16) & 0xFF;
24110                 result = (uint32_t)imm << 24 |
24111                          (uint32_t)imm << 16 |
24112                          (uint32_t)imm << 8  |
24113                          (uint32_t)imm;
24114                 result = (int32_t)result;
24115                 tcg_gen_movi_tl(cpu_gpr[ret], result);
24116             }
24117             break;
24118         case OPC_REPLV_QB:
24119             check_dsp(ctx);
24120             tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
24121             tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
24122             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
24123             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
24124             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
24125             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
24126             break;
24127         case OPC_REPL_PH:
24128             check_dsp(ctx);
24129             {
24130                 imm = (ctx->opcode >> 16) & 0x03FF;
24131                 imm = (int16_t)(imm << 6) >> 6;
24132                 tcg_gen_movi_tl(cpu_gpr[ret], \
24133                                 (target_long)((int32_t)imm << 16 | \
24134                                 (uint16_t)imm));
24135             }
24136             break;
24137         case OPC_REPLV_PH:
24138             check_dsp(ctx);
24139             tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
24140             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
24141             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
24142             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
24143             break;
24144         }
24145         break;
24146 #ifdef TARGET_MIPS64
24147     case OPC_ABSQ_S_QH_DSP:
24148         switch (op2) {
24149         case OPC_REPL_OB:
24150             check_dsp(ctx);
24151             {
24152                 target_long temp;
24153 
24154                 imm = (ctx->opcode >> 16) & 0xFF;
24155                 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
24156                 temp = (temp << 16) | temp;
24157                 temp = (temp << 32) | temp;
24158                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
24159                 break;
24160             }
24161         case OPC_REPL_PW:
24162             check_dsp(ctx);
24163             {
24164                 target_long temp;
24165 
24166                 imm = (ctx->opcode >> 16) & 0x03FF;
24167                 imm = (int16_t)(imm << 6) >> 6;
24168                 temp = ((target_long)imm << 32) \
24169                        | ((target_long)imm & 0xFFFFFFFF);
24170                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
24171                 break;
24172             }
24173         case OPC_REPL_QH:
24174             check_dsp(ctx);
24175             {
24176                 target_long temp;
24177 
24178                 imm = (ctx->opcode >> 16) & 0x03FF;
24179                 imm = (int16_t)(imm << 6) >> 6;
24180 
24181                 temp = ((uint64_t)(uint16_t)imm << 48) |
24182                        ((uint64_t)(uint16_t)imm << 32) |
24183                        ((uint64_t)(uint16_t)imm << 16) |
24184                        (uint64_t)(uint16_t)imm;
24185                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
24186                 break;
24187             }
24188         case OPC_REPLV_OB:
24189             check_dsp(ctx);
24190             tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
24191             tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
24192             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
24193             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
24194             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
24195             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
24196             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
24197             break;
24198         case OPC_REPLV_PW:
24199             check_dsp(ctx);
24200             tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
24201             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
24202             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
24203             break;
24204         case OPC_REPLV_QH:
24205             check_dsp(ctx);
24206             tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
24207             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
24208             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
24209             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
24210             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
24211             break;
24212         }
24213         break;
24214 #endif
24215     }
24216     tcg_temp_free(t0);
24217     tcg_temp_free(val_t);
24218 }
24219 
gen_mipsdsp_add_cmp_pick(DisasContext * ctx,uint32_t op1,uint32_t op2,int ret,int v1,int v2,int check_ret)24220 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
24221                                      uint32_t op1, uint32_t op2,
24222                                      int ret, int v1, int v2, int check_ret)
24223 {
24224     TCGv t1;
24225     TCGv v1_t;
24226     TCGv v2_t;
24227 
24228     if ((ret == 0) && (check_ret == 1)) {
24229         /* Treat as NOP. */
24230         return;
24231     }
24232 
24233     t1 = tcg_temp_new();
24234     v1_t = tcg_temp_new();
24235     v2_t = tcg_temp_new();
24236 
24237     gen_load_gpr(v1_t, v1);
24238     gen_load_gpr(v2_t, v2);
24239 
24240     switch (op1) {
24241     case OPC_CMPU_EQ_QB_DSP:
24242         switch (op2) {
24243         case OPC_CMPU_EQ_QB:
24244             check_dsp(ctx);
24245             gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
24246             break;
24247         case OPC_CMPU_LT_QB:
24248             check_dsp(ctx);
24249             gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
24250             break;
24251         case OPC_CMPU_LE_QB:
24252             check_dsp(ctx);
24253             gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
24254             break;
24255         case OPC_CMPGU_EQ_QB:
24256             check_dsp(ctx);
24257             gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
24258             break;
24259         case OPC_CMPGU_LT_QB:
24260             check_dsp(ctx);
24261             gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
24262             break;
24263         case OPC_CMPGU_LE_QB:
24264             check_dsp(ctx);
24265             gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
24266             break;
24267         case OPC_CMPGDU_EQ_QB:
24268             check_dsp_r2(ctx);
24269             gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
24270             tcg_gen_mov_tl(cpu_gpr[ret], t1);
24271             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
24272             tcg_gen_shli_tl(t1, t1, 24);
24273             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
24274             break;
24275         case OPC_CMPGDU_LT_QB:
24276             check_dsp_r2(ctx);
24277             gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
24278             tcg_gen_mov_tl(cpu_gpr[ret], t1);
24279             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
24280             tcg_gen_shli_tl(t1, t1, 24);
24281             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
24282             break;
24283         case OPC_CMPGDU_LE_QB:
24284             check_dsp_r2(ctx);
24285             gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
24286             tcg_gen_mov_tl(cpu_gpr[ret], t1);
24287             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
24288             tcg_gen_shli_tl(t1, t1, 24);
24289             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
24290             break;
24291         case OPC_CMP_EQ_PH:
24292             check_dsp(ctx);
24293             gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
24294             break;
24295         case OPC_CMP_LT_PH:
24296             check_dsp(ctx);
24297             gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
24298             break;
24299         case OPC_CMP_LE_PH:
24300             check_dsp(ctx);
24301             gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
24302             break;
24303         case OPC_PICK_QB:
24304             check_dsp(ctx);
24305             gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
24306             break;
24307         case OPC_PICK_PH:
24308             check_dsp(ctx);
24309             gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
24310             break;
24311         case OPC_PACKRL_PH:
24312             check_dsp(ctx);
24313             gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
24314             break;
24315         }
24316         break;
24317 #ifdef TARGET_MIPS64
24318     case OPC_CMPU_EQ_OB_DSP:
24319         switch (op2) {
24320         case OPC_CMP_EQ_PW:
24321             check_dsp(ctx);
24322             gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
24323             break;
24324         case OPC_CMP_LT_PW:
24325             check_dsp(ctx);
24326             gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
24327             break;
24328         case OPC_CMP_LE_PW:
24329             check_dsp(ctx);
24330             gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
24331             break;
24332         case OPC_CMP_EQ_QH:
24333             check_dsp(ctx);
24334             gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
24335             break;
24336         case OPC_CMP_LT_QH:
24337             check_dsp(ctx);
24338             gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
24339             break;
24340         case OPC_CMP_LE_QH:
24341             check_dsp(ctx);
24342             gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
24343             break;
24344         case OPC_CMPGDU_EQ_OB:
24345             check_dsp_r2(ctx);
24346             gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
24347             break;
24348         case OPC_CMPGDU_LT_OB:
24349             check_dsp_r2(ctx);
24350             gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
24351             break;
24352         case OPC_CMPGDU_LE_OB:
24353             check_dsp_r2(ctx);
24354             gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
24355             break;
24356         case OPC_CMPGU_EQ_OB:
24357             check_dsp(ctx);
24358             gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
24359             break;
24360         case OPC_CMPGU_LT_OB:
24361             check_dsp(ctx);
24362             gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
24363             break;
24364         case OPC_CMPGU_LE_OB:
24365             check_dsp(ctx);
24366             gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
24367             break;
24368         case OPC_CMPU_EQ_OB:
24369             check_dsp(ctx);
24370             gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
24371             break;
24372         case OPC_CMPU_LT_OB:
24373             check_dsp(ctx);
24374             gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
24375             break;
24376         case OPC_CMPU_LE_OB:
24377             check_dsp(ctx);
24378             gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
24379             break;
24380         case OPC_PACKRL_PW:
24381             check_dsp(ctx);
24382             gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
24383             break;
24384         case OPC_PICK_OB:
24385             check_dsp(ctx);
24386             gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
24387             break;
24388         case OPC_PICK_PW:
24389             check_dsp(ctx);
24390             gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
24391             break;
24392         case OPC_PICK_QH:
24393             check_dsp(ctx);
24394             gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
24395             break;
24396         }
24397         break;
24398 #endif
24399     }
24400 
24401     tcg_temp_free(t1);
24402     tcg_temp_free(v1_t);
24403     tcg_temp_free(v2_t);
24404 }
24405 
gen_mipsdsp_append(CPUMIPSState * env,DisasContext * ctx,uint32_t op1,int rt,int rs,int sa)24406 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
24407                                uint32_t op1, int rt, int rs, int sa)
24408 {
24409     TCGv t0;
24410 
24411     check_dsp_r2(ctx);
24412 
24413     if (rt == 0) {
24414         /* Treat as NOP. */
24415         return;
24416     }
24417 
24418     t0 = tcg_temp_new();
24419     gen_load_gpr(t0, rs);
24420 
24421     switch (op1) {
24422     case OPC_APPEND_DSP:
24423         switch (MASK_APPEND(ctx->opcode)) {
24424         case OPC_APPEND:
24425             if (sa != 0) {
24426                 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
24427             }
24428             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
24429             break;
24430         case OPC_PREPEND:
24431             if (sa != 0) {
24432                 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
24433                 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
24434                 tcg_gen_shli_tl(t0, t0, 32 - sa);
24435                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
24436             }
24437             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
24438             break;
24439         case OPC_BALIGN:
24440             sa &= 3;
24441             if (sa != 0 && sa != 2) {
24442                 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
24443                 tcg_gen_ext32u_tl(t0, t0);
24444                 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
24445                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
24446             }
24447             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
24448             break;
24449         default:            /* Invalid */
24450             MIPS_INVAL("MASK APPEND");
24451             generate_exception_end(ctx, EXCP_RI);
24452             break;
24453         }
24454         break;
24455 #ifdef TARGET_MIPS64
24456     case OPC_DAPPEND_DSP:
24457         switch (MASK_DAPPEND(ctx->opcode)) {
24458         case OPC_DAPPEND:
24459             if (sa != 0) {
24460                 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
24461             }
24462             break;
24463         case OPC_PREPENDD:
24464             tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
24465             tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
24466             tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
24467             break;
24468         case OPC_PREPENDW:
24469             if (sa != 0) {
24470                 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
24471                 tcg_gen_shli_tl(t0, t0, 64 - sa);
24472                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
24473             }
24474             break;
24475         case OPC_DBALIGN:
24476             sa &= 7;
24477             if (sa != 0 && sa != 2 && sa != 4) {
24478                 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
24479                 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
24480                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
24481             }
24482             break;
24483         default:            /* Invalid */
24484             MIPS_INVAL("MASK DAPPEND");
24485             generate_exception_end(ctx, EXCP_RI);
24486             break;
24487         }
24488         break;
24489 #endif
24490     }
24491     tcg_temp_free(t0);
24492 }
24493 
gen_mipsdsp_accinsn(DisasContext * ctx,uint32_t op1,uint32_t op2,int ret,int v1,int v2,int check_ret)24494 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
24495                                 int ret, int v1, int v2, int check_ret)
24496 
24497 {
24498     TCGv t0;
24499     TCGv t1;
24500     TCGv v1_t;
24501     TCGv v2_t;
24502     int16_t imm;
24503 
24504     if ((ret == 0) && (check_ret == 1)) {
24505         /* Treat as NOP. */
24506         return;
24507     }
24508 
24509     t0 = tcg_temp_new();
24510     t1 = tcg_temp_new();
24511     v1_t = tcg_temp_new();
24512     v2_t = tcg_temp_new();
24513 
24514     gen_load_gpr(v1_t, v1);
24515     gen_load_gpr(v2_t, v2);
24516 
24517     switch (op1) {
24518     case OPC_EXTR_W_DSP:
24519         check_dsp(ctx);
24520         switch (op2) {
24521         case OPC_EXTR_W:
24522             tcg_gen_movi_tl(t0, v2);
24523             tcg_gen_movi_tl(t1, v1);
24524             gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
24525             break;
24526         case OPC_EXTR_R_W:
24527             tcg_gen_movi_tl(t0, v2);
24528             tcg_gen_movi_tl(t1, v1);
24529             gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
24530             break;
24531         case OPC_EXTR_RS_W:
24532             tcg_gen_movi_tl(t0, v2);
24533             tcg_gen_movi_tl(t1, v1);
24534             gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
24535             break;
24536         case OPC_EXTR_S_H:
24537             tcg_gen_movi_tl(t0, v2);
24538             tcg_gen_movi_tl(t1, v1);
24539             gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
24540             break;
24541         case OPC_EXTRV_S_H:
24542             tcg_gen_movi_tl(t0, v2);
24543             gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
24544             break;
24545         case OPC_EXTRV_W:
24546             tcg_gen_movi_tl(t0, v2);
24547             gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
24548             break;
24549         case OPC_EXTRV_R_W:
24550             tcg_gen_movi_tl(t0, v2);
24551             gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
24552             break;
24553         case OPC_EXTRV_RS_W:
24554             tcg_gen_movi_tl(t0, v2);
24555             gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
24556             break;
24557         case OPC_EXTP:
24558             tcg_gen_movi_tl(t0, v2);
24559             tcg_gen_movi_tl(t1, v1);
24560             gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
24561             break;
24562         case OPC_EXTPV:
24563             tcg_gen_movi_tl(t0, v2);
24564             gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
24565             break;
24566         case OPC_EXTPDP:
24567             tcg_gen_movi_tl(t0, v2);
24568             tcg_gen_movi_tl(t1, v1);
24569             gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
24570             break;
24571         case OPC_EXTPDPV:
24572             tcg_gen_movi_tl(t0, v2);
24573             gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
24574             break;
24575         case OPC_SHILO:
24576             imm = (ctx->opcode >> 20) & 0x3F;
24577             tcg_gen_movi_tl(t0, ret);
24578             tcg_gen_movi_tl(t1, imm);
24579             gen_helper_shilo(t0, t1, cpu_env);
24580             break;
24581         case OPC_SHILOV:
24582             tcg_gen_movi_tl(t0, ret);
24583             gen_helper_shilo(t0, v1_t, cpu_env);
24584             break;
24585         case OPC_MTHLIP:
24586             tcg_gen_movi_tl(t0, ret);
24587             gen_helper_mthlip(t0, v1_t, cpu_env);
24588             break;
24589         case OPC_WRDSP:
24590             imm = (ctx->opcode >> 11) & 0x3FF;
24591             tcg_gen_movi_tl(t0, imm);
24592             gen_helper_wrdsp(v1_t, t0, cpu_env);
24593             break;
24594         case OPC_RDDSP:
24595             imm = (ctx->opcode >> 16) & 0x03FF;
24596             tcg_gen_movi_tl(t0, imm);
24597             gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
24598             break;
24599         }
24600         break;
24601 #ifdef TARGET_MIPS64
24602     case OPC_DEXTR_W_DSP:
24603         check_dsp(ctx);
24604         switch (op2) {
24605         case OPC_DMTHLIP:
24606             tcg_gen_movi_tl(t0, ret);
24607             gen_helper_dmthlip(v1_t, t0, cpu_env);
24608             break;
24609         case OPC_DSHILO:
24610             {
24611                 int shift = (ctx->opcode >> 19) & 0x7F;
24612                 int ac = (ctx->opcode >> 11) & 0x03;
24613                 tcg_gen_movi_tl(t0, shift);
24614                 tcg_gen_movi_tl(t1, ac);
24615                 gen_helper_dshilo(t0, t1, cpu_env);
24616                 break;
24617             }
24618         case OPC_DSHILOV:
24619             {
24620                 int ac = (ctx->opcode >> 11) & 0x03;
24621                 tcg_gen_movi_tl(t0, ac);
24622                 gen_helper_dshilo(v1_t, t0, cpu_env);
24623                 break;
24624             }
24625         case OPC_DEXTP:
24626             tcg_gen_movi_tl(t0, v2);
24627             tcg_gen_movi_tl(t1, v1);
24628 
24629             gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
24630             break;
24631         case OPC_DEXTPV:
24632             tcg_gen_movi_tl(t0, v2);
24633             gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
24634             break;
24635         case OPC_DEXTPDP:
24636             tcg_gen_movi_tl(t0, v2);
24637             tcg_gen_movi_tl(t1, v1);
24638             gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
24639             break;
24640         case OPC_DEXTPDPV:
24641             tcg_gen_movi_tl(t0, v2);
24642             gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
24643             break;
24644         case OPC_DEXTR_L:
24645             tcg_gen_movi_tl(t0, v2);
24646             tcg_gen_movi_tl(t1, v1);
24647             gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
24648             break;
24649         case OPC_DEXTR_R_L:
24650             tcg_gen_movi_tl(t0, v2);
24651             tcg_gen_movi_tl(t1, v1);
24652             gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
24653             break;
24654         case OPC_DEXTR_RS_L:
24655             tcg_gen_movi_tl(t0, v2);
24656             tcg_gen_movi_tl(t1, v1);
24657             gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
24658             break;
24659         case OPC_DEXTR_W:
24660             tcg_gen_movi_tl(t0, v2);
24661             tcg_gen_movi_tl(t1, v1);
24662             gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
24663             break;
24664         case OPC_DEXTR_R_W:
24665             tcg_gen_movi_tl(t0, v2);
24666             tcg_gen_movi_tl(t1, v1);
24667             gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
24668             break;
24669         case OPC_DEXTR_RS_W:
24670             tcg_gen_movi_tl(t0, v2);
24671             tcg_gen_movi_tl(t1, v1);
24672             gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
24673             break;
24674         case OPC_DEXTR_S_H:
24675             tcg_gen_movi_tl(t0, v2);
24676             tcg_gen_movi_tl(t1, v1);
24677             gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
24678             break;
24679         case OPC_DEXTRV_S_H:
24680             tcg_gen_movi_tl(t0, v2);
24681             tcg_gen_movi_tl(t1, v1);
24682             gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
24683             break;
24684         case OPC_DEXTRV_L:
24685             tcg_gen_movi_tl(t0, v2);
24686             gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
24687             break;
24688         case OPC_DEXTRV_R_L:
24689             tcg_gen_movi_tl(t0, v2);
24690             gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
24691             break;
24692         case OPC_DEXTRV_RS_L:
24693             tcg_gen_movi_tl(t0, v2);
24694             gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
24695             break;
24696         case OPC_DEXTRV_W:
24697             tcg_gen_movi_tl(t0, v2);
24698             gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
24699             break;
24700         case OPC_DEXTRV_R_W:
24701             tcg_gen_movi_tl(t0, v2);
24702             gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
24703             break;
24704         case OPC_DEXTRV_RS_W:
24705             tcg_gen_movi_tl(t0, v2);
24706             gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
24707             break;
24708         }
24709         break;
24710 #endif
24711     }
24712 
24713     tcg_temp_free(t0);
24714     tcg_temp_free(t1);
24715     tcg_temp_free(v1_t);
24716     tcg_temp_free(v2_t);
24717 }
24718 
24719 /* End MIPSDSP functions. */
24720 
decode_opc_special_r6(CPUMIPSState * env,DisasContext * ctx)24721 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
24722 {
24723     int rs, rt, rd, sa;
24724     uint32_t op1, op2;
24725 
24726     rs = (ctx->opcode >> 21) & 0x1f;
24727     rt = (ctx->opcode >> 16) & 0x1f;
24728     rd = (ctx->opcode >> 11) & 0x1f;
24729     sa = (ctx->opcode >> 6) & 0x1f;
24730 
24731     op1 = MASK_SPECIAL(ctx->opcode);
24732     switch (op1) {
24733     case OPC_LSA:
24734         gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
24735         break;
24736     case OPC_MULT:
24737     case OPC_MULTU:
24738     case OPC_DIV:
24739     case OPC_DIVU:
24740         op2 = MASK_R6_MULDIV(ctx->opcode);
24741         switch (op2) {
24742         case R6_OPC_MUL:
24743         case R6_OPC_MUH:
24744         case R6_OPC_MULU:
24745         case R6_OPC_MUHU:
24746         case R6_OPC_DIV:
24747         case R6_OPC_MOD:
24748         case R6_OPC_DIVU:
24749         case R6_OPC_MODU:
24750             gen_r6_muldiv(ctx, op2, rd, rs, rt);
24751             break;
24752         default:
24753             MIPS_INVAL("special_r6 muldiv");
24754             generate_exception_end(ctx, EXCP_RI);
24755             break;
24756         }
24757         break;
24758     case OPC_SELEQZ:
24759     case OPC_SELNEZ:
24760         gen_cond_move(ctx, op1, rd, rs, rt);
24761         break;
24762     case R6_OPC_CLO:
24763     case R6_OPC_CLZ:
24764         if (rt == 0 && sa == 1) {
24765             /*
24766              * Major opcode and function field is shared with preR6 MFHI/MTHI.
24767              * We need additionally to check other fields.
24768              */
24769             gen_cl(ctx, op1, rd, rs);
24770         } else {
24771             generate_exception_end(ctx, EXCP_RI);
24772         }
24773         break;
24774     case R6_OPC_SDBBP:
24775         if (is_uhi(extract32(ctx->opcode, 6, 20))) {
24776             gen_helper_do_semihosting(cpu_env);
24777         } else {
24778             if (ctx->hflags & MIPS_HFLAG_SBRI) {
24779                 generate_exception_end(ctx, EXCP_RI);
24780             } else {
24781                 generate_exception_end(ctx, EXCP_DBp);
24782             }
24783         }
24784         break;
24785 #if defined(TARGET_MIPS64)
24786     case OPC_DLSA:
24787         check_mips_64(ctx);
24788         gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
24789         break;
24790     case R6_OPC_DCLO:
24791     case R6_OPC_DCLZ:
24792         if (rt == 0 && sa == 1) {
24793             /*
24794              * Major opcode and function field is shared with preR6 MFHI/MTHI.
24795              * We need additionally to check other fields.
24796              */
24797             check_mips_64(ctx);
24798             gen_cl(ctx, op1, rd, rs);
24799         } else {
24800             generate_exception_end(ctx, EXCP_RI);
24801         }
24802         break;
24803     case OPC_DMULT:
24804     case OPC_DMULTU:
24805     case OPC_DDIV:
24806     case OPC_DDIVU:
24807 
24808         op2 = MASK_R6_MULDIV(ctx->opcode);
24809         switch (op2) {
24810         case R6_OPC_DMUL:
24811         case R6_OPC_DMUH:
24812         case R6_OPC_DMULU:
24813         case R6_OPC_DMUHU:
24814         case R6_OPC_DDIV:
24815         case R6_OPC_DMOD:
24816         case R6_OPC_DDIVU:
24817         case R6_OPC_DMODU:
24818             check_mips_64(ctx);
24819             gen_r6_muldiv(ctx, op2, rd, rs, rt);
24820             break;
24821         default:
24822             MIPS_INVAL("special_r6 muldiv");
24823             generate_exception_end(ctx, EXCP_RI);
24824             break;
24825         }
24826         break;
24827 #endif
24828     default:            /* Invalid */
24829         MIPS_INVAL("special_r6");
24830         generate_exception_end(ctx, EXCP_RI);
24831         break;
24832     }
24833 }
24834 
decode_opc_special_tx79(CPUMIPSState * env,DisasContext * ctx)24835 static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx)
24836 {
24837     int rs = extract32(ctx->opcode, 21, 5);
24838     int rt = extract32(ctx->opcode, 16, 5);
24839     int rd = extract32(ctx->opcode, 11, 5);
24840     uint32_t op1 = MASK_SPECIAL(ctx->opcode);
24841 
24842     switch (op1) {
24843     case OPC_MOVN:         /* Conditional move */
24844     case OPC_MOVZ:
24845         gen_cond_move(ctx, op1, rd, rs, rt);
24846         break;
24847     case OPC_MFHI:          /* Move from HI/LO */
24848     case OPC_MFLO:
24849         gen_HILO(ctx, op1, 0, rd);
24850         break;
24851     case OPC_MTHI:
24852     case OPC_MTLO:          /* Move to HI/LO */
24853         gen_HILO(ctx, op1, 0, rs);
24854         break;
24855     case OPC_MULT:
24856     case OPC_MULTU:
24857         gen_mul_txx9(ctx, op1, rd, rs, rt);
24858         break;
24859     case OPC_DIV:
24860     case OPC_DIVU:
24861         gen_muldiv(ctx, op1, 0, rs, rt);
24862         break;
24863 #if defined(TARGET_MIPS64)
24864     case OPC_DMULT:
24865     case OPC_DMULTU:
24866     case OPC_DDIV:
24867     case OPC_DDIVU:
24868         check_insn_opc_user_only(ctx, INSN_R5900);
24869         gen_muldiv(ctx, op1, 0, rs, rt);
24870         break;
24871 #endif
24872     case OPC_JR:
24873         gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
24874         break;
24875     default:            /* Invalid */
24876         MIPS_INVAL("special_tx79");
24877         generate_exception_end(ctx, EXCP_RI);
24878         break;
24879     }
24880 }
24881 
decode_opc_special_legacy(CPUMIPSState * env,DisasContext * ctx)24882 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
24883 {
24884     int rs, rt, rd, sa;
24885     uint32_t op1;
24886 
24887     rs = (ctx->opcode >> 21) & 0x1f;
24888     rt = (ctx->opcode >> 16) & 0x1f;
24889     rd = (ctx->opcode >> 11) & 0x1f;
24890     sa = (ctx->opcode >> 6) & 0x1f;
24891 
24892     op1 = MASK_SPECIAL(ctx->opcode);
24893     switch (op1) {
24894     case OPC_MOVN:         /* Conditional move */
24895     case OPC_MOVZ:
24896         check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
24897                    INSN_LOONGSON2E | INSN_LOONGSON2F);
24898         gen_cond_move(ctx, op1, rd, rs, rt);
24899         break;
24900     case OPC_MFHI:          /* Move from HI/LO */
24901     case OPC_MFLO:
24902         gen_HILO(ctx, op1, rs & 3, rd);
24903         break;
24904     case OPC_MTHI:
24905     case OPC_MTLO:          /* Move to HI/LO */
24906         gen_HILO(ctx, op1, rd & 3, rs);
24907         break;
24908     case OPC_MOVCI:
24909         check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
24910         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
24911             check_cp1_enabled(ctx);
24912             gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
24913                       (ctx->opcode >> 16) & 1);
24914         } else {
24915             generate_exception_err(ctx, EXCP_CpU, 1);
24916         }
24917         break;
24918     case OPC_MULT:
24919     case OPC_MULTU:
24920         if (sa) {
24921             check_insn(ctx, INSN_VR54XX);
24922             op1 = MASK_MUL_VR54XX(ctx->opcode);
24923             gen_mul_vr54xx(ctx, op1, rd, rs, rt);
24924         } else {
24925             gen_muldiv(ctx, op1, rd & 3, rs, rt);
24926         }
24927         break;
24928     case OPC_DIV:
24929     case OPC_DIVU:
24930         gen_muldiv(ctx, op1, 0, rs, rt);
24931         break;
24932 #if defined(TARGET_MIPS64)
24933     case OPC_DMULT:
24934     case OPC_DMULTU:
24935     case OPC_DDIV:
24936     case OPC_DDIVU:
24937         check_insn(ctx, ISA_MIPS3);
24938         check_mips_64(ctx);
24939         gen_muldiv(ctx, op1, 0, rs, rt);
24940         break;
24941 #endif
24942     case OPC_JR:
24943         gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
24944         break;
24945     case OPC_SPIM:
24946 #ifdef MIPS_STRICT_STANDARD
24947         MIPS_INVAL("SPIM");
24948         generate_exception_end(ctx, EXCP_RI);
24949 #else
24950         /* Implemented as RI exception for now. */
24951         MIPS_INVAL("spim (unofficial)");
24952         generate_exception_end(ctx, EXCP_RI);
24953 #endif
24954         break;
24955     default:            /* Invalid */
24956         MIPS_INVAL("special_legacy");
24957         generate_exception_end(ctx, EXCP_RI);
24958         break;
24959     }
24960 }
24961 
decode_opc_special(CPUMIPSState * env,DisasContext * ctx)24962 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
24963 {
24964     int rs, rt, rd, sa;
24965     uint32_t op1;
24966 
24967     rs = (ctx->opcode >> 21) & 0x1f;
24968     rt = (ctx->opcode >> 16) & 0x1f;
24969     rd = (ctx->opcode >> 11) & 0x1f;
24970     sa = (ctx->opcode >> 6) & 0x1f;
24971 
24972     op1 = MASK_SPECIAL(ctx->opcode);
24973     switch (op1) {
24974     case OPC_SLL:          /* Shift with immediate */
24975         if (sa == 5 && rd == 0 &&
24976             rs == 0 && rt == 0) { /* PAUSE */
24977             if ((ctx->insn_flags & ISA_MIPS32R6) &&
24978                 (ctx->hflags & MIPS_HFLAG_BMASK)) {
24979                 generate_exception_end(ctx, EXCP_RI);
24980                 break;
24981             }
24982         }
24983         /* Fallthrough */
24984     case OPC_SRA:
24985         gen_shift_imm(ctx, op1, rd, rt, sa);
24986         break;
24987     case OPC_SRL:
24988         switch ((ctx->opcode >> 21) & 0x1f) {
24989         case 1:
24990             /* rotr is decoded as srl on non-R2 CPUs */
24991             if (ctx->insn_flags & ISA_MIPS32R2) {
24992                 op1 = OPC_ROTR;
24993             }
24994             /* Fallthrough */
24995         case 0:
24996             gen_shift_imm(ctx, op1, rd, rt, sa);
24997             break;
24998         default:
24999             generate_exception_end(ctx, EXCP_RI);
25000             break;
25001         }
25002         break;
25003     case OPC_ADD:
25004     case OPC_ADDU:
25005     case OPC_SUB:
25006     case OPC_SUBU:
25007         gen_arith(ctx, op1, rd, rs, rt);
25008         break;
25009     case OPC_SLLV:         /* Shifts */
25010     case OPC_SRAV:
25011         gen_shift(ctx, op1, rd, rs, rt);
25012         break;
25013     case OPC_SRLV:
25014         switch ((ctx->opcode >> 6) & 0x1f) {
25015         case 1:
25016             /* rotrv is decoded as srlv on non-R2 CPUs */
25017             if (ctx->insn_flags & ISA_MIPS32R2) {
25018                 op1 = OPC_ROTRV;
25019             }
25020             /* Fallthrough */
25021         case 0:
25022             gen_shift(ctx, op1, rd, rs, rt);
25023             break;
25024         default:
25025             generate_exception_end(ctx, EXCP_RI);
25026             break;
25027         }
25028         break;
25029     case OPC_SLT:          /* Set on less than */
25030     case OPC_SLTU:
25031         gen_slt(ctx, op1, rd, rs, rt);
25032         break;
25033     case OPC_AND:          /* Logic*/
25034     case OPC_OR:
25035     case OPC_NOR:
25036     case OPC_XOR:
25037         gen_logic(ctx, op1, rd, rs, rt);
25038         break;
25039     case OPC_JALR:
25040         gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
25041         break;
25042     case OPC_TGE: /* Traps */
25043     case OPC_TGEU:
25044     case OPC_TLT:
25045     case OPC_TLTU:
25046     case OPC_TEQ:
25047     case OPC_TNE:
25048         check_insn(ctx, ISA_MIPS2);
25049         gen_trap(ctx, op1, rs, rt, -1);
25050         break;
25051     case OPC_LSA: /* OPC_PMON */
25052         if ((ctx->insn_flags & ISA_MIPS32R6) ||
25053             (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
25054             decode_opc_special_r6(env, ctx);
25055         } else {
25056             /* Pmon entry point, also R4010 selsl */
25057 #ifdef MIPS_STRICT_STANDARD
25058             MIPS_INVAL("PMON / selsl");
25059             generate_exception_end(ctx, EXCP_RI);
25060 #else
25061             gen_helper_0e0i(pmon, sa);
25062 #endif
25063         }
25064         break;
25065     case OPC_SYSCALL:
25066         generate_exception_end(ctx, EXCP_SYSCALL);
25067         break;
25068     case OPC_BREAK:
25069         generate_exception_end(ctx, EXCP_BREAK);
25070         break;
25071     case OPC_SYNC:
25072         check_insn(ctx, ISA_MIPS2);
25073         gen_sync(extract32(ctx->opcode, 6, 5));
25074         break;
25075 
25076 #if defined(TARGET_MIPS64)
25077         /* MIPS64 specific opcodes */
25078     case OPC_DSLL:
25079     case OPC_DSRA:
25080     case OPC_DSLL32:
25081     case OPC_DSRA32:
25082         check_insn(ctx, ISA_MIPS3);
25083         check_mips_64(ctx);
25084         gen_shift_imm(ctx, op1, rd, rt, sa);
25085         break;
25086     case OPC_DSRL:
25087         switch ((ctx->opcode >> 21) & 0x1f) {
25088         case 1:
25089             /* drotr is decoded as dsrl on non-R2 CPUs */
25090             if (ctx->insn_flags & ISA_MIPS32R2) {
25091                 op1 = OPC_DROTR;
25092             }
25093             /* Fallthrough */
25094         case 0:
25095             check_insn(ctx, ISA_MIPS3);
25096             check_mips_64(ctx);
25097             gen_shift_imm(ctx, op1, rd, rt, sa);
25098             break;
25099         default:
25100             generate_exception_end(ctx, EXCP_RI);
25101             break;
25102         }
25103         break;
25104     case OPC_DSRL32:
25105         switch ((ctx->opcode >> 21) & 0x1f) {
25106         case 1:
25107             /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
25108             if (ctx->insn_flags & ISA_MIPS32R2) {
25109                 op1 = OPC_DROTR32;
25110             }
25111             /* Fallthrough */
25112         case 0:
25113             check_insn(ctx, ISA_MIPS3);
25114             check_mips_64(ctx);
25115             gen_shift_imm(ctx, op1, rd, rt, sa);
25116             break;
25117         default:
25118             generate_exception_end(ctx, EXCP_RI);
25119             break;
25120         }
25121         break;
25122     case OPC_DADD:
25123     case OPC_DADDU:
25124     case OPC_DSUB:
25125     case OPC_DSUBU:
25126         check_insn(ctx, ISA_MIPS3);
25127         check_mips_64(ctx);
25128         gen_arith(ctx, op1, rd, rs, rt);
25129         break;
25130     case OPC_DSLLV:
25131     case OPC_DSRAV:
25132         check_insn(ctx, ISA_MIPS3);
25133         check_mips_64(ctx);
25134         gen_shift(ctx, op1, rd, rs, rt);
25135         break;
25136     case OPC_DSRLV:
25137         switch ((ctx->opcode >> 6) & 0x1f) {
25138         case 1:
25139             /* drotrv is decoded as dsrlv on non-R2 CPUs */
25140             if (ctx->insn_flags & ISA_MIPS32R2) {
25141                 op1 = OPC_DROTRV;
25142             }
25143             /* Fallthrough */
25144         case 0:
25145             check_insn(ctx, ISA_MIPS3);
25146             check_mips_64(ctx);
25147             gen_shift(ctx, op1, rd, rs, rt);
25148             break;
25149         default:
25150             generate_exception_end(ctx, EXCP_RI);
25151             break;
25152         }
25153         break;
25154     case OPC_DLSA:
25155         if ((ctx->insn_flags & ISA_MIPS32R6) ||
25156             (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
25157             decode_opc_special_r6(env, ctx);
25158         }
25159         break;
25160 #endif
25161     default:
25162         if (ctx->insn_flags & ISA_MIPS32R6) {
25163             decode_opc_special_r6(env, ctx);
25164         } else if (ctx->insn_flags & INSN_R5900) {
25165             decode_opc_special_tx79(env, ctx);
25166         } else {
25167             decode_opc_special_legacy(env, ctx);
25168         }
25169     }
25170 }
25171 
25172 
25173 #if defined(TARGET_MIPS64)
25174 
25175 /*
25176  *
25177  *           MMI (MultiMedia Interface) ASE instructions
25178  *           ===========================================
25179  */
25180 
25181 /*
25182  *          MMI instructions category: data communication
25183  *          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25184  *
25185  *   PCPYH    PEXCH    PEXTLB   PINTH    PPACB    PEXT5    PREVH
25186  *   PCPYLD   PEXCW    PEXTLH   PINTEH   PPACH    PPAC5    PROT3W
25187  *   PCPYUD   PEXEH    PEXTLW            PPACW
25188  *            PEXEW    PEXTUB
25189  *                     PEXTUH
25190  *                     PEXTUW
25191  */
25192 
25193 /*
25194  *  PCPYH rd, rt
25195  *
25196  *    Parallel Copy Halfword
25197  *
25198  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25199  *  +-----------+---------+---------+---------+---------+-----------+
25200  *  |    MMI    |0 0 0 0 0|   rt    |   rd    |  PCPYH  |    MMI3   |
25201  *  +-----------+---------+---------+---------+---------+-----------+
25202  */
gen_mmi_pcpyh(DisasContext * ctx)25203 static void gen_mmi_pcpyh(DisasContext *ctx)
25204 {
25205     uint32_t pd, rt, rd;
25206     uint32_t opcode;
25207 
25208     opcode = ctx->opcode;
25209 
25210     pd = extract32(opcode, 21, 5);
25211     rt = extract32(opcode, 16, 5);
25212     rd = extract32(opcode, 11, 5);
25213 
25214     if (unlikely(pd != 0)) {
25215         generate_exception_end(ctx, EXCP_RI);
25216     } else if (rd == 0) {
25217         /* nop */
25218     } else if (rt == 0) {
25219         tcg_gen_movi_i64(cpu_gpr[rd], 0);
25220         tcg_gen_movi_i64(cpu_mmr[rd], 0);
25221     } else {
25222         TCGv_i64 t0 = tcg_temp_new();
25223         TCGv_i64 t1 = tcg_temp_new();
25224         uint64_t mask = (1ULL << 16) - 1;
25225 
25226         tcg_gen_andi_i64(t0, cpu_gpr[rt], mask);
25227         tcg_gen_movi_i64(t1, 0);
25228         tcg_gen_or_i64(t1, t0, t1);
25229         tcg_gen_shli_i64(t0, t0, 16);
25230         tcg_gen_or_i64(t1, t0, t1);
25231         tcg_gen_shli_i64(t0, t0, 16);
25232         tcg_gen_or_i64(t1, t0, t1);
25233         tcg_gen_shli_i64(t0, t0, 16);
25234         tcg_gen_or_i64(t1, t0, t1);
25235 
25236         tcg_gen_mov_i64(cpu_gpr[rd], t1);
25237 
25238         tcg_gen_andi_i64(t0, cpu_mmr[rt], mask);
25239         tcg_gen_movi_i64(t1, 0);
25240         tcg_gen_or_i64(t1, t0, t1);
25241         tcg_gen_shli_i64(t0, t0, 16);
25242         tcg_gen_or_i64(t1, t0, t1);
25243         tcg_gen_shli_i64(t0, t0, 16);
25244         tcg_gen_or_i64(t1, t0, t1);
25245         tcg_gen_shli_i64(t0, t0, 16);
25246         tcg_gen_or_i64(t1, t0, t1);
25247 
25248         tcg_gen_mov_i64(cpu_mmr[rd], t1);
25249 
25250         tcg_temp_free(t0);
25251         tcg_temp_free(t1);
25252     }
25253 }
25254 
25255 /*
25256  *  PCPYLD rd, rs, rt
25257  *
25258  *    Parallel Copy Lower Doubleword
25259  *
25260  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25261  *  +-----------+---------+---------+---------+---------+-----------+
25262  *  |    MMI    |   rs    |   rt    |   rd    | PCPYLD  |    MMI2   |
25263  *  +-----------+---------+---------+---------+---------+-----------+
25264  */
gen_mmi_pcpyld(DisasContext * ctx)25265 static void gen_mmi_pcpyld(DisasContext *ctx)
25266 {
25267     uint32_t rs, rt, rd;
25268     uint32_t opcode;
25269 
25270     opcode = ctx->opcode;
25271 
25272     rs = extract32(opcode, 21, 5);
25273     rt = extract32(opcode, 16, 5);
25274     rd = extract32(opcode, 11, 5);
25275 
25276     if (rd == 0) {
25277         /* nop */
25278     } else {
25279         if (rs == 0) {
25280             tcg_gen_movi_i64(cpu_mmr[rd], 0);
25281         } else {
25282             tcg_gen_mov_i64(cpu_mmr[rd], cpu_gpr[rs]);
25283         }
25284         if (rt == 0) {
25285             tcg_gen_movi_i64(cpu_gpr[rd], 0);
25286         } else {
25287             if (rd != rt) {
25288                 tcg_gen_mov_i64(cpu_gpr[rd], cpu_gpr[rt]);
25289             }
25290         }
25291     }
25292 }
25293 
25294 /*
25295  *  PCPYUD rd, rs, rt
25296  *
25297  *    Parallel Copy Upper Doubleword
25298  *
25299  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25300  *  +-----------+---------+---------+---------+---------+-----------+
25301  *  |    MMI    |   rs    |   rt    |   rd    | PCPYUD  |    MMI3   |
25302  *  +-----------+---------+---------+---------+---------+-----------+
25303  */
gen_mmi_pcpyud(DisasContext * ctx)25304 static void gen_mmi_pcpyud(DisasContext *ctx)
25305 {
25306     uint32_t rs, rt, rd;
25307     uint32_t opcode;
25308 
25309     opcode = ctx->opcode;
25310 
25311     rs = extract32(opcode, 21, 5);
25312     rt = extract32(opcode, 16, 5);
25313     rd = extract32(opcode, 11, 5);
25314 
25315     if (rd == 0) {
25316         /* nop */
25317     } else {
25318         if (rs == 0) {
25319             tcg_gen_movi_i64(cpu_gpr[rd], 0);
25320         } else {
25321             tcg_gen_mov_i64(cpu_gpr[rd], cpu_mmr[rs]);
25322         }
25323         if (rt == 0) {
25324             tcg_gen_movi_i64(cpu_mmr[rd], 0);
25325         } else {
25326             if (rd != rt) {
25327                 tcg_gen_mov_i64(cpu_mmr[rd], cpu_mmr[rt]);
25328             }
25329         }
25330     }
25331 }
25332 
25333 #endif
25334 
25335 
25336 #if !defined(TARGET_MIPS64)
25337 
25338 /* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
25339 #define MXU_APTN1_A    0
25340 #define MXU_APTN1_S    1
25341 
25342 /* MXU accumulate add/subtract 2-bit pattern 'aptn2' */
25343 #define MXU_APTN2_AA    0
25344 #define MXU_APTN2_AS    1
25345 #define MXU_APTN2_SA    2
25346 #define MXU_APTN2_SS    3
25347 
25348 /* MXU execute add/subtract 2-bit pattern 'eptn2' */
25349 #define MXU_EPTN2_AA    0
25350 #define MXU_EPTN2_AS    1
25351 #define MXU_EPTN2_SA    2
25352 #define MXU_EPTN2_SS    3
25353 
25354 /* MXU operand getting pattern 'optn2' */
25355 #define MXU_OPTN2_PTN0  0
25356 #define MXU_OPTN2_PTN1  1
25357 #define MXU_OPTN2_PTN2  2
25358 #define MXU_OPTN2_PTN3  3
25359 /* alternative naming scheme for 'optn2' */
25360 #define MXU_OPTN2_WW    0
25361 #define MXU_OPTN2_LW    1
25362 #define MXU_OPTN2_HW    2
25363 #define MXU_OPTN2_XW    3
25364 
25365 /* MXU operand getting pattern 'optn3' */
25366 #define MXU_OPTN3_PTN0  0
25367 #define MXU_OPTN3_PTN1  1
25368 #define MXU_OPTN3_PTN2  2
25369 #define MXU_OPTN3_PTN3  3
25370 #define MXU_OPTN3_PTN4  4
25371 #define MXU_OPTN3_PTN5  5
25372 #define MXU_OPTN3_PTN6  6
25373 #define MXU_OPTN3_PTN7  7
25374 
25375 
25376 /*
25377  * S32I2M XRa, rb - Register move from GRF to XRF
25378  */
gen_mxu_s32i2m(DisasContext * ctx)25379 static void gen_mxu_s32i2m(DisasContext *ctx)
25380 {
25381     TCGv t0;
25382     uint32_t XRa, Rb;
25383 
25384     t0 = tcg_temp_new();
25385 
25386     XRa = extract32(ctx->opcode, 6, 5);
25387     Rb = extract32(ctx->opcode, 16, 5);
25388 
25389     gen_load_gpr(t0, Rb);
25390     if (XRa <= 15) {
25391         gen_store_mxu_gpr(t0, XRa);
25392     } else if (XRa == 16) {
25393         gen_store_mxu_cr(t0);
25394     }
25395 
25396     tcg_temp_free(t0);
25397 }
25398 
25399 /*
25400  * S32M2I XRa, rb - Register move from XRF to GRF
25401  */
gen_mxu_s32m2i(DisasContext * ctx)25402 static void gen_mxu_s32m2i(DisasContext *ctx)
25403 {
25404     TCGv t0;
25405     uint32_t XRa, Rb;
25406 
25407     t0 = tcg_temp_new();
25408 
25409     XRa = extract32(ctx->opcode, 6, 5);
25410     Rb = extract32(ctx->opcode, 16, 5);
25411 
25412     if (XRa <= 15) {
25413         gen_load_mxu_gpr(t0, XRa);
25414     } else if (XRa == 16) {
25415         gen_load_mxu_cr(t0);
25416     }
25417 
25418     gen_store_gpr(t0, Rb);
25419 
25420     tcg_temp_free(t0);
25421 }
25422 
25423 /*
25424  * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF
25425  */
gen_mxu_s8ldd(DisasContext * ctx)25426 static void gen_mxu_s8ldd(DisasContext *ctx)
25427 {
25428     TCGv t0, t1;
25429     uint32_t XRa, Rb, s8, optn3;
25430 
25431     t0 = tcg_temp_new();
25432     t1 = tcg_temp_new();
25433 
25434     XRa = extract32(ctx->opcode, 6, 4);
25435     s8 = extract32(ctx->opcode, 10, 8);
25436     optn3 = extract32(ctx->opcode, 18, 3);
25437     Rb = extract32(ctx->opcode, 21, 5);
25438 
25439     gen_load_gpr(t0, Rb);
25440     tcg_gen_addi_tl(t0, t0, (int8_t)s8);
25441 
25442     switch (optn3) {
25443     /* XRa[7:0] = tmp8 */
25444     case MXU_OPTN3_PTN0:
25445         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
25446         gen_load_mxu_gpr(t0, XRa);
25447         tcg_gen_deposit_tl(t0, t0, t1, 0, 8);
25448         break;
25449     /* XRa[15:8] = tmp8 */
25450     case MXU_OPTN3_PTN1:
25451         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
25452         gen_load_mxu_gpr(t0, XRa);
25453         tcg_gen_deposit_tl(t0, t0, t1, 8, 8);
25454         break;
25455     /* XRa[23:16] = tmp8 */
25456     case MXU_OPTN3_PTN2:
25457         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
25458         gen_load_mxu_gpr(t0, XRa);
25459         tcg_gen_deposit_tl(t0, t0, t1, 16, 8);
25460         break;
25461     /* XRa[31:24] = tmp8 */
25462     case MXU_OPTN3_PTN3:
25463         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
25464         gen_load_mxu_gpr(t0, XRa);
25465         tcg_gen_deposit_tl(t0, t0, t1, 24, 8);
25466         break;
25467     /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
25468     case MXU_OPTN3_PTN4:
25469         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
25470         tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
25471         break;
25472     /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
25473     case MXU_OPTN3_PTN5:
25474         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
25475         tcg_gen_shli_tl(t1, t1, 8);
25476         tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
25477         break;
25478     /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
25479     case MXU_OPTN3_PTN6:
25480         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_SB);
25481         tcg_gen_mov_tl(t0, t1);
25482         tcg_gen_andi_tl(t0, t0, 0xFF00FFFF);
25483         tcg_gen_shli_tl(t1, t1, 16);
25484         tcg_gen_or_tl(t0, t0, t1);
25485         break;
25486     /* XRa = {tmp8, tmp8, tmp8, tmp8} */
25487     case MXU_OPTN3_PTN7:
25488         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
25489         tcg_gen_deposit_tl(t1, t1, t1, 8, 8);
25490         tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
25491         break;
25492     }
25493 
25494     gen_store_mxu_gpr(t0, XRa);
25495 
25496     tcg_temp_free(t0);
25497     tcg_temp_free(t1);
25498 }
25499 
25500 /*
25501  * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication
25502  */
gen_mxu_d16mul(DisasContext * ctx)25503 static void gen_mxu_d16mul(DisasContext *ctx)
25504 {
25505     TCGv t0, t1, t2, t3;
25506     uint32_t XRa, XRb, XRc, XRd, optn2;
25507 
25508     t0 = tcg_temp_new();
25509     t1 = tcg_temp_new();
25510     t2 = tcg_temp_new();
25511     t3 = tcg_temp_new();
25512 
25513     XRa = extract32(ctx->opcode, 6, 4);
25514     XRb = extract32(ctx->opcode, 10, 4);
25515     XRc = extract32(ctx->opcode, 14, 4);
25516     XRd = extract32(ctx->opcode, 18, 4);
25517     optn2 = extract32(ctx->opcode, 22, 2);
25518 
25519     gen_load_mxu_gpr(t1, XRb);
25520     tcg_gen_sextract_tl(t0, t1, 0, 16);
25521     tcg_gen_sextract_tl(t1, t1, 16, 16);
25522     gen_load_mxu_gpr(t3, XRc);
25523     tcg_gen_sextract_tl(t2, t3, 0, 16);
25524     tcg_gen_sextract_tl(t3, t3, 16, 16);
25525 
25526     switch (optn2) {
25527     case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
25528         tcg_gen_mul_tl(t3, t1, t3);
25529         tcg_gen_mul_tl(t2, t0, t2);
25530         break;
25531     case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
25532         tcg_gen_mul_tl(t3, t0, t3);
25533         tcg_gen_mul_tl(t2, t0, t2);
25534         break;
25535     case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
25536         tcg_gen_mul_tl(t3, t1, t3);
25537         tcg_gen_mul_tl(t2, t1, t2);
25538         break;
25539     case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
25540         tcg_gen_mul_tl(t3, t0, t3);
25541         tcg_gen_mul_tl(t2, t1, t2);
25542         break;
25543     }
25544     gen_store_mxu_gpr(t3, XRa);
25545     gen_store_mxu_gpr(t2, XRd);
25546 
25547     tcg_temp_free(t0);
25548     tcg_temp_free(t1);
25549     tcg_temp_free(t2);
25550     tcg_temp_free(t3);
25551 }
25552 
25553 /*
25554  * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply
25555  *                                           and accumulate
25556  */
gen_mxu_d16mac(DisasContext * ctx)25557 static void gen_mxu_d16mac(DisasContext *ctx)
25558 {
25559     TCGv t0, t1, t2, t3;
25560     uint32_t XRa, XRb, XRc, XRd, optn2, aptn2;
25561 
25562     t0 = tcg_temp_new();
25563     t1 = tcg_temp_new();
25564     t2 = tcg_temp_new();
25565     t3 = tcg_temp_new();
25566 
25567     XRa = extract32(ctx->opcode, 6, 4);
25568     XRb = extract32(ctx->opcode, 10, 4);
25569     XRc = extract32(ctx->opcode, 14, 4);
25570     XRd = extract32(ctx->opcode, 18, 4);
25571     optn2 = extract32(ctx->opcode, 22, 2);
25572     aptn2 = extract32(ctx->opcode, 24, 2);
25573 
25574     gen_load_mxu_gpr(t1, XRb);
25575     tcg_gen_sextract_tl(t0, t1, 0, 16);
25576     tcg_gen_sextract_tl(t1, t1, 16, 16);
25577 
25578     gen_load_mxu_gpr(t3, XRc);
25579     tcg_gen_sextract_tl(t2, t3, 0, 16);
25580     tcg_gen_sextract_tl(t3, t3, 16, 16);
25581 
25582     switch (optn2) {
25583     case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
25584         tcg_gen_mul_tl(t3, t1, t3);
25585         tcg_gen_mul_tl(t2, t0, t2);
25586         break;
25587     case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
25588         tcg_gen_mul_tl(t3, t0, t3);
25589         tcg_gen_mul_tl(t2, t0, t2);
25590         break;
25591     case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
25592         tcg_gen_mul_tl(t3, t1, t3);
25593         tcg_gen_mul_tl(t2, t1, t2);
25594         break;
25595     case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
25596         tcg_gen_mul_tl(t3, t0, t3);
25597         tcg_gen_mul_tl(t2, t1, t2);
25598         break;
25599     }
25600     gen_load_mxu_gpr(t0, XRa);
25601     gen_load_mxu_gpr(t1, XRd);
25602 
25603     switch (aptn2) {
25604     case MXU_APTN2_AA:
25605         tcg_gen_add_tl(t3, t0, t3);
25606         tcg_gen_add_tl(t2, t1, t2);
25607         break;
25608     case MXU_APTN2_AS:
25609         tcg_gen_add_tl(t3, t0, t3);
25610         tcg_gen_sub_tl(t2, t1, t2);
25611         break;
25612     case MXU_APTN2_SA:
25613         tcg_gen_sub_tl(t3, t0, t3);
25614         tcg_gen_add_tl(t2, t1, t2);
25615         break;
25616     case MXU_APTN2_SS:
25617         tcg_gen_sub_tl(t3, t0, t3);
25618         tcg_gen_sub_tl(t2, t1, t2);
25619         break;
25620     }
25621     gen_store_mxu_gpr(t3, XRa);
25622     gen_store_mxu_gpr(t2, XRd);
25623 
25624     tcg_temp_free(t0);
25625     tcg_temp_free(t1);
25626     tcg_temp_free(t2);
25627     tcg_temp_free(t3);
25628 }
25629 
25630 /*
25631  * Q8MUL   XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply
25632  * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply
25633  */
gen_mxu_q8mul_q8mulsu(DisasContext * ctx)25634 static void gen_mxu_q8mul_q8mulsu(DisasContext *ctx)
25635 {
25636     TCGv t0, t1, t2, t3, t4, t5, t6, t7;
25637     uint32_t XRa, XRb, XRc, XRd, sel;
25638 
25639     t0 = tcg_temp_new();
25640     t1 = tcg_temp_new();
25641     t2 = tcg_temp_new();
25642     t3 = tcg_temp_new();
25643     t4 = tcg_temp_new();
25644     t5 = tcg_temp_new();
25645     t6 = tcg_temp_new();
25646     t7 = tcg_temp_new();
25647 
25648     XRa = extract32(ctx->opcode, 6, 4);
25649     XRb = extract32(ctx->opcode, 10, 4);
25650     XRc = extract32(ctx->opcode, 14, 4);
25651     XRd = extract32(ctx->opcode, 18, 4);
25652     sel = extract32(ctx->opcode, 22, 2);
25653 
25654     gen_load_mxu_gpr(t3, XRb);
25655     gen_load_mxu_gpr(t7, XRc);
25656 
25657     if (sel == 0x2) {
25658         /* Q8MULSU */
25659         tcg_gen_ext8s_tl(t0, t3);
25660         tcg_gen_shri_tl(t3, t3, 8);
25661         tcg_gen_ext8s_tl(t1, t3);
25662         tcg_gen_shri_tl(t3, t3, 8);
25663         tcg_gen_ext8s_tl(t2, t3);
25664         tcg_gen_shri_tl(t3, t3, 8);
25665         tcg_gen_ext8s_tl(t3, t3);
25666     } else {
25667         /* Q8MUL */
25668         tcg_gen_ext8u_tl(t0, t3);
25669         tcg_gen_shri_tl(t3, t3, 8);
25670         tcg_gen_ext8u_tl(t1, t3);
25671         tcg_gen_shri_tl(t3, t3, 8);
25672         tcg_gen_ext8u_tl(t2, t3);
25673         tcg_gen_shri_tl(t3, t3, 8);
25674         tcg_gen_ext8u_tl(t3, t3);
25675     }
25676 
25677     tcg_gen_ext8u_tl(t4, t7);
25678     tcg_gen_shri_tl(t7, t7, 8);
25679     tcg_gen_ext8u_tl(t5, t7);
25680     tcg_gen_shri_tl(t7, t7, 8);
25681     tcg_gen_ext8u_tl(t6, t7);
25682     tcg_gen_shri_tl(t7, t7, 8);
25683     tcg_gen_ext8u_tl(t7, t7);
25684 
25685     tcg_gen_mul_tl(t0, t0, t4);
25686     tcg_gen_mul_tl(t1, t1, t5);
25687     tcg_gen_mul_tl(t2, t2, t6);
25688     tcg_gen_mul_tl(t3, t3, t7);
25689 
25690     tcg_gen_andi_tl(t0, t0, 0xFFFF);
25691     tcg_gen_andi_tl(t1, t1, 0xFFFF);
25692     tcg_gen_andi_tl(t2, t2, 0xFFFF);
25693     tcg_gen_andi_tl(t3, t3, 0xFFFF);
25694 
25695     tcg_gen_shli_tl(t1, t1, 16);
25696     tcg_gen_shli_tl(t3, t3, 16);
25697 
25698     tcg_gen_or_tl(t0, t0, t1);
25699     tcg_gen_or_tl(t1, t2, t3);
25700 
25701     gen_store_mxu_gpr(t0, XRd);
25702     gen_store_mxu_gpr(t1, XRa);
25703 
25704     tcg_temp_free(t0);
25705     tcg_temp_free(t1);
25706     tcg_temp_free(t2);
25707     tcg_temp_free(t3);
25708     tcg_temp_free(t4);
25709     tcg_temp_free(t5);
25710     tcg_temp_free(t6);
25711     tcg_temp_free(t7);
25712 }
25713 
25714 /*
25715  * S32LDD  XRa, Rb, S12 - Load a word from memory to XRF
25716  * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF, reversed byte seq.
25717  */
gen_mxu_s32ldd_s32lddr(DisasContext * ctx)25718 static void gen_mxu_s32ldd_s32lddr(DisasContext *ctx)
25719 {
25720     TCGv t0, t1;
25721     uint32_t XRa, Rb, s12, sel;
25722 
25723     t0 = tcg_temp_new();
25724     t1 = tcg_temp_new();
25725 
25726     XRa = extract32(ctx->opcode, 6, 4);
25727     s12 = extract32(ctx->opcode, 10, 10);
25728     sel = extract32(ctx->opcode, 20, 1);
25729     Rb = extract32(ctx->opcode, 21, 5);
25730 
25731     gen_load_gpr(t0, Rb);
25732 
25733     tcg_gen_movi_tl(t1, s12);
25734     tcg_gen_shli_tl(t1, t1, 2);
25735     if (s12 & 0x200) {
25736         tcg_gen_ori_tl(t1, t1, 0xFFFFF000);
25737     }
25738     tcg_gen_add_tl(t1, t0, t1);
25739     tcg_gen_qemu_ld_tl(t1, t1, ctx->mem_idx, MO_SL);
25740 
25741     if (sel == 1) {
25742         /* S32LDDR */
25743         tcg_gen_bswap32_tl(t1, t1);
25744     }
25745     gen_store_mxu_gpr(t1, XRa);
25746 
25747     tcg_temp_free(t0);
25748     tcg_temp_free(t1);
25749 }
25750 
25751 
25752 /*
25753  *                 MXU instruction category: logic
25754  *                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25755  *
25756  *               S32NOR    S32AND    S32OR    S32XOR
25757  */
25758 
25759 /*
25760  *  S32NOR XRa, XRb, XRc
25761  *    Update XRa with the result of logical bitwise 'nor' operation
25762  *    applied to the content of XRb and XRc.
25763  *
25764  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25765  *  +-----------+---------+-----+-------+-------+-------+-----------+
25766  *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
25767  *  +-----------+---------+-----+-------+-------+-------+-----------+
25768  */
gen_mxu_S32NOR(DisasContext * ctx)25769 static void gen_mxu_S32NOR(DisasContext *ctx)
25770 {
25771     uint32_t pad, XRc, XRb, XRa;
25772 
25773     pad = extract32(ctx->opcode, 21, 5);
25774     XRc = extract32(ctx->opcode, 14, 4);
25775     XRb = extract32(ctx->opcode, 10, 4);
25776     XRa = extract32(ctx->opcode,  6, 4);
25777 
25778     if (unlikely(pad != 0)) {
25779         /* opcode padding incorrect -> do nothing */
25780     } else if (unlikely(XRa == 0)) {
25781         /* destination is zero register -> do nothing */
25782     } else if (unlikely((XRb == 0) && (XRc == 0))) {
25783         /* both operands zero registers -> just set destination to all 1s */
25784         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0xFFFFFFFF);
25785     } else if (unlikely(XRb == 0)) {
25786         /* XRb zero register -> just set destination to the negation of XRc */
25787         tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25788     } else if (unlikely(XRc == 0)) {
25789         /* XRa zero register -> just set destination to the negation of XRb */
25790         tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25791     } else if (unlikely(XRb == XRc)) {
25792         /* both operands same -> just set destination to the negation of XRb */
25793         tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25794     } else {
25795         /* the most general case */
25796         tcg_gen_nor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
25797     }
25798 }
25799 
25800 /*
25801  *  S32AND XRa, XRb, XRc
25802  *    Update XRa with the result of logical bitwise 'and' operation
25803  *    applied to the content of XRb and XRc.
25804  *
25805  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25806  *  +-----------+---------+-----+-------+-------+-------+-----------+
25807  *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
25808  *  +-----------+---------+-----+-------+-------+-------+-----------+
25809  */
gen_mxu_S32AND(DisasContext * ctx)25810 static void gen_mxu_S32AND(DisasContext *ctx)
25811 {
25812     uint32_t pad, XRc, XRb, XRa;
25813 
25814     pad = extract32(ctx->opcode, 21, 5);
25815     XRc = extract32(ctx->opcode, 14, 4);
25816     XRb = extract32(ctx->opcode, 10, 4);
25817     XRa = extract32(ctx->opcode,  6, 4);
25818 
25819     if (unlikely(pad != 0)) {
25820         /* opcode padding incorrect -> do nothing */
25821     } else if (unlikely(XRa == 0)) {
25822         /* destination is zero register -> do nothing */
25823     } else if (unlikely((XRb == 0) || (XRc == 0))) {
25824         /* one of operands zero register -> just set destination to all 0s */
25825         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25826     } else if (unlikely(XRb == XRc)) {
25827         /* both operands same -> just set destination to one of them */
25828         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25829     } else {
25830         /* the most general case */
25831         tcg_gen_and_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
25832     }
25833 }
25834 
25835 /*
25836  *  S32OR XRa, XRb, XRc
25837  *    Update XRa with the result of logical bitwise 'or' operation
25838  *    applied to the content of XRb and XRc.
25839  *
25840  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25841  *  +-----------+---------+-----+-------+-------+-------+-----------+
25842  *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
25843  *  +-----------+---------+-----+-------+-------+-------+-----------+
25844  */
gen_mxu_S32OR(DisasContext * ctx)25845 static void gen_mxu_S32OR(DisasContext *ctx)
25846 {
25847     uint32_t pad, XRc, XRb, XRa;
25848 
25849     pad = extract32(ctx->opcode, 21, 5);
25850     XRc = extract32(ctx->opcode, 14, 4);
25851     XRb = extract32(ctx->opcode, 10, 4);
25852     XRa = extract32(ctx->opcode,  6, 4);
25853 
25854     if (unlikely(pad != 0)) {
25855         /* opcode padding incorrect -> do nothing */
25856     } else if (unlikely(XRa == 0)) {
25857         /* destination is zero register -> do nothing */
25858     } else if (unlikely((XRb == 0) && (XRc == 0))) {
25859         /* both operands zero registers -> just set destination to all 0s */
25860         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25861     } else if (unlikely(XRb == 0)) {
25862         /* XRb zero register -> just set destination to the content of XRc */
25863         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25864     } else if (unlikely(XRc == 0)) {
25865         /* XRc zero register -> just set destination to the content of XRb */
25866         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25867     } else if (unlikely(XRb == XRc)) {
25868         /* both operands same -> just set destination to one of them */
25869         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25870     } else {
25871         /* the most general case */
25872         tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
25873     }
25874 }
25875 
25876 /*
25877  *  S32XOR XRa, XRb, XRc
25878  *    Update XRa with the result of logical bitwise 'xor' operation
25879  *    applied to the content of XRb and XRc.
25880  *
25881  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25882  *  +-----------+---------+-----+-------+-------+-------+-----------+
25883  *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
25884  *  +-----------+---------+-----+-------+-------+-------+-----------+
25885  */
gen_mxu_S32XOR(DisasContext * ctx)25886 static void gen_mxu_S32XOR(DisasContext *ctx)
25887 {
25888     uint32_t pad, XRc, XRb, XRa;
25889 
25890     pad = extract32(ctx->opcode, 21, 5);
25891     XRc = extract32(ctx->opcode, 14, 4);
25892     XRb = extract32(ctx->opcode, 10, 4);
25893     XRa = extract32(ctx->opcode,  6, 4);
25894 
25895     if (unlikely(pad != 0)) {
25896         /* opcode padding incorrect -> do nothing */
25897     } else if (unlikely(XRa == 0)) {
25898         /* destination is zero register -> do nothing */
25899     } else if (unlikely((XRb == 0) && (XRc == 0))) {
25900         /* both operands zero registers -> just set destination to all 0s */
25901         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25902     } else if (unlikely(XRb == 0)) {
25903         /* XRb zero register -> just set destination to the content of XRc */
25904         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25905     } else if (unlikely(XRc == 0)) {
25906         /* XRc zero register -> just set destination to the content of XRb */
25907         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25908     } else if (unlikely(XRb == XRc)) {
25909         /* both operands same -> just set destination to all 0s */
25910         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25911     } else {
25912         /* the most general case */
25913         tcg_gen_xor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
25914     }
25915 }
25916 
25917 
25918 /*
25919  *                   MXU instruction category max/min
25920  *                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25921  *
25922  *                     S32MAX     D16MAX     Q8MAX
25923  *                     S32MIN     D16MIN     Q8MIN
25924  */
25925 
25926 /*
25927  *  S32MAX XRa, XRb, XRc
25928  *    Update XRa with the maximum of signed 32-bit integers contained
25929  *    in XRb and XRc.
25930  *
25931  *  S32MIN XRa, XRb, XRc
25932  *    Update XRa with the minimum of signed 32-bit integers contained
25933  *    in XRb and XRc.
25934  *
25935  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25936  *  +-----------+---------+-----+-------+-------+-------+-----------+
25937  *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL00|
25938  *  +-----------+---------+-----+-------+-------+-------+-----------+
25939  */
gen_mxu_S32MAX_S32MIN(DisasContext * ctx)25940 static void gen_mxu_S32MAX_S32MIN(DisasContext *ctx)
25941 {
25942     uint32_t pad, opc, XRc, XRb, XRa;
25943 
25944     pad = extract32(ctx->opcode, 21, 5);
25945     opc = extract32(ctx->opcode, 18, 3);
25946     XRc = extract32(ctx->opcode, 14, 4);
25947     XRb = extract32(ctx->opcode, 10, 4);
25948     XRa = extract32(ctx->opcode,  6, 4);
25949 
25950     if (unlikely(pad != 0)) {
25951         /* opcode padding incorrect -> do nothing */
25952     } else if (unlikely(XRa == 0)) {
25953         /* destination is zero register -> do nothing */
25954     } else if (unlikely((XRb == 0) && (XRc == 0))) {
25955         /* both operands zero registers -> just set destination to zero */
25956         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25957     } else if (unlikely((XRb == 0) || (XRc == 0))) {
25958         /* exactly one operand is zero register - find which one is not...*/
25959         uint32_t XRx = XRb ? XRb : XRc;
25960         /* ...and do max/min operation with one operand 0 */
25961         if (opc == OPC_MXU_S32MAX) {
25962             tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
25963         } else {
25964             tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
25965         }
25966     } else if (unlikely(XRb == XRc)) {
25967         /* both operands same -> just set destination to one of them */
25968         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25969     } else {
25970         /* the most general case */
25971         if (opc == OPC_MXU_S32MAX) {
25972             tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
25973                                                mxu_gpr[XRc - 1]);
25974         } else {
25975             tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
25976                                                mxu_gpr[XRc - 1]);
25977         }
25978     }
25979 }
25980 
25981 /*
25982  *  D16MAX
25983  *    Update XRa with the 16-bit-wise maximums of signed integers
25984  *    contained in XRb and XRc.
25985  *
25986  *  D16MIN
25987  *    Update XRa with the 16-bit-wise minimums of signed integers
25988  *    contained in XRb and XRc.
25989  *
25990  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25991  *  +-----------+---------+-----+-------+-------+-------+-----------+
25992  *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL00|
25993  *  +-----------+---------+-----+-------+-------+-------+-----------+
25994  */
gen_mxu_D16MAX_D16MIN(DisasContext * ctx)25995 static void gen_mxu_D16MAX_D16MIN(DisasContext *ctx)
25996 {
25997     uint32_t pad, opc, XRc, XRb, XRa;
25998 
25999     pad = extract32(ctx->opcode, 21, 5);
26000     opc = extract32(ctx->opcode, 18, 3);
26001     XRc = extract32(ctx->opcode, 14, 4);
26002     XRb = extract32(ctx->opcode, 10, 4);
26003     XRa = extract32(ctx->opcode,  6, 4);
26004 
26005     if (unlikely(pad != 0)) {
26006         /* opcode padding incorrect -> do nothing */
26007     } else if (unlikely(XRc == 0)) {
26008         /* destination is zero register -> do nothing */
26009     } else if (unlikely((XRb == 0) && (XRa == 0))) {
26010         /* both operands zero registers -> just set destination to zero */
26011         tcg_gen_movi_i32(mxu_gpr[XRc - 1], 0);
26012     } else if (unlikely((XRb == 0) || (XRa == 0))) {
26013         /* exactly one operand is zero register - find which one is not...*/
26014         uint32_t XRx = XRb ? XRb : XRc;
26015         /* ...and do half-word-wise max/min with one operand 0 */
26016         TCGv_i32 t0 = tcg_temp_new();
26017         TCGv_i32 t1 = tcg_const_i32(0);
26018 
26019         /* the left half-word first */
26020         tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFFFF0000);
26021         if (opc == OPC_MXU_D16MAX) {
26022             tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
26023         } else {
26024             tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
26025         }
26026 
26027         /* the right half-word */
26028         tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0x0000FFFF);
26029         /* move half-words to the leftmost position */
26030         tcg_gen_shli_i32(t0, t0, 16);
26031         /* t0 will be max/min of t0 and t1 */
26032         if (opc == OPC_MXU_D16MAX) {
26033             tcg_gen_smax_i32(t0, t0, t1);
26034         } else {
26035             tcg_gen_smin_i32(t0, t0, t1);
26036         }
26037         /* return resulting half-words to its original position */
26038         tcg_gen_shri_i32(t0, t0, 16);
26039         /* finally update the destination */
26040         tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
26041 
26042         tcg_temp_free(t1);
26043         tcg_temp_free(t0);
26044     } else if (unlikely(XRb == XRc)) {
26045         /* both operands same -> just set destination to one of them */
26046         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
26047     } else {
26048         /* the most general case */
26049         TCGv_i32 t0 = tcg_temp_new();
26050         TCGv_i32 t1 = tcg_temp_new();
26051 
26052         /* the left half-word first */
26053         tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFFFF0000);
26054         tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
26055         if (opc == OPC_MXU_D16MAX) {
26056             tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
26057         } else {
26058             tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
26059         }
26060 
26061         /* the right half-word */
26062         tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
26063         tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0x0000FFFF);
26064         /* move half-words to the leftmost position */
26065         tcg_gen_shli_i32(t0, t0, 16);
26066         tcg_gen_shli_i32(t1, t1, 16);
26067         /* t0 will be max/min of t0 and t1 */
26068         if (opc == OPC_MXU_D16MAX) {
26069             tcg_gen_smax_i32(t0, t0, t1);
26070         } else {
26071             tcg_gen_smin_i32(t0, t0, t1);
26072         }
26073         /* return resulting half-words to its original position */
26074         tcg_gen_shri_i32(t0, t0, 16);
26075         /* finally update the destination */
26076         tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
26077 
26078         tcg_temp_free(t1);
26079         tcg_temp_free(t0);
26080     }
26081 }
26082 
26083 /*
26084  *  Q8MAX
26085  *    Update XRa with the 8-bit-wise maximums of signed integers
26086  *    contained in XRb and XRc.
26087  *
26088  *  Q8MIN
26089  *    Update XRa with the 8-bit-wise minimums of signed integers
26090  *    contained in XRb and XRc.
26091  *
26092  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26093  *  +-----------+---------+-----+-------+-------+-------+-----------+
26094  *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL00|
26095  *  +-----------+---------+-----+-------+-------+-------+-----------+
26096  */
gen_mxu_Q8MAX_Q8MIN(DisasContext * ctx)26097 static void gen_mxu_Q8MAX_Q8MIN(DisasContext *ctx)
26098 {
26099     uint32_t pad, opc, XRc, XRb, XRa;
26100 
26101     pad = extract32(ctx->opcode, 21, 5);
26102     opc = extract32(ctx->opcode, 18, 3);
26103     XRc = extract32(ctx->opcode, 14, 4);
26104     XRb = extract32(ctx->opcode, 10, 4);
26105     XRa = extract32(ctx->opcode,  6, 4);
26106 
26107     if (unlikely(pad != 0)) {
26108         /* opcode padding incorrect -> do nothing */
26109     } else if (unlikely(XRa == 0)) {
26110         /* destination is zero register -> do nothing */
26111     } else if (unlikely((XRb == 0) && (XRc == 0))) {
26112         /* both operands zero registers -> just set destination to zero */
26113         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
26114     } else if (unlikely((XRb == 0) || (XRc == 0))) {
26115         /* exactly one operand is zero register - make it be the first...*/
26116         uint32_t XRx = XRb ? XRb : XRc;
26117         /* ...and do byte-wise max/min with one operand 0 */
26118         TCGv_i32 t0 = tcg_temp_new();
26119         TCGv_i32 t1 = tcg_const_i32(0);
26120         int32_t i;
26121 
26122         /* the leftmost byte (byte 3) first */
26123         tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF000000);
26124         if (opc == OPC_MXU_Q8MAX) {
26125             tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
26126         } else {
26127             tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
26128         }
26129 
26130         /* bytes 2, 1, 0 */
26131         for (i = 2; i >= 0; i--) {
26132             /* extract the byte */
26133             tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF << (8 * i));
26134             /* move the byte to the leftmost position */
26135             tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
26136             /* t0 will be max/min of t0 and t1 */
26137             if (opc == OPC_MXU_Q8MAX) {
26138                 tcg_gen_smax_i32(t0, t0, t1);
26139             } else {
26140                 tcg_gen_smin_i32(t0, t0, t1);
26141             }
26142             /* return resulting byte to its original position */
26143             tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
26144             /* finally update the destination */
26145             tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
26146         }
26147 
26148         tcg_temp_free(t1);
26149         tcg_temp_free(t0);
26150     } else if (unlikely(XRb == XRc)) {
26151         /* both operands same -> just set destination to one of them */
26152         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
26153     } else {
26154         /* the most general case */
26155         TCGv_i32 t0 = tcg_temp_new();
26156         TCGv_i32 t1 = tcg_temp_new();
26157         int32_t i;
26158 
26159         /* the leftmost bytes (bytes 3) first */
26160         tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF000000);
26161         tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
26162         if (opc == OPC_MXU_Q8MAX) {
26163             tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
26164         } else {
26165             tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
26166         }
26167 
26168         /* bytes 2, 1, 0 */
26169         for (i = 2; i >= 0; i--) {
26170             /* extract corresponding bytes */
26171             tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF << (8 * i));
26172             tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF << (8 * i));
26173             /* move the bytes to the leftmost position */
26174             tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
26175             tcg_gen_shli_i32(t1, t1, 8 * (3 - i));
26176             /* t0 will be max/min of t0 and t1 */
26177             if (opc == OPC_MXU_Q8MAX) {
26178                 tcg_gen_smax_i32(t0, t0, t1);
26179             } else {
26180                 tcg_gen_smin_i32(t0, t0, t1);
26181             }
26182             /* return resulting byte to its original position */
26183             tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
26184             /* finally update the destination */
26185             tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
26186         }
26187 
26188         tcg_temp_free(t1);
26189         tcg_temp_free(t0);
26190     }
26191 }
26192 
26193 
26194 /*
26195  *                 MXU instruction category: align
26196  *                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
26197  *
26198  *                       S32ALN     S32ALNI
26199  */
26200 
26201 /*
26202  *  S32ALNI XRc, XRb, XRa, optn3
26203  *    Arrange bytes from XRb and XRc according to one of five sets of
26204  *    rules determined by optn3, and place the result in XRa.
26205  *
26206  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26207  *  +-----------+-----+---+-----+-------+-------+-------+-----------+
26208  *  |  SPECIAL2 |optn3|0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
26209  *  +-----------+-----+---+-----+-------+-------+-------+-----------+
26210  *
26211  */
gen_mxu_S32ALNI(DisasContext * ctx)26212 static void gen_mxu_S32ALNI(DisasContext *ctx)
26213 {
26214     uint32_t optn3, pad, XRc, XRb, XRa;
26215 
26216     optn3 = extract32(ctx->opcode,  23, 3);
26217     pad   = extract32(ctx->opcode,  21, 2);
26218     XRc   = extract32(ctx->opcode, 14, 4);
26219     XRb   = extract32(ctx->opcode, 10, 4);
26220     XRa   = extract32(ctx->opcode,  6, 4);
26221 
26222     if (unlikely(pad != 0)) {
26223         /* opcode padding incorrect -> do nothing */
26224     } else if (unlikely(XRa == 0)) {
26225         /* destination is zero register -> do nothing */
26226     } else if (unlikely((XRb == 0) && (XRc == 0))) {
26227         /* both operands zero registers -> just set destination to all 0s */
26228         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
26229     } else if (unlikely(XRb == 0)) {
26230         /* XRb zero register -> just appropriatelly shift XRc into XRa */
26231         switch (optn3) {
26232         case MXU_OPTN3_PTN0:
26233             tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
26234             break;
26235         case MXU_OPTN3_PTN1:
26236         case MXU_OPTN3_PTN2:
26237         case MXU_OPTN3_PTN3:
26238             tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1],
26239                              8 * (4 - optn3));
26240             break;
26241         case MXU_OPTN3_PTN4:
26242             tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
26243             break;
26244         }
26245     } else if (unlikely(XRc == 0)) {
26246         /* XRc zero register -> just appropriatelly shift XRb into XRa */
26247         switch (optn3) {
26248         case MXU_OPTN3_PTN0:
26249             tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
26250             break;
26251         case MXU_OPTN3_PTN1:
26252         case MXU_OPTN3_PTN2:
26253         case MXU_OPTN3_PTN3:
26254             tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
26255             break;
26256         case MXU_OPTN3_PTN4:
26257             tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
26258             break;
26259         }
26260     } else if (unlikely(XRb == XRc)) {
26261         /* both operands same -> just rotation or moving from any of them */
26262         switch (optn3) {
26263         case MXU_OPTN3_PTN0:
26264         case MXU_OPTN3_PTN4:
26265             tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
26266             break;
26267         case MXU_OPTN3_PTN1:
26268         case MXU_OPTN3_PTN2:
26269         case MXU_OPTN3_PTN3:
26270             tcg_gen_rotli_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
26271             break;
26272         }
26273     } else {
26274         /* the most general case */
26275         switch (optn3) {
26276         case MXU_OPTN3_PTN0:
26277             {
26278                 /*                                         */
26279                 /*         XRb                XRc          */
26280                 /*  +---------------+                      */
26281                 /*  | A   B   C   D |    E   F   G   H     */
26282                 /*  +-------+-------+                      */
26283                 /*          |                              */
26284                 /*         XRa                             */
26285                 /*                                         */
26286 
26287                 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
26288             }
26289             break;
26290         case MXU_OPTN3_PTN1:
26291             {
26292                 /*                                         */
26293                 /*         XRb                 XRc         */
26294                 /*      +-------------------+              */
26295                 /*    A | B   C   D       E | F   G   H    */
26296                 /*      +---------+---------+              */
26297                 /*                |                        */
26298                 /*               XRa                       */
26299                 /*                                         */
26300 
26301                 TCGv_i32 t0 = tcg_temp_new();
26302                 TCGv_i32 t1 = tcg_temp_new();
26303 
26304                 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x00FFFFFF);
26305                 tcg_gen_shli_i32(t0, t0, 8);
26306 
26307                 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
26308                 tcg_gen_shri_i32(t1, t1, 24);
26309 
26310                 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
26311 
26312                 tcg_temp_free(t1);
26313                 tcg_temp_free(t0);
26314             }
26315             break;
26316         case MXU_OPTN3_PTN2:
26317             {
26318                 /*                                         */
26319                 /*         XRb                 XRc         */
26320                 /*          +-------------------+          */
26321                 /*    A   B | C   D       E   F | G   H    */
26322                 /*          +---------+---------+          */
26323                 /*                    |                    */
26324                 /*                   XRa                   */
26325                 /*                                         */
26326 
26327                 TCGv_i32 t0 = tcg_temp_new();
26328                 TCGv_i32 t1 = tcg_temp_new();
26329 
26330                 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
26331                 tcg_gen_shli_i32(t0, t0, 16);
26332 
26333                 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
26334                 tcg_gen_shri_i32(t1, t1, 16);
26335 
26336                 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
26337 
26338                 tcg_temp_free(t1);
26339                 tcg_temp_free(t0);
26340             }
26341             break;
26342         case MXU_OPTN3_PTN3:
26343             {
26344                 /*                                         */
26345                 /*         XRb                 XRc         */
26346                 /*              +-------------------+      */
26347                 /*    A   B   C | D       E   F   G | H    */
26348                 /*              +---------+---------+      */
26349                 /*                        |                */
26350                 /*                       XRa               */
26351                 /*                                         */
26352 
26353                 TCGv_i32 t0 = tcg_temp_new();
26354                 TCGv_i32 t1 = tcg_temp_new();
26355 
26356                 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x000000FF);
26357                 tcg_gen_shli_i32(t0, t0, 24);
26358 
26359                 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFFFF00);
26360                 tcg_gen_shri_i32(t1, t1, 8);
26361 
26362                 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
26363 
26364                 tcg_temp_free(t1);
26365                 tcg_temp_free(t0);
26366             }
26367             break;
26368         case MXU_OPTN3_PTN4:
26369             {
26370                 /*                                         */
26371                 /*         XRb                 XRc         */
26372                 /*                     +---------------+   */
26373                 /*    A   B   C   D    | E   F   G   H |   */
26374                 /*                     +-------+-------+   */
26375                 /*                             |           */
26376                 /*                            XRa          */
26377                 /*                                         */
26378 
26379                 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
26380             }
26381             break;
26382         }
26383     }
26384 }
26385 
26386 
26387 /*
26388  * Decoding engine for MXU
26389  * =======================
26390  */
26391 
26392 /*
26393  *
26394  * Decode MXU pool00
26395  *
26396  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26397  *  +-----------+---------+-----+-------+-------+-------+-----------+
26398  *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL00|
26399  *  +-----------+---------+-----+-------+-------+-------+-----------+
26400  *
26401  */
decode_opc_mxu__pool00(CPUMIPSState * env,DisasContext * ctx)26402 static void decode_opc_mxu__pool00(CPUMIPSState *env, DisasContext *ctx)
26403 {
26404     uint32_t opcode = extract32(ctx->opcode, 18, 3);
26405 
26406     switch (opcode) {
26407     case OPC_MXU_S32MAX:
26408     case OPC_MXU_S32MIN:
26409         gen_mxu_S32MAX_S32MIN(ctx);
26410         break;
26411     case OPC_MXU_D16MAX:
26412     case OPC_MXU_D16MIN:
26413         gen_mxu_D16MAX_D16MIN(ctx);
26414         break;
26415     case OPC_MXU_Q8MAX:
26416     case OPC_MXU_Q8MIN:
26417         gen_mxu_Q8MAX_Q8MIN(ctx);
26418         break;
26419     case OPC_MXU_Q8SLT:
26420         /* TODO: Implement emulation of Q8SLT instruction. */
26421         MIPS_INVAL("OPC_MXU_Q8SLT");
26422         generate_exception_end(ctx, EXCP_RI);
26423         break;
26424     case OPC_MXU_Q8SLTU:
26425         /* TODO: Implement emulation of Q8SLTU instruction. */
26426         MIPS_INVAL("OPC_MXU_Q8SLTU");
26427         generate_exception_end(ctx, EXCP_RI);
26428         break;
26429     default:
26430         MIPS_INVAL("decode_opc_mxu");
26431         generate_exception_end(ctx, EXCP_RI);
26432         break;
26433     }
26434 }
26435 
26436 /*
26437  *
26438  * Decode MXU pool01
26439  *
26440  *  S32SLT, D16SLT, D16AVG, D16AVGR, Q8AVG, Q8AVGR:
26441  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26442  *  +-----------+---------+-----+-------+-------+-------+-----------+
26443  *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL01|
26444  *  +-----------+---------+-----+-------+-------+-------+-----------+
26445  *
26446  *  Q8ADD:
26447  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26448  *  +-----------+---+-----+-----+-------+-------+-------+-----------+
26449  *  |  SPECIAL2 |en2|0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL01|
26450  *  +-----------+---+-----+-----+-------+-------+-------+-----------+
26451  *
26452  */
decode_opc_mxu__pool01(CPUMIPSState * env,DisasContext * ctx)26453 static void decode_opc_mxu__pool01(CPUMIPSState *env, DisasContext *ctx)
26454 {
26455     uint32_t opcode = extract32(ctx->opcode, 18, 3);
26456 
26457     switch (opcode) {
26458     case OPC_MXU_S32SLT:
26459         /* TODO: Implement emulation of S32SLT instruction. */
26460         MIPS_INVAL("OPC_MXU_S32SLT");
26461         generate_exception_end(ctx, EXCP_RI);
26462         break;
26463     case OPC_MXU_D16SLT:
26464         /* TODO: Implement emulation of D16SLT instruction. */
26465         MIPS_INVAL("OPC_MXU_D16SLT");
26466         generate_exception_end(ctx, EXCP_RI);
26467         break;
26468     case OPC_MXU_D16AVG:
26469         /* TODO: Implement emulation of D16AVG instruction. */
26470         MIPS_INVAL("OPC_MXU_D16AVG");
26471         generate_exception_end(ctx, EXCP_RI);
26472         break;
26473     case OPC_MXU_D16AVGR:
26474         /* TODO: Implement emulation of D16AVGR instruction. */
26475         MIPS_INVAL("OPC_MXU_D16AVGR");
26476         generate_exception_end(ctx, EXCP_RI);
26477         break;
26478     case OPC_MXU_Q8AVG:
26479         /* TODO: Implement emulation of Q8AVG instruction. */
26480         MIPS_INVAL("OPC_MXU_Q8AVG");
26481         generate_exception_end(ctx, EXCP_RI);
26482         break;
26483     case OPC_MXU_Q8AVGR:
26484         /* TODO: Implement emulation of Q8AVGR instruction. */
26485         MIPS_INVAL("OPC_MXU_Q8AVGR");
26486         generate_exception_end(ctx, EXCP_RI);
26487         break;
26488     case OPC_MXU_Q8ADD:
26489         /* TODO: Implement emulation of Q8ADD instruction. */
26490         MIPS_INVAL("OPC_MXU_Q8ADD");
26491         generate_exception_end(ctx, EXCP_RI);
26492         break;
26493     default:
26494         MIPS_INVAL("decode_opc_mxu");
26495         generate_exception_end(ctx, EXCP_RI);
26496         break;
26497     }
26498 }
26499 
26500 /*
26501  *
26502  * Decode MXU pool02
26503  *
26504  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26505  *  +-----------+---------+-----+-------+-------+-------+-----------+
26506  *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL02|
26507  *  +-----------+---------+-----+-------+-------+-------+-----------+
26508  *
26509  */
decode_opc_mxu__pool02(CPUMIPSState * env,DisasContext * ctx)26510 static void decode_opc_mxu__pool02(CPUMIPSState *env, DisasContext *ctx)
26511 {
26512     uint32_t opcode = extract32(ctx->opcode, 18, 3);
26513 
26514     switch (opcode) {
26515     case OPC_MXU_S32CPS:
26516         /* TODO: Implement emulation of S32CPS instruction. */
26517         MIPS_INVAL("OPC_MXU_S32CPS");
26518         generate_exception_end(ctx, EXCP_RI);
26519         break;
26520     case OPC_MXU_D16CPS:
26521         /* TODO: Implement emulation of D16CPS instruction. */
26522         MIPS_INVAL("OPC_MXU_D16CPS");
26523         generate_exception_end(ctx, EXCP_RI);
26524         break;
26525     case OPC_MXU_Q8ABD:
26526         /* TODO: Implement emulation of Q8ABD instruction. */
26527         MIPS_INVAL("OPC_MXU_Q8ABD");
26528         generate_exception_end(ctx, EXCP_RI);
26529         break;
26530     case OPC_MXU_Q16SAT:
26531         /* TODO: Implement emulation of Q16SAT instruction. */
26532         MIPS_INVAL("OPC_MXU_Q16SAT");
26533         generate_exception_end(ctx, EXCP_RI);
26534         break;
26535     default:
26536         MIPS_INVAL("decode_opc_mxu");
26537         generate_exception_end(ctx, EXCP_RI);
26538         break;
26539     }
26540 }
26541 
26542 /*
26543  *
26544  * Decode MXU pool03
26545  *
26546  *  D16MULF:
26547  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26548  *  +-----------+---+---+-------+-------+-------+-------+-----------+
26549  *  |  SPECIAL2 |x x|on2|0 0 0 0|  XRc  |  XRb  |  XRa  |MXU__POOL03|
26550  *  +-----------+---+---+-------+-------+-------+-------+-----------+
26551  *
26552  *  D16MULE:
26553  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26554  *  +-----------+---+---+-------+-------+-------+-------+-----------+
26555  *  |  SPECIAL2 |x x|on2|   Xd  |  XRc  |  XRb  |  XRa  |MXU__POOL03|
26556  *  +-----------+---+---+-------+-------+-------+-------+-----------+
26557  *
26558  */
decode_opc_mxu__pool03(CPUMIPSState * env,DisasContext * ctx)26559 static void decode_opc_mxu__pool03(CPUMIPSState *env, DisasContext *ctx)
26560 {
26561     uint32_t opcode = extract32(ctx->opcode, 24, 2);
26562 
26563     switch (opcode) {
26564     case OPC_MXU_D16MULF:
26565         /* TODO: Implement emulation of D16MULF instruction. */
26566         MIPS_INVAL("OPC_MXU_D16MULF");
26567         generate_exception_end(ctx, EXCP_RI);
26568         break;
26569     case OPC_MXU_D16MULE:
26570         /* TODO: Implement emulation of D16MULE instruction. */
26571         MIPS_INVAL("OPC_MXU_D16MULE");
26572         generate_exception_end(ctx, EXCP_RI);
26573         break;
26574     default:
26575         MIPS_INVAL("decode_opc_mxu");
26576         generate_exception_end(ctx, EXCP_RI);
26577         break;
26578     }
26579 }
26580 
26581 /*
26582  *
26583  * Decode MXU pool04
26584  *
26585  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26586  *  +-----------+---------+-+-------------------+-------+-----------+
26587  *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL04|
26588  *  +-----------+---------+-+-------------------+-------+-----------+
26589  *
26590  */
decode_opc_mxu__pool04(CPUMIPSState * env,DisasContext * ctx)26591 static void decode_opc_mxu__pool04(CPUMIPSState *env, DisasContext *ctx)
26592 {
26593     uint32_t opcode = extract32(ctx->opcode, 20, 1);
26594 
26595     switch (opcode) {
26596     case OPC_MXU_S32LDD:
26597     case OPC_MXU_S32LDDR:
26598         gen_mxu_s32ldd_s32lddr(ctx);
26599         break;
26600     default:
26601         MIPS_INVAL("decode_opc_mxu");
26602         generate_exception_end(ctx, EXCP_RI);
26603         break;
26604     }
26605 }
26606 
26607 /*
26608  *
26609  * Decode MXU pool05
26610  *
26611  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26612  *  +-----------+---------+-+-------------------+-------+-----------+
26613  *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL05|
26614  *  +-----------+---------+-+-------------------+-------+-----------+
26615  *
26616  */
decode_opc_mxu__pool05(CPUMIPSState * env,DisasContext * ctx)26617 static void decode_opc_mxu__pool05(CPUMIPSState *env, DisasContext *ctx)
26618 {
26619     uint32_t opcode = extract32(ctx->opcode, 20, 1);
26620 
26621     switch (opcode) {
26622     case OPC_MXU_S32STD:
26623         /* TODO: Implement emulation of S32STD instruction. */
26624         MIPS_INVAL("OPC_MXU_S32STD");
26625         generate_exception_end(ctx, EXCP_RI);
26626         break;
26627     case OPC_MXU_S32STDR:
26628         /* TODO: Implement emulation of S32STDR instruction. */
26629         MIPS_INVAL("OPC_MXU_S32STDR");
26630         generate_exception_end(ctx, EXCP_RI);
26631         break;
26632     default:
26633         MIPS_INVAL("decode_opc_mxu");
26634         generate_exception_end(ctx, EXCP_RI);
26635         break;
26636     }
26637 }
26638 
26639 /*
26640  *
26641  * Decode MXU pool06
26642  *
26643  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26644  *  +-----------+---------+---------+---+-------+-------+-----------+
26645  *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL06|
26646  *  +-----------+---------+---------+---+-------+-------+-----------+
26647  *
26648  */
decode_opc_mxu__pool06(CPUMIPSState * env,DisasContext * ctx)26649 static void decode_opc_mxu__pool06(CPUMIPSState *env, DisasContext *ctx)
26650 {
26651     uint32_t opcode = extract32(ctx->opcode, 10, 4);
26652 
26653     switch (opcode) {
26654     case OPC_MXU_S32LDDV:
26655         /* TODO: Implement emulation of S32LDDV instruction. */
26656         MIPS_INVAL("OPC_MXU_S32LDDV");
26657         generate_exception_end(ctx, EXCP_RI);
26658         break;
26659     case OPC_MXU_S32LDDVR:
26660         /* TODO: Implement emulation of S32LDDVR instruction. */
26661         MIPS_INVAL("OPC_MXU_S32LDDVR");
26662         generate_exception_end(ctx, EXCP_RI);
26663         break;
26664     default:
26665         MIPS_INVAL("decode_opc_mxu");
26666         generate_exception_end(ctx, EXCP_RI);
26667         break;
26668     }
26669 }
26670 
26671 /*
26672  *
26673  * Decode MXU pool07
26674  *
26675  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26676  *  +-----------+---------+---------+---+-------+-------+-----------+
26677  *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL07|
26678  *  +-----------+---------+---------+---+-------+-------+-----------+
26679  *
26680  */
decode_opc_mxu__pool07(CPUMIPSState * env,DisasContext * ctx)26681 static void decode_opc_mxu__pool07(CPUMIPSState *env, DisasContext *ctx)
26682 {
26683     uint32_t opcode = extract32(ctx->opcode, 10, 4);
26684 
26685     switch (opcode) {
26686     case OPC_MXU_S32STDV:
26687         /* TODO: Implement emulation of S32TDV instruction. */
26688         MIPS_INVAL("OPC_MXU_S32TDV");
26689         generate_exception_end(ctx, EXCP_RI);
26690         break;
26691     case OPC_MXU_S32STDVR:
26692         /* TODO: Implement emulation of S32TDVR instruction. */
26693         MIPS_INVAL("OPC_MXU_S32TDVR");
26694         generate_exception_end(ctx, EXCP_RI);
26695         break;
26696     default:
26697         MIPS_INVAL("decode_opc_mxu");
26698         generate_exception_end(ctx, EXCP_RI);
26699         break;
26700     }
26701 }
26702 
26703 /*
26704  *
26705  * Decode MXU pool08
26706  *
26707  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26708  *  +-----------+---------+-+-------------------+-------+-----------+
26709  *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL08|
26710  *  +-----------+---------+-+-------------------+-------+-----------+
26711  *
26712  */
decode_opc_mxu__pool08(CPUMIPSState * env,DisasContext * ctx)26713 static void decode_opc_mxu__pool08(CPUMIPSState *env, DisasContext *ctx)
26714 {
26715     uint32_t opcode = extract32(ctx->opcode, 20, 1);
26716 
26717     switch (opcode) {
26718     case OPC_MXU_S32LDI:
26719         /* TODO: Implement emulation of S32LDI instruction. */
26720         MIPS_INVAL("OPC_MXU_S32LDI");
26721         generate_exception_end(ctx, EXCP_RI);
26722         break;
26723     case OPC_MXU_S32LDIR:
26724         /* TODO: Implement emulation of S32LDIR instruction. */
26725         MIPS_INVAL("OPC_MXU_S32LDIR");
26726         generate_exception_end(ctx, EXCP_RI);
26727         break;
26728     default:
26729         MIPS_INVAL("decode_opc_mxu");
26730         generate_exception_end(ctx, EXCP_RI);
26731         break;
26732     }
26733 }
26734 
26735 /*
26736  *
26737  * Decode MXU pool09
26738  *
26739  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26740  *  +-----------+---------+-+-------------------+-------+-----------+
26741  *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL09|
26742  *  +-----------+---------+-+-------------------+-------+-----------+
26743  *
26744  */
decode_opc_mxu__pool09(CPUMIPSState * env,DisasContext * ctx)26745 static void decode_opc_mxu__pool09(CPUMIPSState *env, DisasContext *ctx)
26746 {
26747     uint32_t opcode = extract32(ctx->opcode, 5, 0);
26748 
26749     switch (opcode) {
26750     case OPC_MXU_S32SDI:
26751         /* TODO: Implement emulation of S32SDI instruction. */
26752         MIPS_INVAL("OPC_MXU_S32SDI");
26753         generate_exception_end(ctx, EXCP_RI);
26754         break;
26755     case OPC_MXU_S32SDIR:
26756         /* TODO: Implement emulation of S32SDIR instruction. */
26757         MIPS_INVAL("OPC_MXU_S32SDIR");
26758         generate_exception_end(ctx, EXCP_RI);
26759         break;
26760     default:
26761         MIPS_INVAL("decode_opc_mxu");
26762         generate_exception_end(ctx, EXCP_RI);
26763         break;
26764     }
26765 }
26766 
26767 /*
26768  *
26769  * Decode MXU pool10
26770  *
26771  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26772  *  +-----------+---------+---------+---+-------+-------+-----------+
26773  *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL10|
26774  *  +-----------+---------+---------+---+-------+-------+-----------+
26775  *
26776  */
decode_opc_mxu__pool10(CPUMIPSState * env,DisasContext * ctx)26777 static void decode_opc_mxu__pool10(CPUMIPSState *env, DisasContext *ctx)
26778 {
26779     uint32_t opcode = extract32(ctx->opcode, 5, 0);
26780 
26781     switch (opcode) {
26782     case OPC_MXU_S32LDIV:
26783         /* TODO: Implement emulation of S32LDIV instruction. */
26784         MIPS_INVAL("OPC_MXU_S32LDIV");
26785         generate_exception_end(ctx, EXCP_RI);
26786         break;
26787     case OPC_MXU_S32LDIVR:
26788         /* TODO: Implement emulation of S32LDIVR instruction. */
26789         MIPS_INVAL("OPC_MXU_S32LDIVR");
26790         generate_exception_end(ctx, EXCP_RI);
26791         break;
26792     default:
26793         MIPS_INVAL("decode_opc_mxu");
26794         generate_exception_end(ctx, EXCP_RI);
26795         break;
26796     }
26797 }
26798 
26799 /*
26800  *
26801  * Decode MXU pool11
26802  *
26803  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26804  *  +-----------+---------+---------+---+-------+-------+-----------+
26805  *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL11|
26806  *  +-----------+---------+---------+---+-------+-------+-----------+
26807  *
26808  */
decode_opc_mxu__pool11(CPUMIPSState * env,DisasContext * ctx)26809 static void decode_opc_mxu__pool11(CPUMIPSState *env, DisasContext *ctx)
26810 {
26811     uint32_t opcode = extract32(ctx->opcode, 10, 4);
26812 
26813     switch (opcode) {
26814     case OPC_MXU_S32SDIV:
26815         /* TODO: Implement emulation of S32SDIV instruction. */
26816         MIPS_INVAL("OPC_MXU_S32SDIV");
26817         generate_exception_end(ctx, EXCP_RI);
26818         break;
26819     case OPC_MXU_S32SDIVR:
26820         /* TODO: Implement emulation of S32SDIVR instruction. */
26821         MIPS_INVAL("OPC_MXU_S32SDIVR");
26822         generate_exception_end(ctx, EXCP_RI);
26823         break;
26824     default:
26825         MIPS_INVAL("decode_opc_mxu");
26826         generate_exception_end(ctx, EXCP_RI);
26827         break;
26828     }
26829 }
26830 
26831 /*
26832  *
26833  * Decode MXU pool12
26834  *
26835  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26836  *  +-----------+---+---+-------+-------+-------+-------+-----------+
26837  *  |  SPECIAL2 |an2|x x|   Xd  |  XRc  |  XRb  |  XRa  |MXU__POOL12|
26838  *  +-----------+---+---+-------+-------+-------+-------+-----------+
26839  *
26840  */
decode_opc_mxu__pool12(CPUMIPSState * env,DisasContext * ctx)26841 static void decode_opc_mxu__pool12(CPUMIPSState *env, DisasContext *ctx)
26842 {
26843     uint32_t opcode = extract32(ctx->opcode, 22, 2);
26844 
26845     switch (opcode) {
26846     case OPC_MXU_D32ACC:
26847         /* TODO: Implement emulation of D32ACC instruction. */
26848         MIPS_INVAL("OPC_MXU_D32ACC");
26849         generate_exception_end(ctx, EXCP_RI);
26850         break;
26851     case OPC_MXU_D32ACCM:
26852         /* TODO: Implement emulation of D32ACCM instruction. */
26853         MIPS_INVAL("OPC_MXU_D32ACCM");
26854         generate_exception_end(ctx, EXCP_RI);
26855         break;
26856     case OPC_MXU_D32ASUM:
26857         /* TODO: Implement emulation of D32ASUM instruction. */
26858         MIPS_INVAL("OPC_MXU_D32ASUM");
26859         generate_exception_end(ctx, EXCP_RI);
26860         break;
26861     default:
26862         MIPS_INVAL("decode_opc_mxu");
26863         generate_exception_end(ctx, EXCP_RI);
26864         break;
26865     }
26866 }
26867 
26868 /*
26869  *
26870  * Decode MXU pool13
26871  *
26872  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26873  *  +-----------+---+---+-------+-------+-------+-------+-----------+
26874  *  |  SPECIAL2 |en2|x x|0 0 0 0|  XRc  |  XRb  |  XRa  |MXU__POOL13|
26875  *  +-----------+---+---+-------+-------+-------+-------+-----------+
26876  *
26877  */
decode_opc_mxu__pool13(CPUMIPSState * env,DisasContext * ctx)26878 static void decode_opc_mxu__pool13(CPUMIPSState *env, DisasContext *ctx)
26879 {
26880     uint32_t opcode = extract32(ctx->opcode, 22, 2);
26881 
26882     switch (opcode) {
26883     case OPC_MXU_Q16ACC:
26884         /* TODO: Implement emulation of Q16ACC instruction. */
26885         MIPS_INVAL("OPC_MXU_Q16ACC");
26886         generate_exception_end(ctx, EXCP_RI);
26887         break;
26888     case OPC_MXU_Q16ACCM:
26889         /* TODO: Implement emulation of Q16ACCM instruction. */
26890         MIPS_INVAL("OPC_MXU_Q16ACCM");
26891         generate_exception_end(ctx, EXCP_RI);
26892         break;
26893     case OPC_MXU_Q16ASUM:
26894         /* TODO: Implement emulation of Q16ASUM instruction. */
26895         MIPS_INVAL("OPC_MXU_Q16ASUM");
26896         generate_exception_end(ctx, EXCP_RI);
26897         break;
26898     default:
26899         MIPS_INVAL("decode_opc_mxu");
26900         generate_exception_end(ctx, EXCP_RI);
26901         break;
26902     }
26903 }
26904 
26905 /*
26906  *
26907  * Decode MXU pool14
26908  *
26909  *  Q8ADDE, Q8ACCE:
26910  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26911  *  +-----------+---+---+-------+-------+-------+-------+-----------+
26912  *  |  SPECIAL2 |0 0|x x|  XRd  |  XRc  |  XRb  |  XRa  |MXU__POOL14|
26913  *  +-----------+---+---+-------+-------+-------+-------+-----------+
26914  *
26915  *  D8SUM, D8SUMC:
26916  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26917  *  +-----------+---+---+-------+-------+-------+-------+-----------+
26918  *  |  SPECIAL2 |en2|x x|0 0 0 0|  XRc  |  XRb  |  XRa  |MXU__POOL14|
26919  *  +-----------+---+---+-------+-------+-------+-------+-----------+
26920  *
26921  */
decode_opc_mxu__pool14(CPUMIPSState * env,DisasContext * ctx)26922 static void decode_opc_mxu__pool14(CPUMIPSState *env, DisasContext *ctx)
26923 {
26924     uint32_t opcode = extract32(ctx->opcode, 22, 2);
26925 
26926     switch (opcode) {
26927     case OPC_MXU_Q8ADDE:
26928         /* TODO: Implement emulation of Q8ADDE instruction. */
26929         MIPS_INVAL("OPC_MXU_Q8ADDE");
26930         generate_exception_end(ctx, EXCP_RI);
26931         break;
26932     case OPC_MXU_D8SUM:
26933         /* TODO: Implement emulation of D8SUM instruction. */
26934         MIPS_INVAL("OPC_MXU_D8SUM");
26935         generate_exception_end(ctx, EXCP_RI);
26936         break;
26937     case OPC_MXU_D8SUMC:
26938         /* TODO: Implement emulation of D8SUMC instruction. */
26939         MIPS_INVAL("OPC_MXU_D8SUMC");
26940         generate_exception_end(ctx, EXCP_RI);
26941         break;
26942     default:
26943         MIPS_INVAL("decode_opc_mxu");
26944         generate_exception_end(ctx, EXCP_RI);
26945         break;
26946     }
26947 }
26948 
26949 /*
26950  *
26951  * Decode MXU pool15
26952  *
26953  *  S32MUL, S32MULU, S32EXTRV:
26954  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26955  *  +-----------+---------+---------+---+-------+-------+-----------+
26956  *  |  SPECIAL2 |    rs   |    rt   |x x|  XRd  |  XRa  |MXU__POOL15|
26957  *  +-----------+---------+---------+---+-------+-------+-----------+
26958  *
26959  *  S32EXTR:
26960  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26961  *  +-----------+---------+---------+---+-------+-------+-----------+
26962  *  |  SPECIAL2 |    rb   |   sft5  |x x|  XRd  |  XRa  |MXU__POOL15|
26963  *  +-----------+---------+---------+---+-------+-------+-----------+
26964  *
26965  */
decode_opc_mxu__pool15(CPUMIPSState * env,DisasContext * ctx)26966 static void decode_opc_mxu__pool15(CPUMIPSState *env, DisasContext *ctx)
26967 {
26968     uint32_t opcode = extract32(ctx->opcode, 14, 2);
26969 
26970     switch (opcode) {
26971     case OPC_MXU_S32MUL:
26972         /* TODO: Implement emulation of S32MUL instruction. */
26973         MIPS_INVAL("OPC_MXU_S32MUL");
26974         generate_exception_end(ctx, EXCP_RI);
26975         break;
26976     case OPC_MXU_S32MULU:
26977         /* TODO: Implement emulation of S32MULU instruction. */
26978         MIPS_INVAL("OPC_MXU_S32MULU");
26979         generate_exception_end(ctx, EXCP_RI);
26980         break;
26981     case OPC_MXU_S32EXTR:
26982         /* TODO: Implement emulation of S32EXTR instruction. */
26983         MIPS_INVAL("OPC_MXU_S32EXTR");
26984         generate_exception_end(ctx, EXCP_RI);
26985         break;
26986     case OPC_MXU_S32EXTRV:
26987         /* TODO: Implement emulation of S32EXTRV instruction. */
26988         MIPS_INVAL("OPC_MXU_S32EXTRV");
26989         generate_exception_end(ctx, EXCP_RI);
26990         break;
26991     default:
26992         MIPS_INVAL("decode_opc_mxu");
26993         generate_exception_end(ctx, EXCP_RI);
26994         break;
26995     }
26996 }
26997 
26998 /*
26999  *
27000  * Decode MXU pool16
27001  *
27002  *  D32SARW:
27003  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
27004  *  +-----------+---------+-----+-------+-------+-------+-----------+
27005  *  |  SPECIAL2 |    rb   |x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
27006  *  +-----------+---------+-----+-------+-------+-------+-----------+
27007  *
27008  *  S32ALN:
27009  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
27010  *  +-----------+---------+-----+-------+-------+-------+-----------+
27011  *  |  SPECIAL2 |    rs   |x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
27012  *  +-----------+---------+-----+-------+-------+-------+-----------+
27013  *
27014  *  S32ALNI:
27015  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
27016  *  +-----------+-----+---+-----+-------+-------+-------+-----------+
27017  *  |  SPECIAL2 |  s3 |0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
27018  *  +-----------+-----+---+-----+-------+-------+-------+-----------+
27019  *
27020  *  S32LUI:
27021  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
27022  *  +-----------+-----+---+-----+-------+---------------+-----------+
27023  *  |  SPECIAL2 |optn3|0 0|x x x|  XRc  |       s8      |MXU__POOL16|
27024  *  +-----------+-----+---+-----+-------+---------------+-----------+
27025  *
27026  *  S32NOR, S32AND, S32OR, S32XOR:
27027  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
27028  *  +-----------+---------+-----+-------+-------+-------+-----------+
27029  *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
27030  *  +-----------+---------+-----+-------+-------+-------+-----------+
27031  *
27032  */
decode_opc_mxu__pool16(CPUMIPSState * env,DisasContext * ctx)27033 static void decode_opc_mxu__pool16(CPUMIPSState *env, DisasContext *ctx)
27034 {
27035     uint32_t opcode = extract32(ctx->opcode, 18, 3);
27036 
27037     switch (opcode) {
27038     case OPC_MXU_D32SARW:
27039         /* TODO: Implement emulation of D32SARW instruction. */
27040         MIPS_INVAL("OPC_MXU_D32SARW");
27041         generate_exception_end(ctx, EXCP_RI);
27042         break;
27043     case OPC_MXU_S32ALN:
27044         /* TODO: Implement emulation of S32ALN instruction. */
27045         MIPS_INVAL("OPC_MXU_S32ALN");
27046         generate_exception_end(ctx, EXCP_RI);
27047         break;
27048     case OPC_MXU_S32ALNI:
27049         gen_mxu_S32ALNI(ctx);
27050         break;
27051     case OPC_MXU_S32LUI:
27052         /* TODO: Implement emulation of S32LUI instruction. */
27053         MIPS_INVAL("OPC_MXU_S32LUI");
27054         generate_exception_end(ctx, EXCP_RI);
27055         break;
27056     case OPC_MXU_S32NOR:
27057         gen_mxu_S32NOR(ctx);
27058         break;
27059     case OPC_MXU_S32AND:
27060         gen_mxu_S32AND(ctx);
27061         break;
27062     case OPC_MXU_S32OR:
27063         gen_mxu_S32OR(ctx);
27064         break;
27065     case OPC_MXU_S32XOR:
27066         gen_mxu_S32XOR(ctx);
27067         break;
27068     default:
27069         MIPS_INVAL("decode_opc_mxu");
27070         generate_exception_end(ctx, EXCP_RI);
27071         break;
27072     }
27073 }
27074 
27075 /*
27076  *
27077  * Decode MXU pool17
27078  *
27079  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
27080  *  +-----------+---------+---------+---+---------+-----+-----------+
27081  *  |  SPECIAL2 |    rs   |    rt   |0 0|    rd   |x x x|MXU__POOL15|
27082  *  +-----------+---------+---------+---+---------+-----+-----------+
27083  *
27084  */
decode_opc_mxu__pool17(CPUMIPSState * env,DisasContext * ctx)27085 static void decode_opc_mxu__pool17(CPUMIPSState *env, DisasContext *ctx)
27086 {
27087     uint32_t opcode = extract32(ctx->opcode, 6, 2);
27088 
27089     switch (opcode) {
27090     case OPC_MXU_LXW:
27091         /* TODO: Implement emulation of LXW instruction. */
27092         MIPS_INVAL("OPC_MXU_LXW");
27093         generate_exception_end(ctx, EXCP_RI);
27094         break;
27095     case OPC_MXU_LXH:
27096         /* TODO: Implement emulation of LXH instruction. */
27097         MIPS_INVAL("OPC_MXU_LXH");
27098         generate_exception_end(ctx, EXCP_RI);
27099         break;
27100     case OPC_MXU_LXHU:
27101         /* TODO: Implement emulation of LXHU instruction. */
27102         MIPS_INVAL("OPC_MXU_LXHU");
27103         generate_exception_end(ctx, EXCP_RI);
27104         break;
27105     case OPC_MXU_LXB:
27106         /* TODO: Implement emulation of LXB instruction. */
27107         MIPS_INVAL("OPC_MXU_LXB");
27108         generate_exception_end(ctx, EXCP_RI);
27109         break;
27110     case OPC_MXU_LXBU:
27111         /* TODO: Implement emulation of LXBU instruction. */
27112         MIPS_INVAL("OPC_MXU_LXBU");
27113         generate_exception_end(ctx, EXCP_RI);
27114         break;
27115     default:
27116         MIPS_INVAL("decode_opc_mxu");
27117         generate_exception_end(ctx, EXCP_RI);
27118         break;
27119     }
27120 }
27121 /*
27122  *
27123  * Decode MXU pool18
27124  *
27125  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
27126  *  +-----------+---------+-----+-------+-------+-------+-----------+
27127  *  |  SPECIAL2 |    rb   |x x x|  XRd  |  XRa  |0 0 0 0|MXU__POOL18|
27128  *  +-----------+---------+-----+-------+-------+-------+-----------+
27129  *
27130  */
decode_opc_mxu__pool18(CPUMIPSState * env,DisasContext * ctx)27131 static void decode_opc_mxu__pool18(CPUMIPSState *env, DisasContext *ctx)
27132 {
27133     uint32_t opcode = extract32(ctx->opcode, 18, 3);
27134 
27135     switch (opcode) {
27136     case OPC_MXU_D32SLLV:
27137         /* TODO: Implement emulation of D32SLLV instruction. */
27138         MIPS_INVAL("OPC_MXU_D32SLLV");
27139         generate_exception_end(ctx, EXCP_RI);
27140         break;
27141     case OPC_MXU_D32SLRV:
27142         /* TODO: Implement emulation of D32SLRV instruction. */
27143         MIPS_INVAL("OPC_MXU_D32SLRV");
27144         generate_exception_end(ctx, EXCP_RI);
27145         break;
27146     case OPC_MXU_D32SARV:
27147         /* TODO: Implement emulation of D32SARV instruction. */
27148         MIPS_INVAL("OPC_MXU_D32SARV");
27149         generate_exception_end(ctx, EXCP_RI);
27150         break;
27151     case OPC_MXU_Q16SLLV:
27152         /* TODO: Implement emulation of Q16SLLV instruction. */
27153         MIPS_INVAL("OPC_MXU_Q16SLLV");
27154         generate_exception_end(ctx, EXCP_RI);
27155         break;
27156     case OPC_MXU_Q16SLRV:
27157         /* TODO: Implement emulation of Q16SLRV instruction. */
27158         MIPS_INVAL("OPC_MXU_Q16SLRV");
27159         generate_exception_end(ctx, EXCP_RI);
27160         break;
27161     case OPC_MXU_Q16SARV:
27162         /* TODO: Implement emulation of Q16SARV instruction. */
27163         MIPS_INVAL("OPC_MXU_Q16SARV");
27164         generate_exception_end(ctx, EXCP_RI);
27165         break;
27166     default:
27167         MIPS_INVAL("decode_opc_mxu");
27168         generate_exception_end(ctx, EXCP_RI);
27169         break;
27170     }
27171 }
27172 
27173 /*
27174  *
27175  * Decode MXU pool19
27176  *
27177  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
27178  *  +-----------+---+---+-------+-------+-------+-------+-----------+
27179  *  |  SPECIAL2 |0 0|x x|  XRd  |  XRc  |  XRb  |  XRa  |MXU__POOL19|
27180  *  +-----------+---+---+-------+-------+-------+-------+-----------+
27181  *
27182  */
decode_opc_mxu__pool19(CPUMIPSState * env,DisasContext * ctx)27183 static void decode_opc_mxu__pool19(CPUMIPSState *env, DisasContext *ctx)
27184 {
27185     uint32_t opcode = extract32(ctx->opcode, 22, 2);
27186 
27187     switch (opcode) {
27188     case OPC_MXU_Q8MUL:
27189     case OPC_MXU_Q8MULSU:
27190         gen_mxu_q8mul_q8mulsu(ctx);
27191         break;
27192     default:
27193         MIPS_INVAL("decode_opc_mxu");
27194         generate_exception_end(ctx, EXCP_RI);
27195         break;
27196     }
27197 }
27198 
27199 /*
27200  *
27201  * Decode MXU pool20
27202  *
27203  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
27204  *  +-----------+---------+-----+-------+-------+-------+-----------+
27205  *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL20|
27206  *  +-----------+---------+-----+-------+-------+-------+-----------+
27207  *
27208  */
decode_opc_mxu__pool20(CPUMIPSState * env,DisasContext * ctx)27209 static void decode_opc_mxu__pool20(CPUMIPSState *env, DisasContext *ctx)
27210 {
27211     uint32_t opcode = extract32(ctx->opcode, 18, 3);
27212 
27213     switch (opcode) {
27214     case OPC_MXU_Q8MOVZ:
27215         /* TODO: Implement emulation of Q8MOVZ instruction. */
27216         MIPS_INVAL("OPC_MXU_Q8MOVZ");
27217         generate_exception_end(ctx, EXCP_RI);
27218         break;
27219     case OPC_MXU_Q8MOVN:
27220         /* TODO: Implement emulation of Q8MOVN instruction. */
27221         MIPS_INVAL("OPC_MXU_Q8MOVN");
27222         generate_exception_end(ctx, EXCP_RI);
27223         break;
27224     case OPC_MXU_D16MOVZ:
27225         /* TODO: Implement emulation of D16MOVZ instruction. */
27226         MIPS_INVAL("OPC_MXU_D16MOVZ");
27227         generate_exception_end(ctx, EXCP_RI);
27228         break;
27229     case OPC_MXU_D16MOVN:
27230         /* TODO: Implement emulation of D16MOVN instruction. */
27231         MIPS_INVAL("OPC_MXU_D16MOVN");
27232         generate_exception_end(ctx, EXCP_RI);
27233         break;
27234     case OPC_MXU_S32MOVZ:
27235         /* TODO: Implement emulation of S32MOVZ instruction. */
27236         MIPS_INVAL("OPC_MXU_S32MOVZ");
27237         generate_exception_end(ctx, EXCP_RI);
27238         break;
27239     case OPC_MXU_S32MOVN:
27240         /* TODO: Implement emulation of S32MOVN instruction. */
27241         MIPS_INVAL("OPC_MXU_S32MOVN");
27242         generate_exception_end(ctx, EXCP_RI);
27243         break;
27244     default:
27245         MIPS_INVAL("decode_opc_mxu");
27246         generate_exception_end(ctx, EXCP_RI);
27247         break;
27248     }
27249 }
27250 
27251 /*
27252  *
27253  * Decode MXU pool21
27254  *
27255  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
27256  *  +-----------+---+---+-------+-------+-------+-------+-----------+
27257  *  |  SPECIAL2 |an2|x x|  XRd  |  XRc  |  XRb  |  XRa  |MXU__POOL21|
27258  *  +-----------+---+---+-------+-------+-------+-------+-----------+
27259  *
27260  */
decode_opc_mxu__pool21(CPUMIPSState * env,DisasContext * ctx)27261 static void decode_opc_mxu__pool21(CPUMIPSState *env, DisasContext *ctx)
27262 {
27263     uint32_t opcode = extract32(ctx->opcode, 22, 2);
27264 
27265     switch (opcode) {
27266     case OPC_MXU_Q8MAC:
27267         /* TODO: Implement emulation of Q8MAC instruction. */
27268         MIPS_INVAL("OPC_MXU_Q8MAC");
27269         generate_exception_end(ctx, EXCP_RI);
27270         break;
27271     case OPC_MXU_Q8MACSU:
27272         /* TODO: Implement emulation of Q8MACSU instruction. */
27273         MIPS_INVAL("OPC_MXU_Q8MACSU");
27274         generate_exception_end(ctx, EXCP_RI);
27275         break;
27276     default:
27277         MIPS_INVAL("decode_opc_mxu");
27278         generate_exception_end(ctx, EXCP_RI);
27279         break;
27280     }
27281 }
27282 
27283 
27284 /*
27285  * Main MXU decoding function
27286  *
27287  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
27288  *  +-----------+---------------------------------------+-----------+
27289  *  |  SPECIAL2 |                                       |x x x x x x|
27290  *  +-----------+---------------------------------------+-----------+
27291  *
27292  */
decode_opc_mxu(CPUMIPSState * env,DisasContext * ctx)27293 static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx)
27294 {
27295     /*
27296      * TODO: Investigate necessity of including handling of
27297      * CLZ, CLO, SDBB in this function, as they belong to
27298      * SPECIAL2 opcode space for regular pre-R6 MIPS ISAs.
27299      */
27300     uint32_t opcode = extract32(ctx->opcode, 0, 6);
27301 
27302     if (opcode == OPC__MXU_MUL) {
27303         uint32_t  rs, rt, rd, op1;
27304 
27305         rs = extract32(ctx->opcode, 21, 5);
27306         rt = extract32(ctx->opcode, 16, 5);
27307         rd = extract32(ctx->opcode, 11, 5);
27308         op1 = MASK_SPECIAL2(ctx->opcode);
27309 
27310         gen_arith(ctx, op1, rd, rs, rt);
27311 
27312         return;
27313     }
27314 
27315     if (opcode == OPC_MXU_S32M2I) {
27316         gen_mxu_s32m2i(ctx);
27317         return;
27318     }
27319 
27320     if (opcode == OPC_MXU_S32I2M) {
27321         gen_mxu_s32i2m(ctx);
27322         return;
27323     }
27324 
27325     {
27326         TCGv t_mxu_cr = tcg_temp_new();
27327         TCGLabel *l_exit = gen_new_label();
27328 
27329         gen_load_mxu_cr(t_mxu_cr);
27330         tcg_gen_andi_tl(t_mxu_cr, t_mxu_cr, MXU_CR_MXU_EN);
27331         tcg_gen_brcondi_tl(TCG_COND_NE, t_mxu_cr, MXU_CR_MXU_EN, l_exit);
27332 
27333         switch (opcode) {
27334         case OPC_MXU_S32MADD:
27335             /* TODO: Implement emulation of S32MADD instruction. */
27336             MIPS_INVAL("OPC_MXU_S32MADD");
27337             generate_exception_end(ctx, EXCP_RI);
27338             break;
27339         case OPC_MXU_S32MADDU:
27340             /* TODO: Implement emulation of S32MADDU instruction. */
27341             MIPS_INVAL("OPC_MXU_S32MADDU");
27342             generate_exception_end(ctx, EXCP_RI);
27343             break;
27344         case OPC_MXU__POOL00:
27345             decode_opc_mxu__pool00(env, ctx);
27346             break;
27347         case OPC_MXU_S32MSUB:
27348             /* TODO: Implement emulation of S32MSUB instruction. */
27349             MIPS_INVAL("OPC_MXU_S32MSUB");
27350             generate_exception_end(ctx, EXCP_RI);
27351             break;
27352         case OPC_MXU_S32MSUBU:
27353             /* TODO: Implement emulation of S32MSUBU instruction. */
27354             MIPS_INVAL("OPC_MXU_S32MSUBU");
27355             generate_exception_end(ctx, EXCP_RI);
27356             break;
27357         case OPC_MXU__POOL01:
27358             decode_opc_mxu__pool01(env, ctx);
27359             break;
27360         case OPC_MXU__POOL02:
27361             decode_opc_mxu__pool02(env, ctx);
27362             break;
27363         case OPC_MXU_D16MUL:
27364             gen_mxu_d16mul(ctx);
27365             break;
27366         case OPC_MXU__POOL03:
27367             decode_opc_mxu__pool03(env, ctx);
27368             break;
27369         case OPC_MXU_D16MAC:
27370             gen_mxu_d16mac(ctx);
27371             break;
27372         case OPC_MXU_D16MACF:
27373             /* TODO: Implement emulation of D16MACF instruction. */
27374             MIPS_INVAL("OPC_MXU_D16MACF");
27375             generate_exception_end(ctx, EXCP_RI);
27376             break;
27377         case OPC_MXU_D16MADL:
27378             /* TODO: Implement emulation of D16MADL instruction. */
27379             MIPS_INVAL("OPC_MXU_D16MADL");
27380             generate_exception_end(ctx, EXCP_RI);
27381             break;
27382         case OPC_MXU_S16MAD:
27383             /* TODO: Implement emulation of S16MAD instruction. */
27384             MIPS_INVAL("OPC_MXU_S16MAD");
27385             generate_exception_end(ctx, EXCP_RI);
27386             break;
27387         case OPC_MXU_Q16ADD:
27388             /* TODO: Implement emulation of Q16ADD instruction. */
27389             MIPS_INVAL("OPC_MXU_Q16ADD");
27390             generate_exception_end(ctx, EXCP_RI);
27391             break;
27392         case OPC_MXU_D16MACE:
27393             /* TODO: Implement emulation of D16MACE instruction. */
27394             MIPS_INVAL("OPC_MXU_D16MACE");
27395             generate_exception_end(ctx, EXCP_RI);
27396             break;
27397         case OPC_MXU__POOL04:
27398             decode_opc_mxu__pool04(env, ctx);
27399             break;
27400         case OPC_MXU__POOL05:
27401             decode_opc_mxu__pool05(env, ctx);
27402             break;
27403         case OPC_MXU__POOL06:
27404             decode_opc_mxu__pool06(env, ctx);
27405             break;
27406         case OPC_MXU__POOL07:
27407             decode_opc_mxu__pool07(env, ctx);
27408             break;
27409         case OPC_MXU__POOL08:
27410             decode_opc_mxu__pool08(env, ctx);
27411             break;
27412         case OPC_MXU__POOL09:
27413             decode_opc_mxu__pool09(env, ctx);
27414             break;
27415         case OPC_MXU__POOL10:
27416             decode_opc_mxu__pool10(env, ctx);
27417             break;
27418         case OPC_MXU__POOL11:
27419             decode_opc_mxu__pool11(env, ctx);
27420             break;
27421         case OPC_MXU_D32ADD:
27422             /* TODO: Implement emulation of D32ADD instruction. */
27423             MIPS_INVAL("OPC_MXU_D32ADD");
27424             generate_exception_end(ctx, EXCP_RI);
27425             break;
27426         case OPC_MXU__POOL12:
27427             decode_opc_mxu__pool12(env, ctx);
27428             break;
27429         case OPC_MXU__POOL13:
27430             decode_opc_mxu__pool13(env, ctx);
27431             break;
27432         case OPC_MXU__POOL14:
27433             decode_opc_mxu__pool14(env, ctx);
27434             break;
27435         case OPC_MXU_Q8ACCE:
27436             /* TODO: Implement emulation of Q8ACCE instruction. */
27437             MIPS_INVAL("OPC_MXU_Q8ACCE");
27438             generate_exception_end(ctx, EXCP_RI);
27439             break;
27440         case OPC_MXU_S8LDD:
27441             gen_mxu_s8ldd(ctx);
27442             break;
27443         case OPC_MXU_S8STD:
27444             /* TODO: Implement emulation of S8STD instruction. */
27445             MIPS_INVAL("OPC_MXU_S8STD");
27446             generate_exception_end(ctx, EXCP_RI);
27447             break;
27448         case OPC_MXU_S8LDI:
27449             /* TODO: Implement emulation of S8LDI instruction. */
27450             MIPS_INVAL("OPC_MXU_S8LDI");
27451             generate_exception_end(ctx, EXCP_RI);
27452             break;
27453         case OPC_MXU_S8SDI:
27454             /* TODO: Implement emulation of S8SDI instruction. */
27455             MIPS_INVAL("OPC_MXU_S8SDI");
27456             generate_exception_end(ctx, EXCP_RI);
27457             break;
27458         case OPC_MXU__POOL15:
27459             decode_opc_mxu__pool15(env, ctx);
27460             break;
27461         case OPC_MXU__POOL16:
27462             decode_opc_mxu__pool16(env, ctx);
27463             break;
27464         case OPC_MXU__POOL17:
27465             decode_opc_mxu__pool17(env, ctx);
27466             break;
27467         case OPC_MXU_S16LDD:
27468             /* TODO: Implement emulation of S16LDD instruction. */
27469             MIPS_INVAL("OPC_MXU_S16LDD");
27470             generate_exception_end(ctx, EXCP_RI);
27471             break;
27472         case OPC_MXU_S16STD:
27473             /* TODO: Implement emulation of S16STD instruction. */
27474             MIPS_INVAL("OPC_MXU_S16STD");
27475             generate_exception_end(ctx, EXCP_RI);
27476             break;
27477         case OPC_MXU_S16LDI:
27478             /* TODO: Implement emulation of S16LDI instruction. */
27479             MIPS_INVAL("OPC_MXU_S16LDI");
27480             generate_exception_end(ctx, EXCP_RI);
27481             break;
27482         case OPC_MXU_S16SDI:
27483             /* TODO: Implement emulation of S16SDI instruction. */
27484             MIPS_INVAL("OPC_MXU_S16SDI");
27485             generate_exception_end(ctx, EXCP_RI);
27486             break;
27487         case OPC_MXU_D32SLL:
27488             /* TODO: Implement emulation of D32SLL instruction. */
27489             MIPS_INVAL("OPC_MXU_D32SLL");
27490             generate_exception_end(ctx, EXCP_RI);
27491             break;
27492         case OPC_MXU_D32SLR:
27493             /* TODO: Implement emulation of D32SLR instruction. */
27494             MIPS_INVAL("OPC_MXU_D32SLR");
27495             generate_exception_end(ctx, EXCP_RI);
27496             break;
27497         case OPC_MXU_D32SARL:
27498             /* TODO: Implement emulation of D32SARL instruction. */
27499             MIPS_INVAL("OPC_MXU_D32SARL");
27500             generate_exception_end(ctx, EXCP_RI);
27501             break;
27502         case OPC_MXU_D32SAR:
27503             /* TODO: Implement emulation of D32SAR instruction. */
27504             MIPS_INVAL("OPC_MXU_D32SAR");
27505             generate_exception_end(ctx, EXCP_RI);
27506             break;
27507         case OPC_MXU_Q16SLL:
27508             /* TODO: Implement emulation of Q16SLL instruction. */
27509             MIPS_INVAL("OPC_MXU_Q16SLL");
27510             generate_exception_end(ctx, EXCP_RI);
27511             break;
27512         case OPC_MXU_Q16SLR:
27513             /* TODO: Implement emulation of Q16SLR instruction. */
27514             MIPS_INVAL("OPC_MXU_Q16SLR");
27515             generate_exception_end(ctx, EXCP_RI);
27516             break;
27517         case OPC_MXU__POOL18:
27518             decode_opc_mxu__pool18(env, ctx);
27519             break;
27520         case OPC_MXU_Q16SAR:
27521             /* TODO: Implement emulation of Q16SAR instruction. */
27522             MIPS_INVAL("OPC_MXU_Q16SAR");
27523             generate_exception_end(ctx, EXCP_RI);
27524             break;
27525         case OPC_MXU__POOL19:
27526             decode_opc_mxu__pool19(env, ctx);
27527             break;
27528         case OPC_MXU__POOL20:
27529             decode_opc_mxu__pool20(env, ctx);
27530             break;
27531         case OPC_MXU__POOL21:
27532             decode_opc_mxu__pool21(env, ctx);
27533             break;
27534         case OPC_MXU_Q16SCOP:
27535             /* TODO: Implement emulation of Q16SCOP instruction. */
27536             MIPS_INVAL("OPC_MXU_Q16SCOP");
27537             generate_exception_end(ctx, EXCP_RI);
27538             break;
27539         case OPC_MXU_Q8MADL:
27540             /* TODO: Implement emulation of Q8MADL instruction. */
27541             MIPS_INVAL("OPC_MXU_Q8MADL");
27542             generate_exception_end(ctx, EXCP_RI);
27543             break;
27544         case OPC_MXU_S32SFL:
27545             /* TODO: Implement emulation of S32SFL instruction. */
27546             MIPS_INVAL("OPC_MXU_S32SFL");
27547             generate_exception_end(ctx, EXCP_RI);
27548             break;
27549         case OPC_MXU_Q8SAD:
27550             /* TODO: Implement emulation of Q8SAD instruction. */
27551             MIPS_INVAL("OPC_MXU_Q8SAD");
27552             generate_exception_end(ctx, EXCP_RI);
27553             break;
27554         default:
27555             MIPS_INVAL("decode_opc_mxu");
27556             generate_exception_end(ctx, EXCP_RI);
27557         }
27558 
27559         gen_set_label(l_exit);
27560         tcg_temp_free(t_mxu_cr);
27561     }
27562 }
27563 
27564 #endif /* !defined(TARGET_MIPS64) */
27565 
27566 
decode_opc_special2_legacy(CPUMIPSState * env,DisasContext * ctx)27567 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
27568 {
27569     int rs, rt, rd;
27570     uint32_t op1;
27571 
27572     check_insn_opc_removed(ctx, ISA_MIPS32R6);
27573 
27574     rs = (ctx->opcode >> 21) & 0x1f;
27575     rt = (ctx->opcode >> 16) & 0x1f;
27576     rd = (ctx->opcode >> 11) & 0x1f;
27577 
27578     op1 = MASK_SPECIAL2(ctx->opcode);
27579     switch (op1) {
27580     case OPC_MADD: /* Multiply and add/sub */
27581     case OPC_MADDU:
27582     case OPC_MSUB:
27583     case OPC_MSUBU:
27584         check_insn(ctx, ISA_MIPS32);
27585         gen_muldiv(ctx, op1, rd & 3, rs, rt);
27586         break;
27587     case OPC_MUL:
27588         gen_arith(ctx, op1, rd, rs, rt);
27589         break;
27590     case OPC_DIV_G_2F:
27591     case OPC_DIVU_G_2F:
27592     case OPC_MULT_G_2F:
27593     case OPC_MULTU_G_2F:
27594     case OPC_MOD_G_2F:
27595     case OPC_MODU_G_2F:
27596         check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT);
27597         gen_loongson_integer(ctx, op1, rd, rs, rt);
27598         break;
27599     case OPC_CLO:
27600     case OPC_CLZ:
27601         check_insn(ctx, ISA_MIPS32);
27602         gen_cl(ctx, op1, rd, rs);
27603         break;
27604     case OPC_SDBBP:
27605         if (is_uhi(extract32(ctx->opcode, 6, 20))) {
27606             gen_helper_do_semihosting(cpu_env);
27607         } else {
27608             /*
27609              * XXX: not clear which exception should be raised
27610              *      when in debug mode...
27611              */
27612             check_insn(ctx, ISA_MIPS32);
27613             generate_exception_end(ctx, EXCP_DBp);
27614         }
27615         break;
27616 #if defined(TARGET_MIPS64)
27617     case OPC_DCLO:
27618     case OPC_DCLZ:
27619         check_insn(ctx, ISA_MIPS64);
27620         check_mips_64(ctx);
27621         gen_cl(ctx, op1, rd, rs);
27622         break;
27623     case OPC_DMULT_G_2F:
27624     case OPC_DMULTU_G_2F:
27625     case OPC_DDIV_G_2F:
27626     case OPC_DDIVU_G_2F:
27627     case OPC_DMOD_G_2F:
27628     case OPC_DMODU_G_2F:
27629         check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT);
27630         gen_loongson_integer(ctx, op1, rd, rs, rt);
27631         break;
27632 #endif
27633     default:            /* Invalid */
27634         MIPS_INVAL("special2_legacy");
27635         generate_exception_end(ctx, EXCP_RI);
27636         break;
27637     }
27638 }
27639 
decode_opc_special3_r6(CPUMIPSState * env,DisasContext * ctx)27640 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
27641 {
27642     int rs, rt, rd, sa;
27643     uint32_t op1, op2;
27644     int16_t imm;
27645 
27646     rs = (ctx->opcode >> 21) & 0x1f;
27647     rt = (ctx->opcode >> 16) & 0x1f;
27648     rd = (ctx->opcode >> 11) & 0x1f;
27649     sa = (ctx->opcode >> 6) & 0x1f;
27650     imm = (int16_t)ctx->opcode >> 7;
27651 
27652     op1 = MASK_SPECIAL3(ctx->opcode);
27653     switch (op1) {
27654     case R6_OPC_PREF:
27655         if (rt >= 24) {
27656             /* hint codes 24-31 are reserved and signal RI */
27657             generate_exception_end(ctx, EXCP_RI);
27658         }
27659         /* Treat as NOP. */
27660         break;
27661     case R6_OPC_CACHE:
27662         check_cp0_enabled(ctx);
27663         if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
27664             gen_cache_operation(ctx, rt, rs, imm);
27665         }
27666         break;
27667     case R6_OPC_SC:
27668         gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
27669         break;
27670     case R6_OPC_LL:
27671         gen_ld(ctx, op1, rt, rs, imm);
27672         break;
27673     case OPC_BSHFL:
27674         {
27675             if (rd == 0) {
27676                 /* Treat as NOP. */
27677                 break;
27678             }
27679             op2 = MASK_BSHFL(ctx->opcode);
27680             switch (op2) {
27681             case OPC_ALIGN:
27682             case OPC_ALIGN_1:
27683             case OPC_ALIGN_2:
27684             case OPC_ALIGN_3:
27685                 gen_align(ctx, 32, rd, rs, rt, sa & 3);
27686                 break;
27687             case OPC_BITSWAP:
27688                 gen_bitswap(ctx, op2, rd, rt);
27689                 break;
27690             }
27691         }
27692         break;
27693 #ifndef CONFIG_USER_ONLY
27694     case OPC_GINV:
27695         if (unlikely(ctx->gi <= 1)) {
27696             generate_exception_end(ctx, EXCP_RI);
27697         }
27698         check_cp0_enabled(ctx);
27699         switch ((ctx->opcode >> 6) & 3) {
27700         case 0:    /* GINVI */
27701             /* Treat as NOP. */
27702             break;
27703         case 2:    /* GINVT */
27704             gen_helper_0e1i(ginvt, cpu_gpr[rs], extract32(ctx->opcode, 8, 2));
27705             break;
27706         default:
27707             generate_exception_end(ctx, EXCP_RI);
27708             break;
27709         }
27710         break;
27711 #endif
27712 #if defined(TARGET_MIPS64)
27713     case R6_OPC_SCD:
27714         gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false);
27715         break;
27716     case R6_OPC_LLD:
27717         gen_ld(ctx, op1, rt, rs, imm);
27718         break;
27719     case OPC_DBSHFL:
27720         check_mips_64(ctx);
27721         {
27722             if (rd == 0) {
27723                 /* Treat as NOP. */
27724                 break;
27725             }
27726             op2 = MASK_DBSHFL(ctx->opcode);
27727             switch (op2) {
27728             case OPC_DALIGN:
27729             case OPC_DALIGN_1:
27730             case OPC_DALIGN_2:
27731             case OPC_DALIGN_3:
27732             case OPC_DALIGN_4:
27733             case OPC_DALIGN_5:
27734             case OPC_DALIGN_6:
27735             case OPC_DALIGN_7:
27736                 gen_align(ctx, 64, rd, rs, rt, sa & 7);
27737                 break;
27738             case OPC_DBITSWAP:
27739                 gen_bitswap(ctx, op2, rd, rt);
27740                 break;
27741             }
27742 
27743         }
27744         break;
27745 #endif
27746     default:            /* Invalid */
27747         MIPS_INVAL("special3_r6");
27748         generate_exception_end(ctx, EXCP_RI);
27749         break;
27750     }
27751 }
27752 
decode_opc_special3_legacy(CPUMIPSState * env,DisasContext * ctx)27753 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
27754 {
27755     int rs, rt, rd;
27756     uint32_t op1, op2;
27757 
27758     rs = (ctx->opcode >> 21) & 0x1f;
27759     rt = (ctx->opcode >> 16) & 0x1f;
27760     rd = (ctx->opcode >> 11) & 0x1f;
27761 
27762     op1 = MASK_SPECIAL3(ctx->opcode);
27763     switch (op1) {
27764     case OPC_DIV_G_2E:
27765     case OPC_DIVU_G_2E:
27766     case OPC_MOD_G_2E:
27767     case OPC_MODU_G_2E:
27768     case OPC_MULT_G_2E:
27769     case OPC_MULTU_G_2E:
27770         /*
27771          * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
27772          * the same mask and op1.
27773          */
27774         if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
27775             op2 = MASK_ADDUH_QB(ctx->opcode);
27776             switch (op2) {
27777             case OPC_ADDUH_QB:
27778             case OPC_ADDUH_R_QB:
27779             case OPC_ADDQH_PH:
27780             case OPC_ADDQH_R_PH:
27781             case OPC_ADDQH_W:
27782             case OPC_ADDQH_R_W:
27783             case OPC_SUBUH_QB:
27784             case OPC_SUBUH_R_QB:
27785             case OPC_SUBQH_PH:
27786             case OPC_SUBQH_R_PH:
27787             case OPC_SUBQH_W:
27788             case OPC_SUBQH_R_W:
27789                 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27790                 break;
27791             case OPC_MUL_PH:
27792             case OPC_MUL_S_PH:
27793             case OPC_MULQ_S_W:
27794             case OPC_MULQ_RS_W:
27795                 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
27796                 break;
27797             default:
27798                 MIPS_INVAL("MASK ADDUH.QB");
27799                 generate_exception_end(ctx, EXCP_RI);
27800                 break;
27801             }
27802         } else if (ctx->insn_flags & INSN_LOONGSON2E) {
27803             gen_loongson_integer(ctx, op1, rd, rs, rt);
27804         } else {
27805             generate_exception_end(ctx, EXCP_RI);
27806         }
27807         break;
27808     case OPC_LX_DSP:
27809         op2 = MASK_LX(ctx->opcode);
27810         switch (op2) {
27811 #if defined(TARGET_MIPS64)
27812         case OPC_LDX:
27813 #endif
27814         case OPC_LBUX:
27815         case OPC_LHX:
27816         case OPC_LWX:
27817             gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
27818             break;
27819         default:            /* Invalid */
27820             MIPS_INVAL("MASK LX");
27821             generate_exception_end(ctx, EXCP_RI);
27822             break;
27823         }
27824         break;
27825     case OPC_ABSQ_S_PH_DSP:
27826         op2 = MASK_ABSQ_S_PH(ctx->opcode);
27827         switch (op2) {
27828         case OPC_ABSQ_S_QB:
27829         case OPC_ABSQ_S_PH:
27830         case OPC_ABSQ_S_W:
27831         case OPC_PRECEQ_W_PHL:
27832         case OPC_PRECEQ_W_PHR:
27833         case OPC_PRECEQU_PH_QBL:
27834         case OPC_PRECEQU_PH_QBR:
27835         case OPC_PRECEQU_PH_QBLA:
27836         case OPC_PRECEQU_PH_QBRA:
27837         case OPC_PRECEU_PH_QBL:
27838         case OPC_PRECEU_PH_QBR:
27839         case OPC_PRECEU_PH_QBLA:
27840         case OPC_PRECEU_PH_QBRA:
27841             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27842             break;
27843         case OPC_BITREV:
27844         case OPC_REPL_QB:
27845         case OPC_REPLV_QB:
27846         case OPC_REPL_PH:
27847         case OPC_REPLV_PH:
27848             gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
27849             break;
27850         default:
27851             MIPS_INVAL("MASK ABSQ_S.PH");
27852             generate_exception_end(ctx, EXCP_RI);
27853             break;
27854         }
27855         break;
27856     case OPC_ADDU_QB_DSP:
27857         op2 = MASK_ADDU_QB(ctx->opcode);
27858         switch (op2) {
27859         case OPC_ADDQ_PH:
27860         case OPC_ADDQ_S_PH:
27861         case OPC_ADDQ_S_W:
27862         case OPC_ADDU_QB:
27863         case OPC_ADDU_S_QB:
27864         case OPC_ADDU_PH:
27865         case OPC_ADDU_S_PH:
27866         case OPC_SUBQ_PH:
27867         case OPC_SUBQ_S_PH:
27868         case OPC_SUBQ_S_W:
27869         case OPC_SUBU_QB:
27870         case OPC_SUBU_S_QB:
27871         case OPC_SUBU_PH:
27872         case OPC_SUBU_S_PH:
27873         case OPC_ADDSC:
27874         case OPC_ADDWC:
27875         case OPC_MODSUB:
27876         case OPC_RADDU_W_QB:
27877             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27878             break;
27879         case OPC_MULEU_S_PH_QBL:
27880         case OPC_MULEU_S_PH_QBR:
27881         case OPC_MULQ_RS_PH:
27882         case OPC_MULEQ_S_W_PHL:
27883         case OPC_MULEQ_S_W_PHR:
27884         case OPC_MULQ_S_PH:
27885             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
27886             break;
27887         default:            /* Invalid */
27888             MIPS_INVAL("MASK ADDU.QB");
27889             generate_exception_end(ctx, EXCP_RI);
27890             break;
27891 
27892         }
27893         break;
27894     case OPC_CMPU_EQ_QB_DSP:
27895         op2 = MASK_CMPU_EQ_QB(ctx->opcode);
27896         switch (op2) {
27897         case OPC_PRECR_SRA_PH_W:
27898         case OPC_PRECR_SRA_R_PH_W:
27899             gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
27900             break;
27901         case OPC_PRECR_QB_PH:
27902         case OPC_PRECRQ_QB_PH:
27903         case OPC_PRECRQ_PH_W:
27904         case OPC_PRECRQ_RS_PH_W:
27905         case OPC_PRECRQU_S_QB_PH:
27906             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27907             break;
27908         case OPC_CMPU_EQ_QB:
27909         case OPC_CMPU_LT_QB:
27910         case OPC_CMPU_LE_QB:
27911         case OPC_CMP_EQ_PH:
27912         case OPC_CMP_LT_PH:
27913         case OPC_CMP_LE_PH:
27914             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
27915             break;
27916         case OPC_CMPGU_EQ_QB:
27917         case OPC_CMPGU_LT_QB:
27918         case OPC_CMPGU_LE_QB:
27919         case OPC_CMPGDU_EQ_QB:
27920         case OPC_CMPGDU_LT_QB:
27921         case OPC_CMPGDU_LE_QB:
27922         case OPC_PICK_QB:
27923         case OPC_PICK_PH:
27924         case OPC_PACKRL_PH:
27925             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
27926             break;
27927         default:            /* Invalid */
27928             MIPS_INVAL("MASK CMPU.EQ.QB");
27929             generate_exception_end(ctx, EXCP_RI);
27930             break;
27931         }
27932         break;
27933     case OPC_SHLL_QB_DSP:
27934         gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
27935         break;
27936     case OPC_DPA_W_PH_DSP:
27937         op2 = MASK_DPA_W_PH(ctx->opcode);
27938         switch (op2) {
27939         case OPC_DPAU_H_QBL:
27940         case OPC_DPAU_H_QBR:
27941         case OPC_DPSU_H_QBL:
27942         case OPC_DPSU_H_QBR:
27943         case OPC_DPA_W_PH:
27944         case OPC_DPAX_W_PH:
27945         case OPC_DPAQ_S_W_PH:
27946         case OPC_DPAQX_S_W_PH:
27947         case OPC_DPAQX_SA_W_PH:
27948         case OPC_DPS_W_PH:
27949         case OPC_DPSX_W_PH:
27950         case OPC_DPSQ_S_W_PH:
27951         case OPC_DPSQX_S_W_PH:
27952         case OPC_DPSQX_SA_W_PH:
27953         case OPC_MULSAQ_S_W_PH:
27954         case OPC_DPAQ_SA_L_W:
27955         case OPC_DPSQ_SA_L_W:
27956         case OPC_MAQ_S_W_PHL:
27957         case OPC_MAQ_S_W_PHR:
27958         case OPC_MAQ_SA_W_PHL:
27959         case OPC_MAQ_SA_W_PHR:
27960         case OPC_MULSA_W_PH:
27961             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
27962             break;
27963         default:            /* Invalid */
27964             MIPS_INVAL("MASK DPAW.PH");
27965             generate_exception_end(ctx, EXCP_RI);
27966             break;
27967         }
27968         break;
27969     case OPC_INSV_DSP:
27970         op2 = MASK_INSV(ctx->opcode);
27971         switch (op2) {
27972         case OPC_INSV:
27973             check_dsp(ctx);
27974             {
27975                 TCGv t0, t1;
27976 
27977                 if (rt == 0) {
27978                     break;
27979                 }
27980 
27981                 t0 = tcg_temp_new();
27982                 t1 = tcg_temp_new();
27983 
27984                 gen_load_gpr(t0, rt);
27985                 gen_load_gpr(t1, rs);
27986 
27987                 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
27988 
27989                 tcg_temp_free(t0);
27990                 tcg_temp_free(t1);
27991                 break;
27992             }
27993         default:            /* Invalid */
27994             MIPS_INVAL("MASK INSV");
27995             generate_exception_end(ctx, EXCP_RI);
27996             break;
27997         }
27998         break;
27999     case OPC_APPEND_DSP:
28000         gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
28001         break;
28002     case OPC_EXTR_W_DSP:
28003         op2 = MASK_EXTR_W(ctx->opcode);
28004         switch (op2) {
28005         case OPC_EXTR_W:
28006         case OPC_EXTR_R_W:
28007         case OPC_EXTR_RS_W:
28008         case OPC_EXTR_S_H:
28009         case OPC_EXTRV_S_H:
28010         case OPC_EXTRV_W:
28011         case OPC_EXTRV_R_W:
28012         case OPC_EXTRV_RS_W:
28013         case OPC_EXTP:
28014         case OPC_EXTPV:
28015         case OPC_EXTPDP:
28016         case OPC_EXTPDPV:
28017             gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
28018             break;
28019         case OPC_RDDSP:
28020             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
28021             break;
28022         case OPC_SHILO:
28023         case OPC_SHILOV:
28024         case OPC_MTHLIP:
28025         case OPC_WRDSP:
28026             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
28027             break;
28028         default:            /* Invalid */
28029             MIPS_INVAL("MASK EXTR.W");
28030             generate_exception_end(ctx, EXCP_RI);
28031             break;
28032         }
28033         break;
28034 #if defined(TARGET_MIPS64)
28035     case OPC_DDIV_G_2E:
28036     case OPC_DDIVU_G_2E:
28037     case OPC_DMULT_G_2E:
28038     case OPC_DMULTU_G_2E:
28039     case OPC_DMOD_G_2E:
28040     case OPC_DMODU_G_2E:
28041         check_insn(ctx, INSN_LOONGSON2E);
28042         gen_loongson_integer(ctx, op1, rd, rs, rt);
28043         break;
28044     case OPC_ABSQ_S_QH_DSP:
28045         op2 = MASK_ABSQ_S_QH(ctx->opcode);
28046         switch (op2) {
28047         case OPC_PRECEQ_L_PWL:
28048         case OPC_PRECEQ_L_PWR:
28049         case OPC_PRECEQ_PW_QHL:
28050         case OPC_PRECEQ_PW_QHR:
28051         case OPC_PRECEQ_PW_QHLA:
28052         case OPC_PRECEQ_PW_QHRA:
28053         case OPC_PRECEQU_QH_OBL:
28054         case OPC_PRECEQU_QH_OBR:
28055         case OPC_PRECEQU_QH_OBLA:
28056         case OPC_PRECEQU_QH_OBRA:
28057         case OPC_PRECEU_QH_OBL:
28058         case OPC_PRECEU_QH_OBR:
28059         case OPC_PRECEU_QH_OBLA:
28060         case OPC_PRECEU_QH_OBRA:
28061         case OPC_ABSQ_S_OB:
28062         case OPC_ABSQ_S_PW:
28063         case OPC_ABSQ_S_QH:
28064             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
28065             break;
28066         case OPC_REPL_OB:
28067         case OPC_REPL_PW:
28068         case OPC_REPL_QH:
28069         case OPC_REPLV_OB:
28070         case OPC_REPLV_PW:
28071         case OPC_REPLV_QH:
28072             gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
28073             break;
28074         default:            /* Invalid */
28075             MIPS_INVAL("MASK ABSQ_S.QH");
28076             generate_exception_end(ctx, EXCP_RI);
28077             break;
28078         }
28079         break;
28080     case OPC_ADDU_OB_DSP:
28081         op2 = MASK_ADDU_OB(ctx->opcode);
28082         switch (op2) {
28083         case OPC_RADDU_L_OB:
28084         case OPC_SUBQ_PW:
28085         case OPC_SUBQ_S_PW:
28086         case OPC_SUBQ_QH:
28087         case OPC_SUBQ_S_QH:
28088         case OPC_SUBU_OB:
28089         case OPC_SUBU_S_OB:
28090         case OPC_SUBU_QH:
28091         case OPC_SUBU_S_QH:
28092         case OPC_SUBUH_OB:
28093         case OPC_SUBUH_R_OB:
28094         case OPC_ADDQ_PW:
28095         case OPC_ADDQ_S_PW:
28096         case OPC_ADDQ_QH:
28097         case OPC_ADDQ_S_QH:
28098         case OPC_ADDU_OB:
28099         case OPC_ADDU_S_OB:
28100         case OPC_ADDU_QH:
28101         case OPC_ADDU_S_QH:
28102         case OPC_ADDUH_OB:
28103         case OPC_ADDUH_R_OB:
28104             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
28105             break;
28106         case OPC_MULEQ_S_PW_QHL:
28107         case OPC_MULEQ_S_PW_QHR:
28108         case OPC_MULEU_S_QH_OBL:
28109         case OPC_MULEU_S_QH_OBR:
28110         case OPC_MULQ_RS_QH:
28111             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
28112             break;
28113         default:            /* Invalid */
28114             MIPS_INVAL("MASK ADDU.OB");
28115             generate_exception_end(ctx, EXCP_RI);
28116             break;
28117         }
28118         break;
28119     case OPC_CMPU_EQ_OB_DSP:
28120         op2 = MASK_CMPU_EQ_OB(ctx->opcode);
28121         switch (op2) {
28122         case OPC_PRECR_SRA_QH_PW:
28123         case OPC_PRECR_SRA_R_QH_PW:
28124             /* Return value is rt. */
28125             gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
28126             break;
28127         case OPC_PRECR_OB_QH:
28128         case OPC_PRECRQ_OB_QH:
28129         case OPC_PRECRQ_PW_L:
28130         case OPC_PRECRQ_QH_PW:
28131         case OPC_PRECRQ_RS_QH_PW:
28132         case OPC_PRECRQU_S_OB_QH:
28133             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
28134             break;
28135         case OPC_CMPU_EQ_OB:
28136         case OPC_CMPU_LT_OB:
28137         case OPC_CMPU_LE_OB:
28138         case OPC_CMP_EQ_QH:
28139         case OPC_CMP_LT_QH:
28140         case OPC_CMP_LE_QH:
28141         case OPC_CMP_EQ_PW:
28142         case OPC_CMP_LT_PW:
28143         case OPC_CMP_LE_PW:
28144             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
28145             break;
28146         case OPC_CMPGDU_EQ_OB:
28147         case OPC_CMPGDU_LT_OB:
28148         case OPC_CMPGDU_LE_OB:
28149         case OPC_CMPGU_EQ_OB:
28150         case OPC_CMPGU_LT_OB:
28151         case OPC_CMPGU_LE_OB:
28152         case OPC_PACKRL_PW:
28153         case OPC_PICK_OB:
28154         case OPC_PICK_PW:
28155         case OPC_PICK_QH:
28156             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
28157             break;
28158         default:            /* Invalid */
28159             MIPS_INVAL("MASK CMPU_EQ.OB");
28160             generate_exception_end(ctx, EXCP_RI);
28161             break;
28162         }
28163         break;
28164     case OPC_DAPPEND_DSP:
28165         gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
28166         break;
28167     case OPC_DEXTR_W_DSP:
28168         op2 = MASK_DEXTR_W(ctx->opcode);
28169         switch (op2) {
28170         case OPC_DEXTP:
28171         case OPC_DEXTPDP:
28172         case OPC_DEXTPDPV:
28173         case OPC_DEXTPV:
28174         case OPC_DEXTR_L:
28175         case OPC_DEXTR_R_L:
28176         case OPC_DEXTR_RS_L:
28177         case OPC_DEXTR_W:
28178         case OPC_DEXTR_R_W:
28179         case OPC_DEXTR_RS_W:
28180         case OPC_DEXTR_S_H:
28181         case OPC_DEXTRV_L:
28182         case OPC_DEXTRV_R_L:
28183         case OPC_DEXTRV_RS_L:
28184         case OPC_DEXTRV_S_H:
28185         case OPC_DEXTRV_W:
28186         case OPC_DEXTRV_R_W:
28187         case OPC_DEXTRV_RS_W:
28188             gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
28189             break;
28190         case OPC_DMTHLIP:
28191         case OPC_DSHILO:
28192         case OPC_DSHILOV:
28193             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
28194             break;
28195         default:            /* Invalid */
28196             MIPS_INVAL("MASK EXTR.W");
28197             generate_exception_end(ctx, EXCP_RI);
28198             break;
28199         }
28200         break;
28201     case OPC_DPAQ_W_QH_DSP:
28202         op2 = MASK_DPAQ_W_QH(ctx->opcode);
28203         switch (op2) {
28204         case OPC_DPAU_H_OBL:
28205         case OPC_DPAU_H_OBR:
28206         case OPC_DPSU_H_OBL:
28207         case OPC_DPSU_H_OBR:
28208         case OPC_DPA_W_QH:
28209         case OPC_DPAQ_S_W_QH:
28210         case OPC_DPS_W_QH:
28211         case OPC_DPSQ_S_W_QH:
28212         case OPC_MULSAQ_S_W_QH:
28213         case OPC_DPAQ_SA_L_PW:
28214         case OPC_DPSQ_SA_L_PW:
28215         case OPC_MULSAQ_S_L_PW:
28216             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
28217             break;
28218         case OPC_MAQ_S_W_QHLL:
28219         case OPC_MAQ_S_W_QHLR:
28220         case OPC_MAQ_S_W_QHRL:
28221         case OPC_MAQ_S_W_QHRR:
28222         case OPC_MAQ_SA_W_QHLL:
28223         case OPC_MAQ_SA_W_QHLR:
28224         case OPC_MAQ_SA_W_QHRL:
28225         case OPC_MAQ_SA_W_QHRR:
28226         case OPC_MAQ_S_L_PWL:
28227         case OPC_MAQ_S_L_PWR:
28228         case OPC_DMADD:
28229         case OPC_DMADDU:
28230         case OPC_DMSUB:
28231         case OPC_DMSUBU:
28232             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
28233             break;
28234         default:            /* Invalid */
28235             MIPS_INVAL("MASK DPAQ.W.QH");
28236             generate_exception_end(ctx, EXCP_RI);
28237             break;
28238         }
28239         break;
28240     case OPC_DINSV_DSP:
28241         op2 = MASK_INSV(ctx->opcode);
28242         switch (op2) {
28243         case OPC_DINSV:
28244         {
28245             TCGv t0, t1;
28246 
28247             if (rt == 0) {
28248                 break;
28249             }
28250             check_dsp(ctx);
28251 
28252             t0 = tcg_temp_new();
28253             t1 = tcg_temp_new();
28254 
28255             gen_load_gpr(t0, rt);
28256             gen_load_gpr(t1, rs);
28257 
28258             gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
28259 
28260             tcg_temp_free(t0);
28261             tcg_temp_free(t1);
28262             break;
28263         }
28264         default:            /* Invalid */
28265             MIPS_INVAL("MASK DINSV");
28266             generate_exception_end(ctx, EXCP_RI);
28267             break;
28268         }
28269         break;
28270     case OPC_SHLL_OB_DSP:
28271         gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
28272         break;
28273 #endif
28274     default:            /* Invalid */
28275         MIPS_INVAL("special3_legacy");
28276         generate_exception_end(ctx, EXCP_RI);
28277         break;
28278     }
28279 }
28280 
28281 
28282 #if defined(TARGET_MIPS64)
28283 
decode_mmi0(CPUMIPSState * env,DisasContext * ctx)28284 static void decode_mmi0(CPUMIPSState *env, DisasContext *ctx)
28285 {
28286     uint32_t opc = MASK_MMI0(ctx->opcode);
28287 
28288     switch (opc) {
28289     case MMI_OPC_0_PADDW:     /* TODO: MMI_OPC_0_PADDW */
28290     case MMI_OPC_0_PSUBW:     /* TODO: MMI_OPC_0_PSUBW */
28291     case MMI_OPC_0_PCGTW:     /* TODO: MMI_OPC_0_PCGTW */
28292     case MMI_OPC_0_PMAXW:     /* TODO: MMI_OPC_0_PMAXW */
28293     case MMI_OPC_0_PADDH:     /* TODO: MMI_OPC_0_PADDH */
28294     case MMI_OPC_0_PSUBH:     /* TODO: MMI_OPC_0_PSUBH */
28295     case MMI_OPC_0_PCGTH:     /* TODO: MMI_OPC_0_PCGTH */
28296     case MMI_OPC_0_PMAXH:     /* TODO: MMI_OPC_0_PMAXH */
28297     case MMI_OPC_0_PADDB:     /* TODO: MMI_OPC_0_PADDB */
28298     case MMI_OPC_0_PSUBB:     /* TODO: MMI_OPC_0_PSUBB */
28299     case MMI_OPC_0_PCGTB:     /* TODO: MMI_OPC_0_PCGTB */
28300     case MMI_OPC_0_PADDSW:    /* TODO: MMI_OPC_0_PADDSW */
28301     case MMI_OPC_0_PSUBSW:    /* TODO: MMI_OPC_0_PSUBSW */
28302     case MMI_OPC_0_PEXTLW:    /* TODO: MMI_OPC_0_PEXTLW */
28303     case MMI_OPC_0_PPACW:     /* TODO: MMI_OPC_0_PPACW */
28304     case MMI_OPC_0_PADDSH:    /* TODO: MMI_OPC_0_PADDSH */
28305     case MMI_OPC_0_PSUBSH:    /* TODO: MMI_OPC_0_PSUBSH */
28306     case MMI_OPC_0_PEXTLH:    /* TODO: MMI_OPC_0_PEXTLH */
28307     case MMI_OPC_0_PPACH:     /* TODO: MMI_OPC_0_PPACH */
28308     case MMI_OPC_0_PADDSB:    /* TODO: MMI_OPC_0_PADDSB */
28309     case MMI_OPC_0_PSUBSB:    /* TODO: MMI_OPC_0_PSUBSB */
28310     case MMI_OPC_0_PEXTLB:    /* TODO: MMI_OPC_0_PEXTLB */
28311     case MMI_OPC_0_PPACB:     /* TODO: MMI_OPC_0_PPACB */
28312     case MMI_OPC_0_PEXT5:     /* TODO: MMI_OPC_0_PEXT5 */
28313     case MMI_OPC_0_PPAC5:     /* TODO: MMI_OPC_0_PPAC5 */
28314         generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI0 */
28315         break;
28316     default:
28317         MIPS_INVAL("TX79 MMI class MMI0");
28318         generate_exception_end(ctx, EXCP_RI);
28319         break;
28320     }
28321 }
28322 
decode_mmi1(CPUMIPSState * env,DisasContext * ctx)28323 static void decode_mmi1(CPUMIPSState *env, DisasContext *ctx)
28324 {
28325     uint32_t opc = MASK_MMI1(ctx->opcode);
28326 
28327     switch (opc) {
28328     case MMI_OPC_1_PABSW:     /* TODO: MMI_OPC_1_PABSW */
28329     case MMI_OPC_1_PCEQW:     /* TODO: MMI_OPC_1_PCEQW */
28330     case MMI_OPC_1_PMINW:     /* TODO: MMI_OPC_1_PMINW */
28331     case MMI_OPC_1_PADSBH:    /* TODO: MMI_OPC_1_PADSBH */
28332     case MMI_OPC_1_PABSH:     /* TODO: MMI_OPC_1_PABSH */
28333     case MMI_OPC_1_PCEQH:     /* TODO: MMI_OPC_1_PCEQH */
28334     case MMI_OPC_1_PMINH:     /* TODO: MMI_OPC_1_PMINH */
28335     case MMI_OPC_1_PCEQB:     /* TODO: MMI_OPC_1_PCEQB */
28336     case MMI_OPC_1_PADDUW:    /* TODO: MMI_OPC_1_PADDUW */
28337     case MMI_OPC_1_PSUBUW:    /* TODO: MMI_OPC_1_PSUBUW */
28338     case MMI_OPC_1_PEXTUW:    /* TODO: MMI_OPC_1_PEXTUW */
28339     case MMI_OPC_1_PADDUH:    /* TODO: MMI_OPC_1_PADDUH */
28340     case MMI_OPC_1_PSUBUH:    /* TODO: MMI_OPC_1_PSUBUH */
28341     case MMI_OPC_1_PEXTUH:    /* TODO: MMI_OPC_1_PEXTUH */
28342     case MMI_OPC_1_PADDUB:    /* TODO: MMI_OPC_1_PADDUB */
28343     case MMI_OPC_1_PSUBUB:    /* TODO: MMI_OPC_1_PSUBUB */
28344     case MMI_OPC_1_PEXTUB:    /* TODO: MMI_OPC_1_PEXTUB */
28345     case MMI_OPC_1_QFSRV:     /* TODO: MMI_OPC_1_QFSRV */
28346         generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI1 */
28347         break;
28348     default:
28349         MIPS_INVAL("TX79 MMI class MMI1");
28350         generate_exception_end(ctx, EXCP_RI);
28351         break;
28352     }
28353 }
28354 
decode_mmi2(CPUMIPSState * env,DisasContext * ctx)28355 static void decode_mmi2(CPUMIPSState *env, DisasContext *ctx)
28356 {
28357     uint32_t opc = MASK_MMI2(ctx->opcode);
28358 
28359     switch (opc) {
28360     case MMI_OPC_2_PMADDW:    /* TODO: MMI_OPC_2_PMADDW */
28361     case MMI_OPC_2_PSLLVW:    /* TODO: MMI_OPC_2_PSLLVW */
28362     case MMI_OPC_2_PSRLVW:    /* TODO: MMI_OPC_2_PSRLVW */
28363     case MMI_OPC_2_PMSUBW:    /* TODO: MMI_OPC_2_PMSUBW */
28364     case MMI_OPC_2_PMFHI:     /* TODO: MMI_OPC_2_PMFHI */
28365     case MMI_OPC_2_PMFLO:     /* TODO: MMI_OPC_2_PMFLO */
28366     case MMI_OPC_2_PINTH:     /* TODO: MMI_OPC_2_PINTH */
28367     case MMI_OPC_2_PMULTW:    /* TODO: MMI_OPC_2_PMULTW */
28368     case MMI_OPC_2_PDIVW:     /* TODO: MMI_OPC_2_PDIVW */
28369     case MMI_OPC_2_PMADDH:    /* TODO: MMI_OPC_2_PMADDH */
28370     case MMI_OPC_2_PHMADH:    /* TODO: MMI_OPC_2_PHMADH */
28371     case MMI_OPC_2_PAND:      /* TODO: MMI_OPC_2_PAND */
28372     case MMI_OPC_2_PXOR:      /* TODO: MMI_OPC_2_PXOR */
28373     case MMI_OPC_2_PMSUBH:    /* TODO: MMI_OPC_2_PMSUBH */
28374     case MMI_OPC_2_PHMSBH:    /* TODO: MMI_OPC_2_PHMSBH */
28375     case MMI_OPC_2_PEXEH:     /* TODO: MMI_OPC_2_PEXEH */
28376     case MMI_OPC_2_PREVH:     /* TODO: MMI_OPC_2_PREVH */
28377     case MMI_OPC_2_PMULTH:    /* TODO: MMI_OPC_2_PMULTH */
28378     case MMI_OPC_2_PDIVBW:    /* TODO: MMI_OPC_2_PDIVBW */
28379     case MMI_OPC_2_PEXEW:     /* TODO: MMI_OPC_2_PEXEW */
28380     case MMI_OPC_2_PROT3W:    /* TODO: MMI_OPC_2_PROT3W */
28381         generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI2 */
28382         break;
28383     case MMI_OPC_2_PCPYLD:
28384         gen_mmi_pcpyld(ctx);
28385         break;
28386     default:
28387         MIPS_INVAL("TX79 MMI class MMI2");
28388         generate_exception_end(ctx, EXCP_RI);
28389         break;
28390     }
28391 }
28392 
decode_mmi3(CPUMIPSState * env,DisasContext * ctx)28393 static void decode_mmi3(CPUMIPSState *env, DisasContext *ctx)
28394 {
28395     uint32_t opc = MASK_MMI3(ctx->opcode);
28396 
28397     switch (opc) {
28398     case MMI_OPC_3_PMADDUW:    /* TODO: MMI_OPC_3_PMADDUW */
28399     case MMI_OPC_3_PSRAVW:     /* TODO: MMI_OPC_3_PSRAVW */
28400     case MMI_OPC_3_PMTHI:      /* TODO: MMI_OPC_3_PMTHI */
28401     case MMI_OPC_3_PMTLO:      /* TODO: MMI_OPC_3_PMTLO */
28402     case MMI_OPC_3_PINTEH:     /* TODO: MMI_OPC_3_PINTEH */
28403     case MMI_OPC_3_PMULTUW:    /* TODO: MMI_OPC_3_PMULTUW */
28404     case MMI_OPC_3_PDIVUW:     /* TODO: MMI_OPC_3_PDIVUW */
28405     case MMI_OPC_3_POR:        /* TODO: MMI_OPC_3_POR */
28406     case MMI_OPC_3_PNOR:       /* TODO: MMI_OPC_3_PNOR */
28407     case MMI_OPC_3_PEXCH:      /* TODO: MMI_OPC_3_PEXCH */
28408     case MMI_OPC_3_PEXCW:      /* TODO: MMI_OPC_3_PEXCW */
28409         generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI3 */
28410         break;
28411     case MMI_OPC_3_PCPYH:
28412         gen_mmi_pcpyh(ctx);
28413         break;
28414     case MMI_OPC_3_PCPYUD:
28415         gen_mmi_pcpyud(ctx);
28416         break;
28417     default:
28418         MIPS_INVAL("TX79 MMI class MMI3");
28419         generate_exception_end(ctx, EXCP_RI);
28420         break;
28421     }
28422 }
28423 
decode_mmi(CPUMIPSState * env,DisasContext * ctx)28424 static void decode_mmi(CPUMIPSState *env, DisasContext *ctx)
28425 {
28426     uint32_t opc = MASK_MMI(ctx->opcode);
28427     int rs = extract32(ctx->opcode, 21, 5);
28428     int rt = extract32(ctx->opcode, 16, 5);
28429     int rd = extract32(ctx->opcode, 11, 5);
28430 
28431     switch (opc) {
28432     case MMI_OPC_CLASS_MMI0:
28433         decode_mmi0(env, ctx);
28434         break;
28435     case MMI_OPC_CLASS_MMI1:
28436         decode_mmi1(env, ctx);
28437         break;
28438     case MMI_OPC_CLASS_MMI2:
28439         decode_mmi2(env, ctx);
28440         break;
28441     case MMI_OPC_CLASS_MMI3:
28442         decode_mmi3(env, ctx);
28443         break;
28444     case MMI_OPC_MULT1:
28445     case MMI_OPC_MULTU1:
28446     case MMI_OPC_MADD:
28447     case MMI_OPC_MADDU:
28448     case MMI_OPC_MADD1:
28449     case MMI_OPC_MADDU1:
28450         gen_mul_txx9(ctx, opc, rd, rs, rt);
28451         break;
28452     case MMI_OPC_DIV1:
28453     case MMI_OPC_DIVU1:
28454         gen_div1_tx79(ctx, opc, rs, rt);
28455         break;
28456     case MMI_OPC_MTLO1:
28457     case MMI_OPC_MTHI1:
28458         gen_HILO1_tx79(ctx, opc, rs);
28459         break;
28460     case MMI_OPC_MFLO1:
28461     case MMI_OPC_MFHI1:
28462         gen_HILO1_tx79(ctx, opc, rd);
28463         break;
28464     case MMI_OPC_PLZCW:         /* TODO: MMI_OPC_PLZCW */
28465     case MMI_OPC_PMFHL:         /* TODO: MMI_OPC_PMFHL */
28466     case MMI_OPC_PMTHL:         /* TODO: MMI_OPC_PMTHL */
28467     case MMI_OPC_PSLLH:         /* TODO: MMI_OPC_PSLLH */
28468     case MMI_OPC_PSRLH:         /* TODO: MMI_OPC_PSRLH */
28469     case MMI_OPC_PSRAH:         /* TODO: MMI_OPC_PSRAH */
28470     case MMI_OPC_PSLLW:         /* TODO: MMI_OPC_PSLLW */
28471     case MMI_OPC_PSRLW:         /* TODO: MMI_OPC_PSRLW */
28472     case MMI_OPC_PSRAW:         /* TODO: MMI_OPC_PSRAW */
28473         generate_exception_end(ctx, EXCP_RI);    /* TODO: MMI_OPC_CLASS_MMI */
28474         break;
28475     default:
28476         MIPS_INVAL("TX79 MMI class");
28477         generate_exception_end(ctx, EXCP_RI);
28478         break;
28479     }
28480 }
28481 
gen_mmi_lq(CPUMIPSState * env,DisasContext * ctx)28482 static void gen_mmi_lq(CPUMIPSState *env, DisasContext *ctx)
28483 {
28484     generate_exception_end(ctx, EXCP_RI);    /* TODO: MMI_OPC_LQ */
28485 }
28486 
gen_mmi_sq(DisasContext * ctx,int base,int rt,int offset)28487 static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset)
28488 {
28489     generate_exception_end(ctx, EXCP_RI);    /* TODO: MMI_OPC_SQ */
28490 }
28491 
28492 /*
28493  * The TX79-specific instruction Store Quadword
28494  *
28495  * +--------+-------+-------+------------------------+
28496  * | 011111 |  base |   rt  |           offset       | SQ
28497  * +--------+-------+-------+------------------------+
28498  *      6       5       5                 16
28499  *
28500  * has the same opcode as the Read Hardware Register instruction
28501  *
28502  * +--------+-------+-------+-------+-------+--------+
28503  * | 011111 | 00000 |   rt  |   rd  | 00000 | 111011 | RDHWR
28504  * +--------+-------+-------+-------+-------+--------+
28505  *      6       5       5       5       5        6
28506  *
28507  * that is required, trapped and emulated by the Linux kernel. However, all
28508  * RDHWR encodings yield address error exceptions on the TX79 since the SQ
28509  * offset is odd. Therefore all valid SQ instructions can execute normally.
28510  * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
28511  * between SQ and RDHWR, as the Linux kernel does.
28512  */
decode_mmi_sq(CPUMIPSState * env,DisasContext * ctx)28513 static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx)
28514 {
28515     int base = extract32(ctx->opcode, 21, 5);
28516     int rt = extract32(ctx->opcode, 16, 5);
28517     int offset = extract32(ctx->opcode, 0, 16);
28518 
28519 #ifdef CONFIG_USER_ONLY
28520     uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
28521     uint32_t op2 = extract32(ctx->opcode, 6, 5);
28522 
28523     if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
28524         int rd = extract32(ctx->opcode, 11, 5);
28525 
28526         gen_rdhwr(ctx, rt, rd, 0);
28527         return;
28528     }
28529 #endif
28530 
28531     gen_mmi_sq(ctx, base, rt, offset);
28532 }
28533 
28534 #endif
28535 
decode_opc_special3(CPUMIPSState * env,DisasContext * ctx)28536 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
28537 {
28538     int rs, rt, rd, sa;
28539     uint32_t op1, op2;
28540     int16_t imm;
28541 
28542     rs = (ctx->opcode >> 21) & 0x1f;
28543     rt = (ctx->opcode >> 16) & 0x1f;
28544     rd = (ctx->opcode >> 11) & 0x1f;
28545     sa = (ctx->opcode >> 6) & 0x1f;
28546     imm = sextract32(ctx->opcode, 7, 9);
28547 
28548     op1 = MASK_SPECIAL3(ctx->opcode);
28549 
28550     /*
28551      * EVA loads and stores overlap Loongson 2E instructions decoded by
28552      * decode_opc_special3_legacy(), so be careful to allow their decoding when
28553      * EVA is absent.
28554      */
28555     if (ctx->eva) {
28556         switch (op1) {
28557         case OPC_LWLE:
28558         case OPC_LWRE:
28559             check_insn_opc_removed(ctx, ISA_MIPS32R6);
28560             /* fall through */
28561         case OPC_LBUE:
28562         case OPC_LHUE:
28563         case OPC_LBE:
28564         case OPC_LHE:
28565         case OPC_LLE:
28566         case OPC_LWE:
28567             check_cp0_enabled(ctx);
28568             gen_ld(ctx, op1, rt, rs, imm);
28569             return;
28570         case OPC_SWLE:
28571         case OPC_SWRE:
28572             check_insn_opc_removed(ctx, ISA_MIPS32R6);
28573             /* fall through */
28574         case OPC_SBE:
28575         case OPC_SHE:
28576         case OPC_SWE:
28577             check_cp0_enabled(ctx);
28578             gen_st(ctx, op1, rt, rs, imm);
28579             return;
28580         case OPC_SCE:
28581             check_cp0_enabled(ctx);
28582             gen_st_cond(ctx, rt, rs, imm, MO_TESL, true);
28583             return;
28584         case OPC_CACHEE:
28585             check_cp0_enabled(ctx);
28586             if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
28587                 gen_cache_operation(ctx, rt, rs, imm);
28588             }
28589             /* Treat as NOP. */
28590             return;
28591         case OPC_PREFE:
28592             check_cp0_enabled(ctx);
28593             /* Treat as NOP. */
28594             return;
28595         }
28596     }
28597 
28598     switch (op1) {
28599     case OPC_EXT:
28600     case OPC_INS:
28601         check_insn(ctx, ISA_MIPS32R2);
28602         gen_bitops(ctx, op1, rt, rs, sa, rd);
28603         break;
28604     case OPC_BSHFL:
28605         op2 = MASK_BSHFL(ctx->opcode);
28606         switch (op2) {
28607         case OPC_ALIGN:
28608         case OPC_ALIGN_1:
28609         case OPC_ALIGN_2:
28610         case OPC_ALIGN_3:
28611         case OPC_BITSWAP:
28612             check_insn(ctx, ISA_MIPS32R6);
28613             decode_opc_special3_r6(env, ctx);
28614             break;
28615         default:
28616             check_insn(ctx, ISA_MIPS32R2);
28617             gen_bshfl(ctx, op2, rt, rd);
28618             break;
28619         }
28620         break;
28621 #if defined(TARGET_MIPS64)
28622     case OPC_DEXTM:
28623     case OPC_DEXTU:
28624     case OPC_DEXT:
28625     case OPC_DINSM:
28626     case OPC_DINSU:
28627     case OPC_DINS:
28628         check_insn(ctx, ISA_MIPS64R2);
28629         check_mips_64(ctx);
28630         gen_bitops(ctx, op1, rt, rs, sa, rd);
28631         break;
28632     case OPC_DBSHFL:
28633         op2 = MASK_DBSHFL(ctx->opcode);
28634         switch (op2) {
28635         case OPC_DALIGN:
28636         case OPC_DALIGN_1:
28637         case OPC_DALIGN_2:
28638         case OPC_DALIGN_3:
28639         case OPC_DALIGN_4:
28640         case OPC_DALIGN_5:
28641         case OPC_DALIGN_6:
28642         case OPC_DALIGN_7:
28643         case OPC_DBITSWAP:
28644             check_insn(ctx, ISA_MIPS32R6);
28645             decode_opc_special3_r6(env, ctx);
28646             break;
28647         default:
28648             check_insn(ctx, ISA_MIPS64R2);
28649             check_mips_64(ctx);
28650             op2 = MASK_DBSHFL(ctx->opcode);
28651             gen_bshfl(ctx, op2, rt, rd);
28652             break;
28653         }
28654         break;
28655 #endif
28656     case OPC_RDHWR:
28657         gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
28658         break;
28659     case OPC_FORK:
28660         check_mt(ctx);
28661         {
28662             TCGv t0 = tcg_temp_new();
28663             TCGv t1 = tcg_temp_new();
28664 
28665             gen_load_gpr(t0, rt);
28666             gen_load_gpr(t1, rs);
28667             gen_helper_fork(t0, t1);
28668             tcg_temp_free(t0);
28669             tcg_temp_free(t1);
28670         }
28671         break;
28672     case OPC_YIELD:
28673         check_mt(ctx);
28674         {
28675             TCGv t0 = tcg_temp_new();
28676 
28677             gen_load_gpr(t0, rs);
28678             gen_helper_yield(t0, cpu_env, t0);
28679             gen_store_gpr(t0, rd);
28680             tcg_temp_free(t0);
28681         }
28682         break;
28683     default:
28684         if (ctx->insn_flags & ISA_MIPS32R6) {
28685             decode_opc_special3_r6(env, ctx);
28686         } else {
28687             decode_opc_special3_legacy(env, ctx);
28688         }
28689     }
28690 }
28691 
28692 /* MIPS SIMD Architecture (MSA)  */
check_msa_access(DisasContext * ctx)28693 static inline int check_msa_access(DisasContext *ctx)
28694 {
28695     if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
28696                  !(ctx->hflags & MIPS_HFLAG_F64))) {
28697         generate_exception_end(ctx, EXCP_RI);
28698         return 0;
28699     }
28700 
28701     if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
28702         if (ctx->insn_flags & ASE_MSA) {
28703             generate_exception_end(ctx, EXCP_MSADIS);
28704             return 0;
28705         } else {
28706             generate_exception_end(ctx, EXCP_RI);
28707             return 0;
28708         }
28709     }
28710     return 1;
28711 }
28712 
gen_check_zero_element(TCGv tresult,uint8_t df,uint8_t wt)28713 static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
28714 {
28715     /* generates tcg ops to check if any element is 0 */
28716     /* Note this function only works with MSA_WRLEN = 128 */
28717     uint64_t eval_zero_or_big = 0;
28718     uint64_t eval_big = 0;
28719     TCGv_i64 t0 = tcg_temp_new_i64();
28720     TCGv_i64 t1 = tcg_temp_new_i64();
28721     switch (df) {
28722     case DF_BYTE:
28723         eval_zero_or_big = 0x0101010101010101ULL;
28724         eval_big = 0x8080808080808080ULL;
28725         break;
28726     case DF_HALF:
28727         eval_zero_or_big = 0x0001000100010001ULL;
28728         eval_big = 0x8000800080008000ULL;
28729         break;
28730     case DF_WORD:
28731         eval_zero_or_big = 0x0000000100000001ULL;
28732         eval_big = 0x8000000080000000ULL;
28733         break;
28734     case DF_DOUBLE:
28735         eval_zero_or_big = 0x0000000000000001ULL;
28736         eval_big = 0x8000000000000000ULL;
28737         break;
28738     }
28739     tcg_gen_subi_i64(t0, msa_wr_d[wt << 1], eval_zero_or_big);
28740     tcg_gen_andc_i64(t0, t0, msa_wr_d[wt << 1]);
28741     tcg_gen_andi_i64(t0, t0, eval_big);
28742     tcg_gen_subi_i64(t1, msa_wr_d[(wt << 1) + 1], eval_zero_or_big);
28743     tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt << 1) + 1]);
28744     tcg_gen_andi_i64(t1, t1, eval_big);
28745     tcg_gen_or_i64(t0, t0, t1);
28746     /* if all bits are zero then all elements are not zero */
28747     /* if some bit is non-zero then some element is zero */
28748     tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
28749     tcg_gen_trunc_i64_tl(tresult, t0);
28750     tcg_temp_free_i64(t0);
28751     tcg_temp_free_i64(t1);
28752 }
28753 
gen_msa_branch(CPUMIPSState * env,DisasContext * ctx,uint32_t op1)28754 static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
28755 {
28756     uint8_t df = (ctx->opcode >> 21) & 0x3;
28757     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28758     int64_t s16 = (int16_t)ctx->opcode;
28759 
28760     check_msa_access(ctx);
28761 
28762     if (ctx->hflags & MIPS_HFLAG_BMASK) {
28763         generate_exception_end(ctx, EXCP_RI);
28764         return;
28765     }
28766     switch (op1) {
28767     case OPC_BZ_V:
28768     case OPC_BNZ_V:
28769         {
28770             TCGv_i64 t0 = tcg_temp_new_i64();
28771             tcg_gen_or_i64(t0, msa_wr_d[wt << 1], msa_wr_d[(wt << 1) + 1]);
28772             tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
28773                     TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
28774             tcg_gen_trunc_i64_tl(bcond, t0);
28775             tcg_temp_free_i64(t0);
28776         }
28777         break;
28778     case OPC_BZ_B:
28779     case OPC_BZ_H:
28780     case OPC_BZ_W:
28781     case OPC_BZ_D:
28782         gen_check_zero_element(bcond, df, wt);
28783         break;
28784     case OPC_BNZ_B:
28785     case OPC_BNZ_H:
28786     case OPC_BNZ_W:
28787     case OPC_BNZ_D:
28788         gen_check_zero_element(bcond, df, wt);
28789         tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
28790         break;
28791     }
28792 
28793     ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
28794 
28795     ctx->hflags |= MIPS_HFLAG_BC;
28796     ctx->hflags |= MIPS_HFLAG_BDS32;
28797 }
28798 
gen_msa_i8(CPUMIPSState * env,DisasContext * ctx)28799 static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
28800 {
28801 #define MASK_MSA_I8(op)    (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
28802     uint8_t i8 = (ctx->opcode >> 16) & 0xff;
28803     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28804     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28805 
28806     TCGv_i32 twd = tcg_const_i32(wd);
28807     TCGv_i32 tws = tcg_const_i32(ws);
28808     TCGv_i32 ti8 = tcg_const_i32(i8);
28809 
28810     switch (MASK_MSA_I8(ctx->opcode)) {
28811     case OPC_ANDI_B:
28812         gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
28813         break;
28814     case OPC_ORI_B:
28815         gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
28816         break;
28817     case OPC_NORI_B:
28818         gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
28819         break;
28820     case OPC_XORI_B:
28821         gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
28822         break;
28823     case OPC_BMNZI_B:
28824         gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
28825         break;
28826     case OPC_BMZI_B:
28827         gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
28828         break;
28829     case OPC_BSELI_B:
28830         gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
28831         break;
28832     case OPC_SHF_B:
28833     case OPC_SHF_H:
28834     case OPC_SHF_W:
28835         {
28836             uint8_t df = (ctx->opcode >> 24) & 0x3;
28837             if (df == DF_DOUBLE) {
28838                 generate_exception_end(ctx, EXCP_RI);
28839             } else {
28840                 TCGv_i32 tdf = tcg_const_i32(df);
28841                 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
28842                 tcg_temp_free_i32(tdf);
28843             }
28844         }
28845         break;
28846     default:
28847         MIPS_INVAL("MSA instruction");
28848         generate_exception_end(ctx, EXCP_RI);
28849         break;
28850     }
28851 
28852     tcg_temp_free_i32(twd);
28853     tcg_temp_free_i32(tws);
28854     tcg_temp_free_i32(ti8);
28855 }
28856 
gen_msa_i5(CPUMIPSState * env,DisasContext * ctx)28857 static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
28858 {
28859 #define MASK_MSA_I5(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28860     uint8_t df = (ctx->opcode >> 21) & 0x3;
28861     int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
28862     uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
28863     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28864     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28865 
28866     TCGv_i32 tdf = tcg_const_i32(df);
28867     TCGv_i32 twd = tcg_const_i32(wd);
28868     TCGv_i32 tws = tcg_const_i32(ws);
28869     TCGv_i32 timm = tcg_temp_new_i32();
28870     tcg_gen_movi_i32(timm, u5);
28871 
28872     switch (MASK_MSA_I5(ctx->opcode)) {
28873     case OPC_ADDVI_df:
28874         gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
28875         break;
28876     case OPC_SUBVI_df:
28877         gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
28878         break;
28879     case OPC_MAXI_S_df:
28880         tcg_gen_movi_i32(timm, s5);
28881         gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
28882         break;
28883     case OPC_MAXI_U_df:
28884         gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
28885         break;
28886     case OPC_MINI_S_df:
28887         tcg_gen_movi_i32(timm, s5);
28888         gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
28889         break;
28890     case OPC_MINI_U_df:
28891         gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
28892         break;
28893     case OPC_CEQI_df:
28894         tcg_gen_movi_i32(timm, s5);
28895         gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
28896         break;
28897     case OPC_CLTI_S_df:
28898         tcg_gen_movi_i32(timm, s5);
28899         gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
28900         break;
28901     case OPC_CLTI_U_df:
28902         gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
28903         break;
28904     case OPC_CLEI_S_df:
28905         tcg_gen_movi_i32(timm, s5);
28906         gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
28907         break;
28908     case OPC_CLEI_U_df:
28909         gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
28910         break;
28911     case OPC_LDI_df:
28912         {
28913             int32_t s10 = sextract32(ctx->opcode, 11, 10);
28914             tcg_gen_movi_i32(timm, s10);
28915             gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
28916         }
28917         break;
28918     default:
28919         MIPS_INVAL("MSA instruction");
28920         generate_exception_end(ctx, EXCP_RI);
28921         break;
28922     }
28923 
28924     tcg_temp_free_i32(tdf);
28925     tcg_temp_free_i32(twd);
28926     tcg_temp_free_i32(tws);
28927     tcg_temp_free_i32(timm);
28928 }
28929 
gen_msa_bit(CPUMIPSState * env,DisasContext * ctx)28930 static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
28931 {
28932 #define MASK_MSA_BIT(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28933     uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
28934     uint32_t df = 0, m = 0;
28935     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28936     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28937 
28938     TCGv_i32 tdf;
28939     TCGv_i32 tm;
28940     TCGv_i32 twd;
28941     TCGv_i32 tws;
28942 
28943     if ((dfm & 0x40) == 0x00) {
28944         m = dfm & 0x3f;
28945         df = DF_DOUBLE;
28946     } else if ((dfm & 0x60) == 0x40) {
28947         m = dfm & 0x1f;
28948         df = DF_WORD;
28949     } else if ((dfm & 0x70) == 0x60) {
28950         m = dfm & 0x0f;
28951         df = DF_HALF;
28952     } else if ((dfm & 0x78) == 0x70) {
28953         m = dfm & 0x7;
28954         df = DF_BYTE;
28955     } else {
28956         generate_exception_end(ctx, EXCP_RI);
28957         return;
28958     }
28959 
28960     tdf = tcg_const_i32(df);
28961     tm  = tcg_const_i32(m);
28962     twd = tcg_const_i32(wd);
28963     tws = tcg_const_i32(ws);
28964 
28965     switch (MASK_MSA_BIT(ctx->opcode)) {
28966     case OPC_SLLI_df:
28967         gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
28968         break;
28969     case OPC_SRAI_df:
28970         gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
28971         break;
28972     case OPC_SRLI_df:
28973         gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
28974         break;
28975     case OPC_BCLRI_df:
28976         gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
28977         break;
28978     case OPC_BSETI_df:
28979         gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
28980         break;
28981     case OPC_BNEGI_df:
28982         gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
28983         break;
28984     case OPC_BINSLI_df:
28985         gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
28986         break;
28987     case OPC_BINSRI_df:
28988         gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
28989         break;
28990     case OPC_SAT_S_df:
28991         gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
28992         break;
28993     case OPC_SAT_U_df:
28994         gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
28995         break;
28996     case OPC_SRARI_df:
28997         gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
28998         break;
28999     case OPC_SRLRI_df:
29000         gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
29001         break;
29002     default:
29003         MIPS_INVAL("MSA instruction");
29004         generate_exception_end(ctx, EXCP_RI);
29005         break;
29006     }
29007 
29008     tcg_temp_free_i32(tdf);
29009     tcg_temp_free_i32(tm);
29010     tcg_temp_free_i32(twd);
29011     tcg_temp_free_i32(tws);
29012 }
29013 
gen_msa_3r(CPUMIPSState * env,DisasContext * ctx)29014 static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
29015 {
29016 #define MASK_MSA_3R(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
29017     uint8_t df = (ctx->opcode >> 21) & 0x3;
29018     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
29019     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
29020     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
29021 
29022     TCGv_i32 tdf = tcg_const_i32(df);
29023     TCGv_i32 twd = tcg_const_i32(wd);
29024     TCGv_i32 tws = tcg_const_i32(ws);
29025     TCGv_i32 twt = tcg_const_i32(wt);
29026 
29027     switch (MASK_MSA_3R(ctx->opcode)) {
29028     case OPC_BINSL_df:
29029         switch (df) {
29030         case DF_BYTE:
29031             gen_helper_msa_binsl_b(cpu_env, twd, tws, twt);
29032             break;
29033         case DF_HALF:
29034             gen_helper_msa_binsl_h(cpu_env, twd, tws, twt);
29035             break;
29036         case DF_WORD:
29037             gen_helper_msa_binsl_w(cpu_env, twd, tws, twt);
29038             break;
29039         case DF_DOUBLE:
29040             gen_helper_msa_binsl_d(cpu_env, twd, tws, twt);
29041             break;
29042         }
29043         break;
29044     case OPC_BINSR_df:
29045         switch (df) {
29046         case DF_BYTE:
29047             gen_helper_msa_binsr_b(cpu_env, twd, tws, twt);
29048             break;
29049         case DF_HALF:
29050             gen_helper_msa_binsr_h(cpu_env, twd, tws, twt);
29051             break;
29052         case DF_WORD:
29053             gen_helper_msa_binsr_w(cpu_env, twd, tws, twt);
29054             break;
29055         case DF_DOUBLE:
29056             gen_helper_msa_binsr_d(cpu_env, twd, tws, twt);
29057             break;
29058         }
29059         break;
29060     case OPC_BCLR_df:
29061         switch (df) {
29062         case DF_BYTE:
29063             gen_helper_msa_bclr_b(cpu_env, twd, tws, twt);
29064             break;
29065         case DF_HALF:
29066             gen_helper_msa_bclr_h(cpu_env, twd, tws, twt);
29067             break;
29068         case DF_WORD:
29069             gen_helper_msa_bclr_w(cpu_env, twd, tws, twt);
29070             break;
29071         case DF_DOUBLE:
29072             gen_helper_msa_bclr_d(cpu_env, twd, tws, twt);
29073             break;
29074         }
29075         break;
29076     case OPC_BNEG_df:
29077         switch (df) {
29078         case DF_BYTE:
29079             gen_helper_msa_bneg_b(cpu_env, twd, tws, twt);
29080             break;
29081         case DF_HALF:
29082             gen_helper_msa_bneg_h(cpu_env, twd, tws, twt);
29083             break;
29084         case DF_WORD:
29085             gen_helper_msa_bneg_w(cpu_env, twd, tws, twt);
29086             break;
29087         case DF_DOUBLE:
29088             gen_helper_msa_bneg_d(cpu_env, twd, tws, twt);
29089             break;
29090         }
29091         break;
29092     case OPC_BSET_df:
29093         switch (df) {
29094         case DF_BYTE:
29095             gen_helper_msa_bset_b(cpu_env, twd, tws, twt);
29096             break;
29097         case DF_HALF:
29098             gen_helper_msa_bset_h(cpu_env, twd, tws, twt);
29099             break;
29100         case DF_WORD:
29101             gen_helper_msa_bset_w(cpu_env, twd, tws, twt);
29102             break;
29103         case DF_DOUBLE:
29104             gen_helper_msa_bset_d(cpu_env, twd, tws, twt);
29105             break;
29106         }
29107         break;
29108     case OPC_ADD_A_df:
29109         switch (df) {
29110         case DF_BYTE:
29111             gen_helper_msa_add_a_b(cpu_env, twd, tws, twt);
29112             break;
29113         case DF_HALF:
29114             gen_helper_msa_add_a_h(cpu_env, twd, tws, twt);
29115             break;
29116         case DF_WORD:
29117             gen_helper_msa_add_a_w(cpu_env, twd, tws, twt);
29118             break;
29119         case DF_DOUBLE:
29120             gen_helper_msa_add_a_d(cpu_env, twd, tws, twt);
29121             break;
29122         }
29123         break;
29124     case OPC_ADDS_A_df:
29125         switch (df) {
29126         case DF_BYTE:
29127             gen_helper_msa_adds_a_b(cpu_env, twd, tws, twt);
29128             break;
29129         case DF_HALF:
29130             gen_helper_msa_adds_a_h(cpu_env, twd, tws, twt);
29131             break;
29132         case DF_WORD:
29133             gen_helper_msa_adds_a_w(cpu_env, twd, tws, twt);
29134             break;
29135         case DF_DOUBLE:
29136             gen_helper_msa_adds_a_d(cpu_env, twd, tws, twt);
29137             break;
29138         }
29139         break;
29140     case OPC_ADDS_S_df:
29141         switch (df) {
29142         case DF_BYTE:
29143             gen_helper_msa_adds_s_b(cpu_env, twd, tws, twt);
29144             break;
29145         case DF_HALF:
29146             gen_helper_msa_adds_s_h(cpu_env, twd, tws, twt);
29147             break;
29148         case DF_WORD:
29149             gen_helper_msa_adds_s_w(cpu_env, twd, tws, twt);
29150             break;
29151         case DF_DOUBLE:
29152             gen_helper_msa_adds_s_d(cpu_env, twd, tws, twt);
29153             break;
29154         }
29155         break;
29156     case OPC_ADDS_U_df:
29157         switch (df) {
29158         case DF_BYTE:
29159             gen_helper_msa_adds_u_b(cpu_env, twd, tws, twt);
29160             break;
29161         case DF_HALF:
29162             gen_helper_msa_adds_u_h(cpu_env, twd, tws, twt);
29163             break;
29164         case DF_WORD:
29165             gen_helper_msa_adds_u_w(cpu_env, twd, tws, twt);
29166             break;
29167         case DF_DOUBLE:
29168             gen_helper_msa_adds_u_d(cpu_env, twd, tws, twt);
29169             break;
29170         }
29171         break;
29172     case OPC_ADDV_df:
29173         switch (df) {
29174         case DF_BYTE:
29175             gen_helper_msa_addv_b(cpu_env, twd, tws, twt);
29176             break;
29177         case DF_HALF:
29178             gen_helper_msa_addv_h(cpu_env, twd, tws, twt);
29179             break;
29180         case DF_WORD:
29181             gen_helper_msa_addv_w(cpu_env, twd, tws, twt);
29182             break;
29183         case DF_DOUBLE:
29184             gen_helper_msa_addv_d(cpu_env, twd, tws, twt);
29185             break;
29186         }
29187         break;
29188     case OPC_AVE_S_df:
29189         switch (df) {
29190         case DF_BYTE:
29191             gen_helper_msa_ave_s_b(cpu_env, twd, tws, twt);
29192             break;
29193         case DF_HALF:
29194             gen_helper_msa_ave_s_h(cpu_env, twd, tws, twt);
29195             break;
29196         case DF_WORD:
29197             gen_helper_msa_ave_s_w(cpu_env, twd, tws, twt);
29198             break;
29199         case DF_DOUBLE:
29200             gen_helper_msa_ave_s_d(cpu_env, twd, tws, twt);
29201             break;
29202         }
29203         break;
29204     case OPC_AVE_U_df:
29205         switch (df) {
29206         case DF_BYTE:
29207             gen_helper_msa_ave_u_b(cpu_env, twd, tws, twt);
29208             break;
29209         case DF_HALF:
29210             gen_helper_msa_ave_u_h(cpu_env, twd, tws, twt);
29211             break;
29212         case DF_WORD:
29213             gen_helper_msa_ave_u_w(cpu_env, twd, tws, twt);
29214             break;
29215         case DF_DOUBLE:
29216             gen_helper_msa_ave_u_d(cpu_env, twd, tws, twt);
29217             break;
29218         }
29219         break;
29220     case OPC_AVER_S_df:
29221         switch (df) {
29222         case DF_BYTE:
29223             gen_helper_msa_aver_s_b(cpu_env, twd, tws, twt);
29224             break;
29225         case DF_HALF:
29226             gen_helper_msa_aver_s_h(cpu_env, twd, tws, twt);
29227             break;
29228         case DF_WORD:
29229             gen_helper_msa_aver_s_w(cpu_env, twd, tws, twt);
29230             break;
29231         case DF_DOUBLE:
29232             gen_helper_msa_aver_s_d(cpu_env, twd, tws, twt);
29233             break;
29234         }
29235         break;
29236     case OPC_AVER_U_df:
29237         switch (df) {
29238         case DF_BYTE:
29239             gen_helper_msa_aver_u_b(cpu_env, twd, tws, twt);
29240             break;
29241         case DF_HALF:
29242             gen_helper_msa_aver_u_h(cpu_env, twd, tws, twt);
29243             break;
29244         case DF_WORD:
29245             gen_helper_msa_aver_u_w(cpu_env, twd, tws, twt);
29246             break;
29247         case DF_DOUBLE:
29248             gen_helper_msa_aver_u_d(cpu_env, twd, tws, twt);
29249             break;
29250         }
29251         break;
29252     case OPC_CEQ_df:
29253         switch (df) {
29254         case DF_BYTE:
29255             gen_helper_msa_ceq_b(cpu_env, twd, tws, twt);
29256             break;
29257         case DF_HALF:
29258             gen_helper_msa_ceq_h(cpu_env, twd, tws, twt);
29259             break;
29260         case DF_WORD:
29261             gen_helper_msa_ceq_w(cpu_env, twd, tws, twt);
29262             break;
29263         case DF_DOUBLE:
29264             gen_helper_msa_ceq_d(cpu_env, twd, tws, twt);
29265             break;
29266         }
29267         break;
29268     case OPC_CLE_S_df:
29269         switch (df) {
29270         case DF_BYTE:
29271             gen_helper_msa_cle_s_b(cpu_env, twd, tws, twt);
29272             break;
29273         case DF_HALF:
29274             gen_helper_msa_cle_s_h(cpu_env, twd, tws, twt);
29275             break;
29276         case DF_WORD:
29277             gen_helper_msa_cle_s_w(cpu_env, twd, tws, twt);
29278             break;
29279         case DF_DOUBLE:
29280             gen_helper_msa_cle_s_d(cpu_env, twd, tws, twt);
29281             break;
29282         }
29283         break;
29284     case OPC_CLE_U_df:
29285         switch (df) {
29286         case DF_BYTE:
29287             gen_helper_msa_cle_u_b(cpu_env, twd, tws, twt);
29288             break;
29289         case DF_HALF:
29290             gen_helper_msa_cle_u_h(cpu_env, twd, tws, twt);
29291             break;
29292         case DF_WORD:
29293             gen_helper_msa_cle_u_w(cpu_env, twd, tws, twt);
29294             break;
29295         case DF_DOUBLE:
29296             gen_helper_msa_cle_u_d(cpu_env, twd, tws, twt);
29297             break;
29298         }
29299         break;
29300     case OPC_CLT_S_df:
29301         switch (df) {
29302         case DF_BYTE:
29303             gen_helper_msa_clt_s_b(cpu_env, twd, tws, twt);
29304             break;
29305         case DF_HALF:
29306             gen_helper_msa_clt_s_h(cpu_env, twd, tws, twt);
29307             break;
29308         case DF_WORD:
29309             gen_helper_msa_clt_s_w(cpu_env, twd, tws, twt);
29310             break;
29311         case DF_DOUBLE:
29312             gen_helper_msa_clt_s_d(cpu_env, twd, tws, twt);
29313             break;
29314         }
29315         break;
29316     case OPC_CLT_U_df:
29317         switch (df) {
29318         case DF_BYTE:
29319             gen_helper_msa_clt_u_b(cpu_env, twd, tws, twt);
29320             break;
29321         case DF_HALF:
29322             gen_helper_msa_clt_u_h(cpu_env, twd, tws, twt);
29323             break;
29324         case DF_WORD:
29325             gen_helper_msa_clt_u_w(cpu_env, twd, tws, twt);
29326             break;
29327         case DF_DOUBLE:
29328             gen_helper_msa_clt_u_d(cpu_env, twd, tws, twt);
29329             break;
29330         }
29331         break;
29332     case OPC_DIV_S_df:
29333         switch (df) {
29334         case DF_BYTE:
29335             gen_helper_msa_div_s_b(cpu_env, twd, tws, twt);
29336             break;
29337         case DF_HALF:
29338             gen_helper_msa_div_s_h(cpu_env, twd, tws, twt);
29339             break;
29340         case DF_WORD:
29341             gen_helper_msa_div_s_w(cpu_env, twd, tws, twt);
29342             break;
29343         case DF_DOUBLE:
29344             gen_helper_msa_div_s_d(cpu_env, twd, tws, twt);
29345             break;
29346         }
29347         break;
29348     case OPC_DIV_U_df:
29349         switch (df) {
29350         case DF_BYTE:
29351             gen_helper_msa_div_u_b(cpu_env, twd, tws, twt);
29352             break;
29353         case DF_HALF:
29354             gen_helper_msa_div_u_h(cpu_env, twd, tws, twt);
29355             break;
29356         case DF_WORD:
29357             gen_helper_msa_div_u_w(cpu_env, twd, tws, twt);
29358             break;
29359         case DF_DOUBLE:
29360             gen_helper_msa_div_u_d(cpu_env, twd, tws, twt);
29361             break;
29362         }
29363         break;
29364     case OPC_MAX_A_df:
29365         switch (df) {
29366         case DF_BYTE:
29367             gen_helper_msa_max_a_b(cpu_env, twd, tws, twt);
29368             break;
29369         case DF_HALF:
29370             gen_helper_msa_max_a_h(cpu_env, twd, tws, twt);
29371             break;
29372         case DF_WORD:
29373             gen_helper_msa_max_a_w(cpu_env, twd, tws, twt);
29374             break;
29375         case DF_DOUBLE:
29376             gen_helper_msa_max_a_d(cpu_env, twd, tws, twt);
29377             break;
29378         }
29379         break;
29380     case OPC_MAX_S_df:
29381         switch (df) {
29382         case DF_BYTE:
29383             gen_helper_msa_max_s_b(cpu_env, twd, tws, twt);
29384             break;
29385         case DF_HALF:
29386             gen_helper_msa_max_s_h(cpu_env, twd, tws, twt);
29387             break;
29388         case DF_WORD:
29389             gen_helper_msa_max_s_w(cpu_env, twd, tws, twt);
29390             break;
29391         case DF_DOUBLE:
29392             gen_helper_msa_max_s_d(cpu_env, twd, tws, twt);
29393             break;
29394         }
29395         break;
29396     case OPC_MAX_U_df:
29397         switch (df) {
29398         case DF_BYTE:
29399             gen_helper_msa_max_u_b(cpu_env, twd, tws, twt);
29400             break;
29401         case DF_HALF:
29402             gen_helper_msa_max_u_h(cpu_env, twd, tws, twt);
29403             break;
29404         case DF_WORD:
29405             gen_helper_msa_max_u_w(cpu_env, twd, tws, twt);
29406             break;
29407         case DF_DOUBLE:
29408             gen_helper_msa_max_u_d(cpu_env, twd, tws, twt);
29409             break;
29410         }
29411         break;
29412     case OPC_MIN_A_df:
29413         switch (df) {
29414         case DF_BYTE:
29415             gen_helper_msa_min_a_b(cpu_env, twd, tws, twt);
29416             break;
29417         case DF_HALF:
29418             gen_helper_msa_min_a_h(cpu_env, twd, tws, twt);
29419             break;
29420         case DF_WORD:
29421             gen_helper_msa_min_a_w(cpu_env, twd, tws, twt);
29422             break;
29423         case DF_DOUBLE:
29424             gen_helper_msa_min_a_d(cpu_env, twd, tws, twt);
29425             break;
29426         }
29427         break;
29428     case OPC_MIN_S_df:
29429         switch (df) {
29430         case DF_BYTE:
29431             gen_helper_msa_min_s_b(cpu_env, twd, tws, twt);
29432             break;
29433         case DF_HALF:
29434             gen_helper_msa_min_s_h(cpu_env, twd, tws, twt);
29435             break;
29436         case DF_WORD:
29437             gen_helper_msa_min_s_w(cpu_env, twd, tws, twt);
29438             break;
29439         case DF_DOUBLE:
29440             gen_helper_msa_min_s_d(cpu_env, twd, tws, twt);
29441             break;
29442         }
29443         break;
29444     case OPC_MIN_U_df:
29445         switch (df) {
29446         case DF_BYTE:
29447             gen_helper_msa_min_u_b(cpu_env, twd, tws, twt);
29448             break;
29449         case DF_HALF:
29450             gen_helper_msa_min_u_h(cpu_env, twd, tws, twt);
29451             break;
29452         case DF_WORD:
29453             gen_helper_msa_min_u_w(cpu_env, twd, tws, twt);
29454             break;
29455         case DF_DOUBLE:
29456             gen_helper_msa_min_u_d(cpu_env, twd, tws, twt);
29457             break;
29458         }
29459         break;
29460     case OPC_MOD_S_df:
29461         switch (df) {
29462         case DF_BYTE:
29463             gen_helper_msa_mod_s_b(cpu_env, twd, tws, twt);
29464             break;
29465         case DF_HALF:
29466             gen_helper_msa_mod_s_h(cpu_env, twd, tws, twt);
29467             break;
29468         case DF_WORD:
29469             gen_helper_msa_mod_s_w(cpu_env, twd, tws, twt);
29470             break;
29471         case DF_DOUBLE:
29472             gen_helper_msa_mod_s_d(cpu_env, twd, tws, twt);
29473             break;
29474         }
29475         break;
29476     case OPC_MOD_U_df:
29477         switch (df) {
29478         case DF_BYTE:
29479             gen_helper_msa_mod_u_b(cpu_env, twd, tws, twt);
29480             break;
29481         case DF_HALF:
29482             gen_helper_msa_mod_u_h(cpu_env, twd, tws, twt);
29483             break;
29484         case DF_WORD:
29485             gen_helper_msa_mod_u_w(cpu_env, twd, tws, twt);
29486             break;
29487         case DF_DOUBLE:
29488             gen_helper_msa_mod_u_d(cpu_env, twd, tws, twt);
29489             break;
29490         }
29491         break;
29492     case OPC_MADDV_df:
29493         switch (df) {
29494         case DF_BYTE:
29495             gen_helper_msa_maddv_b(cpu_env, twd, tws, twt);
29496             break;
29497         case DF_HALF:
29498             gen_helper_msa_maddv_h(cpu_env, twd, tws, twt);
29499             break;
29500         case DF_WORD:
29501             gen_helper_msa_maddv_w(cpu_env, twd, tws, twt);
29502             break;
29503         case DF_DOUBLE:
29504             gen_helper_msa_maddv_d(cpu_env, twd, tws, twt);
29505             break;
29506         }
29507         break;
29508     case OPC_MSUBV_df:
29509         switch (df) {
29510         case DF_BYTE:
29511             gen_helper_msa_msubv_b(cpu_env, twd, tws, twt);
29512             break;
29513         case DF_HALF:
29514             gen_helper_msa_msubv_h(cpu_env, twd, tws, twt);
29515             break;
29516         case DF_WORD:
29517             gen_helper_msa_msubv_w(cpu_env, twd, tws, twt);
29518             break;
29519         case DF_DOUBLE:
29520             gen_helper_msa_msubv_d(cpu_env, twd, tws, twt);
29521             break;
29522         }
29523         break;
29524     case OPC_ASUB_S_df:
29525         switch (df) {
29526         case DF_BYTE:
29527             gen_helper_msa_asub_s_b(cpu_env, twd, tws, twt);
29528             break;
29529         case DF_HALF:
29530             gen_helper_msa_asub_s_h(cpu_env, twd, tws, twt);
29531             break;
29532         case DF_WORD:
29533             gen_helper_msa_asub_s_w(cpu_env, twd, tws, twt);
29534             break;
29535         case DF_DOUBLE:
29536             gen_helper_msa_asub_s_d(cpu_env, twd, tws, twt);
29537             break;
29538         }
29539         break;
29540     case OPC_ASUB_U_df:
29541         switch (df) {
29542         case DF_BYTE:
29543             gen_helper_msa_asub_u_b(cpu_env, twd, tws, twt);
29544             break;
29545         case DF_HALF:
29546             gen_helper_msa_asub_u_h(cpu_env, twd, tws, twt);
29547             break;
29548         case DF_WORD:
29549             gen_helper_msa_asub_u_w(cpu_env, twd, tws, twt);
29550             break;
29551         case DF_DOUBLE:
29552             gen_helper_msa_asub_u_d(cpu_env, twd, tws, twt);
29553             break;
29554         }
29555         break;
29556     case OPC_ILVEV_df:
29557         switch (df) {
29558         case DF_BYTE:
29559             gen_helper_msa_ilvev_b(cpu_env, twd, tws, twt);
29560             break;
29561         case DF_HALF:
29562             gen_helper_msa_ilvev_h(cpu_env, twd, tws, twt);
29563             break;
29564         case DF_WORD:
29565             gen_helper_msa_ilvev_w(cpu_env, twd, tws, twt);
29566             break;
29567         case DF_DOUBLE:
29568             gen_helper_msa_ilvev_d(cpu_env, twd, tws, twt);
29569             break;
29570         }
29571         break;
29572     case OPC_ILVOD_df:
29573         switch (df) {
29574         case DF_BYTE:
29575             gen_helper_msa_ilvod_b(cpu_env, twd, tws, twt);
29576             break;
29577         case DF_HALF:
29578             gen_helper_msa_ilvod_h(cpu_env, twd, tws, twt);
29579             break;
29580         case DF_WORD:
29581             gen_helper_msa_ilvod_w(cpu_env, twd, tws, twt);
29582             break;
29583         case DF_DOUBLE:
29584             gen_helper_msa_ilvod_d(cpu_env, twd, tws, twt);
29585             break;
29586         }
29587         break;
29588     case OPC_ILVL_df:
29589         switch (df) {
29590         case DF_BYTE:
29591             gen_helper_msa_ilvl_b(cpu_env, twd, tws, twt);
29592             break;
29593         case DF_HALF:
29594             gen_helper_msa_ilvl_h(cpu_env, twd, tws, twt);
29595             break;
29596         case DF_WORD:
29597             gen_helper_msa_ilvl_w(cpu_env, twd, tws, twt);
29598             break;
29599         case DF_DOUBLE:
29600             gen_helper_msa_ilvl_d(cpu_env, twd, tws, twt);
29601             break;
29602         }
29603         break;
29604     case OPC_ILVR_df:
29605         switch (df) {
29606         case DF_BYTE:
29607             gen_helper_msa_ilvr_b(cpu_env, twd, tws, twt);
29608             break;
29609         case DF_HALF:
29610             gen_helper_msa_ilvr_h(cpu_env, twd, tws, twt);
29611             break;
29612         case DF_WORD:
29613             gen_helper_msa_ilvr_w(cpu_env, twd, tws, twt);
29614             break;
29615         case DF_DOUBLE:
29616             gen_helper_msa_ilvr_d(cpu_env, twd, tws, twt);
29617             break;
29618         }
29619         break;
29620     case OPC_PCKEV_df:
29621         switch (df) {
29622         case DF_BYTE:
29623             gen_helper_msa_pckev_b(cpu_env, twd, tws, twt);
29624             break;
29625         case DF_HALF:
29626             gen_helper_msa_pckev_h(cpu_env, twd, tws, twt);
29627             break;
29628         case DF_WORD:
29629             gen_helper_msa_pckev_w(cpu_env, twd, tws, twt);
29630             break;
29631         case DF_DOUBLE:
29632             gen_helper_msa_pckev_d(cpu_env, twd, tws, twt);
29633             break;
29634         }
29635         break;
29636     case OPC_PCKOD_df:
29637         switch (df) {
29638         case DF_BYTE:
29639             gen_helper_msa_pckod_b(cpu_env, twd, tws, twt);
29640             break;
29641         case DF_HALF:
29642             gen_helper_msa_pckod_h(cpu_env, twd, tws, twt);
29643             break;
29644         case DF_WORD:
29645             gen_helper_msa_pckod_w(cpu_env, twd, tws, twt);
29646             break;
29647         case DF_DOUBLE:
29648             gen_helper_msa_pckod_d(cpu_env, twd, tws, twt);
29649             break;
29650         }
29651         break;
29652     case OPC_SLL_df:
29653         switch (df) {
29654         case DF_BYTE:
29655             gen_helper_msa_sll_b(cpu_env, twd, tws, twt);
29656             break;
29657         case DF_HALF:
29658             gen_helper_msa_sll_h(cpu_env, twd, tws, twt);
29659             break;
29660         case DF_WORD:
29661             gen_helper_msa_sll_w(cpu_env, twd, tws, twt);
29662             break;
29663         case DF_DOUBLE:
29664             gen_helper_msa_sll_d(cpu_env, twd, tws, twt);
29665             break;
29666         }
29667         break;
29668     case OPC_SRA_df:
29669         switch (df) {
29670         case DF_BYTE:
29671             gen_helper_msa_sra_b(cpu_env, twd, tws, twt);
29672             break;
29673         case DF_HALF:
29674             gen_helper_msa_sra_h(cpu_env, twd, tws, twt);
29675             break;
29676         case DF_WORD:
29677             gen_helper_msa_sra_w(cpu_env, twd, tws, twt);
29678             break;
29679         case DF_DOUBLE:
29680             gen_helper_msa_sra_d(cpu_env, twd, tws, twt);
29681             break;
29682         }
29683         break;
29684     case OPC_SRAR_df:
29685         switch (df) {
29686         case DF_BYTE:
29687             gen_helper_msa_srar_b(cpu_env, twd, tws, twt);
29688             break;
29689         case DF_HALF:
29690             gen_helper_msa_srar_h(cpu_env, twd, tws, twt);
29691             break;
29692         case DF_WORD:
29693             gen_helper_msa_srar_w(cpu_env, twd, tws, twt);
29694             break;
29695         case DF_DOUBLE:
29696             gen_helper_msa_srar_d(cpu_env, twd, tws, twt);
29697             break;
29698         }
29699         break;
29700     case OPC_SRL_df:
29701         switch (df) {
29702         case DF_BYTE:
29703             gen_helper_msa_srl_b(cpu_env, twd, tws, twt);
29704             break;
29705         case DF_HALF:
29706             gen_helper_msa_srl_h(cpu_env, twd, tws, twt);
29707             break;
29708         case DF_WORD:
29709             gen_helper_msa_srl_w(cpu_env, twd, tws, twt);
29710             break;
29711         case DF_DOUBLE:
29712             gen_helper_msa_srl_d(cpu_env, twd, tws, twt);
29713             break;
29714         }
29715         break;
29716     case OPC_SRLR_df:
29717         switch (df) {
29718         case DF_BYTE:
29719             gen_helper_msa_srlr_b(cpu_env, twd, tws, twt);
29720             break;
29721         case DF_HALF:
29722             gen_helper_msa_srlr_h(cpu_env, twd, tws, twt);
29723             break;
29724         case DF_WORD:
29725             gen_helper_msa_srlr_w(cpu_env, twd, tws, twt);
29726             break;
29727         case DF_DOUBLE:
29728             gen_helper_msa_srlr_d(cpu_env, twd, tws, twt);
29729             break;
29730         }
29731         break;
29732     case OPC_SUBS_S_df:
29733         switch (df) {
29734         case DF_BYTE:
29735             gen_helper_msa_subs_s_b(cpu_env, twd, tws, twt);
29736             break;
29737         case DF_HALF:
29738             gen_helper_msa_subs_s_h(cpu_env, twd, tws, twt);
29739             break;
29740         case DF_WORD:
29741             gen_helper_msa_subs_s_w(cpu_env, twd, tws, twt);
29742             break;
29743         case DF_DOUBLE:
29744             gen_helper_msa_subs_s_d(cpu_env, twd, tws, twt);
29745             break;
29746         }
29747         break;
29748     case OPC_MULV_df:
29749         switch (df) {
29750         case DF_BYTE:
29751             gen_helper_msa_mulv_b(cpu_env, twd, tws, twt);
29752             break;
29753         case DF_HALF:
29754             gen_helper_msa_mulv_h(cpu_env, twd, tws, twt);
29755             break;
29756         case DF_WORD:
29757             gen_helper_msa_mulv_w(cpu_env, twd, tws, twt);
29758             break;
29759         case DF_DOUBLE:
29760             gen_helper_msa_mulv_d(cpu_env, twd, tws, twt);
29761             break;
29762         }
29763         break;
29764     case OPC_SLD_df:
29765         gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
29766         break;
29767     case OPC_VSHF_df:
29768         gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
29769         break;
29770     case OPC_SUBV_df:
29771         switch (df) {
29772         case DF_BYTE:
29773             gen_helper_msa_subv_b(cpu_env, twd, tws, twt);
29774             break;
29775         case DF_HALF:
29776             gen_helper_msa_subv_h(cpu_env, twd, tws, twt);
29777             break;
29778         case DF_WORD:
29779             gen_helper_msa_subv_w(cpu_env, twd, tws, twt);
29780             break;
29781         case DF_DOUBLE:
29782             gen_helper_msa_subv_d(cpu_env, twd, tws, twt);
29783             break;
29784         }
29785         break;
29786     case OPC_SUBS_U_df:
29787         switch (df) {
29788         case DF_BYTE:
29789             gen_helper_msa_subs_u_b(cpu_env, twd, tws, twt);
29790             break;
29791         case DF_HALF:
29792             gen_helper_msa_subs_u_h(cpu_env, twd, tws, twt);
29793             break;
29794         case DF_WORD:
29795             gen_helper_msa_subs_u_w(cpu_env, twd, tws, twt);
29796             break;
29797         case DF_DOUBLE:
29798             gen_helper_msa_subs_u_d(cpu_env, twd, tws, twt);
29799             break;
29800         }
29801         break;
29802     case OPC_SPLAT_df:
29803         gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
29804         break;
29805     case OPC_SUBSUS_U_df:
29806         switch (df) {
29807         case DF_BYTE:
29808             gen_helper_msa_subsus_u_b(cpu_env, twd, tws, twt);
29809             break;
29810         case DF_HALF:
29811             gen_helper_msa_subsus_u_h(cpu_env, twd, tws, twt);
29812             break;
29813         case DF_WORD:
29814             gen_helper_msa_subsus_u_w(cpu_env, twd, tws, twt);
29815             break;
29816         case DF_DOUBLE:
29817             gen_helper_msa_subsus_u_d(cpu_env, twd, tws, twt);
29818             break;
29819         }
29820         break;
29821     case OPC_SUBSUU_S_df:
29822         switch (df) {
29823         case DF_BYTE:
29824             gen_helper_msa_subsuu_s_b(cpu_env, twd, tws, twt);
29825             break;
29826         case DF_HALF:
29827             gen_helper_msa_subsuu_s_h(cpu_env, twd, tws, twt);
29828             break;
29829         case DF_WORD:
29830             gen_helper_msa_subsuu_s_w(cpu_env, twd, tws, twt);
29831             break;
29832         case DF_DOUBLE:
29833             gen_helper_msa_subsuu_s_d(cpu_env, twd, tws, twt);
29834             break;
29835         }
29836         break;
29837 
29838     case OPC_DOTP_S_df:
29839     case OPC_DOTP_U_df:
29840     case OPC_DPADD_S_df:
29841     case OPC_DPADD_U_df:
29842     case OPC_DPSUB_S_df:
29843     case OPC_HADD_S_df:
29844     case OPC_DPSUB_U_df:
29845     case OPC_HADD_U_df:
29846     case OPC_HSUB_S_df:
29847     case OPC_HSUB_U_df:
29848         if (df == DF_BYTE) {
29849             generate_exception_end(ctx, EXCP_RI);
29850             break;
29851         }
29852         switch (MASK_MSA_3R(ctx->opcode)) {
29853         case OPC_HADD_S_df:
29854             switch (df) {
29855             case DF_HALF:
29856                 gen_helper_msa_hadd_s_h(cpu_env, twd, tws, twt);
29857                 break;
29858             case DF_WORD:
29859                 gen_helper_msa_hadd_s_w(cpu_env, twd, tws, twt);
29860                 break;
29861             case DF_DOUBLE:
29862                 gen_helper_msa_hadd_s_d(cpu_env, twd, tws, twt);
29863                 break;
29864             }
29865             break;
29866         case OPC_HADD_U_df:
29867             switch (df) {
29868             case DF_HALF:
29869                 gen_helper_msa_hadd_u_h(cpu_env, twd, tws, twt);
29870                 break;
29871             case DF_WORD:
29872                 gen_helper_msa_hadd_u_w(cpu_env, twd, tws, twt);
29873                 break;
29874             case DF_DOUBLE:
29875                 gen_helper_msa_hadd_u_d(cpu_env, twd, tws, twt);
29876                 break;
29877             }
29878             break;
29879         case OPC_HSUB_S_df:
29880             switch (df) {
29881             case DF_HALF:
29882                 gen_helper_msa_hsub_s_h(cpu_env, twd, tws, twt);
29883                 break;
29884             case DF_WORD:
29885                 gen_helper_msa_hsub_s_w(cpu_env, twd, tws, twt);
29886                 break;
29887             case DF_DOUBLE:
29888                 gen_helper_msa_hsub_s_d(cpu_env, twd, tws, twt);
29889                 break;
29890             }
29891             break;
29892         case OPC_HSUB_U_df:
29893             switch (df) {
29894             case DF_HALF:
29895                 gen_helper_msa_hsub_u_h(cpu_env, twd, tws, twt);
29896                 break;
29897             case DF_WORD:
29898                 gen_helper_msa_hsub_u_w(cpu_env, twd, tws, twt);
29899                 break;
29900             case DF_DOUBLE:
29901                 gen_helper_msa_hsub_u_d(cpu_env, twd, tws, twt);
29902                 break;
29903             }
29904             break;
29905         case OPC_DOTP_S_df:
29906             switch (df) {
29907             case DF_HALF:
29908                 gen_helper_msa_dotp_s_h(cpu_env, twd, tws, twt);
29909                 break;
29910             case DF_WORD:
29911                 gen_helper_msa_dotp_s_w(cpu_env, twd, tws, twt);
29912                 break;
29913             case DF_DOUBLE:
29914                 gen_helper_msa_dotp_s_d(cpu_env, twd, tws, twt);
29915                 break;
29916             }
29917             break;
29918         case OPC_DOTP_U_df:
29919             switch (df) {
29920             case DF_HALF:
29921                 gen_helper_msa_dotp_u_h(cpu_env, twd, tws, twt);
29922                 break;
29923             case DF_WORD:
29924                 gen_helper_msa_dotp_u_w(cpu_env, twd, tws, twt);
29925                 break;
29926             case DF_DOUBLE:
29927                 gen_helper_msa_dotp_u_d(cpu_env, twd, tws, twt);
29928                 break;
29929             }
29930             break;
29931         case OPC_DPADD_S_df:
29932             switch (df) {
29933             case DF_HALF:
29934                 gen_helper_msa_dpadd_s_h(cpu_env, twd, tws, twt);
29935                 break;
29936             case DF_WORD:
29937                 gen_helper_msa_dpadd_s_w(cpu_env, twd, tws, twt);
29938                 break;
29939             case DF_DOUBLE:
29940                 gen_helper_msa_dpadd_s_d(cpu_env, twd, tws, twt);
29941                 break;
29942             }
29943             break;
29944         case OPC_DPADD_U_df:
29945             switch (df) {
29946             case DF_HALF:
29947                 gen_helper_msa_dpadd_u_h(cpu_env, twd, tws, twt);
29948                 break;
29949             case DF_WORD:
29950                 gen_helper_msa_dpadd_u_w(cpu_env, twd, tws, twt);
29951                 break;
29952             case DF_DOUBLE:
29953                 gen_helper_msa_dpadd_u_d(cpu_env, twd, tws, twt);
29954                 break;
29955             }
29956             break;
29957         case OPC_DPSUB_S_df:
29958             switch (df) {
29959             case DF_HALF:
29960                 gen_helper_msa_dpsub_s_h(cpu_env, twd, tws, twt);
29961                 break;
29962             case DF_WORD:
29963                 gen_helper_msa_dpsub_s_w(cpu_env, twd, tws, twt);
29964                 break;
29965             case DF_DOUBLE:
29966                 gen_helper_msa_dpsub_s_d(cpu_env, twd, tws, twt);
29967                 break;
29968             }
29969             break;
29970         case OPC_DPSUB_U_df:
29971             switch (df) {
29972             case DF_HALF:
29973                 gen_helper_msa_dpsub_u_h(cpu_env, twd, tws, twt);
29974                 break;
29975             case DF_WORD:
29976                 gen_helper_msa_dpsub_u_w(cpu_env, twd, tws, twt);
29977                 break;
29978             case DF_DOUBLE:
29979                 gen_helper_msa_dpsub_u_d(cpu_env, twd, tws, twt);
29980                 break;
29981             }
29982             break;
29983         }
29984         break;
29985     default:
29986         MIPS_INVAL("MSA instruction");
29987         generate_exception_end(ctx, EXCP_RI);
29988         break;
29989     }
29990     tcg_temp_free_i32(twd);
29991     tcg_temp_free_i32(tws);
29992     tcg_temp_free_i32(twt);
29993     tcg_temp_free_i32(tdf);
29994 }
29995 
gen_msa_elm_3e(CPUMIPSState * env,DisasContext * ctx)29996 static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
29997 {
29998 #define MASK_MSA_ELM_DF3E(op)   (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
29999     uint8_t source = (ctx->opcode >> 11) & 0x1f;
30000     uint8_t dest = (ctx->opcode >> 6) & 0x1f;
30001     TCGv telm = tcg_temp_new();
30002     TCGv_i32 tsr = tcg_const_i32(source);
30003     TCGv_i32 tdt = tcg_const_i32(dest);
30004 
30005     switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
30006     case OPC_CTCMSA:
30007         gen_load_gpr(telm, source);
30008         gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
30009         break;
30010     case OPC_CFCMSA:
30011         gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
30012         gen_store_gpr(telm, dest);
30013         break;
30014     case OPC_MOVE_V:
30015         gen_helper_msa_move_v(cpu_env, tdt, tsr);
30016         break;
30017     default:
30018         MIPS_INVAL("MSA instruction");
30019         generate_exception_end(ctx, EXCP_RI);
30020         break;
30021     }
30022 
30023     tcg_temp_free(telm);
30024     tcg_temp_free_i32(tdt);
30025     tcg_temp_free_i32(tsr);
30026 }
30027 
gen_msa_elm_df(CPUMIPSState * env,DisasContext * ctx,uint32_t df,uint32_t n)30028 static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
30029         uint32_t n)
30030 {
30031 #define MASK_MSA_ELM(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
30032     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
30033     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
30034 
30035     TCGv_i32 tws = tcg_const_i32(ws);
30036     TCGv_i32 twd = tcg_const_i32(wd);
30037     TCGv_i32 tn  = tcg_const_i32(n);
30038     TCGv_i32 tdf = tcg_const_i32(df);
30039 
30040     switch (MASK_MSA_ELM(ctx->opcode)) {
30041     case OPC_SLDI_df:
30042         gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
30043         break;
30044     case OPC_SPLATI_df:
30045         gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
30046         break;
30047     case OPC_INSVE_df:
30048         gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
30049         break;
30050     case OPC_COPY_S_df:
30051     case OPC_COPY_U_df:
30052     case OPC_INSERT_df:
30053 #if !defined(TARGET_MIPS64)
30054         /* Double format valid only for MIPS64 */
30055         if (df == DF_DOUBLE) {
30056             generate_exception_end(ctx, EXCP_RI);
30057             break;
30058         }
30059         if ((MASK_MSA_ELM(ctx->opcode) == OPC_COPY_U_df) &&
30060               (df == DF_WORD)) {
30061             generate_exception_end(ctx, EXCP_RI);
30062             break;
30063         }
30064 #endif
30065         switch (MASK_MSA_ELM(ctx->opcode)) {
30066         case OPC_COPY_S_df:
30067             if (likely(wd != 0)) {
30068                 switch (df) {
30069                 case DF_BYTE:
30070                     gen_helper_msa_copy_s_b(cpu_env, twd, tws, tn);
30071                     break;
30072                 case DF_HALF:
30073                     gen_helper_msa_copy_s_h(cpu_env, twd, tws, tn);
30074                     break;
30075                 case DF_WORD:
30076                     gen_helper_msa_copy_s_w(cpu_env, twd, tws, tn);
30077                     break;
30078 #if defined(TARGET_MIPS64)
30079                 case DF_DOUBLE:
30080                     gen_helper_msa_copy_s_d(cpu_env, twd, tws, tn);
30081                     break;
30082 #endif
30083                 default:
30084                     assert(0);
30085                 }
30086             }
30087             break;
30088         case OPC_COPY_U_df:
30089             if (likely(wd != 0)) {
30090                 switch (df) {
30091                 case DF_BYTE:
30092                     gen_helper_msa_copy_u_b(cpu_env, twd, tws, tn);
30093                     break;
30094                 case DF_HALF:
30095                     gen_helper_msa_copy_u_h(cpu_env, twd, tws, tn);
30096                     break;
30097 #if defined(TARGET_MIPS64)
30098                 case DF_WORD:
30099                     gen_helper_msa_copy_u_w(cpu_env, twd, tws, tn);
30100                     break;
30101 #endif
30102                 default:
30103                     assert(0);
30104                 }
30105             }
30106             break;
30107         case OPC_INSERT_df:
30108             switch (df) {
30109             case DF_BYTE:
30110                 gen_helper_msa_insert_b(cpu_env, twd, tws, tn);
30111                 break;
30112             case DF_HALF:
30113                 gen_helper_msa_insert_h(cpu_env, twd, tws, tn);
30114                 break;
30115             case DF_WORD:
30116                 gen_helper_msa_insert_w(cpu_env, twd, tws, tn);
30117                 break;
30118 #if defined(TARGET_MIPS64)
30119             case DF_DOUBLE:
30120                 gen_helper_msa_insert_d(cpu_env, twd, tws, tn);
30121                 break;
30122 #endif
30123             default:
30124                 assert(0);
30125             }
30126             break;
30127         }
30128         break;
30129     default:
30130         MIPS_INVAL("MSA instruction");
30131         generate_exception_end(ctx, EXCP_RI);
30132     }
30133     tcg_temp_free_i32(twd);
30134     tcg_temp_free_i32(tws);
30135     tcg_temp_free_i32(tn);
30136     tcg_temp_free_i32(tdf);
30137 }
30138 
gen_msa_elm(CPUMIPSState * env,DisasContext * ctx)30139 static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
30140 {
30141     uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
30142     uint32_t df = 0, n = 0;
30143 
30144     if ((dfn & 0x30) == 0x00) {
30145         n = dfn & 0x0f;
30146         df = DF_BYTE;
30147     } else if ((dfn & 0x38) == 0x20) {
30148         n = dfn & 0x07;
30149         df = DF_HALF;
30150     } else if ((dfn & 0x3c) == 0x30) {
30151         n = dfn & 0x03;
30152         df = DF_WORD;
30153     } else if ((dfn & 0x3e) == 0x38) {
30154         n = dfn & 0x01;
30155         df = DF_DOUBLE;
30156     } else if (dfn == 0x3E) {
30157         /* CTCMSA, CFCMSA, MOVE.V */
30158         gen_msa_elm_3e(env, ctx);
30159         return;
30160     } else {
30161         generate_exception_end(ctx, EXCP_RI);
30162         return;
30163     }
30164 
30165     gen_msa_elm_df(env, ctx, df, n);
30166 }
30167 
gen_msa_3rf(CPUMIPSState * env,DisasContext * ctx)30168 static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
30169 {
30170 #define MASK_MSA_3RF(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
30171     uint8_t df = (ctx->opcode >> 21) & 0x1;
30172     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
30173     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
30174     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
30175 
30176     TCGv_i32 twd = tcg_const_i32(wd);
30177     TCGv_i32 tws = tcg_const_i32(ws);
30178     TCGv_i32 twt = tcg_const_i32(wt);
30179     TCGv_i32 tdf = tcg_temp_new_i32();
30180 
30181     /* adjust df value for floating-point instruction */
30182     tcg_gen_movi_i32(tdf, df + 2);
30183 
30184     switch (MASK_MSA_3RF(ctx->opcode)) {
30185     case OPC_FCAF_df:
30186         gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
30187         break;
30188     case OPC_FADD_df:
30189         gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
30190         break;
30191     case OPC_FCUN_df:
30192         gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
30193         break;
30194     case OPC_FSUB_df:
30195         gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
30196         break;
30197     case OPC_FCOR_df:
30198         gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
30199         break;
30200     case OPC_FCEQ_df:
30201         gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
30202         break;
30203     case OPC_FMUL_df:
30204         gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
30205         break;
30206     case OPC_FCUNE_df:
30207         gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
30208         break;
30209     case OPC_FCUEQ_df:
30210         gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
30211         break;
30212     case OPC_FDIV_df:
30213         gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
30214         break;
30215     case OPC_FCNE_df:
30216         gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
30217         break;
30218     case OPC_FCLT_df:
30219         gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
30220         break;
30221     case OPC_FMADD_df:
30222         gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
30223         break;
30224     case OPC_MUL_Q_df:
30225         tcg_gen_movi_i32(tdf, df + 1);
30226         gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
30227         break;
30228     case OPC_FCULT_df:
30229         gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
30230         break;
30231     case OPC_FMSUB_df:
30232         gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
30233         break;
30234     case OPC_MADD_Q_df:
30235         tcg_gen_movi_i32(tdf, df + 1);
30236         gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
30237         break;
30238     case OPC_FCLE_df:
30239         gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
30240         break;
30241     case OPC_MSUB_Q_df:
30242         tcg_gen_movi_i32(tdf, df + 1);
30243         gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
30244         break;
30245     case OPC_FCULE_df:
30246         gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
30247         break;
30248     case OPC_FEXP2_df:
30249         gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
30250         break;
30251     case OPC_FSAF_df:
30252         gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
30253         break;
30254     case OPC_FEXDO_df:
30255         gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
30256         break;
30257     case OPC_FSUN_df:
30258         gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
30259         break;
30260     case OPC_FSOR_df:
30261         gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
30262         break;
30263     case OPC_FSEQ_df:
30264         gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
30265         break;
30266     case OPC_FTQ_df:
30267         gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
30268         break;
30269     case OPC_FSUNE_df:
30270         gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
30271         break;
30272     case OPC_FSUEQ_df:
30273         gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
30274         break;
30275     case OPC_FSNE_df:
30276         gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
30277         break;
30278     case OPC_FSLT_df:
30279         gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
30280         break;
30281     case OPC_FMIN_df:
30282         gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
30283         break;
30284     case OPC_MULR_Q_df:
30285         tcg_gen_movi_i32(tdf, df + 1);
30286         gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
30287         break;
30288     case OPC_FSULT_df:
30289         gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
30290         break;
30291     case OPC_FMIN_A_df:
30292         gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
30293         break;
30294     case OPC_MADDR_Q_df:
30295         tcg_gen_movi_i32(tdf, df + 1);
30296         gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
30297         break;
30298     case OPC_FSLE_df:
30299         gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
30300         break;
30301     case OPC_FMAX_df:
30302         gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
30303         break;
30304     case OPC_MSUBR_Q_df:
30305         tcg_gen_movi_i32(tdf, df + 1);
30306         gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
30307         break;
30308     case OPC_FSULE_df:
30309         gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
30310         break;
30311     case OPC_FMAX_A_df:
30312         gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
30313         break;
30314     default:
30315         MIPS_INVAL("MSA instruction");
30316         generate_exception_end(ctx, EXCP_RI);
30317         break;
30318     }
30319 
30320     tcg_temp_free_i32(twd);
30321     tcg_temp_free_i32(tws);
30322     tcg_temp_free_i32(twt);
30323     tcg_temp_free_i32(tdf);
30324 }
30325 
gen_msa_2r(CPUMIPSState * env,DisasContext * ctx)30326 static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
30327 {
30328 #define MASK_MSA_2R(op)     (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
30329                             (op & (0x7 << 18)))
30330     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
30331     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
30332     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
30333     uint8_t df = (ctx->opcode >> 16) & 0x3;
30334     TCGv_i32 twd = tcg_const_i32(wd);
30335     TCGv_i32 tws = tcg_const_i32(ws);
30336     TCGv_i32 twt = tcg_const_i32(wt);
30337     TCGv_i32 tdf = tcg_const_i32(df);
30338 
30339     switch (MASK_MSA_2R(ctx->opcode)) {
30340     case OPC_FILL_df:
30341 #if !defined(TARGET_MIPS64)
30342         /* Double format valid only for MIPS64 */
30343         if (df == DF_DOUBLE) {
30344             generate_exception_end(ctx, EXCP_RI);
30345             break;
30346         }
30347 #endif
30348         gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
30349         break;
30350     case OPC_NLOC_df:
30351         switch (df) {
30352         case DF_BYTE:
30353             gen_helper_msa_nloc_b(cpu_env, twd, tws);
30354             break;
30355         case DF_HALF:
30356             gen_helper_msa_nloc_h(cpu_env, twd, tws);
30357             break;
30358         case DF_WORD:
30359             gen_helper_msa_nloc_w(cpu_env, twd, tws);
30360             break;
30361         case DF_DOUBLE:
30362             gen_helper_msa_nloc_d(cpu_env, twd, tws);
30363             break;
30364         }
30365         break;
30366     case OPC_NLZC_df:
30367         switch (df) {
30368         case DF_BYTE:
30369             gen_helper_msa_nlzc_b(cpu_env, twd, tws);
30370             break;
30371         case DF_HALF:
30372             gen_helper_msa_nlzc_h(cpu_env, twd, tws);
30373             break;
30374         case DF_WORD:
30375             gen_helper_msa_nlzc_w(cpu_env, twd, tws);
30376             break;
30377         case DF_DOUBLE:
30378             gen_helper_msa_nlzc_d(cpu_env, twd, tws);
30379             break;
30380         }
30381         break;
30382     case OPC_PCNT_df:
30383         switch (df) {
30384         case DF_BYTE:
30385             gen_helper_msa_pcnt_b(cpu_env, twd, tws);
30386             break;
30387         case DF_HALF:
30388             gen_helper_msa_pcnt_h(cpu_env, twd, tws);
30389             break;
30390         case DF_WORD:
30391             gen_helper_msa_pcnt_w(cpu_env, twd, tws);
30392             break;
30393         case DF_DOUBLE:
30394             gen_helper_msa_pcnt_d(cpu_env, twd, tws);
30395             break;
30396         }
30397         break;
30398     default:
30399         MIPS_INVAL("MSA instruction");
30400         generate_exception_end(ctx, EXCP_RI);
30401         break;
30402     }
30403 
30404     tcg_temp_free_i32(twd);
30405     tcg_temp_free_i32(tws);
30406     tcg_temp_free_i32(twt);
30407     tcg_temp_free_i32(tdf);
30408 }
30409 
gen_msa_2rf(CPUMIPSState * env,DisasContext * ctx)30410 static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
30411 {
30412 #define MASK_MSA_2RF(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
30413                             (op & (0xf << 17)))
30414     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
30415     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
30416     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
30417     uint8_t df = (ctx->opcode >> 16) & 0x1;
30418     TCGv_i32 twd = tcg_const_i32(wd);
30419     TCGv_i32 tws = tcg_const_i32(ws);
30420     TCGv_i32 twt = tcg_const_i32(wt);
30421     /* adjust df value for floating-point instruction */
30422     TCGv_i32 tdf = tcg_const_i32(df + 2);
30423 
30424     switch (MASK_MSA_2RF(ctx->opcode)) {
30425     case OPC_FCLASS_df:
30426         gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
30427         break;
30428     case OPC_FTRUNC_S_df:
30429         gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
30430         break;
30431     case OPC_FTRUNC_U_df:
30432         gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
30433         break;
30434     case OPC_FSQRT_df:
30435         gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
30436         break;
30437     case OPC_FRSQRT_df:
30438         gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
30439         break;
30440     case OPC_FRCP_df:
30441         gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
30442         break;
30443     case OPC_FRINT_df:
30444         gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
30445         break;
30446     case OPC_FLOG2_df:
30447         gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
30448         break;
30449     case OPC_FEXUPL_df:
30450         gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
30451         break;
30452     case OPC_FEXUPR_df:
30453         gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
30454         break;
30455     case OPC_FFQL_df:
30456         gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
30457         break;
30458     case OPC_FFQR_df:
30459         gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
30460         break;
30461     case OPC_FTINT_S_df:
30462         gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
30463         break;
30464     case OPC_FTINT_U_df:
30465         gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
30466         break;
30467     case OPC_FFINT_S_df:
30468         gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
30469         break;
30470     case OPC_FFINT_U_df:
30471         gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
30472         break;
30473     }
30474 
30475     tcg_temp_free_i32(twd);
30476     tcg_temp_free_i32(tws);
30477     tcg_temp_free_i32(twt);
30478     tcg_temp_free_i32(tdf);
30479 }
30480 
gen_msa_vec_v(CPUMIPSState * env,DisasContext * ctx)30481 static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
30482 {
30483 #define MASK_MSA_VEC(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
30484     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
30485     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
30486     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
30487     TCGv_i32 twd = tcg_const_i32(wd);
30488     TCGv_i32 tws = tcg_const_i32(ws);
30489     TCGv_i32 twt = tcg_const_i32(wt);
30490 
30491     switch (MASK_MSA_VEC(ctx->opcode)) {
30492     case OPC_AND_V:
30493         gen_helper_msa_and_v(cpu_env, twd, tws, twt);
30494         break;
30495     case OPC_OR_V:
30496         gen_helper_msa_or_v(cpu_env, twd, tws, twt);
30497         break;
30498     case OPC_NOR_V:
30499         gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
30500         break;
30501     case OPC_XOR_V:
30502         gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
30503         break;
30504     case OPC_BMNZ_V:
30505         gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
30506         break;
30507     case OPC_BMZ_V:
30508         gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
30509         break;
30510     case OPC_BSEL_V:
30511         gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
30512         break;
30513     default:
30514         MIPS_INVAL("MSA instruction");
30515         generate_exception_end(ctx, EXCP_RI);
30516         break;
30517     }
30518 
30519     tcg_temp_free_i32(twd);
30520     tcg_temp_free_i32(tws);
30521     tcg_temp_free_i32(twt);
30522 }
30523 
gen_msa_vec(CPUMIPSState * env,DisasContext * ctx)30524 static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
30525 {
30526     switch (MASK_MSA_VEC(ctx->opcode)) {
30527     case OPC_AND_V:
30528     case OPC_OR_V:
30529     case OPC_NOR_V:
30530     case OPC_XOR_V:
30531     case OPC_BMNZ_V:
30532     case OPC_BMZ_V:
30533     case OPC_BSEL_V:
30534         gen_msa_vec_v(env, ctx);
30535         break;
30536     case OPC_MSA_2R:
30537         gen_msa_2r(env, ctx);
30538         break;
30539     case OPC_MSA_2RF:
30540         gen_msa_2rf(env, ctx);
30541         break;
30542     default:
30543         MIPS_INVAL("MSA instruction");
30544         generate_exception_end(ctx, EXCP_RI);
30545         break;
30546     }
30547 }
30548 
gen_msa(CPUMIPSState * env,DisasContext * ctx)30549 static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
30550 {
30551     uint32_t opcode = ctx->opcode;
30552     check_insn(ctx, ASE_MSA);
30553     check_msa_access(ctx);
30554 
30555     switch (MASK_MSA_MINOR(opcode)) {
30556     case OPC_MSA_I8_00:
30557     case OPC_MSA_I8_01:
30558     case OPC_MSA_I8_02:
30559         gen_msa_i8(env, ctx);
30560         break;
30561     case OPC_MSA_I5_06:
30562     case OPC_MSA_I5_07:
30563         gen_msa_i5(env, ctx);
30564         break;
30565     case OPC_MSA_BIT_09:
30566     case OPC_MSA_BIT_0A:
30567         gen_msa_bit(env, ctx);
30568         break;
30569     case OPC_MSA_3R_0D:
30570     case OPC_MSA_3R_0E:
30571     case OPC_MSA_3R_0F:
30572     case OPC_MSA_3R_10:
30573     case OPC_MSA_3R_11:
30574     case OPC_MSA_3R_12:
30575     case OPC_MSA_3R_13:
30576     case OPC_MSA_3R_14:
30577     case OPC_MSA_3R_15:
30578         gen_msa_3r(env, ctx);
30579         break;
30580     case OPC_MSA_ELM:
30581         gen_msa_elm(env, ctx);
30582         break;
30583     case OPC_MSA_3RF_1A:
30584     case OPC_MSA_3RF_1B:
30585     case OPC_MSA_3RF_1C:
30586         gen_msa_3rf(env, ctx);
30587         break;
30588     case OPC_MSA_VEC:
30589         gen_msa_vec(env, ctx);
30590         break;
30591     case OPC_LD_B:
30592     case OPC_LD_H:
30593     case OPC_LD_W:
30594     case OPC_LD_D:
30595     case OPC_ST_B:
30596     case OPC_ST_H:
30597     case OPC_ST_W:
30598     case OPC_ST_D:
30599         {
30600             int32_t s10 = sextract32(ctx->opcode, 16, 10);
30601             uint8_t rs = (ctx->opcode >> 11) & 0x1f;
30602             uint8_t wd = (ctx->opcode >> 6) & 0x1f;
30603             uint8_t df = (ctx->opcode >> 0) & 0x3;
30604 
30605             TCGv_i32 twd = tcg_const_i32(wd);
30606             TCGv taddr = tcg_temp_new();
30607             gen_base_offset_addr(ctx, taddr, rs, s10 << df);
30608 
30609             switch (MASK_MSA_MINOR(opcode)) {
30610             case OPC_LD_B:
30611                 gen_helper_msa_ld_b(cpu_env, twd, taddr);
30612                 break;
30613             case OPC_LD_H:
30614                 gen_helper_msa_ld_h(cpu_env, twd, taddr);
30615                 break;
30616             case OPC_LD_W:
30617                 gen_helper_msa_ld_w(cpu_env, twd, taddr);
30618                 break;
30619             case OPC_LD_D:
30620                 gen_helper_msa_ld_d(cpu_env, twd, taddr);
30621                 break;
30622             case OPC_ST_B:
30623                 gen_helper_msa_st_b(cpu_env, twd, taddr);
30624                 break;
30625             case OPC_ST_H:
30626                 gen_helper_msa_st_h(cpu_env, twd, taddr);
30627                 break;
30628             case OPC_ST_W:
30629                 gen_helper_msa_st_w(cpu_env, twd, taddr);
30630                 break;
30631             case OPC_ST_D:
30632                 gen_helper_msa_st_d(cpu_env, twd, taddr);
30633                 break;
30634             }
30635 
30636             tcg_temp_free_i32(twd);
30637             tcg_temp_free(taddr);
30638         }
30639         break;
30640     default:
30641         MIPS_INVAL("MSA instruction");
30642         generate_exception_end(ctx, EXCP_RI);
30643         break;
30644     }
30645 
30646 }
30647 
decode_opc(CPUMIPSState * env,DisasContext * ctx)30648 static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
30649 {
30650     int32_t offset;
30651     int rs, rt, rd, sa;
30652     uint32_t op, op1;
30653     int16_t imm;
30654 
30655     /* make sure instructions are on a word boundary */
30656     if (ctx->base.pc_next & 0x3) {
30657         env->CP0_BadVAddr = ctx->base.pc_next;
30658         generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
30659         return;
30660     }
30661 
30662     /* Handle blikely not taken case */
30663     if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
30664         TCGLabel *l1 = gen_new_label();
30665 
30666         tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
30667         tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
30668         gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
30669         gen_set_label(l1);
30670     }
30671 
30672     op = MASK_OP_MAJOR(ctx->opcode);
30673     rs = (ctx->opcode >> 21) & 0x1f;
30674     rt = (ctx->opcode >> 16) & 0x1f;
30675     rd = (ctx->opcode >> 11) & 0x1f;
30676     sa = (ctx->opcode >> 6) & 0x1f;
30677     imm = (int16_t)ctx->opcode;
30678     switch (op) {
30679     case OPC_SPECIAL:
30680         decode_opc_special(env, ctx);
30681         break;
30682     case OPC_SPECIAL2:
30683 #if defined(TARGET_MIPS64)
30684         if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
30685             decode_mmi(env, ctx);
30686 #else
30687         if (ctx->insn_flags & ASE_MXU) {
30688             decode_opc_mxu(env, ctx);
30689 #endif
30690         } else {
30691             decode_opc_special2_legacy(env, ctx);
30692         }
30693         break;
30694     case OPC_SPECIAL3:
30695 #if defined(TARGET_MIPS64)
30696         if (ctx->insn_flags & INSN_R5900) {
30697             decode_mmi_sq(env, ctx);    /* MMI_OPC_SQ */
30698         } else {
30699             decode_opc_special3(env, ctx);
30700         }
30701 #else
30702         decode_opc_special3(env, ctx);
30703 #endif
30704         break;
30705     case OPC_REGIMM:
30706         op1 = MASK_REGIMM(ctx->opcode);
30707         switch (op1) {
30708         case OPC_BLTZL: /* REGIMM branches */
30709         case OPC_BGEZL:
30710         case OPC_BLTZALL:
30711         case OPC_BGEZALL:
30712             check_insn(ctx, ISA_MIPS2);
30713             check_insn_opc_removed(ctx, ISA_MIPS32R6);
30714             /* Fallthrough */
30715         case OPC_BLTZ:
30716         case OPC_BGEZ:
30717             gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
30718             break;
30719         case OPC_BLTZAL:
30720         case OPC_BGEZAL:
30721             if (ctx->insn_flags & ISA_MIPS32R6) {
30722                 if (rs == 0) {
30723                     /* OPC_NAL, OPC_BAL */
30724                     gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
30725                 } else {
30726                     generate_exception_end(ctx, EXCP_RI);
30727                 }
30728             } else {
30729                 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
30730             }
30731             break;
30732         case OPC_TGEI: /* REGIMM traps */
30733         case OPC_TGEIU:
30734         case OPC_TLTI:
30735         case OPC_TLTIU:
30736         case OPC_TEQI:
30737 
30738         case OPC_TNEI:
30739             check_insn(ctx, ISA_MIPS2);
30740             check_insn_opc_removed(ctx, ISA_MIPS32R6);
30741             gen_trap(ctx, op1, rs, -1, imm);
30742             break;
30743         case OPC_SIGRIE:
30744             check_insn(ctx, ISA_MIPS32R6);
30745             generate_exception_end(ctx, EXCP_RI);
30746             break;
30747         case OPC_SYNCI:
30748             check_insn(ctx, ISA_MIPS32R2);
30749             /*
30750              * Break the TB to be able to sync copied instructions
30751              * immediately.
30752              */
30753             ctx->base.is_jmp = DISAS_STOP;
30754             break;
30755         case OPC_BPOSGE32:    /* MIPS DSP branch */
30756 #if defined(TARGET_MIPS64)
30757         case OPC_BPOSGE64:
30758 #endif
30759             check_dsp(ctx);
30760             gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
30761             break;
30762 #if defined(TARGET_MIPS64)
30763         case OPC_DAHI:
30764             check_insn(ctx, ISA_MIPS32R6);
30765             check_mips_64(ctx);
30766             if (rs != 0) {
30767                 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
30768             }
30769             break;
30770         case OPC_DATI:
30771             check_insn(ctx, ISA_MIPS32R6);
30772             check_mips_64(ctx);
30773             if (rs != 0) {
30774                 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
30775             }
30776             break;
30777 #endif
30778         default:            /* Invalid */
30779             MIPS_INVAL("regimm");
30780             generate_exception_end(ctx, EXCP_RI);
30781             break;
30782         }
30783         break;
30784     case OPC_CP0:
30785         check_cp0_enabled(ctx);
30786         op1 = MASK_CP0(ctx->opcode);
30787         switch (op1) {
30788         case OPC_MFC0:
30789         case OPC_MTC0:
30790         case OPC_MFTR:
30791         case OPC_MTTR:
30792         case OPC_MFHC0:
30793         case OPC_MTHC0:
30794 #if defined(TARGET_MIPS64)
30795         case OPC_DMFC0:
30796         case OPC_DMTC0:
30797 #endif
30798 #ifndef CONFIG_USER_ONLY
30799             gen_cp0(env, ctx, op1, rt, rd);
30800 #endif /* !CONFIG_USER_ONLY */
30801             break;
30802         case OPC_C0:
30803         case OPC_C0_1:
30804         case OPC_C0_2:
30805         case OPC_C0_3:
30806         case OPC_C0_4:
30807         case OPC_C0_5:
30808         case OPC_C0_6:
30809         case OPC_C0_7:
30810         case OPC_C0_8:
30811         case OPC_C0_9:
30812         case OPC_C0_A:
30813         case OPC_C0_B:
30814         case OPC_C0_C:
30815         case OPC_C0_D:
30816         case OPC_C0_E:
30817         case OPC_C0_F:
30818 #ifndef CONFIG_USER_ONLY
30819             gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
30820 #endif /* !CONFIG_USER_ONLY */
30821             break;
30822         case OPC_MFMC0:
30823 #ifndef CONFIG_USER_ONLY
30824             {
30825                 uint32_t op2;
30826                 TCGv t0 = tcg_temp_new();
30827 
30828                 op2 = MASK_MFMC0(ctx->opcode);
30829                 switch (op2) {
30830                 case OPC_DMT:
30831                     check_cp0_mt(ctx);
30832                     gen_helper_dmt(t0);
30833                     gen_store_gpr(t0, rt);
30834                     break;
30835                 case OPC_EMT:
30836                     check_cp0_mt(ctx);
30837                     gen_helper_emt(t0);
30838                     gen_store_gpr(t0, rt);
30839                     break;
30840                 case OPC_DVPE:
30841                     check_cp0_mt(ctx);
30842                     gen_helper_dvpe(t0, cpu_env);
30843                     gen_store_gpr(t0, rt);
30844                     break;
30845                 case OPC_EVPE:
30846                     check_cp0_mt(ctx);
30847                     gen_helper_evpe(t0, cpu_env);
30848                     gen_store_gpr(t0, rt);
30849                     break;
30850                 case OPC_DVP:
30851                     check_insn(ctx, ISA_MIPS32R6);
30852                     if (ctx->vp) {
30853                         gen_helper_dvp(t0, cpu_env);
30854                         gen_store_gpr(t0, rt);
30855                     }
30856                     break;
30857                 case OPC_EVP:
30858                     check_insn(ctx, ISA_MIPS32R6);
30859                     if (ctx->vp) {
30860                         gen_helper_evp(t0, cpu_env);
30861                         gen_store_gpr(t0, rt);
30862                     }
30863                     break;
30864                 case OPC_DI:
30865                     check_insn(ctx, ISA_MIPS32R2);
30866                     save_cpu_state(ctx, 1);
30867                     gen_helper_di(t0, cpu_env);
30868                     gen_store_gpr(t0, rt);
30869                     /*
30870                      * Stop translation as we may have switched
30871                      * the execution mode.
30872                      */
30873                     ctx->base.is_jmp = DISAS_STOP;
30874                     break;
30875                 case OPC_EI:
30876                     check_insn(ctx, ISA_MIPS32R2);
30877                     save_cpu_state(ctx, 1);
30878                     gen_helper_ei(t0, cpu_env);
30879                     gen_store_gpr(t0, rt);
30880                     /*
30881                      * DISAS_STOP isn't sufficient, we need to ensure we break
30882                      * out of translated code to check for pending interrupts.
30883                      */
30884                     gen_save_pc(ctx->base.pc_next + 4);
30885                     ctx->base.is_jmp = DISAS_EXIT;
30886                     break;
30887                 default:            /* Invalid */
30888                     MIPS_INVAL("mfmc0");
30889                     generate_exception_end(ctx, EXCP_RI);
30890                     break;
30891                 }
30892                 tcg_temp_free(t0);
30893             }
30894 #endif /* !CONFIG_USER_ONLY */
30895             break;
30896         case OPC_RDPGPR:
30897             check_insn(ctx, ISA_MIPS32R2);
30898             gen_load_srsgpr(rt, rd);
30899             break;
30900         case OPC_WRPGPR:
30901             check_insn(ctx, ISA_MIPS32R2);
30902             gen_store_srsgpr(rt, rd);
30903             break;
30904         default:
30905             MIPS_INVAL("cp0");
30906             generate_exception_end(ctx, EXCP_RI);
30907             break;
30908         }
30909         break;
30910     case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
30911         if (ctx->insn_flags & ISA_MIPS32R6) {
30912             /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
30913             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
30914         } else {
30915             /* OPC_ADDI */
30916             /* Arithmetic with immediate opcode */
30917             gen_arith_imm(ctx, op, rt, rs, imm);
30918         }
30919         break;
30920     case OPC_ADDIU:
30921          gen_arith_imm(ctx, op, rt, rs, imm);
30922          break;
30923     case OPC_SLTI: /* Set on less than with immediate opcode */
30924     case OPC_SLTIU:
30925          gen_slt_imm(ctx, op, rt, rs, imm);
30926          break;
30927     case OPC_ANDI: /* Arithmetic with immediate opcode */
30928     case OPC_LUI: /* OPC_AUI */
30929     case OPC_ORI:
30930     case OPC_XORI:
30931          gen_logic_imm(ctx, op, rt, rs, imm);
30932          break;
30933     case OPC_J: /* Jump */
30934     case OPC_JAL:
30935          offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
30936          gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
30937          break;
30938     /* Branch */
30939     case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
30940         if (ctx->insn_flags & ISA_MIPS32R6) {
30941             if (rt == 0) {
30942                 generate_exception_end(ctx, EXCP_RI);
30943                 break;
30944             }
30945             /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
30946             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
30947         } else {
30948             /* OPC_BLEZL */
30949             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
30950         }
30951         break;
30952     case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
30953         if (ctx->insn_flags & ISA_MIPS32R6) {
30954             if (rt == 0) {
30955                 generate_exception_end(ctx, EXCP_RI);
30956                 break;
30957             }
30958             /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
30959             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
30960         } else {
30961             /* OPC_BGTZL */
30962             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
30963         }
30964         break;
30965     case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
30966         if (rt == 0) {
30967             /* OPC_BLEZ */
30968             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
30969         } else {
30970             check_insn(ctx, ISA_MIPS32R6);
30971             /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
30972             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
30973         }
30974         break;
30975     case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
30976         if (rt == 0) {
30977             /* OPC_BGTZ */
30978             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
30979         } else {
30980             check_insn(ctx, ISA_MIPS32R6);
30981             /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
30982             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
30983         }
30984         break;
30985     case OPC_BEQL:
30986     case OPC_BNEL:
30987         check_insn(ctx, ISA_MIPS2);
30988          check_insn_opc_removed(ctx, ISA_MIPS32R6);
30989         /* Fallthrough */
30990     case OPC_BEQ:
30991     case OPC_BNE:
30992          gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
30993          break;
30994     case OPC_LL: /* Load and stores */
30995         check_insn(ctx, ISA_MIPS2);
30996         if (ctx->insn_flags & INSN_R5900) {
30997             check_insn_opc_user_only(ctx, INSN_R5900);
30998         }
30999         /* Fallthrough */
31000     case OPC_LWL:
31001     case OPC_LWR:
31002         check_insn_opc_removed(ctx, ISA_MIPS32R6);
31003          /* Fallthrough */
31004     case OPC_LB:
31005     case OPC_LH:
31006     case OPC_LW:
31007     case OPC_LWPC:
31008     case OPC_LBU:
31009     case OPC_LHU:
31010          gen_ld(ctx, op, rt, rs, imm);
31011          break;
31012     case OPC_SWL:
31013     case OPC_SWR:
31014         check_insn_opc_removed(ctx, ISA_MIPS32R6);
31015         /* fall through */
31016     case OPC_SB:
31017     case OPC_SH:
31018     case OPC_SW:
31019          gen_st(ctx, op, rt, rs, imm);
31020          break;
31021     case OPC_SC:
31022         check_insn(ctx, ISA_MIPS2);
31023          check_insn_opc_removed(ctx, ISA_MIPS32R6);
31024         if (ctx->insn_flags & INSN_R5900) {
31025             check_insn_opc_user_only(ctx, INSN_R5900);
31026         }
31027         gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
31028         break;
31029     case OPC_CACHE:
31030         check_insn_opc_removed(ctx, ISA_MIPS32R6);
31031         check_cp0_enabled(ctx);
31032         check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
31033         if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
31034             gen_cache_operation(ctx, rt, rs, imm);
31035         }
31036         /* Treat as NOP. */
31037         break;
31038     case OPC_PREF:
31039         check_insn_opc_removed(ctx, ISA_MIPS32R6);
31040         if (ctx->insn_flags & INSN_R5900) {
31041             /* Treat as NOP. */
31042         } else {
31043             check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
31044             /* Treat as NOP. */
31045         }
31046         break;
31047 
31048     /* Floating point (COP1). */
31049     case OPC_LWC1:
31050     case OPC_LDC1:
31051     case OPC_SWC1:
31052     case OPC_SDC1:
31053         gen_cop1_ldst(ctx, op, rt, rs, imm);
31054         break;
31055 
31056     case OPC_CP1:
31057         op1 = MASK_CP1(ctx->opcode);
31058 
31059         switch (op1) {
31060         case OPC_MFHC1:
31061         case OPC_MTHC1:
31062             check_cp1_enabled(ctx);
31063             check_insn(ctx, ISA_MIPS32R2);
31064             /* fall through */
31065         case OPC_MFC1:
31066         case OPC_CFC1:
31067         case OPC_MTC1:
31068         case OPC_CTC1:
31069             check_cp1_enabled(ctx);
31070             gen_cp1(ctx, op1, rt, rd);
31071             break;
31072 #if defined(TARGET_MIPS64)
31073         case OPC_DMFC1:
31074         case OPC_DMTC1:
31075             check_cp1_enabled(ctx);
31076             check_insn(ctx, ISA_MIPS3);
31077             check_mips_64(ctx);
31078             gen_cp1(ctx, op1, rt, rd);
31079             break;
31080 #endif
31081         case OPC_BC1EQZ: /* OPC_BC1ANY2 */
31082             check_cp1_enabled(ctx);
31083             if (ctx->insn_flags & ISA_MIPS32R6) {
31084                 /* OPC_BC1EQZ */
31085                 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
31086                                        rt, imm << 2, 4);
31087             } else {
31088                 /* OPC_BC1ANY2 */
31089                 check_cop1x(ctx);
31090                 check_insn(ctx, ASE_MIPS3D);
31091                 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
31092                                     (rt >> 2) & 0x7, imm << 2);
31093             }
31094             break;
31095         case OPC_BC1NEZ:
31096             check_cp1_enabled(ctx);
31097             check_insn(ctx, ISA_MIPS32R6);
31098             gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
31099                                    rt, imm << 2, 4);
31100             break;
31101         case OPC_BC1ANY4:
31102             check_cp1_enabled(ctx);
31103             check_insn_opc_removed(ctx, ISA_MIPS32R6);
31104             check_cop1x(ctx);
31105             check_insn(ctx, ASE_MIPS3D);
31106             /* fall through */
31107         case OPC_BC1:
31108             check_cp1_enabled(ctx);
31109             check_insn_opc_removed(ctx, ISA_MIPS32R6);
31110             gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
31111                                 (rt >> 2) & 0x7, imm << 2);
31112             break;
31113         case OPC_PS_FMT:
31114             check_ps(ctx);
31115             /* fall through */
31116         case OPC_S_FMT:
31117         case OPC_D_FMT:
31118             check_cp1_enabled(ctx);
31119             gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
31120                        (imm >> 8) & 0x7);
31121             break;
31122         case OPC_W_FMT:
31123         case OPC_L_FMT:
31124         {
31125             int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
31126             check_cp1_enabled(ctx);
31127             if (ctx->insn_flags & ISA_MIPS32R6) {
31128                 switch (r6_op) {
31129                 case R6_OPC_CMP_AF_S:
31130                 case R6_OPC_CMP_UN_S:
31131                 case R6_OPC_CMP_EQ_S:
31132                 case R6_OPC_CMP_UEQ_S:
31133                 case R6_OPC_CMP_LT_S:
31134                 case R6_OPC_CMP_ULT_S:
31135                 case R6_OPC_CMP_LE_S:
31136                 case R6_OPC_CMP_ULE_S:
31137                 case R6_OPC_CMP_SAF_S:
31138                 case R6_OPC_CMP_SUN_S:
31139                 case R6_OPC_CMP_SEQ_S:
31140                 case R6_OPC_CMP_SEUQ_S:
31141                 case R6_OPC_CMP_SLT_S:
31142                 case R6_OPC_CMP_SULT_S:
31143                 case R6_OPC_CMP_SLE_S:
31144                 case R6_OPC_CMP_SULE_S:
31145                 case R6_OPC_CMP_OR_S:
31146                 case R6_OPC_CMP_UNE_S:
31147                 case R6_OPC_CMP_NE_S:
31148                 case R6_OPC_CMP_SOR_S:
31149                 case R6_OPC_CMP_SUNE_S:
31150                 case R6_OPC_CMP_SNE_S:
31151                     gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
31152                     break;
31153                 case R6_OPC_CMP_AF_D:
31154                 case R6_OPC_CMP_UN_D:
31155                 case R6_OPC_CMP_EQ_D:
31156                 case R6_OPC_CMP_UEQ_D:
31157                 case R6_OPC_CMP_LT_D:
31158                 case R6_OPC_CMP_ULT_D:
31159                 case R6_OPC_CMP_LE_D:
31160                 case R6_OPC_CMP_ULE_D:
31161                 case R6_OPC_CMP_SAF_D:
31162                 case R6_OPC_CMP_SUN_D:
31163                 case R6_OPC_CMP_SEQ_D:
31164                 case R6_OPC_CMP_SEUQ_D:
31165                 case R6_OPC_CMP_SLT_D:
31166                 case R6_OPC_CMP_SULT_D:
31167                 case R6_OPC_CMP_SLE_D:
31168                 case R6_OPC_CMP_SULE_D:
31169                 case R6_OPC_CMP_OR_D:
31170                 case R6_OPC_CMP_UNE_D:
31171                 case R6_OPC_CMP_NE_D:
31172                 case R6_OPC_CMP_SOR_D:
31173                 case R6_OPC_CMP_SUNE_D:
31174                 case R6_OPC_CMP_SNE_D:
31175                     gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
31176                     break;
31177                 default:
31178                     gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
31179                                rt, rd, sa, (imm >> 8) & 0x7);
31180 
31181                     break;
31182                 }
31183             } else {
31184                 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
31185                            (imm >> 8) & 0x7);
31186             }
31187             break;
31188         }
31189         case OPC_BZ_V:
31190         case OPC_BNZ_V:
31191         case OPC_BZ_B:
31192         case OPC_BZ_H:
31193         case OPC_BZ_W:
31194         case OPC_BZ_D:
31195         case OPC_BNZ_B:
31196         case OPC_BNZ_H:
31197         case OPC_BNZ_W:
31198         case OPC_BNZ_D:
31199             check_insn(ctx, ASE_MSA);
31200             gen_msa_branch(env, ctx, op1);
31201             break;
31202         default:
31203             MIPS_INVAL("cp1");
31204             generate_exception_end(ctx, EXCP_RI);
31205             break;
31206         }
31207         break;
31208 
31209     /* Compact branches [R6] and COP2 [non-R6] */
31210     case OPC_BC: /* OPC_LWC2 */
31211     case OPC_BALC: /* OPC_SWC2 */
31212         if (ctx->insn_flags & ISA_MIPS32R6) {
31213             /* OPC_BC, OPC_BALC */
31214             gen_compute_compact_branch(ctx, op, 0, 0,
31215                                        sextract32(ctx->opcode << 2, 0, 28));
31216         } else if (ctx->insn_flags & ASE_LEXT) {
31217             gen_loongson_lswc2(ctx, rt, rs, rd);
31218         } else {
31219             /* OPC_LWC2, OPC_SWC2 */
31220             /* COP2: Not implemented. */
31221             generate_exception_err(ctx, EXCP_CpU, 2);
31222         }
31223         break;
31224     case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
31225     case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
31226         if (ctx->insn_flags & ISA_MIPS32R6) {
31227             if (rs != 0) {
31228                 /* OPC_BEQZC, OPC_BNEZC */
31229                 gen_compute_compact_branch(ctx, op, rs, 0,
31230                                            sextract32(ctx->opcode << 2, 0, 23));
31231             } else {
31232                 /* OPC_JIC, OPC_JIALC */
31233                 gen_compute_compact_branch(ctx, op, 0, rt, imm);
31234             }
31235         } else if (ctx->insn_flags & ASE_LEXT) {
31236             gen_loongson_lsdc2(ctx, rt, rs, rd);
31237         } else {
31238             /* OPC_LWC2, OPC_SWC2 */
31239             /* COP2: Not implemented. */
31240             generate_exception_err(ctx, EXCP_CpU, 2);
31241         }
31242         break;
31243     case OPC_CP2:
31244         check_insn(ctx, ASE_LMMI);
31245         /* Note that these instructions use different fields.  */
31246         gen_loongson_multimedia(ctx, sa, rd, rt);
31247         break;
31248 
31249     case OPC_CP3:
31250         check_insn_opc_removed(ctx, ISA_MIPS32R6);
31251         if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
31252             check_cp1_enabled(ctx);
31253             op1 = MASK_CP3(ctx->opcode);
31254             switch (op1) {
31255             case OPC_LUXC1:
31256             case OPC_SUXC1:
31257                 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
31258                 /* Fallthrough */
31259             case OPC_LWXC1:
31260             case OPC_LDXC1:
31261             case OPC_SWXC1:
31262             case OPC_SDXC1:
31263                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
31264                 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
31265                 break;
31266             case OPC_PREFX:
31267                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
31268                 /* Treat as NOP. */
31269                 break;
31270             case OPC_ALNV_PS:
31271                 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
31272                 /* Fallthrough */
31273             case OPC_MADD_S:
31274             case OPC_MADD_D:
31275             case OPC_MADD_PS:
31276             case OPC_MSUB_S:
31277             case OPC_MSUB_D:
31278             case OPC_MSUB_PS:
31279             case OPC_NMADD_S:
31280             case OPC_NMADD_D:
31281             case OPC_NMADD_PS:
31282             case OPC_NMSUB_S:
31283             case OPC_NMSUB_D:
31284             case OPC_NMSUB_PS:
31285                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
31286                 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
31287                 break;
31288             default:
31289                 MIPS_INVAL("cp3");
31290                 generate_exception_end(ctx, EXCP_RI);
31291                 break;
31292             }
31293         } else {
31294             generate_exception_err(ctx, EXCP_CpU, 1);
31295         }
31296         break;
31297 
31298 #if defined(TARGET_MIPS64)
31299     /* MIPS64 opcodes */
31300     case OPC_LLD:
31301         if (ctx->insn_flags & INSN_R5900) {
31302             check_insn_opc_user_only(ctx, INSN_R5900);
31303         }
31304         /* fall through */
31305     case OPC_LDL:
31306     case OPC_LDR:
31307         check_insn_opc_removed(ctx, ISA_MIPS32R6);
31308         /* fall through */
31309     case OPC_LWU:
31310     case OPC_LD:
31311         check_insn(ctx, ISA_MIPS3);
31312         check_mips_64(ctx);
31313         gen_ld(ctx, op, rt, rs, imm);
31314         break;
31315     case OPC_SDL:
31316     case OPC_SDR:
31317         check_insn_opc_removed(ctx, ISA_MIPS32R6);
31318         /* fall through */
31319     case OPC_SD:
31320         check_insn(ctx, ISA_MIPS3);
31321         check_mips_64(ctx);
31322         gen_st(ctx, op, rt, rs, imm);
31323         break;
31324     case OPC_SCD:
31325         check_insn_opc_removed(ctx, ISA_MIPS32R6);
31326         check_insn(ctx, ISA_MIPS3);
31327         if (ctx->insn_flags & INSN_R5900) {
31328             check_insn_opc_user_only(ctx, INSN_R5900);
31329         }
31330         check_mips_64(ctx);
31331         gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false);
31332         break;
31333     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
31334         if (ctx->insn_flags & ISA_MIPS32R6) {
31335             /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
31336             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
31337         } else {
31338             /* OPC_DADDI */
31339             check_insn(ctx, ISA_MIPS3);
31340             check_mips_64(ctx);
31341             gen_arith_imm(ctx, op, rt, rs, imm);
31342         }
31343         break;
31344     case OPC_DADDIU:
31345         check_insn(ctx, ISA_MIPS3);
31346         check_mips_64(ctx);
31347         gen_arith_imm(ctx, op, rt, rs, imm);
31348         break;
31349 #else
31350     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
31351         if (ctx->insn_flags & ISA_MIPS32R6) {
31352             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
31353         } else {
31354             MIPS_INVAL("major opcode");
31355             generate_exception_end(ctx, EXCP_RI);
31356         }
31357         break;
31358 #endif
31359     case OPC_DAUI: /* OPC_JALX */
31360         if (ctx->insn_flags & ISA_MIPS32R6) {
31361 #if defined(TARGET_MIPS64)
31362             /* OPC_DAUI */
31363             check_mips_64(ctx);
31364             if (rs == 0) {
31365                 generate_exception(ctx, EXCP_RI);
31366             } else if (rt != 0) {
31367                 TCGv t0 = tcg_temp_new();
31368                 gen_load_gpr(t0, rs);
31369                 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
31370                 tcg_temp_free(t0);
31371             }
31372 #else
31373             generate_exception_end(ctx, EXCP_RI);
31374             MIPS_INVAL("major opcode");
31375 #endif
31376         } else {
31377             /* OPC_JALX */
31378             check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
31379             offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
31380             gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
31381         }
31382         break;
31383     case OPC_MSA: /* OPC_MDMX */
31384         if (ctx->insn_flags & INSN_R5900) {
31385 #if defined(TARGET_MIPS64)
31386             gen_mmi_lq(env, ctx);    /* MMI_OPC_LQ */
31387 #endif
31388         } else {
31389             /* MDMX: Not implemented. */
31390             gen_msa(env, ctx);
31391         }
31392         break;
31393     case OPC_PCREL:
31394         check_insn(ctx, ISA_MIPS32R6);
31395         gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
31396         break;
31397     default:            /* Invalid */
31398         MIPS_INVAL("major opcode");
31399         generate_exception_end(ctx, EXCP_RI);
31400         break;
31401     }
31402 }
31403 
31404 static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
31405 {
31406     DisasContext *ctx = container_of(dcbase, DisasContext, base);
31407     CPUMIPSState *env = cs->env_ptr;
31408 
31409     ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
31410     ctx->saved_pc = -1;
31411     ctx->insn_flags = env->insn_flags;
31412     ctx->CP0_Config1 = env->CP0_Config1;
31413     ctx->CP0_Config2 = env->CP0_Config2;
31414     ctx->CP0_Config3 = env->CP0_Config3;
31415     ctx->CP0_Config5 = env->CP0_Config5;
31416     ctx->btarget = 0;
31417     ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
31418     ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
31419     ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
31420     ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
31421     ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
31422     ctx->PAMask = env->PAMask;
31423     ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
31424     ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
31425     ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
31426     ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
31427     ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
31428     /* Restore delay slot state from the tb context.  */
31429     ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
31430     ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
31431     ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
31432              (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
31433     ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
31434     ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
31435     ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
31436     ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
31437     ctx->mi = (env->CP0_Config5 >> CP0C5_MI) & 1;
31438     ctx->gi = (env->CP0_Config5 >> CP0C5_GI) & 3;
31439     restore_cpu_state(env, ctx);
31440 #ifdef CONFIG_USER_ONLY
31441         ctx->mem_idx = MIPS_HFLAG_UM;
31442 #else
31443         ctx->mem_idx = hflags_mmu_index(ctx->hflags);
31444 #endif
31445     ctx->default_tcg_memop_mask = (ctx->insn_flags & (ISA_MIPS32R6 | ISA_MIPS64R6 |
31446                                   INSN_LOONGSON3A)) ? MO_UNALN : MO_ALIGN;
31447 
31448     LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
31449               ctx->hflags);
31450 }
31451 
31452 static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
31453 {
31454 }
31455 
31456 static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
31457 {
31458     DisasContext *ctx = container_of(dcbase, DisasContext, base);
31459 
31460     tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
31461                        ctx->btarget);
31462 }
31463 
31464 static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
31465                                      const CPUBreakpoint *bp)
31466 {
31467     DisasContext *ctx = container_of(dcbase, DisasContext, base);
31468 
31469     save_cpu_state(ctx, 1);
31470     ctx->base.is_jmp = DISAS_NORETURN;
31471     gen_helper_raise_exception_debug(cpu_env);
31472     /*
31473      * The address covered by the breakpoint must be included in
31474      * [tb->pc, tb->pc + tb->size) in order to for it to be
31475      * properly cleared -- thus we increment the PC here so that
31476      * the logic setting tb->size below does the right thing.
31477      */
31478     ctx->base.pc_next += 4;
31479     return true;
31480 }
31481 
31482 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
31483 {
31484     CPUMIPSState *env = cs->env_ptr;
31485     DisasContext *ctx = container_of(dcbase, DisasContext, base);
31486     int insn_bytes;
31487     int is_slot;
31488 
31489     is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
31490     if (ctx->insn_flags & ISA_NANOMIPS32) {
31491         ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
31492         insn_bytes = decode_nanomips_opc(env, ctx);
31493     } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
31494         ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
31495         insn_bytes = 4;
31496         decode_opc(env, ctx);
31497     } else if (ctx->insn_flags & ASE_MICROMIPS) {
31498         ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
31499         insn_bytes = decode_micromips_opc(env, ctx);
31500     } else if (ctx->insn_flags & ASE_MIPS16) {
31501         ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
31502         insn_bytes = decode_mips16_opc(env, ctx);
31503     } else {
31504         generate_exception_end(ctx, EXCP_RI);
31505         g_assert(ctx->base.is_jmp == DISAS_NORETURN);
31506         return;
31507     }
31508 
31509     if (ctx->hflags & MIPS_HFLAG_BMASK) {
31510         if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
31511                              MIPS_HFLAG_FBNSLOT))) {
31512             /*
31513              * Force to generate branch as there is neither delay nor
31514              * forbidden slot.
31515              */
31516             is_slot = 1;
31517         }
31518         if ((ctx->hflags & MIPS_HFLAG_M16) &&
31519             (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
31520             /*
31521              * Force to generate branch as microMIPS R6 doesn't restrict
31522              * branches in the forbidden slot.
31523              */
31524             is_slot = 1;
31525         }
31526     }
31527     if (is_slot) {
31528         gen_branch(ctx, insn_bytes);
31529     }
31530     ctx->base.pc_next += insn_bytes;
31531 
31532     if (ctx->base.is_jmp != DISAS_NEXT) {
31533         return;
31534     }
31535     /*
31536      * Execute a branch and its delay slot as a single instruction.
31537      * This is what GDB expects and is consistent with what the
31538      * hardware does (e.g. if a delay slot instruction faults, the
31539      * reported PC is the PC of the branch).
31540      */
31541     if (ctx->base.singlestep_enabled &&
31542         (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
31543         ctx->base.is_jmp = DISAS_TOO_MANY;
31544     }
31545     if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
31546         ctx->base.is_jmp = DISAS_TOO_MANY;
31547     }
31548 }
31549 
31550 static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
31551 {
31552     DisasContext *ctx = container_of(dcbase, DisasContext, base);
31553 
31554     if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
31555         save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
31556         gen_helper_raise_exception_debug(cpu_env);
31557     } else {
31558         switch (ctx->base.is_jmp) {
31559         case DISAS_STOP:
31560             gen_save_pc(ctx->base.pc_next);
31561             tcg_gen_lookup_and_goto_ptr();
31562             break;
31563         case DISAS_NEXT:
31564         case DISAS_TOO_MANY:
31565             save_cpu_state(ctx, 0);
31566             gen_goto_tb(ctx, 0, ctx->base.pc_next);
31567             break;
31568         case DISAS_EXIT:
31569             tcg_gen_exit_tb(NULL, 0);
31570             break;
31571         case DISAS_NORETURN:
31572             break;
31573         default:
31574             g_assert_not_reached();
31575         }
31576     }
31577 }
31578 
31579 static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
31580 {
31581     qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
31582     log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
31583 }
31584 
31585 static const TranslatorOps mips_tr_ops = {
31586     .init_disas_context = mips_tr_init_disas_context,
31587     .tb_start           = mips_tr_tb_start,
31588     .insn_start         = mips_tr_insn_start,
31589     .breakpoint_check   = mips_tr_breakpoint_check,
31590     .translate_insn     = mips_tr_translate_insn,
31591     .tb_stop            = mips_tr_tb_stop,
31592     .disas_log          = mips_tr_disas_log,
31593 };
31594 
31595 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
31596 {
31597     DisasContext ctx;
31598 
31599     translator_loop(&mips_tr_ops, &ctx.base, cs, tb, max_insns);
31600 }
31601 
31602 static void fpu_dump_state(CPUMIPSState *env, FILE * f, int flags)
31603 {
31604     int i;
31605     int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
31606 
31607 #define printfpr(fp)                                                    \
31608     do {                                                                \
31609         if (is_fpu64)                                                   \
31610             qemu_fprintf(f, "w:%08x d:%016" PRIx64                      \
31611                          " fd:%13g fs:%13g psu: %13g\n",                \
31612                          (fp)->w[FP_ENDIAN_IDX], (fp)->d,               \
31613                          (double)(fp)->fd,                              \
31614                          (double)(fp)->fs[FP_ENDIAN_IDX],               \
31615                          (double)(fp)->fs[!FP_ENDIAN_IDX]);             \
31616         else {                                                          \
31617             fpr_t tmp;                                                  \
31618             tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];              \
31619             tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];       \
31620             qemu_fprintf(f, "w:%08x d:%016" PRIx64                      \
31621                          " fd:%13g fs:%13g psu:%13g\n",                 \
31622                          tmp.w[FP_ENDIAN_IDX], tmp.d,                   \
31623                          (double)tmp.fd,                                \
31624                          (double)tmp.fs[FP_ENDIAN_IDX],                 \
31625                          (double)tmp.fs[!FP_ENDIAN_IDX]);               \
31626         }                                                               \
31627     } while (0)
31628 
31629 
31630     qemu_fprintf(f,
31631                  "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%02x\n",
31632                  env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
31633                  get_float_exception_flags(&env->active_fpu.fp_status));
31634     for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
31635         qemu_fprintf(f, "%3s: ", fregnames[i]);
31636         printfpr(&env->active_fpu.fpr[i]);
31637     }
31638 
31639 #undef printfpr
31640 }
31641 
31642 void mips_cpu_dump_state(CPUState *cs, FILE *f, int flags)
31643 {
31644     MIPSCPU *cpu = MIPS_CPU(cs);
31645     CPUMIPSState *env = &cpu->env;
31646     int i;
31647 
31648     qemu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
31649                  " LO=0x" TARGET_FMT_lx " ds %04x "
31650                  TARGET_FMT_lx " " TARGET_FMT_ld "\n",
31651                  env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
31652                  env->hflags, env->btarget, env->bcond);
31653     for (i = 0; i < 32; i++) {
31654         if ((i & 3) == 0) {
31655             qemu_fprintf(f, "GPR%02d:", i);
31656         }
31657         qemu_fprintf(f, " %s " TARGET_FMT_lx,
31658                      regnames[i], env->active_tc.gpr[i]);
31659         if ((i & 3) == 3) {
31660             qemu_fprintf(f, "\n");
31661         }
31662     }
31663 
31664     qemu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x"
31665                  TARGET_FMT_lx "\n",
31666                  env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
31667     qemu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
31668                  PRIx64 "\n",
31669                  env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
31670     qemu_fprintf(f, "    Config2 0x%08x Config3 0x%08x\n",
31671                  env->CP0_Config2, env->CP0_Config3);
31672     qemu_fprintf(f, "    Config4 0x%08x Config5 0x%08x\n",
31673                  env->CP0_Config4, env->CP0_Config5);
31674     if ((flags & CPU_DUMP_FPU) && (env->hflags & MIPS_HFLAG_FPU)) {
31675         fpu_dump_state(env, f, flags);
31676     }
31677 }
31678 
31679 void mips_tcg_init(void)
31680 {
31681     int i;
31682 
31683     cpu_gpr[0] = NULL;
31684     for (i = 1; i < 32; i++)
31685         cpu_gpr[i] = tcg_global_mem_new(cpu_env,
31686                                         offsetof(CPUMIPSState,
31687                                                  active_tc.gpr[i]),
31688                                         regnames[i]);
31689 
31690     for (i = 0; i < 32; i++) {
31691         int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
31692         msa_wr_d[i * 2] =
31693                 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
31694         /*
31695          * The scalar floating-point unit (FPU) registers are mapped on
31696          * the MSA vector registers.
31697          */
31698         fpu_f64[i] = msa_wr_d[i * 2];
31699         off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
31700         msa_wr_d[i * 2 + 1] =
31701                 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
31702     }
31703 
31704     cpu_PC = tcg_global_mem_new(cpu_env,
31705                                 offsetof(CPUMIPSState, active_tc.PC), "PC");
31706     for (i = 0; i < MIPS_DSP_ACC; i++) {
31707         cpu_HI[i] = tcg_global_mem_new(cpu_env,
31708                                        offsetof(CPUMIPSState, active_tc.HI[i]),
31709                                        regnames_HI[i]);
31710         cpu_LO[i] = tcg_global_mem_new(cpu_env,
31711                                        offsetof(CPUMIPSState, active_tc.LO[i]),
31712                                        regnames_LO[i]);
31713     }
31714     cpu_dspctrl = tcg_global_mem_new(cpu_env,
31715                                      offsetof(CPUMIPSState,
31716                                               active_tc.DSPControl),
31717                                      "DSPControl");
31718     bcond = tcg_global_mem_new(cpu_env,
31719                                offsetof(CPUMIPSState, bcond), "bcond");
31720     btarget = tcg_global_mem_new(cpu_env,
31721                                  offsetof(CPUMIPSState, btarget), "btarget");
31722     hflags = tcg_global_mem_new_i32(cpu_env,
31723                                     offsetof(CPUMIPSState, hflags), "hflags");
31724 
31725     fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
31726                                       offsetof(CPUMIPSState, active_fpu.fcr0),
31727                                       "fcr0");
31728     fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
31729                                        offsetof(CPUMIPSState, active_fpu.fcr31),
31730                                        "fcr31");
31731     cpu_lladdr = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, lladdr),
31732                                     "lladdr");
31733     cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, llval),
31734                                    "llval");
31735 
31736 #if defined(TARGET_MIPS64)
31737     cpu_mmr[0] = NULL;
31738     for (i = 1; i < 32; i++) {
31739         cpu_mmr[i] = tcg_global_mem_new_i64(cpu_env,
31740                                             offsetof(CPUMIPSState,
31741                                                      active_tc.mmr[i]),
31742                                             regnames[i]);
31743     }
31744 #endif
31745 
31746 #if !defined(TARGET_MIPS64)
31747     for (i = 0; i < NUMBER_OF_MXU_REGISTERS - 1; i++) {
31748         mxu_gpr[i] = tcg_global_mem_new(cpu_env,
31749                                         offsetof(CPUMIPSState,
31750                                                  active_tc.mxu_gpr[i]),
31751                                         mxuregnames[i]);
31752     }
31753 
31754     mxu_CR = tcg_global_mem_new(cpu_env,
31755                                 offsetof(CPUMIPSState, active_tc.mxu_cr),
31756                                 mxuregnames[NUMBER_OF_MXU_REGISTERS - 1]);
31757 #endif
31758 }
31759 
31760 #include "translate_init.c.inc"
31761 
31762 void cpu_mips_realize_env(CPUMIPSState *env)
31763 {
31764     env->exception_base = (int32_t)0xBFC00000;
31765 
31766 #ifndef CONFIG_USER_ONLY
31767     mmu_init(env, env->cpu_model);
31768 #endif
31769     fpu_init(env, env->cpu_model);
31770     mvp_init(env, env->cpu_model);
31771 }
31772 
31773 bool cpu_supports_cps_smp(const char *cpu_type)
31774 {
31775     const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
31776     return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
31777 }
31778 
31779 bool cpu_supports_isa(const char *cpu_type, uint64_t isa)
31780 {
31781     const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
31782     return (mcc->cpu_def->insn_flags & isa) != 0;
31783 }
31784 
31785 void cpu_set_exception_base(int vp_index, target_ulong address)
31786 {
31787     MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
31788     vp->env.exception_base = address;
31789 }
31790 
31791 void cpu_state_reset(CPUMIPSState *env)
31792 {
31793     CPUState *cs = env_cpu(env);
31794 
31795     /* Reset registers to their default values */
31796     env->CP0_PRid = env->cpu_model->CP0_PRid;
31797     env->CP0_Config0 = env->cpu_model->CP0_Config0;
31798 #ifdef TARGET_WORDS_BIGENDIAN
31799     env->CP0_Config0 |= (1 << CP0C0_BE);
31800 #endif
31801     env->CP0_Config1 = env->cpu_model->CP0_Config1;
31802     env->CP0_Config2 = env->cpu_model->CP0_Config2;
31803     env->CP0_Config3 = env->cpu_model->CP0_Config3;
31804     env->CP0_Config4 = env->cpu_model->CP0_Config4;
31805     env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
31806     env->CP0_Config5 = env->cpu_model->CP0_Config5;
31807     env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
31808     env->CP0_Config6 = env->cpu_model->CP0_Config6;
31809     env->CP0_Config6_rw_bitmask = env->cpu_model->CP0_Config6_rw_bitmask;
31810     env->CP0_Config7 = env->cpu_model->CP0_Config7;
31811     env->CP0_Config7_rw_bitmask = env->cpu_model->CP0_Config7_rw_bitmask;
31812     env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
31813                                  << env->cpu_model->CP0_LLAddr_shift;
31814     env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
31815     env->SYNCI_Step = env->cpu_model->SYNCI_Step;
31816     env->CCRes = env->cpu_model->CCRes;
31817     env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
31818     env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
31819     env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
31820     env->current_tc = 0;
31821     env->SEGBITS = env->cpu_model->SEGBITS;
31822     env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
31823 #if defined(TARGET_MIPS64)
31824     if (env->cpu_model->insn_flags & ISA_MIPS3) {
31825         env->SEGMask |= 3ULL << 62;
31826     }
31827 #endif
31828     env->PABITS = env->cpu_model->PABITS;
31829     env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
31830     env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
31831     env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
31832     env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
31833     env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
31834     env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
31835     env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
31836     env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
31837     env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
31838     env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
31839     env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
31840     env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
31841     env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
31842     env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
31843     env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
31844     env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
31845     env->msair = env->cpu_model->MSAIR;
31846     env->insn_flags = env->cpu_model->insn_flags;
31847 
31848 #if defined(CONFIG_USER_ONLY)
31849     env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
31850 # ifdef TARGET_MIPS64
31851     /* Enable 64-bit register mode.  */
31852     env->CP0_Status |= (1 << CP0St_PX);
31853 # endif
31854 # ifdef TARGET_ABI_MIPSN64
31855     /* Enable 64-bit address mode.  */
31856     env->CP0_Status |= (1 << CP0St_UX);
31857 # endif
31858     /*
31859      * Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
31860      * hardware registers.
31861      */
31862     env->CP0_HWREna |= 0x0000000F;
31863     if (env->CP0_Config1 & (1 << CP0C1_FP)) {
31864         env->CP0_Status |= (1 << CP0St_CU1);
31865     }
31866     if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
31867         env->CP0_Status |= (1 << CP0St_MX);
31868     }
31869 # if defined(TARGET_MIPS64)
31870     /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
31871     if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
31872         (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
31873         env->CP0_Status |= (1 << CP0St_FR);
31874     }
31875 # endif
31876 #else
31877     if (env->hflags & MIPS_HFLAG_BMASK) {
31878         /*
31879          * If the exception was raised from a delay slot,
31880          * come back to the jump.
31881          */
31882         env->CP0_ErrorEPC = (env->active_tc.PC
31883                              - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
31884     } else {
31885         env->CP0_ErrorEPC = env->active_tc.PC;
31886     }
31887     env->active_tc.PC = env->exception_base;
31888     env->CP0_Random = env->tlb->nb_tlb - 1;
31889     env->tlb->tlb_in_use = env->tlb->nb_tlb;
31890     env->CP0_Wired = 0;
31891     env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
31892     env->CP0_EBase = (cs->cpu_index & 0x3FF);
31893     if (mips_um_ksegs_enabled()) {
31894         env->CP0_EBase |= 0x40000000;
31895     } else {
31896         env->CP0_EBase |= (int32_t)0x80000000;
31897     }
31898     if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
31899         env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
31900     }
31901     env->CP0_EntryHi_ASID_mask = (env->CP0_Config5 & (1 << CP0C5_MI)) ?
31902             0x0 : (env->CP0_Config4 & (1 << CP0C4_AE)) ? 0x3ff : 0xff;
31903     env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
31904     /*
31905      * Vectored interrupts not implemented, timer on int 7,
31906      * no performance counters.
31907      */
31908     env->CP0_IntCtl = 0xe0000000;
31909     {
31910         int i;
31911 
31912         for (i = 0; i < 7; i++) {
31913             env->CP0_WatchLo[i] = 0;
31914             env->CP0_WatchHi[i] = 0x80000000;
31915         }
31916         env->CP0_WatchLo[7] = 0;
31917         env->CP0_WatchHi[7] = 0;
31918     }
31919     /* Count register increments in debug mode, EJTAG version 1 */
31920     env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
31921 
31922     cpu_mips_store_count(env, 1);
31923 
31924     if (env->CP0_Config3 & (1 << CP0C3_MT)) {
31925         int i;
31926 
31927         /* Only TC0 on VPE 0 starts as active.  */
31928         for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
31929             env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
31930             env->tcs[i].CP0_TCHalt = 1;
31931         }
31932         env->active_tc.CP0_TCHalt = 1;
31933         cs->halted = 1;
31934 
31935         if (cs->cpu_index == 0) {
31936             /* VPE0 starts up enabled.  */
31937             env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
31938             env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
31939 
31940             /* TC0 starts up unhalted.  */
31941             cs->halted = 0;
31942             env->active_tc.CP0_TCHalt = 0;
31943             env->tcs[0].CP0_TCHalt = 0;
31944             /* With thread 0 active.  */
31945             env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
31946             env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
31947         }
31948     }
31949 
31950     /*
31951      * Configure default legacy segmentation control. We use this regardless of
31952      * whether segmentation control is presented to the guest.
31953      */
31954     /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
31955     env->CP0_SegCtl0 =   (CP0SC_AM_MK << CP0SC_AM);
31956     /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
31957     env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
31958     /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
31959     env->CP0_SegCtl1 =   (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
31960                          (2 << CP0SC_C);
31961     /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
31962     env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
31963                          (3 << CP0SC_C)) << 16;
31964     /* USeg (seg4 0x40000000..0x7FFFFFFF) */
31965     env->CP0_SegCtl2 =   (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
31966                          (1 << CP0SC_EU) | (2 << CP0SC_C);
31967     /* USeg (seg5 0x00000000..0x3FFFFFFF) */
31968     env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
31969                          (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
31970     /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
31971     env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
31972 #endif
31973     if ((env->insn_flags & ISA_MIPS32R6) &&
31974         (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
31975         /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
31976         env->CP0_Status |= (1 << CP0St_FR);
31977     }
31978 
31979     if (env->insn_flags & ISA_MIPS32R6) {
31980         /* PTW  =  1 */
31981         env->CP0_PWSize = 0x40;
31982         /* GDI  = 12 */
31983         /* UDI  = 12 */
31984         /* MDI  = 12 */
31985         /* PRI  = 12 */
31986         /* PTEI =  2 */
31987         env->CP0_PWField = 0x0C30C302;
31988     } else {
31989         /* GDI  =  0 */
31990         /* UDI  =  0 */
31991         /* MDI  =  0 */
31992         /* PRI  =  0 */
31993         /* PTEI =  2 */
31994         env->CP0_PWField = 0x02;
31995     }
31996 
31997     if (env->CP0_Config3 & (1 << CP0C3_ISA) & (1 << (CP0C3_ISA + 1))) {
31998         /*  microMIPS on reset when Config3.ISA is 3 */
31999         env->hflags |= MIPS_HFLAG_M16;
32000     }
32001 
32002     /* MSA */
32003     if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
32004         msa_reset(env);
32005     }
32006 
32007     compute_hflags(env);
32008     restore_fp_status(env);
32009     restore_pamask(env);
32010     cs->exception_index = EXCP_NONE;
32011 
32012     if (semihosting_get_argc()) {
32013         /* UHI interface can be used to obtain argc and argv */
32014         env->active_tc.gpr[4] = -1;
32015     }
32016 }
32017 
32018 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
32019                           target_ulong *data)
32020 {
32021     env->active_tc.PC = data[0];
32022     env->hflags &= ~MIPS_HFLAG_BMASK;
32023     env->hflags |= data[1];
32024     switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
32025     case MIPS_HFLAG_BR:
32026         break;
32027     case MIPS_HFLAG_BC:
32028     case MIPS_HFLAG_BL:
32029     case MIPS_HFLAG_B:
32030         env->btarget = data[2];
32031         break;
32032     }
32033 }
32034