1 /*
2  *  MIPS32 emulation for qemu: main translation routines.
3  *
4  *  Copyright (c) 2004-2005 Jocelyn Mayer
5  *  Copyright (c) 2006 Marius Groeger (FPU operations)
6  *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7  *  Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
8  *  Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
22  */
23 
24 #include "cpu.h"
25 #include "tcg-op.h"
26 #include "exec/cpu_ldst.h"
27 
28 #include "exec/helper-proto.h"
29 #include "exec/helper-gen.h"
30 
31 #include "exec/gen-icount.h"
32 
33 #define MIPS_DEBUG_DISAS 0
34 //#define MIPS_DEBUG_SIGN_EXTENSIONS
35 
36 /* MIPS major opcodes */
37 #define MASK_OP_MAJOR(op)  (op & (((uint32_t)0x3F) << 26))
38 
39 enum {
40     /* indirect opcode tables */
41     OPC_SPECIAL  = (0x00 << 26),
42     OPC_REGIMM   = (0x01 << 26),
43     OPC_CP0      = (0x10 << 26),
44     OPC_CP1      = (0x11 << 26),
45     OPC_CP2      = (0x12 << 26),
46     OPC_CP3      = (0x13 << 26),
47     OPC_SPECIAL2 = (0x1C << 26),
48     OPC_SPECIAL3 = (0x1F << 26),
49     /* arithmetic with immediate */
50     OPC_ADDI     = (0x08 << 26),
51     OPC_ADDIU    = (0x09 << 26),
52     OPC_SLTI     = (0x0A << 26),
53     OPC_SLTIU    = (0x0B << 26),
54     /* logic with immediate */
55     OPC_ANDI     = (0x0C << 26),
56     OPC_ORI      = (0x0D << 26),
57     OPC_XORI     = (0x0E << 26),
58     OPC_LUI      = (0x0F << 26),
59     /* arithmetic with immediate */
60     OPC_DADDI    = (0x18 << 26),
61     OPC_DADDIU   = (0x19 << 26),
62     /* Jump and branches */
63     OPC_J        = (0x02 << 26),
64     OPC_JAL      = (0x03 << 26),
65     OPC_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
66     OPC_BEQL     = (0x14 << 26),
67     OPC_BNE      = (0x05 << 26),
68     OPC_BNEL     = (0x15 << 26),
69     OPC_BLEZ     = (0x06 << 26),
70     OPC_BLEZL    = (0x16 << 26),
71     OPC_BGTZ     = (0x07 << 26),
72     OPC_BGTZL    = (0x17 << 26),
73     OPC_JALX     = (0x1D << 26),
74     OPC_DAUI     = (0x1D << 26),
75     /* Load and stores */
76     OPC_LDL      = (0x1A << 26),
77     OPC_LDR      = (0x1B << 26),
78     OPC_LB       = (0x20 << 26),
79     OPC_LH       = (0x21 << 26),
80     OPC_LWL      = (0x22 << 26),
81     OPC_LW       = (0x23 << 26),
82     OPC_LWPC     = OPC_LW | 0x5,
83     OPC_LBU      = (0x24 << 26),
84     OPC_LHU      = (0x25 << 26),
85     OPC_LWR      = (0x26 << 26),
86     OPC_LWU      = (0x27 << 26),
87     OPC_SB       = (0x28 << 26),
88     OPC_SH       = (0x29 << 26),
89     OPC_SWL      = (0x2A << 26),
90     OPC_SW       = (0x2B << 26),
91     OPC_SDL      = (0x2C << 26),
92     OPC_SDR      = (0x2D << 26),
93     OPC_SWR      = (0x2E << 26),
94     OPC_LL       = (0x30 << 26),
95     OPC_LLD      = (0x34 << 26),
96     OPC_LD       = (0x37 << 26),
97     OPC_LDPC     = OPC_LD | 0x5,
98     OPC_SC       = (0x38 << 26),
99     OPC_SCD      = (0x3C << 26),
100     OPC_SD       = (0x3F << 26),
101     /* Floating point load/store */
102     OPC_LWC1     = (0x31 << 26),
103     OPC_LWC2     = (0x32 << 26),
104     OPC_LDC1     = (0x35 << 26),
105     OPC_LDC2     = (0x36 << 26),
106     OPC_SWC1     = (0x39 << 26),
107     OPC_SWC2     = (0x3A << 26),
108     OPC_SDC1     = (0x3D << 26),
109     OPC_SDC2     = (0x3E << 26),
110     /* Compact Branches */
111     OPC_BLEZALC  = (0x06 << 26),
112     OPC_BGEZALC  = (0x06 << 26),
113     OPC_BGEUC    = (0x06 << 26),
114     OPC_BGTZALC  = (0x07 << 26),
115     OPC_BLTZALC  = (0x07 << 26),
116     OPC_BLTUC    = (0x07 << 26),
117     OPC_BOVC     = (0x08 << 26),
118     OPC_BEQZALC  = (0x08 << 26),
119     OPC_BEQC     = (0x08 << 26),
120     OPC_BLEZC    = (0x16 << 26),
121     OPC_BGEZC    = (0x16 << 26),
122     OPC_BGEC     = (0x16 << 26),
123     OPC_BGTZC    = (0x17 << 26),
124     OPC_BLTZC    = (0x17 << 26),
125     OPC_BLTC     = (0x17 << 26),
126     OPC_BNVC     = (0x18 << 26),
127     OPC_BNEZALC  = (0x18 << 26),
128     OPC_BNEC     = (0x18 << 26),
129     OPC_BC       = (0x32 << 26),
130     OPC_BEQZC    = (0x36 << 26),
131     OPC_JIC      = (0x36 << 26),
132     OPC_BALC     = (0x3A << 26),
133     OPC_BNEZC    = (0x3E << 26),
134     OPC_JIALC    = (0x3E << 26),
135     /* MDMX ASE specific */
136     OPC_MDMX     = (0x1E << 26),
137     /* MSA ASE, same as MDMX */
138     OPC_MSA      = OPC_MDMX,
139     /* Cache and prefetch */
140     OPC_CACHE    = (0x2F << 26),
141     OPC_PREF     = (0x33 << 26),
142     /* PC-relative address computation / loads */
143     OPC_PCREL    = (0x3B << 26),
144 };
145 
146 /* PC-relative address computation / loads  */
147 #define MASK_OPC_PCREL_TOP2BITS(op)  (MASK_OP_MAJOR(op) | (op & (3 << 19)))
148 #define MASK_OPC_PCREL_TOP5BITS(op)  (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
149 enum {
150     /* Instructions determined by bits 19 and 20 */
151     OPC_ADDIUPC = OPC_PCREL | (0 << 19),
152     R6_OPC_LWPC = OPC_PCREL | (1 << 19),
153     OPC_LWUPC   = OPC_PCREL | (2 << 19),
154 
155     /* Instructions determined by bits 16 ... 20 */
156     OPC_AUIPC   = OPC_PCREL | (0x1e << 16),
157     OPC_ALUIPC  = OPC_PCREL | (0x1f << 16),
158 
159     /* Other */
160     R6_OPC_LDPC = OPC_PCREL | (6 << 18),
161 };
162 
163 /* MIPS special opcodes */
164 #define MASK_SPECIAL(op)   MASK_OP_MAJOR(op) | (op & 0x3F)
165 
166 enum {
167     /* Shifts */
168     OPC_SLL      = 0x00 | OPC_SPECIAL,
169     /* NOP is SLL r0, r0, 0   */
170     /* SSNOP is SLL r0, r0, 1 */
171     /* EHB is SLL r0, r0, 3 */
172     OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
173     OPC_ROTR     = OPC_SRL | (1 << 21),
174     OPC_SRA      = 0x03 | OPC_SPECIAL,
175     OPC_SLLV     = 0x04 | OPC_SPECIAL,
176     OPC_SRLV     = 0x06 | OPC_SPECIAL, /* also ROTRV */
177     OPC_ROTRV    = OPC_SRLV | (1 << 6),
178     OPC_SRAV     = 0x07 | OPC_SPECIAL,
179     OPC_DSLLV    = 0x14 | OPC_SPECIAL,
180     OPC_DSRLV    = 0x16 | OPC_SPECIAL, /* also DROTRV */
181     OPC_DROTRV   = OPC_DSRLV | (1 << 6),
182     OPC_DSRAV    = 0x17 | OPC_SPECIAL,
183     OPC_DSLL     = 0x38 | OPC_SPECIAL,
184     OPC_DSRL     = 0x3A | OPC_SPECIAL, /* also DROTR */
185     OPC_DROTR    = OPC_DSRL | (1 << 21),
186     OPC_DSRA     = 0x3B | OPC_SPECIAL,
187     OPC_DSLL32   = 0x3C | OPC_SPECIAL,
188     OPC_DSRL32   = 0x3E | OPC_SPECIAL, /* also DROTR32 */
189     OPC_DROTR32  = OPC_DSRL32 | (1 << 21),
190     OPC_DSRA32   = 0x3F | OPC_SPECIAL,
191     /* Multiplication / division */
192     OPC_MULT     = 0x18 | OPC_SPECIAL,
193     OPC_MULTU    = 0x19 | OPC_SPECIAL,
194     OPC_DIV      = 0x1A | OPC_SPECIAL,
195     OPC_DIVU     = 0x1B | OPC_SPECIAL,
196     OPC_DMULT    = 0x1C | OPC_SPECIAL,
197     OPC_DMULTU   = 0x1D | OPC_SPECIAL,
198     OPC_DDIV     = 0x1E | OPC_SPECIAL,
199     OPC_DDIVU    = 0x1F | OPC_SPECIAL,
200 
201     /* 2 registers arithmetic / logic */
202     OPC_ADD      = 0x20 | OPC_SPECIAL,
203     OPC_ADDU     = 0x21 | OPC_SPECIAL,
204     OPC_SUB      = 0x22 | OPC_SPECIAL,
205     OPC_SUBU     = 0x23 | OPC_SPECIAL,
206     OPC_AND      = 0x24 | OPC_SPECIAL,
207     OPC_OR       = 0x25 | OPC_SPECIAL,
208     OPC_XOR      = 0x26 | OPC_SPECIAL,
209     OPC_NOR      = 0x27 | OPC_SPECIAL,
210     OPC_SLT      = 0x2A | OPC_SPECIAL,
211     OPC_SLTU     = 0x2B | OPC_SPECIAL,
212     OPC_DADD     = 0x2C | OPC_SPECIAL,
213     OPC_DADDU    = 0x2D | OPC_SPECIAL,
214     OPC_DSUB     = 0x2E | OPC_SPECIAL,
215     OPC_DSUBU    = 0x2F | OPC_SPECIAL,
216     /* Jumps */
217     OPC_JR       = 0x08 | OPC_SPECIAL, /* Also JR.HB */
218     OPC_JALR     = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
219     /* Traps */
220     OPC_TGE      = 0x30 | OPC_SPECIAL,
221     OPC_TGEU     = 0x31 | OPC_SPECIAL,
222     OPC_TLT      = 0x32 | OPC_SPECIAL,
223     OPC_TLTU     = 0x33 | OPC_SPECIAL,
224     OPC_TEQ      = 0x34 | OPC_SPECIAL,
225     OPC_TNE      = 0x36 | OPC_SPECIAL,
226     /* HI / LO registers load & stores */
227     OPC_MFHI     = 0x10 | OPC_SPECIAL,
228     OPC_MTHI     = 0x11 | OPC_SPECIAL,
229     OPC_MFLO     = 0x12 | OPC_SPECIAL,
230     OPC_MTLO     = 0x13 | OPC_SPECIAL,
231     /* Conditional moves */
232     OPC_MOVZ     = 0x0A | OPC_SPECIAL,
233     OPC_MOVN     = 0x0B | OPC_SPECIAL,
234 
235     OPC_SELEQZ   = 0x35 | OPC_SPECIAL,
236     OPC_SELNEZ   = 0x37 | OPC_SPECIAL,
237 
238     OPC_MOVCI    = 0x01 | OPC_SPECIAL,
239 
240     /* Special */
241     OPC_PMON     = 0x05 | OPC_SPECIAL, /* unofficial */
242     OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
243     OPC_BREAK    = 0x0D | OPC_SPECIAL,
244     OPC_SPIM     = 0x0E | OPC_SPECIAL, /* unofficial */
245     OPC_SYNC     = 0x0F | OPC_SPECIAL,
246 
247     OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
248     OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
249     OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
250     OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
251 };
252 
253 /* R6 Multiply and Divide instructions have the same Opcode
254    and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
255 #define MASK_R6_MULDIV(op)   (MASK_SPECIAL(op) | (op & (0x7ff)))
256 
257 enum {
258     R6_OPC_MUL   = OPC_MULT  | (2 << 6),
259     R6_OPC_MUH   = OPC_MULT  | (3 << 6),
260     R6_OPC_MULU  = OPC_MULTU | (2 << 6),
261     R6_OPC_MUHU  = OPC_MULTU | (3 << 6),
262     R6_OPC_DIV   = OPC_DIV   | (2 << 6),
263     R6_OPC_MOD   = OPC_DIV   | (3 << 6),
264     R6_OPC_DIVU  = OPC_DIVU  | (2 << 6),
265     R6_OPC_MODU  = OPC_DIVU  | (3 << 6),
266 
267     R6_OPC_DMUL   = OPC_DMULT  | (2 << 6),
268     R6_OPC_DMUH   = OPC_DMULT  | (3 << 6),
269     R6_OPC_DMULU  = OPC_DMULTU | (2 << 6),
270     R6_OPC_DMUHU  = OPC_DMULTU | (3 << 6),
271     R6_OPC_DDIV   = OPC_DDIV   | (2 << 6),
272     R6_OPC_DMOD   = OPC_DDIV   | (3 << 6),
273     R6_OPC_DDIVU  = OPC_DDIVU  | (2 << 6),
274     R6_OPC_DMODU  = OPC_DDIVU  | (3 << 6),
275 
276     R6_OPC_CLZ      = 0x10 | OPC_SPECIAL,
277     R6_OPC_CLO      = 0x11 | OPC_SPECIAL,
278     R6_OPC_DCLZ     = 0x12 | OPC_SPECIAL,
279     R6_OPC_DCLO     = 0x13 | OPC_SPECIAL,
280     R6_OPC_SDBBP    = 0x0e | OPC_SPECIAL,
281 
282     OPC_LSA  = 0x05 | OPC_SPECIAL,
283     OPC_DLSA = 0x15 | OPC_SPECIAL,
284 };
285 
286 /* Multiplication variants of the vr54xx. */
287 #define MASK_MUL_VR54XX(op)   MASK_SPECIAL(op) | (op & (0x1F << 6))
288 
289 enum {
290     OPC_VR54XX_MULS    = (0x03 << 6) | OPC_MULT,
291     OPC_VR54XX_MULSU   = (0x03 << 6) | OPC_MULTU,
292     OPC_VR54XX_MACC    = (0x05 << 6) | OPC_MULT,
293     OPC_VR54XX_MACCU   = (0x05 << 6) | OPC_MULTU,
294     OPC_VR54XX_MSAC    = (0x07 << 6) | OPC_MULT,
295     OPC_VR54XX_MSACU   = (0x07 << 6) | OPC_MULTU,
296     OPC_VR54XX_MULHI   = (0x09 << 6) | OPC_MULT,
297     OPC_VR54XX_MULHIU  = (0x09 << 6) | OPC_MULTU,
298     OPC_VR54XX_MULSHI  = (0x0B << 6) | OPC_MULT,
299     OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
300     OPC_VR54XX_MACCHI  = (0x0D << 6) | OPC_MULT,
301     OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
302     OPC_VR54XX_MSACHI  = (0x0F << 6) | OPC_MULT,
303     OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
304 };
305 
306 /* REGIMM (rt field) opcodes */
307 #define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
308 
309 enum {
310     OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
311     OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
312     OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
313     OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
314     OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
315     OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
316     OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
317     OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
318     OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
319     OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
320     OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
321     OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
322     OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
323     OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
324     OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
325 
326     OPC_DAHI     = (0x06 << 16) | OPC_REGIMM,
327     OPC_DATI     = (0x1e << 16) | OPC_REGIMM,
328 };
329 
330 /* Special2 opcodes */
331 #define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
332 
333 enum {
334     /* Multiply & xxx operations */
335     OPC_MADD     = 0x00 | OPC_SPECIAL2,
336     OPC_MADDU    = 0x01 | OPC_SPECIAL2,
337     OPC_MUL      = 0x02 | OPC_SPECIAL2,
338     OPC_MSUB     = 0x04 | OPC_SPECIAL2,
339     OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
340     /* Loongson 2F */
341     OPC_MULT_G_2F   = 0x10 | OPC_SPECIAL2,
342     OPC_DMULT_G_2F  = 0x11 | OPC_SPECIAL2,
343     OPC_MULTU_G_2F  = 0x12 | OPC_SPECIAL2,
344     OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
345     OPC_DIV_G_2F    = 0x14 | OPC_SPECIAL2,
346     OPC_DDIV_G_2F   = 0x15 | OPC_SPECIAL2,
347     OPC_DIVU_G_2F   = 0x16 | OPC_SPECIAL2,
348     OPC_DDIVU_G_2F  = 0x17 | OPC_SPECIAL2,
349     OPC_MOD_G_2F    = 0x1c | OPC_SPECIAL2,
350     OPC_DMOD_G_2F   = 0x1d | OPC_SPECIAL2,
351     OPC_MODU_G_2F   = 0x1e | OPC_SPECIAL2,
352     OPC_DMODU_G_2F  = 0x1f | OPC_SPECIAL2,
353     /* Misc */
354     OPC_CLZ      = 0x20 | OPC_SPECIAL2,
355     OPC_CLO      = 0x21 | OPC_SPECIAL2,
356     OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
357     OPC_DCLO     = 0x25 | OPC_SPECIAL2,
358     /* Special */
359     OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
360 };
361 
362 /* Special3 opcodes */
363 #define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
364 
365 enum {
366     OPC_EXT      = 0x00 | OPC_SPECIAL3,
367     OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
368     OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
369     OPC_DEXT     = 0x03 | OPC_SPECIAL3,
370     OPC_INS      = 0x04 | OPC_SPECIAL3,
371     OPC_DINSM    = 0x05 | OPC_SPECIAL3,
372     OPC_DINSU    = 0x06 | OPC_SPECIAL3,
373     OPC_DINS     = 0x07 | OPC_SPECIAL3,
374     OPC_FORK     = 0x08 | OPC_SPECIAL3,
375     OPC_YIELD    = 0x09 | OPC_SPECIAL3,
376     OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
377     OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
378     OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
379 
380     /* Loongson 2E */
381     OPC_MULT_G_2E   = 0x18 | OPC_SPECIAL3,
382     OPC_MULTU_G_2E  = 0x19 | OPC_SPECIAL3,
383     OPC_DIV_G_2E    = 0x1A | OPC_SPECIAL3,
384     OPC_DIVU_G_2E   = 0x1B | OPC_SPECIAL3,
385     OPC_DMULT_G_2E  = 0x1C | OPC_SPECIAL3,
386     OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
387     OPC_DDIV_G_2E   = 0x1E | OPC_SPECIAL3,
388     OPC_DDIVU_G_2E  = 0x1F | OPC_SPECIAL3,
389     OPC_MOD_G_2E    = 0x22 | OPC_SPECIAL3,
390     OPC_MODU_G_2E   = 0x23 | OPC_SPECIAL3,
391     OPC_DMOD_G_2E   = 0x26 | OPC_SPECIAL3,
392     OPC_DMODU_G_2E  = 0x27 | OPC_SPECIAL3,
393 
394     /* MIPS DSP Load */
395     OPC_LX_DSP         = 0x0A | OPC_SPECIAL3,
396     /* MIPS DSP Arithmetic */
397     OPC_ADDU_QB_DSP    = 0x10 | OPC_SPECIAL3,
398     OPC_ADDU_OB_DSP    = 0x14 | OPC_SPECIAL3,
399     OPC_ABSQ_S_PH_DSP  = 0x12 | OPC_SPECIAL3,
400     OPC_ABSQ_S_QH_DSP  = 0x16 | OPC_SPECIAL3,
401     /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E.  */
402     /* OPC_ADDUH_QB_DSP   = 0x18 | OPC_SPECIAL3,  */
403     OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
404     OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
405     /* MIPS DSP GPR-Based Shift Sub-class */
406     OPC_SHLL_QB_DSP    = 0x13 | OPC_SPECIAL3,
407     OPC_SHLL_OB_DSP    = 0x17 | OPC_SPECIAL3,
408     /* MIPS DSP Multiply Sub-class insns */
409     /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP.  */
410     /* OPC_MUL_PH_DSP     = 0x18 | OPC_SPECIAL3,  */
411     OPC_DPA_W_PH_DSP   = 0x30 | OPC_SPECIAL3,
412     OPC_DPAQ_W_QH_DSP  = 0x34 | OPC_SPECIAL3,
413     /* DSP Bit/Manipulation Sub-class */
414     OPC_INSV_DSP       = 0x0C | OPC_SPECIAL3,
415     OPC_DINSV_DSP      = 0x0D | OPC_SPECIAL3,
416     /* MIPS DSP Append Sub-class */
417     OPC_APPEND_DSP     = 0x31 | OPC_SPECIAL3,
418     OPC_DAPPEND_DSP    = 0x35 | OPC_SPECIAL3,
419     /* MIPS DSP Accumulator and DSPControl Access Sub-class */
420     OPC_EXTR_W_DSP     = 0x38 | OPC_SPECIAL3,
421     OPC_DEXTR_W_DSP    = 0x3C | OPC_SPECIAL3,
422 
423     /* R6 */
424     R6_OPC_PREF        = 0x35 | OPC_SPECIAL3,
425     R6_OPC_CACHE       = 0x25 | OPC_SPECIAL3,
426     R6_OPC_LL          = 0x36 | OPC_SPECIAL3,
427     R6_OPC_SC          = 0x26 | OPC_SPECIAL3,
428     R6_OPC_LLD         = 0x37 | OPC_SPECIAL3,
429     R6_OPC_SCD         = 0x27 | OPC_SPECIAL3,
430 };
431 
432 /* BSHFL opcodes */
433 #define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
434 
435 enum {
436     OPC_WSBH      = (0x02 << 6) | OPC_BSHFL,
437     OPC_SEB       = (0x10 << 6) | OPC_BSHFL,
438     OPC_SEH       = (0x18 << 6) | OPC_BSHFL,
439     OPC_ALIGN     = (0x08 << 6) | OPC_BSHFL, /* 010.bp */
440     OPC_ALIGN_END = (0x0B << 6) | OPC_BSHFL, /* 010.00 to 010.11 */
441     OPC_BITSWAP   = (0x00 << 6) | OPC_BSHFL  /* 00000 */
442 };
443 
444 /* DBSHFL opcodes */
445 #define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
446 
447 enum {
448     OPC_DSBH       = (0x02 << 6) | OPC_DBSHFL,
449     OPC_DSHD       = (0x05 << 6) | OPC_DBSHFL,
450     OPC_DALIGN     = (0x08 << 6) | OPC_DBSHFL, /* 01.bp */
451     OPC_DALIGN_END = (0x0F << 6) | OPC_DBSHFL, /* 01.000 to 01.111 */
452     OPC_DBITSWAP   = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
453 };
454 
455 /* MIPS DSP REGIMM opcodes */
456 enum {
457     OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
458     OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
459 };
460 
461 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
462 /* MIPS DSP Load */
463 enum {
464     OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
465     OPC_LHX  = (0x04 << 6) | OPC_LX_DSP,
466     OPC_LWX  = (0x00 << 6) | OPC_LX_DSP,
467     OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
468 };
469 
470 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
471 enum {
472     /* MIPS DSP Arithmetic Sub-class */
473     OPC_ADDQ_PH        = (0x0A << 6) | OPC_ADDU_QB_DSP,
474     OPC_ADDQ_S_PH      = (0x0E << 6) | OPC_ADDU_QB_DSP,
475     OPC_ADDQ_S_W       = (0x16 << 6) | OPC_ADDU_QB_DSP,
476     OPC_ADDU_QB        = (0x00 << 6) | OPC_ADDU_QB_DSP,
477     OPC_ADDU_S_QB      = (0x04 << 6) | OPC_ADDU_QB_DSP,
478     OPC_ADDU_PH        = (0x08 << 6) | OPC_ADDU_QB_DSP,
479     OPC_ADDU_S_PH      = (0x0C << 6) | OPC_ADDU_QB_DSP,
480     OPC_SUBQ_PH        = (0x0B << 6) | OPC_ADDU_QB_DSP,
481     OPC_SUBQ_S_PH      = (0x0F << 6) | OPC_ADDU_QB_DSP,
482     OPC_SUBQ_S_W       = (0x17 << 6) | OPC_ADDU_QB_DSP,
483     OPC_SUBU_QB        = (0x01 << 6) | OPC_ADDU_QB_DSP,
484     OPC_SUBU_S_QB      = (0x05 << 6) | OPC_ADDU_QB_DSP,
485     OPC_SUBU_PH        = (0x09 << 6) | OPC_ADDU_QB_DSP,
486     OPC_SUBU_S_PH      = (0x0D << 6) | OPC_ADDU_QB_DSP,
487     OPC_ADDSC          = (0x10 << 6) | OPC_ADDU_QB_DSP,
488     OPC_ADDWC          = (0x11 << 6) | OPC_ADDU_QB_DSP,
489     OPC_MODSUB         = (0x12 << 6) | OPC_ADDU_QB_DSP,
490     OPC_RADDU_W_QB     = (0x14 << 6) | OPC_ADDU_QB_DSP,
491     /* MIPS DSP Multiply Sub-class insns */
492     OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
493     OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
494     OPC_MULQ_RS_PH     = (0x1F << 6) | OPC_ADDU_QB_DSP,
495     OPC_MULEQ_S_W_PHL  = (0x1C << 6) | OPC_ADDU_QB_DSP,
496     OPC_MULEQ_S_W_PHR  = (0x1D << 6) | OPC_ADDU_QB_DSP,
497     OPC_MULQ_S_PH      = (0x1E << 6) | OPC_ADDU_QB_DSP,
498 };
499 
500 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
501 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
502 enum {
503     /* MIPS DSP Arithmetic Sub-class */
504     OPC_ADDUH_QB   = (0x00 << 6) | OPC_ADDUH_QB_DSP,
505     OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
506     OPC_ADDQH_PH   = (0x08 << 6) | OPC_ADDUH_QB_DSP,
507     OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
508     OPC_ADDQH_W    = (0x10 << 6) | OPC_ADDUH_QB_DSP,
509     OPC_ADDQH_R_W  = (0x12 << 6) | OPC_ADDUH_QB_DSP,
510     OPC_SUBUH_QB   = (0x01 << 6) | OPC_ADDUH_QB_DSP,
511     OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
512     OPC_SUBQH_PH   = (0x09 << 6) | OPC_ADDUH_QB_DSP,
513     OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
514     OPC_SUBQH_W    = (0x11 << 6) | OPC_ADDUH_QB_DSP,
515     OPC_SUBQH_R_W  = (0x13 << 6) | OPC_ADDUH_QB_DSP,
516     /* MIPS DSP Multiply Sub-class insns */
517     OPC_MUL_PH     = (0x0C << 6) | OPC_ADDUH_QB_DSP,
518     OPC_MUL_S_PH   = (0x0E << 6) | OPC_ADDUH_QB_DSP,
519     OPC_MULQ_S_W   = (0x16 << 6) | OPC_ADDUH_QB_DSP,
520     OPC_MULQ_RS_W  = (0x17 << 6) | OPC_ADDUH_QB_DSP,
521 };
522 
523 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
524 enum {
525     /* MIPS DSP Arithmetic Sub-class */
526     OPC_ABSQ_S_QB       = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
527     OPC_ABSQ_S_PH       = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
528     OPC_ABSQ_S_W        = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
529     OPC_PRECEQ_W_PHL    = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
530     OPC_PRECEQ_W_PHR    = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
531     OPC_PRECEQU_PH_QBL  = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
532     OPC_PRECEQU_PH_QBR  = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
533     OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
534     OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
535     OPC_PRECEU_PH_QBL   = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
536     OPC_PRECEU_PH_QBR   = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
537     OPC_PRECEU_PH_QBLA  = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
538     OPC_PRECEU_PH_QBRA  = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
539     /* DSP Bit/Manipulation Sub-class */
540     OPC_BITREV          = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
541     OPC_REPL_QB         = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
542     OPC_REPLV_QB        = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
543     OPC_REPL_PH         = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
544     OPC_REPLV_PH        = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
545 };
546 
547 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
548 enum {
549     /* MIPS DSP Arithmetic Sub-class */
550     OPC_PRECR_QB_PH      = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
551     OPC_PRECRQ_QB_PH     = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
552     OPC_PRECR_SRA_PH_W   = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
553     OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
554     OPC_PRECRQ_PH_W      = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
555     OPC_PRECRQ_RS_PH_W   = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
556     OPC_PRECRQU_S_QB_PH  = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
557     /* DSP Compare-Pick Sub-class */
558     OPC_CMPU_EQ_QB       = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
559     OPC_CMPU_LT_QB       = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
560     OPC_CMPU_LE_QB       = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
561     OPC_CMPGU_EQ_QB      = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
562     OPC_CMPGU_LT_QB      = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
563     OPC_CMPGU_LE_QB      = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
564     OPC_CMPGDU_EQ_QB     = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
565     OPC_CMPGDU_LT_QB     = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
566     OPC_CMPGDU_LE_QB     = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
567     OPC_CMP_EQ_PH        = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
568     OPC_CMP_LT_PH        = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
569     OPC_CMP_LE_PH        = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
570     OPC_PICK_QB          = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
571     OPC_PICK_PH          = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
572     OPC_PACKRL_PH        = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
573 };
574 
575 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
576 enum {
577     /* MIPS DSP GPR-Based Shift Sub-class */
578     OPC_SHLL_QB    = (0x00 << 6) | OPC_SHLL_QB_DSP,
579     OPC_SHLLV_QB   = (0x02 << 6) | OPC_SHLL_QB_DSP,
580     OPC_SHLL_PH    = (0x08 << 6) | OPC_SHLL_QB_DSP,
581     OPC_SHLLV_PH   = (0x0A << 6) | OPC_SHLL_QB_DSP,
582     OPC_SHLL_S_PH  = (0x0C << 6) | OPC_SHLL_QB_DSP,
583     OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
584     OPC_SHLL_S_W   = (0x14 << 6) | OPC_SHLL_QB_DSP,
585     OPC_SHLLV_S_W  = (0x16 << 6) | OPC_SHLL_QB_DSP,
586     OPC_SHRL_QB    = (0x01 << 6) | OPC_SHLL_QB_DSP,
587     OPC_SHRLV_QB   = (0x03 << 6) | OPC_SHLL_QB_DSP,
588     OPC_SHRL_PH    = (0x19 << 6) | OPC_SHLL_QB_DSP,
589     OPC_SHRLV_PH   = (0x1B << 6) | OPC_SHLL_QB_DSP,
590     OPC_SHRA_QB    = (0x04 << 6) | OPC_SHLL_QB_DSP,
591     OPC_SHRA_R_QB  = (0x05 << 6) | OPC_SHLL_QB_DSP,
592     OPC_SHRAV_QB   = (0x06 << 6) | OPC_SHLL_QB_DSP,
593     OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
594     OPC_SHRA_PH    = (0x09 << 6) | OPC_SHLL_QB_DSP,
595     OPC_SHRAV_PH   = (0x0B << 6) | OPC_SHLL_QB_DSP,
596     OPC_SHRA_R_PH  = (0x0D << 6) | OPC_SHLL_QB_DSP,
597     OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
598     OPC_SHRA_R_W   = (0x15 << 6) | OPC_SHLL_QB_DSP,
599     OPC_SHRAV_R_W  = (0x17 << 6) | OPC_SHLL_QB_DSP,
600 };
601 
602 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
603 enum {
604     /* MIPS DSP Multiply Sub-class insns */
605     OPC_DPAU_H_QBL    = (0x03 << 6) | OPC_DPA_W_PH_DSP,
606     OPC_DPAU_H_QBR    = (0x07 << 6) | OPC_DPA_W_PH_DSP,
607     OPC_DPSU_H_QBL    = (0x0B << 6) | OPC_DPA_W_PH_DSP,
608     OPC_DPSU_H_QBR    = (0x0F << 6) | OPC_DPA_W_PH_DSP,
609     OPC_DPA_W_PH      = (0x00 << 6) | OPC_DPA_W_PH_DSP,
610     OPC_DPAX_W_PH     = (0x08 << 6) | OPC_DPA_W_PH_DSP,
611     OPC_DPAQ_S_W_PH   = (0x04 << 6) | OPC_DPA_W_PH_DSP,
612     OPC_DPAQX_S_W_PH  = (0x18 << 6) | OPC_DPA_W_PH_DSP,
613     OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
614     OPC_DPS_W_PH      = (0x01 << 6) | OPC_DPA_W_PH_DSP,
615     OPC_DPSX_W_PH     = (0x09 << 6) | OPC_DPA_W_PH_DSP,
616     OPC_DPSQ_S_W_PH   = (0x05 << 6) | OPC_DPA_W_PH_DSP,
617     OPC_DPSQX_S_W_PH  = (0x19 << 6) | OPC_DPA_W_PH_DSP,
618     OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
619     OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
620     OPC_DPAQ_SA_L_W   = (0x0C << 6) | OPC_DPA_W_PH_DSP,
621     OPC_DPSQ_SA_L_W   = (0x0D << 6) | OPC_DPA_W_PH_DSP,
622     OPC_MAQ_S_W_PHL   = (0x14 << 6) | OPC_DPA_W_PH_DSP,
623     OPC_MAQ_S_W_PHR   = (0x16 << 6) | OPC_DPA_W_PH_DSP,
624     OPC_MAQ_SA_W_PHL  = (0x10 << 6) | OPC_DPA_W_PH_DSP,
625     OPC_MAQ_SA_W_PHR  = (0x12 << 6) | OPC_DPA_W_PH_DSP,
626     OPC_MULSA_W_PH    = (0x02 << 6) | OPC_DPA_W_PH_DSP,
627 };
628 
629 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
630 enum {
631     /* DSP Bit/Manipulation Sub-class */
632     OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
633 };
634 
635 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
636 enum {
637     /* MIPS DSP Append Sub-class */
638     OPC_APPEND  = (0x00 << 6) | OPC_APPEND_DSP,
639     OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
640     OPC_BALIGN  = (0x10 << 6) | OPC_APPEND_DSP,
641 };
642 
643 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
644 enum {
645     /* MIPS DSP Accumulator and DSPControl Access Sub-class */
646     OPC_EXTR_W     = (0x00 << 6) | OPC_EXTR_W_DSP,
647     OPC_EXTR_R_W   = (0x04 << 6) | OPC_EXTR_W_DSP,
648     OPC_EXTR_RS_W  = (0x06 << 6) | OPC_EXTR_W_DSP,
649     OPC_EXTR_S_H   = (0x0E << 6) | OPC_EXTR_W_DSP,
650     OPC_EXTRV_S_H  = (0x0F << 6) | OPC_EXTR_W_DSP,
651     OPC_EXTRV_W    = (0x01 << 6) | OPC_EXTR_W_DSP,
652     OPC_EXTRV_R_W  = (0x05 << 6) | OPC_EXTR_W_DSP,
653     OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
654     OPC_EXTP       = (0x02 << 6) | OPC_EXTR_W_DSP,
655     OPC_EXTPV      = (0x03 << 6) | OPC_EXTR_W_DSP,
656     OPC_EXTPDP     = (0x0A << 6) | OPC_EXTR_W_DSP,
657     OPC_EXTPDPV    = (0x0B << 6) | OPC_EXTR_W_DSP,
658     OPC_SHILO      = (0x1A << 6) | OPC_EXTR_W_DSP,
659     OPC_SHILOV     = (0x1B << 6) | OPC_EXTR_W_DSP,
660     OPC_MTHLIP     = (0x1F << 6) | OPC_EXTR_W_DSP,
661     OPC_WRDSP      = (0x13 << 6) | OPC_EXTR_W_DSP,
662     OPC_RDDSP      = (0x12 << 6) | OPC_EXTR_W_DSP,
663 };
664 
665 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
666 enum {
667     /* MIPS DSP Arithmetic Sub-class */
668     OPC_PRECEQ_L_PWL    = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
669     OPC_PRECEQ_L_PWR    = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
670     OPC_PRECEQ_PW_QHL   = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
671     OPC_PRECEQ_PW_QHR   = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
672     OPC_PRECEQ_PW_QHLA  = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
673     OPC_PRECEQ_PW_QHRA  = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
674     OPC_PRECEQU_QH_OBL  = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
675     OPC_PRECEQU_QH_OBR  = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
676     OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
677     OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
678     OPC_PRECEU_QH_OBL   = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
679     OPC_PRECEU_QH_OBR   = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
680     OPC_PRECEU_QH_OBLA  = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
681     OPC_PRECEU_QH_OBRA  = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
682     OPC_ABSQ_S_OB       = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
683     OPC_ABSQ_S_PW       = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
684     OPC_ABSQ_S_QH       = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
685     /* DSP Bit/Manipulation Sub-class */
686     OPC_REPL_OB         = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
687     OPC_REPL_PW         = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
688     OPC_REPL_QH         = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
689     OPC_REPLV_OB        = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
690     OPC_REPLV_PW        = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
691     OPC_REPLV_QH        = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
692 };
693 
694 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
695 enum {
696     /* MIPS DSP Multiply Sub-class insns */
697     OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
698     OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
699     OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
700     OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
701     OPC_MULQ_RS_QH     = (0x1F << 6) | OPC_ADDU_OB_DSP,
702     /* MIPS DSP Arithmetic Sub-class */
703     OPC_RADDU_L_OB     = (0x14 << 6) | OPC_ADDU_OB_DSP,
704     OPC_SUBQ_PW        = (0x13 << 6) | OPC_ADDU_OB_DSP,
705     OPC_SUBQ_S_PW      = (0x17 << 6) | OPC_ADDU_OB_DSP,
706     OPC_SUBQ_QH        = (0x0B << 6) | OPC_ADDU_OB_DSP,
707     OPC_SUBQ_S_QH      = (0x0F << 6) | OPC_ADDU_OB_DSP,
708     OPC_SUBU_OB        = (0x01 << 6) | OPC_ADDU_OB_DSP,
709     OPC_SUBU_S_OB      = (0x05 << 6) | OPC_ADDU_OB_DSP,
710     OPC_SUBU_QH        = (0x09 << 6) | OPC_ADDU_OB_DSP,
711     OPC_SUBU_S_QH      = (0x0D << 6) | OPC_ADDU_OB_DSP,
712     OPC_SUBUH_OB       = (0x19 << 6) | OPC_ADDU_OB_DSP,
713     OPC_SUBUH_R_OB     = (0x1B << 6) | OPC_ADDU_OB_DSP,
714     OPC_ADDQ_PW        = (0x12 << 6) | OPC_ADDU_OB_DSP,
715     OPC_ADDQ_S_PW      = (0x16 << 6) | OPC_ADDU_OB_DSP,
716     OPC_ADDQ_QH        = (0x0A << 6) | OPC_ADDU_OB_DSP,
717     OPC_ADDQ_S_QH      = (0x0E << 6) | OPC_ADDU_OB_DSP,
718     OPC_ADDU_OB        = (0x00 << 6) | OPC_ADDU_OB_DSP,
719     OPC_ADDU_S_OB      = (0x04 << 6) | OPC_ADDU_OB_DSP,
720     OPC_ADDU_QH        = (0x08 << 6) | OPC_ADDU_OB_DSP,
721     OPC_ADDU_S_QH      = (0x0C << 6) | OPC_ADDU_OB_DSP,
722     OPC_ADDUH_OB       = (0x18 << 6) | OPC_ADDU_OB_DSP,
723     OPC_ADDUH_R_OB     = (0x1A << 6) | OPC_ADDU_OB_DSP,
724 };
725 
726 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
727 enum {
728     /* DSP Compare-Pick Sub-class */
729     OPC_CMP_EQ_PW         = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
730     OPC_CMP_LT_PW         = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
731     OPC_CMP_LE_PW         = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
732     OPC_CMP_EQ_QH         = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
733     OPC_CMP_LT_QH         = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
734     OPC_CMP_LE_QH         = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
735     OPC_CMPGDU_EQ_OB      = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
736     OPC_CMPGDU_LT_OB      = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
737     OPC_CMPGDU_LE_OB      = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
738     OPC_CMPGU_EQ_OB       = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
739     OPC_CMPGU_LT_OB       = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
740     OPC_CMPGU_LE_OB       = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
741     OPC_CMPU_EQ_OB        = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
742     OPC_CMPU_LT_OB        = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
743     OPC_CMPU_LE_OB        = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
744     OPC_PACKRL_PW         = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
745     OPC_PICK_OB           = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
746     OPC_PICK_PW           = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
747     OPC_PICK_QH           = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
748     /* MIPS DSP Arithmetic Sub-class */
749     OPC_PRECR_OB_QH       = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
750     OPC_PRECR_SRA_QH_PW   = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
751     OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
752     OPC_PRECRQ_OB_QH      = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
753     OPC_PRECRQ_PW_L       = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
754     OPC_PRECRQ_QH_PW      = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
755     OPC_PRECRQ_RS_QH_PW   = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
756     OPC_PRECRQU_S_OB_QH   = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
757 };
758 
759 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
760 enum {
761     /* DSP Append Sub-class */
762     OPC_DAPPEND  = (0x00 << 6) | OPC_DAPPEND_DSP,
763     OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
764     OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
765     OPC_DBALIGN  = (0x10 << 6) | OPC_DAPPEND_DSP,
766 };
767 
768 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
769 enum {
770     /* MIPS DSP Accumulator and DSPControl Access Sub-class */
771     OPC_DMTHLIP     = (0x1F << 6) | OPC_DEXTR_W_DSP,
772     OPC_DSHILO      = (0x1A << 6) | OPC_DEXTR_W_DSP,
773     OPC_DEXTP       = (0x02 << 6) | OPC_DEXTR_W_DSP,
774     OPC_DEXTPDP     = (0x0A << 6) | OPC_DEXTR_W_DSP,
775     OPC_DEXTPDPV    = (0x0B << 6) | OPC_DEXTR_W_DSP,
776     OPC_DEXTPV      = (0x03 << 6) | OPC_DEXTR_W_DSP,
777     OPC_DEXTR_L     = (0x10 << 6) | OPC_DEXTR_W_DSP,
778     OPC_DEXTR_R_L   = (0x14 << 6) | OPC_DEXTR_W_DSP,
779     OPC_DEXTR_RS_L  = (0x16 << 6) | OPC_DEXTR_W_DSP,
780     OPC_DEXTR_W     = (0x00 << 6) | OPC_DEXTR_W_DSP,
781     OPC_DEXTR_R_W   = (0x04 << 6) | OPC_DEXTR_W_DSP,
782     OPC_DEXTR_RS_W  = (0x06 << 6) | OPC_DEXTR_W_DSP,
783     OPC_DEXTR_S_H   = (0x0E << 6) | OPC_DEXTR_W_DSP,
784     OPC_DEXTRV_L    = (0x11 << 6) | OPC_DEXTR_W_DSP,
785     OPC_DEXTRV_R_L  = (0x15 << 6) | OPC_DEXTR_W_DSP,
786     OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
787     OPC_DEXTRV_S_H  = (0x0F << 6) | OPC_DEXTR_W_DSP,
788     OPC_DEXTRV_W    = (0x01 << 6) | OPC_DEXTR_W_DSP,
789     OPC_DEXTRV_R_W  = (0x05 << 6) | OPC_DEXTR_W_DSP,
790     OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
791     OPC_DSHILOV     = (0x1B << 6) | OPC_DEXTR_W_DSP,
792 };
793 
794 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
795 enum {
796     /* DSP Bit/Manipulation Sub-class */
797     OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
798 };
799 
800 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
801 enum {
802     /* MIPS DSP Multiply Sub-class insns */
803     OPC_DMADD         = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
804     OPC_DMADDU        = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
805     OPC_DMSUB         = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
806     OPC_DMSUBU        = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
807     OPC_DPA_W_QH      = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
808     OPC_DPAQ_S_W_QH   = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
809     OPC_DPAQ_SA_L_PW  = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
810     OPC_DPAU_H_OBL    = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
811     OPC_DPAU_H_OBR    = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
812     OPC_DPS_W_QH      = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
813     OPC_DPSQ_S_W_QH   = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
814     OPC_DPSQ_SA_L_PW  = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
815     OPC_DPSU_H_OBL    = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
816     OPC_DPSU_H_OBR    = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
817     OPC_MAQ_S_L_PWL   = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
818     OPC_MAQ_S_L_PWR   = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
819     OPC_MAQ_S_W_QHLL  = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
820     OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
821     OPC_MAQ_S_W_QHLR  = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
822     OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
823     OPC_MAQ_S_W_QHRL  = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
824     OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
825     OPC_MAQ_S_W_QHRR  = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
826     OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
827     OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
828     OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
829 };
830 
831 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
832 enum {
833     /* MIPS DSP GPR-Based Shift Sub-class */
834     OPC_SHLL_PW    = (0x10 << 6) | OPC_SHLL_OB_DSP,
835     OPC_SHLL_S_PW  = (0x14 << 6) | OPC_SHLL_OB_DSP,
836     OPC_SHLLV_OB   = (0x02 << 6) | OPC_SHLL_OB_DSP,
837     OPC_SHLLV_PW   = (0x12 << 6) | OPC_SHLL_OB_DSP,
838     OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
839     OPC_SHLLV_QH   = (0x0A << 6) | OPC_SHLL_OB_DSP,
840     OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
841     OPC_SHRA_PW    = (0x11 << 6) | OPC_SHLL_OB_DSP,
842     OPC_SHRA_R_PW  = (0x15 << 6) | OPC_SHLL_OB_DSP,
843     OPC_SHRAV_OB   = (0x06 << 6) | OPC_SHLL_OB_DSP,
844     OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
845     OPC_SHRAV_PW   = (0x13 << 6) | OPC_SHLL_OB_DSP,
846     OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
847     OPC_SHRAV_QH   = (0x0B << 6) | OPC_SHLL_OB_DSP,
848     OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
849     OPC_SHRLV_OB   = (0x03 << 6) | OPC_SHLL_OB_DSP,
850     OPC_SHRLV_QH   = (0x1B << 6) | OPC_SHLL_OB_DSP,
851     OPC_SHLL_OB    = (0x00 << 6) | OPC_SHLL_OB_DSP,
852     OPC_SHLL_QH    = (0x08 << 6) | OPC_SHLL_OB_DSP,
853     OPC_SHLL_S_QH  = (0x0C << 6) | OPC_SHLL_OB_DSP,
854     OPC_SHRA_OB    = (0x04 << 6) | OPC_SHLL_OB_DSP,
855     OPC_SHRA_R_OB  = (0x05 << 6) | OPC_SHLL_OB_DSP,
856     OPC_SHRA_QH    = (0x09 << 6) | OPC_SHLL_OB_DSP,
857     OPC_SHRA_R_QH  = (0x0D << 6) | OPC_SHLL_OB_DSP,
858     OPC_SHRL_OB    = (0x01 << 6) | OPC_SHLL_OB_DSP,
859     OPC_SHRL_QH    = (0x19 << 6) | OPC_SHLL_OB_DSP,
860 };
861 
862 /* Coprocessor 0 (rs field) */
863 #define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
864 
865 enum {
866     OPC_MFC0     = (0x00 << 21) | OPC_CP0,
867     OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
868     OPC_MTC0     = (0x04 << 21) | OPC_CP0,
869     OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
870     OPC_MFTR     = (0x08 << 21) | OPC_CP0,
871     OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
872     OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
873     OPC_MTTR     = (0x0C << 21) | OPC_CP0,
874     OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
875     OPC_C0       = (0x10 << 21) | OPC_CP0,
876     OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
877     OPC_C0_LAST  = (0x1F << 21) | OPC_CP0,
878 };
879 
880 /* MFMC0 opcodes */
881 #define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
882 
883 enum {
884     OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
885     OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
886     OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
887     OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
888     OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
889     OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
890 };
891 
892 /* Coprocessor 0 (with rs == C0) */
893 #define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
894 
895 enum {
896     OPC_TLBR     = 0x01 | OPC_C0,
897     OPC_TLBWI    = 0x02 | OPC_C0,
898     OPC_TLBINV   = 0x03 | OPC_C0,
899     OPC_TLBINVF  = 0x04 | OPC_C0,
900     OPC_TLBWR    = 0x06 | OPC_C0,
901     OPC_TLBP     = 0x08 | OPC_C0,
902     OPC_RFE      = 0x10 | OPC_C0,
903     OPC_ERET     = 0x18 | OPC_C0,
904     OPC_DERET    = 0x1F | OPC_C0,
905     OPC_WAIT     = 0x20 | OPC_C0,
906 };
907 
908 /* Coprocessor 1 (rs field) */
909 #define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
910 
911 /* Values for the fmt field in FP instructions */
912 enum {
913     /* 0 - 15 are reserved */
914     FMT_S = 16,          /* single fp */
915     FMT_D = 17,          /* double fp */
916     FMT_E = 18,          /* extended fp */
917     FMT_Q = 19,          /* quad fp */
918     FMT_W = 20,          /* 32-bit fixed */
919     FMT_L = 21,          /* 64-bit fixed */
920     FMT_PS = 22,         /* paired single fp */
921     /* 23 - 31 are reserved */
922 };
923 
924 enum {
925     OPC_MFC1     = (0x00 << 21) | OPC_CP1,
926     OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
927     OPC_CFC1     = (0x02 << 21) | OPC_CP1,
928     OPC_MFHC1    = (0x03 << 21) | OPC_CP1,
929     OPC_MTC1     = (0x04 << 21) | OPC_CP1,
930     OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
931     OPC_CTC1     = (0x06 << 21) | OPC_CP1,
932     OPC_MTHC1    = (0x07 << 21) | OPC_CP1,
933     OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
934     OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
935     OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
936     OPC_BZ_V     = (0x0B << 21) | OPC_CP1,
937     OPC_BNZ_V    = (0x0F << 21) | OPC_CP1,
938     OPC_S_FMT    = (FMT_S << 21) | OPC_CP1,
939     OPC_D_FMT    = (FMT_D << 21) | OPC_CP1,
940     OPC_E_FMT    = (FMT_E << 21) | OPC_CP1,
941     OPC_Q_FMT    = (FMT_Q << 21) | OPC_CP1,
942     OPC_W_FMT    = (FMT_W << 21) | OPC_CP1,
943     OPC_L_FMT    = (FMT_L << 21) | OPC_CP1,
944     OPC_PS_FMT   = (FMT_PS << 21) | OPC_CP1,
945     OPC_BC1EQZ   = (0x09 << 21) | OPC_CP1,
946     OPC_BC1NEZ   = (0x0D << 21) | OPC_CP1,
947     OPC_BZ_B     = (0x18 << 21) | OPC_CP1,
948     OPC_BZ_H     = (0x19 << 21) | OPC_CP1,
949     OPC_BZ_W     = (0x1A << 21) | OPC_CP1,
950     OPC_BZ_D     = (0x1B << 21) | OPC_CP1,
951     OPC_BNZ_B    = (0x1C << 21) | OPC_CP1,
952     OPC_BNZ_H    = (0x1D << 21) | OPC_CP1,
953     OPC_BNZ_W    = (0x1E << 21) | OPC_CP1,
954     OPC_BNZ_D    = (0x1F << 21) | OPC_CP1,
955 };
956 
957 #define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
958 #define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
959 
960 enum {
961     OPC_BC1F     = (0x00 << 16) | OPC_BC1,
962     OPC_BC1T     = (0x01 << 16) | OPC_BC1,
963     OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
964     OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
965 };
966 
967 enum {
968     OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
969     OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
970 };
971 
972 enum {
973     OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
974     OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
975 };
976 
977 #define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
978 
979 enum {
980     OPC_MFC2    = (0x00 << 21) | OPC_CP2,
981     OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
982     OPC_CFC2    = (0x02 << 21) | OPC_CP2,
983     OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
984     OPC_MTC2    = (0x04 << 21) | OPC_CP2,
985     OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
986     OPC_CTC2    = (0x06 << 21) | OPC_CP2,
987     OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
988     OPC_BC2     = (0x08 << 21) | OPC_CP2,
989     OPC_BC2EQZ  = (0x09 << 21) | OPC_CP2,
990     OPC_BC2NEZ  = (0x0D << 21) | OPC_CP2,
991 };
992 
993 #define MASK_LMI(op)  (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
994 
995 enum {
996     OPC_PADDSH  = (24 << 21) | (0x00) | OPC_CP2,
997     OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
998     OPC_PADDH   = (26 << 21) | (0x00) | OPC_CP2,
999     OPC_PADDW   = (27 << 21) | (0x00) | OPC_CP2,
1000     OPC_PADDSB  = (28 << 21) | (0x00) | OPC_CP2,
1001     OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1002     OPC_PADDB   = (30 << 21) | (0x00) | OPC_CP2,
1003     OPC_PADDD   = (31 << 21) | (0x00) | OPC_CP2,
1004 
1005     OPC_PSUBSH  = (24 << 21) | (0x01) | OPC_CP2,
1006     OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1007     OPC_PSUBH   = (26 << 21) | (0x01) | OPC_CP2,
1008     OPC_PSUBW   = (27 << 21) | (0x01) | OPC_CP2,
1009     OPC_PSUBSB  = (28 << 21) | (0x01) | OPC_CP2,
1010     OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1011     OPC_PSUBB   = (30 << 21) | (0x01) | OPC_CP2,
1012     OPC_PSUBD   = (31 << 21) | (0x01) | OPC_CP2,
1013 
1014     OPC_PSHUFH   = (24 << 21) | (0x02) | OPC_CP2,
1015     OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1016     OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1017     OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1018     OPC_XOR_CP2  = (28 << 21) | (0x02) | OPC_CP2,
1019     OPC_NOR_CP2  = (29 << 21) | (0x02) | OPC_CP2,
1020     OPC_AND_CP2  = (30 << 21) | (0x02) | OPC_CP2,
1021     OPC_PANDN    = (31 << 21) | (0x02) | OPC_CP2,
1022 
1023     OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1024     OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1025     OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1026     OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1027     OPC_PINSRH_0  = (28 << 21) | (0x03) | OPC_CP2,
1028     OPC_PINSRH_1  = (29 << 21) | (0x03) | OPC_CP2,
1029     OPC_PINSRH_2  = (30 << 21) | (0x03) | OPC_CP2,
1030     OPC_PINSRH_3  = (31 << 21) | (0x03) | OPC_CP2,
1031 
1032     OPC_PAVGH   = (24 << 21) | (0x08) | OPC_CP2,
1033     OPC_PAVGB   = (25 << 21) | (0x08) | OPC_CP2,
1034     OPC_PMAXSH  = (26 << 21) | (0x08) | OPC_CP2,
1035     OPC_PMINSH  = (27 << 21) | (0x08) | OPC_CP2,
1036     OPC_PMAXUB  = (28 << 21) | (0x08) | OPC_CP2,
1037     OPC_PMINUB  = (29 << 21) | (0x08) | OPC_CP2,
1038 
1039     OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1040     OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1041     OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1042     OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1043     OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1044     OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1045 
1046     OPC_PSLLW   = (24 << 21) | (0x0A) | OPC_CP2,
1047     OPC_PSLLH   = (25 << 21) | (0x0A) | OPC_CP2,
1048     OPC_PMULLH  = (26 << 21) | (0x0A) | OPC_CP2,
1049     OPC_PMULHH  = (27 << 21) | (0x0A) | OPC_CP2,
1050     OPC_PMULUW  = (28 << 21) | (0x0A) | OPC_CP2,
1051     OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1052 
1053     OPC_PSRLW     = (24 << 21) | (0x0B) | OPC_CP2,
1054     OPC_PSRLH     = (25 << 21) | (0x0B) | OPC_CP2,
1055     OPC_PSRAW     = (26 << 21) | (0x0B) | OPC_CP2,
1056     OPC_PSRAH     = (27 << 21) | (0x0B) | OPC_CP2,
1057     OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1058     OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1059 
1060     OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1061     OPC_OR_CP2   = (25 << 21) | (0x0C) | OPC_CP2,
1062     OPC_ADD_CP2  = (26 << 21) | (0x0C) | OPC_CP2,
1063     OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1064     OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1065     OPC_SEQ_CP2  = (29 << 21) | (0x0C) | OPC_CP2,
1066 
1067     OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1068     OPC_PASUBUB  = (25 << 21) | (0x0D) | OPC_CP2,
1069     OPC_SUB_CP2  = (26 << 21) | (0x0D) | OPC_CP2,
1070     OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1071     OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1072     OPC_SLT_CP2  = (29 << 21) | (0x0D) | OPC_CP2,
1073 
1074     OPC_SLL_CP2  = (24 << 21) | (0x0E) | OPC_CP2,
1075     OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1076     OPC_PEXTRH   = (26 << 21) | (0x0E) | OPC_CP2,
1077     OPC_PMADDHW  = (27 << 21) | (0x0E) | OPC_CP2,
1078     OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1079     OPC_SLE_CP2  = (29 << 21) | (0x0E) | OPC_CP2,
1080 
1081     OPC_SRL_CP2  = (24 << 21) | (0x0F) | OPC_CP2,
1082     OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1083     OPC_SRA_CP2  = (26 << 21) | (0x0F) | OPC_CP2,
1084     OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1085     OPC_BIADD    = (28 << 21) | (0x0F) | OPC_CP2,
1086     OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1087 };
1088 
1089 
1090 #define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
1091 
1092 enum {
1093     OPC_LWXC1   = 0x00 | OPC_CP3,
1094     OPC_LDXC1   = 0x01 | OPC_CP3,
1095     OPC_LUXC1   = 0x05 | OPC_CP3,
1096     OPC_SWXC1   = 0x08 | OPC_CP3,
1097     OPC_SDXC1   = 0x09 | OPC_CP3,
1098     OPC_SUXC1   = 0x0D | OPC_CP3,
1099     OPC_PREFX   = 0x0F | OPC_CP3,
1100     OPC_ALNV_PS = 0x1E | OPC_CP3,
1101     OPC_MADD_S  = 0x20 | OPC_CP3,
1102     OPC_MADD_D  = 0x21 | OPC_CP3,
1103     OPC_MADD_PS = 0x26 | OPC_CP3,
1104     OPC_MSUB_S  = 0x28 | OPC_CP3,
1105     OPC_MSUB_D  = 0x29 | OPC_CP3,
1106     OPC_MSUB_PS = 0x2E | OPC_CP3,
1107     OPC_NMADD_S = 0x30 | OPC_CP3,
1108     OPC_NMADD_D = 0x31 | OPC_CP3,
1109     OPC_NMADD_PS= 0x36 | OPC_CP3,
1110     OPC_NMSUB_S = 0x38 | OPC_CP3,
1111     OPC_NMSUB_D = 0x39 | OPC_CP3,
1112     OPC_NMSUB_PS= 0x3E | OPC_CP3,
1113 };
1114 
1115 /* MSA Opcodes */
1116 #define MASK_MSA_MINOR(op)    (MASK_OP_MAJOR(op) | (op & 0x3F))
1117 enum {
1118     OPC_MSA_I8_00   = 0x00 | OPC_MSA,
1119     OPC_MSA_I8_01   = 0x01 | OPC_MSA,
1120     OPC_MSA_I8_02   = 0x02 | OPC_MSA,
1121     OPC_MSA_I5_06   = 0x06 | OPC_MSA,
1122     OPC_MSA_I5_07   = 0x07 | OPC_MSA,
1123     OPC_MSA_BIT_09  = 0x09 | OPC_MSA,
1124     OPC_MSA_BIT_0A  = 0x0A | OPC_MSA,
1125     OPC_MSA_3R_0D   = 0x0D | OPC_MSA,
1126     OPC_MSA_3R_0E   = 0x0E | OPC_MSA,
1127     OPC_MSA_3R_0F   = 0x0F | OPC_MSA,
1128     OPC_MSA_3R_10   = 0x10 | OPC_MSA,
1129     OPC_MSA_3R_11   = 0x11 | OPC_MSA,
1130     OPC_MSA_3R_12   = 0x12 | OPC_MSA,
1131     OPC_MSA_3R_13   = 0x13 | OPC_MSA,
1132     OPC_MSA_3R_14   = 0x14 | OPC_MSA,
1133     OPC_MSA_3R_15   = 0x15 | OPC_MSA,
1134     OPC_MSA_ELM     = 0x19 | OPC_MSA,
1135     OPC_MSA_3RF_1A  = 0x1A | OPC_MSA,
1136     OPC_MSA_3RF_1B  = 0x1B | OPC_MSA,
1137     OPC_MSA_3RF_1C  = 0x1C | OPC_MSA,
1138     OPC_MSA_VEC     = 0x1E | OPC_MSA,
1139 
1140     /* MI10 instruction */
1141     OPC_LD_B    = (0x20) | OPC_MSA,
1142     OPC_LD_H    = (0x21) | OPC_MSA,
1143     OPC_LD_W    = (0x22) | OPC_MSA,
1144     OPC_LD_D    = (0x23) | OPC_MSA,
1145     OPC_ST_B    = (0x24) | OPC_MSA,
1146     OPC_ST_H    = (0x25) | OPC_MSA,
1147     OPC_ST_W    = (0x26) | OPC_MSA,
1148     OPC_ST_D    = (0x27) | OPC_MSA,
1149 };
1150 
1151 enum {
1152     /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1153     OPC_ADDVI_df    = (0x0 << 23) | OPC_MSA_I5_06,
1154     OPC_CEQI_df     = (0x0 << 23) | OPC_MSA_I5_07,
1155     OPC_SUBVI_df    = (0x1 << 23) | OPC_MSA_I5_06,
1156     OPC_MAXI_S_df   = (0x2 << 23) | OPC_MSA_I5_06,
1157     OPC_CLTI_S_df   = (0x2 << 23) | OPC_MSA_I5_07,
1158     OPC_MAXI_U_df   = (0x3 << 23) | OPC_MSA_I5_06,
1159     OPC_CLTI_U_df   = (0x3 << 23) | OPC_MSA_I5_07,
1160     OPC_MINI_S_df   = (0x4 << 23) | OPC_MSA_I5_06,
1161     OPC_CLEI_S_df   = (0x4 << 23) | OPC_MSA_I5_07,
1162     OPC_MINI_U_df   = (0x5 << 23) | OPC_MSA_I5_06,
1163     OPC_CLEI_U_df   = (0x5 << 23) | OPC_MSA_I5_07,
1164     OPC_LDI_df      = (0x6 << 23) | OPC_MSA_I5_07,
1165 
1166     /* I8 instruction */
1167     OPC_ANDI_B  = (0x0 << 24) | OPC_MSA_I8_00,
1168     OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1169     OPC_SHF_B   = (0x0 << 24) | OPC_MSA_I8_02,
1170     OPC_ORI_B   = (0x1 << 24) | OPC_MSA_I8_00,
1171     OPC_BMZI_B  = (0x1 << 24) | OPC_MSA_I8_01,
1172     OPC_SHF_H   = (0x1 << 24) | OPC_MSA_I8_02,
1173     OPC_NORI_B  = (0x2 << 24) | OPC_MSA_I8_00,
1174     OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1175     OPC_SHF_W   = (0x2 << 24) | OPC_MSA_I8_02,
1176     OPC_XORI_B  = (0x3 << 24) | OPC_MSA_I8_00,
1177 
1178     /* VEC/2R/2RF instruction */
1179     OPC_AND_V   = (0x00 << 21) | OPC_MSA_VEC,
1180     OPC_OR_V    = (0x01 << 21) | OPC_MSA_VEC,
1181     OPC_NOR_V   = (0x02 << 21) | OPC_MSA_VEC,
1182     OPC_XOR_V   = (0x03 << 21) | OPC_MSA_VEC,
1183     OPC_BMNZ_V  = (0x04 << 21) | OPC_MSA_VEC,
1184     OPC_BMZ_V   = (0x05 << 21) | OPC_MSA_VEC,
1185     OPC_BSEL_V  = (0x06 << 21) | OPC_MSA_VEC,
1186 
1187     OPC_MSA_2R      = (0x18 << 21) | OPC_MSA_VEC,
1188     OPC_MSA_2RF     = (0x19 << 21) | OPC_MSA_VEC,
1189 
1190     /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1191     OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1192     OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1193     OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1194     OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1195 
1196     /* 2RF instruction df(bit 16) = _w, _d */
1197     OPC_FCLASS_df   = (0x00 << 17) | OPC_MSA_2RF,
1198     OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1199     OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1200     OPC_FSQRT_df    = (0x03 << 17) | OPC_MSA_2RF,
1201     OPC_FRSQRT_df   = (0x04 << 17) | OPC_MSA_2RF,
1202     OPC_FRCP_df     = (0x05 << 17) | OPC_MSA_2RF,
1203     OPC_FRINT_df    = (0x06 << 17) | OPC_MSA_2RF,
1204     OPC_FLOG2_df    = (0x07 << 17) | OPC_MSA_2RF,
1205     OPC_FEXUPL_df   = (0x08 << 17) | OPC_MSA_2RF,
1206     OPC_FEXUPR_df   = (0x09 << 17) | OPC_MSA_2RF,
1207     OPC_FFQL_df     = (0x0A << 17) | OPC_MSA_2RF,
1208     OPC_FFQR_df     = (0x0B << 17) | OPC_MSA_2RF,
1209     OPC_FTINT_S_df  = (0x0C << 17) | OPC_MSA_2RF,
1210     OPC_FTINT_U_df  = (0x0D << 17) | OPC_MSA_2RF,
1211     OPC_FFINT_S_df  = (0x0E << 17) | OPC_MSA_2RF,
1212     OPC_FFINT_U_df  = (0x0F << 17) | OPC_MSA_2RF,
1213 
1214     /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1215     OPC_SLL_df      = (0x0 << 23) | OPC_MSA_3R_0D,
1216     OPC_ADDV_df     = (0x0 << 23) | OPC_MSA_3R_0E,
1217     OPC_CEQ_df      = (0x0 << 23) | OPC_MSA_3R_0F,
1218     OPC_ADD_A_df    = (0x0 << 23) | OPC_MSA_3R_10,
1219     OPC_SUBS_S_df   = (0x0 << 23) | OPC_MSA_3R_11,
1220     OPC_MULV_df     = (0x0 << 23) | OPC_MSA_3R_12,
1221     OPC_DOTP_S_df   = (0x0 << 23) | OPC_MSA_3R_13,
1222     OPC_SLD_df      = (0x0 << 23) | OPC_MSA_3R_14,
1223     OPC_VSHF_df     = (0x0 << 23) | OPC_MSA_3R_15,
1224     OPC_SRA_df      = (0x1 << 23) | OPC_MSA_3R_0D,
1225     OPC_SUBV_df     = (0x1 << 23) | OPC_MSA_3R_0E,
1226     OPC_ADDS_A_df   = (0x1 << 23) | OPC_MSA_3R_10,
1227     OPC_SUBS_U_df   = (0x1 << 23) | OPC_MSA_3R_11,
1228     OPC_MADDV_df    = (0x1 << 23) | OPC_MSA_3R_12,
1229     OPC_DOTP_U_df   = (0x1 << 23) | OPC_MSA_3R_13,
1230     OPC_SPLAT_df    = (0x1 << 23) | OPC_MSA_3R_14,
1231     OPC_SRAR_df     = (0x1 << 23) | OPC_MSA_3R_15,
1232     OPC_SRL_df      = (0x2 << 23) | OPC_MSA_3R_0D,
1233     OPC_MAX_S_df    = (0x2 << 23) | OPC_MSA_3R_0E,
1234     OPC_CLT_S_df    = (0x2 << 23) | OPC_MSA_3R_0F,
1235     OPC_ADDS_S_df   = (0x2 << 23) | OPC_MSA_3R_10,
1236     OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1237     OPC_MSUBV_df    = (0x2 << 23) | OPC_MSA_3R_12,
1238     OPC_DPADD_S_df  = (0x2 << 23) | OPC_MSA_3R_13,
1239     OPC_PCKEV_df    = (0x2 << 23) | OPC_MSA_3R_14,
1240     OPC_SRLR_df     = (0x2 << 23) | OPC_MSA_3R_15,
1241     OPC_BCLR_df     = (0x3 << 23) | OPC_MSA_3R_0D,
1242     OPC_MAX_U_df    = (0x3 << 23) | OPC_MSA_3R_0E,
1243     OPC_CLT_U_df    = (0x3 << 23) | OPC_MSA_3R_0F,
1244     OPC_ADDS_U_df   = (0x3 << 23) | OPC_MSA_3R_10,
1245     OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1246     OPC_DPADD_U_df  = (0x3 << 23) | OPC_MSA_3R_13,
1247     OPC_PCKOD_df    = (0x3 << 23) | OPC_MSA_3R_14,
1248     OPC_BSET_df     = (0x4 << 23) | OPC_MSA_3R_0D,
1249     OPC_MIN_S_df    = (0x4 << 23) | OPC_MSA_3R_0E,
1250     OPC_CLE_S_df    = (0x4 << 23) | OPC_MSA_3R_0F,
1251     OPC_AVE_S_df    = (0x4 << 23) | OPC_MSA_3R_10,
1252     OPC_ASUB_S_df   = (0x4 << 23) | OPC_MSA_3R_11,
1253     OPC_DIV_S_df    = (0x4 << 23) | OPC_MSA_3R_12,
1254     OPC_DPSUB_S_df  = (0x4 << 23) | OPC_MSA_3R_13,
1255     OPC_ILVL_df     = (0x4 << 23) | OPC_MSA_3R_14,
1256     OPC_HADD_S_df   = (0x4 << 23) | OPC_MSA_3R_15,
1257     OPC_BNEG_df     = (0x5 << 23) | OPC_MSA_3R_0D,
1258     OPC_MIN_U_df    = (0x5 << 23) | OPC_MSA_3R_0E,
1259     OPC_CLE_U_df    = (0x5 << 23) | OPC_MSA_3R_0F,
1260     OPC_AVE_U_df    = (0x5 << 23) | OPC_MSA_3R_10,
1261     OPC_ASUB_U_df   = (0x5 << 23) | OPC_MSA_3R_11,
1262     OPC_DIV_U_df    = (0x5 << 23) | OPC_MSA_3R_12,
1263     OPC_DPSUB_U_df  = (0x5 << 23) | OPC_MSA_3R_13,
1264     OPC_ILVR_df     = (0x5 << 23) | OPC_MSA_3R_14,
1265     OPC_HADD_U_df   = (0x5 << 23) | OPC_MSA_3R_15,
1266     OPC_BINSL_df    = (0x6 << 23) | OPC_MSA_3R_0D,
1267     OPC_MAX_A_df    = (0x6 << 23) | OPC_MSA_3R_0E,
1268     OPC_AVER_S_df   = (0x6 << 23) | OPC_MSA_3R_10,
1269     OPC_MOD_S_df    = (0x6 << 23) | OPC_MSA_3R_12,
1270     OPC_ILVEV_df    = (0x6 << 23) | OPC_MSA_3R_14,
1271     OPC_HSUB_S_df   = (0x6 << 23) | OPC_MSA_3R_15,
1272     OPC_BINSR_df    = (0x7 << 23) | OPC_MSA_3R_0D,
1273     OPC_MIN_A_df    = (0x7 << 23) | OPC_MSA_3R_0E,
1274     OPC_AVER_U_df   = (0x7 << 23) | OPC_MSA_3R_10,
1275     OPC_MOD_U_df    = (0x7 << 23) | OPC_MSA_3R_12,
1276     OPC_ILVOD_df    = (0x7 << 23) | OPC_MSA_3R_14,
1277     OPC_HSUB_U_df   = (0x7 << 23) | OPC_MSA_3R_15,
1278 
1279     /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1280     OPC_SLDI_df     = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1281     OPC_CTCMSA      = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1282     OPC_SPLATI_df   = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1283     OPC_CFCMSA      = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1284     OPC_COPY_S_df   = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1285     OPC_MOVE_V      = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1286     OPC_COPY_U_df   = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1287     OPC_INSERT_df   = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1288     OPC_INSVE_df    = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1289 
1290     /* 3RF instruction _df(bit 21) = _w, _d */
1291     OPC_FCAF_df     = (0x0 << 22) | OPC_MSA_3RF_1A,
1292     OPC_FADD_df     = (0x0 << 22) | OPC_MSA_3RF_1B,
1293     OPC_FCUN_df     = (0x1 << 22) | OPC_MSA_3RF_1A,
1294     OPC_FSUB_df     = (0x1 << 22) | OPC_MSA_3RF_1B,
1295     OPC_FCOR_df     = (0x1 << 22) | OPC_MSA_3RF_1C,
1296     OPC_FCEQ_df     = (0x2 << 22) | OPC_MSA_3RF_1A,
1297     OPC_FMUL_df     = (0x2 << 22) | OPC_MSA_3RF_1B,
1298     OPC_FCUNE_df    = (0x2 << 22) | OPC_MSA_3RF_1C,
1299     OPC_FCUEQ_df    = (0x3 << 22) | OPC_MSA_3RF_1A,
1300     OPC_FDIV_df     = (0x3 << 22) | OPC_MSA_3RF_1B,
1301     OPC_FCNE_df     = (0x3 << 22) | OPC_MSA_3RF_1C,
1302     OPC_FCLT_df     = (0x4 << 22) | OPC_MSA_3RF_1A,
1303     OPC_FMADD_df    = (0x4 << 22) | OPC_MSA_3RF_1B,
1304     OPC_MUL_Q_df    = (0x4 << 22) | OPC_MSA_3RF_1C,
1305     OPC_FCULT_df    = (0x5 << 22) | OPC_MSA_3RF_1A,
1306     OPC_FMSUB_df    = (0x5 << 22) | OPC_MSA_3RF_1B,
1307     OPC_MADD_Q_df   = (0x5 << 22) | OPC_MSA_3RF_1C,
1308     OPC_FCLE_df     = (0x6 << 22) | OPC_MSA_3RF_1A,
1309     OPC_MSUB_Q_df   = (0x6 << 22) | OPC_MSA_3RF_1C,
1310     OPC_FCULE_df    = (0x7 << 22) | OPC_MSA_3RF_1A,
1311     OPC_FEXP2_df    = (0x7 << 22) | OPC_MSA_3RF_1B,
1312     OPC_FSAF_df     = (0x8 << 22) | OPC_MSA_3RF_1A,
1313     OPC_FEXDO_df    = (0x8 << 22) | OPC_MSA_3RF_1B,
1314     OPC_FSUN_df     = (0x9 << 22) | OPC_MSA_3RF_1A,
1315     OPC_FSOR_df     = (0x9 << 22) | OPC_MSA_3RF_1C,
1316     OPC_FSEQ_df     = (0xA << 22) | OPC_MSA_3RF_1A,
1317     OPC_FTQ_df      = (0xA << 22) | OPC_MSA_3RF_1B,
1318     OPC_FSUNE_df    = (0xA << 22) | OPC_MSA_3RF_1C,
1319     OPC_FSUEQ_df    = (0xB << 22) | OPC_MSA_3RF_1A,
1320     OPC_FSNE_df     = (0xB << 22) | OPC_MSA_3RF_1C,
1321     OPC_FSLT_df     = (0xC << 22) | OPC_MSA_3RF_1A,
1322     OPC_FMIN_df     = (0xC << 22) | OPC_MSA_3RF_1B,
1323     OPC_MULR_Q_df   = (0xC << 22) | OPC_MSA_3RF_1C,
1324     OPC_FSULT_df    = (0xD << 22) | OPC_MSA_3RF_1A,
1325     OPC_FMIN_A_df   = (0xD << 22) | OPC_MSA_3RF_1B,
1326     OPC_MADDR_Q_df  = (0xD << 22) | OPC_MSA_3RF_1C,
1327     OPC_FSLE_df     = (0xE << 22) | OPC_MSA_3RF_1A,
1328     OPC_FMAX_df     = (0xE << 22) | OPC_MSA_3RF_1B,
1329     OPC_MSUBR_Q_df  = (0xE << 22) | OPC_MSA_3RF_1C,
1330     OPC_FSULE_df    = (0xF << 22) | OPC_MSA_3RF_1A,
1331     OPC_FMAX_A_df   = (0xF << 22) | OPC_MSA_3RF_1B,
1332 
1333     /* BIT instruction df(bits 22..16) = _B _H _W _D */
1334     OPC_SLLI_df     = (0x0 << 23) | OPC_MSA_BIT_09,
1335     OPC_SAT_S_df    = (0x0 << 23) | OPC_MSA_BIT_0A,
1336     OPC_SRAI_df     = (0x1 << 23) | OPC_MSA_BIT_09,
1337     OPC_SAT_U_df    = (0x1 << 23) | OPC_MSA_BIT_0A,
1338     OPC_SRLI_df     = (0x2 << 23) | OPC_MSA_BIT_09,
1339     OPC_SRARI_df    = (0x2 << 23) | OPC_MSA_BIT_0A,
1340     OPC_BCLRI_df    = (0x3 << 23) | OPC_MSA_BIT_09,
1341     OPC_SRLRI_df    = (0x3 << 23) | OPC_MSA_BIT_0A,
1342     OPC_BSETI_df    = (0x4 << 23) | OPC_MSA_BIT_09,
1343     OPC_BNEGI_df    = (0x5 << 23) | OPC_MSA_BIT_09,
1344     OPC_BINSLI_df   = (0x6 << 23) | OPC_MSA_BIT_09,
1345     OPC_BINSRI_df   = (0x7 << 23) | OPC_MSA_BIT_09,
1346 };
1347 
1348 
1349 #define gen_helper_0e0i(tcg_ctx, name, arg) do {                           \
1350     TCGv_i32 helper_tmp = tcg_const_i32(tcg_ctx, arg);                     \
1351     gen_helper_##name(tcg_ctx, tcg_ctx->cpu_env, helper_tmp);                       \
1352     tcg_temp_free_i32(tcg_ctx, helper_tmp);                                \
1353     } while(0)
1354 
1355 #define gen_helper_0e1i(tcg_ctx, name, arg1, arg2) do {                    \
1356     TCGv_i32 helper_tmp = tcg_const_i32(tcg_ctx, arg2);                    \
1357     gen_helper_##name(tcg_ctx, tcg_ctx->cpu_env, arg1, helper_tmp);                 \
1358     tcg_temp_free_i32(tcg_ctx, helper_tmp);                                \
1359     } while(0)
1360 
1361 #define gen_helper_1e0i(tcg_ctx, name, ret, arg1) do {                     \
1362     TCGv_i32 helper_tmp = tcg_const_i32(tcg_ctx, arg1);                    \
1363     gen_helper_##name(tcg_ctx, ret, tcg_ctx->cpu_env, helper_tmp);                  \
1364     tcg_temp_free_i32(tcg_ctx, helper_tmp);                                \
1365     } while(0)
1366 
1367 #define gen_helper_1e1i(tcg_ctx, name, ret, arg1, arg2) do {               \
1368     TCGv_i32 helper_tmp = tcg_const_i32(tcg_ctx, arg2);                    \
1369     gen_helper_##name(tcg_ctx, ret, tcg_ctx->cpu_env, arg1, helper_tmp);            \
1370     tcg_temp_free_i32(tcg_ctx, helper_tmp);                                \
1371     } while(0)
1372 
1373 #define gen_helper_0e2i(tcg_ctx, name, arg1, arg2, arg3) do {              \
1374     TCGv_i32 helper_tmp = tcg_const_i32(tcg_ctx, arg3);                    \
1375     gen_helper_##name(tcg_ctx, tcg_ctx->cpu_env, arg1, arg2, helper_tmp);           \
1376     tcg_temp_free_i32(tcg_ctx, helper_tmp);                                \
1377     } while(0)
1378 
1379 #define gen_helper_1e2i(tcg_ctx, name, ret, arg1, arg2, arg3) do {         \
1380     TCGv_i32 helper_tmp = tcg_const_i32(tcg_ctx, arg3);                    \
1381     gen_helper_##name(tcg_ctx, ret, tcg_ctx->cpu_env, arg1, arg2, helper_tmp);      \
1382     tcg_temp_free_i32(tcg_ctx, helper_tmp);                                \
1383     } while(0)
1384 
1385 #define gen_helper_0e3i(tcg_ctx, name, arg1, arg2, arg3, arg4) do {        \
1386     TCGv_i32 helper_tmp = tcg_const_i32(tcg_ctx, arg4);                    \
1387     gen_helper_##name(tcg_ctx, tcg_ctx->cpu_env, arg1, arg2, arg3, helper_tmp);     \
1388     tcg_temp_free_i32(tcg_ctx, helper_tmp);                                \
1389     } while(0)
1390 
1391 typedef struct DisasContext {
1392     struct TranslationBlock *tb;
1393     target_ulong pc, saved_pc;
1394     uint32_t opcode;
1395     int singlestep_enabled;
1396     int insn_flags;
1397     int32_t CP0_Config1;
1398     /* Routine used to access memory */
1399     int mem_idx;
1400     uint32_t hflags, saved_hflags;
1401     int bstate;
1402     target_ulong btarget;
1403     bool ulri;
1404     int kscrexist;
1405     bool rxi;
1406     int ie;
1407     bool bi;
1408     bool bp;
1409     // Unicorn engine
1410     struct uc_struct *uc;
1411 } DisasContext;
1412 
1413 enum {
1414     BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
1415                       * exception condition */
1416     BS_STOP     = 1, /* We want to stop translation for any reason */
1417     BS_BRANCH   = 2, /* We reached a branch condition     */
1418     BS_EXCP     = 3, /* We reached an exception condition */
1419 };
1420 
1421 static const char * const regnames[] = {
1422     "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1423     "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1424     "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1425     "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1426 };
1427 
1428 static const char * const regnames_HI[] = {
1429     "HI0", "HI1", "HI2", "HI3",
1430 };
1431 
1432 static const char * const regnames_LO[] = {
1433     "LO0", "LO1", "LO2", "LO3",
1434 };
1435 
1436 static const char * const fregnames[] = {
1437     "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
1438     "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
1439     "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1440     "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1441 };
1442 
1443 static const char * const msaregnames[] = {
1444     "w0.d0",  "w0.d1",  "w1.d0",  "w1.d1",
1445     "w2.d0",  "w2.d1",  "w3.d0",  "w3.d1",
1446     "w4.d0",  "w4.d1",  "w5.d0",  "w5.d1",
1447     "w6.d0",  "w6.d1",  "w7.d0",  "w7.d1",
1448     "w8.d0",  "w8.d1",  "w9.d0",  "w9.d1",
1449     "w10.d0", "w10.d1", "w11.d0", "w11.d1",
1450     "w12.d0", "w12.d1", "w13.d0", "w13.d1",
1451     "w14.d0", "w14.d1", "w15.d0", "w15.d1",
1452     "w16.d0", "w16.d1", "w17.d0", "w17.d1",
1453     "w18.d0", "w18.d1", "w19.d0", "w19.d1",
1454     "w20.d0", "w20.d1", "w21.d0", "w21.d1",
1455     "w22.d0", "w22.d1", "w23.d0", "w23.d1",
1456     "w24.d0", "w24.d1", "w25.d0", "w25.d1",
1457     "w26.d0", "w26.d1", "w27.d0", "w27.d1",
1458     "w28.d0", "w28.d1", "w29.d0", "w29.d1",
1459     "w30.d0", "w30.d1", "w31.d0", "w31.d1",
1460 };
1461 
1462 #define MIPS_DEBUG(fmt, ...)                                                  \
1463     do {                                                                      \
1464         if (MIPS_DEBUG_DISAS) {                                               \
1465             qemu_log_mask(CPU_LOG_TB_IN_ASM,                                  \
1466                           TARGET_FMT_lx ": %08x " fmt "\n",                   \
1467                           ctx->pc, ctx->opcode , ## __VA_ARGS__);             \
1468         }                                                                     \
1469     } while (0)
1470 
1471 #define LOG_DISAS(...)                                                        \
1472     do {                                                                      \
1473         if (MIPS_DEBUG_DISAS) {                                               \
1474             qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__);                 \
1475         }                                                                     \
1476     } while (0)
1477 
1478 #define MIPS_INVAL(op)                                                        \
1479     MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
1480                ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
1481 
1482 /* General purpose registers moves. */
gen_load_gpr(DisasContext * s,TCGv t,int reg)1483 static inline void gen_load_gpr (DisasContext *s, TCGv t, int reg)
1484 {
1485     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1486     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
1487     if (reg == 0)
1488         tcg_gen_movi_tl(tcg_ctx, t, 0);
1489     else
1490         tcg_gen_mov_tl(tcg_ctx, t, *cpu_gpr[reg]);
1491 }
1492 
gen_store_gpr(TCGContext * tcg_ctx,TCGv t,int reg)1493 static inline void gen_store_gpr (TCGContext *tcg_ctx, TCGv t, int reg)
1494 {
1495     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
1496     if (reg != 0)
1497         tcg_gen_mov_tl(tcg_ctx, *cpu_gpr[reg], t);
1498 }
1499 
1500 /* Moves to/from shadow registers. */
gen_load_srsgpr(DisasContext * s,int from,int to)1501 static inline void gen_load_srsgpr (DisasContext *s, int from, int to)
1502 {
1503     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1504     TCGv t0 = tcg_temp_new(tcg_ctx);
1505 
1506     if (from == 0)
1507         tcg_gen_movi_tl(tcg_ctx, t0, 0);
1508     else {
1509         TCGv_i32 t2 = tcg_temp_new_i32(tcg_ctx);
1510         TCGv_ptr addr = tcg_temp_new_ptr(tcg_ctx);
1511 
1512         tcg_gen_ld_i32(tcg_ctx, t2, tcg_ctx->cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1513         tcg_gen_shri_i32(tcg_ctx, t2, t2, CP0SRSCtl_PSS);
1514         tcg_gen_andi_i32(tcg_ctx, t2, t2, 0xf);
1515         tcg_gen_muli_i32(tcg_ctx, t2, t2, sizeof(target_ulong) * 32);
1516         tcg_gen_ext_i32_ptr(tcg_ctx, addr, t2);
1517         tcg_gen_add_ptr(tcg_ctx, addr, tcg_ctx->cpu_env, addr);
1518 
1519         tcg_gen_ld_tl(tcg_ctx, t0, addr, sizeof(target_ulong) * from);
1520         tcg_temp_free_ptr(tcg_ctx, addr);
1521         tcg_temp_free_i32(tcg_ctx, t2);
1522     }
1523     gen_store_gpr(tcg_ctx, t0, to);
1524     tcg_temp_free(tcg_ctx, t0);
1525 }
1526 
gen_store_srsgpr(DisasContext * s,int from,int to)1527 static inline void gen_store_srsgpr (DisasContext *s, int from, int to)
1528 {
1529     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1530     if (to != 0) {
1531         TCGv t0 = tcg_temp_new(tcg_ctx);
1532         TCGv_i32 t2 = tcg_temp_new_i32(tcg_ctx);
1533         TCGv_ptr addr = tcg_temp_new_ptr(tcg_ctx);
1534 
1535         gen_load_gpr(s, t0, from);
1536         tcg_gen_ld_i32(tcg_ctx, t2, tcg_ctx->cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1537         tcg_gen_shri_i32(tcg_ctx, t2, t2, CP0SRSCtl_PSS);
1538         tcg_gen_andi_i32(tcg_ctx, t2, t2, 0xf);
1539         tcg_gen_muli_i32(tcg_ctx, t2, t2, sizeof(target_ulong) * 32);
1540         tcg_gen_ext_i32_ptr(tcg_ctx, addr, t2);
1541         tcg_gen_add_ptr(tcg_ctx, addr, tcg_ctx->cpu_env, addr);
1542 
1543         tcg_gen_st_tl(tcg_ctx, t0, addr, sizeof(target_ulong) * to);
1544         tcg_temp_free_ptr(tcg_ctx, addr);
1545         tcg_temp_free_i32(tcg_ctx, t2);
1546         tcg_temp_free(tcg_ctx, t0);
1547     }
1548 }
1549 
1550 /* Floating point register moves. */
gen_load_fpr32(DisasContext * s,TCGv_i32 t,int reg)1551 static void gen_load_fpr32(DisasContext *s, TCGv_i32 t, int reg)
1552 {
1553     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1554     tcg_gen_trunc_i64_i32(tcg_ctx, t, tcg_ctx->fpu_f64[reg]);
1555 }
1556 
gen_store_fpr32(DisasContext * s,TCGv_i32 t,int reg)1557 static void gen_store_fpr32(DisasContext *s, TCGv_i32 t, int reg)
1558 {
1559     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1560     TCGv_i64 t64 = tcg_temp_new_i64(tcg_ctx);
1561     tcg_gen_extu_i32_i64(tcg_ctx, t64, t);
1562     tcg_gen_deposit_i64(tcg_ctx, tcg_ctx->fpu_f64[reg], tcg_ctx->fpu_f64[reg], t64, 0, 32);
1563     tcg_temp_free_i64(tcg_ctx, t64);
1564 }
1565 
gen_load_fpr32h(DisasContext * ctx,TCGv_i32 t,int reg)1566 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1567 {
1568     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
1569     if (ctx->hflags & MIPS_HFLAG_F64) {
1570         TCGv_i64 t64 = tcg_temp_new_i64(tcg_ctx);
1571         tcg_gen_shri_i64(tcg_ctx, t64, tcg_ctx->fpu_f64[reg], 32);
1572         tcg_gen_trunc_i64_i32(tcg_ctx, t, t64);
1573         tcg_temp_free_i64(tcg_ctx, t64);
1574     } else {
1575         gen_load_fpr32(ctx, t, reg | 1);
1576     }
1577 }
1578 
gen_store_fpr32h(DisasContext * ctx,TCGv_i32 t,int reg)1579 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1580 {
1581     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
1582     if (ctx->hflags & MIPS_HFLAG_F64) {
1583         TCGv_i64 t64 = tcg_temp_new_i64(tcg_ctx);
1584         tcg_gen_extu_i32_i64(tcg_ctx, t64, t);
1585         tcg_gen_deposit_i64(tcg_ctx, tcg_ctx->fpu_f64[reg], tcg_ctx->fpu_f64[reg], t64, 32, 32);
1586         tcg_temp_free_i64(tcg_ctx, t64);
1587     } else {
1588         gen_store_fpr32(ctx, t, reg | 1);
1589     }
1590 }
1591 
gen_load_fpr64(DisasContext * ctx,TCGv_i64 t,int reg)1592 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1593 {
1594     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
1595     if (ctx->hflags & MIPS_HFLAG_F64) {
1596         tcg_gen_mov_i64(tcg_ctx, t, tcg_ctx->fpu_f64[reg]);
1597     } else {
1598         tcg_gen_concat32_i64(tcg_ctx, t, tcg_ctx->fpu_f64[reg & ~1], tcg_ctx->fpu_f64[reg | 1]);
1599     }
1600 }
1601 
gen_store_fpr64(DisasContext * ctx,TCGv_i64 t,int reg)1602 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1603 {
1604     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
1605     if (ctx->hflags & MIPS_HFLAG_F64) {
1606         tcg_gen_mov_i64(tcg_ctx, tcg_ctx->fpu_f64[reg], t);
1607     } else {
1608         TCGv_i64 t0;
1609         tcg_gen_deposit_i64(tcg_ctx, tcg_ctx->fpu_f64[reg & ~1], tcg_ctx->fpu_f64[reg & ~1], t, 0, 32);
1610         t0 = tcg_temp_new_i64(tcg_ctx);
1611         tcg_gen_shri_i64(tcg_ctx, t0, t, 32);
1612         tcg_gen_deposit_i64(tcg_ctx, tcg_ctx->fpu_f64[reg | 1], tcg_ctx->fpu_f64[reg | 1], t0, 0, 32);
1613         tcg_temp_free_i64(tcg_ctx, t0);
1614     }
1615 }
1616 
get_fp_bit(int cc)1617 static inline int get_fp_bit (int cc)
1618 {
1619     if (cc)
1620         return 24 + cc;
1621     else
1622         return 23;
1623 }
1624 
1625 /* Tests */
gen_save_pc(DisasContext * ctx,target_ulong pc)1626 static inline void gen_save_pc(DisasContext *ctx, target_ulong pc)
1627 {
1628     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
1629     tcg_gen_movi_tl(tcg_ctx, *(TCGv *)tcg_ctx->cpu_PC, pc);
1630 }
1631 
save_cpu_state(DisasContext * ctx,int do_save_pc)1632 static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
1633 {
1634     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
1635     LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1636     if (do_save_pc && ctx->pc != ctx->saved_pc) {
1637         gen_save_pc(ctx, ctx->pc);
1638         ctx->saved_pc = ctx->pc;
1639     }
1640     if (ctx->hflags != ctx->saved_hflags) {
1641         tcg_gen_movi_i32(tcg_ctx, tcg_ctx->hflags, ctx->hflags);
1642         ctx->saved_hflags = ctx->hflags;
1643         switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1644         case MIPS_HFLAG_BR:
1645             break;
1646         case MIPS_HFLAG_BC:
1647         case MIPS_HFLAG_BL:
1648         case MIPS_HFLAG_B:
1649             tcg_gen_movi_tl(tcg_ctx, *(TCGv *)tcg_ctx->btarget, ctx->btarget);
1650             break;
1651         }
1652     }
1653 }
1654 
restore_cpu_state(CPUMIPSState * env,DisasContext * ctx)1655 static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
1656 {
1657     ctx->saved_hflags = ctx->hflags;
1658     switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1659     case MIPS_HFLAG_BR:
1660         break;
1661     case MIPS_HFLAG_BC:
1662     case MIPS_HFLAG_BL:
1663     case MIPS_HFLAG_B:
1664         ctx->btarget = env->btarget;
1665         break;
1666     }
1667 }
1668 
1669 static inline void
generate_exception_err(DisasContext * ctx,int excp,int err)1670 generate_exception_err (DisasContext *ctx, int excp, int err)
1671 {
1672     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
1673     TCGv_i32 texcp = tcg_const_i32(tcg_ctx, excp);
1674     TCGv_i32 terr = tcg_const_i32(tcg_ctx, err);
1675     save_cpu_state(ctx, 1);
1676     gen_helper_raise_exception_err(tcg_ctx, tcg_ctx->cpu_env, texcp, terr);
1677     tcg_temp_free_i32(tcg_ctx, terr);
1678     tcg_temp_free_i32(tcg_ctx, texcp);
1679 }
1680 
1681 static inline void
generate_exception(DisasContext * ctx,int excp)1682 generate_exception (DisasContext *ctx, int excp)
1683 {
1684     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
1685     save_cpu_state(ctx, 1);
1686     gen_helper_0e0i(tcg_ctx, raise_exception, excp);
1687 }
1688 
1689 /* Addresses computation */
gen_op_addr_add(DisasContext * ctx,TCGv ret,TCGv arg0,TCGv arg1)1690 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1691 {
1692     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
1693     tcg_gen_add_tl(tcg_ctx, ret, arg0, arg1);
1694 
1695 #if defined(TARGET_MIPS64)
1696     if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1697         tcg_gen_ext32s_i64(tcg_ctx, ret, ret);
1698     }
1699 #endif
1700 }
1701 
1702 /* Addresses computation (translation time) */
addr_add(DisasContext * ctx,target_long base,target_long offset)1703 static target_long addr_add(DisasContext *ctx, target_long base,
1704                             target_long offset)
1705 {
1706     target_long sum = (target_long)((target_ulong)base + offset);
1707 
1708 #if defined(TARGET_MIPS64)
1709     if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1710         sum = (int32_t)sum;
1711     }
1712 #endif
1713     return sum;
1714 }
1715 
check_cp0_enabled(DisasContext * ctx)1716 static inline void check_cp0_enabled(DisasContext *ctx)
1717 {
1718     if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1719         generate_exception_err(ctx, EXCP_CpU, 0);
1720 }
1721 
check_cp1_enabled(DisasContext * ctx)1722 static inline void check_cp1_enabled(DisasContext *ctx)
1723 {
1724     if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
1725         generate_exception_err(ctx, EXCP_CpU, 1);
1726 }
1727 
1728 /* Verify that the processor is running with COP1X instructions enabled.
1729    This is associated with the nabla symbol in the MIPS32 and MIPS64
1730    opcode tables.  */
1731 
check_cop1x(DisasContext * ctx)1732 static inline void check_cop1x(DisasContext *ctx)
1733 {
1734     if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1735         generate_exception(ctx, EXCP_RI);
1736 }
1737 
1738 /* Verify that the processor is running with 64-bit floating-point
1739    operations enabled.  */
1740 
check_cp1_64bitmode(DisasContext * ctx)1741 static inline void check_cp1_64bitmode(DisasContext *ctx)
1742 {
1743     if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
1744         generate_exception(ctx, EXCP_RI);
1745 }
1746 
1747 /*
1748  * Verify if floating point register is valid; an operation is not defined
1749  * if bit 0 of any register specification is set and the FR bit in the
1750  * Status register equals zero, since the register numbers specify an
1751  * even-odd pair of adjacent coprocessor general registers. When the FR bit
1752  * in the Status register equals one, both even and odd register numbers
1753  * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1754  *
1755  * Multiple 64 bit wide registers can be checked by calling
1756  * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1757  */
check_cp1_registers(DisasContext * ctx,int regs)1758 static inline void check_cp1_registers(DisasContext *ctx, int regs)
1759 {
1760     if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
1761         generate_exception(ctx, EXCP_RI);
1762 }
1763 
1764 /* Verify that the processor is running with DSP instructions enabled.
1765    This is enabled by CP0 Status register MX(24) bit.
1766  */
1767 
check_dsp(DisasContext * ctx)1768 static inline void check_dsp(DisasContext *ctx)
1769 {
1770     if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1771         if (ctx->insn_flags & ASE_DSP) {
1772             generate_exception(ctx, EXCP_DSPDIS);
1773         } else {
1774             generate_exception(ctx, EXCP_RI);
1775         }
1776     }
1777 }
1778 
check_dspr2(DisasContext * ctx)1779 static inline void check_dspr2(DisasContext *ctx)
1780 {
1781     if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1782         if (ctx->insn_flags & ASE_DSP) {
1783             generate_exception(ctx, EXCP_DSPDIS);
1784         } else {
1785             generate_exception(ctx, EXCP_RI);
1786         }
1787     }
1788 }
1789 
1790 /* This code generates a "reserved instruction" exception if the
1791    CPU does not support the instruction set corresponding to flags. */
check_insn(DisasContext * ctx,int flags)1792 static inline void check_insn(DisasContext *ctx, int flags)
1793 {
1794     if (unlikely(!(ctx->insn_flags & flags))) {
1795         generate_exception(ctx, EXCP_RI);
1796     }
1797 }
1798 
1799 /* This code generates a "reserved instruction" exception if the
1800    CPU has corresponding flag set which indicates that the instruction
1801    has been removed. */
check_insn_opc_removed(DisasContext * ctx,int flags)1802 static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
1803 {
1804     if (unlikely(ctx->insn_flags & flags)) {
1805         generate_exception(ctx, EXCP_RI);
1806     }
1807 }
1808 
1809 #ifdef TARGET_MIPS64
1810 /* This code generates a "reserved instruction" exception if 64-bit
1811    instructions are not enabled. */
check_mips_64(DisasContext * ctx)1812 static inline void check_mips_64(DisasContext *ctx)
1813 {
1814     if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
1815         generate_exception(ctx, EXCP_RI);
1816 }
1817 #endif
1818 
1819 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1820    calling interface for 32 and 64-bit FPRs.  No sense in changing
1821    all callers for gen_load_fpr32 when we need the CTX parameter for
1822    this one use.  */
1823 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
1824 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1825 #define FOP_CONDS(type, abs, fmt, ifmt, bits)                                 \
1826 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
1827                                                int ft, int fs, int cc)        \
1828 {                                                                             \
1829     TCGContext *tcg_ctx = ctx->uc->tcg_ctx; \
1830     TCGv_i##bits fp0 = tcg_temp_new_i##bits (tcg_ctx);                               \
1831     TCGv_i##bits fp1 = tcg_temp_new_i##bits (tcg_ctx);                               \
1832     switch (ifmt) {                                                           \
1833     case FMT_PS:                                                              \
1834         check_cp1_64bitmode(ctx);                                             \
1835         break;                                                                \
1836     case FMT_D:                                                               \
1837         if (abs) {                                                            \
1838             check_cop1x(ctx);                                                 \
1839         }                                                                     \
1840         check_cp1_registers(ctx, fs | ft);                                    \
1841         break;                                                                \
1842     case FMT_S:                                                               \
1843         if (abs) {                                                            \
1844             check_cop1x(ctx);                                                 \
1845         }                                                                     \
1846         break;                                                                \
1847     }                                                                         \
1848     gen_ldcmp_fpr##bits (ctx, fp0, fs);                                       \
1849     gen_ldcmp_fpr##bits (ctx, fp1, ft);                                       \
1850     switch (n) {                                                              \
1851     case  0: gen_helper_0e2i(tcg_ctx, cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc);    break;\
1852     case  1: gen_helper_0e2i(tcg_ctx, cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc);   break;\
1853     case  2: gen_helper_0e2i(tcg_ctx, cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc);   break;\
1854     case  3: gen_helper_0e2i(tcg_ctx, cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc);  break;\
1855     case  4: gen_helper_0e2i(tcg_ctx, cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc);  break;\
1856     case  5: gen_helper_0e2i(tcg_ctx, cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc);  break;\
1857     case  6: gen_helper_0e2i(tcg_ctx, cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc);  break;\
1858     case  7: gen_helper_0e2i(tcg_ctx, cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc);  break;\
1859     case  8: gen_helper_0e2i(tcg_ctx, cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc);   break;\
1860     case  9: gen_helper_0e2i(tcg_ctx, cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1861     case 10: gen_helper_0e2i(tcg_ctx, cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc);  break;\
1862     case 11: gen_helper_0e2i(tcg_ctx, cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc);  break;\
1863     case 12: gen_helper_0e2i(tcg_ctx, cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc);   break;\
1864     case 13: gen_helper_0e2i(tcg_ctx, cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc);  break;\
1865     case 14: gen_helper_0e2i(tcg_ctx, cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc);   break;\
1866     case 15: gen_helper_0e2i(tcg_ctx, cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc);  break;\
1867     default: abort();                                                         \
1868     }                                                                         \
1869     tcg_temp_free_i##bits (tcg_ctx, fp0);                                              \
1870     tcg_temp_free_i##bits (tcg_ctx, fp1);                                              \
1871 }
1872 
1873 FOP_CONDS(, 0, d, FMT_D, 64)
1874 FOP_CONDS(abs, 1, d, FMT_D, 64)
1875 FOP_CONDS(, 0, s, FMT_S, 32)
1876 FOP_CONDS(abs, 1, s, FMT_S, 32)
1877 FOP_CONDS(, 0, ps, FMT_PS, 64)
1878 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1879 #undef FOP_CONDS
1880 
1881 #define FOP_CONDNS(fmt, ifmt, bits, STORE)                              \
1882 static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n,        \
1883                                       int ft, int fs, int fd)           \
1884 {                                                                       \
1885     TCGContext *tcg_ctx = ctx->uc->tcg_ctx; \
1886     TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(tcg_ctx);                      \
1887     TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(tcg_ctx);                      \
1888     switch (ifmt) {                                                     \
1889     default: break; \
1890     case FMT_D:                                                         \
1891         check_cp1_registers(ctx, fs | ft | fd);                         \
1892         break;                                                          \
1893     }                                                                   \
1894     gen_ldcmp_fpr ## bits(ctx, fp0, fs);                                \
1895     gen_ldcmp_fpr ## bits(ctx, fp1, ft);                                \
1896     switch (n) {                                                        \
1897     case  0:                                                            \
1898         gen_helper_r6_cmp_ ## fmt ## _af(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);       \
1899         break;                                                          \
1900     case  1:                                                            \
1901         gen_helper_r6_cmp_ ## fmt ## _un(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);       \
1902         break;                                                          \
1903     case  2:                                                            \
1904         gen_helper_r6_cmp_ ## fmt ## _eq(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);       \
1905         break;                                                          \
1906     case  3:                                                            \
1907         gen_helper_r6_cmp_ ## fmt ## _ueq(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);      \
1908         break;                                                          \
1909     case  4:                                                            \
1910         gen_helper_r6_cmp_ ## fmt ## _lt(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);       \
1911         break;                                                          \
1912     case  5:                                                            \
1913         gen_helper_r6_cmp_ ## fmt ## _ult(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);      \
1914         break;                                                          \
1915     case  6:                                                            \
1916         gen_helper_r6_cmp_ ## fmt ## _le(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);       \
1917         break;                                                          \
1918     case  7:                                                            \
1919         gen_helper_r6_cmp_ ## fmt ## _ule(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);      \
1920         break;                                                          \
1921     case  8:                                                            \
1922         gen_helper_r6_cmp_ ## fmt ## _saf(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);      \
1923         break;                                                          \
1924     case  9:                                                            \
1925         gen_helper_r6_cmp_ ## fmt ## _sun(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);      \
1926         break;                                                          \
1927     case 10:                                                            \
1928         gen_helper_r6_cmp_ ## fmt ## _seq(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);      \
1929         break;                                                          \
1930     case 11:                                                            \
1931         gen_helper_r6_cmp_ ## fmt ## _sueq(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);     \
1932         break;                                                          \
1933     case 12:                                                            \
1934         gen_helper_r6_cmp_ ## fmt ## _slt(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);      \
1935         break;                                                          \
1936     case 13:                                                            \
1937         gen_helper_r6_cmp_ ## fmt ## _sult(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);     \
1938         break;                                                          \
1939     case 14:                                                            \
1940         gen_helper_r6_cmp_ ## fmt ## _sle(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);      \
1941         break;                                                          \
1942     case 15:                                                            \
1943         gen_helper_r6_cmp_ ## fmt ## _sule(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);     \
1944         break;                                                          \
1945     case 17:                                                            \
1946         gen_helper_r6_cmp_ ## fmt ## _or(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);       \
1947         break;                                                          \
1948     case 18:                                                            \
1949         gen_helper_r6_cmp_ ## fmt ## _une(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);      \
1950         break;                                                          \
1951     case 19:                                                            \
1952         gen_helper_r6_cmp_ ## fmt ## _ne(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);       \
1953         break;                                                          \
1954     case 25:                                                            \
1955         gen_helper_r6_cmp_ ## fmt ## _sor(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);      \
1956         break;                                                          \
1957     case 26:                                                            \
1958         gen_helper_r6_cmp_ ## fmt ## _sune(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);     \
1959         break;                                                          \
1960     case 27:                                                            \
1961         gen_helper_r6_cmp_ ## fmt ## _sne(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);      \
1962         break;                                                          \
1963     default:                                                            \
1964         abort();                                                        \
1965     }                                                                   \
1966     STORE;                                                              \
1967     tcg_temp_free_i ## bits (tcg_ctx, fp0);                                      \
1968     tcg_temp_free_i ## bits (tcg_ctx, fp1);                                      \
1969 }
1970 
1971 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
1972 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
1973 #undef FOP_CONDNS
1974 #undef gen_ldcmp_fpr32
1975 #undef gen_ldcmp_fpr64
1976 
1977 /* load/store instructions. */
1978 #ifdef CONFIG_USER_ONLY
1979 #define OP_LD_ATOMIC(insn,fname)                                           \
1980 static inline void op_ld_##insn(TCGContext *tcg_ctx, TCGv ret, TCGv arg1, DisasContext *ctx)    \
1981 {                                                                          \
1982     TCGv t0 = tcg_temp_new(tcg_ctx);                                              \
1983     tcg_gen_mov_tl(tcg_ctx, t0, arg1);                                              \
1984     tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
1985     tcg_gen_st_tl(tcg_ctx, t0, tcg_ctx->cpu_env, offsetof(CPUMIPSState, lladdr));                \
1986     tcg_gen_st_tl(tcg_ctx, ret, tcg_ctx->cpu_env, offsetof(CPUMIPSState, llval));                \
1987     tcg_temp_free(tcg_ctx, t0);                                                     \
1988 }
1989 #else
1990 #define OP_LD_ATOMIC(insn,fname)                                           \
1991 static inline void op_ld_##insn(TCGContext *tcg_ctx, TCGv ret, TCGv arg1, DisasContext *ctx)    \
1992 {                                                                          \
1993     gen_helper_1e1i(tcg_ctx, insn, ret, arg1, ctx->mem_idx);                        \
1994 }
1995 #endif
1996 OP_LD_ATOMIC(ll,ld32s);
1997 #if defined(TARGET_MIPS64)
1998 OP_LD_ATOMIC(lld,ld64);
1999 #endif
2000 #undef OP_LD_ATOMIC
2001 
2002 #ifdef CONFIG_USER_ONLY
2003 #define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
2004 static inline void op_st_##insn(DisasContext *s, TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
2005 {                                                                            \
2006     TCGContext *tcg_ctx = s->uc->tcg_ctx; \
2007     TCGv t0 = tcg_temp_new(tcg_ctx);                                                \
2008     int l1 = gen_new_label(tcg_ctx);                                                \
2009     int l2 = gen_new_label(tcg_ctx);                                                \
2010                                                                              \
2011     tcg_gen_andi_tl(tcg_ctx, t0, arg2, almask);                                       \
2012     tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_EQ, t0, 0, l1);                              \
2013     tcg_gen_st_tl(tcg_ctx, arg2, tcg_ctx->cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));          \
2014     generate_exception(ctx, EXCP_AdES);                                      \
2015     gen_set_label(tcg_ctx, l1);                                                       \
2016     tcg_gen_ld_tl(tcg_ctx, t0, tcg_ctx->cpu_env, offsetof(CPUMIPSState, lladdr));                  \
2017     tcg_gen_brcond_tl(tcg_ctx, TCG_COND_NE, arg2, t0, l2);                            \
2018     tcg_gen_movi_tl(tcg_ctx, t0, rt | ((almask << 3) & 0x20));                        \
2019     tcg_gen_st_tl(tcg_ctx, t0, tcg_ctx->cpu_env, offsetof(CPUMIPSState, llreg));                   \
2020     tcg_gen_st_tl(tcg_ctx, arg1, tcg_ctx->cpu_env, offsetof(CPUMIPSState, llnewval));              \
2021     gen_helper_0e0i(tcg_ctx, raise_exception, EXCP_SC);                               \
2022     gen_set_label(tcg_ctx, l2);                                                       \
2023     tcg_gen_movi_tl(tcg_ctx, t0, 0);                                                  \
2024     gen_store_gpr(tcg_ctx, t0, rt);                                                   \
2025     tcg_temp_free(tcg_ctx, t0);                                                       \
2026 }
2027 #else
2028 #define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
2029 static inline void op_st_##insn(TCGContext *tcg_ctx, TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
2030 {                                                                            \
2031     TCGv t0 = tcg_temp_new(tcg_ctx);                                                \
2032     gen_helper_1e2i(tcg_ctx, insn, t0, arg1, arg2, ctx->mem_idx);                     \
2033     gen_store_gpr(tcg_ctx, t0, rt);                                                   \
2034     tcg_temp_free(tcg_ctx, t0);                                                       \
2035 }
2036 #endif
2037 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
2038 #if defined(TARGET_MIPS64)
2039 OP_ST_ATOMIC(scd,st64,ld64,0x7);
2040 #endif
2041 #undef OP_ST_ATOMIC
2042 
gen_base_offset_addr(DisasContext * ctx,TCGv addr,int base,int16_t offset)2043 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
2044                                   int base, int16_t offset)
2045 {
2046     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
2047     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
2048     if (base == 0) {
2049         tcg_gen_movi_tl(tcg_ctx, addr, offset);
2050     } else if (offset == 0) {
2051         gen_load_gpr(ctx, addr, base);
2052     } else {
2053         tcg_gen_movi_tl(tcg_ctx, addr, offset);
2054         gen_op_addr_add(ctx, addr, *cpu_gpr[base], addr);
2055     }
2056 }
2057 
pc_relative_pc(DisasContext * ctx)2058 static target_ulong pc_relative_pc (DisasContext *ctx)
2059 {
2060     target_ulong pc = ctx->pc;
2061 
2062     if (ctx->hflags & MIPS_HFLAG_BMASK) {
2063         int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2064 
2065         pc -= branch_bytes;
2066     }
2067 
2068     pc &= ~(target_ulong)3;
2069     return pc;
2070 }
2071 
2072 /* Load */
gen_ld(DisasContext * ctx,uint32_t opc,int rt,int base,int16_t offset)2073 static void gen_ld(DisasContext *ctx, uint32_t opc,
2074                    int rt, int base, int16_t offset)
2075 {
2076     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
2077     const char *opn = "ld";
2078     TCGv t0, t1, t2;
2079 
2080     if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
2081         /* Loongson CPU uses a load to zero register for prefetch.
2082            We emulate it as a NOP. On other CPU we must perform the
2083            actual memory access. */
2084         MIPS_DEBUG("NOP");
2085         return;
2086     }
2087 
2088     t0 = tcg_temp_new(tcg_ctx);
2089     gen_base_offset_addr(ctx, t0, base, offset);
2090 
2091     switch (opc) {
2092 #if defined(TARGET_MIPS64)
2093     case OPC_LWU:
2094         tcg_gen_qemu_ld_tl(ctx->uc, t0, t0, ctx->mem_idx, MO_TEUL);
2095         gen_store_gpr(tcg_ctx, t0, rt);
2096         opn = "lwu";
2097         break;
2098     case OPC_LD:
2099         tcg_gen_qemu_ld_tl(ctx->uc, t0, t0, ctx->mem_idx, MO_TEQ);
2100         gen_store_gpr(tcg_ctx, t0, rt);
2101         opn = "ld";
2102         break;
2103     case OPC_LLD:
2104     case R6_OPC_LLD:
2105         save_cpu_state(ctx, 1);
2106         op_ld_lld(tcg_ctx, t0, t0, ctx);
2107         gen_store_gpr(tcg_ctx, t0, rt);
2108         opn = "lld";
2109         break;
2110     case OPC_LDL:
2111         t1 = tcg_temp_new(tcg_ctx);
2112         tcg_gen_andi_tl(tcg_ctx, t1, t0, 7);
2113 #ifndef TARGET_WORDS_BIGENDIAN
2114         tcg_gen_xori_tl(tcg_ctx, t1, t1, 7);
2115 #endif
2116         tcg_gen_shli_tl(tcg_ctx, t1, t1, 3);
2117         tcg_gen_andi_tl(tcg_ctx, t0, t0, ~7);
2118         tcg_gen_qemu_ld_tl(ctx->uc, t0, t0, ctx->mem_idx, MO_TEQ);
2119         tcg_gen_shl_tl(tcg_ctx, t0, t0, t1);
2120         tcg_gen_xori_tl(tcg_ctx, t1, t1, 63);
2121         t2 = tcg_const_tl(tcg_ctx, 0x7fffffffffffffffull);
2122         tcg_gen_shr_tl(tcg_ctx, t2, t2, t1);
2123         gen_load_gpr(ctx, t1, rt);
2124         tcg_gen_and_tl(tcg_ctx, t1, t1, t2);
2125         tcg_temp_free(tcg_ctx, t2);
2126         tcg_gen_or_tl(tcg_ctx, t0, t0, t1);
2127         tcg_temp_free(tcg_ctx, t1);
2128         gen_store_gpr(tcg_ctx, t0, rt);
2129         opn = "ldl";
2130         break;
2131     case OPC_LDR:
2132         t1 = tcg_temp_new(tcg_ctx);
2133         tcg_gen_andi_tl(tcg_ctx, t1, t0, 7);
2134 #ifdef TARGET_WORDS_BIGENDIAN
2135         tcg_gen_xori_tl(tcg_ctx, t1, t1, 7);
2136 #endif
2137         tcg_gen_shli_tl(tcg_ctx, t1, t1, 3);
2138         tcg_gen_andi_tl(tcg_ctx, t0, t0, ~7);
2139         tcg_gen_qemu_ld_tl(ctx->uc, t0, t0, ctx->mem_idx, MO_TEQ);
2140         tcg_gen_shr_tl(tcg_ctx, t0, t0, t1);
2141         tcg_gen_xori_tl(tcg_ctx, t1, t1, 63);
2142         t2 = tcg_const_tl(tcg_ctx, 0xfffffffffffffffeull);
2143         tcg_gen_shl_tl(tcg_ctx, t2, t2, t1);
2144         gen_load_gpr(ctx, t1, rt);
2145         tcg_gen_and_tl(tcg_ctx, t1, t1, t2);
2146         tcg_temp_free(tcg_ctx, t2);
2147         tcg_gen_or_tl(tcg_ctx, t0, t0, t1);
2148         tcg_temp_free(tcg_ctx, t1);
2149         gen_store_gpr(tcg_ctx, t0, rt);
2150         opn = "ldr";
2151         break;
2152     case OPC_LDPC:
2153         t1 = tcg_const_tl(tcg_ctx, pc_relative_pc(ctx));
2154         gen_op_addr_add(ctx, t0, t0, t1);
2155         tcg_temp_free(tcg_ctx, t1);
2156         tcg_gen_qemu_ld_tl(ctx->uc, t0, t0, ctx->mem_idx, MO_TEQ);
2157         gen_store_gpr(tcg_ctx, t0, rt);
2158         opn = "ldpc";
2159         break;
2160 #endif
2161     case OPC_LWPC:
2162         t1 = tcg_const_tl(tcg_ctx, pc_relative_pc(ctx));
2163         gen_op_addr_add(ctx, t0, t0, t1);
2164         tcg_temp_free(tcg_ctx, t1);
2165         tcg_gen_qemu_ld_tl(ctx->uc, t0, t0, ctx->mem_idx, MO_TESL);
2166         gen_store_gpr(tcg_ctx, t0, rt);
2167         opn = "lwpc";
2168         break;
2169     case OPC_LW:
2170         tcg_gen_qemu_ld_tl(ctx->uc, t0, t0, ctx->mem_idx, MO_TESL);
2171         gen_store_gpr(tcg_ctx, t0, rt);
2172         opn = "lw";
2173         break;
2174     case OPC_LH:
2175         tcg_gen_qemu_ld_tl(ctx->uc, t0, t0, ctx->mem_idx, MO_TESW);
2176         gen_store_gpr(tcg_ctx, t0, rt);
2177         opn = "lh";
2178         break;
2179     case OPC_LHU:
2180         tcg_gen_qemu_ld_tl(ctx->uc, t0, t0, ctx->mem_idx, MO_TEUW);
2181         gen_store_gpr(tcg_ctx, t0, rt);
2182         opn = "lhu";
2183         break;
2184     case OPC_LB:
2185         tcg_gen_qemu_ld_tl(ctx->uc, t0, t0, ctx->mem_idx, MO_SB);
2186         gen_store_gpr(tcg_ctx, t0, rt);
2187         opn = "lb";
2188         break;
2189     case OPC_LBU:
2190         tcg_gen_qemu_ld_tl(ctx->uc, t0, t0, ctx->mem_idx, MO_UB);
2191         gen_store_gpr(tcg_ctx, t0, rt);
2192         opn = "lbu";
2193         break;
2194     case OPC_LWL:
2195         t1 = tcg_temp_new(tcg_ctx);
2196         tcg_gen_andi_tl(tcg_ctx, t1, t0, 3);
2197 #ifndef TARGET_WORDS_BIGENDIAN
2198         tcg_gen_xori_tl(tcg_ctx, t1, t1, 3);
2199 #endif
2200         tcg_gen_shli_tl(tcg_ctx, t1, t1, 3);
2201         tcg_gen_andi_tl(tcg_ctx, t0, t0, ~3);
2202         tcg_gen_qemu_ld_tl(ctx->uc, t0, t0, ctx->mem_idx, MO_TEUL);
2203         tcg_gen_shl_tl(tcg_ctx, t0, t0, t1);
2204         tcg_gen_xori_tl(tcg_ctx, t1, t1, 31);
2205         t2 = tcg_const_tl(tcg_ctx, 0x7fffffffull);
2206         tcg_gen_shr_tl(tcg_ctx, t2, t2, t1);
2207         gen_load_gpr(ctx, t1, rt);
2208         tcg_gen_and_tl(tcg_ctx, t1, t1, t2);
2209         tcg_temp_free(tcg_ctx, t2);
2210         tcg_gen_or_tl(tcg_ctx, t0, t0, t1);
2211         tcg_temp_free(tcg_ctx, t1);
2212         tcg_gen_ext32s_tl(tcg_ctx, t0, t0);
2213         gen_store_gpr(tcg_ctx, t0, rt);
2214         opn = "lwl";
2215         break;
2216     case OPC_LWR:
2217         t1 = tcg_temp_new(tcg_ctx);
2218         tcg_gen_andi_tl(tcg_ctx, t1, t0, 3);
2219 #ifdef TARGET_WORDS_BIGENDIAN
2220         tcg_gen_xori_tl(tcg_ctx, t1, t1, 3);
2221 #endif
2222         tcg_gen_shli_tl(tcg_ctx, t1, t1, 3);
2223         tcg_gen_andi_tl(tcg_ctx, t0, t0, ~3);
2224         tcg_gen_qemu_ld_tl(ctx->uc, t0, t0, ctx->mem_idx, MO_TEUL);
2225         tcg_gen_shr_tl(tcg_ctx, t0, t0, t1);
2226         tcg_gen_xori_tl(tcg_ctx, t1, t1, 31);
2227         t2 = tcg_const_tl(tcg_ctx, 0xfffffffeull);
2228         tcg_gen_shl_tl(tcg_ctx, t2, t2, t1);
2229         gen_load_gpr(ctx, t1, rt);
2230         tcg_gen_and_tl(tcg_ctx, t1, t1, t2);
2231         tcg_temp_free(tcg_ctx, t2);
2232         tcg_gen_or_tl(tcg_ctx, t0, t0, t1);
2233         tcg_temp_free(tcg_ctx, t1);
2234         tcg_gen_ext32s_tl(tcg_ctx, t0, t0);
2235         gen_store_gpr(tcg_ctx, t0, rt);
2236         opn = "lwr";
2237         break;
2238     case OPC_LL:
2239     case R6_OPC_LL:
2240         save_cpu_state(ctx, 1);
2241         op_ld_ll(tcg_ctx, t0, t0, ctx);
2242         gen_store_gpr(tcg_ctx, t0, rt);
2243         opn = "ll";
2244         break;
2245     }
2246     (void)opn; /* avoid a compiler warning */
2247     MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
2248     tcg_temp_free(tcg_ctx, t0);
2249 }
2250 
2251 /* Store */
gen_st(DisasContext * ctx,uint32_t opc,int rt,int base,int16_t offset)2252 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
2253                     int base, int16_t offset)
2254 {
2255     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
2256     const char *opn = "st";
2257     TCGv t0 = tcg_temp_new(tcg_ctx);
2258     TCGv t1 = tcg_temp_new(tcg_ctx);
2259 
2260     gen_base_offset_addr(ctx, t0, base, offset);
2261     gen_load_gpr(ctx, t1, rt);
2262     switch (opc) {
2263 #if defined(TARGET_MIPS64)
2264     case OPC_SD:
2265         tcg_gen_qemu_st_tl(ctx->uc, t1, t0, ctx->mem_idx, MO_TEQ);
2266         opn = "sd";
2267         break;
2268     case OPC_SDL:
2269         save_cpu_state(ctx, 1);
2270         gen_helper_0e2i(tcg_ctx, sdl, t1, t0, ctx->mem_idx);
2271         opn = "sdl";
2272         break;
2273     case OPC_SDR:
2274         save_cpu_state(ctx, 1);
2275         gen_helper_0e2i(tcg_ctx, sdr, t1, t0, ctx->mem_idx);
2276         opn = "sdr";
2277         break;
2278 #endif
2279     case OPC_SW:
2280         tcg_gen_qemu_st_tl(ctx->uc, t1, t0, ctx->mem_idx, MO_TEUL);
2281         opn = "sw";
2282         break;
2283     case OPC_SH:
2284         tcg_gen_qemu_st_tl(ctx->uc, t1, t0, ctx->mem_idx, MO_TEUW);
2285         opn = "sh";
2286         break;
2287     case OPC_SB:
2288         tcg_gen_qemu_st_tl(ctx->uc, t1, t0, ctx->mem_idx, MO_8);
2289         opn = "sb";
2290         break;
2291     case OPC_SWL:
2292         save_cpu_state(ctx, 1);
2293         gen_helper_0e2i(tcg_ctx, swl, t1, t0, ctx->mem_idx);
2294         opn = "swl";
2295         break;
2296     case OPC_SWR:
2297         save_cpu_state(ctx, 1);
2298         gen_helper_0e2i(tcg_ctx, swr, t1, t0, ctx->mem_idx);
2299         opn = "swr";
2300         break;
2301     }
2302     (void)opn; /* avoid a compiler warning */
2303     MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
2304     tcg_temp_free(tcg_ctx, t0);
2305     tcg_temp_free(tcg_ctx, t1);
2306 }
2307 
2308 
2309 /* Store conditional */
gen_st_cond(DisasContext * ctx,uint32_t opc,int rt,int base,int16_t offset)2310 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
2311                          int base, int16_t offset)
2312 {
2313     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
2314     const char *opn = "st_cond";
2315     TCGv t0, t1;
2316 
2317 #ifdef CONFIG_USER_ONLY
2318     t0 = tcg_temp_local_new(tcg_ctx);
2319     t1 = tcg_temp_local_new(tcg_ctx);
2320 #else
2321     t0 = tcg_temp_new(tcg_ctx);
2322     t1 = tcg_temp_new(tcg_ctx);
2323 #endif
2324     gen_base_offset_addr(ctx, t0, base, offset);
2325     gen_load_gpr(ctx, t1, rt);
2326     switch (opc) {
2327 #if defined(TARGET_MIPS64)
2328     case OPC_SCD:
2329     case R6_OPC_SCD:
2330         save_cpu_state(ctx, 1);
2331         op_st_scd(tcg_ctx, t1, t0, rt, ctx);
2332         opn = "scd";
2333         break;
2334 #endif
2335     case OPC_SC:
2336     case R6_OPC_SC:
2337         save_cpu_state(ctx, 1);
2338         op_st_sc(tcg_ctx, t1, t0, rt, ctx);
2339         opn = "sc";
2340         break;
2341     }
2342     (void)opn; /* avoid a compiler warning */
2343     MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
2344     tcg_temp_free(tcg_ctx, t1);
2345     tcg_temp_free(tcg_ctx, t0);
2346 }
2347 
2348 /* Load and store */
gen_flt_ldst(DisasContext * ctx,uint32_t opc,int ft,int base,int16_t offset)2349 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
2350                           int base, int16_t offset)
2351 {
2352     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
2353     const char *opn = "flt_ldst";
2354     TCGv t0 = tcg_temp_new(tcg_ctx);
2355 
2356     gen_base_offset_addr(ctx, t0, base, offset);
2357     /* Don't do NOP if destination is zero: we must perform the actual
2358        memory access. */
2359     switch (opc) {
2360     case OPC_LWC1:
2361         {
2362             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
2363             tcg_gen_qemu_ld_i32(ctx->uc, fp0, t0, ctx->mem_idx, MO_TESL);
2364             gen_store_fpr32(ctx, fp0, ft);
2365             tcg_temp_free_i32(tcg_ctx, fp0);
2366         }
2367         opn = "lwc1";
2368         break;
2369     case OPC_SWC1:
2370         {
2371             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
2372             gen_load_fpr32(ctx, fp0, ft);
2373             tcg_gen_qemu_st_i32(ctx->uc, fp0, t0, ctx->mem_idx, MO_TEUL);
2374             tcg_temp_free_i32(tcg_ctx, fp0);
2375         }
2376         opn = "swc1";
2377         break;
2378     case OPC_LDC1:
2379         {
2380             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
2381             tcg_gen_qemu_ld_i64(ctx->uc, fp0, t0, ctx->mem_idx, MO_TEQ);
2382             gen_store_fpr64(ctx, fp0, ft);
2383             tcg_temp_free_i64(tcg_ctx, fp0);
2384         }
2385         opn = "ldc1";
2386         break;
2387     case OPC_SDC1:
2388         {
2389             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
2390             gen_load_fpr64(ctx, fp0, ft);
2391             tcg_gen_qemu_st_i64(ctx->uc, fp0, t0, ctx->mem_idx, MO_TEQ);
2392             tcg_temp_free_i64(tcg_ctx, fp0);
2393         }
2394         opn = "sdc1";
2395         break;
2396     default:
2397         MIPS_INVAL(opn);
2398         generate_exception(ctx, EXCP_RI);
2399         goto out;
2400     }
2401     (void)opn; /* avoid a compiler warning */
2402     MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
2403  out:
2404     tcg_temp_free(tcg_ctx, t0);
2405 }
2406 
gen_cop1_ldst(DisasContext * ctx,uint32_t op,int rt,int rs,int16_t imm)2407 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2408                           int rs, int16_t imm)
2409 {
2410     if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
2411         check_cp1_enabled(ctx);
2412         gen_flt_ldst(ctx, op, rt, rs, imm);
2413     } else {
2414         generate_exception_err(ctx, EXCP_CpU, 1);
2415     }
2416 }
2417 
2418 /* Arithmetic with immediate operand */
gen_arith_imm(DisasContext * ctx,uint32_t opc,int rt,int rs,int16_t imm)2419 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2420                           int rt, int rs, int16_t imm)
2421 {
2422     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
2423     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
2424     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2425     const char *opn = "imm arith";
2426 
2427     if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
2428         /* If no destination, treat it as a NOP.
2429            For addi, we must generate the overflow exception when needed. */
2430         MIPS_DEBUG("NOP");
2431         return;
2432     }
2433     switch (opc) {
2434     case OPC_ADDI:
2435         {
2436             TCGv t0 = tcg_temp_local_new(tcg_ctx);
2437             TCGv t1 = tcg_temp_new(tcg_ctx);
2438             TCGv t2 = tcg_temp_new(tcg_ctx);
2439             int l1 = gen_new_label(tcg_ctx);
2440 
2441             gen_load_gpr(ctx, t1, rs);
2442             tcg_gen_addi_tl(tcg_ctx, t0, t1, uimm);
2443             tcg_gen_ext32s_tl(tcg_ctx, t0, t0);
2444 
2445             tcg_gen_xori_tl(tcg_ctx, t1, t1, ~uimm);
2446             tcg_gen_xori_tl(tcg_ctx, t2, t0, uimm);
2447             tcg_gen_and_tl(tcg_ctx, t1, t1, t2);
2448             tcg_temp_free(tcg_ctx, t2);
2449             tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_GE, t1, 0, l1);
2450             tcg_temp_free(tcg_ctx, t1);
2451             /* operands of same sign, result different sign */
2452             generate_exception(ctx, EXCP_OVERFLOW);
2453             gen_set_label(tcg_ctx, l1);
2454             tcg_gen_ext32s_tl(tcg_ctx, t0, t0);
2455             gen_store_gpr(tcg_ctx, t0, rt);
2456             tcg_temp_free(tcg_ctx, t0);
2457         }
2458         opn = "addi";
2459         break;
2460     case OPC_ADDIU:
2461         if (rs != 0) {
2462             tcg_gen_addi_tl(tcg_ctx, *cpu_gpr[rt], *cpu_gpr[rs], uimm);
2463             tcg_gen_ext32s_tl(tcg_ctx, *cpu_gpr[rt], *cpu_gpr[rt]);
2464         } else {
2465             tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[rt], uimm);
2466         }
2467         opn = "addiu";
2468         break;
2469 #if defined(TARGET_MIPS64)
2470     case OPC_DADDI:
2471         {
2472             TCGv t0 = tcg_temp_local_new(tcg_ctx);
2473             TCGv t1 = tcg_temp_new(tcg_ctx);
2474             TCGv t2 = tcg_temp_new(tcg_ctx);
2475             int l1 = gen_new_label(tcg_ctx);
2476 
2477             gen_load_gpr(ctx, t1, rs);
2478             tcg_gen_addi_tl(tcg_ctx, t0, t1, uimm);
2479 
2480             tcg_gen_xori_tl(tcg_ctx, t1, t1, ~uimm);
2481             tcg_gen_xori_tl(tcg_ctx, t2, t0, uimm);
2482             tcg_gen_and_tl(tcg_ctx, t1, t1, t2);
2483             tcg_temp_free(tcg_ctx, t2);
2484             tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_GE, t1, 0, l1);
2485             tcg_temp_free(tcg_ctx, t1);
2486             /* operands of same sign, result different sign */
2487             generate_exception(ctx, EXCP_OVERFLOW);
2488             gen_set_label(tcg_ctx, l1);
2489             gen_store_gpr(tcg_ctx, t0, rt);
2490             tcg_temp_free(tcg_ctx, t0);
2491         }
2492         opn = "daddi";
2493         break;
2494     case OPC_DADDIU:
2495         if (rs != 0) {
2496             tcg_gen_addi_tl(tcg_ctx, *cpu_gpr[rt], *cpu_gpr[rs], uimm);
2497         } else {
2498             tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[rt], uimm);
2499         }
2500         opn = "daddiu";
2501         break;
2502 #endif
2503     }
2504     (void)opn; /* avoid a compiler warning */
2505     MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2506 }
2507 
2508 /* Logic with immediate operand */
gen_logic_imm(DisasContext * ctx,uint32_t opc,int rt,int rs,int16_t imm)2509 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2510                           int rt, int rs, int16_t imm)
2511 {
2512     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
2513     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
2514     target_ulong uimm;
2515 
2516     if (rt == 0) {
2517         /* If no destination, treat it as a NOP. */
2518         MIPS_DEBUG("NOP");
2519         return;
2520     }
2521     uimm = (uint16_t)imm;
2522     switch (opc) {
2523     case OPC_ANDI:
2524         if (likely(rs != 0))
2525             tcg_gen_andi_tl(tcg_ctx, *cpu_gpr[rt], *cpu_gpr[rs], uimm);
2526         else
2527             tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[rt], 0);
2528         MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx, regnames[rt],
2529                    regnames[rs], uimm);
2530         break;
2531     case OPC_ORI:
2532         if (rs != 0)
2533             tcg_gen_ori_tl(tcg_ctx, *cpu_gpr[rt], *cpu_gpr[rs], uimm);
2534         else
2535             tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[rt], uimm);
2536         MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx, regnames[rt],
2537                    regnames[rs], uimm);
2538         break;
2539     case OPC_XORI:
2540         if (likely(rs != 0))
2541             tcg_gen_xori_tl(tcg_ctx, *cpu_gpr[rt], *cpu_gpr[rs], uimm);
2542         else
2543             tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[rt], uimm);
2544         MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx, regnames[rt],
2545                    regnames[rs], uimm);
2546         break;
2547     case OPC_LUI:
2548         if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
2549             /* OPC_AUI */
2550             tcg_gen_addi_tl(tcg_ctx, *cpu_gpr[rt], *cpu_gpr[rs], uimm << 16);
2551             tcg_gen_ext32s_tl(tcg_ctx, *cpu_gpr[rt], *cpu_gpr[rt]);
2552             MIPS_DEBUG("aui %s, %s, %04x", regnames[rt], regnames[rs], imm);
2553         } else {
2554             tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[rt], uimm << 16);
2555             MIPS_DEBUG("lui %s, " TARGET_FMT_lx, regnames[rt], uimm);
2556         }
2557         break;
2558 
2559     default:
2560         MIPS_DEBUG("Unknown logical immediate opcode %08x", opc);
2561         break;
2562     }
2563 }
2564 
2565 /* Set on less than with immediate operand */
gen_slt_imm(DisasContext * ctx,uint32_t opc,int rt,int rs,int16_t imm)2566 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2567                         int rt, int rs, int16_t imm)
2568 {
2569     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
2570     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
2571     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2572     const char *opn = "imm arith";
2573     TCGv t0;
2574 
2575     if (rt == 0) {
2576         /* If no destination, treat it as a NOP. */
2577         MIPS_DEBUG("NOP");
2578         return;
2579     }
2580     t0 = tcg_temp_new(tcg_ctx);
2581     gen_load_gpr(ctx, t0, rs);
2582     switch (opc) {
2583     case OPC_SLTI:
2584         tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_LT, *cpu_gpr[rt], t0, uimm);
2585         opn = "slti";
2586         break;
2587     case OPC_SLTIU:
2588         tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_LTU, *cpu_gpr[rt], t0, uimm);
2589         opn = "sltiu";
2590         break;
2591     }
2592     (void)opn; /* avoid a compiler warning */
2593     MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2594     tcg_temp_free(tcg_ctx, t0);
2595 }
2596 
2597 /* Shifts with immediate operand */
gen_shift_imm(DisasContext * ctx,uint32_t opc,int rt,int rs,int16_t imm)2598 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2599                           int rt, int rs, int16_t imm)
2600 {
2601     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
2602     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
2603     target_ulong uimm = ((uint16_t)imm) & 0x1f;
2604     const char *opn = "imm shift";
2605     TCGv t0;
2606 
2607     if (rt == 0) {
2608         /* If no destination, treat it as a NOP. */
2609         MIPS_DEBUG("NOP");
2610         return;
2611     }
2612 
2613     t0 = tcg_temp_new(tcg_ctx);
2614     gen_load_gpr(ctx, t0, rs);
2615     switch (opc) {
2616     case OPC_SLL:
2617         tcg_gen_shli_tl(tcg_ctx, t0, t0, uimm);
2618         tcg_gen_ext32s_tl(tcg_ctx, *cpu_gpr[rt], t0);
2619         opn = "sll";
2620         break;
2621     case OPC_SRA:
2622         tcg_gen_sari_tl(tcg_ctx, *cpu_gpr[rt], t0, uimm);
2623         opn = "sra";
2624         break;
2625     case OPC_SRL:
2626         if (uimm != 0) {
2627             tcg_gen_ext32u_tl(tcg_ctx, t0, t0);
2628             tcg_gen_shri_tl(tcg_ctx, *cpu_gpr[rt], t0, uimm);
2629         } else {
2630             tcg_gen_ext32s_tl(tcg_ctx, *cpu_gpr[rt], t0);
2631         }
2632         opn = "srl";
2633         break;
2634     case OPC_ROTR:
2635         if (uimm != 0) {
2636             TCGv_i32 t1 = tcg_temp_new_i32(tcg_ctx);
2637 
2638             tcg_gen_trunc_tl_i32(tcg_ctx, t1, t0);
2639             tcg_gen_rotri_i32(tcg_ctx, t1, t1, uimm);
2640             tcg_gen_ext_i32_tl(tcg_ctx, *cpu_gpr[rt], t1);
2641             tcg_temp_free_i32(tcg_ctx, t1);
2642         } else {
2643             tcg_gen_ext32s_tl(tcg_ctx, *cpu_gpr[rt], t0);
2644         }
2645         opn = "rotr";
2646         break;
2647 #if defined(TARGET_MIPS64)
2648     case OPC_DSLL:
2649         tcg_gen_shli_tl(tcg_ctx, *cpu_gpr[rt], t0, uimm);
2650         opn = "dsll";
2651         break;
2652     case OPC_DSRA:
2653         tcg_gen_sari_tl(tcg_ctx, *cpu_gpr[rt], t0, uimm);
2654         opn = "dsra";
2655         break;
2656     case OPC_DSRL:
2657         tcg_gen_shri_tl(tcg_ctx, *cpu_gpr[rt], t0, uimm);
2658         opn = "dsrl";
2659         break;
2660     case OPC_DROTR:
2661         if (uimm != 0) {
2662             tcg_gen_rotri_tl(tcg_ctx, *cpu_gpr[rt], t0, uimm);
2663         } else {
2664             tcg_gen_mov_tl(tcg_ctx, *cpu_gpr[rt], t0);
2665         }
2666         opn = "drotr";
2667         break;
2668     case OPC_DSLL32:
2669         tcg_gen_shli_tl(tcg_ctx, *cpu_gpr[rt], t0, uimm + 32);
2670         opn = "dsll32";
2671         break;
2672     case OPC_DSRA32:
2673         tcg_gen_sari_tl(tcg_ctx, *cpu_gpr[rt], t0, uimm + 32);
2674         opn = "dsra32";
2675         break;
2676     case OPC_DSRL32:
2677         tcg_gen_shri_tl(tcg_ctx, *cpu_gpr[rt], t0, uimm + 32);
2678         opn = "dsrl32";
2679         break;
2680     case OPC_DROTR32:
2681         tcg_gen_rotri_tl(tcg_ctx, *cpu_gpr[rt], t0, uimm + 32);
2682         opn = "drotr32";
2683         break;
2684 #endif
2685     }
2686     (void)opn; /* avoid a compiler warning */
2687     MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2688     tcg_temp_free(tcg_ctx, t0);
2689 }
2690 
2691 /* Arithmetic */
gen_arith(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)2692 static void gen_arith(DisasContext *ctx, uint32_t opc,
2693                       int rd, int rs, int rt)
2694 {
2695     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
2696     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
2697     const char *opn = "arith";
2698 
2699     if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2700        && opc != OPC_DADD && opc != OPC_DSUB) {
2701         /* If no destination, treat it as a NOP.
2702            For add & sub, we must generate the overflow exception when needed. */
2703         MIPS_DEBUG("NOP");
2704         return;
2705     }
2706 
2707     switch (opc) {
2708     case OPC_ADD:
2709         {
2710             TCGv t0 = tcg_temp_local_new(tcg_ctx);
2711             TCGv t1 = tcg_temp_new(tcg_ctx);
2712             TCGv t2 = tcg_temp_new(tcg_ctx);
2713             int l1 = gen_new_label(tcg_ctx);
2714 
2715             gen_load_gpr(ctx, t1, rs);
2716             gen_load_gpr(ctx, t2, rt);
2717             tcg_gen_add_tl(tcg_ctx, t0, t1, t2);
2718             tcg_gen_ext32s_tl(tcg_ctx, t0, t0);
2719             tcg_gen_xor_tl(tcg_ctx, t1, t1, t2);
2720             tcg_gen_xor_tl(tcg_ctx, t2, t0, t2);
2721             tcg_gen_andc_tl(tcg_ctx, t1, t2, t1);
2722             tcg_temp_free(tcg_ctx, t2);
2723             tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_GE, t1, 0, l1);
2724             tcg_temp_free(tcg_ctx, t1);
2725             /* operands of same sign, result different sign */
2726             generate_exception(ctx, EXCP_OVERFLOW);
2727             gen_set_label(tcg_ctx, l1);
2728             gen_store_gpr(tcg_ctx, t0, rd);
2729             tcg_temp_free(tcg_ctx, t0);
2730         }
2731         opn = "add";
2732         break;
2733     case OPC_ADDU:
2734         if (rs != 0 && rt != 0) {
2735             tcg_gen_add_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rs], *cpu_gpr[rt]);
2736             tcg_gen_ext32s_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rd]);
2737         } else if (rs == 0 && rt != 0) {
2738             tcg_gen_mov_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rt]);
2739         } else if (rs != 0 && rt == 0) {
2740             tcg_gen_mov_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rs]);
2741         } else {
2742             tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[rd], 0);
2743         }
2744         opn = "addu";
2745         break;
2746     case OPC_SUB:
2747         {
2748             TCGv t0 = tcg_temp_local_new(tcg_ctx);
2749             TCGv t1 = tcg_temp_new(tcg_ctx);
2750             TCGv t2 = tcg_temp_new(tcg_ctx);
2751             int l1 = gen_new_label(tcg_ctx);
2752 
2753             gen_load_gpr(ctx, t1, rs);
2754             gen_load_gpr(ctx, t2, rt);
2755             tcg_gen_sub_tl(tcg_ctx, t0, t1, t2);
2756             tcg_gen_ext32s_tl(tcg_ctx, t0, t0);
2757             tcg_gen_xor_tl(tcg_ctx, t2, t1, t2);
2758             tcg_gen_xor_tl(tcg_ctx, t1, t0, t1);
2759             tcg_gen_and_tl(tcg_ctx, t1, t1, t2);
2760             tcg_temp_free(tcg_ctx, t2);
2761             tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_GE, t1, 0, l1);
2762             tcg_temp_free(tcg_ctx, t1);
2763             /* operands of different sign, first operand and result different sign */
2764             generate_exception(ctx, EXCP_OVERFLOW);
2765             gen_set_label(tcg_ctx, l1);
2766             gen_store_gpr(tcg_ctx, t0, rd);
2767             tcg_temp_free(tcg_ctx, t0);
2768         }
2769         opn = "sub";
2770         break;
2771     case OPC_SUBU:
2772         if (rs != 0 && rt != 0) {
2773             tcg_gen_sub_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rs], *cpu_gpr[rt]);
2774             tcg_gen_ext32s_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rd]);
2775         } else if (rs == 0 && rt != 0) {
2776             tcg_gen_neg_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rt]);
2777             tcg_gen_ext32s_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rd]);
2778         } else if (rs != 0 && rt == 0) {
2779             tcg_gen_mov_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rs]);
2780         } else {
2781             tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[rd], 0);
2782         }
2783         opn = "subu";
2784         break;
2785 #if defined(TARGET_MIPS64)
2786     case OPC_DADD:
2787         {
2788             TCGv t0 = tcg_temp_local_new(tcg_ctx);
2789             TCGv t1 = tcg_temp_new(tcg_ctx);
2790             TCGv t2 = tcg_temp_new(tcg_ctx);
2791             int l1 = gen_new_label(tcg_ctx);
2792 
2793             gen_load_gpr(ctx, t1, rs);
2794             gen_load_gpr(ctx, t2, rt);
2795             tcg_gen_add_tl(tcg_ctx, t0, t1, t2);
2796             tcg_gen_xor_tl(tcg_ctx, t1, t1, t2);
2797             tcg_gen_xor_tl(tcg_ctx, t2, t0, t2);
2798             tcg_gen_andc_tl(tcg_ctx, t1, t2, t1);
2799             tcg_temp_free(tcg_ctx, t2);
2800             tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_GE, t1, 0, l1);
2801             tcg_temp_free(tcg_ctx, t1);
2802             /* operands of same sign, result different sign */
2803             generate_exception(ctx, EXCP_OVERFLOW);
2804             gen_set_label(tcg_ctx, l1);
2805             gen_store_gpr(tcg_ctx, t0, rd);
2806             tcg_temp_free(tcg_ctx, t0);
2807         }
2808         opn = "dadd";
2809         break;
2810     case OPC_DADDU:
2811         if (rs != 0 && rt != 0) {
2812             tcg_gen_add_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rs], *cpu_gpr[rt]);
2813         } else if (rs == 0 && rt != 0) {
2814             tcg_gen_mov_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rt]);
2815         } else if (rs != 0 && rt == 0) {
2816             tcg_gen_mov_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rs]);
2817         } else {
2818             tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[rd], 0);
2819         }
2820         opn = "daddu";
2821         break;
2822     case OPC_DSUB:
2823         {
2824             TCGv t0 = tcg_temp_local_new(tcg_ctx);
2825             TCGv t1 = tcg_temp_new(tcg_ctx);
2826             TCGv t2 = tcg_temp_new(tcg_ctx);
2827             int l1 = gen_new_label(tcg_ctx);
2828 
2829             gen_load_gpr(ctx, t1, rs);
2830             gen_load_gpr(ctx, t2, rt);
2831             tcg_gen_sub_tl(tcg_ctx, t0, t1, t2);
2832             tcg_gen_xor_tl(tcg_ctx, t2, t1, t2);
2833             tcg_gen_xor_tl(tcg_ctx, t1, t0, t1);
2834             tcg_gen_and_tl(tcg_ctx, t1, t1, t2);
2835             tcg_temp_free(tcg_ctx, t2);
2836             tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_GE, t1, 0, l1);
2837             tcg_temp_free(tcg_ctx, t1);
2838             /* operands of different sign, first operand and result different sign */
2839             generate_exception(ctx, EXCP_OVERFLOW);
2840             gen_set_label(tcg_ctx, l1);
2841             gen_store_gpr(tcg_ctx, t0, rd);
2842             tcg_temp_free(tcg_ctx, t0);
2843         }
2844         opn = "dsub";
2845         break;
2846     case OPC_DSUBU:
2847         if (rs != 0 && rt != 0) {
2848             tcg_gen_sub_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rs], *cpu_gpr[rt]);
2849         } else if (rs == 0 && rt != 0) {
2850             tcg_gen_neg_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rt]);
2851         } else if (rs != 0 && rt == 0) {
2852             tcg_gen_mov_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rs]);
2853         } else {
2854             tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[rd], 0);
2855         }
2856         opn = "dsubu";
2857         break;
2858 #endif
2859     case OPC_MUL:
2860         if (likely(rs != 0 && rt != 0)) {
2861             tcg_gen_mul_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rs], *cpu_gpr[rt]);
2862             tcg_gen_ext32s_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rd]);
2863         } else {
2864             tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[rd], 0);
2865         }
2866         opn = "mul";
2867         break;
2868     }
2869     (void)opn; /* avoid a compiler warning */
2870     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2871 }
2872 
2873 /* Conditional move */
gen_cond_move(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)2874 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2875                           int rd, int rs, int rt)
2876 {
2877     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
2878     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
2879     const char *opn = "cond move";
2880     TCGv t0, t1, t2;
2881 
2882     if (rd == 0) {
2883         /* If no destination, treat it as a NOP. */
2884         MIPS_DEBUG("NOP");
2885         return;
2886     }
2887 
2888     t0 = tcg_temp_new(tcg_ctx);
2889     gen_load_gpr(ctx, t0, rt);
2890     t1 = tcg_const_tl(tcg_ctx, 0);
2891     t2 = tcg_temp_new(tcg_ctx);
2892     gen_load_gpr(ctx, t2, rs);
2893     switch (opc) {
2894     case OPC_MOVN:
2895         tcg_gen_movcond_tl(tcg_ctx, TCG_COND_NE, *cpu_gpr[rd], t0, t1, t2, *cpu_gpr[rd]);
2896         opn = "movn";
2897         break;
2898     case OPC_MOVZ:
2899         tcg_gen_movcond_tl(tcg_ctx, TCG_COND_EQ, *cpu_gpr[rd], t0, t1, t2, *cpu_gpr[rd]);
2900         opn = "movz";
2901         break;
2902     case OPC_SELNEZ:
2903         tcg_gen_movcond_tl(tcg_ctx, TCG_COND_NE, *cpu_gpr[rd], t0, t1, t2, t1);
2904         opn = "selnez";
2905         break;
2906     case OPC_SELEQZ:
2907         tcg_gen_movcond_tl(tcg_ctx, TCG_COND_EQ, *cpu_gpr[rd], t0, t1, t2, t1);
2908         opn = "seleqz";
2909         break;
2910     }
2911     tcg_temp_free(tcg_ctx, t2);
2912     tcg_temp_free(tcg_ctx, t1);
2913     tcg_temp_free(tcg_ctx, t0);
2914 
2915     (void)opn; /* avoid a compiler warning */
2916     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2917 }
2918 
2919 /* Logic */
gen_logic(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)2920 static void gen_logic(DisasContext *ctx, uint32_t opc,
2921                       int rd, int rs, int rt)
2922 {
2923     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
2924     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
2925     const char *opn = "logic";
2926 
2927     if (rd == 0) {
2928         /* If no destination, treat it as a NOP. */
2929         MIPS_DEBUG("NOP");
2930         return;
2931     }
2932 
2933     switch (opc) {
2934     case OPC_AND:
2935         if (likely(rs != 0 && rt != 0)) {
2936             tcg_gen_and_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rs], *cpu_gpr[rt]);
2937         } else {
2938             tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[rd], 0);
2939         }
2940         opn = "and";
2941         break;
2942     case OPC_NOR:
2943         if (rs != 0 && rt != 0) {
2944             tcg_gen_nor_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rs], *cpu_gpr[rt]);
2945         } else if (rs == 0 && rt != 0) {
2946             tcg_gen_not_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rt]);
2947         } else if (rs != 0 && rt == 0) {
2948             tcg_gen_not_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rs]);
2949         } else {
2950             tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[rd], ~((target_ulong)0));
2951         }
2952         opn = "nor";
2953         break;
2954     case OPC_OR:
2955         if (likely(rs != 0 && rt != 0)) {
2956             tcg_gen_or_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rs], *cpu_gpr[rt]);
2957         } else if (rs == 0 && rt != 0) {
2958             tcg_gen_mov_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rt]);
2959         } else if (rs != 0 && rt == 0) {
2960             tcg_gen_mov_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rs]);
2961         } else {
2962             tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[rd], 0);
2963         }
2964         opn = "or";
2965         break;
2966     case OPC_XOR:
2967         if (likely(rs != 0 && rt != 0)) {
2968             tcg_gen_xor_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rs], *cpu_gpr[rt]);
2969         } else if (rs == 0 && rt != 0) {
2970             tcg_gen_mov_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rt]);
2971         } else if (rs != 0 && rt == 0) {
2972             tcg_gen_mov_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rs]);
2973         } else {
2974             tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[rd], 0);
2975         }
2976         opn = "xor";
2977         break;
2978     }
2979     (void)opn; /* avoid a compiler warning */
2980     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2981 }
2982 
2983 /* Set on lower than */
gen_slt(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)2984 static void gen_slt(DisasContext *ctx, uint32_t opc,
2985                     int rd, int rs, int rt)
2986 {
2987     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
2988     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
2989     const char *opn = "slt";
2990     TCGv t0, t1;
2991 
2992     if (rd == 0) {
2993         /* If no destination, treat it as a NOP. */
2994         MIPS_DEBUG("NOP");
2995         return;
2996     }
2997 
2998     t0 = tcg_temp_new(tcg_ctx);
2999     t1 = tcg_temp_new(tcg_ctx);
3000     gen_load_gpr(ctx, t0, rs);
3001     gen_load_gpr(ctx, t1, rt);
3002     switch (opc) {
3003     case OPC_SLT:
3004         tcg_gen_setcond_tl(tcg_ctx, TCG_COND_LT, *cpu_gpr[rd], t0, t1);
3005         opn = "slt";
3006         break;
3007     case OPC_SLTU:
3008         tcg_gen_setcond_tl(tcg_ctx, TCG_COND_LTU, *cpu_gpr[rd], t0, t1);
3009         opn = "sltu";
3010         break;
3011     }
3012     (void)opn; /* avoid a compiler warning */
3013     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
3014     tcg_temp_free(tcg_ctx, t0);
3015     tcg_temp_free(tcg_ctx, t1);
3016 }
3017 
3018 /* Shifts */
gen_shift(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)3019 static void gen_shift(DisasContext *ctx, uint32_t opc,
3020                       int rd, int rs, int rt)
3021 {
3022     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
3023     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
3024     const char *opn = "shifts";
3025     TCGv t0, t1;
3026 
3027     if (rd == 0) {
3028         /* If no destination, treat it as a NOP.
3029            For add & sub, we must generate the overflow exception when needed. */
3030         MIPS_DEBUG("NOP");
3031         return;
3032     }
3033 
3034     t0 = tcg_temp_new(tcg_ctx);
3035     t1 = tcg_temp_new(tcg_ctx);
3036     gen_load_gpr(ctx, t0, rs);
3037     gen_load_gpr(ctx, t1, rt);
3038     switch (opc) {
3039     case OPC_SLLV:
3040         tcg_gen_andi_tl(tcg_ctx, t0, t0, 0x1f);
3041         tcg_gen_shl_tl(tcg_ctx, t0, t1, t0);
3042         tcg_gen_ext32s_tl(tcg_ctx, *cpu_gpr[rd], t0);
3043         opn = "sllv";
3044         break;
3045     case OPC_SRAV:
3046         tcg_gen_andi_tl(tcg_ctx, t0, t0, 0x1f);
3047         tcg_gen_sar_tl(tcg_ctx, *cpu_gpr[rd], t1, t0);
3048         opn = "srav";
3049         break;
3050     case OPC_SRLV:
3051         tcg_gen_ext32u_tl(tcg_ctx, t1, t1);
3052         tcg_gen_andi_tl(tcg_ctx, t0, t0, 0x1f);
3053         tcg_gen_shr_tl(tcg_ctx, t0, t1, t0);
3054         tcg_gen_ext32s_tl(tcg_ctx, *cpu_gpr[rd], t0);
3055         opn = "srlv";
3056         break;
3057     case OPC_ROTRV:
3058         {
3059             TCGv_i32 t2 = tcg_temp_new_i32(tcg_ctx);
3060             TCGv_i32 t3 = tcg_temp_new_i32(tcg_ctx);
3061 
3062             tcg_gen_trunc_tl_i32(tcg_ctx, t2, t0);
3063             tcg_gen_trunc_tl_i32(tcg_ctx, t3, t1);
3064             tcg_gen_andi_i32(tcg_ctx, t2, t2, 0x1f);
3065             tcg_gen_rotr_i32(tcg_ctx, t2, t3, t2);
3066             tcg_gen_ext_i32_tl(tcg_ctx, *cpu_gpr[rd], t2);
3067             tcg_temp_free_i32(tcg_ctx, t2);
3068             tcg_temp_free_i32(tcg_ctx, t3);
3069             opn = "rotrv";
3070         }
3071         break;
3072 #if defined(TARGET_MIPS64)
3073     case OPC_DSLLV:
3074         tcg_gen_andi_tl(tcg_ctx, t0, t0, 0x3f);
3075         tcg_gen_shl_tl(tcg_ctx, *cpu_gpr[rd], t1, t0);
3076         opn = "dsllv";
3077         break;
3078     case OPC_DSRAV:
3079         tcg_gen_andi_tl(tcg_ctx, t0, t0, 0x3f);
3080         tcg_gen_sar_tl(tcg_ctx, *cpu_gpr[rd], t1, t0);
3081         opn = "dsrav";
3082         break;
3083     case OPC_DSRLV:
3084         tcg_gen_andi_tl(tcg_ctx, t0, t0, 0x3f);
3085         tcg_gen_shr_tl(tcg_ctx, *cpu_gpr[rd], t1, t0);
3086         opn = "dsrlv";
3087         break;
3088     case OPC_DROTRV:
3089         tcg_gen_andi_tl(tcg_ctx, t0, t0, 0x3f);
3090         tcg_gen_rotr_tl(tcg_ctx, *cpu_gpr[rd], t1, t0);
3091         opn = "drotrv";
3092         break;
3093 #endif
3094     }
3095     (void)opn; /* avoid a compiler warning */
3096     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
3097     tcg_temp_free(tcg_ctx, t0);
3098     tcg_temp_free(tcg_ctx, t1);
3099 }
3100 
3101 /* Arithmetic on HI/LO registers */
gen_HILO(DisasContext * ctx,uint32_t opc,int acc,int reg)3102 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
3103 {
3104     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
3105     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
3106     TCGv **cpu_HI = (TCGv **)tcg_ctx->cpu_HI;
3107     TCGv **cpu_LO = (TCGv **)tcg_ctx->cpu_LO;
3108     const char *opn = "hilo";
3109 
3110     if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
3111         /* Treat as NOP. */
3112         MIPS_DEBUG("NOP");
3113         return;
3114     }
3115 
3116     if (acc != 0) {
3117         check_dsp(ctx);
3118     }
3119 
3120     switch (opc) {
3121     case OPC_MFHI:
3122 #if defined(TARGET_MIPS64)
3123         if (acc != 0) {
3124             tcg_gen_ext32s_tl(tcg_ctx, *cpu_gpr[reg], *cpu_HI[acc]);
3125         } else
3126 #endif
3127         {
3128             tcg_gen_mov_tl(tcg_ctx, *cpu_gpr[reg], *cpu_HI[acc]);
3129         }
3130         opn = "mfhi";
3131         break;
3132     case OPC_MFLO:
3133 #if defined(TARGET_MIPS64)
3134         if (acc != 0) {
3135             tcg_gen_ext32s_tl(tcg_ctx, *cpu_gpr[reg], *cpu_LO[acc]);
3136         } else
3137 #endif
3138         {
3139             tcg_gen_mov_tl(tcg_ctx, *cpu_gpr[reg], *cpu_LO[acc]);
3140         }
3141         opn = "mflo";
3142         break;
3143     case OPC_MTHI:
3144         if (reg != 0) {
3145 #if defined(TARGET_MIPS64)
3146             if (acc != 0) {
3147                 tcg_gen_ext32s_tl(tcg_ctx, *cpu_HI[acc], *cpu_gpr[reg]);
3148             } else
3149 #endif
3150             {
3151                 tcg_gen_mov_tl(tcg_ctx, *cpu_HI[acc], *cpu_gpr[reg]);
3152             }
3153         } else {
3154             tcg_gen_movi_tl(tcg_ctx, *cpu_HI[acc], 0);
3155         }
3156         opn = "mthi";
3157         break;
3158     case OPC_MTLO:
3159         if (reg != 0) {
3160 #if defined(TARGET_MIPS64)
3161             if (acc != 0) {
3162                 tcg_gen_ext32s_tl(tcg_ctx, *cpu_LO[acc], *cpu_gpr[reg]);
3163             } else
3164 #endif
3165             {
3166                 tcg_gen_mov_tl(tcg_ctx, *cpu_LO[acc], *cpu_gpr[reg]);
3167             }
3168         } else {
3169             tcg_gen_movi_tl(tcg_ctx, *cpu_LO[acc], 0);
3170         }
3171         opn = "mtlo";
3172         break;
3173     }
3174     (void)opn; /* avoid a compiler warning */
3175     MIPS_DEBUG("%s %s", opn, regnames[reg]);
3176 }
3177 
gen_r6_ld(DisasContext * ctx,target_long addr,int reg,int memidx,TCGMemOp memop)3178 static inline void gen_r6_ld(DisasContext *ctx, target_long addr, int reg, int memidx,
3179                              TCGMemOp memop)
3180 {
3181     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
3182     TCGv t0 = tcg_const_tl(tcg_ctx, addr);
3183     tcg_gen_qemu_ld_tl(ctx->uc, t0, t0, memidx, memop);
3184     gen_store_gpr(tcg_ctx, t0, reg);
3185     tcg_temp_free(tcg_ctx, t0);
3186 }
3187 
gen_pcrel(DisasContext * ctx,int rs,int16_t imm)3188 static inline void gen_pcrel(DisasContext *ctx, int rs, int16_t imm)
3189 {
3190     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
3191     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
3192     target_long offset;
3193     target_long addr;
3194 
3195     switch (MASK_OPC_PCREL_TOP2BITS(ctx->opcode)) {
3196     case OPC_ADDIUPC:
3197         if (rs != 0) {
3198             offset = sextract32(ctx->opcode << 2, 0, 21);
3199             addr = addr_add(ctx, ctx->pc, offset);
3200             tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[rs], addr);
3201         }
3202         break;
3203     case R6_OPC_LWPC:
3204         offset = sextract32(ctx->opcode << 2, 0, 21);
3205         addr = addr_add(ctx, ctx->pc, offset);
3206         gen_r6_ld(ctx, addr, rs, ctx->mem_idx, MO_TESL);
3207         break;
3208 #if defined(TARGET_MIPS64)
3209     case OPC_LWUPC:
3210         check_mips_64(ctx);
3211         offset = sextract32(ctx->opcode << 2, 0, 21);
3212         addr = addr_add(ctx, ctx->pc, offset);
3213         gen_r6_ld(ctx, addr, rs, ctx->mem_idx, MO_TEUL);
3214         break;
3215 #endif
3216     default:
3217         switch (MASK_OPC_PCREL_TOP5BITS(ctx->opcode)) {
3218         case OPC_AUIPC:
3219             if (rs != 0) {
3220                 offset = ((target_ulong)imm) << 16;
3221                 addr = addr_add(ctx, ctx->pc, offset);
3222                 tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[rs], addr);
3223             }
3224             break;
3225         case OPC_ALUIPC:
3226             if (rs != 0) {
3227                 offset = ((target_ulong)imm) << 16;
3228                 addr = ~0xFFFF & addr_add(ctx, ctx->pc, offset);
3229                 tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[rs], addr);
3230             }
3231             break;
3232 #if defined(TARGET_MIPS64)
3233         case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3234         case R6_OPC_LDPC + (1 << 16):
3235         case R6_OPC_LDPC + (2 << 16):
3236         case R6_OPC_LDPC + (3 << 16):
3237             check_mips_64(ctx);
3238             offset = sextract32(ctx->opcode << 3, 0, 21);
3239             addr = addr_add(ctx, (ctx->pc & ~0x7), offset);
3240             gen_r6_ld(ctx, addr, rs, ctx->mem_idx, MO_TEQ);
3241             break;
3242 #endif
3243         default:
3244             MIPS_INVAL("OPC_PCREL");
3245             generate_exception(ctx, EXCP_RI);
3246             break;
3247         }
3248         break;
3249     }
3250 }
3251 
gen_r6_muldiv(DisasContext * ctx,int opc,int rd,int rs,int rt)3252 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3253 {
3254     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
3255     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
3256     const char *opn = "r6 mul/div";
3257     TCGv t0, t1;
3258 
3259     if (rd == 0) {
3260         /* Treat as NOP. */
3261         MIPS_DEBUG("NOP");
3262         return;
3263     }
3264 
3265     t0 = tcg_temp_new(tcg_ctx);
3266     t1 = tcg_temp_new(tcg_ctx);
3267 
3268     gen_load_gpr(ctx, t0, rs);
3269     gen_load_gpr(ctx, t1, rt);
3270 
3271     switch (opc) {
3272     case R6_OPC_DIV:
3273         {
3274             TCGv t2 = tcg_temp_new(tcg_ctx);
3275             TCGv t3 = tcg_temp_new(tcg_ctx);
3276             tcg_gen_ext32s_tl(tcg_ctx, t0, t0);
3277             tcg_gen_ext32s_tl(tcg_ctx, t1, t1);
3278             tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_EQ, t2, t0, INT_MIN);
3279             tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_EQ, t3, t1, -1);
3280             tcg_gen_and_tl(tcg_ctx, t2, t2, t3);
3281             tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_EQ, t3, t1, 0);
3282             tcg_gen_or_tl(tcg_ctx, t2, t2, t3);
3283             tcg_gen_movi_tl(tcg_ctx, t3, 0);
3284             tcg_gen_movcond_tl(tcg_ctx, TCG_COND_NE, t1, t2, t3, t2, t1);
3285             tcg_gen_div_tl(tcg_ctx, *cpu_gpr[rd], t0, t1);
3286             tcg_gen_ext32s_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rd]);
3287             tcg_temp_free(tcg_ctx, t3);
3288             tcg_temp_free(tcg_ctx, t2);
3289         }
3290         opn = "div";
3291         break;
3292     case R6_OPC_MOD:
3293         {
3294             TCGv t2 = tcg_temp_new(tcg_ctx);
3295             TCGv t3 = tcg_temp_new(tcg_ctx);
3296             tcg_gen_ext32s_tl(tcg_ctx, t0, t0);
3297             tcg_gen_ext32s_tl(tcg_ctx, t1, t1);
3298             tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_EQ, t2, t0, INT_MIN);
3299             tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_EQ, t3, t1, -1);
3300             tcg_gen_and_tl(tcg_ctx, t2, t2, t3);
3301             tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_EQ, t3, t1, 0);
3302             tcg_gen_or_tl(tcg_ctx, t2, t2, t3);
3303             tcg_gen_movi_tl(tcg_ctx, t3, 0);
3304             tcg_gen_movcond_tl(tcg_ctx, TCG_COND_NE, t1, t2, t3, t2, t1);
3305             tcg_gen_rem_tl(tcg_ctx, *cpu_gpr[rd], t0, t1);
3306             tcg_gen_ext32s_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rd]);
3307             tcg_temp_free(tcg_ctx, t3);
3308             tcg_temp_free(tcg_ctx, t2);
3309         }
3310         opn = "mod";
3311         break;
3312     case R6_OPC_DIVU:
3313         {
3314             TCGv t2 = tcg_const_tl(tcg_ctx, 0);
3315             TCGv t3 = tcg_const_tl(tcg_ctx, 1);
3316             tcg_gen_ext32u_tl(tcg_ctx, t0, t0);
3317             tcg_gen_ext32u_tl(tcg_ctx, t1, t1);
3318             tcg_gen_movcond_tl(tcg_ctx, TCG_COND_EQ, t1, t1, t2, t3, t1);
3319             tcg_gen_divu_tl(tcg_ctx, *cpu_gpr[rd], t0, t1);
3320             tcg_gen_ext32s_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rd]);
3321             tcg_temp_free(tcg_ctx, t3);
3322             tcg_temp_free(tcg_ctx, t2);
3323         }
3324         opn = "divu";
3325         break;
3326     case R6_OPC_MODU:
3327         {
3328             TCGv t2 = tcg_const_tl(tcg_ctx, 0);
3329             TCGv t3 = tcg_const_tl(tcg_ctx, 1);
3330             tcg_gen_ext32u_tl(tcg_ctx, t0, t0);
3331             tcg_gen_ext32u_tl(tcg_ctx, t1, t1);
3332             tcg_gen_movcond_tl(tcg_ctx, TCG_COND_EQ, t1, t1, t2, t3, t1);
3333             tcg_gen_remu_tl(tcg_ctx, *cpu_gpr[rd], t0, t1);
3334             tcg_gen_ext32s_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rd]);
3335             tcg_temp_free(tcg_ctx, t3);
3336             tcg_temp_free(tcg_ctx, t2);
3337         }
3338         opn = "modu";
3339         break;
3340     case R6_OPC_MUL:
3341         {
3342             TCGv_i32 t2 = tcg_temp_new_i32(tcg_ctx);
3343             TCGv_i32 t3 = tcg_temp_new_i32(tcg_ctx);
3344             tcg_gen_trunc_tl_i32(tcg_ctx, t2, t0);
3345             tcg_gen_trunc_tl_i32(tcg_ctx, t3, t1);
3346             tcg_gen_mul_i32(tcg_ctx, t2, t2, t3);
3347             tcg_gen_ext_i32_tl(tcg_ctx, *cpu_gpr[rd], t2);
3348             tcg_temp_free_i32(tcg_ctx, t2);
3349             tcg_temp_free_i32(tcg_ctx, t3);
3350         }
3351         opn = "mul";
3352         break;
3353     case R6_OPC_MUH:
3354         {
3355             TCGv_i32 t2 = tcg_temp_new_i32(tcg_ctx);
3356             TCGv_i32 t3 = tcg_temp_new_i32(tcg_ctx);
3357             tcg_gen_trunc_tl_i32(tcg_ctx, t2, t0);
3358             tcg_gen_trunc_tl_i32(tcg_ctx, t3, t1);
3359             tcg_gen_muls2_i32(tcg_ctx, t2, t3, t2, t3);
3360             tcg_gen_ext_i32_tl(tcg_ctx, *cpu_gpr[rd], t3);
3361             tcg_temp_free_i32(tcg_ctx, t2);
3362             tcg_temp_free_i32(tcg_ctx, t3);
3363         }
3364         opn = "muh";
3365         break;
3366     case R6_OPC_MULU:
3367         {
3368             TCGv_i32 t2 = tcg_temp_new_i32(tcg_ctx);
3369             TCGv_i32 t3 = tcg_temp_new_i32(tcg_ctx);
3370             tcg_gen_trunc_tl_i32(tcg_ctx, t2, t0);
3371             tcg_gen_trunc_tl_i32(tcg_ctx, t3, t1);
3372             tcg_gen_mul_i32(tcg_ctx, t2, t2, t3);
3373             tcg_gen_ext_i32_tl(tcg_ctx, *cpu_gpr[rd], t2);
3374             tcg_temp_free_i32(tcg_ctx, t2);
3375             tcg_temp_free_i32(tcg_ctx, t3);
3376         }
3377         opn = "mulu";
3378         break;
3379     case R6_OPC_MUHU:
3380         {
3381             TCGv_i32 t2 = tcg_temp_new_i32(tcg_ctx);
3382             TCGv_i32 t3 = tcg_temp_new_i32(tcg_ctx);
3383             tcg_gen_trunc_tl_i32(tcg_ctx, t2, t0);
3384             tcg_gen_trunc_tl_i32(tcg_ctx, t3, t1);
3385             tcg_gen_mulu2_i32(tcg_ctx, t2, t3, t2, t3);
3386             tcg_gen_ext_i32_tl(tcg_ctx, *cpu_gpr[rd], t3);
3387             tcg_temp_free_i32(tcg_ctx, t2);
3388             tcg_temp_free_i32(tcg_ctx, t3);
3389         }
3390         opn = "muhu";
3391         break;
3392 #if defined(TARGET_MIPS64)
3393     case R6_OPC_DDIV:
3394         {
3395             TCGv t2 = tcg_temp_new(tcg_ctx);
3396             TCGv t3 = tcg_temp_new(tcg_ctx);
3397             tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_EQ, t2, t0, -1ULL << 63);
3398             tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_EQ, t3, t1, -1LL);
3399             tcg_gen_and_tl(tcg_ctx, t2, t2, t3);
3400             tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_EQ, t3, t1, 0);
3401             tcg_gen_or_tl(tcg_ctx, t2, t2, t3);
3402             tcg_gen_movi_tl(tcg_ctx, t3, 0);
3403             tcg_gen_movcond_tl(tcg_ctx, TCG_COND_NE, t1, t2, t3, t2, t1);
3404             tcg_gen_div_tl(tcg_ctx, *cpu_gpr[rd], t0, t1);
3405             tcg_temp_free(tcg_ctx, t3);
3406             tcg_temp_free(tcg_ctx, t2);
3407         }
3408         opn = "ddiv";
3409         break;
3410     case R6_OPC_DMOD:
3411         {
3412             TCGv t2 = tcg_temp_new(tcg_ctx);
3413             TCGv t3 = tcg_temp_new(tcg_ctx);
3414             tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_EQ, t2, t0, -1ULL << 63);
3415             tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_EQ, t3, t1, -1LL);
3416             tcg_gen_and_tl(tcg_ctx, t2, t2, t3);
3417             tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_EQ, t3, t1, 0);
3418             tcg_gen_or_tl(tcg_ctx, t2, t2, t3);
3419             tcg_gen_movi_tl(tcg_ctx, t3, 0);
3420             tcg_gen_movcond_tl(tcg_ctx, TCG_COND_NE, t1, t2, t3, t2, t1);
3421             tcg_gen_rem_tl(tcg_ctx, *cpu_gpr[rd], t0, t1);
3422             tcg_temp_free(tcg_ctx, t3);
3423             tcg_temp_free(tcg_ctx, t2);
3424         }
3425         opn = "dmod";
3426         break;
3427     case R6_OPC_DDIVU:
3428         {
3429             TCGv t2 = tcg_const_tl(tcg_ctx, 0);
3430             TCGv t3 = tcg_const_tl(tcg_ctx, 1);
3431             tcg_gen_movcond_tl(tcg_ctx, TCG_COND_EQ, t1, t1, t2, t3, t1);
3432             tcg_gen_divu_i64(tcg_ctx, *cpu_gpr[rd], t0, t1);
3433             tcg_temp_free(tcg_ctx, t3);
3434             tcg_temp_free(tcg_ctx, t2);
3435         }
3436         opn = "ddivu";
3437         break;
3438     case R6_OPC_DMODU:
3439         {
3440             TCGv t2 = tcg_const_tl(tcg_ctx, 0);
3441             TCGv t3 = tcg_const_tl(tcg_ctx, 1);
3442             tcg_gen_movcond_tl(tcg_ctx, TCG_COND_EQ, t1, t1, t2, t3, t1);
3443             tcg_gen_remu_i64(tcg_ctx, *cpu_gpr[rd], t0, t1);
3444             tcg_temp_free(tcg_ctx, t3);
3445             tcg_temp_free(tcg_ctx, t2);
3446         }
3447         opn = "dmodu";
3448         break;
3449     case R6_OPC_DMUL:
3450         tcg_gen_mul_i64(tcg_ctx, *cpu_gpr[rd], t0, t1);
3451         opn = "dmul";
3452         break;
3453     case R6_OPC_DMUH:
3454         {
3455             TCGv t2 = tcg_temp_new(tcg_ctx);
3456             tcg_gen_muls2_i64(tcg_ctx, t2, *cpu_gpr[rd], t0, t1);
3457             tcg_temp_free(tcg_ctx, t2);
3458         }
3459         opn = "dmuh";
3460         break;
3461     case R6_OPC_DMULU:
3462         tcg_gen_mul_i64(tcg_ctx, *cpu_gpr[rd], t0, t1);
3463         opn = "dmulu";
3464         break;
3465     case R6_OPC_DMUHU:
3466         {
3467             TCGv t2 = tcg_temp_new(tcg_ctx);
3468             tcg_gen_mulu2_i64(tcg_ctx, t2, *cpu_gpr[rd], t0, t1);
3469             tcg_temp_free(tcg_ctx, t2);
3470         }
3471         opn = "dmuhu";
3472         break;
3473 #endif
3474     default:
3475         MIPS_INVAL(opn);
3476         generate_exception(ctx, EXCP_RI);
3477         goto out;
3478     }
3479     (void)opn; /* avoid a compiler warning */
3480     MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
3481  out:
3482     tcg_temp_free(tcg_ctx, t0);
3483     tcg_temp_free(tcg_ctx, t1);
3484 }
3485 
gen_muldiv(DisasContext * ctx,uint32_t opc,int acc,int rs,int rt)3486 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3487                        int acc, int rs, int rt)
3488 {
3489     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
3490     TCGv **cpu_HI = (TCGv **)tcg_ctx->cpu_HI;
3491     TCGv **cpu_LO = (TCGv **)tcg_ctx->cpu_LO;
3492     const char *opn = "mul/div";
3493     TCGv t0, t1;
3494 
3495     t0 = tcg_temp_new(tcg_ctx);
3496     t1 = tcg_temp_new(tcg_ctx);
3497 
3498     gen_load_gpr(ctx, t0, rs);
3499     gen_load_gpr(ctx, t1, rt);
3500 
3501     if (acc != 0) {
3502         check_dsp(ctx);
3503     }
3504 
3505     switch (opc) {
3506     case OPC_DIV:
3507         {
3508             TCGv t2 = tcg_temp_new(tcg_ctx);
3509             TCGv t3 = tcg_temp_new(tcg_ctx);
3510             tcg_gen_ext32s_tl(tcg_ctx, t0, t0);
3511             tcg_gen_ext32s_tl(tcg_ctx, t1, t1);
3512             tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_EQ, t2, t0, INT_MIN);
3513             tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_EQ, t3, t1, -1);
3514             tcg_gen_and_tl(tcg_ctx, t2, t2, t3);
3515             tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_EQ, t3, t1, 0);
3516             tcg_gen_or_tl(tcg_ctx, t2, t2, t3);
3517             tcg_gen_movi_tl(tcg_ctx, t3, 0);
3518             tcg_gen_movcond_tl(tcg_ctx, TCG_COND_NE, t1, t2, t3, t2, t1);
3519             tcg_gen_div_tl(tcg_ctx, *cpu_LO[acc], t0, t1);
3520             tcg_gen_rem_tl(tcg_ctx, *cpu_HI[acc], t0, t1);
3521             tcg_gen_ext32s_tl(tcg_ctx, *cpu_LO[acc], *cpu_LO[acc]);
3522             tcg_gen_ext32s_tl(tcg_ctx, *cpu_HI[acc], *cpu_HI[acc]);
3523             tcg_temp_free(tcg_ctx, t3);
3524             tcg_temp_free(tcg_ctx, t2);
3525         }
3526         opn = "div";
3527         break;
3528     case OPC_DIVU:
3529         {
3530             TCGv t2 = tcg_const_tl(tcg_ctx, 0);
3531             TCGv t3 = tcg_const_tl(tcg_ctx, 1);
3532             tcg_gen_ext32u_tl(tcg_ctx, t0, t0);
3533             tcg_gen_ext32u_tl(tcg_ctx, t1, t1);
3534             tcg_gen_movcond_tl(tcg_ctx, TCG_COND_EQ, t1, t1, t2, t3, t1);
3535             tcg_gen_divu_tl(tcg_ctx, *cpu_LO[acc], t0, t1);
3536             tcg_gen_remu_tl(tcg_ctx, *cpu_HI[acc], t0, t1);
3537             tcg_gen_ext32s_tl(tcg_ctx, *cpu_LO[acc], *cpu_LO[acc]);
3538             tcg_gen_ext32s_tl(tcg_ctx, *cpu_HI[acc], *cpu_HI[acc]);
3539             tcg_temp_free(tcg_ctx, t3);
3540             tcg_temp_free(tcg_ctx, t2);
3541         }
3542         opn = "divu";
3543         break;
3544     case OPC_MULT:
3545         {
3546             TCGv_i32 t2 = tcg_temp_new_i32(tcg_ctx);
3547             TCGv_i32 t3 = tcg_temp_new_i32(tcg_ctx);
3548             tcg_gen_trunc_tl_i32(tcg_ctx, t2, t0);
3549             tcg_gen_trunc_tl_i32(tcg_ctx, t3, t1);
3550             tcg_gen_muls2_i32(tcg_ctx, t2, t3, t2, t3);
3551             tcg_gen_ext_i32_tl(tcg_ctx, *cpu_LO[acc], t2);
3552             tcg_gen_ext_i32_tl(tcg_ctx, *cpu_HI[acc], t3);
3553             tcg_temp_free_i32(tcg_ctx, t2);
3554             tcg_temp_free_i32(tcg_ctx, t3);
3555         }
3556         opn = "mult";
3557         break;
3558     case OPC_MULTU:
3559         {
3560             TCGv_i32 t2 = tcg_temp_new_i32(tcg_ctx);
3561             TCGv_i32 t3 = tcg_temp_new_i32(tcg_ctx);
3562             tcg_gen_trunc_tl_i32(tcg_ctx, t2, t0);
3563             tcg_gen_trunc_tl_i32(tcg_ctx, t3, t1);
3564             tcg_gen_mulu2_i32(tcg_ctx, t2, t3, t2, t3);
3565             tcg_gen_ext_i32_tl(tcg_ctx, *cpu_LO[acc], t2);
3566             tcg_gen_ext_i32_tl(tcg_ctx, *cpu_HI[acc], t3);
3567             tcg_temp_free_i32(tcg_ctx, t2);
3568             tcg_temp_free_i32(tcg_ctx, t3);
3569         }
3570         opn = "multu";
3571         break;
3572 #if defined(TARGET_MIPS64)
3573     case OPC_DDIV:
3574         {
3575             TCGv t2 = tcg_temp_new(tcg_ctx);
3576             TCGv t3 = tcg_temp_new(tcg_ctx);
3577             tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_EQ, t2, t0, -1ULL << 63);
3578             tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_EQ, t3, t1, -1LL);
3579             tcg_gen_and_tl(tcg_ctx, t2, t2, t3);
3580             tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_EQ, t3, t1, 0);
3581             tcg_gen_or_tl(tcg_ctx, t2, t2, t3);
3582             tcg_gen_movi_tl(tcg_ctx, t3, 0);
3583             tcg_gen_movcond_tl(tcg_ctx, TCG_COND_NE, t1, t2, t3, t2, t1);
3584             tcg_gen_div_tl(tcg_ctx, *cpu_LO[acc], t0, t1);
3585             tcg_gen_rem_tl(tcg_ctx, *cpu_HI[acc], t0, t1);
3586             tcg_temp_free(tcg_ctx, t3);
3587             tcg_temp_free(tcg_ctx, t2);
3588         }
3589         opn = "ddiv";
3590         break;
3591     case OPC_DDIVU:
3592         {
3593             TCGv t2 = tcg_const_tl(tcg_ctx, 0);
3594             TCGv t3 = tcg_const_tl(tcg_ctx, 1);
3595             tcg_gen_movcond_tl(tcg_ctx, TCG_COND_EQ, t1, t1, t2, t3, t1);
3596             tcg_gen_divu_i64(tcg_ctx, *cpu_LO[acc], t0, t1);
3597             tcg_gen_remu_i64(tcg_ctx, *cpu_HI[acc], t0, t1);
3598             tcg_temp_free(tcg_ctx, t3);
3599             tcg_temp_free(tcg_ctx, t2);
3600         }
3601         opn = "ddivu";
3602         break;
3603     case OPC_DMULT:
3604         tcg_gen_muls2_i64(tcg_ctx, *cpu_LO[acc], *cpu_HI[acc], t0, t1);
3605         opn = "dmult";
3606         break;
3607     case OPC_DMULTU:
3608         tcg_gen_mulu2_i64(tcg_ctx, *cpu_LO[acc], *cpu_HI[acc], t0, t1);
3609         opn = "dmultu";
3610         break;
3611 #endif
3612     case OPC_MADD:
3613         {
3614             TCGv_i64 t2 = tcg_temp_new_i64(tcg_ctx);
3615             TCGv_i64 t3 = tcg_temp_new_i64(tcg_ctx);
3616 
3617             tcg_gen_ext_tl_i64(tcg_ctx, t2, t0);
3618             tcg_gen_ext_tl_i64(tcg_ctx, t3, t1);
3619             tcg_gen_mul_i64(tcg_ctx, t2, t2, t3);
3620             tcg_gen_concat_tl_i64(tcg_ctx, t3, *cpu_LO[acc], *cpu_HI[acc]);
3621             tcg_gen_add_i64(tcg_ctx, t2, t2, t3);
3622             tcg_temp_free_i64(tcg_ctx, t3);
3623             tcg_gen_trunc_i64_tl(tcg_ctx, t0, t2);
3624             tcg_gen_shri_i64(tcg_ctx, t2, t2, 32);
3625             tcg_gen_trunc_i64_tl(tcg_ctx, t1, t2);
3626             tcg_temp_free_i64(tcg_ctx, t2);
3627             tcg_gen_ext32s_tl(tcg_ctx, *cpu_LO[acc], t0);
3628             tcg_gen_ext32s_tl(tcg_ctx, *cpu_HI[acc], t1);
3629         }
3630         opn = "madd";
3631         break;
3632     case OPC_MADDU:
3633         {
3634             TCGv_i64 t2 = tcg_temp_new_i64(tcg_ctx);
3635             TCGv_i64 t3 = tcg_temp_new_i64(tcg_ctx);
3636 
3637             tcg_gen_ext32u_tl(tcg_ctx, t0, t0);
3638             tcg_gen_ext32u_tl(tcg_ctx, t1, t1);
3639             tcg_gen_extu_tl_i64(tcg_ctx, t2, t0);
3640             tcg_gen_extu_tl_i64(tcg_ctx, t3, t1);
3641             tcg_gen_mul_i64(tcg_ctx, t2, t2, t3);
3642             tcg_gen_concat_tl_i64(tcg_ctx, t3, *cpu_LO[acc], *cpu_HI[acc]);
3643             tcg_gen_add_i64(tcg_ctx, t2, t2, t3);
3644             tcg_temp_free_i64(tcg_ctx, t3);
3645             tcg_gen_trunc_i64_tl(tcg_ctx, t0, t2);
3646             tcg_gen_shri_i64(tcg_ctx, t2, t2, 32);
3647             tcg_gen_trunc_i64_tl(tcg_ctx, t1, t2);
3648             tcg_temp_free_i64(tcg_ctx, t2);
3649             tcg_gen_ext32s_tl(tcg_ctx, *cpu_LO[acc], t0);
3650             tcg_gen_ext32s_tl(tcg_ctx, *cpu_HI[acc], t1);
3651         }
3652         opn = "maddu";
3653         break;
3654     case OPC_MSUB:
3655         {
3656             TCGv_i64 t2 = tcg_temp_new_i64(tcg_ctx);
3657             TCGv_i64 t3 = tcg_temp_new_i64(tcg_ctx);
3658 
3659             tcg_gen_ext_tl_i64(tcg_ctx, t2, t0);
3660             tcg_gen_ext_tl_i64(tcg_ctx, t3, t1);
3661             tcg_gen_mul_i64(tcg_ctx, t2, t2, t3);
3662             tcg_gen_concat_tl_i64(tcg_ctx, t3, *cpu_LO[acc], *cpu_HI[acc]);
3663             tcg_gen_sub_i64(tcg_ctx, t2, t3, t2);
3664             tcg_temp_free_i64(tcg_ctx, t3);
3665             tcg_gen_trunc_i64_tl(tcg_ctx, t0, t2);
3666             tcg_gen_shri_i64(tcg_ctx, t2, t2, 32);
3667             tcg_gen_trunc_i64_tl(tcg_ctx, t1, t2);
3668             tcg_temp_free_i64(tcg_ctx, t2);
3669             tcg_gen_ext32s_tl(tcg_ctx, *cpu_LO[acc], t0);
3670             tcg_gen_ext32s_tl(tcg_ctx, *cpu_HI[acc], t1);
3671         }
3672         opn = "msub";
3673         break;
3674     case OPC_MSUBU:
3675         {
3676             TCGv_i64 t2 = tcg_temp_new_i64(tcg_ctx);
3677             TCGv_i64 t3 = tcg_temp_new_i64(tcg_ctx);
3678 
3679             tcg_gen_ext32u_tl(tcg_ctx, t0, t0);
3680             tcg_gen_ext32u_tl(tcg_ctx, t1, t1);
3681             tcg_gen_extu_tl_i64(tcg_ctx, t2, t0);
3682             tcg_gen_extu_tl_i64(tcg_ctx, t3, t1);
3683             tcg_gen_mul_i64(tcg_ctx, t2, t2, t3);
3684             tcg_gen_concat_tl_i64(tcg_ctx, t3, *cpu_LO[acc], *cpu_HI[acc]);
3685             tcg_gen_sub_i64(tcg_ctx, t2, t3, t2);
3686             tcg_temp_free_i64(tcg_ctx, t3);
3687             tcg_gen_trunc_i64_tl(tcg_ctx, t0, t2);
3688             tcg_gen_shri_i64(tcg_ctx, t2, t2, 32);
3689             tcg_gen_trunc_i64_tl(tcg_ctx, t1, t2);
3690             tcg_temp_free_i64(tcg_ctx, t2);
3691             tcg_gen_ext32s_tl(tcg_ctx, *cpu_LO[acc], t0);
3692             tcg_gen_ext32s_tl(tcg_ctx, *cpu_HI[acc], t1);
3693         }
3694         opn = "msubu";
3695         break;
3696     default:
3697         MIPS_INVAL(opn);
3698         generate_exception(ctx, EXCP_RI);
3699         goto out;
3700     }
3701     (void)opn; /* avoid a compiler warning */
3702     MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
3703  out:
3704     tcg_temp_free(tcg_ctx, t0);
3705     tcg_temp_free(tcg_ctx, t1);
3706 }
3707 
gen_mul_vr54xx(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)3708 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
3709                             int rd, int rs, int rt)
3710 {
3711     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
3712     const char *opn = "mul vr54xx";
3713     TCGv t0 = tcg_temp_new(tcg_ctx);
3714     TCGv t1 = tcg_temp_new(tcg_ctx);
3715 
3716     gen_load_gpr(ctx, t0, rs);
3717     gen_load_gpr(ctx, t1, rt);
3718 
3719     switch (opc) {
3720     case OPC_VR54XX_MULS:
3721         gen_helper_muls(tcg_ctx, t0, tcg_ctx->cpu_env, t0, t1);
3722         opn = "muls";
3723         break;
3724     case OPC_VR54XX_MULSU:
3725         gen_helper_mulsu(tcg_ctx, t0, tcg_ctx->cpu_env, t0, t1);
3726         opn = "mulsu";
3727         break;
3728     case OPC_VR54XX_MACC:
3729         gen_helper_macc(tcg_ctx, t0, tcg_ctx->cpu_env, t0, t1);
3730         opn = "macc";
3731         break;
3732     case OPC_VR54XX_MACCU:
3733         gen_helper_maccu(tcg_ctx, t0, tcg_ctx->cpu_env, t0, t1);
3734         opn = "maccu";
3735         break;
3736     case OPC_VR54XX_MSAC:
3737         gen_helper_msac(tcg_ctx, t0, tcg_ctx->cpu_env, t0, t1);
3738         opn = "msac";
3739         break;
3740     case OPC_VR54XX_MSACU:
3741         gen_helper_msacu(tcg_ctx, t0, tcg_ctx->cpu_env, t0, t1);
3742         opn = "msacu";
3743         break;
3744     case OPC_VR54XX_MULHI:
3745         gen_helper_mulhi(tcg_ctx, t0, tcg_ctx->cpu_env, t0, t1);
3746         opn = "mulhi";
3747         break;
3748     case OPC_VR54XX_MULHIU:
3749         gen_helper_mulhiu(tcg_ctx, t0, tcg_ctx->cpu_env, t0, t1);
3750         opn = "mulhiu";
3751         break;
3752     case OPC_VR54XX_MULSHI:
3753         gen_helper_mulshi(tcg_ctx, t0, tcg_ctx->cpu_env, t0, t1);
3754         opn = "mulshi";
3755         break;
3756     case OPC_VR54XX_MULSHIU:
3757         gen_helper_mulshiu(tcg_ctx, t0, tcg_ctx->cpu_env, t0, t1);
3758         opn = "mulshiu";
3759         break;
3760     case OPC_VR54XX_MACCHI:
3761         gen_helper_macchi(tcg_ctx, t0, tcg_ctx->cpu_env, t0, t1);
3762         opn = "macchi";
3763         break;
3764     case OPC_VR54XX_MACCHIU:
3765         gen_helper_macchiu(tcg_ctx, t0, tcg_ctx->cpu_env, t0, t1);
3766         opn = "macchiu";
3767         break;
3768     case OPC_VR54XX_MSACHI:
3769         gen_helper_msachi(tcg_ctx, t0, tcg_ctx->cpu_env, t0, t1);
3770         opn = "msachi";
3771         break;
3772     case OPC_VR54XX_MSACHIU:
3773         gen_helper_msachiu(tcg_ctx, t0, tcg_ctx->cpu_env, t0, t1);
3774         opn = "msachiu";
3775         break;
3776     default:
3777         MIPS_INVAL("mul vr54xx");
3778         generate_exception(ctx, EXCP_RI);
3779         goto out;
3780     }
3781     gen_store_gpr(tcg_ctx, t0, rd);
3782     (void)opn; /* avoid a compiler warning */
3783     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
3784 
3785  out:
3786     tcg_temp_free(tcg_ctx, t0);
3787     tcg_temp_free(tcg_ctx, t1);
3788 }
3789 
gen_cl(DisasContext * ctx,uint32_t opc,int rd,int rs)3790 static void gen_cl (DisasContext *ctx, uint32_t opc,
3791                     int rd, int rs)
3792 {
3793     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
3794     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
3795     const char *opn = "CLx";
3796     TCGv t0;
3797 
3798     if (rd == 0) {
3799         /* Treat as NOP. */
3800         MIPS_DEBUG("NOP");
3801         return;
3802     }
3803     t0 = tcg_temp_new(tcg_ctx);
3804     gen_load_gpr(ctx, t0, rs);
3805     switch (opc) {
3806     case OPC_CLO:
3807     case R6_OPC_CLO:
3808         gen_helper_clo(tcg_ctx, *cpu_gpr[rd], t0);
3809         opn = "clo";
3810         break;
3811     case OPC_CLZ:
3812     case R6_OPC_CLZ:
3813         gen_helper_clz(tcg_ctx, *cpu_gpr[rd], t0);
3814         opn = "clz";
3815         break;
3816 #if defined(TARGET_MIPS64)
3817     case OPC_DCLO:
3818     case R6_OPC_DCLO:
3819         gen_helper_dclo(tcg_ctx, *cpu_gpr[rd], t0);
3820         opn = "dclo";
3821         break;
3822     case OPC_DCLZ:
3823     case R6_OPC_DCLZ:
3824         gen_helper_dclz(tcg_ctx, *cpu_gpr[rd], t0);
3825         opn = "dclz";
3826         break;
3827 #endif
3828     }
3829     (void)opn; /* avoid a compiler warning */
3830     MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3831     tcg_temp_free(tcg_ctx, t0);
3832 }
3833 
3834 /* Godson integer instructions */
gen_loongson_integer(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)3835 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3836                                  int rd, int rs, int rt)
3837 {
3838     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
3839     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
3840     const char *opn = "loongson";
3841     TCGv t0, t1;
3842 
3843     if (rd == 0) {
3844         /* Treat as NOP. */
3845         MIPS_DEBUG("NOP");
3846         return;
3847     }
3848 
3849     switch (opc) {
3850     case OPC_MULT_G_2E:
3851     case OPC_MULT_G_2F:
3852     case OPC_MULTU_G_2E:
3853     case OPC_MULTU_G_2F:
3854 #if defined(TARGET_MIPS64)
3855     case OPC_DMULT_G_2E:
3856     case OPC_DMULT_G_2F:
3857     case OPC_DMULTU_G_2E:
3858     case OPC_DMULTU_G_2F:
3859 #endif
3860         t0 = tcg_temp_new(tcg_ctx);
3861         t1 = tcg_temp_new(tcg_ctx);
3862         break;
3863     default:
3864         t0 = tcg_temp_local_new(tcg_ctx);
3865         t1 = tcg_temp_local_new(tcg_ctx);
3866         break;
3867     }
3868 
3869     gen_load_gpr(ctx, t0, rs);
3870     gen_load_gpr(ctx, t1, rt);
3871 
3872     switch (opc) {
3873     case OPC_MULT_G_2E:
3874     case OPC_MULT_G_2F:
3875         tcg_gen_mul_tl(tcg_ctx, *cpu_gpr[rd], t0, t1);
3876         tcg_gen_ext32s_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rd]);
3877         opn = "mult.g";
3878         break;
3879     case OPC_MULTU_G_2E:
3880     case OPC_MULTU_G_2F:
3881         tcg_gen_ext32u_tl(tcg_ctx, t0, t0);
3882         tcg_gen_ext32u_tl(tcg_ctx, t1, t1);
3883         tcg_gen_mul_tl(tcg_ctx, *cpu_gpr[rd], t0, t1);
3884         tcg_gen_ext32s_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rd]);
3885         opn = "multu.g";
3886         break;
3887     case OPC_DIV_G_2E:
3888     case OPC_DIV_G_2F:
3889         {
3890             int l1 = gen_new_label(tcg_ctx);
3891             int l2 = gen_new_label(tcg_ctx);
3892             int l3 = gen_new_label(tcg_ctx);
3893             tcg_gen_ext32s_tl(tcg_ctx, t0, t0);
3894             tcg_gen_ext32s_tl(tcg_ctx, t1, t1);
3895             tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_NE, t1, 0, l1);
3896             tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[rd], 0);
3897             tcg_gen_br(tcg_ctx, l3);
3898             gen_set_label(tcg_ctx, l1);
3899             tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_NE, t0, INT_MIN, l2);
3900             tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_NE, t1, -1, l2);
3901             tcg_gen_mov_tl(tcg_ctx, *cpu_gpr[rd], t0);
3902             tcg_gen_br(tcg_ctx, l3);
3903             gen_set_label(tcg_ctx, l2);
3904             tcg_gen_div_tl(tcg_ctx, *cpu_gpr[rd], t0, t1);
3905             tcg_gen_ext32s_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rd]);
3906             gen_set_label(tcg_ctx, l3);
3907         }
3908         opn = "div.g";
3909         break;
3910     case OPC_DIVU_G_2E:
3911     case OPC_DIVU_G_2F:
3912         {
3913             int l1 = gen_new_label(tcg_ctx);
3914             int l2 = gen_new_label(tcg_ctx);
3915             tcg_gen_ext32u_tl(tcg_ctx, t0, t0);
3916             tcg_gen_ext32u_tl(tcg_ctx, t1, t1);
3917             tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_NE, t1, 0, l1);
3918             tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[rd], 0);
3919             tcg_gen_br(tcg_ctx, l2);
3920             gen_set_label(tcg_ctx, l1);
3921             tcg_gen_divu_tl(tcg_ctx, *cpu_gpr[rd], t0, t1);
3922             tcg_gen_ext32s_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rd]);
3923             gen_set_label(tcg_ctx, l2);
3924         }
3925         opn = "divu.g";
3926         break;
3927     case OPC_MOD_G_2E:
3928     case OPC_MOD_G_2F:
3929         {
3930             int l1 = gen_new_label(tcg_ctx);
3931             int l2 = gen_new_label(tcg_ctx);
3932             int l3 = gen_new_label(tcg_ctx);
3933             tcg_gen_ext32u_tl(tcg_ctx, t0, t0);
3934             tcg_gen_ext32u_tl(tcg_ctx, t1, t1);
3935             tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_EQ, t1, 0, l1);
3936             tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_NE, t0, INT_MIN, l2);
3937             tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_NE, t1, -1, l2);
3938             gen_set_label(tcg_ctx, l1);
3939             tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[rd], 0);
3940             tcg_gen_br(tcg_ctx, l3);
3941             gen_set_label(tcg_ctx, l2);
3942             tcg_gen_rem_tl(tcg_ctx, *cpu_gpr[rd], t0, t1);
3943             tcg_gen_ext32s_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rd]);
3944             gen_set_label(tcg_ctx, l3);
3945         }
3946         opn = "mod.g";
3947         break;
3948     case OPC_MODU_G_2E:
3949     case OPC_MODU_G_2F:
3950         {
3951             int l1 = gen_new_label(tcg_ctx);
3952             int l2 = gen_new_label(tcg_ctx);
3953             tcg_gen_ext32u_tl(tcg_ctx, t0, t0);
3954             tcg_gen_ext32u_tl(tcg_ctx, t1, t1);
3955             tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_NE, t1, 0, l1);
3956             tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[rd], 0);
3957             tcg_gen_br(tcg_ctx, l2);
3958             gen_set_label(tcg_ctx, l1);
3959             tcg_gen_remu_tl(tcg_ctx, *cpu_gpr[rd], t0, t1);
3960             tcg_gen_ext32s_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rd]);
3961             gen_set_label(tcg_ctx, l2);
3962         }
3963         opn = "modu.g";
3964         break;
3965 #if defined(TARGET_MIPS64)
3966     case OPC_DMULT_G_2E:
3967     case OPC_DMULT_G_2F:
3968         tcg_gen_mul_tl(tcg_ctx, *cpu_gpr[rd], t0, t1);
3969         opn = "dmult.g";
3970         break;
3971     case OPC_DMULTU_G_2E:
3972     case OPC_DMULTU_G_2F:
3973         tcg_gen_mul_tl(tcg_ctx, *cpu_gpr[rd], t0, t1);
3974         opn = "dmultu.g";
3975         break;
3976     case OPC_DDIV_G_2E:
3977     case OPC_DDIV_G_2F:
3978         {
3979             int l1 = gen_new_label(tcg_ctx);
3980             int l2 = gen_new_label(tcg_ctx);
3981             int l3 = gen_new_label(tcg_ctx);
3982             tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_NE, t1, 0, l1);
3983             tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[rd], 0);
3984             tcg_gen_br(tcg_ctx, l3);
3985             gen_set_label(tcg_ctx, l1);
3986             tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_NE, t0, -1ULL << 63, l2);
3987             tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_NE, t1, -1LL, l2);
3988             tcg_gen_mov_tl(tcg_ctx, *cpu_gpr[rd], t0);
3989             tcg_gen_br(tcg_ctx, l3);
3990             gen_set_label(tcg_ctx, l2);
3991             tcg_gen_div_tl(tcg_ctx, *cpu_gpr[rd], t0, t1);
3992             gen_set_label(tcg_ctx, l3);
3993         }
3994         opn = "ddiv.g";
3995         break;
3996     case OPC_DDIVU_G_2E:
3997     case OPC_DDIVU_G_2F:
3998         {
3999             int l1 = gen_new_label(tcg_ctx);
4000             int l2 = gen_new_label(tcg_ctx);
4001             tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_NE, t1, 0, l1);
4002             tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[rd], 0);
4003             tcg_gen_br(tcg_ctx, l2);
4004             gen_set_label(tcg_ctx, l1);
4005             tcg_gen_divu_tl(tcg_ctx, *cpu_gpr[rd], t0, t1);
4006             gen_set_label(tcg_ctx, l2);
4007         }
4008         opn = "ddivu.g";
4009         break;
4010     case OPC_DMOD_G_2E:
4011     case OPC_DMOD_G_2F:
4012         {
4013             int l1 = gen_new_label(tcg_ctx);
4014             int l2 = gen_new_label(tcg_ctx);
4015             int l3 = gen_new_label(tcg_ctx);
4016             tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_EQ, t1, 0, l1);
4017             tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_NE, t0, -1ULL << 63, l2);
4018             tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_NE, t1, -1LL, l2);
4019             gen_set_label(tcg_ctx, l1);
4020             tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[rd], 0);
4021             tcg_gen_br(tcg_ctx, l3);
4022             gen_set_label(tcg_ctx, l2);
4023             tcg_gen_rem_tl(tcg_ctx, *cpu_gpr[rd], t0, t1);
4024             gen_set_label(tcg_ctx, l3);
4025         }
4026         opn = "dmod.g";
4027         break;
4028     case OPC_DMODU_G_2E:
4029     case OPC_DMODU_G_2F:
4030         {
4031             int l1 = gen_new_label(tcg_ctx);
4032             int l2 = gen_new_label(tcg_ctx);
4033             tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_NE, t1, 0, l1);
4034             tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[rd], 0);
4035             tcg_gen_br(tcg_ctx, l2);
4036             gen_set_label(tcg_ctx, l1);
4037             tcg_gen_remu_tl(tcg_ctx, *cpu_gpr[rd], t0, t1);
4038             gen_set_label(tcg_ctx, l2);
4039         }
4040         opn = "dmodu.g";
4041         break;
4042 #endif
4043     }
4044 
4045     (void)opn; /* avoid a compiler warning */
4046     MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
4047     tcg_temp_free(tcg_ctx, t0);
4048     tcg_temp_free(tcg_ctx, t1);
4049 }
4050 
4051 /* Loongson multimedia instructions */
gen_loongson_multimedia(DisasContext * ctx,int rd,int rs,int rt)4052 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
4053 {
4054     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
4055     const char *opn = "loongson_cp2";
4056     uint32_t opc, shift_max;
4057     TCGv_i64 t0, t1;
4058 
4059     opc = MASK_LMI(ctx->opcode);
4060     switch (opc) {
4061     case OPC_ADD_CP2:
4062     case OPC_SUB_CP2:
4063     case OPC_DADD_CP2:
4064     case OPC_DSUB_CP2:
4065         t0 = tcg_temp_local_new_i64(tcg_ctx);
4066         t1 = tcg_temp_local_new_i64(tcg_ctx);
4067         break;
4068     default:
4069         t0 = tcg_temp_new_i64(tcg_ctx);
4070         t1 = tcg_temp_new_i64(tcg_ctx);
4071         break;
4072     }
4073 
4074     gen_load_fpr64(ctx, t0, rs);
4075     gen_load_fpr64(ctx, t1, rt);
4076 
4077 #define LMI_HELPER(UP, LO) \
4078     case OPC_##UP: gen_helper_##LO(tcg_ctx, t0, t0, t1); opn = #LO; break
4079 #define LMI_HELPER_1(UP, LO) \
4080     case OPC_##UP: gen_helper_##LO(tcg_ctx, t0, t0); opn = #LO; break
4081 #define LMI_DIRECT(UP, LO, OP) \
4082     case OPC_##UP: tcg_gen_##OP##_i64(tcg_ctx, t0, t0, t1); opn = #LO; break
4083 
4084     switch (opc) {
4085     LMI_HELPER(PADDSH, paddsh);
4086     LMI_HELPER(PADDUSH, paddush);
4087     LMI_HELPER(PADDH, paddh);
4088     LMI_HELPER(PADDW, paddw);
4089     LMI_HELPER(PADDSB, paddsb);
4090     LMI_HELPER(PADDUSB, paddusb);
4091     LMI_HELPER(PADDB, paddb);
4092 
4093     LMI_HELPER(PSUBSH, psubsh);
4094     LMI_HELPER(PSUBUSH, psubush);
4095     LMI_HELPER(PSUBH, psubh);
4096     LMI_HELPER(PSUBW, psubw);
4097     LMI_HELPER(PSUBSB, psubsb);
4098     LMI_HELPER(PSUBUSB, psubusb);
4099     LMI_HELPER(PSUBB, psubb);
4100 
4101     LMI_HELPER(PSHUFH, pshufh);
4102     LMI_HELPER(PACKSSWH, packsswh);
4103     LMI_HELPER(PACKSSHB, packsshb);
4104     LMI_HELPER(PACKUSHB, packushb);
4105 
4106     LMI_HELPER(PUNPCKLHW, punpcklhw);
4107     LMI_HELPER(PUNPCKHHW, punpckhhw);
4108     LMI_HELPER(PUNPCKLBH, punpcklbh);
4109     LMI_HELPER(PUNPCKHBH, punpckhbh);
4110     LMI_HELPER(PUNPCKLWD, punpcklwd);
4111     LMI_HELPER(PUNPCKHWD, punpckhwd);
4112 
4113     LMI_HELPER(PAVGH, pavgh);
4114     LMI_HELPER(PAVGB, pavgb);
4115     LMI_HELPER(PMAXSH, pmaxsh);
4116     LMI_HELPER(PMINSH, pminsh);
4117     LMI_HELPER(PMAXUB, pmaxub);
4118     LMI_HELPER(PMINUB, pminub);
4119 
4120     LMI_HELPER(PCMPEQW, pcmpeqw);
4121     LMI_HELPER(PCMPGTW, pcmpgtw);
4122     LMI_HELPER(PCMPEQH, pcmpeqh);
4123     LMI_HELPER(PCMPGTH, pcmpgth);
4124     LMI_HELPER(PCMPEQB, pcmpeqb);
4125     LMI_HELPER(PCMPGTB, pcmpgtb);
4126 
4127     LMI_HELPER(PSLLW, psllw);
4128     LMI_HELPER(PSLLH, psllh);
4129     LMI_HELPER(PSRLW, psrlw);
4130     LMI_HELPER(PSRLH, psrlh);
4131     LMI_HELPER(PSRAW, psraw);
4132     LMI_HELPER(PSRAH, psrah);
4133 
4134     LMI_HELPER(PMULLH, pmullh);
4135     LMI_HELPER(PMULHH, pmulhh);
4136     LMI_HELPER(PMULHUH, pmulhuh);
4137     LMI_HELPER(PMADDHW, pmaddhw);
4138 
4139     LMI_HELPER(PASUBUB, pasubub);
4140     LMI_HELPER_1(BIADD, biadd);
4141     LMI_HELPER_1(PMOVMSKB, pmovmskb);
4142 
4143     LMI_DIRECT(PADDD, paddd, add);
4144     LMI_DIRECT(PSUBD, psubd, sub);
4145     LMI_DIRECT(XOR_CP2, xor, xor);
4146     LMI_DIRECT(NOR_CP2, nor, nor);
4147     LMI_DIRECT(AND_CP2, and, and);
4148     LMI_DIRECT(PANDN, pandn, andc);
4149     LMI_DIRECT(OR, or, or);
4150 
4151     case OPC_PINSRH_0:
4152         tcg_gen_deposit_i64(tcg_ctx, t0, t0, t1, 0, 16);
4153         opn = "pinsrh_0";
4154         break;
4155     case OPC_PINSRH_1:
4156         tcg_gen_deposit_i64(tcg_ctx, t0, t0, t1, 16, 16);
4157         opn = "pinsrh_1";
4158         break;
4159     case OPC_PINSRH_2:
4160         tcg_gen_deposit_i64(tcg_ctx, t0, t0, t1, 32, 16);
4161         opn = "pinsrh_2";
4162         break;
4163     case OPC_PINSRH_3:
4164         tcg_gen_deposit_i64(tcg_ctx, t0, t0, t1, 48, 16);
4165         opn = "pinsrh_3";
4166         break;
4167 
4168     case OPC_PEXTRH:
4169         tcg_gen_andi_i64(tcg_ctx, t1, t1, 3);
4170         tcg_gen_shli_i64(tcg_ctx, t1, t1, 4);
4171         tcg_gen_shr_i64(tcg_ctx, t0, t0, t1);
4172         tcg_gen_ext16u_i64(tcg_ctx, t0, t0);
4173         opn = "pextrh";
4174         break;
4175 
4176     case OPC_ADDU_CP2:
4177         tcg_gen_add_i64(tcg_ctx, t0, t0, t1);
4178         tcg_gen_ext32s_i64(tcg_ctx, t0, t0);
4179         opn = "addu";
4180         break;
4181     case OPC_SUBU_CP2:
4182         tcg_gen_sub_i64(tcg_ctx, t0, t0, t1);
4183         tcg_gen_ext32s_i64(tcg_ctx, t0, t0);
4184         opn = "addu";
4185         break;
4186 
4187     case OPC_SLL_CP2:
4188         opn = "sll";
4189         shift_max = 32;
4190         goto do_shift;
4191     case OPC_SRL_CP2:
4192         opn = "srl";
4193         shift_max = 32;
4194         goto do_shift;
4195     case OPC_SRA_CP2:
4196         opn = "sra";
4197         shift_max = 32;
4198         goto do_shift;
4199     case OPC_DSLL_CP2:
4200         opn = "dsll";
4201         shift_max = 64;
4202         goto do_shift;
4203     case OPC_DSRL_CP2:
4204         opn = "dsrl";
4205         shift_max = 64;
4206         goto do_shift;
4207     case OPC_DSRA_CP2:
4208         opn = "dsra";
4209         shift_max = 64;
4210         goto do_shift;
4211     do_shift:
4212         /* Make sure shift count isn't TCG undefined behaviour.  */
4213         tcg_gen_andi_i64(tcg_ctx, t1, t1, shift_max - 1);
4214 
4215         switch (opc) {
4216         case OPC_SLL_CP2:
4217         case OPC_DSLL_CP2:
4218             tcg_gen_shl_i64(tcg_ctx, t0, t0, t1);
4219             break;
4220         case OPC_SRA_CP2:
4221         case OPC_DSRA_CP2:
4222             /* Since SRA is UndefinedResult without sign-extended inputs,
4223                we can treat SRA and DSRA the same.  */
4224             tcg_gen_sar_i64(tcg_ctx, t0, t0, t1);
4225             break;
4226         case OPC_SRL_CP2:
4227             /* We want to shift in zeros for SRL; zero-extend first.  */
4228             tcg_gen_ext32u_i64(tcg_ctx, t0, t0);
4229             /* FALLTHRU */
4230         case OPC_DSRL_CP2:
4231             tcg_gen_shr_i64(tcg_ctx, t0, t0, t1);
4232             break;
4233         }
4234 
4235         if (shift_max == 32) {
4236             tcg_gen_ext32s_i64(tcg_ctx, t0, t0);
4237         }
4238 
4239         /* Shifts larger than MAX produce zero.  */
4240         tcg_gen_setcondi_i64(tcg_ctx, TCG_COND_LTU, t1, t1, shift_max);
4241         tcg_gen_neg_i64(tcg_ctx, t1, t1);
4242         tcg_gen_and_i64(tcg_ctx, t0, t0, t1);
4243         break;
4244 
4245     case OPC_ADD_CP2:
4246     case OPC_DADD_CP2:
4247         {
4248             TCGv_i64 t2 = tcg_temp_new_i64(tcg_ctx);
4249             int lab = gen_new_label(tcg_ctx);
4250 
4251             tcg_gen_mov_i64(tcg_ctx, t2, t0);
4252             tcg_gen_add_i64(tcg_ctx, t0, t1, t2);
4253             if (opc == OPC_ADD_CP2) {
4254                 tcg_gen_ext32s_i64(tcg_ctx, t0, t0);
4255             }
4256             tcg_gen_xor_i64(tcg_ctx, t1, t1, t2);
4257             tcg_gen_xor_i64(tcg_ctx, t2, t2, t0);
4258             tcg_gen_andc_i64(tcg_ctx, t1, t2, t1);
4259             tcg_temp_free_i64(tcg_ctx, t2);
4260             tcg_gen_brcondi_i64(tcg_ctx, TCG_COND_GE, t1, 0, lab);
4261             generate_exception(ctx, EXCP_OVERFLOW);
4262             gen_set_label(tcg_ctx, lab);
4263 
4264             opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
4265             break;
4266         }
4267 
4268     case OPC_SUB_CP2:
4269     case OPC_DSUB_CP2:
4270         {
4271             TCGv_i64 t2 = tcg_temp_new_i64(tcg_ctx);
4272             int lab = gen_new_label(tcg_ctx);
4273 
4274             tcg_gen_mov_i64(tcg_ctx, t2, t0);
4275             tcg_gen_sub_i64(tcg_ctx, t0, t1, t2);
4276             if (opc == OPC_SUB_CP2) {
4277                 tcg_gen_ext32s_i64(tcg_ctx, t0, t0);
4278             }
4279             tcg_gen_xor_i64(tcg_ctx, t1, t1, t2);
4280             tcg_gen_xor_i64(tcg_ctx, t2, t2, t0);
4281             tcg_gen_and_i64(tcg_ctx, t1, t1, t2);
4282             tcg_temp_free_i64(tcg_ctx, t2);
4283             tcg_gen_brcondi_i64(tcg_ctx, TCG_COND_GE, t1, 0, lab);
4284             generate_exception(ctx, EXCP_OVERFLOW);
4285             gen_set_label(tcg_ctx, lab);
4286 
4287             opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
4288             break;
4289         }
4290 
4291     case OPC_PMULUW:
4292         tcg_gen_ext32u_i64(tcg_ctx, t0, t0);
4293         tcg_gen_ext32u_i64(tcg_ctx, t1, t1);
4294         tcg_gen_mul_i64(tcg_ctx, t0, t0, t1);
4295         opn = "pmuluw";
4296         break;
4297 
4298     case OPC_SEQU_CP2:
4299     case OPC_SEQ_CP2:
4300     case OPC_SLTU_CP2:
4301     case OPC_SLT_CP2:
4302     case OPC_SLEU_CP2:
4303     case OPC_SLE_CP2:
4304         /* ??? Document is unclear: Set FCC[CC].  Does that mean the
4305            FD field is the CC field?  */
4306     default:
4307         MIPS_INVAL(opn);
4308         generate_exception(ctx, EXCP_RI);
4309         return;
4310     }
4311 
4312 #undef LMI_HELPER
4313 #undef LMI_DIRECT
4314 
4315     gen_store_fpr64(ctx, t0, rd);
4316 
4317     (void)opn; /* avoid a compiler warning */
4318     MIPS_DEBUG("%s %s, %s, %s", opn,
4319                fregnames[rd], fregnames[rs], fregnames[rt]);
4320     tcg_temp_free_i64(tcg_ctx, t0);
4321     tcg_temp_free_i64(tcg_ctx, t1);
4322 }
4323 
4324 /* Traps */
gen_trap(DisasContext * ctx,uint32_t opc,int rs,int rt,int16_t imm)4325 static void gen_trap (DisasContext *ctx, uint32_t opc,
4326                       int rs, int rt, int16_t imm)
4327 {
4328     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
4329     int cond;
4330     TCGv t0 = tcg_temp_new(tcg_ctx);
4331     TCGv t1 = tcg_temp_new(tcg_ctx);
4332 
4333     cond = 0;
4334     /* Load needed operands */
4335     switch (opc) {
4336     case OPC_TEQ:
4337     case OPC_TGE:
4338     case OPC_TGEU:
4339     case OPC_TLT:
4340     case OPC_TLTU:
4341     case OPC_TNE:
4342         /* Compare two registers */
4343         if (rs != rt) {
4344             gen_load_gpr(ctx, t0, rs);
4345             gen_load_gpr(ctx, t1, rt);
4346             cond = 1;
4347         }
4348         break;
4349     case OPC_TEQI:
4350     case OPC_TGEI:
4351     case OPC_TGEIU:
4352     case OPC_TLTI:
4353     case OPC_TLTIU:
4354     case OPC_TNEI:
4355         /* Compare register to immediate */
4356         if (rs != 0 || imm != 0) {
4357             gen_load_gpr(ctx, t0, rs);
4358             tcg_gen_movi_tl(tcg_ctx, t1, (int32_t)imm);
4359             cond = 1;
4360         }
4361         break;
4362     }
4363     if (cond == 0) {
4364         switch (opc) {
4365         case OPC_TEQ:   /* rs == rs */
4366         case OPC_TEQI:  /* r0 == 0  */
4367         case OPC_TGE:   /* rs >= rs */
4368         case OPC_TGEI:  /* r0 >= 0  */
4369         case OPC_TGEU:  /* rs >= rs unsigned */
4370         case OPC_TGEIU: /* r0 >= 0  unsigned */
4371             /* Always trap */
4372             generate_exception(ctx, EXCP_TRAP);
4373             break;
4374         case OPC_TLT:   /* rs < rs           */
4375         case OPC_TLTI:  /* r0 < 0            */
4376         case OPC_TLTU:  /* rs < rs unsigned  */
4377         case OPC_TLTIU: /* r0 < 0  unsigned  */
4378         case OPC_TNE:   /* rs != rs          */
4379         case OPC_TNEI:  /* r0 != 0           */
4380             /* Never trap: treat as NOP. */
4381             break;
4382         }
4383     } else {
4384         int l1 = gen_new_label(tcg_ctx);
4385 
4386         switch (opc) {
4387         case OPC_TEQ:
4388         case OPC_TEQI:
4389             tcg_gen_brcond_tl(tcg_ctx, TCG_COND_NE, t0, t1, l1);
4390             break;
4391         case OPC_TGE:
4392         case OPC_TGEI:
4393             tcg_gen_brcond_tl(tcg_ctx, TCG_COND_LT, t0, t1, l1);
4394             break;
4395         case OPC_TGEU:
4396         case OPC_TGEIU:
4397             tcg_gen_brcond_tl(tcg_ctx, TCG_COND_LTU, t0, t1, l1);
4398             break;
4399         case OPC_TLT:
4400         case OPC_TLTI:
4401             tcg_gen_brcond_tl(tcg_ctx, TCG_COND_GE, t0, t1, l1);
4402             break;
4403         case OPC_TLTU:
4404         case OPC_TLTIU:
4405             tcg_gen_brcond_tl(tcg_ctx, TCG_COND_GEU, t0, t1, l1);
4406             break;
4407         case OPC_TNE:
4408         case OPC_TNEI:
4409             tcg_gen_brcond_tl(tcg_ctx, TCG_COND_EQ, t0, t1, l1);
4410             break;
4411         }
4412         generate_exception(ctx, EXCP_TRAP);
4413         gen_set_label(tcg_ctx, l1);
4414     }
4415     tcg_temp_free(tcg_ctx, t0);
4416     tcg_temp_free(tcg_ctx, t1);
4417 }
4418 
gen_goto_tb(DisasContext * ctx,int n,target_ulong dest)4419 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
4420 {
4421     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
4422     TranslationBlock *tb;
4423     tb = ctx->tb;
4424     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
4425         likely(!ctx->singlestep_enabled)) {
4426         tcg_gen_goto_tb(tcg_ctx, n);
4427         gen_save_pc(ctx, dest);
4428         tcg_gen_exit_tb(tcg_ctx, (uintptr_t)tb + n);
4429     } else {
4430         gen_save_pc(ctx, dest);
4431         if (ctx->singlestep_enabled) {
4432             save_cpu_state(ctx, 0);
4433             gen_helper_0e0i(tcg_ctx, raise_exception, EXCP_DEBUG);
4434         }
4435         tcg_gen_exit_tb(tcg_ctx, 0);
4436     }
4437 }
4438 
4439 /* 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)4440 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
4441                                 int insn_bytes,
4442                                 int rs, int rt, int32_t offset,
4443                                 int delayslot_size)
4444 {
4445     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
4446     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
4447     target_ulong btgt = -1;
4448     int blink = 0;
4449     int bcond_compute = 0;
4450     TCGv t0 = tcg_temp_new(tcg_ctx);
4451     TCGv t1 = tcg_temp_new(tcg_ctx);
4452 
4453     if (ctx->hflags & MIPS_HFLAG_BMASK) {
4454 #ifdef MIPS_DEBUG_DISAS
4455         LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4456                   TARGET_FMT_lx "\n", ctx->pc);
4457 #endif
4458         generate_exception(ctx, EXCP_RI);
4459         goto out;
4460     }
4461 
4462     /* Load needed operands */
4463     switch (opc) {
4464     case OPC_BEQ:
4465     case OPC_BEQL:
4466     case OPC_BNE:
4467     case OPC_BNEL:
4468         /* Compare two registers */
4469         if (rs != rt) {
4470             gen_load_gpr(ctx, t0, rs);
4471             gen_load_gpr(ctx, t1, rt);
4472             bcond_compute = 1;
4473         }
4474         btgt = ctx->pc + insn_bytes + offset;
4475         break;
4476     case OPC_BGEZ:
4477     case OPC_BGEZAL:
4478     case OPC_BGEZALL:
4479     case OPC_BGEZL:
4480     case OPC_BGTZ:
4481     case OPC_BGTZL:
4482     case OPC_BLEZ:
4483     case OPC_BLEZL:
4484     case OPC_BLTZ:
4485     case OPC_BLTZAL:
4486     case OPC_BLTZALL:
4487     case OPC_BLTZL:
4488         /* Compare to zero */
4489         if (rs != 0) {
4490             gen_load_gpr(ctx, t0, rs);
4491             bcond_compute = 1;
4492         }
4493         btgt = ctx->pc + insn_bytes + offset;
4494         break;
4495     case OPC_BPOSGE32:
4496 #if defined(TARGET_MIPS64)
4497     case OPC_BPOSGE64:
4498         tcg_gen_andi_tl(tcg_ctx, t0, *(TCGv *)tcg_ctx->cpu_dspctrl, 0x7F);
4499 #else
4500         tcg_gen_andi_tl(tcg_ctx, t0, *(TCGv *)tcg_ctx->cpu_dspctrl, 0x3F);
4501 #endif
4502         bcond_compute = 1;
4503         btgt = ctx->pc + insn_bytes + offset;
4504         break;
4505     case OPC_J:
4506     case OPC_JAL:
4507     case OPC_JALX:
4508         /* Jump to immediate */
4509         btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
4510         break;
4511     case OPC_JR:
4512     case OPC_JALR:
4513         /* Jump to register */
4514         if (offset != 0 && offset != 16) {
4515             /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
4516                others are reserved. */
4517             MIPS_INVAL("jump hint");
4518             generate_exception(ctx, EXCP_RI);
4519             goto out;
4520         }
4521         gen_load_gpr(ctx, *(TCGv *)tcg_ctx->btarget, rs);
4522         break;
4523     default:
4524         MIPS_INVAL("branch/jump");
4525         generate_exception(ctx, EXCP_RI);
4526         goto out;
4527     }
4528     if (bcond_compute == 0) {
4529         /* No condition to be computed */
4530         switch (opc) {
4531         case OPC_BEQ:     /* rx == rx        */
4532         case OPC_BEQL:    /* rx == rx likely */
4533         case OPC_BGEZ:    /* 0 >= 0          */
4534         case OPC_BGEZL:   /* 0 >= 0 likely   */
4535         case OPC_BLEZ:    /* 0 <= 0          */
4536         case OPC_BLEZL:   /* 0 <= 0 likely   */
4537             /* Always take */
4538             ctx->hflags |= MIPS_HFLAG_B;
4539             MIPS_DEBUG("balways");
4540             break;
4541         case OPC_BGEZAL:  /* 0 >= 0          */
4542         case OPC_BGEZALL: /* 0 >= 0 likely   */
4543             /* Always take and link */
4544             blink = 31;
4545             ctx->hflags |= MIPS_HFLAG_B;
4546             MIPS_DEBUG("balways and link");
4547             break;
4548         case OPC_BNE:     /* rx != rx        */
4549         case OPC_BGTZ:    /* 0 > 0           */
4550         case OPC_BLTZ:    /* 0 < 0           */
4551             /* Treat as NOP. */
4552             MIPS_DEBUG("bnever (NOP)");
4553             goto out;
4554         case OPC_BLTZAL:  /* 0 < 0           */
4555             /* Handle as an unconditional branch to get correct delay
4556                slot checking.  */
4557             blink = 31;
4558             btgt = ctx->pc + insn_bytes + delayslot_size;
4559             ctx->hflags |= MIPS_HFLAG_B;
4560             MIPS_DEBUG("bnever and link");
4561             break;
4562         case OPC_BLTZALL: /* 0 < 0 likely */
4563             tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[31], ctx->pc + 8);
4564             /* Skip the instruction in the delay slot */
4565             MIPS_DEBUG("bnever, link and skip");
4566             ctx->pc += 4;
4567             goto out;
4568         case OPC_BNEL:    /* rx != rx likely */
4569         case OPC_BGTZL:   /* 0 > 0 likely */
4570         case OPC_BLTZL:   /* 0 < 0 likely */
4571             /* Skip the instruction in the delay slot */
4572             MIPS_DEBUG("bnever and skip");
4573             ctx->pc += 4;
4574             goto out;
4575         case OPC_J:
4576             ctx->hflags |= MIPS_HFLAG_B;
4577             MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
4578             break;
4579         case OPC_JALX:
4580             ctx->hflags |= MIPS_HFLAG_BX;
4581             /* Fallthrough */
4582         case OPC_JAL:
4583             blink = 31;
4584             ctx->hflags |= MIPS_HFLAG_B;
4585             MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
4586             break;
4587         case OPC_JR:
4588             ctx->hflags |= MIPS_HFLAG_BR;
4589             MIPS_DEBUG("jr %s", regnames[rs]);
4590             break;
4591         case OPC_JALR:
4592             blink = rt;
4593             ctx->hflags |= MIPS_HFLAG_BR;
4594             MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
4595             break;
4596         default:
4597             MIPS_INVAL("branch/jump");
4598             generate_exception(ctx, EXCP_RI);
4599             goto out;
4600         }
4601     } else {
4602         switch (opc) {
4603         case OPC_BEQ:
4604             tcg_gen_setcond_tl(tcg_ctx, TCG_COND_EQ, *(TCGv *)tcg_ctx->bcond, t0, t1);
4605             MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
4606                        regnames[rs], regnames[rt], btgt);
4607             goto not_likely;
4608         case OPC_BEQL:
4609             tcg_gen_setcond_tl(tcg_ctx, TCG_COND_EQ, *(TCGv *)tcg_ctx->bcond, t0, t1);
4610             MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
4611                        regnames[rs], regnames[rt], btgt);
4612             goto likely;
4613         case OPC_BNE:
4614             tcg_gen_setcond_tl(tcg_ctx, TCG_COND_NE, *(TCGv *)tcg_ctx->bcond, t0, t1);
4615             MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
4616                        regnames[rs], regnames[rt], btgt);
4617             goto not_likely;
4618         case OPC_BNEL:
4619             tcg_gen_setcond_tl(tcg_ctx, TCG_COND_NE, *(TCGv *)tcg_ctx->bcond, t0, t1);
4620             MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
4621                        regnames[rs], regnames[rt], btgt);
4622             goto likely;
4623         case OPC_BGEZ:
4624             tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_GE, *(TCGv *)tcg_ctx->bcond, t0, 0);
4625             MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
4626             goto not_likely;
4627         case OPC_BGEZL:
4628             tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_GE, *(TCGv *)tcg_ctx->bcond, t0, 0);
4629             MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
4630             goto likely;
4631         case OPC_BGEZAL:
4632             tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_GE, *(TCGv *)tcg_ctx->bcond, t0, 0);
4633             MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
4634             blink = 31;
4635             goto not_likely;
4636         case OPC_BGEZALL:
4637             tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_GE, *(TCGv *)tcg_ctx->bcond, t0, 0);
4638             blink = 31;
4639             MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
4640             goto likely;
4641         case OPC_BGTZ:
4642             tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_GT, *(TCGv *)tcg_ctx->bcond, t0, 0);
4643             MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
4644             goto not_likely;
4645         case OPC_BGTZL:
4646             tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_GT, *(TCGv *)tcg_ctx->bcond, t0, 0);
4647             MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
4648             goto likely;
4649         case OPC_BLEZ:
4650             tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_LE, *(TCGv *)tcg_ctx->bcond, t0, 0);
4651             MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
4652             goto not_likely;
4653         case OPC_BLEZL:
4654             tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_LE, *(TCGv *)tcg_ctx->bcond, t0, 0);
4655             MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
4656             goto likely;
4657         case OPC_BLTZ:
4658             tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_LT, *(TCGv *)tcg_ctx->bcond, t0, 0);
4659             MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
4660             goto not_likely;
4661         case OPC_BLTZL:
4662             tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_LT, *(TCGv *)tcg_ctx->bcond, t0, 0);
4663             MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
4664             goto likely;
4665         case OPC_BPOSGE32:
4666             tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_GE, *(TCGv *)tcg_ctx->bcond, t0, 32);
4667             MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
4668             goto not_likely;
4669 #if defined(TARGET_MIPS64)
4670         case OPC_BPOSGE64:
4671             tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_GE, *(TCGv *)tcg_ctx->bcond, t0, 64);
4672             MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
4673             goto not_likely;
4674 #endif
4675         case OPC_BLTZAL:
4676             tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_LT, *(TCGv *)tcg_ctx->bcond, t0, 0);
4677             blink = 31;
4678             MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
4679         not_likely:
4680             ctx->hflags |= MIPS_HFLAG_BC;
4681             break;
4682         case OPC_BLTZALL:
4683             tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_LT, *(TCGv *)tcg_ctx->bcond, t0, 0);
4684             blink = 31;
4685             MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
4686         likely:
4687             ctx->hflags |= MIPS_HFLAG_BL;
4688             break;
4689         default:
4690             MIPS_INVAL("conditional branch/jump");
4691             generate_exception(ctx, EXCP_RI);
4692             goto out;
4693         }
4694     }
4695     MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
4696                blink, ctx->hflags, btgt);
4697 
4698     ctx->btarget = btgt;
4699 
4700     switch (delayslot_size) {
4701     case 2:
4702         ctx->hflags |= MIPS_HFLAG_BDS16;
4703         break;
4704     case 4:
4705         ctx->hflags |= MIPS_HFLAG_BDS32;
4706         break;
4707     }
4708 
4709     if (blink > 0) {
4710         int post_delay = insn_bytes + delayslot_size;
4711         int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4712 
4713         tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[blink], ctx->pc + post_delay + lowbit);
4714     }
4715 
4716  out:
4717     if (insn_bytes == 2)
4718         ctx->hflags |= MIPS_HFLAG_B16;
4719     tcg_temp_free(tcg_ctx, t0);
4720     tcg_temp_free(tcg_ctx, t1);
4721 }
4722 
4723 /* special3 bitfield operations */
gen_bitops(DisasContext * ctx,uint32_t opc,int rt,int rs,int lsb,int msb)4724 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
4725                         int rs, int lsb, int msb)
4726 {
4727     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
4728     TCGv t0 = tcg_temp_new(tcg_ctx);
4729     TCGv t1 = tcg_temp_new(tcg_ctx);
4730 
4731     gen_load_gpr(ctx, t1, rs);
4732     switch (opc) {
4733     case OPC_EXT:
4734         if (lsb + msb > 31)
4735             goto fail;
4736         tcg_gen_shri_tl(tcg_ctx, t0, t1, lsb);
4737         if (msb != 31) {
4738             tcg_gen_andi_tl(tcg_ctx, t0, t0, (1U << (msb + 1)) - 1);
4739         } else {
4740             tcg_gen_ext32s_tl(tcg_ctx, t0, t0);
4741         }
4742         break;
4743 #if defined(TARGET_MIPS64)
4744     case OPC_DEXTM:
4745         tcg_gen_shri_tl(tcg_ctx, t0, t1, lsb);
4746         if (msb != 31) {
4747             tcg_gen_andi_tl(tcg_ctx, t0, t0, (1ULL << (msb + 1 + 32)) - 1);
4748         }
4749         break;
4750     case OPC_DEXTU:
4751         tcg_gen_shri_tl(tcg_ctx, t0, t1, lsb + 32);
4752         tcg_gen_andi_tl(tcg_ctx, t0, t0, (1ULL << (msb + 1)) - 1);
4753         break;
4754     case OPC_DEXT:
4755         tcg_gen_shri_tl(tcg_ctx, t0, t1, lsb);
4756         tcg_gen_andi_tl(tcg_ctx, t0, t0, (1ULL << (msb + 1)) - 1);
4757         break;
4758 #endif
4759     case OPC_INS:
4760         if (lsb > msb)
4761             goto fail;
4762         gen_load_gpr(ctx, t0, rt);
4763         tcg_gen_deposit_tl(tcg_ctx, t0, t0, t1, lsb, msb - lsb + 1);
4764         tcg_gen_ext32s_tl(tcg_ctx, t0, t0);
4765         break;
4766 #if defined(TARGET_MIPS64)
4767     case OPC_DINSM:
4768         gen_load_gpr(ctx, t0, rt);
4769         tcg_gen_deposit_tl(tcg_ctx, t0, t0, t1, lsb, msb + 32 - lsb + 1);
4770         break;
4771     case OPC_DINSU:
4772         gen_load_gpr(ctx, t0, rt);
4773         tcg_gen_deposit_tl(tcg_ctx, t0, t0, t1, lsb + 32, msb - lsb + 1);
4774         break;
4775     case OPC_DINS:
4776         gen_load_gpr(ctx, t0, rt);
4777         tcg_gen_deposit_tl(tcg_ctx, t0, t0, t1, lsb, msb - lsb + 1);
4778         break;
4779 #endif
4780     default:
4781 fail:
4782         MIPS_INVAL("bitops");
4783         generate_exception(ctx, EXCP_RI);
4784         tcg_temp_free(tcg_ctx, t0);
4785         tcg_temp_free(tcg_ctx, t1);
4786         return;
4787     }
4788     gen_store_gpr(tcg_ctx, t0, rt);
4789     tcg_temp_free(tcg_ctx, t0);
4790     tcg_temp_free(tcg_ctx, t1);
4791 }
4792 
gen_bshfl(DisasContext * ctx,uint32_t op2,int rt,int rd)4793 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4794 {
4795     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
4796     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
4797     TCGv t0;
4798 
4799     if (rd == 0) {
4800         /* If no destination, treat it as a NOP. */
4801         MIPS_DEBUG("NOP");
4802         return;
4803     }
4804 
4805     t0 = tcg_temp_new(tcg_ctx);
4806     gen_load_gpr(ctx, t0, rt);
4807     switch (op2) {
4808     case OPC_WSBH:
4809         {
4810             TCGv t1 = tcg_temp_new(tcg_ctx);
4811 
4812             tcg_gen_shri_tl(tcg_ctx, t1, t0, 8);
4813             tcg_gen_andi_tl(tcg_ctx, t1, t1, 0x00FF00FF);
4814             tcg_gen_shli_tl(tcg_ctx, t0, t0, 8);
4815             tcg_gen_andi_tl(tcg_ctx, t0, t0, ~0x00FF00FF);
4816             tcg_gen_or_tl(tcg_ctx, t0, t0, t1);
4817             tcg_temp_free(tcg_ctx, t1);
4818             tcg_gen_ext32s_tl(tcg_ctx, *cpu_gpr[rd], t0);
4819         }
4820         break;
4821     case OPC_SEB:
4822         tcg_gen_ext8s_tl(tcg_ctx, *cpu_gpr[rd], t0);
4823         break;
4824     case OPC_SEH:
4825         tcg_gen_ext16s_tl(tcg_ctx, *cpu_gpr[rd], t0);
4826         break;
4827 #if defined(TARGET_MIPS64)
4828     case OPC_DSBH:
4829         {
4830             TCGv t1 = tcg_temp_new(tcg_ctx);
4831 
4832             tcg_gen_shri_tl(tcg_ctx, t1, t0, 8);
4833             tcg_gen_andi_tl(tcg_ctx, t1, t1, 0x00FF00FF00FF00FFULL);
4834             tcg_gen_shli_tl(tcg_ctx, t0, t0, 8);
4835             tcg_gen_andi_tl(tcg_ctx, t0, t0, ~0x00FF00FF00FF00FFULL);
4836             tcg_gen_or_tl(tcg_ctx, *cpu_gpr[rd], t0, t1);
4837             tcg_temp_free(tcg_ctx, t1);
4838         }
4839         break;
4840     case OPC_DSHD:
4841         {
4842             TCGv t1 = tcg_temp_new(tcg_ctx);
4843 
4844             tcg_gen_shri_tl(tcg_ctx, t1, t0, 16);
4845             tcg_gen_andi_tl(tcg_ctx, t1, t1, 0x0000FFFF0000FFFFULL);
4846             tcg_gen_shli_tl(tcg_ctx, t0, t0, 16);
4847             tcg_gen_andi_tl(tcg_ctx, t0, t0, ~0x0000FFFF0000FFFFULL);
4848             tcg_gen_or_tl(tcg_ctx, t0, t0, t1);
4849             tcg_gen_shri_tl(tcg_ctx, t1, t0, 32);
4850             tcg_gen_shli_tl(tcg_ctx, t0, t0, 32);
4851             tcg_gen_or_tl(tcg_ctx, *cpu_gpr[rd], t0, t1);
4852             tcg_temp_free(tcg_ctx, t1);
4853         }
4854         break;
4855 #endif
4856     default:
4857         MIPS_INVAL("bsfhl");
4858         generate_exception(ctx, EXCP_RI);
4859         tcg_temp_free(tcg_ctx, t0);
4860         return;
4861     }
4862     tcg_temp_free(tcg_ctx, t0);
4863 }
4864 
4865 #ifndef CONFIG_USER_ONLY
4866 /* CP0 (MMU and control) */
gen_mfc0_load32(DisasContext * ctx,TCGv arg,target_ulong off)4867 static inline void gen_mfc0_load32 (DisasContext *ctx, TCGv arg, target_ulong off)
4868 {
4869     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
4870     TCGv_i32 t0 = tcg_temp_new_i32(tcg_ctx);
4871 
4872     tcg_gen_ld_i32(tcg_ctx, t0, tcg_ctx->cpu_env, off);
4873     tcg_gen_ext_i32_tl(tcg_ctx, arg, t0);
4874     tcg_temp_free_i32(tcg_ctx, t0);
4875 }
4876 
gen_mfc0_load64(DisasContext * ctx,TCGv arg,target_ulong off)4877 static inline void gen_mfc0_load64 (DisasContext *ctx, TCGv arg, target_ulong off)
4878 {
4879     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
4880     tcg_gen_ld_tl(tcg_ctx, arg, tcg_ctx->cpu_env, off);
4881     tcg_gen_ext32s_tl(tcg_ctx, arg, arg);
4882 }
4883 
gen_mtc0_store32(DisasContext * ctx,TCGv arg,target_ulong off)4884 static inline void gen_mtc0_store32 (DisasContext *ctx, TCGv arg, target_ulong off)
4885 {
4886     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
4887     TCGv_i32 t0 = tcg_temp_new_i32(tcg_ctx);
4888 
4889     tcg_gen_trunc_tl_i32(tcg_ctx, t0, arg);
4890     tcg_gen_st_i32(tcg_ctx, t0, tcg_ctx->cpu_env, off);
4891     tcg_temp_free_i32(tcg_ctx, t0);
4892 }
4893 
gen_mtc0_store64(DisasContext * ctx,TCGv arg,target_ulong off)4894 static inline void gen_mtc0_store64 (DisasContext *ctx, TCGv arg, target_ulong off)
4895 {
4896     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
4897     tcg_gen_ext32s_tl(tcg_ctx, arg, arg);
4898     tcg_gen_st_tl(tcg_ctx, arg, tcg_ctx->cpu_env, off);
4899 }
4900 
gen_mfc0_unimplemented(DisasContext * ctx,TCGv arg)4901 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
4902 {
4903     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
4904     if (ctx->insn_flags & ISA_MIPS32R6) {
4905         tcg_gen_movi_tl(tcg_ctx, arg, 0);
4906     } else {
4907         tcg_gen_movi_tl(tcg_ctx, arg, ~0);
4908     }
4909 }
4910 
4911 #define CP0_CHECK(c)                            \
4912     do {                                        \
4913         if (!(c)) {                             \
4914             goto cp0_unimplemented;             \
4915         }                                       \
4916     } while (0)
4917 
gen_mfc0(DisasContext * ctx,TCGv arg,int reg,int sel)4918 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4919 {
4920     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
4921     const char *rn = "invalid";
4922 
4923     if (sel != 0)
4924         check_insn(ctx, ISA_MIPS32);
4925 
4926     switch (reg) {
4927     case 0:
4928         switch (sel) {
4929         case 0:
4930             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_Index));
4931             rn = "Index";
4932             break;
4933         case 1:
4934             CP0_CHECK(ctx->insn_flags & ASE_MT);
4935             gen_helper_mfc0_mvpcontrol(tcg_ctx, arg, tcg_ctx->cpu_env);
4936             rn = "MVPControl";
4937             break;
4938         case 2:
4939             CP0_CHECK(ctx->insn_flags & ASE_MT);
4940             gen_helper_mfc0_mvpconf0(tcg_ctx, arg, tcg_ctx->cpu_env);
4941             rn = "MVPConf0";
4942             break;
4943         case 3:
4944             CP0_CHECK(ctx->insn_flags & ASE_MT);
4945             gen_helper_mfc0_mvpconf1(tcg_ctx, arg, tcg_ctx->cpu_env);
4946             rn = "MVPConf1";
4947             break;
4948         default:
4949             goto cp0_unimplemented;
4950         }
4951         break;
4952     case 1:
4953         switch (sel) {
4954         case 0:
4955             CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
4956             gen_helper_mfc0_random(tcg_ctx, arg, tcg_ctx->cpu_env);
4957             rn = "Random";
4958             break;
4959         case 1:
4960             CP0_CHECK(ctx->insn_flags & ASE_MT);
4961             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_VPEControl));
4962             rn = "VPEControl";
4963             break;
4964         case 2:
4965             CP0_CHECK(ctx->insn_flags & ASE_MT);
4966             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4967             rn = "VPEConf0";
4968             break;
4969         case 3:
4970             CP0_CHECK(ctx->insn_flags & ASE_MT);
4971             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4972             rn = "VPEConf1";
4973             break;
4974         case 4:
4975             CP0_CHECK(ctx->insn_flags & ASE_MT);
4976             gen_mfc0_load64(ctx, arg, offsetof(CPUMIPSState, CP0_YQMask));
4977             rn = "YQMask";
4978             break;
4979         case 5:
4980             CP0_CHECK(ctx->insn_flags & ASE_MT);
4981             gen_mfc0_load64(ctx, arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4982             rn = "VPESchedule";
4983             break;
4984         case 6:
4985             CP0_CHECK(ctx->insn_flags & ASE_MT);
4986             gen_mfc0_load64(ctx, arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4987             rn = "VPEScheFBack";
4988             break;
4989         case 7:
4990             CP0_CHECK(ctx->insn_flags & ASE_MT);
4991             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_VPEOpt));
4992             rn = "VPEOpt";
4993             break;
4994         default:
4995             goto cp0_unimplemented;
4996         }
4997         break;
4998     case 2:
4999         switch (sel) {
5000         case 0:
5001             tcg_gen_ld_tl(tcg_ctx, arg, tcg_ctx->cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
5002 #if defined(TARGET_MIPS64)
5003             if (ctx->rxi) {
5004                 TCGv tmp = tcg_temp_new(tcg_ctx);
5005                 tcg_gen_andi_tl(tcg_ctx, tmp, arg, (3ull << 62));
5006                 tcg_gen_shri_tl(tcg_ctx, tmp, tmp, 32);
5007                 tcg_gen_or_tl(tcg_ctx, arg, arg, tmp);
5008                 tcg_temp_free(tcg_ctx, tmp);
5009             }
5010 #endif
5011             tcg_gen_ext32s_tl(tcg_ctx, arg, arg);
5012             rn = "EntryLo0";
5013             break;
5014         case 1:
5015             CP0_CHECK(ctx->insn_flags & ASE_MT);
5016             gen_helper_mfc0_tcstatus(tcg_ctx, arg, tcg_ctx->cpu_env);
5017             rn = "TCStatus";
5018             break;
5019         case 2:
5020             CP0_CHECK(ctx->insn_flags & ASE_MT);
5021             gen_helper_mfc0_tcbind(tcg_ctx, arg, tcg_ctx->cpu_env);
5022             rn = "TCBind";
5023             break;
5024         case 3:
5025             CP0_CHECK(ctx->insn_flags & ASE_MT);
5026             gen_helper_mfc0_tcrestart(tcg_ctx, arg, tcg_ctx->cpu_env);
5027             rn = "TCRestart";
5028             break;
5029         case 4:
5030             CP0_CHECK(ctx->insn_flags & ASE_MT);
5031             gen_helper_mfc0_tchalt(tcg_ctx, arg, tcg_ctx->cpu_env);
5032             rn = "TCHalt";
5033             break;
5034         case 5:
5035             CP0_CHECK(ctx->insn_flags & ASE_MT);
5036             gen_helper_mfc0_tccontext(tcg_ctx, arg, tcg_ctx->cpu_env);
5037             rn = "TCContext";
5038             break;
5039         case 6:
5040             CP0_CHECK(ctx->insn_flags & ASE_MT);
5041             gen_helper_mfc0_tcschedule(tcg_ctx, arg, tcg_ctx->cpu_env);
5042             rn = "TCSchedule";
5043             break;
5044         case 7:
5045             CP0_CHECK(ctx->insn_flags & ASE_MT);
5046             gen_helper_mfc0_tcschefback(tcg_ctx, arg, tcg_ctx->cpu_env);
5047             rn = "TCScheFBack";
5048             break;
5049         default:
5050             goto cp0_unimplemented;
5051         }
5052         break;
5053     case 3:
5054         switch (sel) {
5055         case 0:
5056             tcg_gen_ld_tl(tcg_ctx, arg, tcg_ctx->cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
5057 #if defined(TARGET_MIPS64)
5058             if (ctx->rxi) {
5059                 TCGv tmp = tcg_temp_new(tcg_ctx);
5060                 tcg_gen_andi_tl(tcg_ctx, tmp, arg, (3ull << 62));
5061                 tcg_gen_shri_tl(tcg_ctx, tmp, tmp, 32);
5062                 tcg_gen_or_tl(tcg_ctx, arg, arg, tmp);
5063                 tcg_temp_free(tcg_ctx, tmp);
5064             }
5065 #endif
5066             tcg_gen_ext32s_tl(tcg_ctx, arg, arg);
5067             rn = "EntryLo1";
5068             break;
5069         default:
5070             goto cp0_unimplemented;
5071         }
5072         break;
5073     case 4:
5074         switch (sel) {
5075         case 0:
5076             tcg_gen_ld_tl(tcg_ctx, arg, tcg_ctx->cpu_env, offsetof(CPUMIPSState, CP0_Context));
5077             tcg_gen_ext32s_tl(tcg_ctx, arg, arg);
5078             rn = "Context";
5079             break;
5080         case 1:
5081 //            gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
5082             rn = "ContextConfig";
5083             goto cp0_unimplemented;
5084 //            break;
5085         case 2:
5086             CP0_CHECK(ctx->ulri);
5087             tcg_gen_ld32s_tl(tcg_ctx, arg, tcg_ctx->cpu_env,
5088                              offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5089             rn = "UserLocal";
5090             break;
5091         default:
5092             goto cp0_unimplemented;
5093         }
5094         break;
5095     case 5:
5096         switch (sel) {
5097         case 0:
5098             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_PageMask));
5099             rn = "PageMask";
5100             break;
5101         case 1:
5102             check_insn(ctx, ISA_MIPS32R2);
5103             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_PageGrain));
5104             rn = "PageGrain";
5105             break;
5106         default:
5107             goto cp0_unimplemented;
5108         }
5109         break;
5110     case 6:
5111         switch (sel) {
5112         case 0:
5113             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_Wired));
5114             rn = "Wired";
5115             break;
5116         case 1:
5117             check_insn(ctx, ISA_MIPS32R2);
5118             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5119             rn = "SRSConf0";
5120             break;
5121         case 2:
5122             check_insn(ctx, ISA_MIPS32R2);
5123             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5124             rn = "SRSConf1";
5125             break;
5126         case 3:
5127             check_insn(ctx, ISA_MIPS32R2);
5128             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5129             rn = "SRSConf2";
5130             break;
5131         case 4:
5132             check_insn(ctx, ISA_MIPS32R2);
5133             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5134             rn = "SRSConf3";
5135             break;
5136         case 5:
5137             check_insn(ctx, ISA_MIPS32R2);
5138             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5139             rn = "SRSConf4";
5140             break;
5141         default:
5142             goto cp0_unimplemented;
5143         }
5144         break;
5145     case 7:
5146         switch (sel) {
5147         case 0:
5148             check_insn(ctx, ISA_MIPS32R2);
5149             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_HWREna));
5150             rn = "HWREna";
5151             break;
5152         default:
5153             goto cp0_unimplemented;
5154         }
5155         break;
5156     case 8:
5157         switch (sel) {
5158         case 0:
5159             tcg_gen_ld_tl(tcg_ctx, arg, tcg_ctx->cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5160             tcg_gen_ext32s_tl(tcg_ctx, arg, arg);
5161             rn = "BadVAddr";
5162             break;
5163         case 1:
5164             CP0_CHECK(ctx->bi);
5165             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_BadInstr));
5166             rn = "BadInstr";
5167             break;
5168         case 2:
5169             CP0_CHECK(ctx->bp);
5170             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5171             rn = "BadInstrP";
5172             break;
5173         default:
5174             goto cp0_unimplemented;
5175         }
5176         break;
5177     case 9:
5178         switch (sel) {
5179         case 0:
5180             /* Mark as an IO operation because we read the time.  */
5181             //if (use_icount)
5182             //    gen_io_start();
5183             gen_helper_mfc0_count(tcg_ctx, arg, tcg_ctx->cpu_env);
5184             //if (use_icount) {
5185             //    gen_io_end();
5186             //}
5187             /* Break the TB to be able to take timer interrupts immediately
5188                after reading count.  */
5189             ctx->bstate = BS_STOP;
5190             rn = "Count";
5191             break;
5192         /* 6,7 are implementation dependent */
5193         default:
5194             goto cp0_unimplemented;
5195         }
5196         break;
5197     case 10:
5198         switch (sel) {
5199         case 0:
5200             tcg_gen_ld_tl(tcg_ctx, arg, tcg_ctx->cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5201             tcg_gen_ext32s_tl(tcg_ctx, arg, arg);
5202             rn = "EntryHi";
5203             break;
5204         default:
5205             goto cp0_unimplemented;
5206         }
5207         break;
5208     case 11:
5209         switch (sel) {
5210         case 0:
5211             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_Compare));
5212             rn = "Compare";
5213             break;
5214         /* 6,7 are implementation dependent */
5215         default:
5216             goto cp0_unimplemented;
5217         }
5218         break;
5219     case 12:
5220         switch (sel) {
5221         case 0:
5222             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_Status));
5223             rn = "Status";
5224             break;
5225         case 1:
5226             check_insn(ctx, ISA_MIPS32R2);
5227             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_IntCtl));
5228             rn = "IntCtl";
5229             break;
5230         case 2:
5231             check_insn(ctx, ISA_MIPS32R2);
5232             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5233             rn = "SRSCtl";
5234             break;
5235         case 3:
5236             check_insn(ctx, ISA_MIPS32R2);
5237             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_SRSMap));
5238             rn = "SRSMap";
5239             break;
5240         default:
5241             goto cp0_unimplemented;
5242        }
5243         break;
5244     case 13:
5245         switch (sel) {
5246         case 0:
5247             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_Cause));
5248             rn = "Cause";
5249             break;
5250         default:
5251             goto cp0_unimplemented;
5252        }
5253         break;
5254     case 14:
5255         switch (sel) {
5256         case 0:
5257             tcg_gen_ld_tl(tcg_ctx, arg, tcg_ctx->cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5258             tcg_gen_ext32s_tl(tcg_ctx, arg, arg);
5259             rn = "EPC";
5260             break;
5261         default:
5262             goto cp0_unimplemented;
5263         }
5264         break;
5265     case 15:
5266         switch (sel) {
5267         case 0:
5268             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_PRid));
5269             rn = "PRid";
5270             break;
5271         case 1:
5272             check_insn(ctx, ISA_MIPS32R2);
5273             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_EBase));
5274             rn = "EBase";
5275             break;
5276         default:
5277             goto cp0_unimplemented;
5278        }
5279         break;
5280     case 16:
5281         switch (sel) {
5282         case 0:
5283             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_Config0));
5284             rn = "Config";
5285             break;
5286         case 1:
5287             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_Config1));
5288             rn = "Config1";
5289             break;
5290         case 2:
5291             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_Config2));
5292             rn = "Config2";
5293             break;
5294         case 3:
5295             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_Config3));
5296             rn = "Config3";
5297             break;
5298         case 4:
5299             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_Config4));
5300             rn = "Config4";
5301             break;
5302         case 5:
5303             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_Config5));
5304             rn = "Config5";
5305             break;
5306         /* 6,7 are implementation dependent */
5307         case 6:
5308             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_Config6));
5309             rn = "Config6";
5310             break;
5311         case 7:
5312             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_Config7));
5313             rn = "Config7";
5314             break;
5315         default:
5316             goto cp0_unimplemented;
5317         }
5318         break;
5319     case 17:
5320         switch (sel) {
5321         case 0:
5322             gen_helper_mfc0_lladdr(tcg_ctx, arg, tcg_ctx->cpu_env);
5323             rn = "LLAddr";
5324             break;
5325         default:
5326             goto cp0_unimplemented;
5327         }
5328         break;
5329     case 18:
5330         switch (sel) {
5331         case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
5332             gen_helper_1e0i(tcg_ctx, mfc0_watchlo, arg, sel);
5333             rn = "WatchLo";
5334             break;
5335         default:
5336             goto cp0_unimplemented;
5337         }
5338         break;
5339     case 19:
5340         switch (sel) {
5341         case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
5342             gen_helper_1e0i(tcg_ctx, mfc0_watchhi, arg, sel);
5343             rn = "WatchHi";
5344             break;
5345         default:
5346             goto cp0_unimplemented;
5347         }
5348         break;
5349     case 20:
5350         switch (sel) {
5351         case 0:
5352 #if defined(TARGET_MIPS64)
5353             check_insn(ctx, ISA_MIPS3);
5354             tcg_gen_ld_tl(tcg_ctx, arg, tcg_ctx->cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5355             tcg_gen_ext32s_tl(tcg_ctx, arg, arg);
5356             rn = "XContext";
5357             break;
5358 #endif
5359         default:
5360             goto cp0_unimplemented;
5361         }
5362         break;
5363     case 21:
5364        /* Officially reserved, but sel 0 is used for R1x000 framemask */
5365         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
5366         switch (sel) {
5367         case 0:
5368             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_Framemask));
5369             rn = "Framemask";
5370             break;
5371         default:
5372             goto cp0_unimplemented;
5373         }
5374         break;
5375     case 22:
5376         tcg_gen_movi_tl(tcg_ctx, arg, 0); /* unimplemented */
5377         rn = "'Diagnostic"; /* implementation dependent */
5378         break;
5379     case 23:
5380         switch (sel) {
5381         case 0:
5382             gen_helper_mfc0_debug(tcg_ctx, arg, tcg_ctx->cpu_env); /* EJTAG support */
5383             rn = "Debug";
5384             break;
5385         case 1:
5386 //            gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
5387             rn = "TraceControl";
5388 //            break;
5389         case 2:
5390 //            gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
5391             rn = "TraceControl2";
5392 //            break;
5393         case 3:
5394 //            gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
5395             rn = "UserTraceData";
5396 //            break;
5397         case 4:
5398 //            gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
5399             rn = "TraceBPC";
5400 //            break;
5401         default:
5402             goto cp0_unimplemented;
5403         }
5404         break;
5405     case 24:
5406         switch (sel) {
5407         case 0:
5408             /* EJTAG support */
5409             tcg_gen_ld_tl(tcg_ctx, arg, tcg_ctx->cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5410             tcg_gen_ext32s_tl(tcg_ctx, arg, arg);
5411             rn = "DEPC";
5412             break;
5413         default:
5414             goto cp0_unimplemented;
5415         }
5416         break;
5417     case 25:
5418         switch (sel) {
5419         case 0:
5420             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_Performance0));
5421             rn = "Performance0";
5422             break;
5423         case 1:
5424 //            gen_helper_mfc0_performance1(arg);
5425             rn = "Performance1";
5426 //            break;
5427         case 2:
5428 //            gen_helper_mfc0_performance2(arg);
5429             rn = "Performance2";
5430 //            break;
5431         case 3:
5432 //            gen_helper_mfc0_performance3(arg);
5433             rn = "Performance3";
5434 //            break;
5435         case 4:
5436 //            gen_helper_mfc0_performance4(arg);
5437             rn = "Performance4";
5438 //            break;
5439         case 5:
5440 //            gen_helper_mfc0_performance5(arg);
5441             rn = "Performance5";
5442 //            break;
5443         case 6:
5444 //            gen_helper_mfc0_performance6(arg);
5445             rn = "Performance6";
5446 //            break;
5447         case 7:
5448 //            gen_helper_mfc0_performance7(arg);
5449             rn = "Performance7";
5450 //            break;
5451         default:
5452             goto cp0_unimplemented;
5453         }
5454         break;
5455     case 26:
5456         tcg_gen_movi_tl(tcg_ctx, arg, 0); /* unimplemented */
5457         rn = "ECC";
5458         break;
5459     case 27:
5460         switch (sel) {
5461         case 0: case 1: case 2: case 3:
5462             tcg_gen_movi_tl(tcg_ctx, arg, 0); /* unimplemented */
5463             rn = "CacheErr";
5464             break;
5465         default:
5466             goto cp0_unimplemented;
5467         }
5468         break;
5469     case 28:
5470         switch (sel) {
5471         case 0:
5472         case 2:
5473         case 4:
5474         case 6:
5475             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_TagLo));
5476             rn = "TagLo";
5477             break;
5478         case 1:
5479         case 3:
5480         case 5:
5481         case 7:
5482             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_DataLo));
5483             rn = "DataLo";
5484             break;
5485         default:
5486             goto cp0_unimplemented;
5487         }
5488         break;
5489     case 29:
5490         switch (sel) {
5491         case 0:
5492         case 2:
5493         case 4:
5494         case 6:
5495             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_TagHi));
5496             rn = "TagHi";
5497             break;
5498         case 1:
5499         case 3:
5500         case 5:
5501         case 7:
5502             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_DataHi));
5503             rn = "DataHi";
5504             break;
5505         default:
5506             goto cp0_unimplemented;
5507         }
5508         break;
5509     case 30:
5510         switch (sel) {
5511         case 0:
5512             tcg_gen_ld_tl(tcg_ctx, arg, tcg_ctx->cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5513             tcg_gen_ext32s_tl(tcg_ctx, arg, arg);
5514             rn = "ErrorEPC";
5515             break;
5516         default:
5517             goto cp0_unimplemented;
5518         }
5519         break;
5520     case 31:
5521         switch (sel) {
5522         case 0:
5523             /* EJTAG support */
5524             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_DESAVE));
5525             rn = "DESAVE";
5526             break;
5527         case 2: case 3: case 4: case 5: case 6: case 7:
5528             CP0_CHECK(ctx->kscrexist & (1 << sel));
5529             tcg_gen_ld_tl(tcg_ctx, arg, tcg_ctx->cpu_env,
5530                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
5531             tcg_gen_ext32s_tl(tcg_ctx, arg, arg);
5532             rn = "KScratch";
5533             break;
5534         default:
5535             goto cp0_unimplemented;
5536         }
5537         break;
5538     default:
5539        goto cp0_unimplemented;
5540     }
5541     (void)rn; /* avoid a compiler warning */
5542     LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5543     return;
5544 
5545 cp0_unimplemented:
5546     LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5547     gen_mfc0_unimplemented(ctx, arg);
5548 }
5549 
gen_mtc0(DisasContext * ctx,TCGv arg,int reg,int sel)5550 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5551 {
5552     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
5553     const char *rn = "invalid";
5554 
5555     if (sel != 0)
5556         check_insn(ctx, ISA_MIPS32);
5557 
5558     //if (use_icount)
5559     //    gen_io_start();
5560 
5561     switch (reg) {
5562     case 0:
5563         switch (sel) {
5564         case 0:
5565             gen_helper_mtc0_index(tcg_ctx, tcg_ctx->cpu_env, arg);
5566             rn = "Index";
5567             break;
5568         case 1:
5569             CP0_CHECK(ctx->insn_flags & ASE_MT);
5570             gen_helper_mtc0_mvpcontrol(tcg_ctx, tcg_ctx->cpu_env, arg);
5571             rn = "MVPControl";
5572             break;
5573         case 2:
5574             CP0_CHECK(ctx->insn_flags & ASE_MT);
5575             /* ignored */
5576             rn = "MVPConf0";
5577             break;
5578         case 3:
5579             CP0_CHECK(ctx->insn_flags & ASE_MT);
5580             /* ignored */
5581             rn = "MVPConf1";
5582             break;
5583         default:
5584             goto cp0_unimplemented;
5585         }
5586         break;
5587     case 1:
5588         switch (sel) {
5589         case 0:
5590             /* ignored */
5591             rn = "Random";
5592             break;
5593         case 1:
5594             CP0_CHECK(ctx->insn_flags & ASE_MT);
5595             gen_helper_mtc0_vpecontrol(tcg_ctx, tcg_ctx->cpu_env, arg);
5596             rn = "VPEControl";
5597             break;
5598         case 2:
5599             CP0_CHECK(ctx->insn_flags & ASE_MT);
5600             gen_helper_mtc0_vpeconf0(tcg_ctx, tcg_ctx->cpu_env, arg);
5601             rn = "VPEConf0";
5602             break;
5603         case 3:
5604             CP0_CHECK(ctx->insn_flags & ASE_MT);
5605             gen_helper_mtc0_vpeconf1(tcg_ctx, tcg_ctx->cpu_env, arg);
5606             rn = "VPEConf1";
5607             break;
5608         case 4:
5609             CP0_CHECK(ctx->insn_flags & ASE_MT);
5610             gen_helper_mtc0_yqmask(tcg_ctx, tcg_ctx->cpu_env, arg);
5611             rn = "YQMask";
5612             break;
5613         case 5:
5614             CP0_CHECK(ctx->insn_flags & ASE_MT);
5615             gen_mtc0_store64(ctx, arg, offsetof(CPUMIPSState, CP0_VPESchedule));
5616             rn = "VPESchedule";
5617             break;
5618         case 6:
5619             CP0_CHECK(ctx->insn_flags & ASE_MT);
5620             gen_mtc0_store64(ctx, arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5621             rn = "VPEScheFBack";
5622             break;
5623         case 7:
5624             CP0_CHECK(ctx->insn_flags & ASE_MT);
5625             gen_helper_mtc0_vpeopt(tcg_ctx, tcg_ctx->cpu_env, arg);
5626             rn = "VPEOpt";
5627             break;
5628         default:
5629             goto cp0_unimplemented;
5630         }
5631         break;
5632     case 2:
5633         switch (sel) {
5634         case 0:
5635             gen_helper_mtc0_entrylo0(tcg_ctx, tcg_ctx->cpu_env, arg);
5636             rn = "EntryLo0";
5637             break;
5638         case 1:
5639             CP0_CHECK(ctx->insn_flags & ASE_MT);
5640             gen_helper_mtc0_tcstatus(tcg_ctx, tcg_ctx->cpu_env, arg);
5641             rn = "TCStatus";
5642             break;
5643         case 2:
5644             CP0_CHECK(ctx->insn_flags & ASE_MT);
5645             gen_helper_mtc0_tcbind(tcg_ctx, tcg_ctx->cpu_env, arg);
5646             rn = "TCBind";
5647             break;
5648         case 3:
5649             CP0_CHECK(ctx->insn_flags & ASE_MT);
5650             gen_helper_mtc0_tcrestart(tcg_ctx, tcg_ctx->cpu_env, arg);
5651             rn = "TCRestart";
5652             break;
5653         case 4:
5654             CP0_CHECK(ctx->insn_flags & ASE_MT);
5655             gen_helper_mtc0_tchalt(tcg_ctx, tcg_ctx->cpu_env, arg);
5656             rn = "TCHalt";
5657             break;
5658         case 5:
5659             CP0_CHECK(ctx->insn_flags & ASE_MT);
5660             gen_helper_mtc0_tccontext(tcg_ctx, tcg_ctx->cpu_env, arg);
5661             rn = "TCContext";
5662             break;
5663         case 6:
5664             CP0_CHECK(ctx->insn_flags & ASE_MT);
5665             gen_helper_mtc0_tcschedule(tcg_ctx, tcg_ctx->cpu_env, arg);
5666             rn = "TCSchedule";
5667             break;
5668         case 7:
5669             CP0_CHECK(ctx->insn_flags & ASE_MT);
5670             gen_helper_mtc0_tcschefback(tcg_ctx, tcg_ctx->cpu_env, arg);
5671             rn = "TCScheFBack";
5672             break;
5673         default:
5674             goto cp0_unimplemented;
5675         }
5676         break;
5677     case 3:
5678         switch (sel) {
5679         case 0:
5680             gen_helper_mtc0_entrylo1(tcg_ctx, tcg_ctx->cpu_env, arg);
5681             rn = "EntryLo1";
5682             break;
5683         default:
5684             goto cp0_unimplemented;
5685         }
5686         break;
5687     case 4:
5688         switch (sel) {
5689         case 0:
5690             gen_helper_mtc0_context(tcg_ctx, tcg_ctx->cpu_env, arg);
5691             rn = "Context";
5692             break;
5693         case 1:
5694 //            gen_helper_mtc0_contextconfig(tcg_ctx->cpu_env, arg); /* SmartMIPS ASE */
5695             rn = "ContextConfig";
5696             goto cp0_unimplemented;
5697 //            break;
5698         case 2:
5699             CP0_CHECK(ctx->ulri);
5700             tcg_gen_st_tl(tcg_ctx, arg, tcg_ctx->cpu_env,
5701                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5702             rn = "UserLocal";
5703             break;
5704         default:
5705             goto cp0_unimplemented;
5706         }
5707         break;
5708     case 5:
5709         switch (sel) {
5710         case 0:
5711             gen_helper_mtc0_pagemask(tcg_ctx, tcg_ctx->cpu_env, arg);
5712             rn = "PageMask";
5713             break;
5714         case 1:
5715             check_insn(ctx, ISA_MIPS32R2);
5716             gen_helper_mtc0_pagegrain(tcg_ctx, tcg_ctx->cpu_env, arg);
5717             rn = "PageGrain";
5718             break;
5719         default:
5720             goto cp0_unimplemented;
5721         }
5722         break;
5723     case 6:
5724         switch (sel) {
5725         case 0:
5726             gen_helper_mtc0_wired(tcg_ctx, tcg_ctx->cpu_env, arg);
5727             rn = "Wired";
5728             break;
5729         case 1:
5730             check_insn(ctx, ISA_MIPS32R2);
5731             gen_helper_mtc0_srsconf0(tcg_ctx, tcg_ctx->cpu_env, arg);
5732             rn = "SRSConf0";
5733             break;
5734         case 2:
5735             check_insn(ctx, ISA_MIPS32R2);
5736             gen_helper_mtc0_srsconf1(tcg_ctx, tcg_ctx->cpu_env, arg);
5737             rn = "SRSConf1";
5738             break;
5739         case 3:
5740             check_insn(ctx, ISA_MIPS32R2);
5741             gen_helper_mtc0_srsconf2(tcg_ctx, tcg_ctx->cpu_env, arg);
5742             rn = "SRSConf2";
5743             break;
5744         case 4:
5745             check_insn(ctx, ISA_MIPS32R2);
5746             gen_helper_mtc0_srsconf3(tcg_ctx, tcg_ctx->cpu_env, arg);
5747             rn = "SRSConf3";
5748             break;
5749         case 5:
5750             check_insn(ctx, ISA_MIPS32R2);
5751             gen_helper_mtc0_srsconf4(tcg_ctx, tcg_ctx->cpu_env, arg);
5752             rn = "SRSConf4";
5753             break;
5754         default:
5755             goto cp0_unimplemented;
5756         }
5757         break;
5758     case 7:
5759         switch (sel) {
5760         case 0:
5761             check_insn(ctx, ISA_MIPS32R2);
5762             gen_helper_mtc0_hwrena(tcg_ctx, tcg_ctx->cpu_env, arg);
5763             ctx->bstate = BS_STOP;
5764             rn = "HWREna";
5765             break;
5766         default:
5767             goto cp0_unimplemented;
5768         }
5769         break;
5770     case 8:
5771         switch (sel) {
5772         case 0:
5773             /* ignored */
5774             rn = "BadVAddr";
5775             break;
5776         case 1:
5777             /* ignored */
5778             rn = "BadInstr";
5779             break;
5780         case 2:
5781             /* ignored */
5782             rn = "BadInstrP";
5783             break;
5784         default:
5785             goto cp0_unimplemented;
5786         }
5787         break;
5788     case 9:
5789         switch (sel) {
5790         case 0:
5791             gen_helper_mtc0_count(tcg_ctx, tcg_ctx->cpu_env, arg);
5792             rn = "Count";
5793             break;
5794         /* 6,7 are implementation dependent */
5795         default:
5796             goto cp0_unimplemented;
5797         }
5798         break;
5799     case 10:
5800         switch (sel) {
5801         case 0:
5802             gen_helper_mtc0_entryhi(tcg_ctx, tcg_ctx->cpu_env, arg);
5803             rn = "EntryHi";
5804             break;
5805         default:
5806             goto cp0_unimplemented;
5807         }
5808         break;
5809     case 11:
5810         switch (sel) {
5811         case 0:
5812             gen_helper_mtc0_compare(tcg_ctx, tcg_ctx->cpu_env, arg);
5813             rn = "Compare";
5814             break;
5815         /* 6,7 are implementation dependent */
5816         default:
5817             goto cp0_unimplemented;
5818         }
5819         break;
5820     case 12:
5821         switch (sel) {
5822         case 0:
5823             save_cpu_state(ctx, 1);
5824             gen_helper_mtc0_status(tcg_ctx, tcg_ctx->cpu_env, arg);
5825             /* BS_STOP isn't good enough here, hflags may have changed. */
5826             gen_save_pc(ctx, ctx->pc + 4);
5827             ctx->bstate = BS_EXCP;
5828             rn = "Status";
5829             break;
5830         case 1:
5831             check_insn(ctx, ISA_MIPS32R2);
5832             gen_helper_mtc0_intctl(tcg_ctx, tcg_ctx->cpu_env, arg);
5833             /* Stop translation as we may have switched the execution mode */
5834             ctx->bstate = BS_STOP;
5835             rn = "IntCtl";
5836             break;
5837         case 2:
5838             check_insn(ctx, ISA_MIPS32R2);
5839             gen_helper_mtc0_srsctl(tcg_ctx, tcg_ctx->cpu_env, arg);
5840             /* Stop translation as we may have switched the execution mode */
5841             ctx->bstate = BS_STOP;
5842             rn = "SRSCtl";
5843             break;
5844         case 3:
5845             check_insn(ctx, ISA_MIPS32R2);
5846             gen_mtc0_store32(ctx, arg, offsetof(CPUMIPSState, CP0_SRSMap));
5847             /* Stop translation as we may have switched the execution mode */
5848             ctx->bstate = BS_STOP;
5849             rn = "SRSMap";
5850             break;
5851         default:
5852             goto cp0_unimplemented;
5853         }
5854         break;
5855     case 13:
5856         switch (sel) {
5857         case 0:
5858             save_cpu_state(ctx, 1);
5859             gen_helper_mtc0_cause(tcg_ctx, tcg_ctx->cpu_env, arg);
5860             rn = "Cause";
5861             break;
5862         default:
5863             goto cp0_unimplemented;
5864         }
5865         break;
5866     case 14:
5867         switch (sel) {
5868         case 0:
5869             gen_mtc0_store64(ctx, arg, offsetof(CPUMIPSState, CP0_EPC));
5870             rn = "EPC";
5871             break;
5872         default:
5873             goto cp0_unimplemented;
5874         }
5875         break;
5876     case 15:
5877         switch (sel) {
5878         case 0:
5879             /* ignored */
5880             rn = "PRid";
5881             break;
5882         case 1:
5883             check_insn(ctx, ISA_MIPS32R2);
5884             gen_helper_mtc0_ebase(tcg_ctx, tcg_ctx->cpu_env, arg);
5885             rn = "EBase";
5886             break;
5887         default:
5888             goto cp0_unimplemented;
5889         }
5890         break;
5891     case 16:
5892         switch (sel) {
5893         case 0:
5894             gen_helper_mtc0_config0(tcg_ctx, tcg_ctx->cpu_env, arg);
5895             rn = "Config";
5896             /* Stop translation as we may have switched the execution mode */
5897             ctx->bstate = BS_STOP;
5898             break;
5899         case 1:
5900             /* ignored, read only */
5901             rn = "Config1";
5902             break;
5903         case 2:
5904             gen_helper_mtc0_config2(tcg_ctx, tcg_ctx->cpu_env, arg);
5905             rn = "Config2";
5906             /* Stop translation as we may have switched the execution mode */
5907             ctx->bstate = BS_STOP;
5908             break;
5909         case 3:
5910             /* ignored, read only */
5911             rn = "Config3";
5912             break;
5913         case 4:
5914             gen_helper_mtc0_config4(tcg_ctx, tcg_ctx->cpu_env, arg);
5915             rn = "Config4";
5916             ctx->bstate = BS_STOP;
5917             break;
5918         case 5:
5919             gen_helper_mtc0_config5(tcg_ctx, tcg_ctx->cpu_env, arg);
5920             rn = "Config5";
5921             /* Stop translation as we may have switched the execution mode */
5922             ctx->bstate = BS_STOP;
5923             break;
5924         /* 6,7 are implementation dependent */
5925         case 6:
5926             /* ignored */
5927             rn = "Config6";
5928             break;
5929         case 7:
5930             /* ignored */
5931             rn = "Config7";
5932             break;
5933         default:
5934             rn = "Invalid config selector";
5935             goto cp0_unimplemented;
5936         }
5937         break;
5938     case 17:
5939         switch (sel) {
5940         case 0:
5941             gen_helper_mtc0_lladdr(tcg_ctx, tcg_ctx->cpu_env, arg);
5942             rn = "LLAddr";
5943             break;
5944         default:
5945             goto cp0_unimplemented;
5946         }
5947         break;
5948     case 18:
5949         switch (sel) {
5950         case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
5951             gen_helper_0e1i(tcg_ctx, mtc0_watchlo, arg, sel);
5952             rn = "WatchLo";
5953             break;
5954         default:
5955             goto cp0_unimplemented;
5956         }
5957         break;
5958     case 19:
5959         switch (sel) {
5960         case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
5961             gen_helper_0e1i(tcg_ctx, mtc0_watchhi, arg, sel);
5962             rn = "WatchHi";
5963             break;
5964         default:
5965             goto cp0_unimplemented;
5966         }
5967         break;
5968     case 20:
5969         switch (sel) {
5970         case 0:
5971 #if defined(TARGET_MIPS64)
5972             check_insn(ctx, ISA_MIPS3);
5973             gen_helper_mtc0_xcontext(tcg_ctx, tcg_ctx->cpu_env, arg);
5974             rn = "XContext";
5975             break;
5976 #endif
5977         default:
5978             goto cp0_unimplemented;
5979         }
5980         break;
5981     case 21:
5982        /* Officially reserved, but sel 0 is used for R1x000 framemask */
5983         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
5984         switch (sel) {
5985         case 0:
5986             gen_helper_mtc0_framemask(tcg_ctx, tcg_ctx->cpu_env, arg);
5987             rn = "Framemask";
5988             break;
5989         default:
5990             goto cp0_unimplemented;
5991         }
5992         break;
5993     case 22:
5994         /* ignored */
5995         rn = "Diagnostic"; /* implementation dependent */
5996         break;
5997     case 23:
5998         switch (sel) {
5999         case 0:
6000             gen_helper_mtc0_debug(tcg_ctx, tcg_ctx->cpu_env, arg); /* EJTAG support */
6001             /* BS_STOP isn't good enough here, hflags may have changed. */
6002             gen_save_pc(ctx, ctx->pc + 4);
6003             ctx->bstate = BS_EXCP;
6004             rn = "Debug";
6005             break;
6006         case 1:
6007 //            gen_helper_mtc0_tracecontrol(tcg_ctx->cpu_env, arg); /* PDtrace support */
6008             rn = "TraceControl";
6009             /* Stop translation as we may have switched the execution mode */
6010             ctx->bstate = BS_STOP;
6011 //            break;
6012         case 2:
6013 //            gen_helper_mtc0_tracecontrol2(tcg_ctx->cpu_env, arg); /* PDtrace support */
6014             rn = "TraceControl2";
6015             /* Stop translation as we may have switched the execution mode */
6016             ctx->bstate = BS_STOP;
6017 //            break;
6018         case 3:
6019             /* Stop translation as we may have switched the execution mode */
6020             ctx->bstate = BS_STOP;
6021 //            gen_helper_mtc0_usertracedata(tcg_ctx->cpu_env, arg); /* PDtrace support */
6022             rn = "UserTraceData";
6023             /* Stop translation as we may have switched the execution mode */
6024             ctx->bstate = BS_STOP;
6025 //            break;
6026         case 4:
6027 //            gen_helper_mtc0_tracebpc(tcg_ctx->cpu_env, arg); /* PDtrace support */
6028             /* Stop translation as we may have switched the execution mode */
6029             ctx->bstate = BS_STOP;
6030             rn = "TraceBPC";
6031 //            break;
6032         default:
6033             goto cp0_unimplemented;
6034         }
6035         break;
6036     case 24:
6037         switch (sel) {
6038         case 0:
6039             /* EJTAG support */
6040             gen_mtc0_store64(ctx, arg, offsetof(CPUMIPSState, CP0_DEPC));
6041             rn = "DEPC";
6042             break;
6043         default:
6044             goto cp0_unimplemented;
6045         }
6046         break;
6047     case 25:
6048         switch (sel) {
6049         case 0:
6050             gen_helper_mtc0_performance0(tcg_ctx, tcg_ctx->cpu_env, arg);
6051             rn = "Performance0";
6052             break;
6053         case 1:
6054 //            gen_helper_mtc0_performance1(arg);
6055             rn = "Performance1";
6056 //            break;
6057         case 2:
6058 //            gen_helper_mtc0_performance2(arg);
6059             rn = "Performance2";
6060 //            break;
6061         case 3:
6062 //            gen_helper_mtc0_performance3(arg);
6063             rn = "Performance3";
6064 //            break;
6065         case 4:
6066 //            gen_helper_mtc0_performance4(arg);
6067             rn = "Performance4";
6068 //            break;
6069         case 5:
6070 //            gen_helper_mtc0_performance5(arg);
6071             rn = "Performance5";
6072 //            break;
6073         case 6:
6074 //            gen_helper_mtc0_performance6(arg);
6075             rn = "Performance6";
6076 //            break;
6077         case 7:
6078 //            gen_helper_mtc0_performance7(arg);
6079             rn = "Performance7";
6080 //            break;
6081         default:
6082             goto cp0_unimplemented;
6083         }
6084        break;
6085     case 26:
6086         /* ignored */
6087         rn = "ECC";
6088         break;
6089     case 27:
6090         switch (sel) {
6091         case 0: case 1: case 2: case 3:
6092             /* ignored */
6093             rn = "CacheErr";
6094             break;
6095         default:
6096             goto cp0_unimplemented;
6097         }
6098        break;
6099     case 28:
6100         switch (sel) {
6101         case 0:
6102         case 2:
6103         case 4:
6104         case 6:
6105             gen_helper_mtc0_taglo(tcg_ctx, tcg_ctx->cpu_env, arg);
6106             rn = "TagLo";
6107             break;
6108         case 1:
6109         case 3:
6110         case 5:
6111         case 7:
6112             gen_helper_mtc0_datalo(tcg_ctx, tcg_ctx->cpu_env, arg);
6113             rn = "DataLo";
6114             break;
6115         default:
6116             goto cp0_unimplemented;
6117         }
6118         break;
6119     case 29:
6120         switch (sel) {
6121         case 0:
6122         case 2:
6123         case 4:
6124         case 6:
6125             gen_helper_mtc0_taghi(tcg_ctx, tcg_ctx->cpu_env, arg);
6126             rn = "TagHi";
6127             break;
6128         case 1:
6129         case 3:
6130         case 5:
6131         case 7:
6132             gen_helper_mtc0_datahi(tcg_ctx, tcg_ctx->cpu_env, arg);
6133             rn = "DataHi";
6134             break;
6135         default:
6136             rn = "invalid sel";
6137             goto cp0_unimplemented;
6138         }
6139        break;
6140     case 30:
6141         switch (sel) {
6142         case 0:
6143             gen_mtc0_store64(ctx, arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
6144             rn = "ErrorEPC";
6145             break;
6146         default:
6147             goto cp0_unimplemented;
6148         }
6149         break;
6150     case 31:
6151         switch (sel) {
6152         case 0:
6153             /* EJTAG support */
6154             gen_mtc0_store32(ctx, arg, offsetof(CPUMIPSState, CP0_DESAVE));
6155             rn = "DESAVE";
6156             break;
6157         case 2: case 3: case 4: case 5: case 6: case 7:
6158             CP0_CHECK(ctx->kscrexist & (1 << sel));
6159             tcg_gen_st_tl(tcg_ctx, arg, tcg_ctx->cpu_env,
6160                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6161             rn = "KScratch";
6162             break;
6163         default:
6164             goto cp0_unimplemented;
6165         }
6166         /* Stop translation as we may have switched the execution mode */
6167         ctx->bstate = BS_STOP;
6168         break;
6169     default:
6170        goto cp0_unimplemented;
6171     }
6172     (void)rn; /* avoid a compiler warning */
6173     LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6174     /* For simplicity assume that all writes can cause interrupts.  */
6175     //if (use_icount) {
6176     //    gen_io_end();
6177     //    ctx->bstate = BS_STOP;
6178     //}
6179     return;
6180 
6181 cp0_unimplemented:
6182     LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6183 }
6184 
6185 #if defined(TARGET_MIPS64)
gen_dmfc0(DisasContext * ctx,TCGv arg,int reg,int sel)6186 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6187 {
6188     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
6189     const char *rn = "invalid";
6190 
6191     if (sel != 0)
6192         check_insn(ctx, ISA_MIPS64);
6193 
6194     switch (reg) {
6195     case 0:
6196         switch (sel) {
6197         case 0:
6198             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_Index));
6199             rn = "Index";
6200             break;
6201         case 1:
6202             CP0_CHECK(ctx->insn_flags & ASE_MT);
6203             gen_helper_mfc0_mvpcontrol(tcg_ctx, arg, tcg_ctx->cpu_env);
6204             rn = "MVPControl";
6205             break;
6206         case 2:
6207             CP0_CHECK(ctx->insn_flags & ASE_MT);
6208             gen_helper_mfc0_mvpconf0(tcg_ctx, arg, tcg_ctx->cpu_env);
6209             rn = "MVPConf0";
6210             break;
6211         case 3:
6212             CP0_CHECK(ctx->insn_flags & ASE_MT);
6213             gen_helper_mfc0_mvpconf1(tcg_ctx, arg, tcg_ctx->cpu_env);
6214             rn = "MVPConf1";
6215             break;
6216         default:
6217             goto cp0_unimplemented;
6218         }
6219         break;
6220     case 1:
6221         switch (sel) {
6222         case 0:
6223             CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6224             gen_helper_mfc0_random(tcg_ctx, arg, tcg_ctx->cpu_env);
6225             rn = "Random";
6226             break;
6227         case 1:
6228             CP0_CHECK(ctx->insn_flags & ASE_MT);
6229             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_VPEControl));
6230             rn = "VPEControl";
6231             break;
6232         case 2:
6233             CP0_CHECK(ctx->insn_flags & ASE_MT);
6234             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_VPEConf0));
6235             rn = "VPEConf0";
6236             break;
6237         case 3:
6238             CP0_CHECK(ctx->insn_flags & ASE_MT);
6239             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_VPEConf1));
6240             rn = "VPEConf1";
6241             break;
6242         case 4:
6243             CP0_CHECK(ctx->insn_flags & ASE_MT);
6244             tcg_gen_ld_tl(tcg_ctx, arg, tcg_ctx->cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
6245             rn = "YQMask";
6246             break;
6247         case 5:
6248             CP0_CHECK(ctx->insn_flags & ASE_MT);
6249             tcg_gen_ld_tl(tcg_ctx, arg, tcg_ctx->cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
6250             rn = "VPESchedule";
6251             break;
6252         case 6:
6253             CP0_CHECK(ctx->insn_flags & ASE_MT);
6254             tcg_gen_ld_tl(tcg_ctx, arg, tcg_ctx->cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6255             rn = "VPEScheFBack";
6256             break;
6257         case 7:
6258             CP0_CHECK(ctx->insn_flags & ASE_MT);
6259             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_VPEOpt));
6260             rn = "VPEOpt";
6261             break;
6262         default:
6263             goto cp0_unimplemented;
6264         }
6265         break;
6266     case 2:
6267         switch (sel) {
6268         case 0:
6269             tcg_gen_ld_tl(tcg_ctx, arg, tcg_ctx->cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
6270             rn = "EntryLo0";
6271             break;
6272         case 1:
6273             CP0_CHECK(ctx->insn_flags & ASE_MT);
6274             gen_helper_mfc0_tcstatus(tcg_ctx, arg, tcg_ctx->cpu_env);
6275             rn = "TCStatus";
6276             break;
6277         case 2:
6278             CP0_CHECK(ctx->insn_flags & ASE_MT);
6279             gen_helper_mfc0_tcbind(tcg_ctx, arg, tcg_ctx->cpu_env);
6280             rn = "TCBind";
6281             break;
6282         case 3:
6283             CP0_CHECK(ctx->insn_flags & ASE_MT);
6284             gen_helper_dmfc0_tcrestart(tcg_ctx, arg, tcg_ctx->cpu_env);
6285             rn = "TCRestart";
6286             break;
6287         case 4:
6288             CP0_CHECK(ctx->insn_flags & ASE_MT);
6289             gen_helper_dmfc0_tchalt(tcg_ctx, arg, tcg_ctx->cpu_env);
6290             rn = "TCHalt";
6291             break;
6292         case 5:
6293             CP0_CHECK(ctx->insn_flags & ASE_MT);
6294             gen_helper_dmfc0_tccontext(tcg_ctx, arg, tcg_ctx->cpu_env);
6295             rn = "TCContext";
6296             break;
6297         case 6:
6298             CP0_CHECK(ctx->insn_flags & ASE_MT);
6299             gen_helper_dmfc0_tcschedule(tcg_ctx, arg, tcg_ctx->cpu_env);
6300             rn = "TCSchedule";
6301             break;
6302         case 7:
6303             CP0_CHECK(ctx->insn_flags & ASE_MT);
6304             gen_helper_dmfc0_tcschefback(tcg_ctx, arg, tcg_ctx->cpu_env);
6305             rn = "TCScheFBack";
6306             break;
6307         default:
6308             goto cp0_unimplemented;
6309         }
6310         break;
6311     case 3:
6312         switch (sel) {
6313         case 0:
6314             tcg_gen_ld_tl(tcg_ctx, arg, tcg_ctx->cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
6315             rn = "EntryLo1";
6316             break;
6317         default:
6318             goto cp0_unimplemented;
6319         }
6320         break;
6321     case 4:
6322         switch (sel) {
6323         case 0:
6324             tcg_gen_ld_tl(tcg_ctx, arg, tcg_ctx->cpu_env, offsetof(CPUMIPSState, CP0_Context));
6325             rn = "Context";
6326             break;
6327         case 1:
6328 //            gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
6329             rn = "ContextConfig";
6330             goto cp0_unimplemented;
6331 //            break;
6332         case 2:
6333             CP0_CHECK(ctx->ulri);
6334             tcg_gen_ld_tl(tcg_ctx, arg, tcg_ctx->cpu_env,
6335                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6336             rn = "UserLocal";
6337             break;
6338         default:
6339             goto cp0_unimplemented;
6340         }
6341         break;
6342     case 5:
6343         switch (sel) {
6344         case 0:
6345             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_PageMask));
6346             rn = "PageMask";
6347             break;
6348         case 1:
6349             check_insn(ctx, ISA_MIPS32R2);
6350             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_PageGrain));
6351             rn = "PageGrain";
6352             break;
6353         default:
6354             goto cp0_unimplemented;
6355         }
6356         break;
6357     case 6:
6358         switch (sel) {
6359         case 0:
6360             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_Wired));
6361             rn = "Wired";
6362             break;
6363         case 1:
6364             check_insn(ctx, ISA_MIPS32R2);
6365             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_SRSConf0));
6366             rn = "SRSConf0";
6367             break;
6368         case 2:
6369             check_insn(ctx, ISA_MIPS32R2);
6370             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_SRSConf1));
6371             rn = "SRSConf1";
6372             break;
6373         case 3:
6374             check_insn(ctx, ISA_MIPS32R2);
6375             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_SRSConf2));
6376             rn = "SRSConf2";
6377             break;
6378         case 4:
6379             check_insn(ctx, ISA_MIPS32R2);
6380             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_SRSConf3));
6381             rn = "SRSConf3";
6382             break;
6383         case 5:
6384             check_insn(ctx, ISA_MIPS32R2);
6385             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_SRSConf4));
6386             rn = "SRSConf4";
6387             break;
6388         default:
6389             goto cp0_unimplemented;
6390         }
6391         break;
6392     case 7:
6393         switch (sel) {
6394         case 0:
6395             check_insn(ctx, ISA_MIPS32R2);
6396             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_HWREna));
6397             rn = "HWREna";
6398             break;
6399         default:
6400             goto cp0_unimplemented;
6401         }
6402         break;
6403     case 8:
6404         switch (sel) {
6405         case 0:
6406             tcg_gen_ld_tl(tcg_ctx, arg, tcg_ctx->cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
6407             rn = "BadVAddr";
6408             break;
6409         case 1:
6410             CP0_CHECK(ctx->bi);
6411             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_BadInstr));
6412             rn = "BadInstr";
6413             break;
6414         case 2:
6415             CP0_CHECK(ctx->bp);
6416             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6417             rn = "BadInstrP";
6418             break;
6419         default:
6420             goto cp0_unimplemented;
6421         }
6422         break;
6423     case 9:
6424         switch (sel) {
6425         case 0:
6426             /* Mark as an IO operation because we read the time.  */
6427             //if (use_icount)
6428             //    gen_io_start();
6429             gen_helper_mfc0_count(tcg_ctx, arg, tcg_ctx->cpu_env);
6430             //if (use_icount) {
6431             //    gen_io_end();
6432             //}
6433             /* Break the TB to be able to take timer interrupts immediately
6434                after reading count.  */
6435             ctx->bstate = BS_STOP;
6436             rn = "Count";
6437             break;
6438         /* 6,7 are implementation dependent */
6439         default:
6440             goto cp0_unimplemented;
6441         }
6442         break;
6443     case 10:
6444         switch (sel) {
6445         case 0:
6446             tcg_gen_ld_tl(tcg_ctx, arg, tcg_ctx->cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
6447             rn = "EntryHi";
6448             break;
6449         default:
6450             goto cp0_unimplemented;
6451         }
6452         break;
6453     case 11:
6454         switch (sel) {
6455         case 0:
6456             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_Compare));
6457             rn = "Compare";
6458             break;
6459         /* 6,7 are implementation dependent */
6460         default:
6461             goto cp0_unimplemented;
6462         }
6463         break;
6464     case 12:
6465         switch (sel) {
6466         case 0:
6467             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_Status));
6468             rn = "Status";
6469             break;
6470         case 1:
6471             check_insn(ctx, ISA_MIPS32R2);
6472             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_IntCtl));
6473             rn = "IntCtl";
6474             break;
6475         case 2:
6476             check_insn(ctx, ISA_MIPS32R2);
6477             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_SRSCtl));
6478             rn = "SRSCtl";
6479             break;
6480         case 3:
6481             check_insn(ctx, ISA_MIPS32R2);
6482             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_SRSMap));
6483             rn = "SRSMap";
6484             break;
6485         default:
6486             goto cp0_unimplemented;
6487         }
6488         break;
6489     case 13:
6490         switch (sel) {
6491         case 0:
6492             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_Cause));
6493             rn = "Cause";
6494             break;
6495         default:
6496             goto cp0_unimplemented;
6497         }
6498         break;
6499     case 14:
6500         switch (sel) {
6501         case 0:
6502             tcg_gen_ld_tl(tcg_ctx, arg, tcg_ctx->cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6503             rn = "EPC";
6504             break;
6505         default:
6506             goto cp0_unimplemented;
6507         }
6508         break;
6509     case 15:
6510         switch (sel) {
6511         case 0:
6512             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_PRid));
6513             rn = "PRid";
6514             break;
6515         case 1:
6516             check_insn(ctx, ISA_MIPS32R2);
6517             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_EBase));
6518             rn = "EBase";
6519             break;
6520         default:
6521             goto cp0_unimplemented;
6522         }
6523         break;
6524     case 16:
6525         switch (sel) {
6526         case 0:
6527             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_Config0));
6528             rn = "Config";
6529             break;
6530         case 1:
6531             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_Config1));
6532             rn = "Config1";
6533             break;
6534         case 2:
6535             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_Config2));
6536             rn = "Config2";
6537             break;
6538         case 3:
6539             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_Config3));
6540             rn = "Config3";
6541             break;
6542         case 4:
6543             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_Config4));
6544             rn = "Config4";
6545             break;
6546         case 5:
6547             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_Config5));
6548             rn = "Config5";
6549             break;
6550        /* 6,7 are implementation dependent */
6551         case 6:
6552             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_Config6));
6553             rn = "Config6";
6554             break;
6555         case 7:
6556             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_Config7));
6557             rn = "Config7";
6558             break;
6559         default:
6560             goto cp0_unimplemented;
6561         }
6562         break;
6563     case 17:
6564         switch (sel) {
6565         case 0:
6566             gen_helper_dmfc0_lladdr(tcg_ctx, arg, tcg_ctx->cpu_env);
6567             rn = "LLAddr";
6568             break;
6569         default:
6570             goto cp0_unimplemented;
6571         }
6572         break;
6573     case 18:
6574         switch (sel) {
6575         case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
6576             gen_helper_1e0i(tcg_ctx, dmfc0_watchlo, arg, sel);
6577             rn = "WatchLo";
6578             break;
6579         default:
6580             goto cp0_unimplemented;
6581         }
6582         break;
6583     case 19:
6584         switch (sel) {
6585         case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
6586             gen_helper_1e0i(tcg_ctx, mfc0_watchhi, arg, sel);
6587             rn = "WatchHi";
6588             break;
6589         default:
6590             goto cp0_unimplemented;
6591         }
6592         break;
6593     case 20:
6594         switch (sel) {
6595         case 0:
6596             check_insn(ctx, ISA_MIPS3);
6597             tcg_gen_ld_tl(tcg_ctx, arg, tcg_ctx->cpu_env, offsetof(CPUMIPSState, CP0_XContext));
6598             rn = "XContext";
6599             break;
6600         default:
6601             goto cp0_unimplemented;
6602         }
6603         break;
6604     case 21:
6605        /* Officially reserved, but sel 0 is used for R1x000 framemask */
6606         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6607         switch (sel) {
6608         case 0:
6609             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_Framemask));
6610             rn = "Framemask";
6611             break;
6612         default:
6613             goto cp0_unimplemented;
6614         }
6615         break;
6616     case 22:
6617         tcg_gen_movi_tl(tcg_ctx, arg, 0); /* unimplemented */
6618         rn = "'Diagnostic"; /* implementation dependent */
6619         break;
6620     case 23:
6621         switch (sel) {
6622         case 0:
6623             gen_helper_mfc0_debug(tcg_ctx, arg, tcg_ctx->cpu_env); /* EJTAG support */
6624             rn = "Debug";
6625             break;
6626         case 1:
6627 //            gen_helper_dmfc0_tracecontrol(arg, tcg_ctx->cpu_env); /* PDtrace support */
6628             rn = "TraceControl";
6629 //            break;
6630         case 2:
6631 //            gen_helper_dmfc0_tracecontrol2(arg, tcg_ctx->cpu_env); /* PDtrace support */
6632             rn = "TraceControl2";
6633 //            break;
6634         case 3:
6635 //            gen_helper_dmfc0_usertracedata(arg, tcg_ctx->cpu_env); /* PDtrace support */
6636             rn = "UserTraceData";
6637 //            break;
6638         case 4:
6639 //            gen_helper_dmfc0_tracebpc(arg, tcg_ctx->cpu_env); /* PDtrace support */
6640             rn = "TraceBPC";
6641 //            break;
6642         default:
6643             goto cp0_unimplemented;
6644         }
6645         break;
6646     case 24:
6647         switch (sel) {
6648         case 0:
6649             /* EJTAG support */
6650             tcg_gen_ld_tl(tcg_ctx, arg, tcg_ctx->cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6651             rn = "DEPC";
6652             break;
6653         default:
6654             goto cp0_unimplemented;
6655         }
6656         break;
6657     case 25:
6658         switch (sel) {
6659         case 0:
6660             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_Performance0));
6661             rn = "Performance0";
6662             break;
6663         case 1:
6664 //            gen_helper_dmfc0_performance1(arg);
6665             rn = "Performance1";
6666 //            break;
6667         case 2:
6668 //            gen_helper_dmfc0_performance2(arg);
6669             rn = "Performance2";
6670 //            break;
6671         case 3:
6672 //            gen_helper_dmfc0_performance3(arg);
6673             rn = "Performance3";
6674 //            break;
6675         case 4:
6676 //            gen_helper_dmfc0_performance4(arg);
6677             rn = "Performance4";
6678 //            break;
6679         case 5:
6680 //            gen_helper_dmfc0_performance5(arg);
6681             rn = "Performance5";
6682 //            break;
6683         case 6:
6684 //            gen_helper_dmfc0_performance6(arg);
6685             rn = "Performance6";
6686 //            break;
6687         case 7:
6688 //            gen_helper_dmfc0_performance7(arg);
6689             rn = "Performance7";
6690 //            break;
6691         default:
6692             goto cp0_unimplemented;
6693         }
6694         break;
6695     case 26:
6696         tcg_gen_movi_tl(tcg_ctx, arg, 0); /* unimplemented */
6697         rn = "ECC";
6698         break;
6699     case 27:
6700         switch (sel) {
6701         /* ignored */
6702         case 0: case 1: case 2: case 3:
6703             tcg_gen_movi_tl(tcg_ctx, arg, 0); /* unimplemented */
6704             rn = "CacheErr";
6705             break;
6706         default:
6707             goto cp0_unimplemented;
6708         }
6709         break;
6710     case 28:
6711         switch (sel) {
6712         case 0:
6713         case 2:
6714         case 4:
6715         case 6:
6716             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_TagLo));
6717             rn = "TagLo";
6718             break;
6719         case 1:
6720         case 3:
6721         case 5:
6722         case 7:
6723             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_DataLo));
6724             rn = "DataLo";
6725             break;
6726         default:
6727             goto cp0_unimplemented;
6728         }
6729         break;
6730     case 29:
6731         switch (sel) {
6732         case 0:
6733         case 2:
6734         case 4:
6735         case 6:
6736             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_TagHi));
6737             rn = "TagHi";
6738             break;
6739         case 1:
6740         case 3:
6741         case 5:
6742         case 7:
6743             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_DataHi));
6744             rn = "DataHi";
6745             break;
6746         default:
6747             goto cp0_unimplemented;
6748         }
6749         break;
6750     case 30:
6751         switch (sel) {
6752         case 0:
6753             tcg_gen_ld_tl(tcg_ctx, arg, tcg_ctx->cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6754             rn = "ErrorEPC";
6755             break;
6756         default:
6757             goto cp0_unimplemented;
6758         }
6759         break;
6760     case 31:
6761         switch (sel) {
6762         case 0:
6763             /* EJTAG support */
6764             gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_DESAVE));
6765             rn = "DESAVE";
6766             break;
6767         case 2: case 3: case 4: case 5: case 6: case 7:
6768             CP0_CHECK(ctx->kscrexist & (1 << sel));
6769             tcg_gen_ld_tl(tcg_ctx, arg, tcg_ctx->cpu_env,
6770                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6771             rn = "KScratch";
6772             break;
6773         default:
6774             goto cp0_unimplemented;
6775         }
6776         break;
6777     default:
6778         goto cp0_unimplemented;
6779     }
6780     (void)rn; /* avoid a compiler warning */
6781     LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
6782     return;
6783 
6784 cp0_unimplemented:
6785     LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
6786     gen_mfc0_unimplemented(ctx, arg);
6787 }
6788 
gen_dmtc0(DisasContext * ctx,TCGv arg,int reg,int sel)6789 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6790 {
6791     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
6792     const char *rn = "invalid";
6793 
6794     if (sel != 0)
6795         check_insn(ctx, ISA_MIPS64);
6796 
6797     //if (use_icount)
6798     //    gen_io_start();
6799 
6800     switch (reg) {
6801     case 0:
6802         switch (sel) {
6803         case 0:
6804             gen_helper_mtc0_index(tcg_ctx, tcg_ctx->cpu_env, arg);
6805             rn = "Index";
6806             break;
6807         case 1:
6808             CP0_CHECK(ctx->insn_flags & ASE_MT);
6809             gen_helper_mtc0_mvpcontrol(tcg_ctx, tcg_ctx->cpu_env, arg);
6810             rn = "MVPControl";
6811             break;
6812         case 2:
6813             CP0_CHECK(ctx->insn_flags & ASE_MT);
6814             /* ignored */
6815             rn = "MVPConf0";
6816             break;
6817         case 3:
6818             CP0_CHECK(ctx->insn_flags & ASE_MT);
6819             /* ignored */
6820             rn = "MVPConf1";
6821             break;
6822         default:
6823             goto cp0_unimplemented;
6824         }
6825         break;
6826     case 1:
6827         switch (sel) {
6828         case 0:
6829             /* ignored */
6830             rn = "Random";
6831             break;
6832         case 1:
6833             CP0_CHECK(ctx->insn_flags & ASE_MT);
6834             gen_helper_mtc0_vpecontrol(tcg_ctx, tcg_ctx->cpu_env, arg);
6835             rn = "VPEControl";
6836             break;
6837         case 2:
6838             CP0_CHECK(ctx->insn_flags & ASE_MT);
6839             gen_helper_mtc0_vpeconf0(tcg_ctx, tcg_ctx->cpu_env, arg);
6840             rn = "VPEConf0";
6841             break;
6842         case 3:
6843             CP0_CHECK(ctx->insn_flags & ASE_MT);
6844             gen_helper_mtc0_vpeconf1(tcg_ctx, tcg_ctx->cpu_env, arg);
6845             rn = "VPEConf1";
6846             break;
6847         case 4:
6848             CP0_CHECK(ctx->insn_flags & ASE_MT);
6849             gen_helper_mtc0_yqmask(tcg_ctx, tcg_ctx->cpu_env, arg);
6850             rn = "YQMask";
6851             break;
6852         case 5:
6853             CP0_CHECK(ctx->insn_flags & ASE_MT);
6854             tcg_gen_st_tl(tcg_ctx, arg, tcg_ctx->cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
6855             rn = "VPESchedule";
6856             break;
6857         case 6:
6858             CP0_CHECK(ctx->insn_flags & ASE_MT);
6859             tcg_gen_st_tl(tcg_ctx, arg, tcg_ctx->cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6860             rn = "VPEScheFBack";
6861             break;
6862         case 7:
6863             CP0_CHECK(ctx->insn_flags & ASE_MT);
6864             gen_helper_mtc0_vpeopt(tcg_ctx, tcg_ctx->cpu_env, arg);
6865             rn = "VPEOpt";
6866             break;
6867         default:
6868             goto cp0_unimplemented;
6869         }
6870         break;
6871     case 2:
6872         switch (sel) {
6873         case 0:
6874             gen_helper_dmtc0_entrylo0(tcg_ctx, tcg_ctx->cpu_env, arg);
6875             rn = "EntryLo0";
6876             break;
6877         case 1:
6878             CP0_CHECK(ctx->insn_flags & ASE_MT);
6879             gen_helper_mtc0_tcstatus(tcg_ctx, tcg_ctx->cpu_env, arg);
6880             rn = "TCStatus";
6881             break;
6882         case 2:
6883             CP0_CHECK(ctx->insn_flags & ASE_MT);
6884             gen_helper_mtc0_tcbind(tcg_ctx, tcg_ctx->cpu_env, arg);
6885             rn = "TCBind";
6886             break;
6887         case 3:
6888             CP0_CHECK(ctx->insn_flags & ASE_MT);
6889             gen_helper_mtc0_tcrestart(tcg_ctx, tcg_ctx->cpu_env, arg);
6890             rn = "TCRestart";
6891             break;
6892         case 4:
6893             CP0_CHECK(ctx->insn_flags & ASE_MT);
6894             gen_helper_mtc0_tchalt(tcg_ctx, tcg_ctx->cpu_env, arg);
6895             rn = "TCHalt";
6896             break;
6897         case 5:
6898             CP0_CHECK(ctx->insn_flags & ASE_MT);
6899             gen_helper_mtc0_tccontext(tcg_ctx, tcg_ctx->cpu_env, arg);
6900             rn = "TCContext";
6901             break;
6902         case 6:
6903             CP0_CHECK(ctx->insn_flags & ASE_MT);
6904             gen_helper_mtc0_tcschedule(tcg_ctx, tcg_ctx->cpu_env, arg);
6905             rn = "TCSchedule";
6906             break;
6907         case 7:
6908             CP0_CHECK(ctx->insn_flags & ASE_MT);
6909             gen_helper_mtc0_tcschefback(tcg_ctx, tcg_ctx->cpu_env, arg);
6910             rn = "TCScheFBack";
6911             break;
6912         default:
6913             goto cp0_unimplemented;
6914         }
6915         break;
6916     case 3:
6917         switch (sel) {
6918         case 0:
6919             gen_helper_dmtc0_entrylo1(tcg_ctx, tcg_ctx->cpu_env, arg);
6920             rn = "EntryLo1";
6921             break;
6922         default:
6923             goto cp0_unimplemented;
6924         }
6925         break;
6926     case 4:
6927         switch (sel) {
6928         case 0:
6929             gen_helper_mtc0_context(tcg_ctx, tcg_ctx->cpu_env, arg);
6930             rn = "Context";
6931             break;
6932         case 1:
6933 //           gen_helper_mtc0_contextconfig(tcg_ctx->cpu_env, arg); /* SmartMIPS ASE */
6934             rn = "ContextConfig";
6935             goto cp0_unimplemented;
6936 //           break;
6937         case 2:
6938             CP0_CHECK(ctx->ulri);
6939             tcg_gen_st_tl(tcg_ctx, arg, tcg_ctx->cpu_env,
6940                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6941             rn = "UserLocal";
6942             break;
6943         default:
6944             goto cp0_unimplemented;
6945         }
6946         break;
6947     case 5:
6948         switch (sel) {
6949         case 0:
6950             gen_helper_mtc0_pagemask(tcg_ctx, tcg_ctx->cpu_env, arg);
6951             rn = "PageMask";
6952             break;
6953         case 1:
6954             check_insn(ctx, ISA_MIPS32R2);
6955             gen_helper_mtc0_pagegrain(tcg_ctx, tcg_ctx->cpu_env, arg);
6956             rn = "PageGrain";
6957             break;
6958         default:
6959             goto cp0_unimplemented;
6960         }
6961         break;
6962     case 6:
6963         switch (sel) {
6964         case 0:
6965             gen_helper_mtc0_wired(tcg_ctx, tcg_ctx->cpu_env, arg);
6966             rn = "Wired";
6967             break;
6968         case 1:
6969             check_insn(ctx, ISA_MIPS32R2);
6970             gen_helper_mtc0_srsconf0(tcg_ctx, tcg_ctx->cpu_env, arg);
6971             rn = "SRSConf0";
6972             break;
6973         case 2:
6974             check_insn(ctx, ISA_MIPS32R2);
6975             gen_helper_mtc0_srsconf1(tcg_ctx, tcg_ctx->cpu_env, arg);
6976             rn = "SRSConf1";
6977             break;
6978         case 3:
6979             check_insn(ctx, ISA_MIPS32R2);
6980             gen_helper_mtc0_srsconf2(tcg_ctx, tcg_ctx->cpu_env, arg);
6981             rn = "SRSConf2";
6982             break;
6983         case 4:
6984             check_insn(ctx, ISA_MIPS32R2);
6985             gen_helper_mtc0_srsconf3(tcg_ctx, tcg_ctx->cpu_env, arg);
6986             rn = "SRSConf3";
6987             break;
6988         case 5:
6989             check_insn(ctx, ISA_MIPS32R2);
6990             gen_helper_mtc0_srsconf4(tcg_ctx, tcg_ctx->cpu_env, arg);
6991             rn = "SRSConf4";
6992             break;
6993         default:
6994             goto cp0_unimplemented;
6995         }
6996         break;
6997     case 7:
6998         switch (sel) {
6999         case 0:
7000             check_insn(ctx, ISA_MIPS32R2);
7001             gen_helper_mtc0_hwrena(tcg_ctx, tcg_ctx->cpu_env, arg);
7002             ctx->bstate = BS_STOP;
7003             rn = "HWREna";
7004             break;
7005         default:
7006             goto cp0_unimplemented;
7007         }
7008         break;
7009     case 8:
7010         switch (sel) {
7011         case 0:
7012             /* ignored */
7013             rn = "BadVAddr";
7014             break;
7015         case 1:
7016             /* ignored */
7017             rn = "BadInstr";
7018             break;
7019         case 2:
7020             /* ignored */
7021             rn = "BadInstrP";
7022             break;
7023         default:
7024             goto cp0_unimplemented;
7025         }
7026         break;
7027     case 9:
7028         switch (sel) {
7029         case 0:
7030             gen_helper_mtc0_count(tcg_ctx, tcg_ctx->cpu_env, arg);
7031             rn = "Count";
7032             break;
7033         /* 6,7 are implementation dependent */
7034         default:
7035             goto cp0_unimplemented;
7036         }
7037         /* Stop translation as we may have switched the execution mode */
7038         ctx->bstate = BS_STOP;
7039         break;
7040     case 10:
7041         switch (sel) {
7042         case 0:
7043             gen_helper_mtc0_entryhi(tcg_ctx, tcg_ctx->cpu_env, arg);
7044             rn = "EntryHi";
7045             break;
7046         default:
7047             goto cp0_unimplemented;
7048         }
7049         break;
7050     case 11:
7051         switch (sel) {
7052         case 0:
7053             gen_helper_mtc0_compare(tcg_ctx, tcg_ctx->cpu_env, arg);
7054             rn = "Compare";
7055             break;
7056         /* 6,7 are implementation dependent */
7057         default:
7058             goto cp0_unimplemented;
7059         }
7060         /* Stop translation as we may have switched the execution mode */
7061         ctx->bstate = BS_STOP;
7062         break;
7063     case 12:
7064         switch (sel) {
7065         case 0:
7066             save_cpu_state(ctx, 1);
7067             gen_helper_mtc0_status(tcg_ctx, tcg_ctx->cpu_env, arg);
7068             /* BS_STOP isn't good enough here, hflags may have changed. */
7069             gen_save_pc(ctx, ctx->pc + 4);
7070             ctx->bstate = BS_EXCP;
7071             rn = "Status";
7072             break;
7073         case 1:
7074             check_insn(ctx, ISA_MIPS32R2);
7075             gen_helper_mtc0_intctl(tcg_ctx, tcg_ctx->cpu_env, arg);
7076             /* Stop translation as we may have switched the execution mode */
7077             ctx->bstate = BS_STOP;
7078             rn = "IntCtl";
7079             break;
7080         case 2:
7081             check_insn(ctx, ISA_MIPS32R2);
7082             gen_helper_mtc0_srsctl(tcg_ctx, tcg_ctx->cpu_env, arg);
7083             /* Stop translation as we may have switched the execution mode */
7084             ctx->bstate = BS_STOP;
7085             rn = "SRSCtl";
7086             break;
7087         case 3:
7088             check_insn(ctx, ISA_MIPS32R2);
7089             gen_mtc0_store32(ctx, arg, offsetof(CPUMIPSState, CP0_SRSMap));
7090             /* Stop translation as we may have switched the execution mode */
7091             ctx->bstate = BS_STOP;
7092             rn = "SRSMap";
7093             break;
7094         default:
7095             goto cp0_unimplemented;
7096         }
7097         break;
7098     case 13:
7099         switch (sel) {
7100         case 0:
7101             save_cpu_state(ctx, 1);
7102             /* Mark as an IO operation because we may trigger a software
7103                interrupt.  */
7104             //if (use_icount) {
7105             //    gen_io_start();
7106             //}
7107             gen_helper_mtc0_cause(tcg_ctx, tcg_ctx->cpu_env, arg);
7108             //if (use_icount) {
7109             //    gen_io_end();
7110             //}
7111             /* Stop translation as we may have triggered an intetrupt */
7112             ctx->bstate = BS_STOP;
7113             rn = "Cause";
7114             break;
7115         default:
7116             goto cp0_unimplemented;
7117         }
7118         break;
7119     case 14:
7120         switch (sel) {
7121         case 0:
7122             tcg_gen_st_tl(tcg_ctx, arg, tcg_ctx->cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7123             rn = "EPC";
7124             break;
7125         default:
7126             goto cp0_unimplemented;
7127         }
7128         break;
7129     case 15:
7130         switch (sel) {
7131         case 0:
7132             /* ignored */
7133             rn = "PRid";
7134             break;
7135         case 1:
7136             check_insn(ctx, ISA_MIPS32R2);
7137             gen_helper_mtc0_ebase(tcg_ctx, tcg_ctx->cpu_env, arg);
7138             rn = "EBase";
7139             break;
7140         default:
7141             goto cp0_unimplemented;
7142         }
7143         break;
7144     case 16:
7145         switch (sel) {
7146         case 0:
7147             gen_helper_mtc0_config0(tcg_ctx, tcg_ctx->cpu_env, arg);
7148             rn = "Config";
7149             /* Stop translation as we may have switched the execution mode */
7150             ctx->bstate = BS_STOP;
7151             break;
7152         case 1:
7153             /* ignored, read only */
7154             rn = "Config1";
7155             break;
7156         case 2:
7157             gen_helper_mtc0_config2(tcg_ctx, tcg_ctx->cpu_env, arg);
7158             rn = "Config2";
7159             /* Stop translation as we may have switched the execution mode */
7160             ctx->bstate = BS_STOP;
7161             break;
7162         case 3:
7163             /* ignored */
7164             rn = "Config3";
7165             break;
7166         case 4:
7167             /* currently ignored */
7168             rn = "Config4";
7169             break;
7170         case 5:
7171             gen_helper_mtc0_config5(tcg_ctx, tcg_ctx->cpu_env, arg);
7172             rn = "Config5";
7173             /* Stop translation as we may have switched the execution mode */
7174             ctx->bstate = BS_STOP;
7175             break;
7176         /* 6,7 are implementation dependent */
7177         default:
7178             rn = "Invalid config selector";
7179             goto cp0_unimplemented;
7180         }
7181         break;
7182     case 17:
7183         switch (sel) {
7184         case 0:
7185             gen_helper_mtc0_lladdr(tcg_ctx, tcg_ctx->cpu_env, arg);
7186             rn = "LLAddr";
7187             break;
7188         default:
7189             goto cp0_unimplemented;
7190         }
7191         break;
7192     case 18:
7193         switch (sel) {
7194         case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
7195             gen_helper_0e1i(tcg_ctx, mtc0_watchlo, arg, sel);
7196             rn = "WatchLo";
7197             break;
7198         default:
7199             goto cp0_unimplemented;
7200         }
7201         break;
7202     case 19:
7203         switch (sel) {
7204         case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
7205             gen_helper_0e1i(tcg_ctx, mtc0_watchhi, arg, sel);
7206             rn = "WatchHi";
7207             break;
7208         default:
7209             goto cp0_unimplemented;
7210         }
7211         break;
7212     case 20:
7213         switch (sel) {
7214         case 0:
7215             check_insn(ctx, ISA_MIPS3);
7216             gen_helper_mtc0_xcontext(tcg_ctx, tcg_ctx->cpu_env, arg);
7217             rn = "XContext";
7218             break;
7219         default:
7220             goto cp0_unimplemented;
7221         }
7222         break;
7223     case 21:
7224        /* Officially reserved, but sel 0 is used for R1x000 framemask */
7225         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7226         switch (sel) {
7227         case 0:
7228             gen_helper_mtc0_framemask(tcg_ctx, tcg_ctx->cpu_env, arg);
7229             rn = "Framemask";
7230             break;
7231         default:
7232             goto cp0_unimplemented;
7233         }
7234         break;
7235     case 22:
7236         /* ignored */
7237         rn = "Diagnostic"; /* implementation dependent */
7238         break;
7239     case 23:
7240         switch (sel) {
7241         case 0:
7242             gen_helper_mtc0_debug(tcg_ctx, tcg_ctx->cpu_env, arg); /* EJTAG support */
7243             /* BS_STOP isn't good enough here, hflags may have changed. */
7244             gen_save_pc(ctx, ctx->pc + 4);
7245             ctx->bstate = BS_EXCP;
7246             rn = "Debug";
7247             break;
7248         case 1:
7249 //            gen_helper_mtc0_tracecontrol(tcg_ctx->cpu_env, arg); /* PDtrace support */
7250             /* Stop translation as we may have switched the execution mode */
7251             ctx->bstate = BS_STOP;
7252             rn = "TraceControl";
7253 //            break;
7254         case 2:
7255 //            gen_helper_mtc0_tracecontrol2(tcg_ctx->cpu_env, arg); /* PDtrace support */
7256             /* Stop translation as we may have switched the execution mode */
7257             ctx->bstate = BS_STOP;
7258             rn = "TraceControl2";
7259 //            break;
7260         case 3:
7261 //            gen_helper_mtc0_usertracedata(tcg_ctx->cpu_env, arg); /* PDtrace support */
7262             /* Stop translation as we may have switched the execution mode */
7263             ctx->bstate = BS_STOP;
7264             rn = "UserTraceData";
7265 //            break;
7266         case 4:
7267 //            gen_helper_mtc0_tracebpc(tcg_ctx->cpu_env, arg); /* PDtrace support */
7268             /* Stop translation as we may have switched the execution mode */
7269             ctx->bstate = BS_STOP;
7270             rn = "TraceBPC";
7271 //            break;
7272         default:
7273             goto cp0_unimplemented;
7274         }
7275         break;
7276     case 24:
7277         switch (sel) {
7278         case 0:
7279             /* EJTAG support */
7280             tcg_gen_st_tl(tcg_ctx, arg, tcg_ctx->cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7281             rn = "DEPC";
7282             break;
7283         default:
7284             goto cp0_unimplemented;
7285         }
7286         break;
7287     case 25:
7288         switch (sel) {
7289         case 0:
7290             gen_helper_mtc0_performance0(tcg_ctx, tcg_ctx->cpu_env, arg);
7291             rn = "Performance0";
7292             break;
7293         case 1:
7294 //            gen_helper_mtc0_performance1(tcg_ctx->cpu_env, arg);
7295             rn = "Performance1";
7296 //            break;
7297         case 2:
7298 //            gen_helper_mtc0_performance2(tcg_ctx->cpu_env, arg);
7299             rn = "Performance2";
7300 //            break;
7301         case 3:
7302 //            gen_helper_mtc0_performance3(tcg_ctx->cpu_env, arg);
7303             rn = "Performance3";
7304 //            break;
7305         case 4:
7306 //            gen_helper_mtc0_performance4(tcg_ctx->cpu_env, arg);
7307             rn = "Performance4";
7308 //            break;
7309         case 5:
7310 //            gen_helper_mtc0_performance5(tcg_ctx->cpu_env, arg);
7311             rn = "Performance5";
7312 //            break;
7313         case 6:
7314 //            gen_helper_mtc0_performance6(tcg_ctx->cpu_env, arg);
7315             rn = "Performance6";
7316 //            break;
7317         case 7:
7318 //            gen_helper_mtc0_performance7(tcg_ctx->cpu_env, arg);
7319             rn = "Performance7";
7320 //            break;
7321         default:
7322             goto cp0_unimplemented;
7323         }
7324         break;
7325     case 26:
7326         /* ignored */
7327         rn = "ECC";
7328         break;
7329     case 27:
7330         switch (sel) {
7331         case 0: case 1: case 2: case 3:
7332             /* ignored */
7333             rn = "CacheErr";
7334             break;
7335         default:
7336             goto cp0_unimplemented;
7337         }
7338         break;
7339     case 28:
7340         switch (sel) {
7341         case 0:
7342         case 2:
7343         case 4:
7344         case 6:
7345             gen_helper_mtc0_taglo(tcg_ctx, tcg_ctx->cpu_env, arg);
7346             rn = "TagLo";
7347             break;
7348         case 1:
7349         case 3:
7350         case 5:
7351         case 7:
7352             gen_helper_mtc0_datalo(tcg_ctx, tcg_ctx->cpu_env, arg);
7353             rn = "DataLo";
7354             break;
7355         default:
7356             goto cp0_unimplemented;
7357         }
7358         break;
7359     case 29:
7360         switch (sel) {
7361         case 0:
7362         case 2:
7363         case 4:
7364         case 6:
7365             gen_helper_mtc0_taghi(tcg_ctx, tcg_ctx->cpu_env, arg);
7366             rn = "TagHi";
7367             break;
7368         case 1:
7369         case 3:
7370         case 5:
7371         case 7:
7372             gen_helper_mtc0_datahi(tcg_ctx, tcg_ctx->cpu_env, arg);
7373             rn = "DataHi";
7374             break;
7375         default:
7376             rn = "invalid sel";
7377             goto cp0_unimplemented;
7378         }
7379         break;
7380     case 30:
7381         switch (sel) {
7382         case 0:
7383             tcg_gen_st_tl(tcg_ctx, arg, tcg_ctx->cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7384             rn = "ErrorEPC";
7385             break;
7386         default:
7387             goto cp0_unimplemented;
7388         }
7389         break;
7390     case 31:
7391         switch (sel) {
7392         case 0:
7393             /* EJTAG support */
7394             gen_mtc0_store32(ctx, arg, offsetof(CPUMIPSState, CP0_DESAVE));
7395             rn = "DESAVE";
7396             break;
7397         case 2: case 3: case 4: case 5: case 6: case 7:
7398             CP0_CHECK(ctx->kscrexist & (1 << sel));
7399             tcg_gen_st_tl(tcg_ctx, arg, tcg_ctx->cpu_env,
7400                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7401             rn = "KScratch";
7402             break;
7403         default:
7404             goto cp0_unimplemented;
7405         }
7406         /* Stop translation as we may have switched the execution mode */
7407         ctx->bstate = BS_STOP;
7408         break;
7409     default:
7410         goto cp0_unimplemented;
7411     }
7412     (void)rn; /* avoid a compiler warning */
7413     LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
7414     /* For simplicity assume that all writes can cause interrupts.  */
7415     //if (use_icount) {
7416     //    gen_io_end();
7417     //    ctx->bstate = BS_STOP;
7418     //}
7419     return;
7420 
7421 cp0_unimplemented:
7422     LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
7423 }
7424 #endif /* TARGET_MIPS64 */
7425 
gen_mftr(CPUMIPSState * env,DisasContext * ctx,int rt,int rd,int u,int sel,int h)7426 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
7427                      int u, int sel, int h)
7428 {
7429     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
7430     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
7431     TCGv t0 = tcg_temp_local_new(tcg_ctx);
7432 
7433     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
7434         ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7435          (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
7436         tcg_gen_movi_tl(tcg_ctx, t0, -1);
7437     else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7438              (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7439         tcg_gen_movi_tl(tcg_ctx, t0, -1);
7440     else if (u == 0) {
7441         switch (rt) {
7442         case 1:
7443             switch (sel) {
7444             case 1:
7445                 gen_helper_mftc0_vpecontrol(tcg_ctx, t0, tcg_ctx->cpu_env);
7446                 break;
7447             case 2:
7448                 gen_helper_mftc0_vpeconf0(tcg_ctx, t0, tcg_ctx->cpu_env);
7449                 break;
7450             default:
7451                 goto die;
7452                 break;
7453             }
7454             break;
7455         case 2:
7456             switch (sel) {
7457             case 1:
7458                 gen_helper_mftc0_tcstatus(tcg_ctx, t0, tcg_ctx->cpu_env);
7459                 break;
7460             case 2:
7461                 gen_helper_mftc0_tcbind(tcg_ctx, t0, tcg_ctx->cpu_env);
7462                 break;
7463             case 3:
7464                 gen_helper_mftc0_tcrestart(tcg_ctx, t0, tcg_ctx->cpu_env);
7465                 break;
7466             case 4:
7467                 gen_helper_mftc0_tchalt(tcg_ctx, t0, tcg_ctx->cpu_env);
7468                 break;
7469             case 5:
7470                 gen_helper_mftc0_tccontext(tcg_ctx, t0, tcg_ctx->cpu_env);
7471                 break;
7472             case 6:
7473                 gen_helper_mftc0_tcschedule(tcg_ctx, t0, tcg_ctx->cpu_env);
7474                 break;
7475             case 7:
7476                 gen_helper_mftc0_tcschefback(tcg_ctx, t0, tcg_ctx->cpu_env);
7477                 break;
7478             default:
7479                 gen_mfc0(ctx, t0, rt, sel);
7480                 break;
7481             }
7482             break;
7483         case 10:
7484             switch (sel) {
7485             case 0:
7486                 gen_helper_mftc0_entryhi(tcg_ctx, t0, tcg_ctx->cpu_env);
7487                 break;
7488             default:
7489                 gen_mfc0(ctx, t0, rt, sel);
7490                 break;
7491             }
7492         case 12:
7493             switch (sel) {
7494             case 0:
7495                 gen_helper_mftc0_status(tcg_ctx, t0, tcg_ctx->cpu_env);
7496                 break;
7497             default:
7498                 gen_mfc0(ctx, t0, rt, sel);
7499                 break;
7500             }
7501         case 13:
7502             switch (sel) {
7503             case 0:
7504                 gen_helper_mftc0_cause(tcg_ctx, t0, tcg_ctx->cpu_env);
7505                 break;
7506             default:
7507                 goto die;
7508                 break;
7509             }
7510             break;
7511         case 14:
7512             switch (sel) {
7513             case 0:
7514                 gen_helper_mftc0_epc(tcg_ctx, t0, tcg_ctx->cpu_env);
7515                 break;
7516             default:
7517                 goto die;
7518                 break;
7519             }
7520             break;
7521         case 15:
7522             switch (sel) {
7523             case 1:
7524                 gen_helper_mftc0_ebase(tcg_ctx, t0, tcg_ctx->cpu_env);
7525                 break;
7526             default:
7527                 goto die;
7528                 break;
7529             }
7530             break;
7531         case 16:
7532             switch (sel) {
7533             case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
7534                 gen_helper_mftc0_configx(tcg_ctx, t0, tcg_ctx->cpu_env, tcg_const_tl(tcg_ctx, sel));
7535                 break;
7536             default:
7537                 goto die;
7538                 break;
7539             }
7540             break;
7541         case 23:
7542             switch (sel) {
7543             case 0:
7544                 gen_helper_mftc0_debug(tcg_ctx, t0, tcg_ctx->cpu_env);
7545                 break;
7546             default:
7547                 gen_mfc0(ctx, t0, rt, sel);
7548                 break;
7549             }
7550             break;
7551         default:
7552             gen_mfc0(ctx, t0, rt, sel);
7553         }
7554     } else switch (sel) {
7555     /* GPR registers. */
7556     case 0:
7557         gen_helper_1e0i(tcg_ctx, mftgpr, t0, rt);
7558         break;
7559     /* Auxiliary CPU registers */
7560     case 1:
7561         switch (rt) {
7562         case 0:
7563             gen_helper_1e0i(tcg_ctx, mftlo, t0, 0);
7564             break;
7565         case 1:
7566             gen_helper_1e0i(tcg_ctx, mfthi, t0, 0);
7567             break;
7568         case 2:
7569             gen_helper_1e0i(tcg_ctx, mftacx, t0, 0);
7570             break;
7571         case 4:
7572             gen_helper_1e0i(tcg_ctx, mftlo, t0, 1);
7573             break;
7574         case 5:
7575             gen_helper_1e0i(tcg_ctx, mfthi, t0, 1);
7576             break;
7577         case 6:
7578             gen_helper_1e0i(tcg_ctx, mftacx, t0, 1);
7579             break;
7580         case 8:
7581             gen_helper_1e0i(tcg_ctx, mftlo, t0, 2);
7582             break;
7583         case 9:
7584             gen_helper_1e0i(tcg_ctx, mfthi, t0, 2);
7585             break;
7586         case 10:
7587             gen_helper_1e0i(tcg_ctx, mftacx, t0, 2);
7588             break;
7589         case 12:
7590             gen_helper_1e0i(tcg_ctx, mftlo, t0, 3);
7591             break;
7592         case 13:
7593             gen_helper_1e0i(tcg_ctx, mfthi, t0, 3);
7594             break;
7595         case 14:
7596             gen_helper_1e0i(tcg_ctx, mftacx, t0, 3);
7597             break;
7598         case 16:
7599             gen_helper_mftdsp(tcg_ctx, t0, tcg_ctx->cpu_env);
7600             break;
7601         default:
7602             goto die;
7603         }
7604         break;
7605     /* Floating point (COP1). */
7606     case 2:
7607         /* XXX: For now we support only a single FPU context. */
7608         if (h == 0) {
7609             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
7610 
7611             gen_load_fpr32(ctx, fp0, rt);
7612             tcg_gen_ext_i32_tl(tcg_ctx, t0, fp0);
7613             tcg_temp_free_i32(tcg_ctx, fp0);
7614         } else {
7615             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
7616 
7617             gen_load_fpr32h(ctx, fp0, rt);
7618             tcg_gen_ext_i32_tl(tcg_ctx, t0, fp0);
7619             tcg_temp_free_i32(tcg_ctx, fp0);
7620         }
7621         break;
7622     case 3:
7623         /* XXX: For now we support only a single FPU context. */
7624         gen_helper_1e0i(tcg_ctx, cfc1, t0, rt);
7625         break;
7626     /* COP2: Not implemented. */
7627     case 4:
7628     case 5:
7629         /* fall through */
7630     default:
7631         goto die;
7632     }
7633     LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
7634     gen_store_gpr(tcg_ctx, t0, rd);
7635     tcg_temp_free(tcg_ctx, t0);
7636     return;
7637 
7638 die:
7639     tcg_temp_free(tcg_ctx, t0);
7640     LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
7641     generate_exception(ctx, EXCP_RI);
7642 }
7643 
gen_mttr(CPUMIPSState * env,DisasContext * ctx,int rd,int rt,int u,int sel,int h)7644 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
7645                      int u, int sel, int h)
7646 {
7647     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
7648     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
7649     TCGv t0 = tcg_temp_local_new(tcg_ctx);
7650 
7651     gen_load_gpr(ctx, t0, rt);
7652     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
7653         ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7654          (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
7655         /* NOP */ ;
7656     else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7657              (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7658         /* NOP */ ;
7659     else if (u == 0) {
7660         switch (rd) {
7661         case 1:
7662             switch (sel) {
7663             case 1:
7664                 gen_helper_mttc0_vpecontrol(tcg_ctx, tcg_ctx->cpu_env, t0);
7665                 break;
7666             case 2:
7667                 gen_helper_mttc0_vpeconf0(tcg_ctx, tcg_ctx->cpu_env, t0);
7668                 break;
7669             default:
7670                 goto die;
7671                 break;
7672             }
7673             break;
7674         case 2:
7675             switch (sel) {
7676             case 1:
7677                 gen_helper_mttc0_tcstatus(tcg_ctx, tcg_ctx->cpu_env, t0);
7678                 break;
7679             case 2:
7680                 gen_helper_mttc0_tcbind(tcg_ctx, tcg_ctx->cpu_env, t0);
7681                 break;
7682             case 3:
7683                 gen_helper_mttc0_tcrestart(tcg_ctx, tcg_ctx->cpu_env, t0);
7684                 break;
7685             case 4:
7686                 gen_helper_mttc0_tchalt(tcg_ctx, tcg_ctx->cpu_env, t0);
7687                 break;
7688             case 5:
7689                 gen_helper_mttc0_tccontext(tcg_ctx, tcg_ctx->cpu_env, t0);
7690                 break;
7691             case 6:
7692                 gen_helper_mttc0_tcschedule(tcg_ctx, tcg_ctx->cpu_env, t0);
7693                 break;
7694             case 7:
7695                 gen_helper_mttc0_tcschefback(tcg_ctx, tcg_ctx->cpu_env, t0);
7696                 break;
7697             default:
7698                 gen_mtc0(ctx, t0, rd, sel);
7699                 break;
7700             }
7701             break;
7702         case 10:
7703             switch (sel) {
7704             case 0:
7705                 gen_helper_mttc0_entryhi(tcg_ctx, tcg_ctx->cpu_env, t0);
7706                 break;
7707             default:
7708                 gen_mtc0(ctx, t0, rd, sel);
7709                 break;
7710             }
7711         case 12:
7712             switch (sel) {
7713             case 0:
7714                 gen_helper_mttc0_status(tcg_ctx, tcg_ctx->cpu_env, t0);
7715                 break;
7716             default:
7717                 gen_mtc0(ctx, t0, rd, sel);
7718                 break;
7719             }
7720         case 13:
7721             switch (sel) {
7722             case 0:
7723                 gen_helper_mttc0_cause(tcg_ctx, tcg_ctx->cpu_env, t0);
7724                 break;
7725             default:
7726                 goto die;
7727                 break;
7728             }
7729             break;
7730         case 15:
7731             switch (sel) {
7732             case 1:
7733                 gen_helper_mttc0_ebase(tcg_ctx, tcg_ctx->cpu_env, t0);
7734                 break;
7735             default:
7736                 goto die;
7737                 break;
7738             }
7739             break;
7740         case 23:
7741             switch (sel) {
7742             case 0:
7743                 gen_helper_mttc0_debug(tcg_ctx, tcg_ctx->cpu_env, t0);
7744                 break;
7745             default:
7746                 gen_mtc0(ctx, t0, rd, sel);
7747                 break;
7748             }
7749             break;
7750         default:
7751             gen_mtc0(ctx, t0, rd, sel);
7752         }
7753     } else switch (sel) {
7754     /* GPR registers. */
7755     case 0:
7756         gen_helper_0e1i(tcg_ctx, mttgpr, t0, rd);
7757         break;
7758     /* Auxiliary CPU registers */
7759     case 1:
7760         switch (rd) {
7761         case 0:
7762             gen_helper_0e1i(tcg_ctx, mttlo, t0, 0);
7763             break;
7764         case 1:
7765             gen_helper_0e1i(tcg_ctx, mtthi, t0, 0);
7766             break;
7767         case 2:
7768             gen_helper_0e1i(tcg_ctx, mttacx, t0, 0);
7769             break;
7770         case 4:
7771             gen_helper_0e1i(tcg_ctx, mttlo, t0, 1);
7772             break;
7773         case 5:
7774             gen_helper_0e1i(tcg_ctx, mtthi, t0, 1);
7775             break;
7776         case 6:
7777             gen_helper_0e1i(tcg_ctx, mttacx, t0, 1);
7778             break;
7779         case 8:
7780             gen_helper_0e1i(tcg_ctx, mttlo, t0, 2);
7781             break;
7782         case 9:
7783             gen_helper_0e1i(tcg_ctx, mtthi, t0, 2);
7784             break;
7785         case 10:
7786             gen_helper_0e1i(tcg_ctx, mttacx, t0, 2);
7787             break;
7788         case 12:
7789             gen_helper_0e1i(tcg_ctx, mttlo, t0, 3);
7790             break;
7791         case 13:
7792             gen_helper_0e1i(tcg_ctx, mtthi, t0, 3);
7793             break;
7794         case 14:
7795             gen_helper_0e1i(tcg_ctx, mttacx, t0, 3);
7796             break;
7797         case 16:
7798             gen_helper_mttdsp(tcg_ctx, tcg_ctx->cpu_env, t0);
7799             break;
7800         default:
7801             goto die;
7802         }
7803         break;
7804     /* Floating point (COP1). */
7805     case 2:
7806         /* XXX: For now we support only a single FPU context. */
7807         if (h == 0) {
7808             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
7809 
7810             tcg_gen_trunc_tl_i32(tcg_ctx, fp0, t0);
7811             gen_store_fpr32(ctx, fp0, rd);
7812             tcg_temp_free_i32(tcg_ctx, fp0);
7813         } else {
7814             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
7815 
7816             tcg_gen_trunc_tl_i32(tcg_ctx, fp0, t0);
7817             gen_store_fpr32h(ctx, fp0, rd);
7818             tcg_temp_free_i32(tcg_ctx, fp0);
7819         }
7820         break;
7821     case 3:
7822         /* XXX: For now we support only a single FPU context. */
7823         save_cpu_state(ctx, 1);
7824         {
7825             TCGv_i32 fs_tmp = tcg_const_i32(tcg_ctx, rd);
7826 
7827             gen_helper_0e2i(tcg_ctx, ctc1, t0, fs_tmp, rt);
7828             tcg_temp_free_i32(tcg_ctx, fs_tmp);
7829         }
7830         /* Stop translation as we may have changed hflags */
7831         ctx->bstate = BS_STOP;
7832         break;
7833     /* COP2: Not implemented. */
7834     case 4:
7835     case 5:
7836         /* fall through */
7837     default:
7838         goto die;
7839     }
7840     LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
7841     tcg_temp_free(tcg_ctx, t0);
7842     return;
7843 
7844 die:
7845     tcg_temp_free(tcg_ctx, t0);
7846     LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
7847     generate_exception(ctx, EXCP_RI);
7848 }
7849 
gen_cp0(CPUMIPSState * env,DisasContext * ctx,uint32_t opc,int rt,int rd)7850 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
7851 {
7852     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
7853     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
7854     const char *opn = "ldst";
7855 
7856     check_cp0_enabled(ctx);
7857     switch (opc) {
7858     case OPC_MFC0:
7859         if (rt == 0) {
7860             /* Treat as NOP. */
7861             return;
7862         }
7863         gen_mfc0(ctx, *cpu_gpr[rt], rd, ctx->opcode & 0x7);
7864         opn = "mfc0";
7865         break;
7866     case OPC_MTC0:
7867         {
7868             TCGv t0 = tcg_temp_new(tcg_ctx);
7869 
7870             gen_load_gpr(ctx, t0, rt);
7871             gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
7872             tcg_temp_free(tcg_ctx, t0);
7873         }
7874         opn = "mtc0";
7875         break;
7876 #if defined(TARGET_MIPS64)
7877     case OPC_DMFC0:
7878         check_insn(ctx, ISA_MIPS3);
7879         if (rt == 0) {
7880             /* Treat as NOP. */
7881             return;
7882         }
7883         gen_dmfc0(ctx, *cpu_gpr[rt], rd, ctx->opcode & 0x7);
7884         opn = "dmfc0";
7885         break;
7886     case OPC_DMTC0:
7887         check_insn(ctx, ISA_MIPS3);
7888         {
7889             TCGv t0 = tcg_temp_new(tcg_ctx);
7890 
7891             gen_load_gpr(ctx, t0, rt);
7892             gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
7893             tcg_temp_free(tcg_ctx, t0);
7894         }
7895         opn = "dmtc0";
7896         break;
7897 #endif
7898     case OPC_MFTR:
7899         check_insn(ctx, ASE_MT);
7900         if (rd == 0) {
7901             /* Treat as NOP. */
7902             return;
7903         }
7904         gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
7905                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
7906         opn = "mftr";
7907         break;
7908     case OPC_MTTR:
7909         check_insn(ctx, ASE_MT);
7910         gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
7911                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
7912         opn = "mttr";
7913         break;
7914     case OPC_TLBWI:
7915         opn = "tlbwi";
7916         if (!env->tlb->helper_tlbwi)
7917             goto die;
7918         gen_helper_tlbwi(tcg_ctx, tcg_ctx->cpu_env);
7919         break;
7920     case OPC_TLBINV:
7921         opn = "tlbinv";
7922         if (ctx->ie >= 2) {
7923             if (!env->tlb->helper_tlbinv) {
7924                 goto die;
7925             }
7926             gen_helper_tlbinv(tcg_ctx, tcg_ctx->cpu_env);
7927         } /* treat as nop if TLBINV not supported */
7928         break;
7929     case OPC_TLBINVF:
7930         opn = "tlbinvf";
7931         if (ctx->ie >= 2) {
7932             if (!env->tlb->helper_tlbinvf) {
7933                 goto die;
7934             }
7935             gen_helper_tlbinvf(tcg_ctx, tcg_ctx->cpu_env);
7936         } /* treat as nop if TLBINV not supported */
7937         break;
7938     case OPC_TLBWR:
7939         opn = "tlbwr";
7940         if (!env->tlb->helper_tlbwr)
7941             goto die;
7942         gen_helper_tlbwr(tcg_ctx, tcg_ctx->cpu_env);
7943         break;
7944     case OPC_TLBP:
7945         opn = "tlbp";
7946         if (!env->tlb->helper_tlbp)
7947             goto die;
7948         gen_helper_tlbp(tcg_ctx, tcg_ctx->cpu_env);
7949         break;
7950     case OPC_TLBR:
7951         opn = "tlbr";
7952         if (!env->tlb->helper_tlbr)
7953             goto die;
7954         gen_helper_tlbr(tcg_ctx, tcg_ctx->cpu_env);
7955         break;
7956     case OPC_ERET:
7957         opn = "eret";
7958         check_insn(ctx, ISA_MIPS2);
7959         if ((ctx->insn_flags & ISA_MIPS32R6) &&
7960             (ctx->hflags & MIPS_HFLAG_BMASK)) {
7961             MIPS_DEBUG("CTI in delay / forbidden slot");
7962             goto die;
7963         }
7964         gen_helper_eret(tcg_ctx, tcg_ctx->cpu_env);
7965         ctx->bstate = BS_EXCP;
7966         break;
7967     case OPC_DERET:
7968         opn = "deret";
7969         check_insn(ctx, ISA_MIPS32);
7970         if ((ctx->insn_flags & ISA_MIPS32R6) &&
7971             (ctx->hflags & MIPS_HFLAG_BMASK)) {
7972             MIPS_DEBUG("CTI in delay / forbidden slot");
7973             goto die;
7974         }
7975         if (!(ctx->hflags & MIPS_HFLAG_DM)) {
7976             MIPS_INVAL(opn);
7977             generate_exception(ctx, EXCP_RI);
7978         } else {
7979             gen_helper_deret(tcg_ctx, tcg_ctx->cpu_env);
7980             ctx->bstate = BS_EXCP;
7981         }
7982         break;
7983     case OPC_WAIT:
7984         opn = "wait";
7985         check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
7986         if ((ctx->insn_flags & ISA_MIPS32R6) &&
7987             (ctx->hflags & MIPS_HFLAG_BMASK)) {
7988             MIPS_DEBUG("CTI in delay / forbidden slot");
7989             goto die;
7990         }
7991         /* If we get an exception, we want to restart at next instruction */
7992         ctx->pc += 4;
7993         save_cpu_state(ctx, 1);
7994         ctx->pc -= 4;
7995         gen_helper_wait(tcg_ctx, tcg_ctx->cpu_env);
7996         ctx->bstate = BS_EXCP;
7997         break;
7998     default:
7999  die:
8000         MIPS_INVAL(opn);
8001         generate_exception(ctx, EXCP_RI);
8002         return;
8003     }
8004     (void)opn; /* avoid a compiler warning */
8005     MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
8006 }
8007 #endif /* !CONFIG_USER_ONLY */
8008 
8009 /* CP1 Branches (before delay slot) */
gen_compute_branch1(DisasContext * ctx,uint32_t op,int32_t cc,int32_t offset)8010 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
8011                                 int32_t cc, int32_t offset)
8012 {
8013     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
8014     target_ulong btarget;
8015     const char *opn = "cp1 cond branch";
8016     TCGv_i32 t0 = tcg_temp_new_i32(tcg_ctx);
8017 
8018     if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8019         MIPS_DEBUG("CTI in delay / forbidden slot");
8020         generate_exception(ctx, EXCP_RI);
8021         goto out;
8022     }
8023 
8024     if (cc != 0)
8025         check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
8026 
8027     btarget = ctx->pc + 4 + offset;
8028 
8029     switch (op) {
8030     case OPC_BC1F:
8031         tcg_gen_shri_i32(tcg_ctx, t0, tcg_ctx->fpu_fcr31, get_fp_bit(cc));
8032         tcg_gen_not_i32(tcg_ctx, t0, t0);
8033         tcg_gen_andi_i32(tcg_ctx, t0, t0, 1);
8034         tcg_gen_extu_i32_tl(tcg_ctx, *(TCGv *)tcg_ctx->bcond, t0);
8035         opn = "bc1f";
8036         goto not_likely;
8037     case OPC_BC1FL:
8038         tcg_gen_shri_i32(tcg_ctx, t0, tcg_ctx->fpu_fcr31, get_fp_bit(cc));
8039         tcg_gen_not_i32(tcg_ctx, t0, t0);
8040         tcg_gen_andi_i32(tcg_ctx, t0, t0, 1);
8041         tcg_gen_extu_i32_tl(tcg_ctx, *(TCGv *)tcg_ctx->bcond, t0);
8042         opn = "bc1fl";
8043         goto likely;
8044     case OPC_BC1T:
8045         tcg_gen_shri_i32(tcg_ctx, t0, tcg_ctx->fpu_fcr31, get_fp_bit(cc));
8046         tcg_gen_andi_i32(tcg_ctx, t0, t0, 1);
8047         tcg_gen_extu_i32_tl(tcg_ctx, *(TCGv *)tcg_ctx->bcond, t0);
8048         opn = "bc1t";
8049         goto not_likely;
8050     case OPC_BC1TL:
8051         tcg_gen_shri_i32(tcg_ctx, t0, tcg_ctx->fpu_fcr31, get_fp_bit(cc));
8052         tcg_gen_andi_i32(tcg_ctx, t0, t0, 1);
8053         tcg_gen_extu_i32_tl(tcg_ctx, *(TCGv *)tcg_ctx->bcond, t0);
8054         opn = "bc1tl";
8055     likely:
8056         ctx->hflags |= MIPS_HFLAG_BL;
8057         break;
8058     case OPC_BC1FANY2:
8059         {
8060             TCGv_i32 t1 = tcg_temp_new_i32(tcg_ctx);
8061             tcg_gen_shri_i32(tcg_ctx, t0, tcg_ctx->fpu_fcr31, get_fp_bit(cc));
8062             tcg_gen_shri_i32(tcg_ctx, t1, tcg_ctx->fpu_fcr31, get_fp_bit(cc+1));
8063             tcg_gen_nand_i32(tcg_ctx, t0, t0, t1);
8064             tcg_temp_free_i32(tcg_ctx, t1);
8065             tcg_gen_andi_i32(tcg_ctx, t0, t0, 1);
8066             tcg_gen_extu_i32_tl(tcg_ctx, *(TCGv *)tcg_ctx->bcond, t0);
8067         }
8068         opn = "bc1any2f";
8069         goto not_likely;
8070     case OPC_BC1TANY2:
8071         {
8072             TCGv_i32 t1 = tcg_temp_new_i32(tcg_ctx);
8073             tcg_gen_shri_i32(tcg_ctx, t0, tcg_ctx->fpu_fcr31, get_fp_bit(cc));
8074             tcg_gen_shri_i32(tcg_ctx, t1, tcg_ctx->fpu_fcr31, get_fp_bit(cc+1));
8075             tcg_gen_or_i32(tcg_ctx, t0, t0, t1);
8076             tcg_temp_free_i32(tcg_ctx, t1);
8077             tcg_gen_andi_i32(tcg_ctx, t0, t0, 1);
8078             tcg_gen_extu_i32_tl(tcg_ctx, *(TCGv *)tcg_ctx->bcond, t0);
8079         }
8080         opn = "bc1any2t";
8081         goto not_likely;
8082     case OPC_BC1FANY4:
8083         {
8084             TCGv_i32 t1 = tcg_temp_new_i32(tcg_ctx);
8085             tcg_gen_shri_i32(tcg_ctx, t0, tcg_ctx->fpu_fcr31, get_fp_bit(cc));
8086             tcg_gen_shri_i32(tcg_ctx, t1, tcg_ctx->fpu_fcr31, get_fp_bit(cc+1));
8087             tcg_gen_and_i32(tcg_ctx, t0, t0, t1);
8088             tcg_gen_shri_i32(tcg_ctx, t1, tcg_ctx->fpu_fcr31, get_fp_bit(cc+2));
8089             tcg_gen_and_i32(tcg_ctx, t0, t0, t1);
8090             tcg_gen_shri_i32(tcg_ctx, t1, tcg_ctx->fpu_fcr31, get_fp_bit(cc+3));
8091             tcg_gen_nand_i32(tcg_ctx, t0, t0, t1);
8092             tcg_temp_free_i32(tcg_ctx, t1);
8093             tcg_gen_andi_i32(tcg_ctx, t0, t0, 1);
8094             tcg_gen_extu_i32_tl(tcg_ctx, *(TCGv *)tcg_ctx->bcond, t0);
8095         }
8096         opn = "bc1any4f";
8097         goto not_likely;
8098     case OPC_BC1TANY4:
8099         {
8100             TCGv_i32 t1 = tcg_temp_new_i32(tcg_ctx);
8101             tcg_gen_shri_i32(tcg_ctx, t0, tcg_ctx->fpu_fcr31, get_fp_bit(cc));
8102             tcg_gen_shri_i32(tcg_ctx, t1, tcg_ctx->fpu_fcr31, get_fp_bit(cc+1));
8103             tcg_gen_or_i32(tcg_ctx, t0, t0, t1);
8104             tcg_gen_shri_i32(tcg_ctx, t1, tcg_ctx->fpu_fcr31, get_fp_bit(cc+2));
8105             tcg_gen_or_i32(tcg_ctx, t0, t0, t1);
8106             tcg_gen_shri_i32(tcg_ctx, t1, tcg_ctx->fpu_fcr31, get_fp_bit(cc+3));
8107             tcg_gen_or_i32(tcg_ctx, t0, t0, t1);
8108             tcg_temp_free_i32(tcg_ctx, t1);
8109             tcg_gen_andi_i32(tcg_ctx, t0, t0, 1);
8110             tcg_gen_extu_i32_tl(tcg_ctx, *(TCGv *)tcg_ctx->bcond, t0);
8111         }
8112         opn = "bc1any4t";
8113     not_likely:
8114         ctx->hflags |= MIPS_HFLAG_BC;
8115         break;
8116     default:
8117         MIPS_INVAL(opn);
8118         generate_exception (ctx, EXCP_RI);
8119         goto out;
8120     }
8121     (void)opn; /* avoid a compiler warning */
8122     MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
8123                ctx->hflags, btarget);
8124     ctx->btarget = btarget;
8125     ctx->hflags |= MIPS_HFLAG_BDS32;
8126  out:
8127     tcg_temp_free_i32(tcg_ctx, t0);
8128 }
8129 
8130 /* R6 CP1 Branches */
gen_compute_branch1_r6(DisasContext * ctx,uint32_t op,int32_t ft,int32_t offset)8131 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
8132                                    int32_t ft, int32_t offset)
8133 {
8134     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
8135     target_ulong btarget;
8136     const char *opn = "cp1 cond branch";
8137     TCGv_i64 t0 = tcg_temp_new_i64(tcg_ctx);
8138 
8139     if (ctx->hflags & MIPS_HFLAG_BMASK) {
8140 #ifdef MIPS_DEBUG_DISAS
8141         LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
8142                   "\n", ctx->pc);
8143 #endif
8144         generate_exception(ctx, EXCP_RI);
8145         goto out;
8146     }
8147 
8148     gen_load_fpr64(ctx, t0, ft);
8149     tcg_gen_andi_i64(tcg_ctx, t0, t0, 1);
8150 
8151     btarget = addr_add(ctx, ctx->pc + 4, offset);
8152 
8153     switch (op) {
8154     case OPC_BC1EQZ:
8155         tcg_gen_xori_i64(tcg_ctx, t0, t0, 1);
8156         opn = "bc1eqz";
8157         ctx->hflags |= MIPS_HFLAG_BC;
8158         break;
8159     case OPC_BC1NEZ:
8160         /* t0 already set */
8161         opn = "bc1nez";
8162         ctx->hflags |= MIPS_HFLAG_BC;
8163         break;
8164     default:
8165         MIPS_INVAL(opn);
8166         generate_exception(ctx, EXCP_RI);
8167         goto out;
8168     }
8169 
8170     tcg_gen_trunc_i64_tl(tcg_ctx, *(TCGv *)tcg_ctx->bcond, t0);
8171 
8172     (void)opn; /* avoid a compiler warning */
8173     MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
8174                ctx->hflags, btarget);
8175     ctx->btarget = btarget;
8176     ctx->hflags |= MIPS_HFLAG_BDS32;
8177 
8178 out:
8179     tcg_temp_free_i64(tcg_ctx, t0);
8180 }
8181 
8182 /* Coprocessor 1 (FPU) */
8183 
8184 #define FOP(func, fmt) (((fmt) << 21) | (func))
8185 
8186 enum fopcode {
8187     OPC_ADD_S = FOP(0, FMT_S),
8188     OPC_SUB_S = FOP(1, FMT_S),
8189     OPC_MUL_S = FOP(2, FMT_S),
8190     OPC_DIV_S = FOP(3, FMT_S),
8191     OPC_SQRT_S = FOP(4, FMT_S),
8192     OPC_ABS_S = FOP(5, FMT_S),
8193     OPC_MOV_S = FOP(6, FMT_S),
8194     OPC_NEG_S = FOP(7, FMT_S),
8195     OPC_ROUND_L_S = FOP(8, FMT_S),
8196     OPC_TRUNC_L_S = FOP(9, FMT_S),
8197     OPC_CEIL_L_S = FOP(10, FMT_S),
8198     OPC_FLOOR_L_S = FOP(11, FMT_S),
8199     OPC_ROUND_W_S = FOP(12, FMT_S),
8200     OPC_TRUNC_W_S = FOP(13, FMT_S),
8201     OPC_CEIL_W_S = FOP(14, FMT_S),
8202     OPC_FLOOR_W_S = FOP(15, FMT_S),
8203     OPC_SEL_S = FOP(16, FMT_S),
8204     OPC_MOVCF_S = FOP(17, FMT_S),
8205     OPC_MOVZ_S = FOP(18, FMT_S),
8206     OPC_MOVN_S = FOP(19, FMT_S),
8207     OPC_SELEQZ_S = FOP(20, FMT_S),
8208     OPC_RECIP_S = FOP(21, FMT_S),
8209     OPC_RSQRT_S = FOP(22, FMT_S),
8210     OPC_SELNEZ_S = FOP(23, FMT_S),
8211     OPC_MADDF_S = FOP(24, FMT_S),
8212     OPC_MSUBF_S = FOP(25, FMT_S),
8213     OPC_RINT_S = FOP(26, FMT_S),
8214     OPC_CLASS_S = FOP(27, FMT_S),
8215     OPC_MIN_S = FOP(28, FMT_S),
8216     OPC_RECIP2_S = FOP(28, FMT_S),
8217     OPC_MINA_S = FOP(29, FMT_S),
8218     OPC_RECIP1_S = FOP(29, FMT_S),
8219     OPC_MAX_S = FOP(30, FMT_S),
8220     OPC_RSQRT1_S = FOP(30, FMT_S),
8221     OPC_MAXA_S = FOP(31, FMT_S),
8222     OPC_RSQRT2_S = FOP(31, FMT_S),
8223     OPC_CVT_D_S = FOP(33, FMT_S),
8224     OPC_CVT_W_S = FOP(36, FMT_S),
8225     OPC_CVT_L_S = FOP(37, FMT_S),
8226     OPC_CVT_PS_S = FOP(38, FMT_S),
8227     OPC_CMP_F_S = FOP (48, FMT_S),
8228     OPC_CMP_UN_S = FOP (49, FMT_S),
8229     OPC_CMP_EQ_S = FOP (50, FMT_S),
8230     OPC_CMP_UEQ_S = FOP (51, FMT_S),
8231     OPC_CMP_OLT_S = FOP (52, FMT_S),
8232     OPC_CMP_ULT_S = FOP (53, FMT_S),
8233     OPC_CMP_OLE_S = FOP (54, FMT_S),
8234     OPC_CMP_ULE_S = FOP (55, FMT_S),
8235     OPC_CMP_SF_S = FOP (56, FMT_S),
8236     OPC_CMP_NGLE_S = FOP (57, FMT_S),
8237     OPC_CMP_SEQ_S = FOP (58, FMT_S),
8238     OPC_CMP_NGL_S = FOP (59, FMT_S),
8239     OPC_CMP_LT_S = FOP (60, FMT_S),
8240     OPC_CMP_NGE_S = FOP (61, FMT_S),
8241     OPC_CMP_LE_S = FOP (62, FMT_S),
8242     OPC_CMP_NGT_S = FOP (63, FMT_S),
8243 
8244     OPC_ADD_D = FOP(0, FMT_D),
8245     OPC_SUB_D = FOP(1, FMT_D),
8246     OPC_MUL_D = FOP(2, FMT_D),
8247     OPC_DIV_D = FOP(3, FMT_D),
8248     OPC_SQRT_D = FOP(4, FMT_D),
8249     OPC_ABS_D = FOP(5, FMT_D),
8250     OPC_MOV_D = FOP(6, FMT_D),
8251     OPC_NEG_D = FOP(7, FMT_D),
8252     OPC_ROUND_L_D = FOP(8, FMT_D),
8253     OPC_TRUNC_L_D = FOP(9, FMT_D),
8254     OPC_CEIL_L_D = FOP(10, FMT_D),
8255     OPC_FLOOR_L_D = FOP(11, FMT_D),
8256     OPC_ROUND_W_D = FOP(12, FMT_D),
8257     OPC_TRUNC_W_D = FOP(13, FMT_D),
8258     OPC_CEIL_W_D = FOP(14, FMT_D),
8259     OPC_FLOOR_W_D = FOP(15, FMT_D),
8260     OPC_SEL_D = FOP(16, FMT_D),
8261     OPC_MOVCF_D = FOP(17, FMT_D),
8262     OPC_MOVZ_D = FOP(18, FMT_D),
8263     OPC_MOVN_D = FOP(19, FMT_D),
8264     OPC_SELEQZ_D = FOP(20, FMT_D),
8265     OPC_RECIP_D = FOP(21, FMT_D),
8266     OPC_RSQRT_D = FOP(22, FMT_D),
8267     OPC_SELNEZ_D = FOP(23, FMT_D),
8268     OPC_MADDF_D = FOP(24, FMT_D),
8269     OPC_MSUBF_D = FOP(25, FMT_D),
8270     OPC_RINT_D = FOP(26, FMT_D),
8271     OPC_CLASS_D = FOP(27, FMT_D),
8272     OPC_MIN_D = FOP(28, FMT_D),
8273     OPC_RECIP2_D = FOP(28, FMT_D),
8274     OPC_MINA_D = FOP(29, FMT_D),
8275     OPC_RECIP1_D = FOP(29, FMT_D),
8276     OPC_MAX_D = FOP(30, FMT_D),
8277     OPC_RSQRT1_D = FOP(30, FMT_D),
8278     OPC_MAXA_D = FOP(31, FMT_D),
8279     OPC_RSQRT2_D = FOP(31, FMT_D),
8280     OPC_CVT_S_D = FOP(32, FMT_D),
8281     OPC_CVT_W_D = FOP(36, FMT_D),
8282     OPC_CVT_L_D = FOP(37, FMT_D),
8283     OPC_CMP_F_D = FOP (48, FMT_D),
8284     OPC_CMP_UN_D = FOP (49, FMT_D),
8285     OPC_CMP_EQ_D = FOP (50, FMT_D),
8286     OPC_CMP_UEQ_D = FOP (51, FMT_D),
8287     OPC_CMP_OLT_D = FOP (52, FMT_D),
8288     OPC_CMP_ULT_D = FOP (53, FMT_D),
8289     OPC_CMP_OLE_D = FOP (54, FMT_D),
8290     OPC_CMP_ULE_D = FOP (55, FMT_D),
8291     OPC_CMP_SF_D = FOP (56, FMT_D),
8292     OPC_CMP_NGLE_D = FOP (57, FMT_D),
8293     OPC_CMP_SEQ_D = FOP (58, FMT_D),
8294     OPC_CMP_NGL_D = FOP (59, FMT_D),
8295     OPC_CMP_LT_D = FOP (60, FMT_D),
8296     OPC_CMP_NGE_D = FOP (61, FMT_D),
8297     OPC_CMP_LE_D = FOP (62, FMT_D),
8298     OPC_CMP_NGT_D = FOP (63, FMT_D),
8299 
8300     OPC_CVT_S_W = FOP(32, FMT_W),
8301     OPC_CVT_D_W = FOP(33, FMT_W),
8302     OPC_CVT_S_L = FOP(32, FMT_L),
8303     OPC_CVT_D_L = FOP(33, FMT_L),
8304     OPC_CVT_PS_PW = FOP(38, FMT_W),
8305 
8306     OPC_ADD_PS = FOP(0, FMT_PS),
8307     OPC_SUB_PS = FOP(1, FMT_PS),
8308     OPC_MUL_PS = FOP(2, FMT_PS),
8309     OPC_DIV_PS = FOP(3, FMT_PS),
8310     OPC_ABS_PS = FOP(5, FMT_PS),
8311     OPC_MOV_PS = FOP(6, FMT_PS),
8312     OPC_NEG_PS = FOP(7, FMT_PS),
8313     OPC_MOVCF_PS = FOP(17, FMT_PS),
8314     OPC_MOVZ_PS = FOP(18, FMT_PS),
8315     OPC_MOVN_PS = FOP(19, FMT_PS),
8316     OPC_ADDR_PS = FOP(24, FMT_PS),
8317     OPC_MULR_PS = FOP(26, FMT_PS),
8318     OPC_RECIP2_PS = FOP(28, FMT_PS),
8319     OPC_RECIP1_PS = FOP(29, FMT_PS),
8320     OPC_RSQRT1_PS = FOP(30, FMT_PS),
8321     OPC_RSQRT2_PS = FOP(31, FMT_PS),
8322 
8323     OPC_CVT_S_PU = FOP(32, FMT_PS),
8324     OPC_CVT_PW_PS = FOP(36, FMT_PS),
8325     OPC_CVT_S_PL = FOP(40, FMT_PS),
8326     OPC_PLL_PS = FOP(44, FMT_PS),
8327     OPC_PLU_PS = FOP(45, FMT_PS),
8328     OPC_PUL_PS = FOP(46, FMT_PS),
8329     OPC_PUU_PS = FOP(47, FMT_PS),
8330     OPC_CMP_F_PS = FOP (48, FMT_PS),
8331     OPC_CMP_UN_PS = FOP (49, FMT_PS),
8332     OPC_CMP_EQ_PS = FOP (50, FMT_PS),
8333     OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
8334     OPC_CMP_OLT_PS = FOP (52, FMT_PS),
8335     OPC_CMP_ULT_PS = FOP (53, FMT_PS),
8336     OPC_CMP_OLE_PS = FOP (54, FMT_PS),
8337     OPC_CMP_ULE_PS = FOP (55, FMT_PS),
8338     OPC_CMP_SF_PS = FOP (56, FMT_PS),
8339     OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
8340     OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
8341     OPC_CMP_NGL_PS = FOP (59, FMT_PS),
8342     OPC_CMP_LT_PS = FOP (60, FMT_PS),
8343     OPC_CMP_NGE_PS = FOP (61, FMT_PS),
8344     OPC_CMP_LE_PS = FOP (62, FMT_PS),
8345     OPC_CMP_NGT_PS = FOP (63, FMT_PS),
8346 };
8347 
8348 enum r6_f_cmp_op {
8349     R6_OPC_CMP_AF_S   = FOP(0, FMT_W),
8350     R6_OPC_CMP_UN_S   = FOP(1, FMT_W),
8351     R6_OPC_CMP_EQ_S   = FOP(2, FMT_W),
8352     R6_OPC_CMP_UEQ_S  = FOP(3, FMT_W),
8353     R6_OPC_CMP_LT_S   = FOP(4, FMT_W),
8354     R6_OPC_CMP_ULT_S  = FOP(5, FMT_W),
8355     R6_OPC_CMP_LE_S   = FOP(6, FMT_W),
8356     R6_OPC_CMP_ULE_S  = FOP(7, FMT_W),
8357     R6_OPC_CMP_SAF_S  = FOP(8, FMT_W),
8358     R6_OPC_CMP_SUN_S  = FOP(9, FMT_W),
8359     R6_OPC_CMP_SEQ_S  = FOP(10, FMT_W),
8360     R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
8361     R6_OPC_CMP_SLT_S  = FOP(12, FMT_W),
8362     R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
8363     R6_OPC_CMP_SLE_S  = FOP(14, FMT_W),
8364     R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
8365     R6_OPC_CMP_OR_S   = FOP(17, FMT_W),
8366     R6_OPC_CMP_UNE_S  = FOP(18, FMT_W),
8367     R6_OPC_CMP_NE_S   = FOP(19, FMT_W),
8368     R6_OPC_CMP_SOR_S  = FOP(25, FMT_W),
8369     R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
8370     R6_OPC_CMP_SNE_S  = FOP(27, FMT_W),
8371 
8372     R6_OPC_CMP_AF_D   = FOP(0, FMT_L),
8373     R6_OPC_CMP_UN_D   = FOP(1, FMT_L),
8374     R6_OPC_CMP_EQ_D   = FOP(2, FMT_L),
8375     R6_OPC_CMP_UEQ_D  = FOP(3, FMT_L),
8376     R6_OPC_CMP_LT_D   = FOP(4, FMT_L),
8377     R6_OPC_CMP_ULT_D  = FOP(5, FMT_L),
8378     R6_OPC_CMP_LE_D   = FOP(6, FMT_L),
8379     R6_OPC_CMP_ULE_D  = FOP(7, FMT_L),
8380     R6_OPC_CMP_SAF_D  = FOP(8, FMT_L),
8381     R6_OPC_CMP_SUN_D  = FOP(9, FMT_L),
8382     R6_OPC_CMP_SEQ_D  = FOP(10, FMT_L),
8383     R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
8384     R6_OPC_CMP_SLT_D  = FOP(12, FMT_L),
8385     R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
8386     R6_OPC_CMP_SLE_D  = FOP(14, FMT_L),
8387     R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
8388     R6_OPC_CMP_OR_D   = FOP(17, FMT_L),
8389     R6_OPC_CMP_UNE_D  = FOP(18, FMT_L),
8390     R6_OPC_CMP_NE_D   = FOP(19, FMT_L),
8391     R6_OPC_CMP_SOR_D  = FOP(25, FMT_L),
8392     R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
8393     R6_OPC_CMP_SNE_D  = FOP(27, FMT_L),
8394 };
gen_cp1(DisasContext * ctx,uint32_t opc,int rt,int fs)8395 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
8396 {
8397     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
8398     const char *opn = "cp1 move";
8399     TCGv t0 = tcg_temp_new(tcg_ctx);
8400 
8401     switch (opc) {
8402     case OPC_MFC1:
8403         {
8404             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
8405 
8406             gen_load_fpr32(ctx, fp0, fs);
8407             tcg_gen_ext_i32_tl(tcg_ctx, t0, fp0);
8408             tcg_temp_free_i32(tcg_ctx, fp0);
8409         }
8410         gen_store_gpr(tcg_ctx, t0, rt);
8411         opn = "mfc1";
8412         break;
8413     case OPC_MTC1:
8414         gen_load_gpr(ctx, t0, rt);
8415         {
8416             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
8417 
8418             tcg_gen_trunc_tl_i32(tcg_ctx, fp0, t0);
8419             gen_store_fpr32(ctx, fp0, fs);
8420             tcg_temp_free_i32(tcg_ctx, fp0);
8421         }
8422         opn = "mtc1";
8423         break;
8424     case OPC_CFC1:
8425         gen_helper_1e0i(tcg_ctx, cfc1, t0, fs);
8426         gen_store_gpr(tcg_ctx, t0, rt);
8427         opn = "cfc1";
8428         break;
8429     case OPC_CTC1:
8430         gen_load_gpr(ctx, t0, rt);
8431         save_cpu_state(ctx, 1);
8432         {
8433             TCGv_i32 fs_tmp = tcg_const_i32(tcg_ctx, fs);
8434 
8435             gen_helper_0e2i(tcg_ctx, ctc1, t0, fs_tmp, rt);
8436             tcg_temp_free_i32(tcg_ctx, fs_tmp);
8437         }
8438         /* Stop translation as we may have changed hflags */
8439         ctx->bstate = BS_STOP;
8440         opn = "ctc1";
8441         break;
8442 #if defined(TARGET_MIPS64)
8443     case OPC_DMFC1:
8444         gen_load_fpr64(ctx, t0, fs);
8445         gen_store_gpr(tcg_ctx, t0, rt);
8446         opn = "dmfc1";
8447         break;
8448     case OPC_DMTC1:
8449         gen_load_gpr(ctx, t0, rt);
8450         gen_store_fpr64(ctx, t0, fs);
8451         opn = "dmtc1";
8452         break;
8453 #endif
8454     case OPC_MFHC1:
8455         {
8456             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
8457 
8458             gen_load_fpr32h(ctx, fp0, fs);
8459             tcg_gen_ext_i32_tl(tcg_ctx, t0, fp0);
8460             tcg_temp_free_i32(tcg_ctx, fp0);
8461         }
8462         gen_store_gpr(tcg_ctx, t0, rt);
8463         opn = "mfhc1";
8464         break;
8465     case OPC_MTHC1:
8466         gen_load_gpr(ctx, t0, rt);
8467         {
8468             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
8469 
8470             tcg_gen_trunc_tl_i32(tcg_ctx, fp0, t0);
8471             gen_store_fpr32h(ctx, fp0, fs);
8472             tcg_temp_free_i32(tcg_ctx, fp0);
8473         }
8474         opn = "mthc1";
8475         break;
8476     default:
8477         MIPS_INVAL(opn);
8478         generate_exception (ctx, EXCP_RI);
8479         goto out;
8480     }
8481     (void)opn; /* avoid a compiler warning */
8482     MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
8483 
8484  out:
8485     tcg_temp_free(tcg_ctx, t0);
8486 }
8487 
gen_movci(DisasContext * ctx,int rd,int rs,int cc,int tf)8488 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
8489 {
8490     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
8491     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
8492     int l1;
8493     TCGCond cond;
8494     TCGv_i32 t0;
8495 
8496     if (rd == 0) {
8497         /* Treat as NOP. */
8498         return;
8499     }
8500 
8501     if (tf)
8502         cond = TCG_COND_EQ;
8503     else
8504         cond = TCG_COND_NE;
8505 
8506     l1 = gen_new_label(tcg_ctx);
8507     t0 = tcg_temp_new_i32(tcg_ctx);
8508     tcg_gen_andi_i32(tcg_ctx, t0, tcg_ctx->fpu_fcr31, 1U << (get_fp_bit(cc) & 0x1f));
8509     tcg_gen_brcondi_i32(tcg_ctx, cond, t0, 0, l1);
8510     tcg_temp_free_i32(tcg_ctx, t0);
8511     if (rs == 0) {
8512         tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[rd], 0);
8513     } else {
8514         tcg_gen_mov_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rs]);
8515     }
8516     gen_set_label(tcg_ctx, l1);
8517 }
8518 
gen_movcf_s(DisasContext * ctx,int fs,int fd,int cc,int tf)8519 static inline void gen_movcf_s (DisasContext *ctx, int fs, int fd, int cc, int tf)
8520 {
8521     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
8522     int cond;
8523     TCGv_i32 t0 = tcg_temp_new_i32(tcg_ctx);
8524     int l1 = gen_new_label(tcg_ctx);
8525 
8526     if (tf)
8527         cond = TCG_COND_EQ;
8528     else
8529         cond = TCG_COND_NE;
8530 
8531     tcg_gen_andi_i32(tcg_ctx, t0, tcg_ctx->fpu_fcr31, 1U << (get_fp_bit(cc) & 0x1f));
8532     tcg_gen_brcondi_i32(tcg_ctx, cond, t0, 0, l1);
8533     gen_load_fpr32(ctx, t0, fs);
8534     gen_store_fpr32(ctx, t0, fd);
8535     gen_set_label(tcg_ctx, l1);
8536     tcg_temp_free_i32(tcg_ctx, t0);
8537 }
8538 
gen_movcf_d(DisasContext * ctx,int fs,int fd,int cc,int tf)8539 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
8540 {
8541     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
8542     int cond;
8543     TCGv_i32 t0 = tcg_temp_new_i32(tcg_ctx);
8544     TCGv_i64 fp0;
8545     int l1 = gen_new_label(tcg_ctx);
8546 
8547     if (tf)
8548         cond = TCG_COND_EQ;
8549     else
8550         cond = TCG_COND_NE;
8551 
8552     tcg_gen_andi_i32(tcg_ctx, t0, tcg_ctx->fpu_fcr31, 1U << (get_fp_bit(cc) & 0x1f));
8553     tcg_gen_brcondi_i32(tcg_ctx, cond, t0, 0, l1);
8554     tcg_temp_free_i32(tcg_ctx, t0);
8555     fp0 = tcg_temp_new_i64(tcg_ctx);
8556     gen_load_fpr64(ctx, fp0, fs);
8557     gen_store_fpr64(ctx, fp0, fd);
8558     tcg_temp_free_i64(tcg_ctx, fp0);
8559     gen_set_label(tcg_ctx, l1);
8560 }
8561 
gen_movcf_ps(DisasContext * ctx,int fs,int fd,int cc,int tf)8562 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
8563                                 int cc, int tf)
8564 {
8565     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
8566     int cond;
8567     TCGv_i32 t0 = tcg_temp_new_i32(tcg_ctx);
8568     int l1 = gen_new_label(tcg_ctx);
8569     int l2 = gen_new_label(tcg_ctx);
8570 
8571     if (tf)
8572         cond = TCG_COND_EQ;
8573     else
8574         cond = TCG_COND_NE;
8575 
8576     tcg_gen_andi_i32(tcg_ctx, t0, tcg_ctx->fpu_fcr31, 1U << (get_fp_bit(cc) & 0x1f));
8577     tcg_gen_brcondi_i32(tcg_ctx, cond, t0, 0, l1);
8578     gen_load_fpr32(ctx, t0, fs);
8579     gen_store_fpr32(ctx, t0, fd);
8580     gen_set_label(tcg_ctx, l1);
8581 
8582     tcg_gen_andi_i32(tcg_ctx, t0, tcg_ctx->fpu_fcr31, 1U << (get_fp_bit(cc+1) & 0x1f));
8583     tcg_gen_brcondi_i32(tcg_ctx, cond, t0, 0, l2);
8584     gen_load_fpr32h(ctx, t0, fs);
8585     gen_store_fpr32h(ctx, t0, fd);
8586     tcg_temp_free_i32(tcg_ctx, t0);
8587     gen_set_label(tcg_ctx, l2);
8588 }
8589 
gen_sel_s(DisasContext * ctx,enum fopcode op1,int fd,int ft,int fs)8590 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8591                       int fs)
8592 {
8593     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
8594     TCGv_i32 t1 = tcg_const_i32(tcg_ctx, 0);
8595     TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
8596     TCGv_i32 fp1 = tcg_temp_new_i32(tcg_ctx);
8597     TCGv_i32 fp2 = tcg_temp_new_i32(tcg_ctx);
8598     gen_load_fpr32(ctx, fp0, fd);
8599     gen_load_fpr32(ctx, fp1, ft);
8600     gen_load_fpr32(ctx, fp2, fs);
8601 
8602     switch (op1) {
8603     case OPC_SEL_S:
8604         tcg_gen_andi_i32(tcg_ctx, fp0, fp0, 1);
8605         tcg_gen_movcond_i32(tcg_ctx, TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8606         break;
8607     case OPC_SELEQZ_S:
8608         tcg_gen_andi_i32(tcg_ctx, fp1, fp1, 1);
8609         tcg_gen_movcond_i32(tcg_ctx, TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8610         break;
8611     case OPC_SELNEZ_S:
8612         tcg_gen_andi_i32(tcg_ctx, fp1, fp1, 1);
8613         tcg_gen_movcond_i32(tcg_ctx, TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8614         break;
8615     default:
8616         MIPS_INVAL("gen_sel_s");
8617         generate_exception (ctx, EXCP_RI);
8618         break;
8619     }
8620 
8621     gen_store_fpr32(ctx, fp0, fd);
8622     tcg_temp_free_i32(tcg_ctx, fp2);
8623     tcg_temp_free_i32(tcg_ctx, fp1);
8624     tcg_temp_free_i32(tcg_ctx, fp0);
8625     tcg_temp_free_i32(tcg_ctx, t1);
8626 }
8627 
gen_sel_d(DisasContext * ctx,enum fopcode op1,int fd,int ft,int fs)8628 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8629                       int fs)
8630 {
8631     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
8632     TCGv_i64 t1 = tcg_const_i64(tcg_ctx, 0);
8633     TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
8634     TCGv_i64 fp1 = tcg_temp_new_i64(tcg_ctx);
8635     TCGv_i64 fp2 = tcg_temp_new_i64(tcg_ctx);
8636     gen_load_fpr64(ctx, fp0, fd);
8637     gen_load_fpr64(ctx, fp1, ft);
8638     gen_load_fpr64(ctx, fp2, fs);
8639 
8640     switch (op1) {
8641     case OPC_SEL_D:
8642         tcg_gen_andi_i64(tcg_ctx, fp0, fp0, 1);
8643         tcg_gen_movcond_i64(tcg_ctx, TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8644         break;
8645     case OPC_SELEQZ_D:
8646         tcg_gen_andi_i64(tcg_ctx, fp1, fp1, 1);
8647         tcg_gen_movcond_i64(tcg_ctx, TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8648         break;
8649     case OPC_SELNEZ_D:
8650         tcg_gen_andi_i64(tcg_ctx, fp1, fp1, 1);
8651         tcg_gen_movcond_i64(tcg_ctx, TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8652         break;
8653     default:
8654         MIPS_INVAL("gen_sel_d");
8655         generate_exception (ctx, EXCP_RI);
8656         break;
8657     }
8658 
8659     gen_store_fpr64(ctx, fp0, fd);
8660     tcg_temp_free_i64(tcg_ctx, fp2);
8661     tcg_temp_free_i64(tcg_ctx, fp1);
8662     tcg_temp_free_i64(tcg_ctx, fp0);
8663     tcg_temp_free_i64(tcg_ctx, t1);
8664 }
8665 
gen_farith(DisasContext * ctx,enum fopcode op1,int ft,int fs,int fd,int cc)8666 static void gen_farith (DisasContext *ctx, enum fopcode op1,
8667                         int ft, int fs, int fd, int cc)
8668 {
8669     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
8670     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
8671     const char *opn = "farith";
8672     const char *condnames[] = {
8673             "c.f",
8674             "c.un",
8675             "c.eq",
8676             "c.ueq",
8677             "c.olt",
8678             "c.ult",
8679             "c.ole",
8680             "c.ule",
8681             "c.sf",
8682             "c.ngle",
8683             "c.seq",
8684             "c.ngl",
8685             "c.lt",
8686             "c.nge",
8687             "c.le",
8688             "c.ngt",
8689     };
8690     const char *condnames_abs[] = {
8691             "cabs.f",
8692             "cabs.un",
8693             "cabs.eq",
8694             "cabs.ueq",
8695             "cabs.olt",
8696             "cabs.ult",
8697             "cabs.ole",
8698             "cabs.ule",
8699             "cabs.sf",
8700             "cabs.ngle",
8701             "cabs.seq",
8702             "cabs.ngl",
8703             "cabs.lt",
8704             "cabs.nge",
8705             "cabs.le",
8706             "cabs.ngt",
8707     };
8708     enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
8709     uint32_t func = ctx->opcode & 0x3f;
8710 
8711     switch (op1) {
8712     case OPC_ADD_S:
8713         {
8714             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
8715             TCGv_i32 fp1 = tcg_temp_new_i32(tcg_ctx);
8716 
8717             gen_load_fpr32(ctx, fp0, fs);
8718             gen_load_fpr32(ctx, fp1, ft);
8719             gen_helper_float_add_s(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);
8720             tcg_temp_free_i32(tcg_ctx, fp1);
8721             gen_store_fpr32(ctx, fp0, fd);
8722             tcg_temp_free_i32(tcg_ctx, fp0);
8723         }
8724         opn = "add.s";
8725         optype = BINOP;
8726         break;
8727     case OPC_SUB_S:
8728         {
8729             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
8730             TCGv_i32 fp1 = tcg_temp_new_i32(tcg_ctx);
8731 
8732             gen_load_fpr32(ctx, fp0, fs);
8733             gen_load_fpr32(ctx, fp1, ft);
8734             gen_helper_float_sub_s(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);
8735             tcg_temp_free_i32(tcg_ctx, fp1);
8736             gen_store_fpr32(ctx, fp0, fd);
8737             tcg_temp_free_i32(tcg_ctx, fp0);
8738         }
8739         opn = "sub.s";
8740         optype = BINOP;
8741         break;
8742     case OPC_MUL_S:
8743         {
8744             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
8745             TCGv_i32 fp1 = tcg_temp_new_i32(tcg_ctx);
8746 
8747             gen_load_fpr32(ctx, fp0, fs);
8748             gen_load_fpr32(ctx, fp1, ft);
8749             gen_helper_float_mul_s(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);
8750             tcg_temp_free_i32(tcg_ctx, fp1);
8751             gen_store_fpr32(ctx, fp0, fd);
8752             tcg_temp_free_i32(tcg_ctx, fp0);
8753         }
8754         opn = "mul.s";
8755         optype = BINOP;
8756         break;
8757     case OPC_DIV_S:
8758         {
8759             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
8760             TCGv_i32 fp1 = tcg_temp_new_i32(tcg_ctx);
8761 
8762             gen_load_fpr32(ctx, fp0, fs);
8763             gen_load_fpr32(ctx, fp1, ft);
8764             gen_helper_float_div_s(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);
8765             tcg_temp_free_i32(tcg_ctx, fp1);
8766             gen_store_fpr32(ctx, fp0, fd);
8767             tcg_temp_free_i32(tcg_ctx, fp0);
8768         }
8769         opn = "div.s";
8770         optype = BINOP;
8771         break;
8772     case OPC_SQRT_S:
8773         {
8774             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
8775 
8776             gen_load_fpr32(ctx, fp0, fs);
8777             gen_helper_float_sqrt_s(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0);
8778             gen_store_fpr32(ctx, fp0, fd);
8779             tcg_temp_free_i32(tcg_ctx, fp0);
8780         }
8781         opn = "sqrt.s";
8782         break;
8783     case OPC_ABS_S:
8784         {
8785             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
8786 
8787             gen_load_fpr32(ctx, fp0, fs);
8788             gen_helper_float_abs_s(tcg_ctx, fp0, fp0);
8789             gen_store_fpr32(ctx, fp0, fd);
8790             tcg_temp_free_i32(tcg_ctx, fp0);
8791         }
8792         opn = "abs.s";
8793         break;
8794     case OPC_MOV_S:
8795         {
8796             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
8797 
8798             gen_load_fpr32(ctx, fp0, fs);
8799             gen_store_fpr32(ctx, fp0, fd);
8800             tcg_temp_free_i32(tcg_ctx, fp0);
8801         }
8802         opn = "mov.s";
8803         break;
8804     case OPC_NEG_S:
8805         {
8806             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
8807 
8808             gen_load_fpr32(ctx, fp0, fs);
8809             gen_helper_float_chs_s(tcg_ctx, fp0, fp0);
8810             gen_store_fpr32(ctx, fp0, fd);
8811             tcg_temp_free_i32(tcg_ctx, fp0);
8812         }
8813         opn = "neg.s";
8814         break;
8815     case OPC_ROUND_L_S:
8816         check_cp1_64bitmode(ctx);
8817         {
8818             TCGv_i32 fp32 = tcg_temp_new_i32(tcg_ctx);
8819             TCGv_i64 fp64 = tcg_temp_new_i64(tcg_ctx);
8820 
8821             gen_load_fpr32(ctx, fp32, fs);
8822             gen_helper_float_roundl_s(tcg_ctx, fp64, tcg_ctx->cpu_env, fp32);
8823             tcg_temp_free_i32(tcg_ctx, fp32);
8824             gen_store_fpr64(ctx, fp64, fd);
8825             tcg_temp_free_i64(tcg_ctx, fp64);
8826         }
8827         opn = "round.l.s";
8828         break;
8829     case OPC_TRUNC_L_S:
8830         check_cp1_64bitmode(ctx);
8831         {
8832             TCGv_i32 fp32 = tcg_temp_new_i32(tcg_ctx);
8833             TCGv_i64 fp64 = tcg_temp_new_i64(tcg_ctx);
8834 
8835             gen_load_fpr32(ctx, fp32, fs);
8836             gen_helper_float_truncl_s(tcg_ctx, fp64, tcg_ctx->cpu_env, fp32);
8837             tcg_temp_free_i32(tcg_ctx, fp32);
8838             gen_store_fpr64(ctx, fp64, fd);
8839             tcg_temp_free_i64(tcg_ctx, fp64);
8840         }
8841         opn = "trunc.l.s";
8842         break;
8843     case OPC_CEIL_L_S:
8844         check_cp1_64bitmode(ctx);
8845         {
8846             TCGv_i32 fp32 = tcg_temp_new_i32(tcg_ctx);
8847             TCGv_i64 fp64 = tcg_temp_new_i64(tcg_ctx);
8848 
8849             gen_load_fpr32(ctx, fp32, fs);
8850             gen_helper_float_ceill_s(tcg_ctx, fp64, tcg_ctx->cpu_env, fp32);
8851             tcg_temp_free_i32(tcg_ctx, fp32);
8852             gen_store_fpr64(ctx, fp64, fd);
8853             tcg_temp_free_i64(tcg_ctx, fp64);
8854         }
8855         opn = "ceil.l.s";
8856         break;
8857     case OPC_FLOOR_L_S:
8858         check_cp1_64bitmode(ctx);
8859         {
8860             TCGv_i32 fp32 = tcg_temp_new_i32(tcg_ctx);
8861             TCGv_i64 fp64 = tcg_temp_new_i64(tcg_ctx);
8862 
8863             gen_load_fpr32(ctx, fp32, fs);
8864             gen_helper_float_floorl_s(tcg_ctx, fp64, tcg_ctx->cpu_env, fp32);
8865             tcg_temp_free_i32(tcg_ctx, fp32);
8866             gen_store_fpr64(ctx, fp64, fd);
8867             tcg_temp_free_i64(tcg_ctx, fp64);
8868         }
8869         opn = "floor.l.s";
8870         break;
8871     case OPC_ROUND_W_S:
8872         {
8873             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
8874 
8875             gen_load_fpr32(ctx, fp0, fs);
8876             gen_helper_float_roundw_s(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0);
8877             gen_store_fpr32(ctx, fp0, fd);
8878             tcg_temp_free_i32(tcg_ctx, fp0);
8879         }
8880         opn = "round.w.s";
8881         break;
8882     case OPC_TRUNC_W_S:
8883         {
8884             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
8885 
8886             gen_load_fpr32(ctx, fp0, fs);
8887             gen_helper_float_truncw_s(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0);
8888             gen_store_fpr32(ctx, fp0, fd);
8889             tcg_temp_free_i32(tcg_ctx, fp0);
8890         }
8891         opn = "trunc.w.s";
8892         break;
8893     case OPC_CEIL_W_S:
8894         {
8895             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
8896 
8897             gen_load_fpr32(ctx, fp0, fs);
8898             gen_helper_float_ceilw_s(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0);
8899             gen_store_fpr32(ctx, fp0, fd);
8900             tcg_temp_free_i32(tcg_ctx, fp0);
8901         }
8902         opn = "ceil.w.s";
8903         break;
8904     case OPC_FLOOR_W_S:
8905         {
8906             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
8907 
8908             gen_load_fpr32(ctx, fp0, fs);
8909             gen_helper_float_floorw_s(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0);
8910             gen_store_fpr32(ctx, fp0, fd);
8911             tcg_temp_free_i32(tcg_ctx, fp0);
8912         }
8913         opn = "floor.w.s";
8914         break;
8915     case OPC_SEL_S:
8916         check_insn(ctx, ISA_MIPS32R6);
8917         gen_sel_s(ctx, op1, fd, ft, fs);
8918         opn = "sel.s";
8919         break;
8920     case OPC_SELEQZ_S:
8921         check_insn(ctx, ISA_MIPS32R6);
8922         gen_sel_s(ctx, op1, fd, ft, fs);
8923         opn = "seleqz.s";
8924         break;
8925     case OPC_SELNEZ_S:
8926         check_insn(ctx, ISA_MIPS32R6);
8927         gen_sel_s(ctx, op1, fd, ft, fs);
8928         opn = "selnez.s";
8929         break;
8930     case OPC_MOVCF_S:
8931         check_insn_opc_removed(ctx, ISA_MIPS32R6);
8932         gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8933         opn = "movcf.s";
8934         break;
8935     case OPC_MOVZ_S:
8936         check_insn_opc_removed(ctx, ISA_MIPS32R6);
8937         {
8938             int l1 = gen_new_label(tcg_ctx);
8939             TCGv_i32 fp0;
8940 
8941             if (ft != 0) {
8942                 tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_NE, *cpu_gpr[ft], 0, l1);
8943             }
8944             fp0 = tcg_temp_new_i32(tcg_ctx);
8945             gen_load_fpr32(ctx, fp0, fs);
8946             gen_store_fpr32(ctx, fp0, fd);
8947             tcg_temp_free_i32(tcg_ctx, fp0);
8948             gen_set_label(tcg_ctx, l1);
8949         }
8950         opn = "movz.s";
8951         break;
8952     case OPC_MOVN_S:
8953         check_insn_opc_removed(ctx, ISA_MIPS32R6);
8954         {
8955             int l1 = gen_new_label(tcg_ctx);
8956             TCGv_i32 fp0;
8957 
8958             if (ft != 0) {
8959                 tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_EQ, *cpu_gpr[ft], 0, l1);
8960                 fp0 = tcg_temp_new_i32(tcg_ctx);
8961                 gen_load_fpr32(ctx, fp0, fs);
8962                 gen_store_fpr32(ctx, fp0, fd);
8963                 tcg_temp_free_i32(tcg_ctx, fp0);
8964                 gen_set_label(tcg_ctx, l1);
8965             }
8966         }
8967         opn = "movn.s";
8968         break;
8969     case OPC_RECIP_S:
8970         check_cop1x(ctx);
8971         {
8972             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
8973 
8974             gen_load_fpr32(ctx, fp0, fs);
8975             gen_helper_float_recip_s(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0);
8976             gen_store_fpr32(ctx, fp0, fd);
8977             tcg_temp_free_i32(tcg_ctx, fp0);
8978         }
8979         opn = "recip.s";
8980         break;
8981     case OPC_RSQRT_S:
8982         check_cop1x(ctx);
8983         {
8984             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
8985 
8986             gen_load_fpr32(ctx, fp0, fs);
8987             gen_helper_float_rsqrt_s(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0);
8988             gen_store_fpr32(ctx, fp0, fd);
8989             tcg_temp_free_i32(tcg_ctx, fp0);
8990         }
8991         opn = "rsqrt.s";
8992         break;
8993     case OPC_MADDF_S:
8994         check_insn(ctx, ISA_MIPS32R6);
8995         {
8996             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
8997             TCGv_i32 fp1 = tcg_temp_new_i32(tcg_ctx);
8998             TCGv_i32 fp2 = tcg_temp_new_i32(tcg_ctx);
8999             gen_load_fpr32(ctx, fp0, fs);
9000             gen_load_fpr32(ctx, fp1, ft);
9001             gen_load_fpr32(ctx, fp2, fd);
9002             gen_helper_float_maddf_s(tcg_ctx, fp2, tcg_ctx->cpu_env, fp0, fp1, fp2);
9003             gen_store_fpr32(ctx, fp2, fd);
9004             tcg_temp_free_i32(tcg_ctx, fp2);
9005             tcg_temp_free_i32(tcg_ctx, fp1);
9006             tcg_temp_free_i32(tcg_ctx, fp0);
9007             opn = "maddf.s";
9008         }
9009         break;
9010     case OPC_MSUBF_S:
9011         check_insn(ctx, ISA_MIPS32R6);
9012         {
9013             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
9014             TCGv_i32 fp1 = tcg_temp_new_i32(tcg_ctx);
9015             TCGv_i32 fp2 = tcg_temp_new_i32(tcg_ctx);
9016             gen_load_fpr32(ctx, fp0, fs);
9017             gen_load_fpr32(ctx, fp1, ft);
9018             gen_load_fpr32(ctx, fp2, fd);
9019             gen_helper_float_msubf_s(tcg_ctx, fp2, tcg_ctx->cpu_env, fp0, fp1, fp2);
9020             gen_store_fpr32(ctx, fp2, fd);
9021             tcg_temp_free_i32(tcg_ctx, fp2);
9022             tcg_temp_free_i32(tcg_ctx, fp1);
9023             tcg_temp_free_i32(tcg_ctx, fp0);
9024             opn = "msubf.s";
9025         }
9026         break;
9027     case OPC_RINT_S:
9028         check_insn(ctx, ISA_MIPS32R6);
9029         {
9030             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
9031             gen_load_fpr32(ctx, fp0, fs);
9032             gen_helper_float_rint_s(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0);
9033             gen_store_fpr32(ctx, fp0, fd);
9034             tcg_temp_free_i32(tcg_ctx, fp0);
9035             opn = "rint.s";
9036         }
9037         break;
9038     case OPC_CLASS_S:
9039         check_insn(ctx, ISA_MIPS32R6);
9040         {
9041             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
9042             gen_load_fpr32(ctx, fp0, fs);
9043             gen_helper_float_class_s(tcg_ctx, fp0, fp0);
9044             gen_store_fpr32(ctx, fp0, fd);
9045             tcg_temp_free_i32(tcg_ctx, fp0);
9046             opn = "class.s";
9047         }
9048         break;
9049     case OPC_MIN_S: /* OPC_RECIP2_S */
9050         if (ctx->insn_flags & ISA_MIPS32R6) {
9051             /* OPC_MIN_S */
9052             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
9053             TCGv_i32 fp1 = tcg_temp_new_i32(tcg_ctx);
9054             TCGv_i32 fp2 = tcg_temp_new_i32(tcg_ctx);
9055             gen_load_fpr32(ctx, fp0, fs);
9056             gen_load_fpr32(ctx, fp1, ft);
9057             gen_helper_float_min_s(tcg_ctx, fp2, tcg_ctx->cpu_env, fp0, fp1);
9058             gen_store_fpr32(ctx, fp2, fd);
9059             tcg_temp_free_i32(tcg_ctx, fp2);
9060             tcg_temp_free_i32(tcg_ctx, fp1);
9061             tcg_temp_free_i32(tcg_ctx, fp0);
9062             opn = "min.s";
9063         } else {
9064             /* OPC_RECIP2_S */
9065             check_cp1_64bitmode(ctx);
9066             {
9067                 TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
9068                 TCGv_i32 fp1 = tcg_temp_new_i32(tcg_ctx);
9069 
9070                 gen_load_fpr32(ctx, fp0, fs);
9071                 gen_load_fpr32(ctx, fp1, ft);
9072                 gen_helper_float_recip2_s(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);
9073                 tcg_temp_free_i32(tcg_ctx, fp1);
9074                 gen_store_fpr32(ctx, fp0, fd);
9075                 tcg_temp_free_i32(tcg_ctx, fp0);
9076             }
9077             opn = "recip2.s";
9078         }
9079         break;
9080     case OPC_MINA_S: /* OPC_RECIP1_S */
9081         if (ctx->insn_flags & ISA_MIPS32R6) {
9082             /* OPC_MINA_S */
9083             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
9084             TCGv_i32 fp1 = tcg_temp_new_i32(tcg_ctx);
9085             TCGv_i32 fp2 = tcg_temp_new_i32(tcg_ctx);
9086             gen_load_fpr32(ctx, fp0, fs);
9087             gen_load_fpr32(ctx, fp1, ft);
9088             gen_helper_float_mina_s(tcg_ctx, fp2, tcg_ctx->cpu_env, fp0, fp1);
9089             gen_store_fpr32(ctx, fp2, fd);
9090             tcg_temp_free_i32(tcg_ctx, fp2);
9091             tcg_temp_free_i32(tcg_ctx, fp1);
9092             tcg_temp_free_i32(tcg_ctx, fp0);
9093             opn = "mina.s";
9094         } else {
9095             /* OPC_RECIP1_S */
9096             check_cp1_64bitmode(ctx);
9097             {
9098                 TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
9099 
9100                 gen_load_fpr32(ctx, fp0, fs);
9101                 gen_helper_float_recip1_s(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0);
9102                 gen_store_fpr32(ctx, fp0, fd);
9103                 tcg_temp_free_i32(tcg_ctx, fp0);
9104             }
9105             opn = "recip1.s";
9106         }
9107         break;
9108     case OPC_MAX_S: /* OPC_RSQRT1_S */
9109         if (ctx->insn_flags & ISA_MIPS32R6) {
9110             /* OPC_MAX_S */
9111             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
9112             TCGv_i32 fp1 = tcg_temp_new_i32(tcg_ctx);
9113             gen_load_fpr32(ctx, fp0, fs);
9114             gen_load_fpr32(ctx, fp1, ft);
9115             gen_helper_float_max_s(tcg_ctx, fp1, tcg_ctx->cpu_env, fp0, fp1);
9116             gen_store_fpr32(ctx, fp1, fd);
9117             tcg_temp_free_i32(tcg_ctx, fp1);
9118             tcg_temp_free_i32(tcg_ctx, fp0);
9119             opn = "max.s";
9120         } else {
9121             /* OPC_RSQRT1_S */
9122             check_cp1_64bitmode(ctx);
9123             {
9124                 TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
9125 
9126                 gen_load_fpr32(ctx, fp0, fs);
9127                 gen_helper_float_rsqrt1_s(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0);
9128                 gen_store_fpr32(ctx, fp0, fd);
9129                 tcg_temp_free_i32(tcg_ctx, fp0);
9130             }
9131             opn = "rsqrt1.s";
9132         }
9133         break;
9134     case OPC_MAXA_S: /* OPC_RSQRT2_S */
9135         if (ctx->insn_flags & ISA_MIPS32R6) {
9136             /* OPC_MAXA_S */
9137             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
9138             TCGv_i32 fp1 = tcg_temp_new_i32(tcg_ctx);
9139             gen_load_fpr32(ctx, fp0, fs);
9140             gen_load_fpr32(ctx, fp1, ft);
9141             gen_helper_float_maxa_s(tcg_ctx, fp1, tcg_ctx->cpu_env, fp0, fp1);
9142             gen_store_fpr32(ctx, fp1, fd);
9143             tcg_temp_free_i32(tcg_ctx, fp1);
9144             tcg_temp_free_i32(tcg_ctx, fp0);
9145             opn = "maxa.s";
9146         } else {
9147             /* OPC_RSQRT2_S */
9148             check_cp1_64bitmode(ctx);
9149             {
9150                 TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
9151                 TCGv_i32 fp1 = tcg_temp_new_i32(tcg_ctx);
9152 
9153                 gen_load_fpr32(ctx, fp0, fs);
9154                 gen_load_fpr32(ctx, fp1, ft);
9155                 gen_helper_float_rsqrt2_s(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);
9156                 tcg_temp_free_i32(tcg_ctx, fp1);
9157                 gen_store_fpr32(ctx, fp0, fd);
9158                 tcg_temp_free_i32(tcg_ctx, fp0);
9159             }
9160             opn = "rsqrt2.s";
9161         }
9162         break;
9163     case OPC_CVT_D_S:
9164         check_cp1_registers(ctx, fd);
9165         {
9166             TCGv_i32 fp32 = tcg_temp_new_i32(tcg_ctx);
9167             TCGv_i64 fp64 = tcg_temp_new_i64(tcg_ctx);
9168 
9169             gen_load_fpr32(ctx, fp32, fs);
9170             gen_helper_float_cvtd_s(tcg_ctx, fp64, tcg_ctx->cpu_env, fp32);
9171             tcg_temp_free_i32(tcg_ctx, fp32);
9172             gen_store_fpr64(ctx, fp64, fd);
9173             tcg_temp_free_i64(tcg_ctx, fp64);
9174         }
9175         opn = "cvt.d.s";
9176         break;
9177     case OPC_CVT_W_S:
9178         {
9179             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
9180 
9181             gen_load_fpr32(ctx, fp0, fs);
9182             gen_helper_float_cvtw_s(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0);
9183             gen_store_fpr32(ctx, fp0, fd);
9184             tcg_temp_free_i32(tcg_ctx, fp0);
9185         }
9186         opn = "cvt.w.s";
9187         break;
9188     case OPC_CVT_L_S:
9189         check_cp1_64bitmode(ctx);
9190         {
9191             TCGv_i32 fp32 = tcg_temp_new_i32(tcg_ctx);
9192             TCGv_i64 fp64 = tcg_temp_new_i64(tcg_ctx);
9193 
9194             gen_load_fpr32(ctx, fp32, fs);
9195             gen_helper_float_cvtl_s(tcg_ctx, fp64, tcg_ctx->cpu_env, fp32);
9196             tcg_temp_free_i32(tcg_ctx, fp32);
9197             gen_store_fpr64(ctx, fp64, fd);
9198             tcg_temp_free_i64(tcg_ctx, fp64);
9199         }
9200         opn = "cvt.l.s";
9201         break;
9202     case OPC_CVT_PS_S:
9203         check_insn_opc_removed(ctx, ISA_MIPS32R6);
9204         check_cp1_64bitmode(ctx);
9205         {
9206             TCGv_i64 fp64 = tcg_temp_new_i64(tcg_ctx);
9207             TCGv_i32 fp32_0 = tcg_temp_new_i32(tcg_ctx);
9208             TCGv_i32 fp32_1 = tcg_temp_new_i32(tcg_ctx);
9209 
9210             gen_load_fpr32(ctx, fp32_0, fs);
9211             gen_load_fpr32(ctx, fp32_1, ft);
9212             tcg_gen_concat_i32_i64(tcg_ctx, fp64, fp32_1, fp32_0);
9213             tcg_temp_free_i32(tcg_ctx, fp32_1);
9214             tcg_temp_free_i32(tcg_ctx, fp32_0);
9215             gen_store_fpr64(ctx, fp64, fd);
9216             tcg_temp_free_i64(tcg_ctx, fp64);
9217         }
9218         opn = "cvt.ps.s";
9219         break;
9220     case OPC_CMP_F_S:
9221     case OPC_CMP_UN_S:
9222     case OPC_CMP_EQ_S:
9223     case OPC_CMP_UEQ_S:
9224     case OPC_CMP_OLT_S:
9225     case OPC_CMP_ULT_S:
9226     case OPC_CMP_OLE_S:
9227     case OPC_CMP_ULE_S:
9228     case OPC_CMP_SF_S:
9229     case OPC_CMP_NGLE_S:
9230     case OPC_CMP_SEQ_S:
9231     case OPC_CMP_NGL_S:
9232     case OPC_CMP_LT_S:
9233     case OPC_CMP_NGE_S:
9234     case OPC_CMP_LE_S:
9235     case OPC_CMP_NGT_S:
9236         check_insn_opc_removed(ctx, ISA_MIPS32R6);
9237         if (ctx->opcode & (1 << 6)) {
9238             gen_cmpabs_s(ctx, func-48, ft, fs, cc);
9239             opn = condnames_abs[func-48];
9240         } else {
9241             gen_cmp_s(ctx, func-48, ft, fs, cc);
9242             opn = condnames[func-48];
9243         }
9244         break;
9245     case OPC_ADD_D:
9246         check_cp1_registers(ctx, fs | ft | fd);
9247         {
9248             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
9249             TCGv_i64 fp1 = tcg_temp_new_i64(tcg_ctx);
9250 
9251             gen_load_fpr64(ctx, fp0, fs);
9252             gen_load_fpr64(ctx, fp1, ft);
9253             gen_helper_float_add_d(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);
9254             tcg_temp_free_i64(tcg_ctx, fp1);
9255             gen_store_fpr64(ctx, fp0, fd);
9256             tcg_temp_free_i64(tcg_ctx, fp0);
9257         }
9258         opn = "add.d";
9259         optype = BINOP;
9260         break;
9261     case OPC_SUB_D:
9262         check_cp1_registers(ctx, fs | ft | fd);
9263         {
9264             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
9265             TCGv_i64 fp1 = tcg_temp_new_i64(tcg_ctx);
9266 
9267             gen_load_fpr64(ctx, fp0, fs);
9268             gen_load_fpr64(ctx, fp1, ft);
9269             gen_helper_float_sub_d(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);
9270             tcg_temp_free_i64(tcg_ctx, fp1);
9271             gen_store_fpr64(ctx, fp0, fd);
9272             tcg_temp_free_i64(tcg_ctx, fp0);
9273         }
9274         opn = "sub.d";
9275         optype = BINOP;
9276         break;
9277     case OPC_MUL_D:
9278         check_cp1_registers(ctx, fs | ft | fd);
9279         {
9280             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
9281             TCGv_i64 fp1 = tcg_temp_new_i64(tcg_ctx);
9282 
9283             gen_load_fpr64(ctx, fp0, fs);
9284             gen_load_fpr64(ctx, fp1, ft);
9285             gen_helper_float_mul_d(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);
9286             tcg_temp_free_i64(tcg_ctx, fp1);
9287             gen_store_fpr64(ctx, fp0, fd);
9288             tcg_temp_free_i64(tcg_ctx, fp0);
9289         }
9290         opn = "mul.d";
9291         optype = BINOP;
9292         break;
9293     case OPC_DIV_D:
9294         check_cp1_registers(ctx, fs | ft | fd);
9295         {
9296             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
9297             TCGv_i64 fp1 = tcg_temp_new_i64(tcg_ctx);
9298 
9299             gen_load_fpr64(ctx, fp0, fs);
9300             gen_load_fpr64(ctx, fp1, ft);
9301             gen_helper_float_div_d(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);
9302             tcg_temp_free_i64(tcg_ctx, fp1);
9303             gen_store_fpr64(ctx, fp0, fd);
9304             tcg_temp_free_i64(tcg_ctx, fp0);
9305         }
9306         opn = "div.d";
9307         optype = BINOP;
9308         break;
9309     case OPC_SQRT_D:
9310         check_cp1_registers(ctx, fs | fd);
9311         {
9312             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
9313 
9314             gen_load_fpr64(ctx, fp0, fs);
9315             gen_helper_float_sqrt_d(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0);
9316             gen_store_fpr64(ctx, fp0, fd);
9317             tcg_temp_free_i64(tcg_ctx, fp0);
9318         }
9319         opn = "sqrt.d";
9320         break;
9321     case OPC_ABS_D:
9322         check_cp1_registers(ctx, fs | fd);
9323         {
9324             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
9325 
9326             gen_load_fpr64(ctx, fp0, fs);
9327             gen_helper_float_abs_d(tcg_ctx, fp0, fp0);
9328             gen_store_fpr64(ctx, fp0, fd);
9329             tcg_temp_free_i64(tcg_ctx, fp0);
9330         }
9331         opn = "abs.d";
9332         break;
9333     case OPC_MOV_D:
9334         check_cp1_registers(ctx, fs | fd);
9335         {
9336             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
9337 
9338             gen_load_fpr64(ctx, fp0, fs);
9339             gen_store_fpr64(ctx, fp0, fd);
9340             tcg_temp_free_i64(tcg_ctx, fp0);
9341         }
9342         opn = "mov.d";
9343         break;
9344     case OPC_NEG_D:
9345         check_cp1_registers(ctx, fs | fd);
9346         {
9347             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
9348 
9349             gen_load_fpr64(ctx, fp0, fs);
9350             gen_helper_float_chs_d(tcg_ctx, fp0, fp0);
9351             gen_store_fpr64(ctx, fp0, fd);
9352             tcg_temp_free_i64(tcg_ctx, fp0);
9353         }
9354         opn = "neg.d";
9355         break;
9356     case OPC_ROUND_L_D:
9357         check_cp1_64bitmode(ctx);
9358         {
9359             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
9360 
9361             gen_load_fpr64(ctx, fp0, fs);
9362             gen_helper_float_roundl_d(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0);
9363             gen_store_fpr64(ctx, fp0, fd);
9364             tcg_temp_free_i64(tcg_ctx, fp0);
9365         }
9366         opn = "round.l.d";
9367         break;
9368     case OPC_TRUNC_L_D:
9369         check_cp1_64bitmode(ctx);
9370         {
9371             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
9372 
9373             gen_load_fpr64(ctx, fp0, fs);
9374             gen_helper_float_truncl_d(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0);
9375             gen_store_fpr64(ctx, fp0, fd);
9376             tcg_temp_free_i64(tcg_ctx, fp0);
9377         }
9378         opn = "trunc.l.d";
9379         break;
9380     case OPC_CEIL_L_D:
9381         check_cp1_64bitmode(ctx);
9382         {
9383             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
9384 
9385             gen_load_fpr64(ctx, fp0, fs);
9386             gen_helper_float_ceill_d(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0);
9387             gen_store_fpr64(ctx, fp0, fd);
9388             tcg_temp_free_i64(tcg_ctx, fp0);
9389         }
9390         opn = "ceil.l.d";
9391         break;
9392     case OPC_FLOOR_L_D:
9393         check_cp1_64bitmode(ctx);
9394         {
9395             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
9396 
9397             gen_load_fpr64(ctx, fp0, fs);
9398             gen_helper_float_floorl_d(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0);
9399             gen_store_fpr64(ctx, fp0, fd);
9400             tcg_temp_free_i64(tcg_ctx, fp0);
9401         }
9402         opn = "floor.l.d";
9403         break;
9404     case OPC_ROUND_W_D:
9405         check_cp1_registers(ctx, fs);
9406         {
9407             TCGv_i32 fp32 = tcg_temp_new_i32(tcg_ctx);
9408             TCGv_i64 fp64 = tcg_temp_new_i64(tcg_ctx);
9409 
9410             gen_load_fpr64(ctx, fp64, fs);
9411             gen_helper_float_roundw_d(tcg_ctx, fp32, tcg_ctx->cpu_env, fp64);
9412             tcg_temp_free_i64(tcg_ctx, fp64);
9413             gen_store_fpr32(ctx, fp32, fd);
9414             tcg_temp_free_i32(tcg_ctx, fp32);
9415         }
9416         opn = "round.w.d";
9417         break;
9418     case OPC_TRUNC_W_D:
9419         check_cp1_registers(ctx, fs);
9420         {
9421             TCGv_i32 fp32 = tcg_temp_new_i32(tcg_ctx);
9422             TCGv_i64 fp64 = tcg_temp_new_i64(tcg_ctx);
9423 
9424             gen_load_fpr64(ctx, fp64, fs);
9425             gen_helper_float_truncw_d(tcg_ctx, fp32, tcg_ctx->cpu_env, fp64);
9426             tcg_temp_free_i64(tcg_ctx, fp64);
9427             gen_store_fpr32(ctx, fp32, fd);
9428             tcg_temp_free_i32(tcg_ctx, fp32);
9429         }
9430         opn = "trunc.w.d";
9431         break;
9432     case OPC_CEIL_W_D:
9433         check_cp1_registers(ctx, fs);
9434         {
9435             TCGv_i32 fp32 = tcg_temp_new_i32(tcg_ctx);
9436             TCGv_i64 fp64 = tcg_temp_new_i64(tcg_ctx);
9437 
9438             gen_load_fpr64(ctx, fp64, fs);
9439             gen_helper_float_ceilw_d(tcg_ctx, fp32, tcg_ctx->cpu_env, fp64);
9440             tcg_temp_free_i64(tcg_ctx, fp64);
9441             gen_store_fpr32(ctx, fp32, fd);
9442             tcg_temp_free_i32(tcg_ctx, fp32);
9443         }
9444         opn = "ceil.w.d";
9445         break;
9446     case OPC_FLOOR_W_D:
9447         check_cp1_registers(ctx, fs);
9448         {
9449             TCGv_i32 fp32 = tcg_temp_new_i32(tcg_ctx);
9450             TCGv_i64 fp64 = tcg_temp_new_i64(tcg_ctx);
9451 
9452             gen_load_fpr64(ctx, fp64, fs);
9453             gen_helper_float_floorw_d(tcg_ctx, fp32, tcg_ctx->cpu_env, fp64);
9454             tcg_temp_free_i64(tcg_ctx, fp64);
9455             gen_store_fpr32(ctx, fp32, fd);
9456             tcg_temp_free_i32(tcg_ctx, fp32);
9457         }
9458         opn = "floor.w.d";
9459         break;
9460     case OPC_SEL_D:
9461         check_insn(ctx, ISA_MIPS32R6);
9462         gen_sel_d(ctx, op1, fd, ft, fs);
9463         opn = "sel.d";
9464         break;
9465     case OPC_SELEQZ_D:
9466         check_insn(ctx, ISA_MIPS32R6);
9467         gen_sel_d(ctx, op1, fd, ft, fs);
9468         opn = "seleqz.d";
9469         break;
9470     case OPC_SELNEZ_D:
9471         check_insn(ctx, ISA_MIPS32R6);
9472         gen_sel_d(ctx, op1, fd, ft, fs);
9473         opn = "selnez.d";
9474         break;
9475     case OPC_MOVCF_D:
9476         check_insn_opc_removed(ctx, ISA_MIPS32R6);
9477         gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9478         opn = "movcf.d";
9479         break;
9480     case OPC_MOVZ_D:
9481         check_insn_opc_removed(ctx, ISA_MIPS32R6);
9482         {
9483             int l1 = gen_new_label(tcg_ctx);
9484             TCGv_i64 fp0;
9485 
9486             if (ft != 0) {
9487                 tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_NE, *cpu_gpr[ft], 0, l1);
9488             }
9489             fp0 = tcg_temp_new_i64(tcg_ctx);
9490             gen_load_fpr64(ctx, fp0, fs);
9491             gen_store_fpr64(ctx, fp0, fd);
9492             tcg_temp_free_i64(tcg_ctx, fp0);
9493             gen_set_label(tcg_ctx, l1);
9494         }
9495         opn = "movz.d";
9496         break;
9497     case OPC_MOVN_D:
9498         check_insn_opc_removed(ctx, ISA_MIPS32R6);
9499         {
9500             int l1 = gen_new_label(tcg_ctx);
9501             TCGv_i64 fp0;
9502 
9503             if (ft != 0) {
9504                 tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_EQ, *cpu_gpr[ft], 0, l1);
9505                 fp0 = tcg_temp_new_i64(tcg_ctx);
9506                 gen_load_fpr64(ctx, fp0, fs);
9507                 gen_store_fpr64(ctx, fp0, fd);
9508                 tcg_temp_free_i64(tcg_ctx, fp0);
9509                 gen_set_label(tcg_ctx, l1);
9510             }
9511         }
9512         opn = "movn.d";
9513         break;
9514     case OPC_RECIP_D:
9515         check_cp1_64bitmode(ctx);
9516         {
9517             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
9518 
9519             gen_load_fpr64(ctx, fp0, fs);
9520             gen_helper_float_recip_d(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0);
9521             gen_store_fpr64(ctx, fp0, fd);
9522             tcg_temp_free_i64(tcg_ctx, fp0);
9523         }
9524         opn = "recip.d";
9525         break;
9526     case OPC_RSQRT_D:
9527         check_cp1_64bitmode(ctx);
9528         {
9529             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
9530 
9531             gen_load_fpr64(ctx, fp0, fs);
9532             gen_helper_float_rsqrt_d(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0);
9533             gen_store_fpr64(ctx, fp0, fd);
9534             tcg_temp_free_i64(tcg_ctx, fp0);
9535         }
9536         opn = "rsqrt.d";
9537         break;
9538     case OPC_MADDF_D:
9539         check_insn(ctx, ISA_MIPS32R6);
9540         {
9541             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
9542             TCGv_i64 fp1 = tcg_temp_new_i64(tcg_ctx);
9543             TCGv_i64 fp2 = tcg_temp_new_i64(tcg_ctx);
9544             gen_load_fpr64(ctx, fp0, fs);
9545             gen_load_fpr64(ctx, fp1, ft);
9546             gen_load_fpr64(ctx, fp2, fd);
9547             gen_helper_float_maddf_d(tcg_ctx, fp2, tcg_ctx->cpu_env, fp0, fp1, fp2);
9548             gen_store_fpr64(ctx, fp2, fd);
9549             tcg_temp_free_i64(tcg_ctx, fp2);
9550             tcg_temp_free_i64(tcg_ctx, fp1);
9551             tcg_temp_free_i64(tcg_ctx, fp0);
9552             opn = "maddf.d";
9553         }
9554         break;
9555     case OPC_MSUBF_D:
9556         check_insn(ctx, ISA_MIPS32R6);
9557         {
9558             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
9559             TCGv_i64 fp1 = tcg_temp_new_i64(tcg_ctx);
9560             TCGv_i64 fp2 = tcg_temp_new_i64(tcg_ctx);
9561             gen_load_fpr64(ctx, fp0, fs);
9562             gen_load_fpr64(ctx, fp1, ft);
9563             gen_load_fpr64(ctx, fp2, fd);
9564             gen_helper_float_msubf_d(tcg_ctx, fp2, tcg_ctx->cpu_env, fp0, fp1, fp2);
9565             gen_store_fpr64(ctx, fp2, fd);
9566             tcg_temp_free_i64(tcg_ctx, fp2);
9567             tcg_temp_free_i64(tcg_ctx, fp1);
9568             tcg_temp_free_i64(tcg_ctx, fp0);
9569             opn = "msubf.d";
9570         }
9571         break;
9572     case OPC_RINT_D:
9573         check_insn(ctx, ISA_MIPS32R6);
9574         {
9575             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
9576             gen_load_fpr64(ctx, fp0, fs);
9577             gen_helper_float_rint_d(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0);
9578             gen_store_fpr64(ctx, fp0, fd);
9579             tcg_temp_free_i64(tcg_ctx, fp0);
9580             opn = "rint.d";
9581         }
9582         break;
9583     case OPC_CLASS_D:
9584         check_insn(ctx, ISA_MIPS32R6);
9585         {
9586             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
9587             gen_load_fpr64(ctx, fp0, fs);
9588             gen_helper_float_class_d(tcg_ctx, fp0, fp0);
9589             gen_store_fpr64(ctx, fp0, fd);
9590             tcg_temp_free_i64(tcg_ctx, fp0);
9591             opn = "class.d";
9592         }
9593         break;
9594     case OPC_MIN_D: /* OPC_RECIP2_D */
9595         if (ctx->insn_flags & ISA_MIPS32R6) {
9596             /* OPC_MIN_D */
9597             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
9598             TCGv_i64 fp1 = tcg_temp_new_i64(tcg_ctx);
9599             gen_load_fpr64(ctx, fp0, fs);
9600             gen_load_fpr64(ctx, fp1, ft);
9601             gen_helper_float_min_d(tcg_ctx, fp1, tcg_ctx->cpu_env, fp0, fp1);
9602             gen_store_fpr64(ctx, fp1, fd);
9603             tcg_temp_free_i64(tcg_ctx, fp1);
9604             tcg_temp_free_i64(tcg_ctx, fp0);
9605             opn = "min.d";
9606         } else {
9607             /* OPC_RECIP2_D */
9608             check_cp1_64bitmode(ctx);
9609             {
9610                 TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
9611                 TCGv_i64 fp1 = tcg_temp_new_i64(tcg_ctx);
9612 
9613                 gen_load_fpr64(ctx, fp0, fs);
9614                 gen_load_fpr64(ctx, fp1, ft);
9615                 gen_helper_float_recip2_d(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);
9616                 tcg_temp_free_i64(tcg_ctx, fp1);
9617                 gen_store_fpr64(ctx, fp0, fd);
9618                 tcg_temp_free_i64(tcg_ctx, fp0);
9619             }
9620             opn = "recip2.d";
9621         }
9622         break;
9623     case OPC_MINA_D: /* OPC_RECIP1_D */
9624         if (ctx->insn_flags & ISA_MIPS32R6) {
9625             /* OPC_MINA_D */
9626             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
9627             TCGv_i64 fp1 = tcg_temp_new_i64(tcg_ctx);
9628             gen_load_fpr64(ctx, fp0, fs);
9629             gen_load_fpr64(ctx, fp1, ft);
9630             gen_helper_float_mina_d(tcg_ctx, fp1, tcg_ctx->cpu_env, fp0, fp1);
9631             gen_store_fpr64(ctx, fp1, fd);
9632             tcg_temp_free_i64(tcg_ctx, fp1);
9633             tcg_temp_free_i64(tcg_ctx, fp0);
9634             opn = "mina.d";
9635         } else {
9636             /* OPC_RECIP1_D */
9637             check_cp1_64bitmode(ctx);
9638             {
9639                 TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
9640 
9641                 gen_load_fpr64(ctx, fp0, fs);
9642                 gen_helper_float_recip1_d(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0);
9643                 gen_store_fpr64(ctx, fp0, fd);
9644                 tcg_temp_free_i64(tcg_ctx, fp0);
9645             }
9646             opn = "recip1.d";
9647         }
9648         break;
9649     case OPC_MAX_D: /*  OPC_RSQRT1_D */
9650         if (ctx->insn_flags & ISA_MIPS32R6) {
9651             /* OPC_MAX_D */
9652             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
9653             TCGv_i64 fp1 = tcg_temp_new_i64(tcg_ctx);
9654             gen_load_fpr64(ctx, fp0, fs);
9655             gen_load_fpr64(ctx, fp1, ft);
9656             gen_helper_float_max_d(tcg_ctx, fp1, tcg_ctx->cpu_env, fp0, fp1);
9657             gen_store_fpr64(ctx, fp1, fd);
9658             tcg_temp_free_i64(tcg_ctx, fp1);
9659             tcg_temp_free_i64(tcg_ctx, fp0);
9660             opn = "max.d";
9661         } else {
9662             /* OPC_RSQRT1_D */
9663             check_cp1_64bitmode(ctx);
9664             {
9665                 TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
9666 
9667                 gen_load_fpr64(ctx, fp0, fs);
9668                 gen_helper_float_rsqrt1_d(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0);
9669                 gen_store_fpr64(ctx, fp0, fd);
9670                 tcg_temp_free_i64(tcg_ctx, fp0);
9671             }
9672             opn = "rsqrt1.d";
9673         }
9674         break;
9675     case OPC_MAXA_D: /* OPC_RSQRT2_D */
9676         if (ctx->insn_flags & ISA_MIPS32R6) {
9677             /* OPC_MAXA_D */
9678             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
9679             TCGv_i64 fp1 = tcg_temp_new_i64(tcg_ctx);
9680             gen_load_fpr64(ctx, fp0, fs);
9681             gen_load_fpr64(ctx, fp1, ft);
9682             gen_helper_float_maxa_d(tcg_ctx, fp1, tcg_ctx->cpu_env, fp0, fp1);
9683             gen_store_fpr64(ctx, fp1, fd);
9684             tcg_temp_free_i64(tcg_ctx, fp1);
9685             tcg_temp_free_i64(tcg_ctx, fp0);
9686             opn = "maxa.d";
9687         } else {
9688             /* OPC_RSQRT2_D */
9689             check_cp1_64bitmode(ctx);
9690             {
9691                 TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
9692                 TCGv_i64 fp1 = tcg_temp_new_i64(tcg_ctx);
9693 
9694                 gen_load_fpr64(ctx, fp0, fs);
9695                 gen_load_fpr64(ctx, fp1, ft);
9696                 gen_helper_float_rsqrt2_d(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);
9697                 tcg_temp_free_i64(tcg_ctx, fp1);
9698                 gen_store_fpr64(ctx, fp0, fd);
9699                 tcg_temp_free_i64(tcg_ctx, fp0);
9700             }
9701             opn = "rsqrt2.d";
9702         }
9703         break;
9704     case OPC_CMP_F_D:
9705     case OPC_CMP_UN_D:
9706     case OPC_CMP_EQ_D:
9707     case OPC_CMP_UEQ_D:
9708     case OPC_CMP_OLT_D:
9709     case OPC_CMP_ULT_D:
9710     case OPC_CMP_OLE_D:
9711     case OPC_CMP_ULE_D:
9712     case OPC_CMP_SF_D:
9713     case OPC_CMP_NGLE_D:
9714     case OPC_CMP_SEQ_D:
9715     case OPC_CMP_NGL_D:
9716     case OPC_CMP_LT_D:
9717     case OPC_CMP_NGE_D:
9718     case OPC_CMP_LE_D:
9719     case OPC_CMP_NGT_D:
9720         check_insn_opc_removed(ctx, ISA_MIPS32R6);
9721         if (ctx->opcode & (1 << 6)) {
9722             gen_cmpabs_d(ctx, func-48, ft, fs, cc);
9723             opn = condnames_abs[func-48];
9724         } else {
9725             gen_cmp_d(ctx, func-48, ft, fs, cc);
9726             opn = condnames[func-48];
9727         }
9728         break;
9729     case OPC_CVT_S_D:
9730         check_cp1_registers(ctx, fs);
9731         {
9732             TCGv_i32 fp32 = tcg_temp_new_i32(tcg_ctx);
9733             TCGv_i64 fp64 = tcg_temp_new_i64(tcg_ctx);
9734 
9735             gen_load_fpr64(ctx, fp64, fs);
9736             gen_helper_float_cvts_d(tcg_ctx, fp32, tcg_ctx->cpu_env, fp64);
9737             tcg_temp_free_i64(tcg_ctx, fp64);
9738             gen_store_fpr32(ctx, fp32, fd);
9739             tcg_temp_free_i32(tcg_ctx, fp32);
9740         }
9741         opn = "cvt.s.d";
9742         break;
9743     case OPC_CVT_W_D:
9744         check_cp1_registers(ctx, fs);
9745         {
9746             TCGv_i32 fp32 = tcg_temp_new_i32(tcg_ctx);
9747             TCGv_i64 fp64 = tcg_temp_new_i64(tcg_ctx);
9748 
9749             gen_load_fpr64(ctx, fp64, fs);
9750             gen_helper_float_cvtw_d(tcg_ctx, fp32, tcg_ctx->cpu_env, fp64);
9751             tcg_temp_free_i64(tcg_ctx, fp64);
9752             gen_store_fpr32(ctx, fp32, fd);
9753             tcg_temp_free_i32(tcg_ctx, fp32);
9754         }
9755         opn = "cvt.w.d";
9756         break;
9757     case OPC_CVT_L_D:
9758         check_cp1_64bitmode(ctx);
9759         {
9760             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
9761 
9762             gen_load_fpr64(ctx, fp0, fs);
9763             gen_helper_float_cvtl_d(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0);
9764             gen_store_fpr64(ctx, fp0, fd);
9765             tcg_temp_free_i64(tcg_ctx, fp0);
9766         }
9767         opn = "cvt.l.d";
9768         break;
9769     case OPC_CVT_S_W:
9770         {
9771             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
9772 
9773             gen_load_fpr32(ctx, fp0, fs);
9774             gen_helper_float_cvts_w(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0);
9775             gen_store_fpr32(ctx, fp0, fd);
9776             tcg_temp_free_i32(tcg_ctx, fp0);
9777         }
9778         opn = "cvt.s.w";
9779         break;
9780     case OPC_CVT_D_W:
9781         check_cp1_registers(ctx, fd);
9782         {
9783             TCGv_i32 fp32 = tcg_temp_new_i32(tcg_ctx);
9784             TCGv_i64 fp64 = tcg_temp_new_i64(tcg_ctx);
9785 
9786             gen_load_fpr32(ctx, fp32, fs);
9787             gen_helper_float_cvtd_w(tcg_ctx, fp64, tcg_ctx->cpu_env, fp32);
9788             tcg_temp_free_i32(tcg_ctx, fp32);
9789             gen_store_fpr64(ctx, fp64, fd);
9790             tcg_temp_free_i64(tcg_ctx, fp64);
9791         }
9792         opn = "cvt.d.w";
9793         break;
9794     case OPC_CVT_S_L:
9795         check_cp1_64bitmode(ctx);
9796         {
9797             TCGv_i32 fp32 = tcg_temp_new_i32(tcg_ctx);
9798             TCGv_i64 fp64 = tcg_temp_new_i64(tcg_ctx);
9799 
9800             gen_load_fpr64(ctx, fp64, fs);
9801             gen_helper_float_cvts_l(tcg_ctx, fp32, tcg_ctx->cpu_env, fp64);
9802             tcg_temp_free_i64(tcg_ctx, fp64);
9803             gen_store_fpr32(ctx, fp32, fd);
9804             tcg_temp_free_i32(tcg_ctx, fp32);
9805         }
9806         opn = "cvt.s.l";
9807         break;
9808     case OPC_CVT_D_L:
9809         check_cp1_64bitmode(ctx);
9810         {
9811             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
9812 
9813             gen_load_fpr64(ctx, fp0, fs);
9814             gen_helper_float_cvtd_l(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0);
9815             gen_store_fpr64(ctx, fp0, fd);
9816             tcg_temp_free_i64(tcg_ctx, fp0);
9817         }
9818         opn = "cvt.d.l";
9819         break;
9820     case OPC_CVT_PS_PW:
9821         check_insn_opc_removed(ctx, ISA_MIPS32R6);
9822         check_cp1_64bitmode(ctx);
9823         {
9824             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
9825 
9826             gen_load_fpr64(ctx, fp0, fs);
9827             gen_helper_float_cvtps_pw(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0);
9828             gen_store_fpr64(ctx, fp0, fd);
9829             tcg_temp_free_i64(tcg_ctx, fp0);
9830         }
9831         opn = "cvt.ps.pw";
9832         break;
9833     case OPC_ADD_PS:
9834         check_cp1_64bitmode(ctx);
9835         {
9836             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
9837             TCGv_i64 fp1 = tcg_temp_new_i64(tcg_ctx);
9838 
9839             gen_load_fpr64(ctx, fp0, fs);
9840             gen_load_fpr64(ctx, fp1, ft);
9841             gen_helper_float_add_ps(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);
9842             tcg_temp_free_i64(tcg_ctx, fp1);
9843             gen_store_fpr64(ctx, fp0, fd);
9844             tcg_temp_free_i64(tcg_ctx, fp0);
9845         }
9846         opn = "add.ps";
9847         break;
9848     case OPC_SUB_PS:
9849         check_cp1_64bitmode(ctx);
9850         {
9851             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
9852             TCGv_i64 fp1 = tcg_temp_new_i64(tcg_ctx);
9853 
9854             gen_load_fpr64(ctx, fp0, fs);
9855             gen_load_fpr64(ctx, fp1, ft);
9856             gen_helper_float_sub_ps(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);
9857             tcg_temp_free_i64(tcg_ctx, fp1);
9858             gen_store_fpr64(ctx, fp0, fd);
9859             tcg_temp_free_i64(tcg_ctx, fp0);
9860         }
9861         opn = "sub.ps";
9862         break;
9863     case OPC_MUL_PS:
9864         check_cp1_64bitmode(ctx);
9865         {
9866             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
9867             TCGv_i64 fp1 = tcg_temp_new_i64(tcg_ctx);
9868 
9869             gen_load_fpr64(ctx, fp0, fs);
9870             gen_load_fpr64(ctx, fp1, ft);
9871             gen_helper_float_mul_ps(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);
9872             tcg_temp_free_i64(tcg_ctx, fp1);
9873             gen_store_fpr64(ctx, fp0, fd);
9874             tcg_temp_free_i64(tcg_ctx, fp0);
9875         }
9876         opn = "mul.ps";
9877         break;
9878     case OPC_ABS_PS:
9879         check_cp1_64bitmode(ctx);
9880         {
9881             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
9882 
9883             gen_load_fpr64(ctx, fp0, fs);
9884             gen_helper_float_abs_ps(tcg_ctx, fp0, fp0);
9885             gen_store_fpr64(ctx, fp0, fd);
9886             tcg_temp_free_i64(tcg_ctx, fp0);
9887         }
9888         opn = "abs.ps";
9889         break;
9890     case OPC_MOV_PS:
9891         check_cp1_64bitmode(ctx);
9892         {
9893             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
9894 
9895             gen_load_fpr64(ctx, fp0, fs);
9896             gen_store_fpr64(ctx, fp0, fd);
9897             tcg_temp_free_i64(tcg_ctx, fp0);
9898         }
9899         opn = "mov.ps";
9900         break;
9901     case OPC_NEG_PS:
9902         check_cp1_64bitmode(ctx);
9903         {
9904             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
9905 
9906             gen_load_fpr64(ctx, fp0, fs);
9907             gen_helper_float_chs_ps(tcg_ctx, fp0, fp0);
9908             gen_store_fpr64(ctx, fp0, fd);
9909             tcg_temp_free_i64(tcg_ctx, fp0);
9910         }
9911         opn = "neg.ps";
9912         break;
9913     case OPC_MOVCF_PS:
9914         check_cp1_64bitmode(ctx);
9915         gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9916         opn = "movcf.ps";
9917         break;
9918     case OPC_MOVZ_PS:
9919         check_cp1_64bitmode(ctx);
9920         {
9921             int l1 = gen_new_label(tcg_ctx);
9922             TCGv_i64 fp0;
9923 
9924             if (ft != 0)
9925                 tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_NE, *cpu_gpr[ft], 0, l1);
9926             fp0 = tcg_temp_new_i64(tcg_ctx);
9927             gen_load_fpr64(ctx, fp0, fs);
9928             gen_store_fpr64(ctx, fp0, fd);
9929             tcg_temp_free_i64(tcg_ctx, fp0);
9930             gen_set_label(tcg_ctx, l1);
9931         }
9932         opn = "movz.ps";
9933         break;
9934     case OPC_MOVN_PS:
9935         check_cp1_64bitmode(ctx);
9936         {
9937             int l1 = gen_new_label(tcg_ctx);
9938             TCGv_i64 fp0;
9939 
9940             if (ft != 0) {
9941                 tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_EQ, *cpu_gpr[ft], 0, l1);
9942                 fp0 = tcg_temp_new_i64(tcg_ctx);
9943                 gen_load_fpr64(ctx, fp0, fs);
9944                 gen_store_fpr64(ctx, fp0, fd);
9945                 tcg_temp_free_i64(tcg_ctx, fp0);
9946                 gen_set_label(tcg_ctx, l1);
9947             }
9948         }
9949         opn = "movn.ps";
9950         break;
9951     case OPC_ADDR_PS:
9952         check_cp1_64bitmode(ctx);
9953         {
9954             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
9955             TCGv_i64 fp1 = tcg_temp_new_i64(tcg_ctx);
9956 
9957             gen_load_fpr64(ctx, fp0, ft);
9958             gen_load_fpr64(ctx, fp1, fs);
9959             gen_helper_float_addr_ps(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);
9960             tcg_temp_free_i64(tcg_ctx, fp1);
9961             gen_store_fpr64(ctx, fp0, fd);
9962             tcg_temp_free_i64(tcg_ctx, fp0);
9963         }
9964         opn = "addr.ps";
9965         break;
9966     case OPC_MULR_PS:
9967         check_cp1_64bitmode(ctx);
9968         {
9969             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
9970             TCGv_i64 fp1 = tcg_temp_new_i64(tcg_ctx);
9971 
9972             gen_load_fpr64(ctx, fp0, ft);
9973             gen_load_fpr64(ctx, fp1, fs);
9974             gen_helper_float_mulr_ps(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);
9975             tcg_temp_free_i64(tcg_ctx, fp1);
9976             gen_store_fpr64(ctx, fp0, fd);
9977             tcg_temp_free_i64(tcg_ctx, fp0);
9978         }
9979         opn = "mulr.ps";
9980         break;
9981     case OPC_RECIP2_PS:
9982         check_cp1_64bitmode(ctx);
9983         {
9984             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
9985             TCGv_i64 fp1 = tcg_temp_new_i64(tcg_ctx);
9986 
9987             gen_load_fpr64(ctx, fp0, fs);
9988             gen_load_fpr64(ctx, fp1, ft);
9989             gen_helper_float_recip2_ps(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);
9990             tcg_temp_free_i64(tcg_ctx, fp1);
9991             gen_store_fpr64(ctx, fp0, fd);
9992             tcg_temp_free_i64(tcg_ctx, fp0);
9993         }
9994         opn = "recip2.ps";
9995         break;
9996     case OPC_RECIP1_PS:
9997         check_cp1_64bitmode(ctx);
9998         {
9999             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
10000 
10001             gen_load_fpr64(ctx, fp0, fs);
10002             gen_helper_float_recip1_ps(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0);
10003             gen_store_fpr64(ctx, fp0, fd);
10004             tcg_temp_free_i64(tcg_ctx, fp0);
10005         }
10006         opn = "recip1.ps";
10007         break;
10008     case OPC_RSQRT1_PS:
10009         check_cp1_64bitmode(ctx);
10010         {
10011             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
10012 
10013             gen_load_fpr64(ctx, fp0, fs);
10014             gen_helper_float_rsqrt1_ps(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0);
10015             gen_store_fpr64(ctx, fp0, fd);
10016             tcg_temp_free_i64(tcg_ctx, fp0);
10017         }
10018         opn = "rsqrt1.ps";
10019         break;
10020     case OPC_RSQRT2_PS:
10021         check_cp1_64bitmode(ctx);
10022         {
10023             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
10024             TCGv_i64 fp1 = tcg_temp_new_i64(tcg_ctx);
10025 
10026             gen_load_fpr64(ctx, fp0, fs);
10027             gen_load_fpr64(ctx, fp1, ft);
10028             gen_helper_float_rsqrt2_ps(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0, fp1);
10029             tcg_temp_free_i64(tcg_ctx, fp1);
10030             gen_store_fpr64(ctx, fp0, fd);
10031             tcg_temp_free_i64(tcg_ctx, fp0);
10032         }
10033         opn = "rsqrt2.ps";
10034         break;
10035     case OPC_CVT_S_PU:
10036         check_cp1_64bitmode(ctx);
10037         {
10038             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
10039 
10040             gen_load_fpr32h(ctx, fp0, fs);
10041             gen_helper_float_cvts_pu(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0);
10042             gen_store_fpr32(ctx, fp0, fd);
10043             tcg_temp_free_i32(tcg_ctx, fp0);
10044         }
10045         opn = "cvt.s.pu";
10046         break;
10047     case OPC_CVT_PW_PS:
10048         check_cp1_64bitmode(ctx);
10049         {
10050             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
10051 
10052             gen_load_fpr64(ctx, fp0, fs);
10053             gen_helper_float_cvtpw_ps(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0);
10054             gen_store_fpr64(ctx, fp0, fd);
10055             tcg_temp_free_i64(tcg_ctx, fp0);
10056         }
10057         opn = "cvt.pw.ps";
10058         break;
10059     case OPC_CVT_S_PL:
10060         check_cp1_64bitmode(ctx);
10061         {
10062             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
10063 
10064             gen_load_fpr32(ctx, fp0, fs);
10065             gen_helper_float_cvts_pl(tcg_ctx, fp0, tcg_ctx->cpu_env, fp0);
10066             gen_store_fpr32(ctx, fp0, fd);
10067             tcg_temp_free_i32(tcg_ctx, fp0);
10068         }
10069         opn = "cvt.s.pl";
10070         break;
10071     case OPC_PLL_PS:
10072         check_cp1_64bitmode(ctx);
10073         {
10074             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
10075             TCGv_i32 fp1 = tcg_temp_new_i32(tcg_ctx);
10076 
10077             gen_load_fpr32(ctx, fp0, fs);
10078             gen_load_fpr32(ctx, fp1, ft);
10079             gen_store_fpr32h(ctx, fp0, fd);
10080             gen_store_fpr32(ctx, fp1, fd);
10081             tcg_temp_free_i32(tcg_ctx, fp0);
10082             tcg_temp_free_i32(tcg_ctx, fp1);
10083         }
10084         opn = "pll.ps";
10085         break;
10086     case OPC_PLU_PS:
10087         check_cp1_64bitmode(ctx);
10088         {
10089             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
10090             TCGv_i32 fp1 = tcg_temp_new_i32(tcg_ctx);
10091 
10092             gen_load_fpr32(ctx, fp0, fs);
10093             gen_load_fpr32h(ctx, fp1, ft);
10094             gen_store_fpr32(ctx, fp1, fd);
10095             gen_store_fpr32h(ctx, fp0, fd);
10096             tcg_temp_free_i32(tcg_ctx, fp0);
10097             tcg_temp_free_i32(tcg_ctx, fp1);
10098         }
10099         opn = "plu.ps";
10100         break;
10101     case OPC_PUL_PS:
10102         check_cp1_64bitmode(ctx);
10103         {
10104             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
10105             TCGv_i32 fp1 = tcg_temp_new_i32(tcg_ctx);
10106 
10107             gen_load_fpr32h(ctx, fp0, fs);
10108             gen_load_fpr32(ctx, fp1, ft);
10109             gen_store_fpr32(ctx, fp1, fd);
10110             gen_store_fpr32h(ctx, fp0, fd);
10111             tcg_temp_free_i32(tcg_ctx, fp0);
10112             tcg_temp_free_i32(tcg_ctx, fp1);
10113         }
10114         opn = "pul.ps";
10115         break;
10116     case OPC_PUU_PS:
10117         check_cp1_64bitmode(ctx);
10118         {
10119             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
10120             TCGv_i32 fp1 = tcg_temp_new_i32(tcg_ctx);
10121 
10122             gen_load_fpr32h(ctx, fp0, fs);
10123             gen_load_fpr32h(ctx, fp1, ft);
10124             gen_store_fpr32(ctx, fp1, fd);
10125             gen_store_fpr32h(ctx, fp0, fd);
10126             tcg_temp_free_i32(tcg_ctx, fp0);
10127             tcg_temp_free_i32(tcg_ctx, fp1);
10128         }
10129         opn = "puu.ps";
10130         break;
10131     case OPC_CMP_F_PS:
10132     case OPC_CMP_UN_PS:
10133     case OPC_CMP_EQ_PS:
10134     case OPC_CMP_UEQ_PS:
10135     case OPC_CMP_OLT_PS:
10136     case OPC_CMP_ULT_PS:
10137     case OPC_CMP_OLE_PS:
10138     case OPC_CMP_ULE_PS:
10139     case OPC_CMP_SF_PS:
10140     case OPC_CMP_NGLE_PS:
10141     case OPC_CMP_SEQ_PS:
10142     case OPC_CMP_NGL_PS:
10143     case OPC_CMP_LT_PS:
10144     case OPC_CMP_NGE_PS:
10145     case OPC_CMP_LE_PS:
10146     case OPC_CMP_NGT_PS:
10147         if (ctx->opcode & (1 << 6)) {
10148             gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
10149             opn = condnames_abs[func-48];
10150         } else {
10151             gen_cmp_ps(ctx, func-48, ft, fs, cc);
10152             opn = condnames[func-48];
10153         }
10154         break;
10155     default:
10156         MIPS_INVAL(opn);
10157         generate_exception (ctx, EXCP_RI);
10158         return;
10159     }
10160     (void)opn; /* avoid a compiler warning */
10161     switch (optype) {
10162     case BINOP:
10163         MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
10164         break;
10165     case CMPOP:
10166         MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
10167         break;
10168     default:
10169         MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
10170         break;
10171     }
10172 }
10173 
10174 /* Coprocessor 3 (FPU) */
gen_flt3_ldst(DisasContext * ctx,uint32_t opc,int fd,int fs,int base,int index)10175 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
10176                            int fd, int fs, int base, int index)
10177 {
10178     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
10179     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
10180     const char *opn = "extended float load/store";
10181     int store = 0;
10182     TCGv t0 = tcg_temp_new(tcg_ctx);
10183 
10184     if (base == 0) {
10185         gen_load_gpr(ctx, t0, index);
10186     } else if (index == 0) {
10187         gen_load_gpr(ctx, t0, base);
10188     } else {
10189         gen_op_addr_add(ctx, t0, *cpu_gpr[base], *cpu_gpr[index]);
10190     }
10191     /* Don't do NOP if destination is zero: we must perform the actual
10192        memory access. */
10193     switch (opc) {
10194     case OPC_LWXC1:
10195         check_cop1x(ctx);
10196         {
10197             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
10198 
10199             tcg_gen_qemu_ld_tl(ctx->uc, t0, t0, ctx->mem_idx, MO_TESL);
10200             tcg_gen_trunc_tl_i32(tcg_ctx, fp0, t0);
10201             gen_store_fpr32(ctx, fp0, fd);
10202             tcg_temp_free_i32(tcg_ctx, fp0);
10203         }
10204         opn = "lwxc1";
10205         break;
10206     case OPC_LDXC1:
10207         check_cop1x(ctx);
10208         check_cp1_registers(ctx, fd);
10209         {
10210             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
10211             tcg_gen_qemu_ld_i64(ctx->uc, fp0, t0, ctx->mem_idx, MO_TEQ);
10212             gen_store_fpr64(ctx, fp0, fd);
10213             tcg_temp_free_i64(tcg_ctx, fp0);
10214         }
10215         opn = "ldxc1";
10216         break;
10217     case OPC_LUXC1:
10218         check_cp1_64bitmode(ctx);
10219         tcg_gen_andi_tl(tcg_ctx, t0, t0, ~0x7);
10220         {
10221             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
10222 
10223             tcg_gen_qemu_ld_i64(ctx->uc, fp0, t0, ctx->mem_idx, MO_TEQ);
10224             gen_store_fpr64(ctx, fp0, fd);
10225             tcg_temp_free_i64(tcg_ctx, fp0);
10226         }
10227         opn = "luxc1";
10228         break;
10229     case OPC_SWXC1:
10230         check_cop1x(ctx);
10231         {
10232             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
10233             gen_load_fpr32(ctx, fp0, fs);
10234             tcg_gen_qemu_st_i32(ctx->uc, fp0, t0, ctx->mem_idx, MO_TEUL);
10235             tcg_temp_free_i32(tcg_ctx, fp0);
10236         }
10237         opn = "swxc1";
10238         store = 1;
10239         break;
10240     case OPC_SDXC1:
10241         check_cop1x(ctx);
10242         check_cp1_registers(ctx, fs);
10243         {
10244             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
10245             gen_load_fpr64(ctx, fp0, fs);
10246             tcg_gen_qemu_st_i64(ctx->uc, fp0, t0, ctx->mem_idx, MO_TEQ);
10247             tcg_temp_free_i64(tcg_ctx, fp0);
10248         }
10249         opn = "sdxc1";
10250         store = 1;
10251         break;
10252     case OPC_SUXC1:
10253         check_cp1_64bitmode(ctx);
10254         tcg_gen_andi_tl(tcg_ctx, t0, t0, ~0x7);
10255         {
10256             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
10257             gen_load_fpr64(ctx, fp0, fs);
10258             tcg_gen_qemu_st_i64(ctx->uc, fp0, t0, ctx->mem_idx, MO_TEQ);
10259             tcg_temp_free_i64(tcg_ctx, fp0);
10260         }
10261         opn = "suxc1";
10262         store = 1;
10263         break;
10264     }
10265     tcg_temp_free(tcg_ctx, t0);
10266     (void)opn; (void)store; /* avoid compiler warnings */
10267     MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
10268                regnames[index], regnames[base]);
10269 }
10270 
gen_flt3_arith(DisasContext * ctx,uint32_t opc,int fd,int fr,int fs,int ft)10271 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
10272                             int fd, int fr, int fs, int ft)
10273 {
10274     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
10275     const char *opn = "flt3_arith";
10276 
10277     switch (opc) {
10278     case OPC_ALNV_PS:
10279         check_cp1_64bitmode(ctx);
10280         {
10281             TCGv t0 = tcg_temp_local_new(tcg_ctx);
10282             TCGv_i32 fp = tcg_temp_new_i32(tcg_ctx);
10283             TCGv_i32 fph = tcg_temp_new_i32(tcg_ctx);
10284             int l1 = gen_new_label(tcg_ctx);
10285             int l2 = gen_new_label(tcg_ctx);
10286 
10287             gen_load_gpr(ctx, t0, fr);
10288             tcg_gen_andi_tl(tcg_ctx, t0, t0, 0x7);
10289 
10290             tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_NE, t0, 0, l1);
10291             gen_load_fpr32(ctx, fp, fs);
10292             gen_load_fpr32h(ctx, fph, fs);
10293             gen_store_fpr32(ctx, fp, fd);
10294             gen_store_fpr32h(ctx, fph, fd);
10295             tcg_gen_br(tcg_ctx, l2);
10296             gen_set_label(tcg_ctx, l1);
10297             tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_NE, t0, 4, l2);
10298             tcg_temp_free(tcg_ctx, t0);
10299 #ifdef TARGET_WORDS_BIGENDIAN
10300             gen_load_fpr32(ctx, fp, fs);
10301             gen_load_fpr32h(ctx, fph, ft);
10302             gen_store_fpr32h(ctx, fp, fd);
10303             gen_store_fpr32(ctx, fph, fd);
10304 #else
10305             gen_load_fpr32h(ctx, fph, fs);
10306             gen_load_fpr32(ctx, fp, ft);
10307             gen_store_fpr32(ctx, fph, fd);
10308             gen_store_fpr32h(ctx, fp, fd);
10309 #endif
10310             gen_set_label(tcg_ctx, l2);
10311             tcg_temp_free_i32(tcg_ctx, fp);
10312             tcg_temp_free_i32(tcg_ctx, fph);
10313         }
10314         opn = "alnv.ps";
10315         break;
10316     case OPC_MADD_S:
10317         check_cop1x(ctx);
10318         {
10319             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
10320             TCGv_i32 fp1 = tcg_temp_new_i32(tcg_ctx);
10321             TCGv_i32 fp2 = tcg_temp_new_i32(tcg_ctx);
10322 
10323             gen_load_fpr32(ctx, fp0, fs);
10324             gen_load_fpr32(ctx, fp1, ft);
10325             gen_load_fpr32(ctx, fp2, fr);
10326             gen_helper_float_madd_s(tcg_ctx, fp2, tcg_ctx->cpu_env, fp0, fp1, fp2);
10327             tcg_temp_free_i32(tcg_ctx, fp0);
10328             tcg_temp_free_i32(tcg_ctx, fp1);
10329             gen_store_fpr32(ctx, fp2, fd);
10330             tcg_temp_free_i32(tcg_ctx, fp2);
10331         }
10332         opn = "madd.s";
10333         break;
10334     case OPC_MADD_D:
10335         check_cop1x(ctx);
10336         check_cp1_registers(ctx, fd | fs | ft | fr);
10337         {
10338             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
10339             TCGv_i64 fp1 = tcg_temp_new_i64(tcg_ctx);
10340             TCGv_i64 fp2 = tcg_temp_new_i64(tcg_ctx);
10341 
10342             gen_load_fpr64(ctx, fp0, fs);
10343             gen_load_fpr64(ctx, fp1, ft);
10344             gen_load_fpr64(ctx, fp2, fr);
10345             gen_helper_float_madd_d(tcg_ctx, fp2, tcg_ctx->cpu_env, fp0, fp1, fp2);
10346             tcg_temp_free_i64(tcg_ctx, fp0);
10347             tcg_temp_free_i64(tcg_ctx, fp1);
10348             gen_store_fpr64(ctx, fp2, fd);
10349             tcg_temp_free_i64(tcg_ctx, fp2);
10350         }
10351         opn = "madd.d";
10352         break;
10353     case OPC_MADD_PS:
10354         check_cp1_64bitmode(ctx);
10355         {
10356             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
10357             TCGv_i64 fp1 = tcg_temp_new_i64(tcg_ctx);
10358             TCGv_i64 fp2 = tcg_temp_new_i64(tcg_ctx);
10359 
10360             gen_load_fpr64(ctx, fp0, fs);
10361             gen_load_fpr64(ctx, fp1, ft);
10362             gen_load_fpr64(ctx, fp2, fr);
10363             gen_helper_float_madd_ps(tcg_ctx, fp2, tcg_ctx->cpu_env, fp0, fp1, fp2);
10364             tcg_temp_free_i64(tcg_ctx, fp0);
10365             tcg_temp_free_i64(tcg_ctx, fp1);
10366             gen_store_fpr64(ctx, fp2, fd);
10367             tcg_temp_free_i64(tcg_ctx, fp2);
10368         }
10369         opn = "madd.ps";
10370         break;
10371     case OPC_MSUB_S:
10372         check_cop1x(ctx);
10373         {
10374             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
10375             TCGv_i32 fp1 = tcg_temp_new_i32(tcg_ctx);
10376             TCGv_i32 fp2 = tcg_temp_new_i32(tcg_ctx);
10377 
10378             gen_load_fpr32(ctx, fp0, fs);
10379             gen_load_fpr32(ctx, fp1, ft);
10380             gen_load_fpr32(ctx, fp2, fr);
10381             gen_helper_float_msub_s(tcg_ctx, fp2, tcg_ctx->cpu_env, fp0, fp1, fp2);
10382             tcg_temp_free_i32(tcg_ctx, fp0);
10383             tcg_temp_free_i32(tcg_ctx, fp1);
10384             gen_store_fpr32(ctx, fp2, fd);
10385             tcg_temp_free_i32(tcg_ctx, fp2);
10386         }
10387         opn = "msub.s";
10388         break;
10389     case OPC_MSUB_D:
10390         check_cop1x(ctx);
10391         check_cp1_registers(ctx, fd | fs | ft | fr);
10392         {
10393             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
10394             TCGv_i64 fp1 = tcg_temp_new_i64(tcg_ctx);
10395             TCGv_i64 fp2 = tcg_temp_new_i64(tcg_ctx);
10396 
10397             gen_load_fpr64(ctx, fp0, fs);
10398             gen_load_fpr64(ctx, fp1, ft);
10399             gen_load_fpr64(ctx, fp2, fr);
10400             gen_helper_float_msub_d(tcg_ctx, fp2, tcg_ctx->cpu_env, fp0, fp1, fp2);
10401             tcg_temp_free_i64(tcg_ctx, fp0);
10402             tcg_temp_free_i64(tcg_ctx, fp1);
10403             gen_store_fpr64(ctx, fp2, fd);
10404             tcg_temp_free_i64(tcg_ctx, fp2);
10405         }
10406         opn = "msub.d";
10407         break;
10408     case OPC_MSUB_PS:
10409         check_cp1_64bitmode(ctx);
10410         {
10411             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
10412             TCGv_i64 fp1 = tcg_temp_new_i64(tcg_ctx);
10413             TCGv_i64 fp2 = tcg_temp_new_i64(tcg_ctx);
10414 
10415             gen_load_fpr64(ctx, fp0, fs);
10416             gen_load_fpr64(ctx, fp1, ft);
10417             gen_load_fpr64(ctx, fp2, fr);
10418             gen_helper_float_msub_ps(tcg_ctx, fp2, tcg_ctx->cpu_env, fp0, fp1, fp2);
10419             tcg_temp_free_i64(tcg_ctx, fp0);
10420             tcg_temp_free_i64(tcg_ctx, fp1);
10421             gen_store_fpr64(ctx, fp2, fd);
10422             tcg_temp_free_i64(tcg_ctx, fp2);
10423         }
10424         opn = "msub.ps";
10425         break;
10426     case OPC_NMADD_S:
10427         check_cop1x(ctx);
10428         {
10429             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
10430             TCGv_i32 fp1 = tcg_temp_new_i32(tcg_ctx);
10431             TCGv_i32 fp2 = tcg_temp_new_i32(tcg_ctx);
10432 
10433             gen_load_fpr32(ctx, fp0, fs);
10434             gen_load_fpr32(ctx, fp1, ft);
10435             gen_load_fpr32(ctx, fp2, fr);
10436             gen_helper_float_nmadd_s(tcg_ctx, fp2, tcg_ctx->cpu_env, fp0, fp1, fp2);
10437             tcg_temp_free_i32(tcg_ctx, fp0);
10438             tcg_temp_free_i32(tcg_ctx, fp1);
10439             gen_store_fpr32(ctx, fp2, fd);
10440             tcg_temp_free_i32(tcg_ctx, fp2);
10441         }
10442         opn = "nmadd.s";
10443         break;
10444     case OPC_NMADD_D:
10445         check_cop1x(ctx);
10446         check_cp1_registers(ctx, fd | fs | ft | fr);
10447         {
10448             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
10449             TCGv_i64 fp1 = tcg_temp_new_i64(tcg_ctx);
10450             TCGv_i64 fp2 = tcg_temp_new_i64(tcg_ctx);
10451 
10452             gen_load_fpr64(ctx, fp0, fs);
10453             gen_load_fpr64(ctx, fp1, ft);
10454             gen_load_fpr64(ctx, fp2, fr);
10455             gen_helper_float_nmadd_d(tcg_ctx, fp2, tcg_ctx->cpu_env, fp0, fp1, fp2);
10456             tcg_temp_free_i64(tcg_ctx, fp0);
10457             tcg_temp_free_i64(tcg_ctx, fp1);
10458             gen_store_fpr64(ctx, fp2, fd);
10459             tcg_temp_free_i64(tcg_ctx, fp2);
10460         }
10461         opn = "nmadd.d";
10462         break;
10463     case OPC_NMADD_PS:
10464         check_cp1_64bitmode(ctx);
10465         {
10466             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
10467             TCGv_i64 fp1 = tcg_temp_new_i64(tcg_ctx);
10468             TCGv_i64 fp2 = tcg_temp_new_i64(tcg_ctx);
10469 
10470             gen_load_fpr64(ctx, fp0, fs);
10471             gen_load_fpr64(ctx, fp1, ft);
10472             gen_load_fpr64(ctx, fp2, fr);
10473             gen_helper_float_nmadd_ps(tcg_ctx, fp2, tcg_ctx->cpu_env, fp0, fp1, fp2);
10474             tcg_temp_free_i64(tcg_ctx, fp0);
10475             tcg_temp_free_i64(tcg_ctx, fp1);
10476             gen_store_fpr64(ctx, fp2, fd);
10477             tcg_temp_free_i64(tcg_ctx, fp2);
10478         }
10479         opn = "nmadd.ps";
10480         break;
10481     case OPC_NMSUB_S:
10482         check_cop1x(ctx);
10483         {
10484             TCGv_i32 fp0 = tcg_temp_new_i32(tcg_ctx);
10485             TCGv_i32 fp1 = tcg_temp_new_i32(tcg_ctx);
10486             TCGv_i32 fp2 = tcg_temp_new_i32(tcg_ctx);
10487 
10488             gen_load_fpr32(ctx, fp0, fs);
10489             gen_load_fpr32(ctx, fp1, ft);
10490             gen_load_fpr32(ctx, fp2, fr);
10491             gen_helper_float_nmsub_s(tcg_ctx, fp2, tcg_ctx->cpu_env, fp0, fp1, fp2);
10492             tcg_temp_free_i32(tcg_ctx, fp0);
10493             tcg_temp_free_i32(tcg_ctx, fp1);
10494             gen_store_fpr32(ctx, fp2, fd);
10495             tcg_temp_free_i32(tcg_ctx, fp2);
10496         }
10497         opn = "nmsub.s";
10498         break;
10499     case OPC_NMSUB_D:
10500         check_cop1x(ctx);
10501         check_cp1_registers(ctx, fd | fs | ft | fr);
10502         {
10503             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
10504             TCGv_i64 fp1 = tcg_temp_new_i64(tcg_ctx);
10505             TCGv_i64 fp2 = tcg_temp_new_i64(tcg_ctx);
10506 
10507             gen_load_fpr64(ctx, fp0, fs);
10508             gen_load_fpr64(ctx, fp1, ft);
10509             gen_load_fpr64(ctx, fp2, fr);
10510             gen_helper_float_nmsub_d(tcg_ctx, fp2, tcg_ctx->cpu_env, fp0, fp1, fp2);
10511             tcg_temp_free_i64(tcg_ctx, fp0);
10512             tcg_temp_free_i64(tcg_ctx, fp1);
10513             gen_store_fpr64(ctx, fp2, fd);
10514             tcg_temp_free_i64(tcg_ctx, fp2);
10515         }
10516         opn = "nmsub.d";
10517         break;
10518     case OPC_NMSUB_PS:
10519         check_cp1_64bitmode(ctx);
10520         {
10521             TCGv_i64 fp0 = tcg_temp_new_i64(tcg_ctx);
10522             TCGv_i64 fp1 = tcg_temp_new_i64(tcg_ctx);
10523             TCGv_i64 fp2 = tcg_temp_new_i64(tcg_ctx);
10524 
10525             gen_load_fpr64(ctx, fp0, fs);
10526             gen_load_fpr64(ctx, fp1, ft);
10527             gen_load_fpr64(ctx, fp2, fr);
10528             gen_helper_float_nmsub_ps(tcg_ctx, fp2, tcg_ctx->cpu_env, fp0, fp1, fp2);
10529             tcg_temp_free_i64(tcg_ctx, fp0);
10530             tcg_temp_free_i64(tcg_ctx, fp1);
10531             gen_store_fpr64(ctx, fp2, fd);
10532             tcg_temp_free_i64(tcg_ctx, fp2);
10533         }
10534         opn = "nmsub.ps";
10535         break;
10536     default:
10537         MIPS_INVAL(opn);
10538         generate_exception (ctx, EXCP_RI);
10539         return;
10540     }
10541     (void)opn; /* avoid a compiler warning */
10542     MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
10543                fregnames[fs], fregnames[ft]);
10544 }
10545 
gen_rdhwr(DisasContext * ctx,int rt,int rd)10546 static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
10547 {
10548     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
10549     TCGv t0;
10550 
10551 #if !defined(CONFIG_USER_ONLY)
10552     /* The Linux kernel will emulate rdhwr if it's not supported natively.
10553        Therefore only check the ISA in system mode.  */
10554     check_insn(ctx, ISA_MIPS32R2);
10555 #endif
10556     t0 = tcg_temp_new(tcg_ctx);
10557 
10558     switch (rd) {
10559     case 0:
10560         save_cpu_state(ctx, 1);
10561         gen_helper_rdhwr_cpunum(tcg_ctx, t0, tcg_ctx->cpu_env);
10562         gen_store_gpr(tcg_ctx, t0, rt);
10563         break;
10564     case 1:
10565         save_cpu_state(ctx, 1);
10566         gen_helper_rdhwr_synci_step(tcg_ctx, t0, tcg_ctx->cpu_env);
10567         gen_store_gpr(tcg_ctx, t0, rt);
10568         break;
10569     case 2:
10570         save_cpu_state(ctx, 1);
10571         gen_helper_rdhwr_cc(tcg_ctx, t0, tcg_ctx->cpu_env);
10572         gen_store_gpr(tcg_ctx, t0, rt);
10573         break;
10574     case 3:
10575         save_cpu_state(ctx, 1);
10576         gen_helper_rdhwr_ccres(tcg_ctx, t0, tcg_ctx->cpu_env);
10577         gen_store_gpr(tcg_ctx, t0, rt);
10578         break;
10579     case 29:
10580 #if defined(CONFIG_USER_ONLY)
10581         tcg_gen_ld_tl(tcg_ctx, t0, tcg_ctx->cpu_env,
10582                       offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10583         gen_store_gpr(tcg_ctx, t0, rt);
10584         break;
10585 #else
10586         if ((ctx->hflags & MIPS_HFLAG_CP0) ||
10587             (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
10588             tcg_gen_ld_tl(tcg_ctx, t0, tcg_ctx->cpu_env,
10589                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10590             gen_store_gpr(tcg_ctx, t0, rt);
10591         } else {
10592             generate_exception(ctx, EXCP_RI);
10593         }
10594         break;
10595 #endif
10596     default:            /* Invalid */
10597         MIPS_INVAL("rdhwr");
10598         generate_exception(ctx, EXCP_RI);
10599         break;
10600     }
10601     tcg_temp_free(tcg_ctx, t0);
10602 }
10603 
gen_branch(DisasContext * ctx,int insn_bytes)10604 static void gen_branch(DisasContext *ctx, int insn_bytes)
10605 {
10606     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
10607     if (ctx->hflags & MIPS_HFLAG_BMASK) {
10608         int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
10609         /* Branches completion */
10610         ctx->hflags &= ~MIPS_HFLAG_BMASK;
10611         ctx->bstate = BS_BRANCH;
10612         save_cpu_state(ctx, 0);
10613         /* FIXME: Need to clear can_do_io.  */
10614         switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
10615         case MIPS_HFLAG_FBNSLOT:
10616             MIPS_DEBUG("forbidden slot");
10617             gen_goto_tb(ctx, 0, ctx->pc + insn_bytes);
10618             break;
10619         case MIPS_HFLAG_B:
10620             /* unconditional branch */
10621             MIPS_DEBUG("unconditional branch");
10622             if (proc_hflags & MIPS_HFLAG_BX) {
10623                 tcg_gen_xori_i32(tcg_ctx, tcg_ctx->hflags, tcg_ctx->hflags, MIPS_HFLAG_M16);
10624             }
10625             gen_goto_tb(ctx, 0, ctx->btarget);
10626             break;
10627         case MIPS_HFLAG_BL:
10628             /* blikely taken case */
10629             MIPS_DEBUG("blikely branch taken");
10630             gen_goto_tb(ctx, 0, ctx->btarget);
10631             break;
10632         case MIPS_HFLAG_BC:
10633             /* Conditional branch */
10634             MIPS_DEBUG("conditional branch");
10635             {
10636                 int l1 = gen_new_label(tcg_ctx);
10637 
10638                 tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_NE, *(TCGv *)tcg_ctx->bcond, 0, l1);
10639                 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
10640                 gen_set_label(tcg_ctx, l1);
10641                 gen_goto_tb(ctx, 0, ctx->btarget);
10642             }
10643             break;
10644         case MIPS_HFLAG_BR:
10645             /* unconditional branch to register */
10646             MIPS_DEBUG("branch to register");
10647             if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
10648                 TCGv t0 = tcg_temp_new(tcg_ctx);
10649                 TCGv_i32 t1 = tcg_temp_new_i32(tcg_ctx);
10650 
10651                 tcg_gen_andi_tl(tcg_ctx, t0, *(TCGv *)tcg_ctx->btarget, 0x1);
10652                 tcg_gen_trunc_tl_i32(tcg_ctx, t1, t0);
10653                 tcg_temp_free(tcg_ctx, t0);
10654                 tcg_gen_andi_i32(tcg_ctx, tcg_ctx->hflags, tcg_ctx->hflags, ~(uint32_t)MIPS_HFLAG_M16);
10655                 tcg_gen_shli_i32(tcg_ctx, t1, t1, MIPS_HFLAG_M16_SHIFT);
10656                 tcg_gen_or_i32(tcg_ctx, tcg_ctx->hflags, tcg_ctx->hflags, t1);
10657                 tcg_temp_free_i32(tcg_ctx, t1);
10658 
10659                 tcg_gen_andi_tl(tcg_ctx, *(TCGv *)tcg_ctx->cpu_PC, *(TCGv *)tcg_ctx->btarget, ~(target_ulong)0x1);
10660             } else {
10661                 tcg_gen_mov_tl(tcg_ctx, *(TCGv *)tcg_ctx->cpu_PC, *(TCGv *)tcg_ctx->btarget);
10662             }
10663             if (ctx->singlestep_enabled) {
10664                 save_cpu_state(ctx, 0);
10665                 gen_helper_0e0i(tcg_ctx, raise_exception, EXCP_DEBUG);
10666             }
10667             tcg_gen_exit_tb(tcg_ctx, 0);
10668             break;
10669         default:
10670             MIPS_DEBUG("unknown branch");
10671             break;
10672         }
10673     }
10674 }
10675 
10676 /* ISA extensions (ASEs) */
10677 /* MIPS16 extension to MIPS32 */
10678 
10679 /* MIPS16 major opcodes */
10680 enum {
10681   M16_OPC_ADDIUSP = 0x00,
10682   M16_OPC_ADDIUPC = 0x01,
10683   M16_OPC_B = 0x02,
10684   M16_OPC_JAL = 0x03,
10685   M16_OPC_BEQZ = 0x04,
10686   M16_OPC_BNEQZ = 0x05,
10687   M16_OPC_SHIFT = 0x06,
10688   M16_OPC_LD = 0x07,
10689   M16_OPC_RRIA = 0x08,
10690   M16_OPC_ADDIU8 = 0x09,
10691   M16_OPC_SLTI = 0x0a,
10692   M16_OPC_SLTIU = 0x0b,
10693   M16_OPC_I8 = 0x0c,
10694   M16_OPC_LI = 0x0d,
10695   M16_OPC_CMPI = 0x0e,
10696   M16_OPC_SD = 0x0f,
10697   M16_OPC_LB = 0x10,
10698   M16_OPC_LH = 0x11,
10699   M16_OPC_LWSP = 0x12,
10700   M16_OPC_LW = 0x13,
10701   M16_OPC_LBU = 0x14,
10702   M16_OPC_LHU = 0x15,
10703   M16_OPC_LWPC = 0x16,
10704   M16_OPC_LWU = 0x17,
10705   M16_OPC_SB = 0x18,
10706   M16_OPC_SH = 0x19,
10707   M16_OPC_SWSP = 0x1a,
10708   M16_OPC_SW = 0x1b,
10709   M16_OPC_RRR = 0x1c,
10710   M16_OPC_RR = 0x1d,
10711   M16_OPC_EXTEND = 0x1e,
10712   M16_OPC_I64 = 0x1f
10713 };
10714 
10715 /* I8 funct field */
10716 enum {
10717   I8_BTEQZ = 0x0,
10718   I8_BTNEZ = 0x1,
10719   I8_SWRASP = 0x2,
10720   I8_ADJSP = 0x3,
10721   I8_SVRS = 0x4,
10722   I8_MOV32R = 0x5,
10723   I8_MOVR32 = 0x7
10724 };
10725 
10726 /* RRR f field */
10727 enum {
10728   RRR_DADDU = 0x0,
10729   RRR_ADDU = 0x1,
10730   RRR_DSUBU = 0x2,
10731   RRR_SUBU = 0x3
10732 };
10733 
10734 /* RR funct field */
10735 enum {
10736   RR_JR = 0x00,
10737   RR_SDBBP = 0x01,
10738   RR_SLT = 0x02,
10739   RR_SLTU = 0x03,
10740   RR_SLLV = 0x04,
10741   RR_BREAK = 0x05,
10742   RR_SRLV = 0x06,
10743   RR_SRAV = 0x07,
10744   RR_DSRL = 0x08,
10745   RR_CMP = 0x0a,
10746   RR_NEG = 0x0b,
10747   RR_AND = 0x0c,
10748   RR_OR = 0x0d,
10749   RR_XOR = 0x0e,
10750   RR_NOT = 0x0f,
10751   RR_MFHI = 0x10,
10752   RR_CNVT = 0x11,
10753   RR_MFLO = 0x12,
10754   RR_DSRA = 0x13,
10755   RR_DSLLV = 0x14,
10756   RR_DSRLV = 0x16,
10757   RR_DSRAV = 0x17,
10758   RR_MULT = 0x18,
10759   RR_MULTU = 0x19,
10760   RR_DIV = 0x1a,
10761   RR_DIVU = 0x1b,
10762   RR_DMULT = 0x1c,
10763   RR_DMULTU = 0x1d,
10764   RR_DDIV = 0x1e,
10765   RR_DDIVU = 0x1f
10766 };
10767 
10768 /* I64 funct field */
10769 enum {
10770   I64_LDSP = 0x0,
10771   I64_SDSP = 0x1,
10772   I64_SDRASP = 0x2,
10773   I64_DADJSP = 0x3,
10774   I64_LDPC = 0x4,
10775   I64_DADDIU5 = 0x5,
10776   I64_DADDIUPC = 0x6,
10777   I64_DADDIUSP = 0x7
10778 };
10779 
10780 /* RR ry field for CNVT */
10781 enum {
10782   RR_RY_CNVT_ZEB = 0x0,
10783   RR_RY_CNVT_ZEH = 0x1,
10784   RR_RY_CNVT_ZEW = 0x2,
10785   RR_RY_CNVT_SEB = 0x4,
10786   RR_RY_CNVT_SEH = 0x5,
10787   RR_RY_CNVT_SEW = 0x6,
10788 };
10789 
xlat(int r)10790 static int xlat (int r)
10791 {
10792   static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10793 
10794   return map[r];
10795 }
10796 
gen_mips16_save(DisasContext * ctx,int xsregs,int aregs,int do_ra,int do_s0,int do_s1,int framesize)10797 static void gen_mips16_save (DisasContext *ctx,
10798                              int xsregs, int aregs,
10799                              int do_ra, int do_s0, int do_s1,
10800                              int framesize)
10801 {
10802     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
10803     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
10804     TCGv t0 = tcg_temp_new(tcg_ctx);
10805     TCGv t1 = tcg_temp_new(tcg_ctx);
10806     int args, astatic;
10807 
10808     switch (aregs) {
10809     case 0:
10810     case 1:
10811     case 2:
10812     case 3:
10813     case 11:
10814         args = 0;
10815         break;
10816     case 4:
10817     case 5:
10818     case 6:
10819     case 7:
10820         args = 1;
10821         break;
10822     case 8:
10823     case 9:
10824     case 10:
10825         args = 2;
10826         break;
10827     case 12:
10828     case 13:
10829         args = 3;
10830         break;
10831     case 14:
10832         args = 4;
10833         break;
10834     default:
10835         generate_exception(ctx, EXCP_RI);
10836         return;
10837     }
10838 
10839     switch (args) {
10840     case 4:
10841         gen_base_offset_addr(ctx, t0, 29, 12);
10842         gen_load_gpr(ctx, t1, 7);
10843         tcg_gen_qemu_st_tl(ctx->uc, t1, t0, ctx->mem_idx, MO_TEUL);
10844         /* Fall through */
10845     case 3:
10846         gen_base_offset_addr(ctx, t0, 29, 8);
10847         gen_load_gpr(ctx, t1, 6);
10848         tcg_gen_qemu_st_tl(ctx->uc, t1, t0, ctx->mem_idx, MO_TEUL);
10849         /* Fall through */
10850     case 2:
10851         gen_base_offset_addr(ctx, t0, 29, 4);
10852         gen_load_gpr(ctx, t1, 5);
10853         tcg_gen_qemu_st_tl(ctx->uc, t1, t0, ctx->mem_idx, MO_TEUL);
10854         /* Fall through */
10855     case 1:
10856         gen_base_offset_addr(ctx, t0, 29, 0);
10857         gen_load_gpr(ctx, t1, 4);
10858         tcg_gen_qemu_st_tl(ctx->uc, t1, t0, ctx->mem_idx, MO_TEUL);
10859     }
10860 
10861     gen_load_gpr(ctx, t0, 29);
10862 
10863 #define DECR_AND_STORE(reg) do {                                 \
10864         tcg_gen_subi_tl(tcg_ctx, t0, t0, 4);                              \
10865         gen_load_gpr(ctx, t1, reg);                                   \
10866         tcg_gen_qemu_st_tl(ctx->uc, t1, t0, ctx->mem_idx, MO_TEUL); \
10867     } while (0)
10868 
10869     if (do_ra) {
10870         DECR_AND_STORE(31);
10871     }
10872 
10873     switch (xsregs) {
10874     case 7:
10875         DECR_AND_STORE(30);
10876         /* Fall through */
10877     case 6:
10878         DECR_AND_STORE(23);
10879         /* Fall through */
10880     case 5:
10881         DECR_AND_STORE(22);
10882         /* Fall through */
10883     case 4:
10884         DECR_AND_STORE(21);
10885         /* Fall through */
10886     case 3:
10887         DECR_AND_STORE(20);
10888         /* Fall through */
10889     case 2:
10890         DECR_AND_STORE(19);
10891         /* Fall through */
10892     case 1:
10893         DECR_AND_STORE(18);
10894     }
10895 
10896     if (do_s1) {
10897         DECR_AND_STORE(17);
10898     }
10899     if (do_s0) {
10900         DECR_AND_STORE(16);
10901     }
10902 
10903     switch (aregs) {
10904     case 0:
10905     case 4:
10906     case 8:
10907     case 12:
10908     case 14:
10909         astatic = 0;
10910         break;
10911     case 1:
10912     case 5:
10913     case 9:
10914     case 13:
10915         astatic = 1;
10916         break;
10917     case 2:
10918     case 6:
10919     case 10:
10920         astatic = 2;
10921         break;
10922     case 3:
10923     case 7:
10924         astatic = 3;
10925         break;
10926     case 11:
10927         astatic = 4;
10928         break;
10929     default:
10930         generate_exception(ctx, EXCP_RI);
10931         return;
10932     }
10933 
10934     if (astatic > 0) {
10935         DECR_AND_STORE(7);
10936         if (astatic > 1) {
10937             DECR_AND_STORE(6);
10938             if (astatic > 2) {
10939                 DECR_AND_STORE(5);
10940                 if (astatic > 3) {
10941                     DECR_AND_STORE(4);
10942                 }
10943             }
10944         }
10945     }
10946 #undef DECR_AND_STORE
10947 
10948     tcg_gen_subi_tl(tcg_ctx, *cpu_gpr[29], *cpu_gpr[29], framesize);
10949     tcg_temp_free(tcg_ctx, t0);
10950     tcg_temp_free(tcg_ctx, t1);
10951 }
10952 
gen_mips16_restore(DisasContext * ctx,int xsregs,int aregs,int do_ra,int do_s0,int do_s1,int framesize)10953 static void gen_mips16_restore (DisasContext *ctx,
10954                                 int xsregs, int aregs,
10955                                 int do_ra, int do_s0, int do_s1,
10956                                 int framesize)
10957 {
10958     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
10959     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
10960     int astatic;
10961     TCGv t0 = tcg_temp_new(tcg_ctx);
10962     TCGv t1 = tcg_temp_new(tcg_ctx);
10963 
10964     tcg_gen_addi_tl(tcg_ctx, t0, *cpu_gpr[29], framesize);
10965 
10966 #define DECR_AND_LOAD(reg) do {                            \
10967         tcg_gen_subi_tl(tcg_ctx, t0, t0, 4);                        \
10968         tcg_gen_qemu_ld_tl(ctx->uc, t1, t0, ctx->mem_idx, MO_TESL); \
10969         gen_store_gpr(tcg_ctx, t1, reg);                            \
10970     } while (0)
10971 
10972     if (do_ra) {
10973         DECR_AND_LOAD(31);
10974     }
10975 
10976     switch (xsregs) {
10977     case 7:
10978         DECR_AND_LOAD(30);
10979         /* Fall through */
10980     case 6:
10981         DECR_AND_LOAD(23);
10982         /* Fall through */
10983     case 5:
10984         DECR_AND_LOAD(22);
10985         /* Fall through */
10986     case 4:
10987         DECR_AND_LOAD(21);
10988         /* Fall through */
10989     case 3:
10990         DECR_AND_LOAD(20);
10991         /* Fall through */
10992     case 2:
10993         DECR_AND_LOAD(19);
10994         /* Fall through */
10995     case 1:
10996         DECR_AND_LOAD(18);
10997     }
10998 
10999     if (do_s1) {
11000         DECR_AND_LOAD(17);
11001     }
11002     if (do_s0) {
11003         DECR_AND_LOAD(16);
11004     }
11005 
11006     switch (aregs) {
11007     case 0:
11008     case 4:
11009     case 8:
11010     case 12:
11011     case 14:
11012         astatic = 0;
11013         break;
11014     case 1:
11015     case 5:
11016     case 9:
11017     case 13:
11018         astatic = 1;
11019         break;
11020     case 2:
11021     case 6:
11022     case 10:
11023         astatic = 2;
11024         break;
11025     case 3:
11026     case 7:
11027         astatic = 3;
11028         break;
11029     case 11:
11030         astatic = 4;
11031         break;
11032     default:
11033         generate_exception(ctx, EXCP_RI);
11034         return;
11035     }
11036 
11037     if (astatic > 0) {
11038         DECR_AND_LOAD(7);
11039         if (astatic > 1) {
11040             DECR_AND_LOAD(6);
11041             if (astatic > 2) {
11042                 DECR_AND_LOAD(5);
11043                 if (astatic > 3) {
11044                     DECR_AND_LOAD(4);
11045                 }
11046             }
11047         }
11048     }
11049 #undef DECR_AND_LOAD
11050 
11051     tcg_gen_addi_tl(tcg_ctx, *cpu_gpr[29], *cpu_gpr[29], framesize);
11052     tcg_temp_free(tcg_ctx, t0);
11053     tcg_temp_free(tcg_ctx, t1);
11054 }
11055 
gen_addiupc(DisasContext * ctx,int rx,int imm,int is_64_bit,int extended)11056 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
11057                          int is_64_bit, int extended)
11058 {
11059     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
11060     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
11061     TCGv t0;
11062 
11063     if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11064         generate_exception(ctx, EXCP_RI);
11065         return;
11066     }
11067 
11068     t0 = tcg_temp_new(tcg_ctx);
11069 
11070     tcg_gen_movi_tl(tcg_ctx, t0, pc_relative_pc(ctx));
11071     tcg_gen_addi_tl(tcg_ctx, *cpu_gpr[rx], t0, imm);
11072     if (!is_64_bit) {
11073         tcg_gen_ext32s_tl(tcg_ctx, *cpu_gpr[rx], *cpu_gpr[rx]);
11074     }
11075 
11076     tcg_temp_free(tcg_ctx, t0);
11077 }
11078 
11079 #if defined(TARGET_MIPS64)
decode_i64_mips16(DisasContext * ctx,int ry,int funct,int16_t offset,int extended)11080 static void decode_i64_mips16 (DisasContext *ctx,
11081                                int ry, int funct, int16_t offset,
11082                                int extended)
11083 {
11084     switch (funct) {
11085     case I64_LDSP:
11086         check_mips_64(ctx);
11087         offset = extended ? offset : offset << 3;
11088         gen_ld(ctx, OPC_LD, ry, 29, offset);
11089         break;
11090     case I64_SDSP:
11091         check_mips_64(ctx);
11092         offset = extended ? offset : offset << 3;
11093         gen_st(ctx, OPC_SD, ry, 29, offset);
11094         break;
11095     case I64_SDRASP:
11096         check_mips_64(ctx);
11097         offset = extended ? offset : (ctx->opcode & 0xff) << 3;
11098         gen_st(ctx, OPC_SD, 31, 29, offset);
11099         break;
11100     case I64_DADJSP:
11101         check_mips_64(ctx);
11102         offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
11103         gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
11104         break;
11105     case I64_LDPC:
11106         if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11107             generate_exception(ctx, EXCP_RI);
11108         } else {
11109             offset = extended ? offset : offset << 3;
11110             gen_ld(ctx, OPC_LDPC, ry, 0, offset);
11111         }
11112         break;
11113     case I64_DADDIU5:
11114         check_mips_64(ctx);
11115         offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
11116         gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
11117         break;
11118     case I64_DADDIUPC:
11119         check_mips_64(ctx);
11120         offset = extended ? offset : offset << 2;
11121         gen_addiupc(ctx, ry, offset, 1, extended);
11122         break;
11123     case I64_DADDIUSP:
11124         check_mips_64(ctx);
11125         offset = extended ? offset : offset << 2;
11126         gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
11127         break;
11128     }
11129 }
11130 #endif
11131 
decode_extended_mips16_opc(CPUMIPSState * env,DisasContext * ctx)11132 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
11133 {
11134     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
11135     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
11136     int extend = cpu_lduw_code(env, ctx->pc + 2);
11137     int op, rx, ry, funct, sa;
11138     int16_t imm, offset;
11139 
11140     ctx->opcode = (ctx->opcode << 16) | extend;
11141     op = (ctx->opcode >> 11) & 0x1f;
11142     sa = (ctx->opcode >> 22) & 0x1f;
11143     funct = (ctx->opcode >> 8) & 0x7;
11144     rx = xlat((ctx->opcode >> 8) & 0x7);
11145     ry = xlat((ctx->opcode >> 5) & 0x7);
11146     offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
11147                               | ((ctx->opcode >> 21) & 0x3f) << 5
11148                               | (ctx->opcode & 0x1f));
11149 
11150     /* The extended opcodes cleverly reuse the opcodes from their 16-bit
11151        counterparts.  */
11152     switch (op) {
11153     case M16_OPC_ADDIUSP:
11154         gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
11155         break;
11156     case M16_OPC_ADDIUPC:
11157         gen_addiupc(ctx, rx, imm, 0, 1);
11158         break;
11159     case M16_OPC_B:
11160         gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, (uint32_t)offset << 1, 0);
11161         /* No delay slot, so just process as a normal instruction */
11162         break;
11163     case M16_OPC_BEQZ:
11164         gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, (uint16_t)offset << 1, 0);
11165         /* No delay slot, so just process as a normal instruction */
11166         break;
11167     case M16_OPC_BNEQZ:
11168         gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, (uint16_t)offset << 1, 0);
11169         /* No delay slot, so just process as a normal instruction */
11170         break;
11171     case M16_OPC_SHIFT:
11172         switch (ctx->opcode & 0x3) {
11173         case 0x0:
11174             gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
11175             break;
11176         case 0x1:
11177 #if defined(TARGET_MIPS64)
11178             check_mips_64(ctx);
11179             gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
11180 #else
11181             generate_exception(ctx, EXCP_RI);
11182 #endif
11183             break;
11184         case 0x2:
11185             gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
11186             break;
11187         case 0x3:
11188             gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
11189             break;
11190         }
11191         break;
11192 #if defined(TARGET_MIPS64)
11193     case M16_OPC_LD:
11194             check_mips_64(ctx);
11195         gen_ld(ctx, OPC_LD, ry, rx, offset);
11196         break;
11197 #endif
11198     case M16_OPC_RRIA:
11199         imm = ctx->opcode & 0xf;
11200         imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
11201         imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
11202         imm = (int16_t) (imm << 1) >> 1;
11203         if ((ctx->opcode >> 4) & 0x1) {
11204 #if defined(TARGET_MIPS64)
11205             check_mips_64(ctx);
11206             gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
11207 #else
11208             generate_exception(ctx, EXCP_RI);
11209 #endif
11210         } else {
11211             gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
11212         }
11213         break;
11214     case M16_OPC_ADDIU8:
11215         gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
11216         break;
11217     case M16_OPC_SLTI:
11218         gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
11219         break;
11220     case M16_OPC_SLTIU:
11221         gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
11222         break;
11223     case M16_OPC_I8:
11224         switch (funct) {
11225         case I8_BTEQZ:
11226             gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, (uint16_t)offset << 1, 0);
11227             break;
11228         case I8_BTNEZ:
11229             gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, (uint16_t)offset << 1, 0);
11230             break;
11231         case I8_SWRASP:
11232             gen_st(ctx, OPC_SW, 31, 29, imm);
11233             break;
11234         case I8_ADJSP:
11235             gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
11236             break;
11237         case I8_SVRS:
11238             {
11239                 int xsregs = (ctx->opcode >> 24) & 0x7;
11240                 int aregs = (ctx->opcode >> 16) & 0xf;
11241                 int do_ra = (ctx->opcode >> 6) & 0x1;
11242                 int do_s0 = (ctx->opcode >> 5) & 0x1;
11243                 int do_s1 = (ctx->opcode >> 4) & 0x1;
11244                 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
11245                                  | (ctx->opcode & 0xf)) << 3;
11246 
11247                 if (ctx->opcode & (1 << 7)) {
11248                     gen_mips16_save(ctx, xsregs, aregs,
11249                                     do_ra, do_s0, do_s1,
11250                                     framesize);
11251                 } else {
11252                     gen_mips16_restore(ctx, xsregs, aregs,
11253                                        do_ra, do_s0, do_s1,
11254                                        framesize);
11255                 }
11256             }
11257             break;
11258         default:
11259             generate_exception(ctx, EXCP_RI);
11260             break;
11261         }
11262         break;
11263     case M16_OPC_LI:
11264         tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[rx], (uint16_t) imm);
11265         break;
11266     case M16_OPC_CMPI:
11267         tcg_gen_xori_tl(tcg_ctx, *cpu_gpr[24], *cpu_gpr[rx], (uint16_t) imm);
11268         break;
11269 #if defined(TARGET_MIPS64)
11270     case M16_OPC_SD:
11271         gen_st(ctx, OPC_SD, ry, rx, offset);
11272         break;
11273 #endif
11274     case M16_OPC_LB:
11275         gen_ld(ctx, OPC_LB, ry, rx, offset);
11276         break;
11277     case M16_OPC_LH:
11278         gen_ld(ctx, OPC_LH, ry, rx, offset);
11279         break;
11280     case M16_OPC_LWSP:
11281         gen_ld(ctx, OPC_LW, rx, 29, offset);
11282         break;
11283     case M16_OPC_LW:
11284         gen_ld(ctx, OPC_LW, ry, rx, offset);
11285         break;
11286     case M16_OPC_LBU:
11287         gen_ld(ctx, OPC_LBU, ry, rx, offset);
11288         break;
11289     case M16_OPC_LHU:
11290         gen_ld(ctx, OPC_LHU, ry, rx, offset);
11291         break;
11292     case M16_OPC_LWPC:
11293         gen_ld(ctx, OPC_LWPC, rx, 0, offset);
11294         break;
11295 #if defined(TARGET_MIPS64)
11296     case M16_OPC_LWU:
11297         gen_ld(ctx, OPC_LWU, ry, rx, offset);
11298         break;
11299 #endif
11300     case M16_OPC_SB:
11301         gen_st(ctx, OPC_SB, ry, rx, offset);
11302         break;
11303     case M16_OPC_SH:
11304         gen_st(ctx, OPC_SH, ry, rx, offset);
11305         break;
11306     case M16_OPC_SWSP:
11307         gen_st(ctx, OPC_SW, rx, 29, offset);
11308         break;
11309     case M16_OPC_SW:
11310         gen_st(ctx, OPC_SW, ry, rx, offset);
11311         break;
11312 #if defined(TARGET_MIPS64)
11313     case M16_OPC_I64:
11314         decode_i64_mips16(ctx, ry, funct, offset, 1);
11315         break;
11316 #endif
11317     default:
11318         generate_exception(ctx, EXCP_RI);
11319         break;
11320     }
11321 
11322     return 4;
11323 }
11324 
decode_mips16_opc(CPUMIPSState * env,DisasContext * ctx,bool * insn_need_patch)11325 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx, bool *insn_need_patch)
11326 {
11327     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
11328     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
11329     int rx, ry;
11330     int sa;
11331     int op, cnvt_op, op1, offset;
11332     int funct;
11333     int n_bytes;
11334 
11335     op = (ctx->opcode >> 11) & 0x1f;
11336     sa = (ctx->opcode >> 2) & 0x7;
11337     sa = sa == 0 ? 8 : sa;
11338     rx = xlat((ctx->opcode >> 8) & 0x7);
11339     cnvt_op = (ctx->opcode >> 5) & 0x7;
11340     ry = xlat((ctx->opcode >> 5) & 0x7);
11341     op1 = offset = ctx->opcode & 0x1f;
11342 
11343     n_bytes = 2;
11344 
11345     // Unicorn: trace this instruction on request
11346     if (HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_CODE, ctx->pc)) {
11347         gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_CODE_IDX, env->uc, ctx->pc);
11348         *insn_need_patch = true;
11349         // the callback might want to stop emulation immediately
11350         check_exit_request(tcg_ctx);
11351     }
11352 
11353     switch (op) {
11354     case M16_OPC_ADDIUSP:
11355         {
11356             int16_t imm = ((uint8_t) ctx->opcode) << 2;
11357 
11358             gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
11359         }
11360         break;
11361     case M16_OPC_ADDIUPC:
11362         gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
11363         break;
11364     case M16_OPC_B:
11365         offset = (ctx->opcode & 0x7ff) << 1;
11366         offset = (int16_t)(offset << 4) >> 4;
11367         gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
11368         /* No delay slot, so just process as a normal instruction */
11369         break;
11370     case M16_OPC_JAL:
11371         offset = cpu_lduw_code(env, ctx->pc + 2);
11372         offset = (((ctx->opcode & 0x1f) << 21)
11373                   | ((ctx->opcode >> 5) & 0x1f) << 16
11374                   | offset) << 2;
11375         op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
11376         gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
11377         n_bytes = 4;
11378         break;
11379     case M16_OPC_BEQZ:
11380         gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
11381                            ((uint8_t)ctx->opcode) << 1, 0);
11382         /* No delay slot, so just process as a normal instruction */
11383         break;
11384     case M16_OPC_BNEQZ:
11385         gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
11386                            ((uint8_t)ctx->opcode) << 1, 0);
11387         /* No delay slot, so just process as a normal instruction */
11388         break;
11389     case M16_OPC_SHIFT:
11390         switch (ctx->opcode & 0x3) {
11391         case 0x0:
11392             gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
11393             break;
11394         case 0x1:
11395 #if defined(TARGET_MIPS64)
11396             check_mips_64(ctx);
11397             gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
11398 #else
11399             generate_exception(ctx, EXCP_RI);
11400 #endif
11401             break;
11402         case 0x2:
11403             gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
11404             break;
11405         case 0x3:
11406             gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
11407             break;
11408         }
11409         break;
11410 #if defined(TARGET_MIPS64)
11411     case M16_OPC_LD:
11412         check_mips_64(ctx);
11413         gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
11414         break;
11415 #endif
11416     case M16_OPC_RRIA:
11417         {
11418             int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
11419 
11420             if ((ctx->opcode >> 4) & 1) {
11421 #if defined(TARGET_MIPS64)
11422                 check_mips_64(ctx);
11423                 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
11424 #else
11425                 generate_exception(ctx, EXCP_RI);
11426 #endif
11427             } else {
11428                 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
11429             }
11430         }
11431         break;
11432     case M16_OPC_ADDIU8:
11433         {
11434             int16_t imm = (int8_t) ctx->opcode;
11435 
11436             gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
11437         }
11438         break;
11439     case M16_OPC_SLTI:
11440         {
11441             int16_t imm = (uint8_t) ctx->opcode;
11442             gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
11443         }
11444         break;
11445     case M16_OPC_SLTIU:
11446         {
11447             int16_t imm = (uint8_t) ctx->opcode;
11448             gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
11449         }
11450         break;
11451     case M16_OPC_I8:
11452         {
11453             int reg32;
11454 
11455             funct = (ctx->opcode >> 8) & 0x7;
11456             switch (funct) {
11457             case I8_BTEQZ:
11458                 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
11459                                    ((uint8_t)ctx->opcode) << 1, 0);
11460                 break;
11461             case I8_BTNEZ:
11462                 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
11463                                    ((uint8_t)ctx->opcode) << 1, 0);
11464                 break;
11465             case I8_SWRASP:
11466                 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
11467                 break;
11468             case I8_ADJSP:
11469                 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
11470                               ((uint8_t)ctx->opcode) << 3);
11471                 break;
11472             case I8_SVRS:
11473                 {
11474                     int do_ra = ctx->opcode & (1 << 6);
11475                     int do_s0 = ctx->opcode & (1 << 5);
11476                     int do_s1 = ctx->opcode & (1 << 4);
11477                     int framesize = ctx->opcode & 0xf;
11478 
11479                     if (framesize == 0) {
11480                         framesize = 128;
11481                     } else {
11482                         framesize = framesize << 3;
11483                     }
11484 
11485                     if (ctx->opcode & (1 << 7)) {
11486                         gen_mips16_save(ctx, 0, 0,
11487                                         do_ra, do_s0, do_s1, framesize);
11488                     } else {
11489                         gen_mips16_restore(ctx, 0, 0,
11490                                            do_ra, do_s0, do_s1, framesize);
11491                     }
11492                 }
11493                 break;
11494             case I8_MOV32R:
11495                 {
11496                     int rz = xlat(ctx->opcode & 0x7);
11497 
11498                     reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
11499                         ((ctx->opcode >> 5) & 0x7);
11500                     gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
11501                 }
11502                 break;
11503             case I8_MOVR32:
11504                 reg32 = ctx->opcode & 0x1f;
11505                 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
11506                 break;
11507             default:
11508                 generate_exception(ctx, EXCP_RI);
11509                 break;
11510             }
11511         }
11512         break;
11513     case M16_OPC_LI:
11514         {
11515             int16_t imm = (uint8_t) ctx->opcode;
11516 
11517             gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
11518         }
11519         break;
11520     case M16_OPC_CMPI:
11521         {
11522             int16_t imm = (uint8_t) ctx->opcode;
11523             gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
11524         }
11525         break;
11526 #if defined(TARGET_MIPS64)
11527     case M16_OPC_SD:
11528         check_mips_64(ctx);
11529         gen_st(ctx, OPC_SD, ry, rx, offset << 3);
11530         break;
11531 #endif
11532     case M16_OPC_LB:
11533         gen_ld(ctx, OPC_LB, ry, rx, offset);
11534         break;
11535     case M16_OPC_LH:
11536         gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
11537         break;
11538     case M16_OPC_LWSP:
11539         gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
11540         break;
11541     case M16_OPC_LW:
11542         gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
11543         break;
11544     case M16_OPC_LBU:
11545         gen_ld(ctx, OPC_LBU, ry, rx, offset);
11546         break;
11547     case M16_OPC_LHU:
11548         gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
11549         break;
11550     case M16_OPC_LWPC:
11551         gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
11552         break;
11553 #if defined (TARGET_MIPS64)
11554     case M16_OPC_LWU:
11555         check_mips_64(ctx);
11556         gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
11557         break;
11558 #endif
11559     case M16_OPC_SB:
11560         gen_st(ctx, OPC_SB, ry, rx, offset);
11561         break;
11562     case M16_OPC_SH:
11563         gen_st(ctx, OPC_SH, ry, rx, offset << 1);
11564         break;
11565     case M16_OPC_SWSP:
11566         gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
11567         break;
11568     case M16_OPC_SW:
11569         gen_st(ctx, OPC_SW, ry, rx, offset << 2);
11570         break;
11571     case M16_OPC_RRR:
11572         {
11573             int rz = xlat((ctx->opcode >> 2) & 0x7);
11574             int mips32_op;
11575 
11576             switch (ctx->opcode & 0x3) {
11577             case RRR_ADDU:
11578                 mips32_op = OPC_ADDU;
11579                 break;
11580             case RRR_SUBU:
11581                 mips32_op = OPC_SUBU;
11582                 break;
11583 #if defined(TARGET_MIPS64)
11584             case RRR_DADDU:
11585                 mips32_op = OPC_DADDU;
11586                 check_mips_64(ctx);
11587                 break;
11588             case RRR_DSUBU:
11589                 mips32_op = OPC_DSUBU;
11590                 check_mips_64(ctx);
11591                 break;
11592 #endif
11593             default:
11594                 generate_exception(ctx, EXCP_RI);
11595                 goto done;
11596             }
11597 
11598             gen_arith(ctx, mips32_op, rz, rx, ry);
11599         done:
11600             ;
11601         }
11602         break;
11603     case M16_OPC_RR:
11604         switch (op1) {
11605         case RR_JR:
11606             {
11607                 int nd = (ctx->opcode >> 7) & 0x1;
11608                 int link = (ctx->opcode >> 6) & 0x1;
11609                 int ra = (ctx->opcode >> 5) & 0x1;
11610 
11611                 if (link) {
11612                     op = OPC_JALR;
11613                 } else {
11614                     op = OPC_JR;
11615                 }
11616 
11617                 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
11618                                    (nd ? 0 : 2));
11619             }
11620             break;
11621         case RR_SDBBP:
11622             /* XXX: not clear which exception should be raised
11623              *      when in debug mode...
11624              */
11625             check_insn(ctx, ISA_MIPS32);
11626             if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11627                 generate_exception(ctx, EXCP_DBp);
11628             } else {
11629                 generate_exception(ctx, EXCP_DBp);
11630             }
11631             break;
11632         case RR_SLT:
11633             gen_slt(ctx, OPC_SLT, 24, rx, ry);
11634             break;
11635         case RR_SLTU:
11636             gen_slt(ctx, OPC_SLTU, 24, rx, ry);
11637             break;
11638         case RR_BREAK:
11639             generate_exception(ctx, EXCP_BREAK);
11640             break;
11641         case RR_SLLV:
11642             gen_shift(ctx, OPC_SLLV, ry, rx, ry);
11643             break;
11644         case RR_SRLV:
11645             gen_shift(ctx, OPC_SRLV, ry, rx, ry);
11646             break;
11647         case RR_SRAV:
11648             gen_shift(ctx, OPC_SRAV, ry, rx, ry);
11649             break;
11650 #if defined (TARGET_MIPS64)
11651         case RR_DSRL:
11652             check_mips_64(ctx);
11653             gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
11654             break;
11655 #endif
11656         case RR_CMP:
11657             gen_logic(ctx, OPC_XOR, 24, rx, ry);
11658             break;
11659         case RR_NEG:
11660             gen_arith(ctx, OPC_SUBU, rx, 0, ry);
11661             break;
11662         case RR_AND:
11663             gen_logic(ctx, OPC_AND, rx, rx, ry);
11664             break;
11665         case RR_OR:
11666             gen_logic(ctx, OPC_OR, rx, rx, ry);
11667             break;
11668         case RR_XOR:
11669             gen_logic(ctx, OPC_XOR, rx, rx, ry);
11670             break;
11671         case RR_NOT:
11672             gen_logic(ctx, OPC_NOR, rx, ry, 0);
11673             break;
11674         case RR_MFHI:
11675             gen_HILO(ctx, OPC_MFHI, 0, rx);
11676             break;
11677         case RR_CNVT:
11678             switch (cnvt_op) {
11679             case RR_RY_CNVT_ZEB:
11680                 tcg_gen_ext8u_tl(tcg_ctx, *cpu_gpr[rx], *cpu_gpr[rx]);
11681                 break;
11682             case RR_RY_CNVT_ZEH:
11683                 tcg_gen_ext16u_tl(tcg_ctx, *cpu_gpr[rx], *cpu_gpr[rx]);
11684                 break;
11685             case RR_RY_CNVT_SEB:
11686                 tcg_gen_ext8s_tl(tcg_ctx, *cpu_gpr[rx], *cpu_gpr[rx]);
11687                 break;
11688             case RR_RY_CNVT_SEH:
11689                 tcg_gen_ext16s_tl(tcg_ctx, *cpu_gpr[rx], *cpu_gpr[rx]);
11690                 break;
11691 #if defined (TARGET_MIPS64)
11692             case RR_RY_CNVT_ZEW:
11693                 check_mips_64(ctx);
11694                 tcg_gen_ext32u_tl(tcg_ctx, *cpu_gpr[rx], *cpu_gpr[rx]);
11695                 break;
11696             case RR_RY_CNVT_SEW:
11697                 check_mips_64(ctx);
11698                 tcg_gen_ext32s_tl(tcg_ctx, *cpu_gpr[rx], *cpu_gpr[rx]);
11699                 break;
11700 #endif
11701             default:
11702                 generate_exception(ctx, EXCP_RI);
11703                 break;
11704             }
11705             break;
11706         case RR_MFLO:
11707             gen_HILO(ctx, OPC_MFLO, 0, rx);
11708             break;
11709 #if defined (TARGET_MIPS64)
11710         case RR_DSRA:
11711             check_mips_64(ctx);
11712             gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
11713             break;
11714         case RR_DSLLV:
11715             check_mips_64(ctx);
11716             gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
11717             break;
11718         case RR_DSRLV:
11719             check_mips_64(ctx);
11720             gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
11721             break;
11722         case RR_DSRAV:
11723             check_mips_64(ctx);
11724             gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
11725             break;
11726 #endif
11727         case RR_MULT:
11728             gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
11729             break;
11730         case RR_MULTU:
11731             gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
11732             break;
11733         case RR_DIV:
11734             gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
11735             break;
11736         case RR_DIVU:
11737             gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
11738             break;
11739 #if defined (TARGET_MIPS64)
11740         case RR_DMULT:
11741             check_mips_64(ctx);
11742             gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
11743             break;
11744         case RR_DMULTU:
11745             check_mips_64(ctx);
11746             gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
11747             break;
11748         case RR_DDIV:
11749             check_mips_64(ctx);
11750             gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
11751             break;
11752         case RR_DDIVU:
11753             check_mips_64(ctx);
11754             gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
11755             break;
11756 #endif
11757         default:
11758             generate_exception(ctx, EXCP_RI);
11759             break;
11760         }
11761         break;
11762     case M16_OPC_EXTEND:
11763         decode_extended_mips16_opc(env, ctx);
11764         n_bytes = 4;
11765         break;
11766 #if defined(TARGET_MIPS64)
11767     case M16_OPC_I64:
11768         funct = (ctx->opcode >> 8) & 0x7;
11769         decode_i64_mips16(ctx, ry, funct, offset, 0);
11770         break;
11771 #endif
11772     default:
11773         generate_exception(ctx, EXCP_RI);
11774         break;
11775     }
11776 
11777     return n_bytes;
11778 }
11779 
11780 /* microMIPS extension to MIPS32/MIPS64 */
11781 
11782 /*
11783  * microMIPS32/microMIPS64 major opcodes
11784  *
11785  * 1. MIPS Architecture for Programmers Volume II-B:
11786  *      The microMIPS32 Instruction Set (Revision 3.05)
11787  *
11788  *    Table 6.2 microMIPS32 Encoding of Major Opcode Field
11789  *
11790  * 2. MIPS Architecture For Programmers Volume II-A:
11791  *      The MIPS64 Instruction Set (Revision 3.51)
11792  */
11793 
11794 enum {
11795     POOL32A = 0x00,
11796     POOL16A = 0x01,
11797     LBU16 = 0x02,
11798     MOVE16 = 0x03,
11799     ADDI32 = 0x04,
11800     LBU32 = 0x05,
11801     SB32 = 0x06,
11802     LB32 = 0x07,
11803 
11804     POOL32B = 0x08,
11805     POOL16B = 0x09,
11806     LHU16 = 0x0a,
11807     ANDI16 = 0x0b,
11808     ADDIU32 = 0x0c,
11809     LHU32 = 0x0d,
11810     SH32 = 0x0e,
11811     LH32 = 0x0f,
11812 
11813     POOL32I = 0x10,
11814     POOL16C = 0x11,
11815     LWSP16 = 0x12,
11816     POOL16D = 0x13,
11817     ORI32 = 0x14,
11818     POOL32F = 0x15,
11819     POOL32S = 0x16,  /* MIPS64 */
11820     DADDIU32 = 0x17, /* MIPS64 */
11821 
11822     /* 0x1f is reserved */
11823     POOL32C = 0x18,
11824     LWGP16 = 0x19,
11825     LW16 = 0x1a,
11826     POOL16E = 0x1b,
11827     XORI32 = 0x1c,
11828     JALS32 = 0x1d,
11829     ADDIUPC = 0x1e,
11830 
11831     /* 0x20 is reserved */
11832     RES_20 = 0x20,
11833     POOL16F = 0x21,
11834     SB16 = 0x22,
11835     BEQZ16 = 0x23,
11836     SLTI32 = 0x24,
11837     BEQ32 = 0x25,
11838     SWC132 = 0x26,
11839     LWC132 = 0x27,
11840 
11841     /* 0x28 and 0x29 are reserved */
11842     RES_28 = 0x28,
11843     RES_29 = 0x29,
11844     SH16 = 0x2a,
11845     BNEZ16 = 0x2b,
11846     SLTIU32 = 0x2c,
11847     BNE32 = 0x2d,
11848     SDC132 = 0x2e,
11849     LDC132 = 0x2f,
11850 
11851     /* 0x30 and 0x31 are reserved */
11852     RES_30 = 0x30,
11853     RES_31 = 0x31,
11854     SWSP16 = 0x32,
11855     B16 = 0x33,
11856     ANDI32 = 0x34,
11857     J32 = 0x35,
11858     SD32 = 0x36, /* MIPS64 */
11859     LD32 = 0x37, /* MIPS64 */
11860 
11861     /* 0x38 and 0x39 are reserved */
11862     RES_38 = 0x38,
11863     RES_39 = 0x39,
11864     SW16 = 0x3a,
11865     LI16 = 0x3b,
11866     JALX32 = 0x3c,
11867     JAL32 = 0x3d,
11868     SW32 = 0x3e,
11869     LW32 = 0x3f
11870 };
11871 
11872 /* POOL32A encoding of minor opcode field */
11873 
11874 enum {
11875     /* These opcodes are distinguished only by bits 9..6; those bits are
11876      * what are recorded below. */
11877     SLL32 = 0x0,
11878     SRL32 = 0x1,
11879     SRA = 0x2,
11880     ROTR = 0x3,
11881 
11882     SLLV = 0x0,
11883     SRLV = 0x1,
11884     SRAV = 0x2,
11885     ROTRV = 0x3,
11886     ADD = 0x4,
11887     ADDU32 = 0x5,
11888     SUB = 0x6,
11889     SUBU32 = 0x7,
11890     MUL = 0x8,
11891     AND = 0x9,
11892     OR32 = 0xa,
11893     NOR = 0xb,
11894     XOR32 = 0xc,
11895     SLT = 0xd,
11896     SLTU = 0xe,
11897 
11898     MOVN = 0x0,
11899     MOVZ = 0x1,
11900     LWXS = 0x4,
11901 
11902     /* The following can be distinguished by their lower 6 bits. */
11903     INS = 0x0c,
11904     EXT = 0x2c,
11905     POOL32AXF = 0x3c
11906 };
11907 
11908 /* POOL32AXF encoding of minor opcode field extension */
11909 
11910 /*
11911  * 1. MIPS Architecture for Programmers Volume II-B:
11912  *      The microMIPS32 Instruction Set (Revision 3.05)
11913  *
11914  *    Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
11915  *
11916  * 2. MIPS Architecture for Programmers VolumeIV-e:
11917  *      The MIPS DSP Application-Specific Extension
11918  *        to the microMIPS32 Architecture (Revision 2.34)
11919  *
11920  *    Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
11921  */
11922 
11923 enum {
11924     /* bits 11..6 */
11925     TEQ = 0x00,
11926     TGE = 0x08,
11927     TGEU = 0x10,
11928     TLT = 0x20,
11929     TLTU = 0x28,
11930     TNE = 0x30,
11931 
11932     MFC0 = 0x03,
11933     MTC0 = 0x0b,
11934 
11935     /* begin of microMIPS32 DSP */
11936 
11937     /* bits 13..12 for 0x01 */
11938     MFHI_ACC = 0x0,
11939     MFLO_ACC = 0x1,
11940     MTHI_ACC = 0x2,
11941     MTLO_ACC = 0x3,
11942 
11943     /* bits 13..12 for 0x2a */
11944     MADD_ACC = 0x0,
11945     MADDU_ACC = 0x1,
11946     MSUB_ACC = 0x2,
11947     MSUBU_ACC = 0x3,
11948 
11949     /* bits 13..12 for 0x32 */
11950     MULT_ACC = 0x0,
11951     MULTU_ACC = 0x1,
11952 
11953     /* end of microMIPS32 DSP */
11954 
11955     /* bits 15..12 for 0x2c */
11956     SEB = 0x2,
11957     SEH = 0x3,
11958     CLO = 0x4,
11959     CLZ = 0x5,
11960     RDHWR = 0x6,
11961     WSBH = 0x7,
11962     MULT = 0x8,
11963     MULTU = 0x9,
11964     DIV = 0xa,
11965     DIVU = 0xb,
11966     MADD = 0xc,
11967     MADDU = 0xd,
11968     MSUB = 0xe,
11969     MSUBU = 0xf,
11970 
11971     /* bits 15..12 for 0x34 */
11972     MFC2 = 0x4,
11973     MTC2 = 0x5,
11974     MFHC2 = 0x8,
11975     MTHC2 = 0x9,
11976     CFC2 = 0xc,
11977     CTC2 = 0xd,
11978 
11979     /* bits 15..12 for 0x3c */
11980     JALR = 0x0,
11981     JR = 0x0,                   /* alias */
11982     JALR_HB = 0x1,
11983     JALRS = 0x4,
11984     JALRS_HB = 0x5,
11985 
11986     /* bits 15..12 for 0x05 */
11987     RDPGPR = 0xe,
11988     WRPGPR = 0xf,
11989 
11990     /* bits 15..12 for 0x0d */
11991     TLBP = 0x0,
11992     TLBR = 0x1,
11993     TLBWI = 0x2,
11994     TLBWR = 0x3,
11995     WAIT = 0x9,
11996     IRET = 0xd,
11997     DERET = 0xe,
11998     ERET = 0xf,
11999 
12000     /* bits 15..12 for 0x15 */
12001     DMT = 0x0,
12002     DVPE = 0x1,
12003     EMT = 0x2,
12004     EVPE = 0x3,
12005 
12006     /* bits 15..12 for 0x1d */
12007     DI = 0x4,
12008     EI = 0x5,
12009 
12010     /* bits 15..12 for 0x2d */
12011     SYNC = 0x6,
12012     SYSCALL = 0x8,
12013     SDBBP = 0xd,
12014 
12015     /* bits 15..12 for 0x35 */
12016     MFHI32 = 0x0,
12017     MFLO32 = 0x1,
12018     MTHI32 = 0x2,
12019     MTLO32 = 0x3,
12020 };
12021 
12022 /* POOL32B encoding of minor opcode field (bits 15..12) */
12023 
12024 enum {
12025     LWC2 = 0x0,
12026     LWP = 0x1,
12027     LDP = 0x4,
12028     LWM32 = 0x5,
12029     CACHE = 0x6,
12030     LDM = 0x7,
12031     SWC2 = 0x8,
12032     SWP = 0x9,
12033     SDP = 0xc,
12034     SWM32 = 0xd,
12035     SDM = 0xf
12036 };
12037 
12038 /* POOL32C encoding of minor opcode field (bits 15..12) */
12039 
12040 enum {
12041     LWL = 0x0,
12042     SWL = 0x8,
12043     LWR = 0x1,
12044     SWR = 0x9,
12045     PREF = 0x2,
12046     /* 0xa is reserved */
12047     LL = 0x3,
12048     SC = 0xb,
12049     LDL = 0x4,
12050     SDL = 0xc,
12051     LDR = 0x5,
12052     SDR = 0xd,
12053     /* 0x6 is reserved */
12054     LWU = 0xe,
12055     LLD = 0x7,
12056     SCD = 0xf
12057 };
12058 
12059 /* POOL32F encoding of minor opcode field (bits 5..0) */
12060 
12061 enum {
12062     /* These are the bit 7..6 values */
12063     ADD_FMT = 0x0,
12064     MOVN_FMT = 0x0,
12065 
12066     SUB_FMT = 0x1,
12067     MOVZ_FMT = 0x1,
12068 
12069     MUL_FMT = 0x2,
12070 
12071     DIV_FMT = 0x3,
12072 
12073     /* These are the bit 8..6 values */
12074     RSQRT2_FMT = 0x0,
12075     MOVF_FMT = 0x0,
12076 
12077     LWXC1 = 0x1,
12078     MOVT_FMT = 0x1,
12079 
12080     PLL_PS = 0x2,
12081     SWXC1 = 0x2,
12082 
12083     PLU_PS = 0x3,
12084     LDXC1 = 0x3,
12085 
12086     PUL_PS = 0x4,
12087     SDXC1 = 0x4,
12088     RECIP2_FMT = 0x4,
12089 
12090     PUU_PS = 0x5,
12091     LUXC1 = 0x5,
12092 
12093     CVT_PS_S = 0x6,
12094     SUXC1 = 0x6,
12095     ADDR_PS = 0x6,
12096     PREFX = 0x6,
12097 
12098     MULR_PS = 0x7,
12099 
12100     MADD_S = 0x01,
12101     MADD_D = 0x09,
12102     MADD_PS = 0x11,
12103     ALNV_PS = 0x19,
12104     MSUB_S = 0x21,
12105     MSUB_D = 0x29,
12106     MSUB_PS = 0x31,
12107 
12108     NMADD_S = 0x02,
12109     NMADD_D = 0x0a,
12110     NMADD_PS = 0x12,
12111     NMSUB_S = 0x22,
12112     NMSUB_D = 0x2a,
12113     NMSUB_PS = 0x32,
12114 
12115     POOL32FXF = 0x3b,
12116 
12117     CABS_COND_FMT = 0x1c,              /* MIPS3D */
12118     C_COND_FMT = 0x3c
12119 };
12120 
12121 /* POOL32Fxf encoding of minor opcode extension field */
12122 
12123 enum {
12124     CVT_L = 0x04,
12125     RSQRT_FMT = 0x08,
12126     FLOOR_L = 0x0c,
12127     CVT_PW_PS = 0x1c,
12128     CVT_W = 0x24,
12129     SQRT_FMT = 0x28,
12130     FLOOR_W = 0x2c,
12131     CVT_PS_PW = 0x3c,
12132     CFC1 = 0x40,
12133     RECIP_FMT = 0x48,
12134     CEIL_L = 0x4c,
12135     CTC1 = 0x60,
12136     CEIL_W = 0x6c,
12137     MFC1 = 0x80,
12138     CVT_S_PL = 0x84,
12139     TRUNC_L = 0x8c,
12140     MTC1 = 0xa0,
12141     CVT_S_PU = 0xa4,
12142     TRUNC_W = 0xac,
12143     MFHC1 = 0xc0,
12144     ROUND_L = 0xcc,
12145     MTHC1 = 0xe0,
12146     ROUND_W = 0xec,
12147 
12148     MOV_FMT = 0x01,
12149     MOVF = 0x05,
12150     ABS_FMT = 0x0d,
12151     RSQRT1_FMT = 0x1d,
12152     MOVT = 0x25,
12153     NEG_FMT = 0x2d,
12154     CVT_D = 0x4d,
12155     RECIP1_FMT = 0x5d,
12156     CVT_S = 0x6d
12157 };
12158 
12159 /* POOL32I encoding of minor opcode field (bits 25..21) */
12160 
12161 enum {
12162     BLTZ = 0x00,
12163     BLTZAL = 0x01,
12164     BGEZ = 0x02,
12165     BGEZAL = 0x03,
12166     BLEZ = 0x04,
12167     BNEZC = 0x05,
12168     BGTZ = 0x06,
12169     BEQZC = 0x07,
12170     TLTI = 0x08,
12171     TGEI = 0x09,
12172     TLTIU = 0x0a,
12173     TGEIU = 0x0b,
12174     TNEI = 0x0c,
12175     LUI = 0x0d,
12176     TEQI = 0x0e,
12177     SYNCI = 0x10,
12178     BLTZALS = 0x11,
12179     BGEZALS = 0x13,
12180     BC2F = 0x14,
12181     BC2T = 0x15,
12182     BPOSGE64 = 0x1a,
12183     BPOSGE32 = 0x1b,
12184     /* These overlap and are distinguished by bit16 of the instruction */
12185     BC1F = 0x1c,
12186     BC1T = 0x1d,
12187     BC1ANY2F = 0x1c,
12188     BC1ANY2T = 0x1d,
12189     BC1ANY4F = 0x1e,
12190     BC1ANY4T = 0x1f
12191 };
12192 
12193 /* POOL16A encoding of minor opcode field */
12194 
12195 enum {
12196     ADDU16 = 0x0,
12197     SUBU16 = 0x1
12198 };
12199 
12200 /* POOL16B encoding of minor opcode field */
12201 
12202 enum {
12203     SLL16 = 0x0,
12204     SRL16 = 0x1
12205 };
12206 
12207 /* POOL16C encoding of minor opcode field */
12208 
12209 enum {
12210     NOT16 = 0x00,
12211     XOR16 = 0x04,
12212     AND16 = 0x08,
12213     OR16 = 0x0c,
12214     LWM16 = 0x10,
12215     SWM16 = 0x14,
12216     JR16 = 0x18,
12217     JRC16 = 0x1a,
12218     JALR16 = 0x1c,
12219     JALR16S = 0x1e,
12220     MFHI16 = 0x20,
12221     MFLO16 = 0x24,
12222     BREAK16 = 0x28,
12223     SDBBP16 = 0x2c,
12224     JRADDIUSP = 0x30
12225 };
12226 
12227 /* POOL16D encoding of minor opcode field */
12228 
12229 enum {
12230     ADDIUS5 = 0x0,
12231     ADDIUSP = 0x1
12232 };
12233 
12234 /* POOL16E encoding of minor opcode field */
12235 
12236 enum {
12237     ADDIUR2 = 0x0,
12238     ADDIUR1SP = 0x1
12239 };
12240 
mmreg(int r)12241 static int mmreg (int r)
12242 {
12243     static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12244 
12245     return map[r];
12246 }
12247 
12248 /* Used for 16-bit store instructions.  */
mmreg2(int r)12249 static int mmreg2 (int r)
12250 {
12251     static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
12252 
12253     return map[r];
12254 }
12255 
12256 #define uMIPS_RD(op) ((op >> 7) & 0x7)
12257 #define uMIPS_RS(op) ((op >> 4) & 0x7)
12258 #define uMIPS_RS2(op) uMIPS_RS(op)
12259 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
12260 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
12261 #define uMIPS_RS5(op) (op & 0x1f)
12262 
12263 /* Signed immediate */
12264 #define SIMM(op, start, width)                                          \
12265     ((int32_t)(((op >> start) & ((~0U) >> (32-width)))                 \
12266                << (32-width))                                           \
12267      >> (32-width))
12268 /* Zero-extended immediate */
12269 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
12270 
gen_addiur1sp(DisasContext * ctx)12271 static void gen_addiur1sp(DisasContext *ctx)
12272 {
12273     int rd = mmreg(uMIPS_RD(ctx->opcode));
12274 
12275     gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
12276 }
12277 
gen_addiur2(DisasContext * ctx)12278 static void gen_addiur2(DisasContext *ctx)
12279 {
12280     static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
12281     int rd = mmreg(uMIPS_RD(ctx->opcode));
12282     int rs = mmreg(uMIPS_RS(ctx->opcode));
12283 
12284     gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
12285 }
12286 
gen_addiusp(DisasContext * ctx)12287 static void gen_addiusp(DisasContext *ctx)
12288 {
12289     int encoded = ZIMM(ctx->opcode, 1, 9);
12290     int decoded;
12291 
12292     if (encoded <= 1) {
12293         decoded = 256 + encoded;
12294     } else if (encoded <= 255) {
12295         decoded = encoded;
12296     } else if (encoded <= 509) {
12297         decoded = encoded - 512;
12298     } else {
12299         decoded = encoded - 768;
12300     }
12301 
12302     gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
12303 }
12304 
gen_addius5(DisasContext * ctx)12305 static void gen_addius5(DisasContext *ctx)
12306 {
12307     int imm = SIMM(ctx->opcode, 1, 4);
12308     int rd = (ctx->opcode >> 5) & 0x1f;
12309 
12310     gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
12311 }
12312 
gen_andi16(DisasContext * ctx)12313 static void gen_andi16(DisasContext *ctx)
12314 {
12315     static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
12316                                  31, 32, 63, 64, 255, 32768, 65535 };
12317     int rd = mmreg(uMIPS_RD(ctx->opcode));
12318     int rs = mmreg(uMIPS_RS(ctx->opcode));
12319     int encoded = ZIMM(ctx->opcode, 0, 4);
12320 
12321     gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
12322 }
12323 
gen_ldst_multiple(DisasContext * ctx,uint32_t opc,int reglist,int base,int16_t offset)12324 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
12325                                int base, int16_t offset)
12326 {
12327     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
12328     const char *opn = "ldst_multiple";
12329     TCGv t0, t1;
12330     TCGv_i32 t2;
12331 
12332     if (ctx->hflags & MIPS_HFLAG_BMASK) {
12333         generate_exception(ctx, EXCP_RI);
12334         return;
12335     }
12336 
12337     t0 = tcg_temp_new(tcg_ctx);
12338 
12339     gen_base_offset_addr(ctx, t0, base, offset);
12340 
12341     t1 = tcg_const_tl(tcg_ctx, reglist);
12342     t2 = tcg_const_i32(tcg_ctx, ctx->mem_idx);
12343 
12344     save_cpu_state(ctx, 1);
12345     switch (opc) {
12346     case LWM32:
12347         gen_helper_lwm(tcg_ctx, tcg_ctx->cpu_env, t0, t1, t2);
12348         opn = "lwm";
12349         break;
12350     case SWM32:
12351         gen_helper_swm(tcg_ctx, tcg_ctx->cpu_env, t0, t1, t2);
12352         opn = "swm";
12353         break;
12354 #ifdef TARGET_MIPS64
12355     case LDM:
12356         gen_helper_ldm(tcg_ctx, tcg_ctx->cpu_env, t0, t1, t2);
12357         opn = "ldm";
12358         break;
12359     case SDM:
12360         gen_helper_sdm(tcg_ctx, tcg_ctx->cpu_env, t0, t1, t2);
12361         opn = "sdm";
12362         break;
12363 #endif
12364     }
12365     (void)opn;
12366     MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
12367     tcg_temp_free(tcg_ctx, t0);
12368     tcg_temp_free(tcg_ctx, t1);
12369     tcg_temp_free_i32(tcg_ctx, t2);
12370 }
12371 
12372 
gen_pool16c_insn(DisasContext * ctx)12373 static void gen_pool16c_insn(DisasContext *ctx)
12374 {
12375     int rd = mmreg((ctx->opcode >> 3) & 0x7);
12376     int rs = mmreg(ctx->opcode & 0x7);
12377 
12378     switch (((ctx->opcode) >> 4) & 0x3f) {
12379     case NOT16 + 0:
12380     case NOT16 + 1:
12381     case NOT16 + 2:
12382     case NOT16 + 3:
12383         gen_logic(ctx, OPC_NOR, rd, rs, 0);
12384         break;
12385     case XOR16 + 0:
12386     case XOR16 + 1:
12387     case XOR16 + 2:
12388     case XOR16 + 3:
12389         gen_logic(ctx, OPC_XOR, rd, rd, rs);
12390         break;
12391     case AND16 + 0:
12392     case AND16 + 1:
12393     case AND16 + 2:
12394     case AND16 + 3:
12395         gen_logic(ctx, OPC_AND, rd, rd, rs);
12396         break;
12397     case OR16 + 0:
12398     case OR16 + 1:
12399     case OR16 + 2:
12400     case OR16 + 3:
12401         gen_logic(ctx, OPC_OR, rd, rd, rs);
12402         break;
12403     case LWM16 + 0:
12404     case LWM16 + 1:
12405     case LWM16 + 2:
12406     case LWM16 + 3:
12407         {
12408             static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12409             int offset = ZIMM(ctx->opcode, 0, 4);
12410 
12411             gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
12412                               29, offset << 2);
12413         }
12414         break;
12415     case SWM16 + 0:
12416     case SWM16 + 1:
12417     case SWM16 + 2:
12418     case SWM16 + 3:
12419         {
12420             static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12421             int offset = ZIMM(ctx->opcode, 0, 4);
12422 
12423             gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
12424                               29, offset << 2);
12425         }
12426         break;
12427     case JR16 + 0:
12428     case JR16 + 1:
12429         {
12430             int reg = ctx->opcode & 0x1f;
12431 
12432             gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
12433         }
12434         break;
12435     case JRC16 + 0:
12436     case JRC16 + 1:
12437         {
12438             int reg = ctx->opcode & 0x1f;
12439             gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
12440             /* Let normal delay slot handling in our caller take us
12441                to the branch target.  */
12442         }
12443         break;
12444     case JALR16 + 0:
12445     case JALR16 + 1:
12446         gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
12447         ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
12448         break;
12449     case JALR16S + 0:
12450     case JALR16S + 1:
12451         gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
12452         ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
12453         break;
12454     case MFHI16 + 0:
12455     case MFHI16 + 1:
12456         gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
12457         break;
12458     case MFLO16 + 0:
12459     case MFLO16 + 1:
12460         gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
12461         break;
12462     case BREAK16:
12463         generate_exception(ctx, EXCP_BREAK);
12464         break;
12465     case SDBBP16:
12466         /* XXX: not clear which exception should be raised
12467          *      when in debug mode...
12468          */
12469         check_insn(ctx, ISA_MIPS32);
12470         if (!(ctx->hflags & MIPS_HFLAG_DM)) {
12471             generate_exception(ctx, EXCP_DBp);
12472         } else {
12473             generate_exception(ctx, EXCP_DBp);
12474         }
12475         break;
12476     case JRADDIUSP + 0:
12477     case JRADDIUSP + 1:
12478         {
12479             int imm = ZIMM(ctx->opcode, 0, 5);
12480             gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
12481             gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
12482             /* Let normal delay slot handling in our caller take us
12483                to the branch target.  */
12484         }
12485         break;
12486     default:
12487         generate_exception(ctx, EXCP_RI);
12488         break;
12489     }
12490 }
12491 
gen_ldxs(DisasContext * ctx,int base,int index,int rd)12492 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
12493 {
12494     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
12495     TCGv t0 = tcg_temp_new(tcg_ctx);
12496     TCGv t1 = tcg_temp_new(tcg_ctx);
12497 
12498     gen_load_gpr(ctx, t0, base);
12499 
12500     if (index != 0) {
12501         gen_load_gpr(ctx, t1, index);
12502         tcg_gen_shli_tl(tcg_ctx, t1, t1, 2);
12503         gen_op_addr_add(ctx, t0, t1, t0);
12504     }
12505 
12506     tcg_gen_qemu_ld_tl(ctx->uc, t1, t0, ctx->mem_idx, MO_TESL);
12507     gen_store_gpr(tcg_ctx, t1, rd);
12508 
12509     tcg_temp_free(tcg_ctx, t0);
12510     tcg_temp_free(tcg_ctx, t1);
12511 }
12512 
gen_ldst_pair(DisasContext * ctx,uint32_t opc,int rd,int base,int16_t offset)12513 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
12514                            int base, int16_t offset)
12515 {
12516     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
12517     const char *opn = "ldst_pair";
12518     TCGv t0, t1;
12519 
12520     if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
12521         generate_exception(ctx, EXCP_RI);
12522         return;
12523     }
12524 
12525     t0 = tcg_temp_new(tcg_ctx);
12526     t1 = tcg_temp_new(tcg_ctx);
12527 
12528     gen_base_offset_addr(ctx, t0, base, offset);
12529 
12530     switch (opc) {
12531     case LWP:
12532         if (rd == base) {
12533             generate_exception(ctx, EXCP_RI);
12534             return;
12535         }
12536         tcg_gen_qemu_ld_tl(ctx->uc, t1, t0, ctx->mem_idx, MO_TESL);
12537         gen_store_gpr(tcg_ctx, t1, rd);
12538         tcg_gen_movi_tl(tcg_ctx, t1, 4);
12539         gen_op_addr_add(ctx, t0, t0, t1);
12540         tcg_gen_qemu_ld_tl(ctx->uc, t1, t0, ctx->mem_idx, MO_TESL);
12541         gen_store_gpr(tcg_ctx, t1, rd+1);
12542         opn = "lwp";
12543         break;
12544     case SWP:
12545         gen_load_gpr(ctx, t1, rd);
12546         tcg_gen_qemu_st_tl(ctx->uc, t1, t0, ctx->mem_idx, MO_TEUL);
12547         tcg_gen_movi_tl(tcg_ctx, t1, 4);
12548         gen_op_addr_add(ctx, t0, t0, t1);
12549         gen_load_gpr(ctx, t1, rd+1);
12550         tcg_gen_qemu_st_tl(ctx->uc, t1, t0, ctx->mem_idx, MO_TEUL);
12551         opn = "swp";
12552         break;
12553 #ifdef TARGET_MIPS64
12554     case LDP:
12555         if (rd == base) {
12556             generate_exception(ctx, EXCP_RI);
12557             return;
12558         }
12559         tcg_gen_qemu_ld_tl(ctx->uc, t1, t0, ctx->mem_idx, MO_TEQ);
12560         gen_store_gpr(tcg_ctx, t1, rd);
12561         tcg_gen_movi_tl(tcg_ctx, t1, 8);
12562         gen_op_addr_add(ctx, t0, t0, t1);
12563         tcg_gen_qemu_ld_tl(ctx->uc, t1, t0, ctx->mem_idx, MO_TEQ);
12564         gen_store_gpr(tcg_ctx, t1, rd+1);
12565         opn = "ldp";
12566         break;
12567     case SDP:
12568         gen_load_gpr(ctx, t1, rd);
12569         tcg_gen_qemu_st_tl(ctx->uc, t1, t0, ctx->mem_idx, MO_TEQ);
12570         tcg_gen_movi_tl(tcg_ctx, t1, 8);
12571         gen_op_addr_add(ctx, t0, t0, t1);
12572         gen_load_gpr(ctx, t1, rd+1);
12573         tcg_gen_qemu_st_tl(ctx->uc, t1, t0, ctx->mem_idx, MO_TEQ);
12574         opn = "sdp";
12575         break;
12576 #endif
12577     }
12578     (void)opn; /* avoid a compiler warning */
12579     MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
12580     tcg_temp_free(tcg_ctx, t0);
12581     tcg_temp_free(tcg_ctx, t1);
12582 }
12583 
gen_pool32axf(CPUMIPSState * env,DisasContext * ctx,int rt,int rs)12584 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
12585 {
12586     TCGContext *tcg_ctx = env->uc->tcg_ctx;
12587     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
12588     int extension = (ctx->opcode >> 6) & 0x3f;
12589     int minor = (ctx->opcode >> 12) & 0xf;
12590     uint32_t mips32_op;
12591 
12592     switch (extension) {
12593     case TEQ:
12594         mips32_op = OPC_TEQ;
12595         goto do_trap;
12596     case TGE:
12597         mips32_op = OPC_TGE;
12598         goto do_trap;
12599     case TGEU:
12600         mips32_op = OPC_TGEU;
12601         goto do_trap;
12602     case TLT:
12603         mips32_op = OPC_TLT;
12604         goto do_trap;
12605     case TLTU:
12606         mips32_op = OPC_TLTU;
12607         goto do_trap;
12608     case TNE:
12609         mips32_op = OPC_TNE;
12610     do_trap:
12611         gen_trap(ctx, mips32_op, rs, rt, -1);
12612         break;
12613 #ifndef CONFIG_USER_ONLY
12614     case MFC0:
12615     case MFC0 + 32:
12616         check_cp0_enabled(ctx);
12617         if (rt == 0) {
12618             /* Treat as NOP. */
12619             break;
12620         }
12621         gen_mfc0(ctx, *cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
12622         break;
12623     case MTC0:
12624     case MTC0 + 32:
12625         check_cp0_enabled(ctx);
12626         {
12627             TCGv t0 = tcg_temp_new(tcg_ctx);
12628 
12629             gen_load_gpr(ctx, t0, rt);
12630             gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
12631             tcg_temp_free(tcg_ctx, t0);
12632         }
12633         break;
12634 #endif
12635     case 0x2a:
12636         switch (minor & 3) {
12637         case MADD_ACC:
12638             gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
12639             break;
12640         case MADDU_ACC:
12641             gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
12642             break;
12643         case MSUB_ACC:
12644             gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
12645             break;
12646         case MSUBU_ACC:
12647             gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
12648             break;
12649         default:
12650             goto pool32axf_invalid;
12651         }
12652         break;
12653     case 0x32:
12654         switch (minor & 3) {
12655         case MULT_ACC:
12656             gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
12657             break;
12658         case MULTU_ACC:
12659             gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
12660             break;
12661         default:
12662             goto pool32axf_invalid;
12663         }
12664         break;
12665     case 0x2c:
12666         switch (minor) {
12667         case SEB:
12668             gen_bshfl(ctx, OPC_SEB, rs, rt);
12669             break;
12670         case SEH:
12671             gen_bshfl(ctx, OPC_SEH, rs, rt);
12672             break;
12673         case CLO:
12674             mips32_op = OPC_CLO;
12675             goto do_cl;
12676         case CLZ:
12677             mips32_op = OPC_CLZ;
12678         do_cl:
12679             check_insn(ctx, ISA_MIPS32);
12680             gen_cl(ctx, mips32_op, rt, rs);
12681             break;
12682         case RDHWR:
12683             gen_rdhwr(ctx, rt, rs);
12684             break;
12685         case WSBH:
12686             gen_bshfl(ctx, OPC_WSBH, rs, rt);
12687             break;
12688         case MULT:
12689             mips32_op = OPC_MULT;
12690             goto do_mul;
12691         case MULTU:
12692             mips32_op = OPC_MULTU;
12693             goto do_mul;
12694         case DIV:
12695             mips32_op = OPC_DIV;
12696             goto do_div;
12697         case DIVU:
12698             mips32_op = OPC_DIVU;
12699             goto do_div;
12700         do_div:
12701             check_insn(ctx, ISA_MIPS32);
12702             gen_muldiv(ctx, mips32_op, 0, rs, rt);
12703             break;
12704         case MADD:
12705             mips32_op = OPC_MADD;
12706             goto do_mul;
12707         case MADDU:
12708             mips32_op = OPC_MADDU;
12709             goto do_mul;
12710         case MSUB:
12711             mips32_op = OPC_MSUB;
12712             goto do_mul;
12713         case MSUBU:
12714             mips32_op = OPC_MSUBU;
12715         do_mul:
12716             check_insn(ctx, ISA_MIPS32);
12717             gen_muldiv(ctx, mips32_op, 0, rs, rt);
12718             break;
12719         default:
12720             goto pool32axf_invalid;
12721         }
12722         break;
12723     case 0x34:
12724         switch (minor) {
12725         case MFC2:
12726         case MTC2:
12727         case MFHC2:
12728         case MTHC2:
12729         case CFC2:
12730         case CTC2:
12731             generate_exception_err(ctx, EXCP_CpU, 2);
12732             break;
12733         default:
12734             goto pool32axf_invalid;
12735         }
12736         break;
12737     case 0x3c:
12738         switch (minor) {
12739         case JALR:
12740         case JALR_HB:
12741             gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
12742             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
12743             break;
12744         case JALRS:
12745         case JALRS_HB:
12746             gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
12747             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
12748             break;
12749         default:
12750             goto pool32axf_invalid;
12751         }
12752         break;
12753     case 0x05:
12754         switch (minor) {
12755         case RDPGPR:
12756             check_cp0_enabled(ctx);
12757             check_insn(ctx, ISA_MIPS32R2);
12758             gen_load_srsgpr(ctx, rt, rs);
12759             break;
12760         case WRPGPR:
12761             check_cp0_enabled(ctx);
12762             check_insn(ctx, ISA_MIPS32R2);
12763             gen_store_srsgpr(ctx, rt, rs);
12764             break;
12765         default:
12766             goto pool32axf_invalid;
12767         }
12768         break;
12769 #ifndef CONFIG_USER_ONLY
12770     case 0x0d:
12771         switch (minor) {
12772         case TLBP:
12773             mips32_op = OPC_TLBP;
12774             goto do_cp0;
12775         case TLBR:
12776             mips32_op = OPC_TLBR;
12777             goto do_cp0;
12778         case TLBWI:
12779             mips32_op = OPC_TLBWI;
12780             goto do_cp0;
12781         case TLBWR:
12782             mips32_op = OPC_TLBWR;
12783             goto do_cp0;
12784         case WAIT:
12785             mips32_op = OPC_WAIT;
12786             goto do_cp0;
12787         case DERET:
12788             mips32_op = OPC_DERET;
12789             goto do_cp0;
12790         case ERET:
12791             mips32_op = OPC_ERET;
12792         do_cp0:
12793             gen_cp0(env, ctx, mips32_op, rt, rs);
12794             break;
12795         default:
12796             goto pool32axf_invalid;
12797         }
12798         break;
12799     case 0x1d:
12800         switch (minor) {
12801         case DI:
12802             check_cp0_enabled(ctx);
12803             {
12804                 TCGv t0 = tcg_temp_new(tcg_ctx);
12805 
12806                 save_cpu_state(ctx, 1);
12807                 gen_helper_di(tcg_ctx, t0, tcg_ctx->cpu_env);
12808                 gen_store_gpr(tcg_ctx, t0, rs);
12809                 /* Stop translation as we may have switched the execution mode */
12810                 ctx->bstate = BS_STOP;
12811                 tcg_temp_free(tcg_ctx, t0);
12812             }
12813             break;
12814         case EI:
12815             check_cp0_enabled(ctx);
12816             {
12817                 TCGv t0 = tcg_temp_new(tcg_ctx);
12818 
12819                 save_cpu_state(ctx, 1);
12820                 gen_helper_ei(tcg_ctx, t0, tcg_ctx->cpu_env);
12821                 gen_store_gpr(tcg_ctx, t0, rs);
12822                 /* Stop translation as we may have switched the execution mode */
12823                 ctx->bstate = BS_STOP;
12824                 tcg_temp_free(tcg_ctx, t0);
12825             }
12826             break;
12827         default:
12828             goto pool32axf_invalid;
12829         }
12830         break;
12831 #endif
12832     case 0x2d:
12833         switch (minor) {
12834         case SYNC:
12835             /* NOP */
12836             break;
12837         case SYSCALL:
12838             generate_exception(ctx, EXCP_SYSCALL);
12839             ctx->bstate = BS_STOP;
12840             break;
12841         case SDBBP:
12842             check_insn(ctx, ISA_MIPS32);
12843             if (!(ctx->hflags & MIPS_HFLAG_DM)) {
12844                 generate_exception(ctx, EXCP_DBp);
12845             } else {
12846                 generate_exception(ctx, EXCP_DBp);
12847             }
12848             break;
12849         default:
12850             goto pool32axf_invalid;
12851         }
12852         break;
12853     case 0x01:
12854         switch (minor & 3) {
12855         case MFHI_ACC:
12856             gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
12857             break;
12858         case MFLO_ACC:
12859             gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
12860             break;
12861         case MTHI_ACC:
12862             gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
12863             break;
12864         case MTLO_ACC:
12865             gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
12866             break;
12867         default:
12868             goto pool32axf_invalid;
12869         }
12870         break;
12871     case 0x35:
12872         switch (minor) {
12873         case MFHI32:
12874             gen_HILO(ctx, OPC_MFHI, 0, rs);
12875             break;
12876         case MFLO32:
12877             gen_HILO(ctx, OPC_MFLO, 0, rs);
12878             break;
12879         case MTHI32:
12880             gen_HILO(ctx, OPC_MTHI, 0, rs);
12881             break;
12882         case MTLO32:
12883             gen_HILO(ctx, OPC_MTLO, 0, rs);
12884             break;
12885         default:
12886             goto pool32axf_invalid;
12887         }
12888         break;
12889     default:
12890     pool32axf_invalid:
12891         MIPS_INVAL("pool32axf");
12892         generate_exception(ctx, EXCP_RI);
12893         break;
12894     }
12895 }
12896 
12897 /* Values for microMIPS fmt field.  Variable-width, depending on which
12898    formats the instruction supports.  */
12899 
12900 enum {
12901     FMT_SD_S = 0,
12902     FMT_SD_D = 1,
12903 
12904     FMT_SDPS_S = 0,
12905     FMT_SDPS_D = 1,
12906     FMT_SDPS_PS = 2,
12907 
12908     FMT_SWL_S = 0,
12909     FMT_SWL_W = 1,
12910     FMT_SWL_L = 2,
12911 
12912     FMT_DWL_D = 0,
12913     FMT_DWL_W = 1,
12914     FMT_DWL_L = 2
12915 };
12916 
gen_pool32fxf(DisasContext * ctx,int rt,int rs)12917 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
12918 {
12919     int extension = (ctx->opcode >> 6) & 0x3ff;
12920     uint32_t mips32_op;
12921 
12922 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
12923 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
12924 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
12925 
12926     switch (extension) {
12927     case FLOAT_1BIT_FMT(CFC1, 0):
12928         mips32_op = OPC_CFC1;
12929         goto do_cp1;
12930     case FLOAT_1BIT_FMT(CTC1, 0):
12931         mips32_op = OPC_CTC1;
12932         goto do_cp1;
12933     case FLOAT_1BIT_FMT(MFC1, 0):
12934         mips32_op = OPC_MFC1;
12935         goto do_cp1;
12936     case FLOAT_1BIT_FMT(MTC1, 0):
12937         mips32_op = OPC_MTC1;
12938         goto do_cp1;
12939     case FLOAT_1BIT_FMT(MFHC1, 0):
12940         mips32_op = OPC_MFHC1;
12941         goto do_cp1;
12942     case FLOAT_1BIT_FMT(MTHC1, 0):
12943         mips32_op = OPC_MTHC1;
12944     do_cp1:
12945         gen_cp1(ctx, mips32_op, rt, rs);
12946         break;
12947 
12948         /* Reciprocal square root */
12949     case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
12950         mips32_op = OPC_RSQRT_S;
12951         goto do_unaryfp;
12952     case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
12953         mips32_op = OPC_RSQRT_D;
12954         goto do_unaryfp;
12955 
12956         /* Square root */
12957     case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
12958         mips32_op = OPC_SQRT_S;
12959         goto do_unaryfp;
12960     case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
12961         mips32_op = OPC_SQRT_D;
12962         goto do_unaryfp;
12963 
12964         /* Reciprocal */
12965     case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
12966         mips32_op = OPC_RECIP_S;
12967         goto do_unaryfp;
12968     case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
12969         mips32_op = OPC_RECIP_D;
12970         goto do_unaryfp;
12971 
12972         /* Floor */
12973     case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
12974         mips32_op = OPC_FLOOR_L_S;
12975         goto do_unaryfp;
12976     case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
12977         mips32_op = OPC_FLOOR_L_D;
12978         goto do_unaryfp;
12979     case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
12980         mips32_op = OPC_FLOOR_W_S;
12981         goto do_unaryfp;
12982     case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
12983         mips32_op = OPC_FLOOR_W_D;
12984         goto do_unaryfp;
12985 
12986         /* Ceiling */
12987     case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
12988         mips32_op = OPC_CEIL_L_S;
12989         goto do_unaryfp;
12990     case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
12991         mips32_op = OPC_CEIL_L_D;
12992         goto do_unaryfp;
12993     case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
12994         mips32_op = OPC_CEIL_W_S;
12995         goto do_unaryfp;
12996     case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
12997         mips32_op = OPC_CEIL_W_D;
12998         goto do_unaryfp;
12999 
13000         /* Truncation */
13001     case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
13002         mips32_op = OPC_TRUNC_L_S;
13003         goto do_unaryfp;
13004     case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
13005         mips32_op = OPC_TRUNC_L_D;
13006         goto do_unaryfp;
13007     case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
13008         mips32_op = OPC_TRUNC_W_S;
13009         goto do_unaryfp;
13010     case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
13011         mips32_op = OPC_TRUNC_W_D;
13012         goto do_unaryfp;
13013 
13014         /* Round */
13015     case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
13016         mips32_op = OPC_ROUND_L_S;
13017         goto do_unaryfp;
13018     case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
13019         mips32_op = OPC_ROUND_L_D;
13020         goto do_unaryfp;
13021     case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
13022         mips32_op = OPC_ROUND_W_S;
13023         goto do_unaryfp;
13024     case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
13025         mips32_op = OPC_ROUND_W_D;
13026         goto do_unaryfp;
13027 
13028         /* Integer to floating-point conversion */
13029     case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
13030         mips32_op = OPC_CVT_L_S;
13031         goto do_unaryfp;
13032     case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
13033         mips32_op = OPC_CVT_L_D;
13034         goto do_unaryfp;
13035     case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
13036         mips32_op = OPC_CVT_W_S;
13037         goto do_unaryfp;
13038     case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
13039         mips32_op = OPC_CVT_W_D;
13040         goto do_unaryfp;
13041 
13042         /* Paired-foo conversions */
13043     case FLOAT_1BIT_FMT(CVT_S_PL, 0):
13044         mips32_op = OPC_CVT_S_PL;
13045         goto do_unaryfp;
13046     case FLOAT_1BIT_FMT(CVT_S_PU, 0):
13047         mips32_op = OPC_CVT_S_PU;
13048         goto do_unaryfp;
13049     case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
13050         mips32_op = OPC_CVT_PW_PS;
13051         goto do_unaryfp;
13052     case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
13053         mips32_op = OPC_CVT_PS_PW;
13054         goto do_unaryfp;
13055 
13056         /* Floating-point moves */
13057     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
13058         mips32_op = OPC_MOV_S;
13059         goto do_unaryfp;
13060     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
13061         mips32_op = OPC_MOV_D;
13062         goto do_unaryfp;
13063     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
13064         mips32_op = OPC_MOV_PS;
13065         goto do_unaryfp;
13066 
13067         /* Absolute value */
13068     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
13069         mips32_op = OPC_ABS_S;
13070         goto do_unaryfp;
13071     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
13072         mips32_op = OPC_ABS_D;
13073         goto do_unaryfp;
13074     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
13075         mips32_op = OPC_ABS_PS;
13076         goto do_unaryfp;
13077 
13078         /* Negation */
13079     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
13080         mips32_op = OPC_NEG_S;
13081         goto do_unaryfp;
13082     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
13083         mips32_op = OPC_NEG_D;
13084         goto do_unaryfp;
13085     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
13086         mips32_op = OPC_NEG_PS;
13087         goto do_unaryfp;
13088 
13089         /* Reciprocal square root step */
13090     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
13091         mips32_op = OPC_RSQRT1_S;
13092         goto do_unaryfp;
13093     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
13094         mips32_op = OPC_RSQRT1_D;
13095         goto do_unaryfp;
13096     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
13097         mips32_op = OPC_RSQRT1_PS;
13098         goto do_unaryfp;
13099 
13100         /* Reciprocal step */
13101     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
13102         mips32_op = OPC_RECIP1_S;
13103         goto do_unaryfp;
13104     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
13105         mips32_op = OPC_RECIP1_S;
13106         goto do_unaryfp;
13107     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
13108         mips32_op = OPC_RECIP1_PS;
13109         goto do_unaryfp;
13110 
13111         /* Conversions from double */
13112     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
13113         mips32_op = OPC_CVT_D_S;
13114         goto do_unaryfp;
13115     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
13116         mips32_op = OPC_CVT_D_W;
13117         goto do_unaryfp;
13118     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
13119         mips32_op = OPC_CVT_D_L;
13120         goto do_unaryfp;
13121 
13122         /* Conversions from single */
13123     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
13124         mips32_op = OPC_CVT_S_D;
13125         goto do_unaryfp;
13126     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
13127         mips32_op = OPC_CVT_S_W;
13128         goto do_unaryfp;
13129     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
13130         mips32_op = OPC_CVT_S_L;
13131     do_unaryfp:
13132         gen_farith(ctx, mips32_op, -1, rs, rt, 0);
13133         break;
13134 
13135         /* Conditional moves on floating-point codes */
13136     case COND_FLOAT_MOV(MOVT, 0):
13137     case COND_FLOAT_MOV(MOVT, 1):
13138     case COND_FLOAT_MOV(MOVT, 2):
13139     case COND_FLOAT_MOV(MOVT, 3):
13140     case COND_FLOAT_MOV(MOVT, 4):
13141     case COND_FLOAT_MOV(MOVT, 5):
13142     case COND_FLOAT_MOV(MOVT, 6):
13143     case COND_FLOAT_MOV(MOVT, 7):
13144         gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
13145         break;
13146     case COND_FLOAT_MOV(MOVF, 0):
13147     case COND_FLOAT_MOV(MOVF, 1):
13148     case COND_FLOAT_MOV(MOVF, 2):
13149     case COND_FLOAT_MOV(MOVF, 3):
13150     case COND_FLOAT_MOV(MOVF, 4):
13151     case COND_FLOAT_MOV(MOVF, 5):
13152     case COND_FLOAT_MOV(MOVF, 6):
13153     case COND_FLOAT_MOV(MOVF, 7):
13154         gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
13155         break;
13156     default:
13157         MIPS_INVAL("pool32fxf");
13158         generate_exception(ctx, EXCP_RI);
13159         break;
13160     }
13161 }
13162 
decode_micromips32_opc(CPUMIPSState * env,DisasContext * ctx,uint16_t insn_hw1)13163 static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
13164                                     uint16_t insn_hw1)
13165 {
13166     int32_t offset;
13167     uint16_t insn;
13168     int rt, rs, rd, rr;
13169     int16_t imm;
13170     uint32_t op, minor, mips32_op;
13171     uint32_t cond, fmt, cc;
13172 
13173     insn = cpu_lduw_code(env, ctx->pc + 2);
13174     ctx->opcode = (ctx->opcode << 16) | insn;
13175 
13176     rt = (ctx->opcode >> 21) & 0x1f;
13177     rs = (ctx->opcode >> 16) & 0x1f;
13178     rd = (ctx->opcode >> 11) & 0x1f;
13179     rr = (ctx->opcode >> 6) & 0x1f;
13180     imm = (int16_t) ctx->opcode;
13181 
13182     op = (ctx->opcode >> 26) & 0x3f;
13183     switch (op) {
13184     case POOL32A:
13185         minor = ctx->opcode & 0x3f;
13186         switch (minor) {
13187         case 0x00:
13188             minor = (ctx->opcode >> 6) & 0xf;
13189             switch (minor) {
13190             case SLL32:
13191                 mips32_op = OPC_SLL;
13192                 goto do_shifti;
13193             case SRA:
13194                 mips32_op = OPC_SRA;
13195                 goto do_shifti;
13196             case SRL32:
13197                 mips32_op = OPC_SRL;
13198                 goto do_shifti;
13199             case ROTR:
13200                 mips32_op = OPC_ROTR;
13201             do_shifti:
13202                 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
13203                 break;
13204             default:
13205                 goto pool32a_invalid;
13206             }
13207             break;
13208         case 0x10:
13209             minor = (ctx->opcode >> 6) & 0xf;
13210             switch (minor) {
13211                 /* Arithmetic */
13212             case ADD:
13213                 mips32_op = OPC_ADD;
13214                 goto do_arith;
13215             case ADDU32:
13216                 mips32_op = OPC_ADDU;
13217                 goto do_arith;
13218             case SUB:
13219                 mips32_op = OPC_SUB;
13220                 goto do_arith;
13221             case SUBU32:
13222                 mips32_op = OPC_SUBU;
13223                 goto do_arith;
13224             case MUL:
13225                 mips32_op = OPC_MUL;
13226             do_arith:
13227                 gen_arith(ctx, mips32_op, rd, rs, rt);
13228                 break;
13229                 /* Shifts */
13230             case SLLV:
13231                 mips32_op = OPC_SLLV;
13232                 goto do_shift;
13233             case SRLV:
13234                 mips32_op = OPC_SRLV;
13235                 goto do_shift;
13236             case SRAV:
13237                 mips32_op = OPC_SRAV;
13238                 goto do_shift;
13239             case ROTRV:
13240                 mips32_op = OPC_ROTRV;
13241             do_shift:
13242                 gen_shift(ctx, mips32_op, rd, rs, rt);
13243                 break;
13244                 /* Logical operations */
13245             case AND:
13246                 mips32_op = OPC_AND;
13247                 goto do_logic;
13248             case OR32:
13249                 mips32_op = OPC_OR;
13250                 goto do_logic;
13251             case NOR:
13252                 mips32_op = OPC_NOR;
13253                 goto do_logic;
13254             case XOR32:
13255                 mips32_op = OPC_XOR;
13256             do_logic:
13257                 gen_logic(ctx, mips32_op, rd, rs, rt);
13258                 break;
13259                 /* Set less than */
13260             case SLT:
13261                 mips32_op = OPC_SLT;
13262                 goto do_slt;
13263             case SLTU:
13264                 mips32_op = OPC_SLTU;
13265             do_slt:
13266                 gen_slt(ctx, mips32_op, rd, rs, rt);
13267                 break;
13268             default:
13269                 goto pool32a_invalid;
13270             }
13271             break;
13272         case 0x18:
13273             minor = (ctx->opcode >> 6) & 0xf;
13274             switch (minor) {
13275                 /* Conditional moves */
13276             case MOVN:
13277                 mips32_op = OPC_MOVN;
13278                 goto do_cmov;
13279             case MOVZ:
13280                 mips32_op = OPC_MOVZ;
13281             do_cmov:
13282                 gen_cond_move(ctx, mips32_op, rd, rs, rt);
13283                 break;
13284             case LWXS:
13285                 gen_ldxs(ctx, rs, rt, rd);
13286                 break;
13287             default:
13288                 goto pool32a_invalid;
13289             }
13290             break;
13291         case INS:
13292             gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
13293             return;
13294         case EXT:
13295             gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
13296             return;
13297         case POOL32AXF:
13298             gen_pool32axf(env, ctx, rt, rs);
13299             break;
13300         case 0x07:
13301             generate_exception(ctx, EXCP_BREAK);
13302             break;
13303         default:
13304         pool32a_invalid:
13305                 MIPS_INVAL("pool32a");
13306                 generate_exception(ctx, EXCP_RI);
13307                 break;
13308         }
13309         break;
13310     case POOL32B:
13311         minor = (ctx->opcode >> 12) & 0xf;
13312         switch (minor) {
13313         case CACHE:
13314             check_cp0_enabled(ctx);
13315             /* Treat as no-op. */
13316             break;
13317         case LWC2:
13318         case SWC2:
13319             /* COP2: Not implemented. */
13320             generate_exception_err(ctx, EXCP_CpU, 2);
13321             break;
13322         case LWP:
13323         case SWP:
13324 #ifdef TARGET_MIPS64
13325         case LDP:
13326         case SDP:
13327 #endif
13328             gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13329             break;
13330         case LWM32:
13331         case SWM32:
13332 #ifdef TARGET_MIPS64
13333         case LDM:
13334         case SDM:
13335 #endif
13336             gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13337             break;
13338         default:
13339             MIPS_INVAL("pool32b");
13340             generate_exception(ctx, EXCP_RI);
13341             break;
13342         }
13343         break;
13344     case POOL32F:
13345         if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
13346             minor = ctx->opcode & 0x3f;
13347             check_cp1_enabled(ctx);
13348             switch (minor) {
13349             case ALNV_PS:
13350                 mips32_op = OPC_ALNV_PS;
13351                 goto do_madd;
13352             case MADD_S:
13353                 mips32_op = OPC_MADD_S;
13354                 goto do_madd;
13355             case MADD_D:
13356                 mips32_op = OPC_MADD_D;
13357                 goto do_madd;
13358             case MADD_PS:
13359                 mips32_op = OPC_MADD_PS;
13360                 goto do_madd;
13361             case MSUB_S:
13362                 mips32_op = OPC_MSUB_S;
13363                 goto do_madd;
13364             case MSUB_D:
13365                 mips32_op = OPC_MSUB_D;
13366                 goto do_madd;
13367             case MSUB_PS:
13368                 mips32_op = OPC_MSUB_PS;
13369                 goto do_madd;
13370             case NMADD_S:
13371                 mips32_op = OPC_NMADD_S;
13372                 goto do_madd;
13373             case NMADD_D:
13374                 mips32_op = OPC_NMADD_D;
13375                 goto do_madd;
13376             case NMADD_PS:
13377                 mips32_op = OPC_NMADD_PS;
13378                 goto do_madd;
13379             case NMSUB_S:
13380                 mips32_op = OPC_NMSUB_S;
13381                 goto do_madd;
13382             case NMSUB_D:
13383                 mips32_op = OPC_NMSUB_D;
13384                 goto do_madd;
13385             case NMSUB_PS:
13386                 mips32_op = OPC_NMSUB_PS;
13387             do_madd:
13388                 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
13389                 break;
13390             case CABS_COND_FMT:
13391                 cond = (ctx->opcode >> 6) & 0xf;
13392                 cc = (ctx->opcode >> 13) & 0x7;
13393                 fmt = (ctx->opcode >> 10) & 0x3;
13394                 switch (fmt) {
13395                 case 0x0:
13396                     gen_cmpabs_s(ctx, cond, rt, rs, cc);
13397                     break;
13398                 case 0x1:
13399                     gen_cmpabs_d(ctx, cond, rt, rs, cc);
13400                     break;
13401                 case 0x2:
13402                     gen_cmpabs_ps(ctx, cond, rt, rs, cc);
13403                     break;
13404                 default:
13405                     goto pool32f_invalid;
13406                 }
13407                 break;
13408             case C_COND_FMT:
13409                 cond = (ctx->opcode >> 6) & 0xf;
13410                 cc = (ctx->opcode >> 13) & 0x7;
13411                 fmt = (ctx->opcode >> 10) & 0x3;
13412                 switch (fmt) {
13413                 case 0x0:
13414                     gen_cmp_s(ctx, cond, rt, rs, cc);
13415                     break;
13416                 case 0x1:
13417                     gen_cmp_d(ctx, cond, rt, rs, cc);
13418                     break;
13419                 case 0x2:
13420                     gen_cmp_ps(ctx, cond, rt, rs, cc);
13421                     break;
13422                 default:
13423                     goto pool32f_invalid;
13424                 }
13425                 break;
13426             case POOL32FXF:
13427                 gen_pool32fxf(ctx, rt, rs);
13428                 break;
13429             case 0x00:
13430                 /* PLL foo */
13431                 switch ((ctx->opcode >> 6) & 0x7) {
13432                 case PLL_PS:
13433                     mips32_op = OPC_PLL_PS;
13434                     goto do_ps;
13435                 case PLU_PS:
13436                     mips32_op = OPC_PLU_PS;
13437                     goto do_ps;
13438                 case PUL_PS:
13439                     mips32_op = OPC_PUL_PS;
13440                     goto do_ps;
13441                 case PUU_PS:
13442                     mips32_op = OPC_PUU_PS;
13443                     goto do_ps;
13444                 case CVT_PS_S:
13445                     mips32_op = OPC_CVT_PS_S;
13446                 do_ps:
13447                     gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13448                     break;
13449                 default:
13450                     goto pool32f_invalid;
13451                 }
13452                 break;
13453             case 0x08:
13454                 /* [LS][WDU]XC1 */
13455                 switch ((ctx->opcode >> 6) & 0x7) {
13456                 case LWXC1:
13457                     mips32_op = OPC_LWXC1;
13458                     goto do_ldst_cp1;
13459                 case SWXC1:
13460                     mips32_op = OPC_SWXC1;
13461                     goto do_ldst_cp1;
13462                 case LDXC1:
13463                     mips32_op = OPC_LDXC1;
13464                     goto do_ldst_cp1;
13465                 case SDXC1:
13466                     mips32_op = OPC_SDXC1;
13467                     goto do_ldst_cp1;
13468                 case LUXC1:
13469                     mips32_op = OPC_LUXC1;
13470                     goto do_ldst_cp1;
13471                 case SUXC1:
13472                     mips32_op = OPC_SUXC1;
13473                 do_ldst_cp1:
13474                     gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
13475                     break;
13476                 default:
13477                     goto pool32f_invalid;
13478                 }
13479                 break;
13480             case 0x18:
13481                 /* 3D insns */
13482                 fmt = (ctx->opcode >> 9) & 0x3;
13483                 switch ((ctx->opcode >> 6) & 0x7) {
13484                 case RSQRT2_FMT:
13485                     switch (fmt) {
13486                     case FMT_SDPS_S:
13487                         mips32_op = OPC_RSQRT2_S;
13488                         goto do_3d;
13489                     case FMT_SDPS_D:
13490                         mips32_op = OPC_RSQRT2_D;
13491                         goto do_3d;
13492                     case FMT_SDPS_PS:
13493                         mips32_op = OPC_RSQRT2_PS;
13494                         goto do_3d;
13495                     default:
13496                         goto pool32f_invalid;
13497                     }
13498                     break;
13499                 case RECIP2_FMT:
13500                     switch (fmt) {
13501                     case FMT_SDPS_S:
13502                         mips32_op = OPC_RECIP2_S;
13503                         goto do_3d;
13504                     case FMT_SDPS_D:
13505                         mips32_op = OPC_RECIP2_D;
13506                         goto do_3d;
13507                     case FMT_SDPS_PS:
13508                         mips32_op = OPC_RECIP2_PS;
13509                         goto do_3d;
13510                     default:
13511                         goto pool32f_invalid;
13512                     }
13513                     break;
13514                 case ADDR_PS:
13515                     mips32_op = OPC_ADDR_PS;
13516                     goto do_3d;
13517                 case MULR_PS:
13518                     mips32_op = OPC_MULR_PS;
13519                 do_3d:
13520                     gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13521                     break;
13522                 default:
13523                     goto pool32f_invalid;
13524                 }
13525                 break;
13526             case 0x20:
13527                 /* MOV[FT].fmt and PREFX */
13528                 cc = (ctx->opcode >> 13) & 0x7;
13529                 fmt = (ctx->opcode >> 9) & 0x3;
13530                 switch ((ctx->opcode >> 6) & 0x7) {
13531                 case MOVF_FMT:
13532                     switch (fmt) {
13533                     case FMT_SDPS_S:
13534                         gen_movcf_s(ctx, rs, rt, cc, 0);
13535                         break;
13536                     case FMT_SDPS_D:
13537                         gen_movcf_d(ctx, rs, rt, cc, 0);
13538                         break;
13539                     case FMT_SDPS_PS:
13540                         gen_movcf_ps(ctx, rs, rt, cc, 0);
13541                         break;
13542                     default:
13543                         goto pool32f_invalid;
13544                     }
13545                     break;
13546                 case MOVT_FMT:
13547                     switch (fmt) {
13548                     case FMT_SDPS_S:
13549                         gen_movcf_s(ctx, rs, rt, cc, 1);
13550                         break;
13551                     case FMT_SDPS_D:
13552                         gen_movcf_d(ctx, rs, rt, cc, 1);
13553                         break;
13554                     case FMT_SDPS_PS:
13555                         gen_movcf_ps(ctx, rs, rt, cc, 1);
13556                         break;
13557                     default:
13558                         goto pool32f_invalid;
13559                     }
13560                     break;
13561                 case PREFX:
13562                     break;
13563                 default:
13564                     goto pool32f_invalid;
13565                 }
13566                 break;
13567 #define FINSN_3ARG_SDPS(prfx)                           \
13568                 switch ((ctx->opcode >> 8) & 0x3) {     \
13569                 case FMT_SDPS_S:                        \
13570                     mips32_op = OPC_##prfx##_S;         \
13571                     goto do_fpop;                       \
13572                 case FMT_SDPS_D:                        \
13573                     mips32_op = OPC_##prfx##_D;         \
13574                     goto do_fpop;                       \
13575                 case FMT_SDPS_PS:                       \
13576                     mips32_op = OPC_##prfx##_PS;        \
13577                     goto do_fpop;                       \
13578                 default:                                \
13579                     goto pool32f_invalid;               \
13580                 }
13581             case 0x30:
13582                 /* regular FP ops */
13583                 switch ((ctx->opcode >> 6) & 0x3) {
13584                 case ADD_FMT:
13585                     FINSN_3ARG_SDPS(ADD);
13586                     break;
13587                 case SUB_FMT:
13588                     FINSN_3ARG_SDPS(SUB);
13589                     break;
13590                 case MUL_FMT:
13591                     FINSN_3ARG_SDPS(MUL);
13592                     break;
13593                 case DIV_FMT:
13594                     fmt = (ctx->opcode >> 8) & 0x3;
13595                     if (fmt == 1) {
13596                         mips32_op = OPC_DIV_D;
13597                     } else if (fmt == 0) {
13598                         mips32_op = OPC_DIV_S;
13599                     } else {
13600                         goto pool32f_invalid;
13601                     }
13602                     goto do_fpop;
13603                 default:
13604                     goto pool32f_invalid;
13605                 }
13606                 break;
13607             case 0x38:
13608                 /* cmovs */
13609                 switch ((ctx->opcode >> 6) & 0x3) {
13610                 case MOVN_FMT:
13611                     FINSN_3ARG_SDPS(MOVN);
13612                     break;
13613                 case MOVZ_FMT:
13614                     FINSN_3ARG_SDPS(MOVZ);
13615                     break;
13616                 default:
13617                     goto pool32f_invalid;
13618                 }
13619                 break;
13620             do_fpop:
13621                 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13622                 break;
13623             default:
13624             pool32f_invalid:
13625                 MIPS_INVAL("pool32f");
13626                 generate_exception(ctx, EXCP_RI);
13627                 break;
13628             }
13629         } else {
13630             generate_exception_err(ctx, EXCP_CpU, 1);
13631         }
13632         break;
13633     case POOL32I:
13634         minor = (ctx->opcode >> 21) & 0x1f;
13635         switch (minor) {
13636         case BLTZ:
13637             gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
13638             break;
13639         case BLTZAL:
13640             gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
13641             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13642             break;
13643         case BLTZALS:
13644             gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
13645             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13646             break;
13647         case BGEZ:
13648             gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
13649             break;
13650         case BGEZAL:
13651             gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
13652             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13653             break;
13654         case BGEZALS:
13655             gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
13656             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13657             break;
13658         case BLEZ:
13659             gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
13660             break;
13661         case BGTZ:
13662             gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
13663             break;
13664 
13665             /* Traps */
13666         case TLTI:
13667             mips32_op = OPC_TLTI;
13668             goto do_trapi;
13669         case TGEI:
13670             mips32_op = OPC_TGEI;
13671             goto do_trapi;
13672         case TLTIU:
13673             mips32_op = OPC_TLTIU;
13674             goto do_trapi;
13675         case TGEIU:
13676             mips32_op = OPC_TGEIU;
13677             goto do_trapi;
13678         case TNEI:
13679             mips32_op = OPC_TNEI;
13680             goto do_trapi;
13681         case TEQI:
13682             mips32_op = OPC_TEQI;
13683         do_trapi:
13684             gen_trap(ctx, mips32_op, rs, -1, imm);
13685             break;
13686 
13687         case BNEZC:
13688         case BEQZC:
13689             gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
13690                                4, rs, 0, imm << 1, 0);
13691             /* Compact branches don't have a delay slot, so just let
13692                the normal delay slot handling take us to the branch
13693                target. */
13694             break;
13695         case LUI:
13696             gen_logic_imm(ctx, OPC_LUI, rs, -1, imm);
13697             break;
13698         case SYNCI:
13699             /* Break the TB to be able to sync copied instructions
13700                immediately */
13701             ctx->bstate = BS_STOP;
13702             break;
13703         case BC2F:
13704         case BC2T:
13705             /* COP2: Not implemented. */
13706             generate_exception_err(ctx, EXCP_CpU, 2);
13707             break;
13708         case BC1F:
13709             mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
13710             goto do_cp1branch;
13711         case BC1T:
13712             mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
13713             goto do_cp1branch;
13714         case BC1ANY4F:
13715             mips32_op = OPC_BC1FANY4;
13716             goto do_cp1mips3d;
13717         case BC1ANY4T:
13718             mips32_op = OPC_BC1TANY4;
13719         do_cp1mips3d:
13720             check_cop1x(ctx);
13721             check_insn(ctx, ASE_MIPS3D);
13722             /* Fall through */
13723         do_cp1branch:
13724             if (env->CP0_Config1 & (1 << CP0C1_FP)) {
13725                 check_cp1_enabled(ctx);
13726                 gen_compute_branch1(ctx, mips32_op,
13727                                     (ctx->opcode >> 18) & 0x7, imm << 1);
13728             } else {
13729                 generate_exception_err(ctx, EXCP_CpU, 1);
13730             }
13731             break;
13732         case BPOSGE64:
13733         case BPOSGE32:
13734             /* MIPS DSP: not implemented */
13735             /* Fall through */
13736         default:
13737             MIPS_INVAL("pool32i");
13738             generate_exception(ctx, EXCP_RI);
13739             break;
13740         }
13741         break;
13742     case POOL32C:
13743         minor = (ctx->opcode >> 12) & 0xf;
13744         switch (minor) {
13745         case LWL:
13746             mips32_op = OPC_LWL;
13747             goto do_ld_lr;
13748         case SWL:
13749             mips32_op = OPC_SWL;
13750             goto do_st_lr;
13751         case LWR:
13752             mips32_op = OPC_LWR;
13753             goto do_ld_lr;
13754         case SWR:
13755             mips32_op = OPC_SWR;
13756             goto do_st_lr;
13757 #if defined(TARGET_MIPS64)
13758         case LDL:
13759             mips32_op = OPC_LDL;
13760             goto do_ld_lr;
13761         case SDL:
13762             mips32_op = OPC_SDL;
13763             goto do_st_lr;
13764         case LDR:
13765             mips32_op = OPC_LDR;
13766             goto do_ld_lr;
13767         case SDR:
13768             mips32_op = OPC_SDR;
13769             goto do_st_lr;
13770         case LWU:
13771             mips32_op = OPC_LWU;
13772             goto do_ld_lr;
13773         case LLD:
13774             mips32_op = OPC_LLD;
13775             goto do_ld_lr;
13776 #endif
13777         case LL:
13778             mips32_op = OPC_LL;
13779             goto do_ld_lr;
13780         do_ld_lr:
13781             gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
13782             break;
13783         do_st_lr:
13784             gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
13785             break;
13786         case SC:
13787             gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
13788             break;
13789 #if defined(TARGET_MIPS64)
13790         case SCD:
13791             gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
13792             break;
13793 #endif
13794         case PREF:
13795             /* Treat as no-op */
13796             break;
13797         default:
13798             MIPS_INVAL("pool32c");
13799             generate_exception(ctx, EXCP_RI);
13800             break;
13801         }
13802         break;
13803     case ADDI32:
13804         mips32_op = OPC_ADDI;
13805         goto do_addi;
13806     case ADDIU32:
13807         mips32_op = OPC_ADDIU;
13808     do_addi:
13809         gen_arith_imm(ctx, mips32_op, rt, rs, imm);
13810         break;
13811 
13812         /* Logical operations */
13813     case ORI32:
13814         mips32_op = OPC_ORI;
13815         goto do_logici;
13816     case XORI32:
13817         mips32_op = OPC_XORI;
13818         goto do_logici;
13819     case ANDI32:
13820         mips32_op = OPC_ANDI;
13821     do_logici:
13822         gen_logic_imm(ctx, mips32_op, rt, rs, imm);
13823         break;
13824 
13825         /* Set less than immediate */
13826     case SLTI32:
13827         mips32_op = OPC_SLTI;
13828         goto do_slti;
13829     case SLTIU32:
13830         mips32_op = OPC_SLTIU;
13831     do_slti:
13832         gen_slt_imm(ctx, mips32_op, rt, rs, imm);
13833         break;
13834     case JALX32:
13835         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
13836         gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
13837         ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13838         break;
13839     case JALS32:
13840         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
13841         gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
13842         ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13843         break;
13844     case BEQ32:
13845         gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
13846         break;
13847     case BNE32:
13848         gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
13849         break;
13850     case J32:
13851         gen_compute_branch(ctx, OPC_J, 4, rt, rs,
13852                            (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
13853         break;
13854     case JAL32:
13855         gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
13856                            (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
13857         ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13858         break;
13859         /* Floating point (COP1) */
13860     case LWC132:
13861         mips32_op = OPC_LWC1;
13862         goto do_cop1;
13863     case LDC132:
13864         mips32_op = OPC_LDC1;
13865         goto do_cop1;
13866     case SWC132:
13867         mips32_op = OPC_SWC1;
13868         goto do_cop1;
13869     case SDC132:
13870         mips32_op = OPC_SDC1;
13871     do_cop1:
13872         gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
13873         break;
13874     case ADDIUPC:
13875         {
13876             int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
13877             int offset = SIMM(ctx->opcode, 0, 23) << 2;
13878 
13879             gen_addiupc(ctx, reg, offset, 0, 0);
13880         }
13881         break;
13882         /* Loads and stores */
13883     case LB32:
13884         mips32_op = OPC_LB;
13885         goto do_ld;
13886     case LBU32:
13887         mips32_op = OPC_LBU;
13888         goto do_ld;
13889     case LH32:
13890         mips32_op = OPC_LH;
13891         goto do_ld;
13892     case LHU32:
13893         mips32_op = OPC_LHU;
13894         goto do_ld;
13895     case LW32:
13896         mips32_op = OPC_LW;
13897         goto do_ld;
13898 #ifdef TARGET_MIPS64
13899     case LD32:
13900         mips32_op = OPC_LD;
13901         goto do_ld;
13902     case SD32:
13903         mips32_op = OPC_SD;
13904         goto do_st;
13905 #endif
13906     case SB32:
13907         mips32_op = OPC_SB;
13908         goto do_st;
13909     case SH32:
13910         mips32_op = OPC_SH;
13911         goto do_st;
13912     case SW32:
13913         mips32_op = OPC_SW;
13914         goto do_st;
13915     do_ld:
13916         gen_ld(ctx, mips32_op, rt, rs, imm);
13917         break;
13918     do_st:
13919         gen_st(ctx, mips32_op, rt, rs, imm);
13920         break;
13921     default:
13922         generate_exception(ctx, EXCP_RI);
13923         break;
13924     }
13925 }
13926 
decode_micromips_opc(CPUMIPSState * env,DisasContext * ctx,bool * insn_need_patch)13927 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, bool *insn_need_patch)
13928 {
13929     TCGContext *tcg_ctx = env->uc->tcg_ctx;
13930     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
13931     uint32_t op;
13932 
13933     /* make sure instructions are on a halfword boundary */
13934     if (ctx->pc & 0x1) {
13935         env->CP0_BadVAddr = ctx->pc;
13936         generate_exception(ctx, EXCP_AdEL);
13937         ctx->bstate = BS_STOP;
13938         return 2;
13939     }
13940 
13941     // Unicorn: trace this instruction on request
13942     if (HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_CODE, ctx->pc)) {
13943         gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_CODE_IDX, env->uc, ctx->pc);
13944         *insn_need_patch = true;
13945         // the callback might want to stop emulation immediately
13946         check_exit_request(tcg_ctx);
13947     }
13948 
13949     op = (ctx->opcode >> 10) & 0x3f;
13950     /* Enforce properly-sized instructions in a delay slot */
13951     if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
13952         switch (op & 0x7) { /* MSB-3..MSB-5 */
13953         case 0:
13954         /* POOL32A, POOL32B, POOL32I, POOL32C */
13955         case 4:
13956         /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
13957         case 5:
13958         /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
13959         case 6:
13960         /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
13961         case 7:
13962         /* LB32, LH32, LWC132, LDC132, LW32 */
13963             if (ctx->hflags & MIPS_HFLAG_BDS16) {
13964                 generate_exception(ctx, EXCP_RI);
13965                 /* Just stop translation; the user is confused.  */
13966                 ctx->bstate = BS_STOP;
13967                 return 2;
13968             }
13969             break;
13970         case 1:
13971         /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
13972         case 2:
13973         /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
13974         case 3:
13975         /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
13976             if (ctx->hflags & MIPS_HFLAG_BDS32) {
13977                 generate_exception(ctx, EXCP_RI);
13978                 /* Just stop translation; the user is confused.  */
13979                 ctx->bstate = BS_STOP;
13980                 return 2;
13981             }
13982             break;
13983         }
13984     }
13985 
13986     switch (op) {
13987     case POOL16A:
13988         {
13989             int rd = mmreg(uMIPS_RD(ctx->opcode));
13990             int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
13991             int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
13992             uint32_t opc = 0;
13993 
13994             switch (ctx->opcode & 0x1) {
13995             case ADDU16:
13996                 opc = OPC_ADDU;
13997                 break;
13998             case SUBU16:
13999                 opc = OPC_SUBU;
14000                 break;
14001             }
14002 
14003             gen_arith(ctx, opc, rd, rs1, rs2);
14004         }
14005         break;
14006     case POOL16B:
14007         {
14008             int rd = mmreg(uMIPS_RD(ctx->opcode));
14009             int rs = mmreg(uMIPS_RS(ctx->opcode));
14010             int amount = (ctx->opcode >> 1) & 0x7;
14011             uint32_t opc = 0;
14012             amount = amount == 0 ? 8 : amount;
14013 
14014             switch (ctx->opcode & 0x1) {
14015             case SLL16:
14016                 opc = OPC_SLL;
14017                 break;
14018             case SRL16:
14019                 opc = OPC_SRL;
14020                 break;
14021             }
14022 
14023             gen_shift_imm(ctx, opc, rd, rs, amount);
14024         }
14025         break;
14026     case POOL16C:
14027         gen_pool16c_insn(ctx);
14028         break;
14029     case LWGP16:
14030         {
14031             int rd = mmreg(uMIPS_RD(ctx->opcode));
14032             int rb = 28;            /* GP */
14033             int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
14034 
14035             gen_ld(ctx, OPC_LW, rd, rb, offset);
14036         }
14037         break;
14038     case POOL16F:
14039         if (ctx->opcode & 1) {
14040             generate_exception(ctx, EXCP_RI);
14041         } else {
14042             /* MOVEP */
14043             int enc_dest = uMIPS_RD(ctx->opcode);
14044             int enc_rt = uMIPS_RS2(ctx->opcode);
14045             int enc_rs = uMIPS_RS1(ctx->opcode);
14046             int rd, rs, re, rt;
14047             static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
14048             static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
14049             static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
14050 
14051             rd = rd_enc[enc_dest];
14052             re = re_enc[enc_dest];
14053             rs = rs_rt_enc[enc_rs];
14054             rt = rs_rt_enc[enc_rt];
14055 
14056             gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
14057             gen_arith_imm(ctx, OPC_ADDIU, re, rt, 0);
14058         }
14059         break;
14060     case LBU16:
14061         {
14062             int rd = mmreg(uMIPS_RD(ctx->opcode));
14063             int rb = mmreg(uMIPS_RS(ctx->opcode));
14064             int16_t offset = ZIMM(ctx->opcode, 0, 4);
14065             offset = (offset == 0xf ? -1 : offset);
14066 
14067             gen_ld(ctx, OPC_LBU, rd, rb, offset);
14068         }
14069         break;
14070     case LHU16:
14071         {
14072             int rd = mmreg(uMIPS_RD(ctx->opcode));
14073             int rb = mmreg(uMIPS_RS(ctx->opcode));
14074             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
14075 
14076             gen_ld(ctx, OPC_LHU, rd, rb, offset);
14077         }
14078         break;
14079     case LWSP16:
14080         {
14081             int rd = (ctx->opcode >> 5) & 0x1f;
14082             int rb = 29;            /* SP */
14083             int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
14084 
14085             gen_ld(ctx, OPC_LW, rd, rb, offset);
14086         }
14087         break;
14088     case LW16:
14089         {
14090             int rd = mmreg(uMIPS_RD(ctx->opcode));
14091             int rb = mmreg(uMIPS_RS(ctx->opcode));
14092             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
14093 
14094             gen_ld(ctx, OPC_LW, rd, rb, offset);
14095         }
14096         break;
14097     case SB16:
14098         {
14099             int rd = mmreg2(uMIPS_RD(ctx->opcode));
14100             int rb = mmreg(uMIPS_RS(ctx->opcode));
14101             int16_t offset = ZIMM(ctx->opcode, 0, 4);
14102 
14103             gen_st(ctx, OPC_SB, rd, rb, offset);
14104         }
14105         break;
14106     case SH16:
14107         {
14108             int rd = mmreg2(uMIPS_RD(ctx->opcode));
14109             int rb = mmreg(uMIPS_RS(ctx->opcode));
14110             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
14111 
14112             gen_st(ctx, OPC_SH, rd, rb, offset);
14113         }
14114         break;
14115     case SWSP16:
14116         {
14117             int rd = (ctx->opcode >> 5) & 0x1f;
14118             int rb = 29;            /* SP */
14119             int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
14120 
14121             gen_st(ctx, OPC_SW, rd, rb, offset);
14122         }
14123         break;
14124     case SW16:
14125         {
14126             int rd = mmreg2(uMIPS_RD(ctx->opcode));
14127             int rb = mmreg(uMIPS_RS(ctx->opcode));
14128             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
14129 
14130             gen_st(ctx, OPC_SW, rd, rb, offset);
14131         }
14132         break;
14133     case MOVE16:
14134         {
14135             int rd = uMIPS_RD5(ctx->opcode);
14136             int rs = uMIPS_RS5(ctx->opcode);
14137 
14138             gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
14139         }
14140         break;
14141     case ANDI16:
14142         gen_andi16(ctx);
14143         break;
14144     case POOL16D:
14145         switch (ctx->opcode & 0x1) {
14146         case ADDIUS5:
14147             gen_addius5(ctx);
14148             break;
14149         case ADDIUSP:
14150             gen_addiusp(ctx);
14151             break;
14152         }
14153         break;
14154     case POOL16E:
14155         switch (ctx->opcode & 0x1) {
14156         case ADDIUR2:
14157             gen_addiur2(ctx);
14158             break;
14159         case ADDIUR1SP:
14160             gen_addiur1sp(ctx);
14161             break;
14162         }
14163         break;
14164     case B16:
14165         gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
14166                            SIMM(ctx->opcode, 0, 10) << 1, 4);
14167         break;
14168     case BNEZ16:
14169     case BEQZ16:
14170         gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
14171                            mmreg(uMIPS_RD(ctx->opcode)),
14172                            0, SIMM(ctx->opcode, 0, 7) << 1, 4);
14173         break;
14174     case LI16:
14175         {
14176             int reg = mmreg(uMIPS_RD(ctx->opcode));
14177             int imm = ZIMM(ctx->opcode, 0, 7);
14178 
14179             imm = (imm == 0x7f ? -1 : imm);
14180             tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[reg], imm);
14181         }
14182         break;
14183     case RES_20:
14184     case RES_28:
14185     case RES_29:
14186     case RES_30:
14187     case RES_31:
14188     case RES_38:
14189     case RES_39:
14190         generate_exception(ctx, EXCP_RI);
14191         break;
14192     default:
14193         decode_micromips32_opc (env, ctx, op);
14194         return 4;
14195     }
14196 
14197     return 2;
14198 }
14199 
14200 /* SmartMIPS extension to MIPS32 */
14201 
14202 #if defined(TARGET_MIPS64)
14203 
14204 /* MDMX extension to MIPS64 */
14205 
14206 #endif
14207 
14208 /* MIPSDSP functions. */
gen_mipsdsp_ld(DisasContext * ctx,uint32_t opc,int rd,int base,int offset)14209 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
14210                            int rd, int base, int offset)
14211 {
14212     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
14213     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
14214     const char *opn = "ldx";
14215     TCGv t0;
14216 
14217     check_dsp(ctx);
14218     t0 = tcg_temp_new(tcg_ctx);
14219 
14220     if (base == 0) {
14221         gen_load_gpr(ctx, t0, offset);
14222     } else if (offset == 0) {
14223         gen_load_gpr(ctx, t0, base);
14224     } else {
14225         gen_op_addr_add(ctx, t0, *cpu_gpr[base], *cpu_gpr[offset]);
14226     }
14227 
14228     switch (opc) {
14229     case OPC_LBUX:
14230         tcg_gen_qemu_ld_tl(ctx->uc, t0, t0, ctx->mem_idx, MO_UB);
14231         gen_store_gpr(tcg_ctx, t0, rd);
14232         opn = "lbux";
14233         break;
14234     case OPC_LHX:
14235         tcg_gen_qemu_ld_tl(ctx->uc, t0, t0, ctx->mem_idx, MO_TESW);
14236         gen_store_gpr(tcg_ctx, t0, rd);
14237         opn = "lhx";
14238         break;
14239     case OPC_LWX:
14240         tcg_gen_qemu_ld_tl(ctx->uc, t0, t0, ctx->mem_idx, MO_TESL);
14241         gen_store_gpr(tcg_ctx, t0, rd);
14242         opn = "lwx";
14243         break;
14244 #if defined(TARGET_MIPS64)
14245     case OPC_LDX:
14246         tcg_gen_qemu_ld_tl(ctx->uc, t0, t0, ctx->mem_idx, MO_TEQ);
14247         gen_store_gpr(tcg_ctx, t0, rd);
14248         opn = "ldx";
14249         break;
14250 #endif
14251     }
14252     (void)opn; /* avoid a compiler warning */
14253     MIPS_DEBUG("%s %s, %s(%s)", opn,
14254                regnames[rd], regnames[offset], regnames[base]);
14255     tcg_temp_free(tcg_ctx, t0);
14256 }
14257 
gen_mipsdsp_arith(DisasContext * ctx,uint32_t op1,uint32_t op2,int ret,int v1,int v2)14258 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
14259                               int ret, int v1, int v2)
14260 {
14261     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
14262     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
14263     const char *opn = "mipsdsp arith";
14264     TCGv v1_t;
14265     TCGv v2_t;
14266 
14267     if (ret == 0) {
14268         /* Treat as NOP. */
14269         MIPS_DEBUG("NOP");
14270         return;
14271     }
14272 
14273     v1_t = tcg_temp_new(tcg_ctx);
14274     v2_t = tcg_temp_new(tcg_ctx);
14275 
14276     gen_load_gpr(ctx, v1_t, v1);
14277     gen_load_gpr(ctx, v2_t, v2);
14278 
14279     switch (op1) {
14280     /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
14281     case OPC_MULT_G_2E:
14282         check_dspr2(ctx);
14283         switch (op2) {
14284         case OPC_ADDUH_QB:
14285             gen_helper_adduh_qb(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
14286             break;
14287         case OPC_ADDUH_R_QB:
14288             gen_helper_adduh_r_qb(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
14289             break;
14290         case OPC_ADDQH_PH:
14291             gen_helper_addqh_ph(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
14292             break;
14293         case OPC_ADDQH_R_PH:
14294             gen_helper_addqh_r_ph(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
14295             break;
14296         case OPC_ADDQH_W:
14297             gen_helper_addqh_w(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
14298             break;
14299         case OPC_ADDQH_R_W:
14300             gen_helper_addqh_r_w(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
14301             break;
14302         case OPC_SUBUH_QB:
14303             gen_helper_subuh_qb(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
14304             break;
14305         case OPC_SUBUH_R_QB:
14306             gen_helper_subuh_r_qb(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
14307             break;
14308         case OPC_SUBQH_PH:
14309             gen_helper_subqh_ph(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
14310             break;
14311         case OPC_SUBQH_R_PH:
14312             gen_helper_subqh_r_ph(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
14313             break;
14314         case OPC_SUBQH_W:
14315             gen_helper_subqh_w(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
14316             break;
14317         case OPC_SUBQH_R_W:
14318             gen_helper_subqh_r_w(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
14319             break;
14320         }
14321         break;
14322     case OPC_ABSQ_S_PH_DSP:
14323         switch (op2) {
14324         case OPC_ABSQ_S_QB:
14325             check_dspr2(ctx);
14326             gen_helper_absq_s_qb(tcg_ctx, *cpu_gpr[ret], v2_t, tcg_ctx->cpu_env);
14327             break;
14328         case OPC_ABSQ_S_PH:
14329             check_dsp(ctx);
14330             gen_helper_absq_s_ph(tcg_ctx, *cpu_gpr[ret], v2_t, tcg_ctx->cpu_env);
14331             break;
14332         case OPC_ABSQ_S_W:
14333             check_dsp(ctx);
14334             gen_helper_absq_s_w(tcg_ctx, *cpu_gpr[ret], v2_t, tcg_ctx->cpu_env);
14335             break;
14336         case OPC_PRECEQ_W_PHL:
14337             check_dsp(ctx);
14338             tcg_gen_andi_tl(tcg_ctx, *cpu_gpr[ret], v2_t, 0xFFFF0000);
14339             tcg_gen_ext32s_tl(tcg_ctx, *cpu_gpr[ret], *cpu_gpr[ret]);
14340             break;
14341         case OPC_PRECEQ_W_PHR:
14342             check_dsp(ctx);
14343             tcg_gen_andi_tl(tcg_ctx, *cpu_gpr[ret], v2_t, 0x0000FFFF);
14344             tcg_gen_shli_tl(tcg_ctx, *cpu_gpr[ret], *cpu_gpr[ret], 16);
14345             tcg_gen_ext32s_tl(tcg_ctx, *cpu_gpr[ret], *cpu_gpr[ret]);
14346             break;
14347         case OPC_PRECEQU_PH_QBL:
14348             check_dsp(ctx);
14349             gen_helper_precequ_ph_qbl(tcg_ctx, *cpu_gpr[ret], v2_t);
14350             break;
14351         case OPC_PRECEQU_PH_QBR:
14352             check_dsp(ctx);
14353             gen_helper_precequ_ph_qbr(tcg_ctx, *cpu_gpr[ret], v2_t);
14354             break;
14355         case OPC_PRECEQU_PH_QBLA:
14356             check_dsp(ctx);
14357             gen_helper_precequ_ph_qbla(tcg_ctx, *cpu_gpr[ret], v2_t);
14358             break;
14359         case OPC_PRECEQU_PH_QBRA:
14360             check_dsp(ctx);
14361             gen_helper_precequ_ph_qbra(tcg_ctx, *cpu_gpr[ret], v2_t);
14362             break;
14363         case OPC_PRECEU_PH_QBL:
14364             check_dsp(ctx);
14365             gen_helper_preceu_ph_qbl(tcg_ctx, *cpu_gpr[ret], v2_t);
14366             break;
14367         case OPC_PRECEU_PH_QBR:
14368             check_dsp(ctx);
14369             gen_helper_preceu_ph_qbr(tcg_ctx, *cpu_gpr[ret], v2_t);
14370             break;
14371         case OPC_PRECEU_PH_QBLA:
14372             check_dsp(ctx);
14373             gen_helper_preceu_ph_qbla(tcg_ctx, *cpu_gpr[ret], v2_t);
14374             break;
14375         case OPC_PRECEU_PH_QBRA:
14376             check_dsp(ctx);
14377             gen_helper_preceu_ph_qbra(tcg_ctx, *cpu_gpr[ret], v2_t);
14378             break;
14379         }
14380         break;
14381     case OPC_ADDU_QB_DSP:
14382         switch (op2) {
14383         case OPC_ADDQ_PH:
14384             check_dsp(ctx);
14385             gen_helper_addq_ph(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14386             break;
14387         case OPC_ADDQ_S_PH:
14388             check_dsp(ctx);
14389             gen_helper_addq_s_ph(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14390             break;
14391         case OPC_ADDQ_S_W:
14392             check_dsp(ctx);
14393             gen_helper_addq_s_w(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14394             break;
14395         case OPC_ADDU_QB:
14396             check_dsp(ctx);
14397             gen_helper_addu_qb(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14398             break;
14399         case OPC_ADDU_S_QB:
14400             check_dsp(ctx);
14401             gen_helper_addu_s_qb(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14402             break;
14403         case OPC_ADDU_PH:
14404             check_dspr2(ctx);
14405             gen_helper_addu_ph(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14406             break;
14407         case OPC_ADDU_S_PH:
14408             check_dspr2(ctx);
14409             gen_helper_addu_s_ph(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14410             break;
14411         case OPC_SUBQ_PH:
14412             check_dsp(ctx);
14413             gen_helper_subq_ph(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14414             break;
14415         case OPC_SUBQ_S_PH:
14416             check_dsp(ctx);
14417             gen_helper_subq_s_ph(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14418             break;
14419         case OPC_SUBQ_S_W:
14420             check_dsp(ctx);
14421             gen_helper_subq_s_w(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14422             break;
14423         case OPC_SUBU_QB:
14424             check_dsp(ctx);
14425             gen_helper_subu_qb(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14426             break;
14427         case OPC_SUBU_S_QB:
14428             check_dsp(ctx);
14429             gen_helper_subu_s_qb(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14430             break;
14431         case OPC_SUBU_PH:
14432             check_dspr2(ctx);
14433             gen_helper_subu_ph(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14434             break;
14435         case OPC_SUBU_S_PH:
14436             check_dspr2(ctx);
14437             gen_helper_subu_s_ph(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14438             break;
14439         case OPC_ADDSC:
14440             check_dsp(ctx);
14441             gen_helper_addsc(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14442             break;
14443         case OPC_ADDWC:
14444             check_dsp(ctx);
14445             gen_helper_addwc(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14446             break;
14447         case OPC_MODSUB:
14448             check_dsp(ctx);
14449             gen_helper_modsub(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
14450             break;
14451         case OPC_RADDU_W_QB:
14452             check_dsp(ctx);
14453             gen_helper_raddu_w_qb(tcg_ctx, *cpu_gpr[ret], v1_t);
14454             break;
14455         }
14456         break;
14457     case OPC_CMPU_EQ_QB_DSP:
14458         switch (op2) {
14459         case OPC_PRECR_QB_PH:
14460             check_dspr2(ctx);
14461             gen_helper_precr_qb_ph(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
14462             break;
14463         case OPC_PRECRQ_QB_PH:
14464             check_dsp(ctx);
14465             gen_helper_precrq_qb_ph(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
14466             break;
14467         case OPC_PRECR_SRA_PH_W:
14468             check_dspr2(ctx);
14469             {
14470                 TCGv_i32 sa_t = tcg_const_i32(tcg_ctx, v2);
14471                 gen_helper_precr_sra_ph_w(tcg_ctx, *cpu_gpr[ret], sa_t, v1_t,
14472                                           *cpu_gpr[ret]);
14473                 tcg_temp_free_i32(tcg_ctx, sa_t);
14474                 break;
14475             }
14476         case OPC_PRECR_SRA_R_PH_W:
14477             check_dspr2(ctx);
14478             {
14479                 TCGv_i32 sa_t = tcg_const_i32(tcg_ctx, v2);
14480                 gen_helper_precr_sra_r_ph_w(tcg_ctx, *cpu_gpr[ret], sa_t, v1_t,
14481                                             *cpu_gpr[ret]);
14482                 tcg_temp_free_i32(tcg_ctx, sa_t);
14483                 break;
14484             }
14485         case OPC_PRECRQ_PH_W:
14486             check_dsp(ctx);
14487             gen_helper_precrq_ph_w(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
14488             break;
14489         case OPC_PRECRQ_RS_PH_W:
14490             check_dsp(ctx);
14491             gen_helper_precrq_rs_ph_w(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14492             break;
14493         case OPC_PRECRQU_S_QB_PH:
14494             check_dsp(ctx);
14495             gen_helper_precrqu_s_qb_ph(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14496             break;
14497         }
14498         break;
14499 #ifdef TARGET_MIPS64
14500     case OPC_ABSQ_S_QH_DSP:
14501         switch (op2) {
14502         case OPC_PRECEQ_L_PWL:
14503             check_dsp(ctx);
14504             tcg_gen_andi_tl(tcg_ctx, *cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
14505             break;
14506         case OPC_PRECEQ_L_PWR:
14507             check_dsp(ctx);
14508             tcg_gen_shli_tl(tcg_ctx, *cpu_gpr[ret], v2_t, 32);
14509             break;
14510         case OPC_PRECEQ_PW_QHL:
14511             check_dsp(ctx);
14512             gen_helper_preceq_pw_qhl(tcg_ctx, *cpu_gpr[ret], v2_t);
14513             break;
14514         case OPC_PRECEQ_PW_QHR:
14515             check_dsp(ctx);
14516             gen_helper_preceq_pw_qhr(tcg_ctx, *cpu_gpr[ret], v2_t);
14517             break;
14518         case OPC_PRECEQ_PW_QHLA:
14519             check_dsp(ctx);
14520             gen_helper_preceq_pw_qhla(tcg_ctx, *cpu_gpr[ret], v2_t);
14521             break;
14522         case OPC_PRECEQ_PW_QHRA:
14523             check_dsp(ctx);
14524             gen_helper_preceq_pw_qhra(tcg_ctx, *cpu_gpr[ret], v2_t);
14525             break;
14526         case OPC_PRECEQU_QH_OBL:
14527             check_dsp(ctx);
14528             gen_helper_precequ_qh_obl(tcg_ctx, *cpu_gpr[ret], v2_t);
14529             break;
14530         case OPC_PRECEQU_QH_OBR:
14531             check_dsp(ctx);
14532             gen_helper_precequ_qh_obr(tcg_ctx, *cpu_gpr[ret], v2_t);
14533             break;
14534         case OPC_PRECEQU_QH_OBLA:
14535             check_dsp(ctx);
14536             gen_helper_precequ_qh_obla(tcg_ctx, *cpu_gpr[ret], v2_t);
14537             break;
14538         case OPC_PRECEQU_QH_OBRA:
14539             check_dsp(ctx);
14540             gen_helper_precequ_qh_obra(tcg_ctx, *cpu_gpr[ret], v2_t);
14541             break;
14542         case OPC_PRECEU_QH_OBL:
14543             check_dsp(ctx);
14544             gen_helper_preceu_qh_obl(tcg_ctx, *cpu_gpr[ret], v2_t);
14545             break;
14546         case OPC_PRECEU_QH_OBR:
14547             check_dsp(ctx);
14548             gen_helper_preceu_qh_obr(tcg_ctx, *cpu_gpr[ret], v2_t);
14549             break;
14550         case OPC_PRECEU_QH_OBLA:
14551             check_dsp(ctx);
14552             gen_helper_preceu_qh_obla(tcg_ctx, *cpu_gpr[ret], v2_t);
14553             break;
14554         case OPC_PRECEU_QH_OBRA:
14555             check_dsp(ctx);
14556             gen_helper_preceu_qh_obra(tcg_ctx, *cpu_gpr[ret], v2_t);
14557             break;
14558         case OPC_ABSQ_S_OB:
14559             check_dspr2(ctx);
14560             gen_helper_absq_s_ob(tcg_ctx, *cpu_gpr[ret], v2_t, tcg_ctx->cpu_env);
14561             break;
14562         case OPC_ABSQ_S_PW:
14563             check_dsp(ctx);
14564             gen_helper_absq_s_pw(tcg_ctx, *cpu_gpr[ret], v2_t, tcg_ctx->cpu_env);
14565             break;
14566         case OPC_ABSQ_S_QH:
14567             check_dsp(ctx);
14568             gen_helper_absq_s_qh(tcg_ctx, *cpu_gpr[ret], v2_t, tcg_ctx->cpu_env);
14569             break;
14570         }
14571         break;
14572     case OPC_ADDU_OB_DSP:
14573         switch (op2) {
14574         case OPC_RADDU_L_OB:
14575             check_dsp(ctx);
14576             gen_helper_raddu_l_ob(tcg_ctx, *cpu_gpr[ret], v1_t);
14577             break;
14578         case OPC_SUBQ_PW:
14579             check_dsp(ctx);
14580             gen_helper_subq_pw(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14581             break;
14582         case OPC_SUBQ_S_PW:
14583             check_dsp(ctx);
14584             gen_helper_subq_s_pw(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14585             break;
14586         case OPC_SUBQ_QH:
14587             check_dsp(ctx);
14588             gen_helper_subq_qh(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14589             break;
14590         case OPC_SUBQ_S_QH:
14591             check_dsp(ctx);
14592             gen_helper_subq_s_qh(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14593             break;
14594         case OPC_SUBU_OB:
14595             check_dsp(ctx);
14596             gen_helper_subu_ob(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14597             break;
14598         case OPC_SUBU_S_OB:
14599             check_dsp(ctx);
14600             gen_helper_subu_s_ob(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14601             break;
14602         case OPC_SUBU_QH:
14603             check_dspr2(ctx);
14604             gen_helper_subu_qh(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14605             break;
14606         case OPC_SUBU_S_QH:
14607             check_dspr2(ctx);
14608             gen_helper_subu_s_qh(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14609             break;
14610         case OPC_SUBUH_OB:
14611             check_dspr2(ctx);
14612             gen_helper_subuh_ob(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
14613             break;
14614         case OPC_SUBUH_R_OB:
14615             check_dspr2(ctx);
14616             gen_helper_subuh_r_ob(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
14617             break;
14618         case OPC_ADDQ_PW:
14619             check_dsp(ctx);
14620             gen_helper_addq_pw(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14621             break;
14622         case OPC_ADDQ_S_PW:
14623             check_dsp(ctx);
14624             gen_helper_addq_s_pw(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14625             break;
14626         case OPC_ADDQ_QH:
14627             check_dsp(ctx);
14628             gen_helper_addq_qh(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14629             break;
14630         case OPC_ADDQ_S_QH:
14631             check_dsp(ctx);
14632             gen_helper_addq_s_qh(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14633             break;
14634         case OPC_ADDU_OB:
14635             check_dsp(ctx);
14636             gen_helper_addu_ob(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14637             break;
14638         case OPC_ADDU_S_OB:
14639             check_dsp(ctx);
14640             gen_helper_addu_s_ob(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14641             break;
14642         case OPC_ADDU_QH:
14643             check_dspr2(ctx);
14644             gen_helper_addu_qh(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14645             break;
14646         case OPC_ADDU_S_QH:
14647             check_dspr2(ctx);
14648             gen_helper_addu_s_qh(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14649             break;
14650         case OPC_ADDUH_OB:
14651             check_dspr2(ctx);
14652             gen_helper_adduh_ob(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
14653             break;
14654         case OPC_ADDUH_R_OB:
14655             check_dspr2(ctx);
14656             gen_helper_adduh_r_ob(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
14657             break;
14658         }
14659         break;
14660     case OPC_CMPU_EQ_OB_DSP:
14661         switch (op2) {
14662         case OPC_PRECR_OB_QH:
14663             check_dspr2(ctx);
14664             gen_helper_precr_ob_qh(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
14665             break;
14666         case OPC_PRECR_SRA_QH_PW:
14667             check_dspr2(ctx);
14668             {
14669                 TCGv_i32 ret_t = tcg_const_i32(tcg_ctx, ret);
14670                 gen_helper_precr_sra_qh_pw(tcg_ctx, v2_t, v1_t, v2_t, ret_t);
14671                 tcg_temp_free_i32(tcg_ctx, ret_t);
14672                 break;
14673             }
14674         case OPC_PRECR_SRA_R_QH_PW:
14675             check_dspr2(ctx);
14676             {
14677                 TCGv_i32 sa_v = tcg_const_i32(tcg_ctx, ret);
14678                 gen_helper_precr_sra_r_qh_pw(tcg_ctx, v2_t, v1_t, v2_t, sa_v);
14679                 tcg_temp_free_i32(tcg_ctx, sa_v);
14680                 break;
14681             }
14682         case OPC_PRECRQ_OB_QH:
14683             check_dsp(ctx);
14684             gen_helper_precrq_ob_qh(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
14685             break;
14686         case OPC_PRECRQ_PW_L:
14687             check_dsp(ctx);
14688             gen_helper_precrq_pw_l(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
14689             break;
14690         case OPC_PRECRQ_QH_PW:
14691             check_dsp(ctx);
14692             gen_helper_precrq_qh_pw(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
14693             break;
14694         case OPC_PRECRQ_RS_QH_PW:
14695             check_dsp(ctx);
14696             gen_helper_precrq_rs_qh_pw(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14697             break;
14698         case OPC_PRECRQU_S_OB_QH:
14699             check_dsp(ctx);
14700             gen_helper_precrqu_s_ob_qh(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14701             break;
14702         }
14703         break;
14704 #endif
14705     }
14706 
14707     tcg_temp_free(tcg_ctx, v1_t);
14708     tcg_temp_free(tcg_ctx, v2_t);
14709 
14710     (void)opn; /* avoid a compiler warning */
14711     MIPS_DEBUG("%s", opn);
14712 }
14713 
gen_mipsdsp_shift(DisasContext * ctx,uint32_t opc,int ret,int v1,int v2)14714 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
14715                               int ret, int v1, int v2)
14716 {
14717     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
14718     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
14719     uint32_t op2;
14720     const char *opn = "mipsdsp shift";
14721     TCGv t0;
14722     TCGv v1_t;
14723     TCGv v2_t;
14724 
14725     if (ret == 0) {
14726         /* Treat as NOP. */
14727         MIPS_DEBUG("NOP");
14728         return;
14729     }
14730 
14731     t0 = tcg_temp_new(tcg_ctx);
14732     v1_t = tcg_temp_new(tcg_ctx);
14733     v2_t = tcg_temp_new(tcg_ctx);
14734 
14735     tcg_gen_movi_tl(tcg_ctx, t0, v1);
14736     gen_load_gpr(ctx, v1_t, v1);
14737     gen_load_gpr(ctx, v2_t, v2);
14738 
14739     switch (opc) {
14740     case OPC_SHLL_QB_DSP:
14741         {
14742             op2 = MASK_SHLL_QB(ctx->opcode);
14743             switch (op2) {
14744             case OPC_SHLL_QB:
14745                 check_dsp(ctx);
14746                 gen_helper_shll_qb(tcg_ctx, *cpu_gpr[ret], t0, v2_t, tcg_ctx->cpu_env);
14747                 break;
14748             case OPC_SHLLV_QB:
14749                 check_dsp(ctx);
14750                 gen_helper_shll_qb(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14751                 break;
14752             case OPC_SHLL_PH:
14753                 check_dsp(ctx);
14754                 gen_helper_shll_ph(tcg_ctx, *cpu_gpr[ret], t0, v2_t, tcg_ctx->cpu_env);
14755                 break;
14756             case OPC_SHLLV_PH:
14757                 check_dsp(ctx);
14758                 gen_helper_shll_ph(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14759                 break;
14760             case OPC_SHLL_S_PH:
14761                 check_dsp(ctx);
14762                 gen_helper_shll_s_ph(tcg_ctx, *cpu_gpr[ret], t0, v2_t, tcg_ctx->cpu_env);
14763                 break;
14764             case OPC_SHLLV_S_PH:
14765                 check_dsp(ctx);
14766                 gen_helper_shll_s_ph(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14767                 break;
14768             case OPC_SHLL_S_W:
14769                 check_dsp(ctx);
14770                 gen_helper_shll_s_w(tcg_ctx, *cpu_gpr[ret], t0, v2_t, tcg_ctx->cpu_env);
14771                 break;
14772             case OPC_SHLLV_S_W:
14773                 check_dsp(ctx);
14774                 gen_helper_shll_s_w(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14775                 break;
14776             case OPC_SHRL_QB:
14777                 check_dsp(ctx);
14778                 gen_helper_shrl_qb(tcg_ctx, *cpu_gpr[ret], t0, v2_t);
14779                 break;
14780             case OPC_SHRLV_QB:
14781                 check_dsp(ctx);
14782                 gen_helper_shrl_qb(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
14783                 break;
14784             case OPC_SHRL_PH:
14785                 check_dspr2(ctx);
14786                 gen_helper_shrl_ph(tcg_ctx, *cpu_gpr[ret], t0, v2_t);
14787                 break;
14788             case OPC_SHRLV_PH:
14789                 check_dspr2(ctx);
14790                 gen_helper_shrl_ph(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
14791                 break;
14792             case OPC_SHRA_QB:
14793                 check_dspr2(ctx);
14794                 gen_helper_shra_qb(tcg_ctx, *cpu_gpr[ret], t0, v2_t);
14795                 break;
14796             case OPC_SHRA_R_QB:
14797                 check_dspr2(ctx);
14798                 gen_helper_shra_r_qb(tcg_ctx, *cpu_gpr[ret], t0, v2_t);
14799                 break;
14800             case OPC_SHRAV_QB:
14801                 check_dspr2(ctx);
14802                 gen_helper_shra_qb(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
14803                 break;
14804             case OPC_SHRAV_R_QB:
14805                 check_dspr2(ctx);
14806                 gen_helper_shra_r_qb(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
14807                 break;
14808             case OPC_SHRA_PH:
14809                 check_dsp(ctx);
14810                 gen_helper_shra_ph(tcg_ctx, *cpu_gpr[ret], t0, v2_t);
14811                 break;
14812             case OPC_SHRA_R_PH:
14813                 check_dsp(ctx);
14814                 gen_helper_shra_r_ph(tcg_ctx, *cpu_gpr[ret], t0, v2_t);
14815                 break;
14816             case OPC_SHRAV_PH:
14817                 check_dsp(ctx);
14818                 gen_helper_shra_ph(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
14819                 break;
14820             case OPC_SHRAV_R_PH:
14821                 check_dsp(ctx);
14822                 gen_helper_shra_r_ph(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
14823                 break;
14824             case OPC_SHRA_R_W:
14825                 check_dsp(ctx);
14826                 gen_helper_shra_r_w(tcg_ctx, *cpu_gpr[ret], t0, v2_t);
14827                 break;
14828             case OPC_SHRAV_R_W:
14829                 check_dsp(ctx);
14830                 gen_helper_shra_r_w(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
14831                 break;
14832             default:            /* Invalid */
14833                 MIPS_INVAL("MASK SHLL.QB");
14834                 generate_exception(ctx, EXCP_RI);
14835                 break;
14836             }
14837             break;
14838         }
14839 #ifdef TARGET_MIPS64
14840     case OPC_SHLL_OB_DSP:
14841         op2 = MASK_SHLL_OB(ctx->opcode);
14842         switch (op2) {
14843         case OPC_SHLL_PW:
14844             check_dsp(ctx);
14845             gen_helper_shll_pw(tcg_ctx, *cpu_gpr[ret], v2_t, t0, tcg_ctx->cpu_env);
14846             break;
14847         case OPC_SHLLV_PW:
14848             check_dsp(ctx);
14849             gen_helper_shll_pw(tcg_ctx, *cpu_gpr[ret], v2_t, v1_t, tcg_ctx->cpu_env);
14850             break;
14851         case OPC_SHLL_S_PW:
14852             check_dsp(ctx);
14853             gen_helper_shll_s_pw(tcg_ctx, *cpu_gpr[ret], v2_t, t0, tcg_ctx->cpu_env);
14854             break;
14855         case OPC_SHLLV_S_PW:
14856             check_dsp(ctx);
14857             gen_helper_shll_s_pw(tcg_ctx, *cpu_gpr[ret], v2_t, v1_t, tcg_ctx->cpu_env);
14858             break;
14859         case OPC_SHLL_OB:
14860             check_dsp(ctx);
14861             gen_helper_shll_ob(tcg_ctx, *cpu_gpr[ret], v2_t, t0, tcg_ctx->cpu_env);
14862             break;
14863         case OPC_SHLLV_OB:
14864             check_dsp(ctx);
14865             gen_helper_shll_ob(tcg_ctx, *cpu_gpr[ret], v2_t, v1_t, tcg_ctx->cpu_env);
14866             break;
14867         case OPC_SHLL_QH:
14868             check_dsp(ctx);
14869             gen_helper_shll_qh(tcg_ctx, *cpu_gpr[ret], v2_t, t0, tcg_ctx->cpu_env);
14870             break;
14871         case OPC_SHLLV_QH:
14872             check_dsp(ctx);
14873             gen_helper_shll_qh(tcg_ctx, *cpu_gpr[ret], v2_t, v1_t, tcg_ctx->cpu_env);
14874             break;
14875         case OPC_SHLL_S_QH:
14876             check_dsp(ctx);
14877             gen_helper_shll_s_qh(tcg_ctx, *cpu_gpr[ret], v2_t, t0, tcg_ctx->cpu_env);
14878             break;
14879         case OPC_SHLLV_S_QH:
14880             check_dsp(ctx);
14881             gen_helper_shll_s_qh(tcg_ctx, *cpu_gpr[ret], v2_t, v1_t, tcg_ctx->cpu_env);
14882             break;
14883         case OPC_SHRA_OB:
14884             check_dspr2(ctx);
14885             gen_helper_shra_ob(tcg_ctx, *cpu_gpr[ret], v2_t, t0);
14886             break;
14887         case OPC_SHRAV_OB:
14888             check_dspr2(ctx);
14889             gen_helper_shra_ob(tcg_ctx, *cpu_gpr[ret], v2_t, v1_t);
14890             break;
14891         case OPC_SHRA_R_OB:
14892             check_dspr2(ctx);
14893             gen_helper_shra_r_ob(tcg_ctx, *cpu_gpr[ret], v2_t, t0);
14894             break;
14895         case OPC_SHRAV_R_OB:
14896             check_dspr2(ctx);
14897             gen_helper_shra_r_ob(tcg_ctx, *cpu_gpr[ret], v2_t, v1_t);
14898             break;
14899         case OPC_SHRA_PW:
14900             check_dsp(ctx);
14901             gen_helper_shra_pw(tcg_ctx, *cpu_gpr[ret], v2_t, t0);
14902             break;
14903         case OPC_SHRAV_PW:
14904             check_dsp(ctx);
14905             gen_helper_shra_pw(tcg_ctx, *cpu_gpr[ret], v2_t, v1_t);
14906             break;
14907         case OPC_SHRA_R_PW:
14908             check_dsp(ctx);
14909             gen_helper_shra_r_pw(tcg_ctx, *cpu_gpr[ret], v2_t, t0);
14910             break;
14911         case OPC_SHRAV_R_PW:
14912             check_dsp(ctx);
14913             gen_helper_shra_r_pw(tcg_ctx, *cpu_gpr[ret], v2_t, v1_t);
14914             break;
14915         case OPC_SHRA_QH:
14916             check_dsp(ctx);
14917             gen_helper_shra_qh(tcg_ctx, *cpu_gpr[ret], v2_t, t0);
14918             break;
14919         case OPC_SHRAV_QH:
14920             check_dsp(ctx);
14921             gen_helper_shra_qh(tcg_ctx, *cpu_gpr[ret], v2_t, v1_t);
14922             break;
14923         case OPC_SHRA_R_QH:
14924             check_dsp(ctx);
14925             gen_helper_shra_r_qh(tcg_ctx, *cpu_gpr[ret], v2_t, t0);
14926             break;
14927         case OPC_SHRAV_R_QH:
14928             check_dsp(ctx);
14929             gen_helper_shra_r_qh(tcg_ctx, *cpu_gpr[ret], v2_t, v1_t);
14930             break;
14931         case OPC_SHRL_OB:
14932             check_dsp(ctx);
14933             gen_helper_shrl_ob(tcg_ctx, *cpu_gpr[ret], v2_t, t0);
14934             break;
14935         case OPC_SHRLV_OB:
14936             check_dsp(ctx);
14937             gen_helper_shrl_ob(tcg_ctx, *cpu_gpr[ret], v2_t, v1_t);
14938             break;
14939         case OPC_SHRL_QH:
14940             check_dspr2(ctx);
14941             gen_helper_shrl_qh(tcg_ctx, *cpu_gpr[ret], v2_t, t0);
14942             break;
14943         case OPC_SHRLV_QH:
14944             check_dspr2(ctx);
14945             gen_helper_shrl_qh(tcg_ctx, *cpu_gpr[ret], v2_t, v1_t);
14946             break;
14947         default:            /* Invalid */
14948             MIPS_INVAL("MASK SHLL.OB");
14949             generate_exception(ctx, EXCP_RI);
14950             break;
14951         }
14952         break;
14953 #endif
14954     }
14955 
14956     tcg_temp_free(tcg_ctx, t0);
14957     tcg_temp_free(tcg_ctx, v1_t);
14958     tcg_temp_free(tcg_ctx, v2_t);
14959     (void)opn; /* avoid a compiler warning */
14960     MIPS_DEBUG("%s", opn);
14961 }
14962 
gen_mipsdsp_multiply(DisasContext * ctx,uint32_t op1,uint32_t op2,int ret,int v1,int v2,int check_ret)14963 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
14964                                  int ret, int v1, int v2, int check_ret)
14965 {
14966     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
14967     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
14968     const char *opn = "mipsdsp multiply";
14969     TCGv_i32 t0;
14970     TCGv v1_t;
14971     TCGv v2_t;
14972 
14973     if ((ret == 0) && (check_ret == 1)) {
14974         /* Treat as NOP. */
14975         MIPS_DEBUG("NOP");
14976         return;
14977     }
14978 
14979     t0 = tcg_temp_new_i32(tcg_ctx);
14980     v1_t = tcg_temp_new(tcg_ctx);
14981     v2_t = tcg_temp_new(tcg_ctx);
14982 
14983     tcg_gen_movi_i32(tcg_ctx, t0, ret);
14984     gen_load_gpr(ctx, v1_t, v1);
14985     gen_load_gpr(ctx, v2_t, v2);
14986 
14987     switch (op1) {
14988     /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14989      * the same mask and op1. */
14990     case OPC_MULT_G_2E:
14991         check_dspr2(ctx);
14992         switch (op2) {
14993         case  OPC_MUL_PH:
14994             gen_helper_mul_ph(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14995             break;
14996         case  OPC_MUL_S_PH:
14997             gen_helper_mul_s_ph(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
14998             break;
14999         case OPC_MULQ_S_W:
15000             gen_helper_mulq_s_w(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
15001             break;
15002         case OPC_MULQ_RS_W:
15003             gen_helper_mulq_rs_w(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
15004             break;
15005         }
15006         break;
15007     case OPC_DPA_W_PH_DSP:
15008         switch (op2) {
15009         case OPC_DPAU_H_QBL:
15010             check_dsp(ctx);
15011             gen_helper_dpau_h_qbl(tcg_ctx, t0, v1_t, v2_t, tcg_ctx->cpu_env);
15012             break;
15013         case OPC_DPAU_H_QBR:
15014             check_dsp(ctx);
15015             gen_helper_dpau_h_qbr(tcg_ctx, t0, v1_t, v2_t, tcg_ctx->cpu_env);
15016             break;
15017         case OPC_DPSU_H_QBL:
15018             check_dsp(ctx);
15019             gen_helper_dpsu_h_qbl(tcg_ctx, t0, v1_t, v2_t, tcg_ctx->cpu_env);
15020             break;
15021         case OPC_DPSU_H_QBR:
15022             check_dsp(ctx);
15023             gen_helper_dpsu_h_qbr(tcg_ctx, t0, v1_t, v2_t, tcg_ctx->cpu_env);
15024             break;
15025         case OPC_DPA_W_PH:
15026             check_dspr2(ctx);
15027             gen_helper_dpa_w_ph(tcg_ctx, t0, v1_t, v2_t, tcg_ctx->cpu_env);
15028             break;
15029         case OPC_DPAX_W_PH:
15030             check_dspr2(ctx);
15031             gen_helper_dpax_w_ph(tcg_ctx, t0, v1_t, v2_t, tcg_ctx->cpu_env);
15032             break;
15033         case OPC_DPAQ_S_W_PH:
15034             check_dsp(ctx);
15035             gen_helper_dpaq_s_w_ph(tcg_ctx, t0, v1_t, v2_t, tcg_ctx->cpu_env);
15036             break;
15037         case OPC_DPAQX_S_W_PH:
15038             check_dspr2(ctx);
15039             gen_helper_dpaqx_s_w_ph(tcg_ctx, t0, v1_t, v2_t, tcg_ctx->cpu_env);
15040             break;
15041         case OPC_DPAQX_SA_W_PH:
15042             check_dspr2(ctx);
15043             gen_helper_dpaqx_sa_w_ph(tcg_ctx, t0, v1_t, v2_t, tcg_ctx->cpu_env);
15044             break;
15045         case OPC_DPS_W_PH:
15046             check_dspr2(ctx);
15047             gen_helper_dps_w_ph(tcg_ctx, t0, v1_t, v2_t, tcg_ctx->cpu_env);
15048             break;
15049         case OPC_DPSX_W_PH:
15050             check_dspr2(ctx);
15051             gen_helper_dpsx_w_ph(tcg_ctx, t0, v1_t, v2_t, tcg_ctx->cpu_env);
15052             break;
15053         case OPC_DPSQ_S_W_PH:
15054             check_dsp(ctx);
15055             gen_helper_dpsq_s_w_ph(tcg_ctx, t0, v1_t, v2_t, tcg_ctx->cpu_env);
15056             break;
15057         case OPC_DPSQX_S_W_PH:
15058             check_dspr2(ctx);
15059             gen_helper_dpsqx_s_w_ph(tcg_ctx, t0, v1_t, v2_t, tcg_ctx->cpu_env);
15060             break;
15061         case OPC_DPSQX_SA_W_PH:
15062             check_dspr2(ctx);
15063             gen_helper_dpsqx_sa_w_ph(tcg_ctx, t0, v1_t, v2_t, tcg_ctx->cpu_env);
15064             break;
15065         case OPC_MULSAQ_S_W_PH:
15066             check_dsp(ctx);
15067             gen_helper_mulsaq_s_w_ph(tcg_ctx, t0, v1_t, v2_t, tcg_ctx->cpu_env);
15068             break;
15069         case OPC_DPAQ_SA_L_W:
15070             check_dsp(ctx);
15071             gen_helper_dpaq_sa_l_w(tcg_ctx, t0, v1_t, v2_t, tcg_ctx->cpu_env);
15072             break;
15073         case OPC_DPSQ_SA_L_W:
15074             check_dsp(ctx);
15075             gen_helper_dpsq_sa_l_w(tcg_ctx, t0, v1_t, v2_t, tcg_ctx->cpu_env);
15076             break;
15077         case OPC_MAQ_S_W_PHL:
15078             check_dsp(ctx);
15079             gen_helper_maq_s_w_phl(tcg_ctx, t0, v1_t, v2_t, tcg_ctx->cpu_env);
15080             break;
15081         case OPC_MAQ_S_W_PHR:
15082             check_dsp(ctx);
15083             gen_helper_maq_s_w_phr(tcg_ctx, t0, v1_t, v2_t, tcg_ctx->cpu_env);
15084             break;
15085         case OPC_MAQ_SA_W_PHL:
15086             check_dsp(ctx);
15087             gen_helper_maq_sa_w_phl(tcg_ctx, t0, v1_t, v2_t, tcg_ctx->cpu_env);
15088             break;
15089         case OPC_MAQ_SA_W_PHR:
15090             check_dsp(ctx);
15091             gen_helper_maq_sa_w_phr(tcg_ctx, t0, v1_t, v2_t, tcg_ctx->cpu_env);
15092             break;
15093         case OPC_MULSA_W_PH:
15094             check_dspr2(ctx);
15095             gen_helper_mulsa_w_ph(tcg_ctx, t0, v1_t, v2_t, tcg_ctx->cpu_env);
15096             break;
15097         }
15098         break;
15099 #ifdef TARGET_MIPS64
15100     case OPC_DPAQ_W_QH_DSP:
15101         {
15102             int ac = ret & 0x03;
15103             tcg_gen_movi_i32(tcg_ctx, t0, ac);
15104 
15105             switch (op2) {
15106             case OPC_DMADD:
15107                 check_dsp(ctx);
15108                 gen_helper_dmadd(tcg_ctx, v1_t, v2_t, t0, tcg_ctx->cpu_env);
15109                 break;
15110             case OPC_DMADDU:
15111                 check_dsp(ctx);
15112                 gen_helper_dmaddu(tcg_ctx, v1_t, v2_t, t0, tcg_ctx->cpu_env);
15113                 break;
15114             case OPC_DMSUB:
15115                 check_dsp(ctx);
15116                 gen_helper_dmsub(tcg_ctx, v1_t, v2_t, t0, tcg_ctx->cpu_env);
15117                 break;
15118             case OPC_DMSUBU:
15119                 check_dsp(ctx);
15120                 gen_helper_dmsubu(tcg_ctx, v1_t, v2_t, t0, tcg_ctx->cpu_env);
15121                 break;
15122             case OPC_DPA_W_QH:
15123                 check_dspr2(ctx);
15124                 gen_helper_dpa_w_qh(tcg_ctx, v1_t, v2_t, t0, tcg_ctx->cpu_env);
15125                 break;
15126             case OPC_DPAQ_S_W_QH:
15127                 check_dsp(ctx);
15128                 gen_helper_dpaq_s_w_qh(tcg_ctx, v1_t, v2_t, t0, tcg_ctx->cpu_env);
15129                 break;
15130             case OPC_DPAQ_SA_L_PW:
15131                 check_dsp(ctx);
15132                 gen_helper_dpaq_sa_l_pw(tcg_ctx, v1_t, v2_t, t0, tcg_ctx->cpu_env);
15133                 break;
15134             case OPC_DPAU_H_OBL:
15135                 check_dsp(ctx);
15136                 gen_helper_dpau_h_obl(tcg_ctx, v1_t, v2_t, t0, tcg_ctx->cpu_env);
15137                 break;
15138             case OPC_DPAU_H_OBR:
15139                 check_dsp(ctx);
15140                 gen_helper_dpau_h_obr(tcg_ctx, v1_t, v2_t, t0, tcg_ctx->cpu_env);
15141                 break;
15142             case OPC_DPS_W_QH:
15143                 check_dspr2(ctx);
15144                 gen_helper_dps_w_qh(tcg_ctx, v1_t, v2_t, t0, tcg_ctx->cpu_env);
15145                 break;
15146             case OPC_DPSQ_S_W_QH:
15147                 check_dsp(ctx);
15148                 gen_helper_dpsq_s_w_qh(tcg_ctx, v1_t, v2_t, t0, tcg_ctx->cpu_env);
15149                 break;
15150             case OPC_DPSQ_SA_L_PW:
15151                 check_dsp(ctx);
15152                 gen_helper_dpsq_sa_l_pw(tcg_ctx, v1_t, v2_t, t0, tcg_ctx->cpu_env);
15153                 break;
15154             case OPC_DPSU_H_OBL:
15155                 check_dsp(ctx);
15156                 gen_helper_dpsu_h_obl(tcg_ctx, v1_t, v2_t, t0, tcg_ctx->cpu_env);
15157                 break;
15158             case OPC_DPSU_H_OBR:
15159                 check_dsp(ctx);
15160                 gen_helper_dpsu_h_obr(tcg_ctx, v1_t, v2_t, t0, tcg_ctx->cpu_env);
15161                 break;
15162             case OPC_MAQ_S_L_PWL:
15163                 check_dsp(ctx);
15164                 gen_helper_maq_s_l_pwl(tcg_ctx, v1_t, v2_t, t0, tcg_ctx->cpu_env);
15165                 break;
15166             case OPC_MAQ_S_L_PWR:
15167                 check_dsp(ctx);
15168                 gen_helper_maq_s_l_pwr(tcg_ctx, v1_t, v2_t, t0, tcg_ctx->cpu_env);
15169                 break;
15170             case OPC_MAQ_S_W_QHLL:
15171                 check_dsp(ctx);
15172                 gen_helper_maq_s_w_qhll(tcg_ctx, v1_t, v2_t, t0, tcg_ctx->cpu_env);
15173                 break;
15174             case OPC_MAQ_SA_W_QHLL:
15175                 check_dsp(ctx);
15176                 gen_helper_maq_sa_w_qhll(tcg_ctx, v1_t, v2_t, t0, tcg_ctx->cpu_env);
15177                 break;
15178             case OPC_MAQ_S_W_QHLR:
15179                 check_dsp(ctx);
15180                 gen_helper_maq_s_w_qhlr(tcg_ctx, v1_t, v2_t, t0, tcg_ctx->cpu_env);
15181                 break;
15182             case OPC_MAQ_SA_W_QHLR:
15183                 check_dsp(ctx);
15184                 gen_helper_maq_sa_w_qhlr(tcg_ctx, v1_t, v2_t, t0, tcg_ctx->cpu_env);
15185                 break;
15186             case OPC_MAQ_S_W_QHRL:
15187                 check_dsp(ctx);
15188                 gen_helper_maq_s_w_qhrl(tcg_ctx, v1_t, v2_t, t0, tcg_ctx->cpu_env);
15189                 break;
15190             case OPC_MAQ_SA_W_QHRL:
15191                 check_dsp(ctx);
15192                 gen_helper_maq_sa_w_qhrl(tcg_ctx, v1_t, v2_t, t0, tcg_ctx->cpu_env);
15193                 break;
15194             case OPC_MAQ_S_W_QHRR:
15195                 check_dsp(ctx);
15196                 gen_helper_maq_s_w_qhrr(tcg_ctx, v1_t, v2_t, t0, tcg_ctx->cpu_env);
15197                 break;
15198             case OPC_MAQ_SA_W_QHRR:
15199                 check_dsp(ctx);
15200                 gen_helper_maq_sa_w_qhrr(tcg_ctx, v1_t, v2_t, t0, tcg_ctx->cpu_env);
15201                 break;
15202             case OPC_MULSAQ_S_L_PW:
15203                 check_dsp(ctx);
15204                 gen_helper_mulsaq_s_l_pw(tcg_ctx, v1_t, v2_t, t0, tcg_ctx->cpu_env);
15205                 break;
15206             case OPC_MULSAQ_S_W_QH:
15207                 check_dsp(ctx);
15208                 gen_helper_mulsaq_s_w_qh(tcg_ctx, v1_t, v2_t, t0, tcg_ctx->cpu_env);
15209                 break;
15210             }
15211         }
15212         break;
15213 #endif
15214     case OPC_ADDU_QB_DSP:
15215         switch (op2) {
15216         case OPC_MULEU_S_PH_QBL:
15217             check_dsp(ctx);
15218             gen_helper_muleu_s_ph_qbl(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
15219             break;
15220         case OPC_MULEU_S_PH_QBR:
15221             check_dsp(ctx);
15222             gen_helper_muleu_s_ph_qbr(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
15223             break;
15224         case OPC_MULQ_RS_PH:
15225             check_dsp(ctx);
15226             gen_helper_mulq_rs_ph(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
15227             break;
15228         case OPC_MULEQ_S_W_PHL:
15229             check_dsp(ctx);
15230             gen_helper_muleq_s_w_phl(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
15231             break;
15232         case OPC_MULEQ_S_W_PHR:
15233             check_dsp(ctx);
15234             gen_helper_muleq_s_w_phr(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
15235             break;
15236         case OPC_MULQ_S_PH:
15237             check_dspr2(ctx);
15238             gen_helper_mulq_s_ph(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
15239             break;
15240         }
15241         break;
15242 #ifdef TARGET_MIPS64
15243     case OPC_ADDU_OB_DSP:
15244         switch (op2) {
15245         case OPC_MULEQ_S_PW_QHL:
15246             check_dsp(ctx);
15247             gen_helper_muleq_s_pw_qhl(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
15248             break;
15249         case OPC_MULEQ_S_PW_QHR:
15250             check_dsp(ctx);
15251             gen_helper_muleq_s_pw_qhr(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
15252             break;
15253         case OPC_MULEU_S_QH_OBL:
15254             check_dsp(ctx);
15255             gen_helper_muleu_s_qh_obl(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
15256             break;
15257         case OPC_MULEU_S_QH_OBR:
15258             check_dsp(ctx);
15259             gen_helper_muleu_s_qh_obr(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
15260             break;
15261         case OPC_MULQ_RS_QH:
15262             check_dsp(ctx);
15263             gen_helper_mulq_rs_qh(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
15264             break;
15265         }
15266         break;
15267 #endif
15268     }
15269 
15270     tcg_temp_free_i32(tcg_ctx, t0);
15271     tcg_temp_free(tcg_ctx, v1_t);
15272     tcg_temp_free(tcg_ctx, v2_t);
15273 
15274     (void)opn; /* avoid a compiler warning */
15275     MIPS_DEBUG("%s", opn);
15276 
15277 }
15278 
gen_mipsdsp_bitinsn(DisasContext * ctx,uint32_t op1,uint32_t op2,int ret,int val)15279 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
15280                                 int ret, int val)
15281 {
15282     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
15283     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
15284     const char *opn = "mipsdsp Bit/ Manipulation";
15285     int16_t imm;
15286     TCGv t0;
15287     TCGv val_t;
15288 
15289     if (ret == 0) {
15290         /* Treat as NOP. */
15291         MIPS_DEBUG("NOP");
15292         return;
15293     }
15294 
15295     t0 = tcg_temp_new(tcg_ctx);
15296     val_t = tcg_temp_new(tcg_ctx);
15297     gen_load_gpr(ctx, val_t, val);
15298 
15299     switch (op1) {
15300     case OPC_ABSQ_S_PH_DSP:
15301         switch (op2) {
15302         case OPC_BITREV:
15303             check_dsp(ctx);
15304             gen_helper_bitrev(tcg_ctx, *cpu_gpr[ret], val_t);
15305             break;
15306         case OPC_REPL_QB:
15307             check_dsp(ctx);
15308             {
15309                 target_long result;
15310                 imm = (ctx->opcode >> 16) & 0xFF;
15311                 result = (uint32_t)imm << 24 |
15312                          (uint32_t)imm << 16 |
15313                          (uint32_t)imm << 8  |
15314                          (uint32_t)imm;
15315                 result = (int32_t)result;
15316                 tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[ret], result);
15317             }
15318             break;
15319         case OPC_REPLV_QB:
15320             check_dsp(ctx);
15321             tcg_gen_ext8u_tl(tcg_ctx, *cpu_gpr[ret], val_t);
15322             tcg_gen_shli_tl(tcg_ctx, t0, *cpu_gpr[ret], 8);
15323             tcg_gen_or_tl(tcg_ctx, *cpu_gpr[ret], *cpu_gpr[ret], t0);
15324             tcg_gen_shli_tl(tcg_ctx, t0, *cpu_gpr[ret], 16);
15325             tcg_gen_or_tl(tcg_ctx, *cpu_gpr[ret], *cpu_gpr[ret], t0);
15326             tcg_gen_ext32s_tl(tcg_ctx, *cpu_gpr[ret], *cpu_gpr[ret]);
15327             break;
15328         case OPC_REPL_PH:
15329             check_dsp(ctx);
15330             {
15331                 imm = (ctx->opcode >> 16) & 0x03FF;
15332                 imm = (int16_t)(imm << 6) >> 6;
15333                 tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[ret], \
15334                                 (target_long)((int32_t)((uint32_t)imm << 16) | \
15335                                 (uint16_t)imm));
15336             }
15337             break;
15338         case OPC_REPLV_PH:
15339             check_dsp(ctx);
15340             tcg_gen_ext16u_tl(tcg_ctx, *cpu_gpr[ret], val_t);
15341             tcg_gen_shli_tl(tcg_ctx, t0, *cpu_gpr[ret], 16);
15342             tcg_gen_or_tl(tcg_ctx, *cpu_gpr[ret], *cpu_gpr[ret], t0);
15343             tcg_gen_ext32s_tl(tcg_ctx, *cpu_gpr[ret], *cpu_gpr[ret]);
15344             break;
15345         }
15346         break;
15347 #ifdef TARGET_MIPS64
15348     case OPC_ABSQ_S_QH_DSP:
15349         switch (op2) {
15350         case OPC_REPL_OB:
15351             check_dsp(ctx);
15352             {
15353                 target_long temp;
15354 
15355                 imm = (ctx->opcode >> 16) & 0xFF;
15356                 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
15357                 temp = (temp << 16) | temp;
15358                 temp = (temp << 32) | temp;
15359                 tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[ret], temp);
15360                 break;
15361             }
15362         case OPC_REPL_PW:
15363             check_dsp(ctx);
15364             {
15365                 target_long temp;
15366 
15367                 imm = (ctx->opcode >> 16) & 0x03FF;
15368                 imm = (int16_t)(imm << 6) >> 6;
15369                 temp = ((target_long)imm << 32) \
15370                        | ((target_long)imm & 0xFFFFFFFF);
15371                 tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[ret], temp);
15372                 break;
15373             }
15374         case OPC_REPL_QH:
15375             check_dsp(ctx);
15376             {
15377                 target_long temp;
15378 
15379                 imm = (ctx->opcode >> 16) & 0x03FF;
15380                 imm = (int16_t)(imm << 6) >> 6;
15381 
15382                 temp = ((uint64_t)(uint16_t)imm << 48) |
15383                        ((uint64_t)(uint16_t)imm << 32) |
15384                        ((uint64_t)(uint16_t)imm << 16) |
15385                        (uint64_t)(uint16_t)imm;
15386                 tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[ret], temp);
15387                 break;
15388             }
15389         case OPC_REPLV_OB:
15390             check_dsp(ctx);
15391             tcg_gen_ext8u_tl(tcg_ctx, *cpu_gpr[ret], val_t);
15392             tcg_gen_shli_tl(tcg_ctx, t0, *cpu_gpr[ret], 8);
15393             tcg_gen_or_tl(tcg_ctx, *cpu_gpr[ret], *cpu_gpr[ret], t0);
15394             tcg_gen_shli_tl(tcg_ctx, t0, *cpu_gpr[ret], 16);
15395             tcg_gen_or_tl(tcg_ctx, *cpu_gpr[ret], *cpu_gpr[ret], t0);
15396             tcg_gen_shli_tl(tcg_ctx, t0, *cpu_gpr[ret], 32);
15397             tcg_gen_or_tl(tcg_ctx, *cpu_gpr[ret], *cpu_gpr[ret], t0);
15398             break;
15399         case OPC_REPLV_PW:
15400             check_dsp(ctx);
15401             tcg_gen_ext32u_i64(tcg_ctx, *cpu_gpr[ret], val_t);
15402             tcg_gen_shli_tl(tcg_ctx, t0, *cpu_gpr[ret], 32);
15403             tcg_gen_or_tl(tcg_ctx, *cpu_gpr[ret], *cpu_gpr[ret], t0);
15404             break;
15405         case OPC_REPLV_QH:
15406             check_dsp(ctx);
15407             tcg_gen_ext16u_tl(tcg_ctx, *cpu_gpr[ret], val_t);
15408             tcg_gen_shli_tl(tcg_ctx, t0, *cpu_gpr[ret], 16);
15409             tcg_gen_or_tl(tcg_ctx, *cpu_gpr[ret], *cpu_gpr[ret], t0);
15410             tcg_gen_shli_tl(tcg_ctx, t0, *cpu_gpr[ret], 32);
15411             tcg_gen_or_tl(tcg_ctx, *cpu_gpr[ret], *cpu_gpr[ret], t0);
15412             break;
15413         }
15414         break;
15415 #endif
15416     }
15417     tcg_temp_free(tcg_ctx, t0);
15418     tcg_temp_free(tcg_ctx, val_t);
15419 
15420     (void)opn; /* avoid a compiler warning */
15421     MIPS_DEBUG("%s", opn);
15422 }
15423 
gen_mipsdsp_add_cmp_pick(DisasContext * ctx,uint32_t op1,uint32_t op2,int ret,int v1,int v2,int check_ret)15424 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
15425                                      uint32_t op1, uint32_t op2,
15426                                      int ret, int v1, int v2, int check_ret)
15427 {
15428     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
15429     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
15430     const char *opn = "mipsdsp add compare pick";
15431     TCGv t1;
15432     TCGv v1_t;
15433     TCGv v2_t;
15434 
15435     if ((ret == 0) && (check_ret == 1)) {
15436         /* Treat as NOP. */
15437         MIPS_DEBUG("NOP");
15438         return;
15439     }
15440 
15441     t1 = tcg_temp_new(tcg_ctx);
15442     v1_t = tcg_temp_new(tcg_ctx);
15443     v2_t = tcg_temp_new(tcg_ctx);
15444 
15445     gen_load_gpr(ctx, v1_t, v1);
15446     gen_load_gpr(ctx, v2_t, v2);
15447 
15448     switch (op1) {
15449     case OPC_CMPU_EQ_QB_DSP:
15450         switch (op2) {
15451         case OPC_CMPU_EQ_QB:
15452             check_dsp(ctx);
15453             gen_helper_cmpu_eq_qb(tcg_ctx, v1_t, v2_t, tcg_ctx->cpu_env);
15454             break;
15455         case OPC_CMPU_LT_QB:
15456             check_dsp(ctx);
15457             gen_helper_cmpu_lt_qb(tcg_ctx, v1_t, v2_t, tcg_ctx->cpu_env);
15458             break;
15459         case OPC_CMPU_LE_QB:
15460             check_dsp(ctx);
15461             gen_helper_cmpu_le_qb(tcg_ctx, v1_t, v2_t, tcg_ctx->cpu_env);
15462             break;
15463         case OPC_CMPGU_EQ_QB:
15464             check_dsp(ctx);
15465             gen_helper_cmpgu_eq_qb(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
15466             break;
15467         case OPC_CMPGU_LT_QB:
15468             check_dsp(ctx);
15469             gen_helper_cmpgu_lt_qb(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
15470             break;
15471         case OPC_CMPGU_LE_QB:
15472             check_dsp(ctx);
15473             gen_helper_cmpgu_le_qb(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
15474             break;
15475         case OPC_CMPGDU_EQ_QB:
15476             check_dspr2(ctx);
15477             gen_helper_cmpgu_eq_qb(tcg_ctx, t1, v1_t, v2_t);
15478             tcg_gen_mov_tl(tcg_ctx, *cpu_gpr[ret], t1);
15479             tcg_gen_andi_tl(tcg_ctx, *(TCGv *)tcg_ctx->cpu_dspctrl, *(TCGv *)tcg_ctx->cpu_dspctrl, 0xF0FFFFFF);
15480             tcg_gen_shli_tl(tcg_ctx, t1, t1, 24);
15481             tcg_gen_or_tl(tcg_ctx, *(TCGv *)tcg_ctx->cpu_dspctrl, *(TCGv *)tcg_ctx->cpu_dspctrl, t1);
15482             break;
15483         case OPC_CMPGDU_LT_QB:
15484             check_dspr2(ctx);
15485             gen_helper_cmpgu_lt_qb(tcg_ctx, t1, v1_t, v2_t);
15486             tcg_gen_mov_tl(tcg_ctx, *cpu_gpr[ret], t1);
15487             tcg_gen_andi_tl(tcg_ctx, *(TCGv *)tcg_ctx->cpu_dspctrl, *(TCGv *)tcg_ctx->cpu_dspctrl, 0xF0FFFFFF);
15488             tcg_gen_shli_tl(tcg_ctx, t1, t1, 24);
15489             tcg_gen_or_tl(tcg_ctx, *(TCGv *)tcg_ctx->cpu_dspctrl, *(TCGv *)tcg_ctx->cpu_dspctrl, t1);
15490             break;
15491         case OPC_CMPGDU_LE_QB:
15492             check_dspr2(ctx);
15493             gen_helper_cmpgu_le_qb(tcg_ctx, t1, v1_t, v2_t);
15494             tcg_gen_mov_tl(tcg_ctx, *cpu_gpr[ret], t1);
15495             tcg_gen_andi_tl(tcg_ctx, *(TCGv *)tcg_ctx->cpu_dspctrl, *(TCGv *)tcg_ctx->cpu_dspctrl, 0xF0FFFFFF);
15496             tcg_gen_shli_tl(tcg_ctx, t1, t1, 24);
15497             tcg_gen_or_tl(tcg_ctx, *(TCGv *)tcg_ctx->cpu_dspctrl, *(TCGv *)tcg_ctx->cpu_dspctrl, t1);
15498             break;
15499         case OPC_CMP_EQ_PH:
15500             check_dsp(ctx);
15501             gen_helper_cmp_eq_ph(tcg_ctx, v1_t, v2_t, tcg_ctx->cpu_env);
15502             break;
15503         case OPC_CMP_LT_PH:
15504             check_dsp(ctx);
15505             gen_helper_cmp_lt_ph(tcg_ctx, v1_t, v2_t, tcg_ctx->cpu_env);
15506             break;
15507         case OPC_CMP_LE_PH:
15508             check_dsp(ctx);
15509             gen_helper_cmp_le_ph(tcg_ctx, v1_t, v2_t, tcg_ctx->cpu_env);
15510             break;
15511         case OPC_PICK_QB:
15512             check_dsp(ctx);
15513             gen_helper_pick_qb(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
15514             break;
15515         case OPC_PICK_PH:
15516             check_dsp(ctx);
15517             gen_helper_pick_ph(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
15518             break;
15519         case OPC_PACKRL_PH:
15520             check_dsp(ctx);
15521             gen_helper_packrl_ph(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
15522             break;
15523         }
15524         break;
15525 #ifdef TARGET_MIPS64
15526     case OPC_CMPU_EQ_OB_DSP:
15527         switch (op2) {
15528         case OPC_CMP_EQ_PW:
15529             check_dsp(ctx);
15530             gen_helper_cmp_eq_pw(tcg_ctx, v1_t, v2_t, tcg_ctx->cpu_env);
15531             break;
15532         case OPC_CMP_LT_PW:
15533             check_dsp(ctx);
15534             gen_helper_cmp_lt_pw(tcg_ctx, v1_t, v2_t, tcg_ctx->cpu_env);
15535             break;
15536         case OPC_CMP_LE_PW:
15537             check_dsp(ctx);
15538             gen_helper_cmp_le_pw(tcg_ctx, v1_t, v2_t, tcg_ctx->cpu_env);
15539             break;
15540         case OPC_CMP_EQ_QH:
15541             check_dsp(ctx);
15542             gen_helper_cmp_eq_qh(tcg_ctx, v1_t, v2_t, tcg_ctx->cpu_env);
15543             break;
15544         case OPC_CMP_LT_QH:
15545             check_dsp(ctx);
15546             gen_helper_cmp_lt_qh(tcg_ctx, v1_t, v2_t, tcg_ctx->cpu_env);
15547             break;
15548         case OPC_CMP_LE_QH:
15549             check_dsp(ctx);
15550             gen_helper_cmp_le_qh(tcg_ctx, v1_t, v2_t, tcg_ctx->cpu_env);
15551             break;
15552         case OPC_CMPGDU_EQ_OB:
15553             check_dspr2(ctx);
15554             gen_helper_cmpgdu_eq_ob(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
15555             break;
15556         case OPC_CMPGDU_LT_OB:
15557             check_dspr2(ctx);
15558             gen_helper_cmpgdu_lt_ob(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
15559             break;
15560         case OPC_CMPGDU_LE_OB:
15561             check_dspr2(ctx);
15562             gen_helper_cmpgdu_le_ob(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
15563             break;
15564         case OPC_CMPGU_EQ_OB:
15565             check_dsp(ctx);
15566             gen_helper_cmpgu_eq_ob(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
15567             break;
15568         case OPC_CMPGU_LT_OB:
15569             check_dsp(ctx);
15570             gen_helper_cmpgu_lt_ob(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
15571             break;
15572         case OPC_CMPGU_LE_OB:
15573             check_dsp(ctx);
15574             gen_helper_cmpgu_le_ob(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
15575             break;
15576         case OPC_CMPU_EQ_OB:
15577             check_dsp(ctx);
15578             gen_helper_cmpu_eq_ob(tcg_ctx, v1_t, v2_t, tcg_ctx->cpu_env);
15579             break;
15580         case OPC_CMPU_LT_OB:
15581             check_dsp(ctx);
15582             gen_helper_cmpu_lt_ob(tcg_ctx, v1_t, v2_t, tcg_ctx->cpu_env);
15583             break;
15584         case OPC_CMPU_LE_OB:
15585             check_dsp(ctx);
15586             gen_helper_cmpu_le_ob(tcg_ctx, v1_t, v2_t, tcg_ctx->cpu_env);
15587             break;
15588         case OPC_PACKRL_PW:
15589             check_dsp(ctx);
15590             gen_helper_packrl_pw(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t);
15591             break;
15592         case OPC_PICK_OB:
15593             check_dsp(ctx);
15594             gen_helper_pick_ob(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
15595             break;
15596         case OPC_PICK_PW:
15597             check_dsp(ctx);
15598             gen_helper_pick_pw(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
15599             break;
15600         case OPC_PICK_QH:
15601             check_dsp(ctx);
15602             gen_helper_pick_qh(tcg_ctx, *cpu_gpr[ret], v1_t, v2_t, tcg_ctx->cpu_env);
15603             break;
15604         }
15605         break;
15606 #endif
15607     }
15608 
15609     tcg_temp_free(tcg_ctx, t1);
15610     tcg_temp_free(tcg_ctx, v1_t);
15611     tcg_temp_free(tcg_ctx, v2_t);
15612 
15613     (void)opn; /* avoid a compiler warning */
15614     MIPS_DEBUG("%s", opn);
15615 }
15616 
gen_mipsdsp_append(CPUMIPSState * env,DisasContext * ctx,uint32_t op1,int rt,int rs,int sa)15617 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
15618                                uint32_t op1, int rt, int rs, int sa)
15619 {
15620     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
15621     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
15622     const char *opn = "mipsdsp append/dappend";
15623     TCGv t0;
15624 
15625     check_dspr2(ctx);
15626 
15627     if (rt == 0) {
15628         /* Treat as NOP. */
15629         MIPS_DEBUG("NOP");
15630         return;
15631     }
15632 
15633     t0 = tcg_temp_new(tcg_ctx);
15634     gen_load_gpr(ctx, t0, rs);
15635 
15636     switch (op1) {
15637     case OPC_APPEND_DSP:
15638         switch (MASK_APPEND(ctx->opcode)) {
15639         case OPC_APPEND:
15640             if (sa != 0) {
15641                 tcg_gen_deposit_tl(tcg_ctx, *cpu_gpr[rt], t0, *cpu_gpr[rt], sa, 32 - sa);
15642             }
15643             tcg_gen_ext32s_tl(tcg_ctx, *cpu_gpr[rt], *cpu_gpr[rt]);
15644             break;
15645         case OPC_PREPEND:
15646             if (sa != 0) {
15647                 tcg_gen_ext32u_tl(tcg_ctx, *cpu_gpr[rt], *cpu_gpr[rt]);
15648                 tcg_gen_shri_tl(tcg_ctx, *cpu_gpr[rt], *cpu_gpr[rt], sa);
15649                 tcg_gen_shli_tl(tcg_ctx, t0, t0, 32 - sa);
15650                 tcg_gen_or_tl(tcg_ctx, *cpu_gpr[rt], *cpu_gpr[rt], t0);
15651             }
15652             tcg_gen_ext32s_tl(tcg_ctx, *cpu_gpr[rt], *cpu_gpr[rt]);
15653             break;
15654         case OPC_BALIGN:
15655             sa &= 3;
15656             if (sa != 0 && sa != 2) {
15657                 tcg_gen_shli_tl(tcg_ctx, *cpu_gpr[rt], *cpu_gpr[rt], 8 * sa);
15658                 tcg_gen_ext32u_tl(tcg_ctx, t0, t0);
15659                 tcg_gen_shri_tl(tcg_ctx, t0, t0, 8 * (4 - sa));
15660                 tcg_gen_or_tl(tcg_ctx, *cpu_gpr[rt], *cpu_gpr[rt], t0);
15661             }
15662             tcg_gen_ext32s_tl(tcg_ctx, *cpu_gpr[rt], *cpu_gpr[rt]);
15663             break;
15664         default:            /* Invalid */
15665             MIPS_INVAL("MASK APPEND");
15666             generate_exception(ctx, EXCP_RI);
15667             break;
15668         }
15669         break;
15670 #ifdef TARGET_MIPS64
15671     case OPC_DAPPEND_DSP:
15672         switch (MASK_DAPPEND(ctx->opcode)) {
15673         case OPC_DAPPEND:
15674             if (sa != 0) {
15675                 tcg_gen_deposit_tl(tcg_ctx, *cpu_gpr[rt], t0, *cpu_gpr[rt], sa, 64 - sa);
15676             }
15677             break;
15678         case OPC_PREPENDD:
15679             tcg_gen_shri_tl(tcg_ctx, *cpu_gpr[rt], *cpu_gpr[rt], 0x20 | sa);
15680             tcg_gen_shli_tl(tcg_ctx, t0, t0, 64 - (0x20 | sa));
15681             tcg_gen_or_tl(tcg_ctx, *cpu_gpr[rt], t0, t0);
15682             break;
15683         case OPC_PREPENDW:
15684             if (sa != 0) {
15685                 tcg_gen_shri_tl(tcg_ctx, *cpu_gpr[rt], *cpu_gpr[rt], sa);
15686                 tcg_gen_shli_tl(tcg_ctx, t0, t0, 64 - sa);
15687                 tcg_gen_or_tl(tcg_ctx, *cpu_gpr[rt], *cpu_gpr[rt], t0);
15688             }
15689             break;
15690         case OPC_DBALIGN:
15691             sa &= 7;
15692             if (sa != 0 && sa != 2 && sa != 4) {
15693                 tcg_gen_shli_tl(tcg_ctx, *cpu_gpr[rt], *cpu_gpr[rt], 8 * sa);
15694                 tcg_gen_shri_tl(tcg_ctx, t0, t0, 8 * (8 - sa));
15695                 tcg_gen_or_tl(tcg_ctx, *cpu_gpr[rt], *cpu_gpr[rt], t0);
15696             }
15697             break;
15698         default:            /* Invalid */
15699             MIPS_INVAL("MASK DAPPEND");
15700             generate_exception(ctx, EXCP_RI);
15701             break;
15702         }
15703         break;
15704 #endif
15705     }
15706     tcg_temp_free(tcg_ctx, t0);
15707     (void)opn; /* avoid a compiler warning */
15708     MIPS_DEBUG("%s", opn);
15709 }
15710 
gen_mipsdsp_accinsn(DisasContext * ctx,uint32_t op1,uint32_t op2,int ret,int v1,int v2,int check_ret)15711 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
15712                                 int ret, int v1, int v2, int check_ret)
15713 
15714 {
15715     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
15716     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
15717     const char *opn = "mipsdsp accumulator";
15718     TCGv t0;
15719     TCGv t1;
15720     TCGv v1_t;
15721     TCGv v2_t;
15722     int16_t imm;
15723 
15724     if ((ret == 0) && (check_ret == 1)) {
15725         /* Treat as NOP. */
15726         MIPS_DEBUG("NOP");
15727         return;
15728     }
15729 
15730     t0 = tcg_temp_new(tcg_ctx);
15731     t1 = tcg_temp_new(tcg_ctx);
15732     v1_t = tcg_temp_new(tcg_ctx);
15733     v2_t = tcg_temp_new(tcg_ctx);
15734 
15735     gen_load_gpr(ctx, v1_t, v1);
15736     gen_load_gpr(ctx, v2_t, v2);
15737 
15738     switch (op1) {
15739     case OPC_EXTR_W_DSP:
15740         check_dsp(ctx);
15741         switch (op2) {
15742         case OPC_EXTR_W:
15743             tcg_gen_movi_tl(tcg_ctx, t0, v2);
15744             tcg_gen_movi_tl(tcg_ctx, t1, v1);
15745             gen_helper_extr_w(tcg_ctx, *cpu_gpr[ret], t0, t1, tcg_ctx->cpu_env);
15746             break;
15747         case OPC_EXTR_R_W:
15748             tcg_gen_movi_tl(tcg_ctx, t0, v2);
15749             tcg_gen_movi_tl(tcg_ctx, t1, v1);
15750             gen_helper_extr_r_w(tcg_ctx, *cpu_gpr[ret], t0, t1, tcg_ctx->cpu_env);
15751             break;
15752         case OPC_EXTR_RS_W:
15753             tcg_gen_movi_tl(tcg_ctx, t0, v2);
15754             tcg_gen_movi_tl(tcg_ctx, t1, v1);
15755             gen_helper_extr_rs_w(tcg_ctx, *cpu_gpr[ret], t0, t1, tcg_ctx->cpu_env);
15756             break;
15757         case OPC_EXTR_S_H:
15758             tcg_gen_movi_tl(tcg_ctx, t0, v2);
15759             tcg_gen_movi_tl(tcg_ctx, t1, v1);
15760             gen_helper_extr_s_h(tcg_ctx, *cpu_gpr[ret], t0, t1, tcg_ctx->cpu_env);
15761             break;
15762         case OPC_EXTRV_S_H:
15763             tcg_gen_movi_tl(tcg_ctx, t0, v2);
15764             gen_helper_extr_s_h(tcg_ctx, *cpu_gpr[ret], t0, v1_t, tcg_ctx->cpu_env);
15765             break;
15766         case OPC_EXTRV_W:
15767             tcg_gen_movi_tl(tcg_ctx, t0, v2);
15768             gen_helper_extr_w(tcg_ctx, *cpu_gpr[ret], t0, v1_t, tcg_ctx->cpu_env);
15769             break;
15770         case OPC_EXTRV_R_W:
15771             tcg_gen_movi_tl(tcg_ctx, t0, v2);
15772             gen_helper_extr_r_w(tcg_ctx, *cpu_gpr[ret], t0, v1_t, tcg_ctx->cpu_env);
15773             break;
15774         case OPC_EXTRV_RS_W:
15775             tcg_gen_movi_tl(tcg_ctx, t0, v2);
15776             gen_helper_extr_rs_w(tcg_ctx, *cpu_gpr[ret], t0, v1_t, tcg_ctx->cpu_env);
15777             break;
15778         case OPC_EXTP:
15779             tcg_gen_movi_tl(tcg_ctx, t0, v2);
15780             tcg_gen_movi_tl(tcg_ctx, t1, v1);
15781             gen_helper_extp(tcg_ctx, *cpu_gpr[ret], t0, t1, tcg_ctx->cpu_env);
15782             break;
15783         case OPC_EXTPV:
15784             tcg_gen_movi_tl(tcg_ctx, t0, v2);
15785             gen_helper_extp(tcg_ctx, *cpu_gpr[ret], t0, v1_t, tcg_ctx->cpu_env);
15786             break;
15787         case OPC_EXTPDP:
15788             tcg_gen_movi_tl(tcg_ctx, t0, v2);
15789             tcg_gen_movi_tl(tcg_ctx, t1, v1);
15790             gen_helper_extpdp(tcg_ctx, *cpu_gpr[ret], t0, t1, tcg_ctx->cpu_env);
15791             break;
15792         case OPC_EXTPDPV:
15793             tcg_gen_movi_tl(tcg_ctx, t0, v2);
15794             gen_helper_extpdp(tcg_ctx, *cpu_gpr[ret], t0, v1_t, tcg_ctx->cpu_env);
15795             break;
15796         case OPC_SHILO:
15797             imm = (ctx->opcode >> 20) & 0x3F;
15798             tcg_gen_movi_tl(tcg_ctx, t0, ret);
15799             tcg_gen_movi_tl(tcg_ctx, t1, imm);
15800             gen_helper_shilo(tcg_ctx, t0, t1, tcg_ctx->cpu_env);
15801             break;
15802         case OPC_SHILOV:
15803             tcg_gen_movi_tl(tcg_ctx, t0, ret);
15804             gen_helper_shilo(tcg_ctx, t0, v1_t, tcg_ctx->cpu_env);
15805             break;
15806         case OPC_MTHLIP:
15807             tcg_gen_movi_tl(tcg_ctx, t0, ret);
15808             gen_helper_mthlip(tcg_ctx, t0, v1_t, tcg_ctx->cpu_env);
15809             break;
15810         case OPC_WRDSP:
15811             imm = (ctx->opcode >> 11) & 0x3FF;
15812             tcg_gen_movi_tl(tcg_ctx, t0, imm);
15813             gen_helper_wrdsp(tcg_ctx, v1_t, t0, tcg_ctx->cpu_env);
15814             break;
15815         case OPC_RDDSP:
15816             imm = (ctx->opcode >> 16) & 0x03FF;
15817             tcg_gen_movi_tl(tcg_ctx, t0, imm);
15818             gen_helper_rddsp(tcg_ctx, *cpu_gpr[ret], t0, tcg_ctx->cpu_env);
15819             break;
15820         }
15821         break;
15822 #ifdef TARGET_MIPS64
15823     case OPC_DEXTR_W_DSP:
15824         check_dsp(ctx);
15825         switch (op2) {
15826         case OPC_DMTHLIP:
15827             tcg_gen_movi_tl(tcg_ctx, t0, ret);
15828             gen_helper_dmthlip(tcg_ctx, v1_t, t0, tcg_ctx->cpu_env);
15829             break;
15830         case OPC_DSHILO:
15831             {
15832                 int shift = (ctx->opcode >> 19) & 0x7F;
15833                 int ac = (ctx->opcode >> 11) & 0x03;
15834                 tcg_gen_movi_tl(tcg_ctx, t0, shift);
15835                 tcg_gen_movi_tl(tcg_ctx, t1, ac);
15836                 gen_helper_dshilo(tcg_ctx, t0, t1, tcg_ctx->cpu_env);
15837                 break;
15838             }
15839         case OPC_DSHILOV:
15840             {
15841                 int ac = (ctx->opcode >> 11) & 0x03;
15842                 tcg_gen_movi_tl(tcg_ctx, t0, ac);
15843                 gen_helper_dshilo(tcg_ctx, v1_t, t0, tcg_ctx->cpu_env);
15844                 break;
15845             }
15846         case OPC_DEXTP:
15847             tcg_gen_movi_tl(tcg_ctx, t0, v2);
15848             tcg_gen_movi_tl(tcg_ctx, t1, v1);
15849 
15850             gen_helper_dextp(tcg_ctx, *cpu_gpr[ret], t0, t1, tcg_ctx->cpu_env);
15851             break;
15852         case OPC_DEXTPV:
15853             tcg_gen_movi_tl(tcg_ctx, t0, v2);
15854             gen_helper_dextp(tcg_ctx, *cpu_gpr[ret], t0, v1_t, tcg_ctx->cpu_env);
15855             break;
15856         case OPC_DEXTPDP:
15857             tcg_gen_movi_tl(tcg_ctx, t0, v2);
15858             tcg_gen_movi_tl(tcg_ctx, t1, v1);
15859             gen_helper_dextpdp(tcg_ctx, *cpu_gpr[ret], t0, t1, tcg_ctx->cpu_env);
15860             break;
15861         case OPC_DEXTPDPV:
15862             tcg_gen_movi_tl(tcg_ctx, t0, v2);
15863             gen_helper_dextpdp(tcg_ctx, *cpu_gpr[ret], t0, v1_t, tcg_ctx->cpu_env);
15864             break;
15865         case OPC_DEXTR_L:
15866             tcg_gen_movi_tl(tcg_ctx, t0, v2);
15867             tcg_gen_movi_tl(tcg_ctx, t1, v1);
15868             gen_helper_dextr_l(tcg_ctx, *cpu_gpr[ret], t0, t1, tcg_ctx->cpu_env);
15869             break;
15870         case OPC_DEXTR_R_L:
15871             tcg_gen_movi_tl(tcg_ctx, t0, v2);
15872             tcg_gen_movi_tl(tcg_ctx, t1, v1);
15873             gen_helper_dextr_r_l(tcg_ctx, *cpu_gpr[ret], t0, t1, tcg_ctx->cpu_env);
15874             break;
15875         case OPC_DEXTR_RS_L:
15876             tcg_gen_movi_tl(tcg_ctx, t0, v2);
15877             tcg_gen_movi_tl(tcg_ctx, t1, v1);
15878             gen_helper_dextr_rs_l(tcg_ctx, *cpu_gpr[ret], t0, t1, tcg_ctx->cpu_env);
15879             break;
15880         case OPC_DEXTR_W:
15881             tcg_gen_movi_tl(tcg_ctx, t0, v2);
15882             tcg_gen_movi_tl(tcg_ctx, t1, v1);
15883             gen_helper_dextr_w(tcg_ctx, *cpu_gpr[ret], t0, t1, tcg_ctx->cpu_env);
15884             break;
15885         case OPC_DEXTR_R_W:
15886             tcg_gen_movi_tl(tcg_ctx, t0, v2);
15887             tcg_gen_movi_tl(tcg_ctx, t1, v1);
15888             gen_helper_dextr_r_w(tcg_ctx, *cpu_gpr[ret], t0, t1, tcg_ctx->cpu_env);
15889             break;
15890         case OPC_DEXTR_RS_W:
15891             tcg_gen_movi_tl(tcg_ctx, t0, v2);
15892             tcg_gen_movi_tl(tcg_ctx, t1, v1);
15893             gen_helper_dextr_rs_w(tcg_ctx, *cpu_gpr[ret], t0, t1, tcg_ctx->cpu_env);
15894             break;
15895         case OPC_DEXTR_S_H:
15896             tcg_gen_movi_tl(tcg_ctx, t0, v2);
15897             tcg_gen_movi_tl(tcg_ctx, t1, v1);
15898             gen_helper_dextr_s_h(tcg_ctx, *cpu_gpr[ret], t0, t1, tcg_ctx->cpu_env);
15899             break;
15900         case OPC_DEXTRV_S_H:
15901             tcg_gen_movi_tl(tcg_ctx, t0, v2);
15902             tcg_gen_movi_tl(tcg_ctx, t1, v1);
15903             gen_helper_dextr_s_h(tcg_ctx, *cpu_gpr[ret], t0, t1, tcg_ctx->cpu_env);
15904             break;
15905         case OPC_DEXTRV_L:
15906             tcg_gen_movi_tl(tcg_ctx, t0, v2);
15907             gen_helper_dextr_l(tcg_ctx, *cpu_gpr[ret], t0, v1_t, tcg_ctx->cpu_env);
15908             break;
15909         case OPC_DEXTRV_R_L:
15910             tcg_gen_movi_tl(tcg_ctx, t0, v2);
15911             gen_helper_dextr_r_l(tcg_ctx, *cpu_gpr[ret], t0, v1_t, tcg_ctx->cpu_env);
15912             break;
15913         case OPC_DEXTRV_RS_L:
15914             tcg_gen_movi_tl(tcg_ctx, t0, v2);
15915             gen_helper_dextr_rs_l(tcg_ctx, *cpu_gpr[ret], t0, v1_t, tcg_ctx->cpu_env);
15916             break;
15917         case OPC_DEXTRV_W:
15918             tcg_gen_movi_tl(tcg_ctx, t0, v2);
15919             gen_helper_dextr_w(tcg_ctx, *cpu_gpr[ret], t0, v1_t, tcg_ctx->cpu_env);
15920             break;
15921         case OPC_DEXTRV_R_W:
15922             tcg_gen_movi_tl(tcg_ctx, t0, v2);
15923             gen_helper_dextr_r_w(tcg_ctx, *cpu_gpr[ret], t0, v1_t, tcg_ctx->cpu_env);
15924             break;
15925         case OPC_DEXTRV_RS_W:
15926             tcg_gen_movi_tl(tcg_ctx, t0, v2);
15927             gen_helper_dextr_rs_w(tcg_ctx, *cpu_gpr[ret], t0, v1_t, tcg_ctx->cpu_env);
15928             break;
15929         }
15930         break;
15931 #endif
15932     }
15933 
15934     tcg_temp_free(tcg_ctx, t0);
15935     tcg_temp_free(tcg_ctx, t1);
15936     tcg_temp_free(tcg_ctx, v1_t);
15937     tcg_temp_free(tcg_ctx, v2_t);
15938 
15939     (void)opn; /* avoid a compiler warning */
15940     MIPS_DEBUG("%s", opn);
15941 }
15942 
15943 /* End MIPSDSP functions. */
15944 
15945 /* Compact Branches */
gen_compute_compact_branch(DisasContext * ctx,uint32_t opc,int rs,int rt,int32_t offset)15946 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
15947                                        int rs, int rt, int32_t offset)
15948 {
15949     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
15950     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
15951     int bcond_compute = 0;
15952     TCGv t0 = tcg_temp_new(tcg_ctx);
15953     TCGv t1 = tcg_temp_new(tcg_ctx);
15954 
15955     if (ctx->hflags & MIPS_HFLAG_BMASK) {
15956 #ifdef MIPS_DEBUG_DISAS
15957         LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
15958                   "\n", ctx->pc);
15959 #endif
15960         generate_exception(ctx, EXCP_RI);
15961         goto out;
15962     }
15963 
15964     /* Load needed operands and calculate btarget */
15965     switch (opc) {
15966     /* compact branch */
15967     case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
15968     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
15969         gen_load_gpr(ctx, t0, rs);
15970         gen_load_gpr(ctx, t1, rt);
15971         bcond_compute = 1;
15972         ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15973         if (rs <= rt && rs == 0) {
15974             /* OPC_BEQZALC, OPC_BNEZALC */
15975             tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[31], ctx->pc + 4);
15976         }
15977         break;
15978     case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
15979     case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
15980         gen_load_gpr(ctx, t0, rs);
15981         gen_load_gpr(ctx, t1, rt);
15982         bcond_compute = 1;
15983         ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15984         break;
15985     case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
15986     case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
15987         if (rs == 0 || rs == rt) {
15988             /* OPC_BLEZALC, OPC_BGEZALC */
15989             /* OPC_BGTZALC, OPC_BLTZALC */
15990             tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[31], ctx->pc + 4);
15991         }
15992         gen_load_gpr(ctx, t0, rs);
15993         gen_load_gpr(ctx, t1, rt);
15994         bcond_compute = 1;
15995         ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15996         break;
15997     case OPC_BC:
15998     case OPC_BALC:
15999         ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
16000         break;
16001     case OPC_BEQZC:
16002     case OPC_BNEZC:
16003         if (rs != 0) {
16004             /* OPC_BEQZC, OPC_BNEZC */
16005             gen_load_gpr(ctx, t0, rs);
16006             bcond_compute = 1;
16007             ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
16008         } else {
16009             /* OPC_JIC, OPC_JIALC */
16010             TCGv tbase = tcg_temp_new(tcg_ctx);
16011             TCGv toffset = tcg_temp_new(tcg_ctx);
16012 
16013             gen_load_gpr(ctx, tbase, rt);
16014             tcg_gen_movi_tl(tcg_ctx, toffset, offset);
16015             gen_op_addr_add(ctx, *(TCGv *)tcg_ctx->btarget, tbase, toffset);
16016             tcg_temp_free(tcg_ctx, tbase);
16017             tcg_temp_free(tcg_ctx, toffset);
16018         }
16019         break;
16020     default:
16021         MIPS_INVAL("Compact branch/jump");
16022         generate_exception(ctx, EXCP_RI);
16023         goto out;
16024     }
16025 
16026     if (bcond_compute == 0) {
16027         /* Uncoditional compact branch */
16028         switch (opc) {
16029         case OPC_JIALC:
16030             tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[31], ctx->pc + 4);
16031             /* Fallthrough */
16032         case OPC_JIC:
16033             ctx->hflags |= MIPS_HFLAG_BR;
16034             break;
16035         case OPC_BALC:
16036             tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[31], ctx->pc + 4);
16037             /* Fallthrough */
16038         case OPC_BC:
16039             ctx->hflags |= MIPS_HFLAG_B;
16040             break;
16041         default:
16042             MIPS_INVAL("Compact branch/jump");
16043             generate_exception(ctx, EXCP_RI);
16044             goto out;
16045         }
16046 
16047         /* Generating branch here as compact branches don't have delay slot */
16048         gen_branch(ctx, 4);
16049     } else {
16050         /* Conditional compact branch */
16051         int fs = gen_new_label(tcg_ctx);
16052         save_cpu_state(ctx, 0);
16053 
16054         switch (opc) {
16055         case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
16056             if (rs == 0 && rt != 0) {
16057                 /* OPC_BLEZALC */
16058                 tcg_gen_brcondi_tl(tcg_ctx, tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
16059             } else if (rs != 0 && rt != 0 && rs == rt) {
16060                 /* OPC_BGEZALC */
16061                 tcg_gen_brcondi_tl(tcg_ctx, tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
16062             } else {
16063                 /* OPC_BGEUC */
16064                 tcg_gen_brcond_tl(tcg_ctx, tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
16065             }
16066             break;
16067         case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
16068             if (rs == 0 && rt != 0) {
16069                 /* OPC_BGTZALC */
16070                 tcg_gen_brcondi_tl(tcg_ctx, tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
16071             } else if (rs != 0 && rt != 0 && rs == rt) {
16072                 /* OPC_BLTZALC */
16073                 tcg_gen_brcondi_tl(tcg_ctx, tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
16074             } else {
16075                 /* OPC_BLTUC */
16076                 tcg_gen_brcond_tl(tcg_ctx, tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
16077             }
16078             break;
16079         case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
16080             if (rs == 0 && rt != 0) {
16081                 /* OPC_BLEZC */
16082                 tcg_gen_brcondi_tl(tcg_ctx, tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
16083             } else if (rs != 0 && rt != 0 && rs == rt) {
16084                 /* OPC_BGEZC */
16085                 tcg_gen_brcondi_tl(tcg_ctx, tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
16086             } else {
16087                 /* OPC_BGEC */
16088                 tcg_gen_brcond_tl(tcg_ctx, tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
16089             }
16090             break;
16091         case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
16092             if (rs == 0 && rt != 0) {
16093                 /* OPC_BGTZC */
16094                 tcg_gen_brcondi_tl(tcg_ctx, tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
16095             } else if (rs != 0 && rt != 0 && rs == rt) {
16096                 /* OPC_BLTZC */
16097                 tcg_gen_brcondi_tl(tcg_ctx, tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
16098             } else {
16099                 /* OPC_BLTC */
16100                 tcg_gen_brcond_tl(tcg_ctx, tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
16101             }
16102             break;
16103         case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
16104         case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
16105             if (rs >= rt) {
16106                 /* OPC_BOVC, OPC_BNVC */
16107                 TCGv t2 = tcg_temp_new(tcg_ctx);
16108                 TCGv t3 = tcg_temp_new(tcg_ctx);
16109                 TCGv t4 = tcg_temp_new(tcg_ctx);
16110                 TCGv input_overflow = tcg_temp_new(tcg_ctx);
16111 
16112                 gen_load_gpr(ctx, t0, rs);
16113                 gen_load_gpr(ctx, t1, rt);
16114                 tcg_gen_ext32s_tl(tcg_ctx, t2, t0);
16115                 tcg_gen_setcond_tl(tcg_ctx, TCG_COND_NE, input_overflow, t2, t0);
16116                 tcg_gen_ext32s_tl(tcg_ctx, t3, t1);
16117                 tcg_gen_setcond_tl(tcg_ctx, TCG_COND_NE, t4, t3, t1);
16118                 tcg_gen_or_tl(tcg_ctx, input_overflow, input_overflow, t4);
16119 
16120                 tcg_gen_add_tl(tcg_ctx, t4, t2, t3);
16121                 tcg_gen_ext32s_tl(tcg_ctx, t4, t4);
16122                 tcg_gen_xor_tl(tcg_ctx, t2, t2, t3);
16123                 tcg_gen_xor_tl(tcg_ctx, t3, t4, t3);
16124                 tcg_gen_andc_tl(tcg_ctx, t2, t3, t2);
16125                 tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_LT, t4, t2, 0);
16126                 tcg_gen_or_tl(tcg_ctx, t4, t4, input_overflow);
16127                 if (opc == OPC_BOVC) {
16128                     /* OPC_BOVC */
16129                     tcg_gen_brcondi_tl(tcg_ctx, tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
16130                 } else {
16131                     /* OPC_BNVC */
16132                     tcg_gen_brcondi_tl(tcg_ctx, tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
16133                 }
16134                 tcg_temp_free(tcg_ctx, input_overflow);
16135                 tcg_temp_free(tcg_ctx, t4);
16136                 tcg_temp_free(tcg_ctx, t3);
16137                 tcg_temp_free(tcg_ctx, t2);
16138             } else if (rs < rt && rs == 0) {
16139                 /* OPC_BEQZALC, OPC_BNEZALC */
16140                 if (opc == OPC_BEQZALC) {
16141                     /* OPC_BEQZALC */
16142                     tcg_gen_brcondi_tl(tcg_ctx, tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
16143                 } else {
16144                     /* OPC_BNEZALC */
16145                     tcg_gen_brcondi_tl(tcg_ctx, tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
16146                 }
16147             } else {
16148                 /* OPC_BEQC, OPC_BNEC */
16149                 if (opc == OPC_BEQC) {
16150                     /* OPC_BEQC */
16151                     tcg_gen_brcond_tl(tcg_ctx, tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
16152                 } else {
16153                     /* OPC_BNEC */
16154                     tcg_gen_brcond_tl(tcg_ctx, tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
16155                 }
16156             }
16157             break;
16158         case OPC_BEQZC:
16159             tcg_gen_brcondi_tl(tcg_ctx, tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
16160             break;
16161         case OPC_BNEZC:
16162             tcg_gen_brcondi_tl(tcg_ctx, tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
16163             break;
16164         default:
16165             MIPS_INVAL("Compact conditional branch/jump");
16166             generate_exception(ctx, EXCP_RI);
16167             goto out;
16168         }
16169 
16170         /* Generating branch here as compact branches don't have delay slot */
16171         gen_goto_tb(ctx, 1, ctx->btarget);
16172         gen_set_label(tcg_ctx, fs);
16173 
16174         ctx->hflags |= MIPS_HFLAG_FBNSLOT;
16175         MIPS_DEBUG("Compact conditional branch");
16176     }
16177 
16178 out:
16179     tcg_temp_free(tcg_ctx, t0);
16180     tcg_temp_free(tcg_ctx, t1);
16181 }
16182 
decode_opc_special_r6(CPUMIPSState * env,DisasContext * ctx)16183 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
16184 {
16185     TCGContext *tcg_ctx = env->uc->tcg_ctx;
16186     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
16187     int rs, rt, rd, sa;
16188     uint32_t op1, op2;
16189 
16190     rs = (ctx->opcode >> 21) & 0x1f;
16191     rt = (ctx->opcode >> 16) & 0x1f;
16192     rd = (ctx->opcode >> 11) & 0x1f;
16193     sa = (ctx->opcode >> 6) & 0x1f;
16194 
16195     op1 = MASK_SPECIAL(ctx->opcode);
16196     switch (op1) {
16197     case OPC_LSA:
16198         if (rd != 0) {
16199             int imm2 = extract32(ctx->opcode, 6, 3);
16200             TCGv t0 = tcg_temp_new(tcg_ctx);
16201             TCGv t1 = tcg_temp_new(tcg_ctx);
16202             gen_load_gpr(ctx, t0, rs);
16203             gen_load_gpr(ctx, t1, rt);
16204             tcg_gen_shli_tl(tcg_ctx, t0, t0, imm2 + 1);
16205             tcg_gen_add_tl(tcg_ctx, t0, t0, t1);
16206             tcg_gen_ext32s_tl(tcg_ctx, *cpu_gpr[rd], t0);
16207             tcg_temp_free(tcg_ctx, t1);
16208             tcg_temp_free(tcg_ctx, t0);
16209         }
16210         break;
16211     case OPC_MULT: case OPC_MULTU: case OPC_DIV: case OPC_DIVU:
16212         op2 = MASK_R6_MULDIV(ctx->opcode);
16213         switch (op2) {
16214         case R6_OPC_MUL:
16215         case R6_OPC_MUH:
16216         case R6_OPC_MULU:
16217         case R6_OPC_MUHU:
16218         case R6_OPC_DIV:
16219         case R6_OPC_MOD:
16220         case R6_OPC_DIVU:
16221         case R6_OPC_MODU:
16222             gen_r6_muldiv(ctx, op2, rd, rs, rt);
16223             break;
16224         default:
16225             MIPS_INVAL("special_r6 muldiv");
16226             generate_exception(ctx, EXCP_RI);
16227             break;
16228         }
16229         break;
16230     case OPC_SELEQZ:
16231     case OPC_SELNEZ:
16232         gen_cond_move(ctx, op1, rd, rs, rt);
16233         break;
16234     case R6_OPC_CLO:
16235     case R6_OPC_CLZ:
16236         if (rt == 0 && sa == 1) {
16237             /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16238                We need additionally to check other fields */
16239             gen_cl(ctx, op1, rd, rs);
16240         } else {
16241             generate_exception(ctx, EXCP_RI);
16242         }
16243         break;
16244     case R6_OPC_SDBBP:
16245         if (ctx->hflags & MIPS_HFLAG_SBRI) {
16246             generate_exception(ctx, EXCP_RI);
16247         } else {
16248             generate_exception(ctx, EXCP_DBp);
16249         }
16250         break;
16251 #if defined(TARGET_MIPS64)
16252     case OPC_DLSA:
16253         check_mips_64(ctx);
16254         if (rd != 0) {
16255             int imm2 = extract32(ctx->opcode, 6, 3);
16256             TCGv t0 = tcg_temp_new(tcg_ctx);
16257             TCGv t1 = tcg_temp_new(tcg_ctx);
16258             gen_load_gpr(ctx, t0, rs);
16259             gen_load_gpr(ctx, t1, rt);
16260             tcg_gen_shli_tl(tcg_ctx, t0, t0, imm2 + 1);
16261             tcg_gen_add_tl(tcg_ctx, *cpu_gpr[rd], t0, t1);
16262             tcg_temp_free(tcg_ctx, t1);
16263             tcg_temp_free(tcg_ctx, t0);
16264         }
16265         break;
16266     case R6_OPC_DCLO:
16267     case R6_OPC_DCLZ:
16268         if (rt == 0 && sa == 1) {
16269             /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16270                We need additionally to check other fields */
16271             check_mips_64(ctx);
16272             gen_cl(ctx, op1, rd, rs);
16273         } else {
16274             generate_exception(ctx, EXCP_RI);
16275         }
16276         break;
16277     case OPC_DMULT: case OPC_DMULTU: case OPC_DDIV: case OPC_DDIVU:
16278         op2 = MASK_R6_MULDIV(ctx->opcode);
16279         switch (op2) {
16280         case R6_OPC_DMUL:
16281         case R6_OPC_DMUH:
16282         case R6_OPC_DMULU:
16283         case R6_OPC_DMUHU:
16284         case R6_OPC_DDIV:
16285         case R6_OPC_DMOD:
16286         case R6_OPC_DDIVU:
16287         case R6_OPC_DMODU:
16288             check_mips_64(ctx);
16289             gen_r6_muldiv(ctx, op2, rd, rs, rt);
16290             break;
16291         default:
16292             MIPS_INVAL("special_r6 muldiv");
16293             generate_exception(ctx, EXCP_RI);
16294             break;
16295         }
16296         break;
16297 #endif
16298     default:            /* Invalid */
16299         MIPS_INVAL("special_r6");
16300         generate_exception(ctx, EXCP_RI);
16301         break;
16302     }
16303 }
16304 
decode_opc_special_legacy(CPUMIPSState * env,DisasContext * ctx)16305 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
16306 {
16307     int rs, rt, rd, sa;
16308     uint32_t op1;
16309 
16310     rs = (ctx->opcode >> 21) & 0x1f;
16311     rt = (ctx->opcode >> 16) & 0x1f;
16312     rd = (ctx->opcode >> 11) & 0x1f;
16313     sa = (ctx->opcode >> 6) & 0x1f;
16314 
16315     op1 = MASK_SPECIAL(ctx->opcode);
16316     switch (op1) {
16317     case OPC_MOVN:         /* Conditional move */
16318     case OPC_MOVZ:
16319         check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
16320                    INSN_LOONGSON2E | INSN_LOONGSON2F);
16321         gen_cond_move(ctx, op1, rd, rs, rt);
16322         break;
16323     case OPC_MFHI:          /* Move from HI/LO */
16324     case OPC_MFLO:
16325         gen_HILO(ctx, op1, rs & 3, rd);
16326         break;
16327     case OPC_MTHI:
16328     case OPC_MTLO:          /* Move to HI/LO */
16329         gen_HILO(ctx, op1, rd & 3, rs);
16330         break;
16331     case OPC_MOVCI:
16332         check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
16333         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16334             check_cp1_enabled(ctx);
16335             gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
16336                       (ctx->opcode >> 16) & 1);
16337         } else {
16338             generate_exception_err(ctx, EXCP_CpU, 1);
16339         }
16340         break;
16341     case OPC_MULT:
16342     case OPC_MULTU:
16343         if (sa) {
16344             check_insn(ctx, INSN_VR54XX);
16345             op1 = MASK_MUL_VR54XX(ctx->opcode);
16346             gen_mul_vr54xx(ctx, op1, rd, rs, rt);
16347         } else {
16348             gen_muldiv(ctx, op1, rd & 3, rs, rt);
16349         }
16350         break;
16351     case OPC_DIV:
16352     case OPC_DIVU:
16353         gen_muldiv(ctx, op1, 0, rs, rt);
16354         break;
16355 #if defined(TARGET_MIPS64)
16356     case OPC_DMULT: case OPC_DMULTU: case OPC_DDIV: case OPC_DDIVU:
16357         check_insn(ctx, ISA_MIPS3);
16358         check_mips_64(ctx);
16359         gen_muldiv(ctx, op1, 0, rs, rt);
16360         break;
16361 #endif
16362     case OPC_JR:
16363         gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
16364         break;
16365     case OPC_SPIM:
16366 #ifdef MIPS_STRICT_STANDARD
16367         MIPS_INVAL("SPIM");
16368         generate_exception(ctx, EXCP_RI);
16369 #else
16370         /* Implemented as RI exception for now. */
16371         MIPS_INVAL("spim (unofficial)");
16372         generate_exception(ctx, EXCP_RI);
16373 #endif
16374         break;
16375     default:            /* Invalid */
16376         MIPS_INVAL("special_legacy");
16377         generate_exception(ctx, EXCP_RI);
16378         break;
16379     }
16380 }
16381 
decode_opc_special(CPUMIPSState * env,DisasContext * ctx)16382 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
16383 {
16384     TCGContext *tcg_ctx = env->uc->tcg_ctx;
16385     int rs, rt, rd, sa;
16386     uint32_t op1;
16387 
16388     rs = (ctx->opcode >> 21) & 0x1f;
16389     rt = (ctx->opcode >> 16) & 0x1f;
16390     rd = (ctx->opcode >> 11) & 0x1f;
16391     sa = (ctx->opcode >> 6) & 0x1f;
16392 
16393     op1 = MASK_SPECIAL(ctx->opcode);
16394     switch (op1) {
16395     case OPC_SLL:          /* Shift with immediate */
16396         if (sa == 5 && rd == 0 &&
16397             rs == 0 && rt == 0) { /* PAUSE */
16398             if ((ctx->insn_flags & ISA_MIPS32R6) &&
16399                 (ctx->hflags & MIPS_HFLAG_BMASK)) {
16400                 MIPS_DEBUG("CTI in delay / forbidden slot");
16401                 generate_exception(ctx, EXCP_RI);
16402                 break;
16403             }
16404         }
16405         /* Fallthrough */
16406     case OPC_SRA:
16407         gen_shift_imm(ctx, op1, rd, rt, sa);
16408         break;
16409     case OPC_SRL:
16410         switch ((ctx->opcode >> 21) & 0x1f) {
16411         case 1:
16412             /* rotr is decoded as srl on non-R2 CPUs */
16413             if (ctx->insn_flags & ISA_MIPS32R2) {
16414                 op1 = OPC_ROTR;
16415             }
16416             /* Fallthrough */
16417         case 0:
16418             gen_shift_imm(ctx, op1, rd, rt, sa);
16419             break;
16420         default:
16421             generate_exception(ctx, EXCP_RI);
16422             break;
16423         }
16424         break;
16425     case OPC_ADD: case OPC_ADDU: case OPC_SUB: case OPC_SUBU:
16426         gen_arith(ctx, op1, rd, rs, rt);
16427         break;
16428     case OPC_SLLV:         /* Shifts */
16429     case OPC_SRAV:
16430         gen_shift(ctx, op1, rd, rs, rt);
16431         break;
16432     case OPC_SRLV:
16433         switch ((ctx->opcode >> 6) & 0x1f) {
16434         case 1:
16435             /* rotrv is decoded as srlv on non-R2 CPUs */
16436             if (ctx->insn_flags & ISA_MIPS32R2) {
16437                 op1 = OPC_ROTRV;
16438             }
16439             /* Fallthrough */
16440         case 0:
16441             gen_shift(ctx, op1, rd, rs, rt);
16442             break;
16443         default:
16444             generate_exception(ctx, EXCP_RI);
16445             break;
16446         }
16447         break;
16448     case OPC_SLT:          /* Set on less than */
16449     case OPC_SLTU:
16450         gen_slt(ctx, op1, rd, rs, rt);
16451         break;
16452     case OPC_AND:          /* Logic*/
16453     case OPC_OR:
16454     case OPC_NOR:
16455     case OPC_XOR:
16456         gen_logic(ctx, op1, rd, rs, rt);
16457         break;
16458     case OPC_JALR:
16459         gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
16460         break;
16461     case OPC_TGE: case OPC_TGEU: case OPC_TLT: case OPC_TLTU: case OPC_TEQ:
16462     case OPC_TNE:
16463         gen_trap(ctx, op1, rs, rt, -1);
16464         break;
16465     case OPC_LSA: /* OPC_PMON */
16466         if ((ctx->insn_flags & ISA_MIPS32R6) ||
16467             (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
16468             decode_opc_special_r6(env, ctx);
16469         } else {
16470             /* Pmon entry point, also R4010 selsl */
16471 #ifdef MIPS_STRICT_STANDARD
16472             MIPS_INVAL("PMON / selsl");
16473             generate_exception(ctx, EXCP_RI);
16474 #else
16475             gen_helper_0e0i(tcg_ctx, pmon, sa);
16476 #endif
16477         }
16478         break;
16479     case OPC_SYSCALL:
16480         generate_exception(ctx, EXCP_SYSCALL);
16481         ctx->bstate = BS_STOP;
16482         break;
16483     case OPC_BREAK:
16484         generate_exception(ctx, EXCP_BREAK);
16485         break;
16486     case OPC_SYNC:
16487         /* Treat as NOP. */
16488         break;
16489 
16490 #if defined(TARGET_MIPS64)
16491         /* MIPS64 specific opcodes */
16492     case OPC_DSLL:
16493     case OPC_DSRA:
16494     case OPC_DSLL32:
16495     case OPC_DSRA32:
16496         check_insn(ctx, ISA_MIPS3);
16497         check_mips_64(ctx);
16498         gen_shift_imm(ctx, op1, rd, rt, sa);
16499         break;
16500     case OPC_DSRL:
16501         switch ((ctx->opcode >> 21) & 0x1f) {
16502         case 1:
16503             /* drotr is decoded as dsrl on non-R2 CPUs */
16504             if (ctx->insn_flags & ISA_MIPS32R2) {
16505                 op1 = OPC_DROTR;
16506             }
16507             /* Fallthrough */
16508         case 0:
16509             check_insn(ctx, ISA_MIPS3);
16510             check_mips_64(ctx);
16511             gen_shift_imm(ctx, op1, rd, rt, sa);
16512             break;
16513         default:
16514             generate_exception(ctx, EXCP_RI);
16515             break;
16516         }
16517         break;
16518     case OPC_DSRL32:
16519         switch ((ctx->opcode >> 21) & 0x1f) {
16520         case 1:
16521             /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
16522             if (ctx->insn_flags & ISA_MIPS32R2) {
16523                 op1 = OPC_DROTR32;
16524             }
16525             /* Fallthrough */
16526         case 0:
16527             check_insn(ctx, ISA_MIPS3);
16528             check_mips_64(ctx);
16529             gen_shift_imm(ctx, op1, rd, rt, sa);
16530             break;
16531         default:
16532             generate_exception(ctx, EXCP_RI);
16533             break;
16534         }
16535         break;
16536     case OPC_DADD: case OPC_DADDU: case OPC_DSUB: case OPC_DSUBU:
16537         check_insn(ctx, ISA_MIPS3);
16538         check_mips_64(ctx);
16539         gen_arith(ctx, op1, rd, rs, rt);
16540         break;
16541     case OPC_DSLLV:
16542     case OPC_DSRAV:
16543         check_insn(ctx, ISA_MIPS3);
16544         check_mips_64(ctx);
16545         gen_shift(ctx, op1, rd, rs, rt);
16546         break;
16547     case OPC_DSRLV:
16548         switch ((ctx->opcode >> 6) & 0x1f) {
16549         case 1:
16550             /* drotrv is decoded as dsrlv on non-R2 CPUs */
16551             if (ctx->insn_flags & ISA_MIPS32R2) {
16552                 op1 = OPC_DROTRV;
16553             }
16554             /* Fallthrough */
16555         case 0:
16556             check_insn(ctx, ISA_MIPS3);
16557             check_mips_64(ctx);
16558             gen_shift(ctx, op1, rd, rs, rt);
16559             break;
16560         default:
16561             generate_exception(ctx, EXCP_RI);
16562             break;
16563         }
16564         break;
16565     case OPC_DLSA:
16566         if ((ctx->insn_flags & ISA_MIPS32R6) ||
16567             (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
16568             decode_opc_special_r6(env, ctx);
16569         }
16570         break;
16571 #endif
16572     default:
16573         if (ctx->insn_flags & ISA_MIPS32R6) {
16574             decode_opc_special_r6(env, ctx);
16575         } else {
16576             decode_opc_special_legacy(env, ctx);
16577         }
16578     }
16579 }
16580 
decode_opc_special2_legacy(CPUMIPSState * env,DisasContext * ctx)16581 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
16582 {
16583     int rs, rt, rd;
16584     uint32_t op1;
16585 
16586     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16587 
16588     rs = (ctx->opcode >> 21) & 0x1f;
16589     rt = (ctx->opcode >> 16) & 0x1f;
16590     rd = (ctx->opcode >> 11) & 0x1f;
16591 
16592     op1 = MASK_SPECIAL2(ctx->opcode);
16593     switch (op1) {
16594     case OPC_MADD: case OPC_MADDU:
16595     case OPC_MSUB: case OPC_MSUBU:
16596         check_insn(ctx, ISA_MIPS32);
16597         gen_muldiv(ctx, op1, rd & 3, rs, rt);
16598         break;
16599     case OPC_MUL:
16600         gen_arith(ctx, op1, rd, rs, rt);
16601         break;
16602     case OPC_DIV_G_2F:
16603     case OPC_DIVU_G_2F:
16604     case OPC_MULT_G_2F:
16605     case OPC_MULTU_G_2F:
16606     case OPC_MOD_G_2F:
16607     case OPC_MODU_G_2F:
16608         check_insn(ctx, INSN_LOONGSON2F);
16609         gen_loongson_integer(ctx, op1, rd, rs, rt);
16610         break;
16611     case OPC_CLO:
16612     case OPC_CLZ:
16613         check_insn(ctx, ISA_MIPS32);
16614         gen_cl(ctx, op1, rd, rs);
16615         break;
16616     case OPC_SDBBP:
16617         /* XXX: not clear which exception should be raised
16618          *      when in debug mode...
16619          */
16620         check_insn(ctx, ISA_MIPS32);
16621         if (!(ctx->hflags & MIPS_HFLAG_DM)) {
16622             generate_exception(ctx, EXCP_DBp);
16623         } else {
16624             generate_exception(ctx, EXCP_DBp);
16625         }
16626         /* Treat as NOP. */
16627         break;
16628 #if defined(TARGET_MIPS64)
16629     case OPC_DCLO:
16630     case OPC_DCLZ:
16631         check_insn(ctx, ISA_MIPS64);
16632         check_mips_64(ctx);
16633         gen_cl(ctx, op1, rd, rs);
16634         break;
16635     case OPC_DMULT_G_2F:
16636     case OPC_DMULTU_G_2F:
16637     case OPC_DDIV_G_2F:
16638     case OPC_DDIVU_G_2F:
16639     case OPC_DMOD_G_2F:
16640     case OPC_DMODU_G_2F:
16641         check_insn(ctx, INSN_LOONGSON2F);
16642         gen_loongson_integer(ctx, op1, rd, rs, rt);
16643         break;
16644 #endif
16645     default:            /* Invalid */
16646         MIPS_INVAL("special2_legacy");
16647         generate_exception(ctx, EXCP_RI);
16648         break;
16649     }
16650 }
16651 
decode_opc_special3_r6(CPUMIPSState * env,DisasContext * ctx)16652 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
16653 {
16654     TCGContext *tcg_ctx = env->uc->tcg_ctx;
16655     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
16656     int rs, rt, rd, sa;
16657     uint32_t op1, op2;
16658     int16_t imm;
16659 
16660     rs = (ctx->opcode >> 21) & 0x1f;
16661     rt = (ctx->opcode >> 16) & 0x1f;
16662     rd = (ctx->opcode >> 11) & 0x1f;
16663     sa = (ctx->opcode >> 6) & 0x1f;
16664     imm = (int16_t)ctx->opcode >> 7;
16665 
16666     op1 = MASK_SPECIAL3(ctx->opcode);
16667     switch (op1) {
16668     case R6_OPC_PREF:
16669         if (rt >= 24) {
16670             /* hint codes 24-31 are reserved and signal RI */
16671             generate_exception(ctx, EXCP_RI);
16672         }
16673         /* Treat as NOP. */
16674         break;
16675     case R6_OPC_CACHE:
16676         /* Treat as NOP. */
16677         break;
16678     case R6_OPC_SC:
16679         gen_st_cond(ctx, op1, rt, rs, imm);
16680         break;
16681     case R6_OPC_LL:
16682         gen_ld(ctx, op1, rt, rs, imm);
16683         break;
16684     case OPC_BSHFL:
16685         {
16686             TCGv t0;
16687             if (rd == 0) {
16688                 /* Treat as NOP. */
16689                 break;
16690             }
16691             t0 = tcg_temp_new(tcg_ctx);
16692             gen_load_gpr(ctx, t0, rt);
16693 
16694             op2 = MASK_BSHFL(ctx->opcode);
16695             switch (op2) {
16696             case OPC_ALIGN: case OPC_ALIGN_END:
16697                 sa &= 3;
16698                 if (sa == 0) {
16699                     tcg_gen_mov_tl(tcg_ctx, *cpu_gpr[rd], t0);
16700                 } else {
16701                     TCGv t1 = tcg_temp_new(tcg_ctx);
16702                     TCGv_i64 t2 = tcg_temp_new_i64(tcg_ctx);
16703                     gen_load_gpr(ctx, t1, rs);
16704                     tcg_gen_concat_tl_i64(tcg_ctx, t2, t1, t0);
16705                     tcg_gen_shri_i64(tcg_ctx, t2, t2, 8 * (4 - sa));
16706 #if defined(TARGET_MIPS64)
16707                     tcg_gen_ext32s_i64(tcg_ctx, *cpu_gpr[rd], t2);
16708 #else
16709                     tcg_gen_trunc_i64_i32(tcg_ctx, *cpu_gpr[rd], t2);
16710 #endif
16711                     tcg_temp_free_i64(tcg_ctx, t2);
16712                     tcg_temp_free(tcg_ctx, t1);
16713                 }
16714                 break;
16715             case OPC_BITSWAP:
16716                 gen_helper_bitswap(tcg_ctx, *cpu_gpr[rd], t0);
16717                 break;
16718             }
16719             tcg_temp_free(tcg_ctx, t0);
16720         }
16721         break;
16722 #if defined(TARGET_MIPS64)
16723     case R6_OPC_SCD:
16724         gen_st_cond(ctx, op1, rt, rs, imm);
16725         break;
16726     case R6_OPC_LLD:
16727         gen_ld(ctx, op1, rt, rs, imm);
16728         break;
16729     case OPC_DBSHFL:
16730         check_mips_64(ctx);
16731         {
16732             TCGv t0;
16733             if (rd == 0) {
16734                 /* Treat as NOP. */
16735                 break;
16736             }
16737             t0 = tcg_temp_new(tcg_ctx);
16738             gen_load_gpr(ctx, t0, rt);
16739 
16740             op2 = MASK_DBSHFL(ctx->opcode);
16741             switch (op2) {
16742             case OPC_DALIGN: case OPC_DALIGN_END:
16743                 sa &= 7;
16744                 if (sa == 0) {
16745                     tcg_gen_mov_tl(tcg_ctx, *cpu_gpr[rd], t0);
16746                 } else {
16747                     TCGv t1 = tcg_temp_new(tcg_ctx);
16748                     gen_load_gpr(ctx, t1, rs);
16749                     tcg_gen_shli_tl(tcg_ctx, t0, t0, 8 * sa);
16750                     tcg_gen_shri_tl(tcg_ctx, t1, t1, 8 * (8 - sa));
16751                     tcg_gen_or_tl(tcg_ctx, *cpu_gpr[rd], t1, t0);
16752                     tcg_temp_free(tcg_ctx, t1);
16753                 }
16754                 break;
16755             case OPC_DBITSWAP:
16756                 gen_helper_dbitswap(tcg_ctx, *cpu_gpr[rd], t0);
16757                 break;
16758             }
16759             tcg_temp_free(tcg_ctx, t0);
16760         }
16761         break;
16762 #endif
16763     default:            /* Invalid */
16764         MIPS_INVAL("special3_r6");
16765         generate_exception(ctx, EXCP_RI);
16766         break;
16767     }
16768 }
16769 
decode_opc_special3_legacy(CPUMIPSState * env,DisasContext * ctx)16770 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
16771 {
16772     TCGContext *tcg_ctx = env->uc->tcg_ctx;
16773     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
16774     int rs, rt, rd;
16775     uint32_t op1, op2;
16776 
16777     rs = (ctx->opcode >> 21) & 0x1f;
16778     rt = (ctx->opcode >> 16) & 0x1f;
16779     rd = (ctx->opcode >> 11) & 0x1f;
16780 
16781     op1 = MASK_SPECIAL3(ctx->opcode);
16782     switch (op1) {
16783     case OPC_DIV_G_2E: case OPC_DIVU_G_2E:
16784     case OPC_MOD_G_2E: case OPC_MODU_G_2E:
16785     case OPC_MULT_G_2E: case OPC_MULTU_G_2E:
16786         /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
16787          * the same mask and op1. */
16788         if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
16789             op2 = MASK_ADDUH_QB(ctx->opcode);
16790             switch (op2) {
16791             case OPC_ADDUH_QB:
16792             case OPC_ADDUH_R_QB:
16793             case OPC_ADDQH_PH:
16794             case OPC_ADDQH_R_PH:
16795             case OPC_ADDQH_W:
16796             case OPC_ADDQH_R_W:
16797             case OPC_SUBUH_QB:
16798             case OPC_SUBUH_R_QB:
16799             case OPC_SUBQH_PH:
16800             case OPC_SUBQH_R_PH:
16801             case OPC_SUBQH_W:
16802             case OPC_SUBQH_R_W:
16803                 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16804                 break;
16805             case OPC_MUL_PH:
16806             case OPC_MUL_S_PH:
16807             case OPC_MULQ_S_W:
16808             case OPC_MULQ_RS_W:
16809                 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
16810                 break;
16811             default:
16812                 MIPS_INVAL("MASK ADDUH.QB");
16813                 generate_exception(ctx, EXCP_RI);
16814                 break;
16815             }
16816         } else if (ctx->insn_flags & INSN_LOONGSON2E) {
16817             gen_loongson_integer(ctx, op1, rd, rs, rt);
16818         } else {
16819             generate_exception(ctx, EXCP_RI);
16820         }
16821         break;
16822     case OPC_LX_DSP:
16823         op2 = MASK_LX(ctx->opcode);
16824         switch (op2) {
16825 #if defined(TARGET_MIPS64)
16826         case OPC_LDX:
16827 #endif
16828         case OPC_LBUX:
16829         case OPC_LHX:
16830         case OPC_LWX:
16831             gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
16832             break;
16833         default:            /* Invalid */
16834             MIPS_INVAL("MASK LX");
16835             generate_exception(ctx, EXCP_RI);
16836             break;
16837         }
16838         break;
16839     case OPC_ABSQ_S_PH_DSP:
16840         op2 = MASK_ABSQ_S_PH(ctx->opcode);
16841         switch (op2) {
16842         case OPC_ABSQ_S_QB:
16843         case OPC_ABSQ_S_PH:
16844         case OPC_ABSQ_S_W:
16845         case OPC_PRECEQ_W_PHL:
16846         case OPC_PRECEQ_W_PHR:
16847         case OPC_PRECEQU_PH_QBL:
16848         case OPC_PRECEQU_PH_QBR:
16849         case OPC_PRECEQU_PH_QBLA:
16850         case OPC_PRECEQU_PH_QBRA:
16851         case OPC_PRECEU_PH_QBL:
16852         case OPC_PRECEU_PH_QBR:
16853         case OPC_PRECEU_PH_QBLA:
16854         case OPC_PRECEU_PH_QBRA:
16855             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16856             break;
16857         case OPC_BITREV:
16858         case OPC_REPL_QB:
16859         case OPC_REPLV_QB:
16860         case OPC_REPL_PH:
16861         case OPC_REPLV_PH:
16862             gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
16863             break;
16864         default:
16865             MIPS_INVAL("MASK ABSQ_S.PH");
16866             generate_exception(ctx, EXCP_RI);
16867             break;
16868         }
16869         break;
16870     case OPC_ADDU_QB_DSP:
16871         op2 = MASK_ADDU_QB(ctx->opcode);
16872         switch (op2) {
16873         case OPC_ADDQ_PH:
16874         case OPC_ADDQ_S_PH:
16875         case OPC_ADDQ_S_W:
16876         case OPC_ADDU_QB:
16877         case OPC_ADDU_S_QB:
16878         case OPC_ADDU_PH:
16879         case OPC_ADDU_S_PH:
16880         case OPC_SUBQ_PH:
16881         case OPC_SUBQ_S_PH:
16882         case OPC_SUBQ_S_W:
16883         case OPC_SUBU_QB:
16884         case OPC_SUBU_S_QB:
16885         case OPC_SUBU_PH:
16886         case OPC_SUBU_S_PH:
16887         case OPC_ADDSC:
16888         case OPC_ADDWC:
16889         case OPC_MODSUB:
16890         case OPC_RADDU_W_QB:
16891             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16892             break;
16893         case OPC_MULEU_S_PH_QBL:
16894         case OPC_MULEU_S_PH_QBR:
16895         case OPC_MULQ_RS_PH:
16896         case OPC_MULEQ_S_W_PHL:
16897         case OPC_MULEQ_S_W_PHR:
16898         case OPC_MULQ_S_PH:
16899             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
16900             break;
16901         default:            /* Invalid */
16902             MIPS_INVAL("MASK ADDU.QB");
16903             generate_exception(ctx, EXCP_RI);
16904             break;
16905 
16906         }
16907         break;
16908     case OPC_CMPU_EQ_QB_DSP:
16909         op2 = MASK_CMPU_EQ_QB(ctx->opcode);
16910         switch (op2) {
16911         case OPC_PRECR_SRA_PH_W:
16912         case OPC_PRECR_SRA_R_PH_W:
16913             gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
16914             break;
16915         case OPC_PRECR_QB_PH:
16916         case OPC_PRECRQ_QB_PH:
16917         case OPC_PRECRQ_PH_W:
16918         case OPC_PRECRQ_RS_PH_W:
16919         case OPC_PRECRQU_S_QB_PH:
16920             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16921             break;
16922         case OPC_CMPU_EQ_QB:
16923         case OPC_CMPU_LT_QB:
16924         case OPC_CMPU_LE_QB:
16925         case OPC_CMP_EQ_PH:
16926         case OPC_CMP_LT_PH:
16927         case OPC_CMP_LE_PH:
16928             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
16929             break;
16930         case OPC_CMPGU_EQ_QB:
16931         case OPC_CMPGU_LT_QB:
16932         case OPC_CMPGU_LE_QB:
16933         case OPC_CMPGDU_EQ_QB:
16934         case OPC_CMPGDU_LT_QB:
16935         case OPC_CMPGDU_LE_QB:
16936         case OPC_PICK_QB:
16937         case OPC_PICK_PH:
16938         case OPC_PACKRL_PH:
16939             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
16940             break;
16941         default:            /* Invalid */
16942             MIPS_INVAL("MASK CMPU.EQ.QB");
16943             generate_exception(ctx, EXCP_RI);
16944             break;
16945         }
16946         break;
16947     case OPC_SHLL_QB_DSP:
16948         gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
16949         break;
16950     case OPC_DPA_W_PH_DSP:
16951         op2 = MASK_DPA_W_PH(ctx->opcode);
16952         switch (op2) {
16953         case OPC_DPAU_H_QBL:
16954         case OPC_DPAU_H_QBR:
16955         case OPC_DPSU_H_QBL:
16956         case OPC_DPSU_H_QBR:
16957         case OPC_DPA_W_PH:
16958         case OPC_DPAX_W_PH:
16959         case OPC_DPAQ_S_W_PH:
16960         case OPC_DPAQX_S_W_PH:
16961         case OPC_DPAQX_SA_W_PH:
16962         case OPC_DPS_W_PH:
16963         case OPC_DPSX_W_PH:
16964         case OPC_DPSQ_S_W_PH:
16965         case OPC_DPSQX_S_W_PH:
16966         case OPC_DPSQX_SA_W_PH:
16967         case OPC_MULSAQ_S_W_PH:
16968         case OPC_DPAQ_SA_L_W:
16969         case OPC_DPSQ_SA_L_W:
16970         case OPC_MAQ_S_W_PHL:
16971         case OPC_MAQ_S_W_PHR:
16972         case OPC_MAQ_SA_W_PHL:
16973         case OPC_MAQ_SA_W_PHR:
16974         case OPC_MULSA_W_PH:
16975             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
16976             break;
16977         default:            /* Invalid */
16978             MIPS_INVAL("MASK DPAW.PH");
16979             generate_exception(ctx, EXCP_RI);
16980             break;
16981         }
16982         break;
16983     case OPC_INSV_DSP:
16984         op2 = MASK_INSV(ctx->opcode);
16985         switch (op2) {
16986         case OPC_INSV:
16987             check_dsp(ctx);
16988             {
16989                 TCGv t0, t1;
16990 
16991                 if (rt == 0) {
16992                     MIPS_DEBUG("NOP");
16993                     break;
16994                 }
16995 
16996                 t0 = tcg_temp_new(tcg_ctx);
16997                 t1 = tcg_temp_new(tcg_ctx);
16998 
16999                 gen_load_gpr(ctx, t0, rt);
17000                 gen_load_gpr(ctx, t1, rs);
17001 
17002                 gen_helper_insv(tcg_ctx, *cpu_gpr[rt], tcg_ctx->cpu_env, t1, t0);
17003 
17004                 tcg_temp_free(tcg_ctx, t0);
17005                 tcg_temp_free(tcg_ctx, t1);
17006                 break;
17007             }
17008         default:            /* Invalid */
17009             MIPS_INVAL("MASK INSV");
17010             generate_exception(ctx, EXCP_RI);
17011             break;
17012         }
17013         break;
17014     case OPC_APPEND_DSP:
17015         gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17016         break;
17017     case OPC_EXTR_W_DSP:
17018         op2 = MASK_EXTR_W(ctx->opcode);
17019         switch (op2) {
17020         case OPC_EXTR_W:
17021         case OPC_EXTR_R_W:
17022         case OPC_EXTR_RS_W:
17023         case OPC_EXTR_S_H:
17024         case OPC_EXTRV_S_H:
17025         case OPC_EXTRV_W:
17026         case OPC_EXTRV_R_W:
17027         case OPC_EXTRV_RS_W:
17028         case OPC_EXTP:
17029         case OPC_EXTPV:
17030         case OPC_EXTPDP:
17031         case OPC_EXTPDPV:
17032             gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
17033             break;
17034         case OPC_RDDSP:
17035             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
17036             break;
17037         case OPC_SHILO:
17038         case OPC_SHILOV:
17039         case OPC_MTHLIP:
17040         case OPC_WRDSP:
17041             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
17042             break;
17043         default:            /* Invalid */
17044             MIPS_INVAL("MASK EXTR.W");
17045             generate_exception(ctx, EXCP_RI);
17046             break;
17047         }
17048         break;
17049 #if defined(TARGET_MIPS64)
17050     case OPC_DDIV_G_2E: case OPC_DDIVU_G_2E:
17051     case OPC_DMULT_G_2E: case OPC_DMULTU_G_2E:
17052     case OPC_DMOD_G_2E: case OPC_DMODU_G_2E:
17053         check_insn(ctx, INSN_LOONGSON2E);
17054         gen_loongson_integer(ctx, op1, rd, rs, rt);
17055         break;
17056     case OPC_ABSQ_S_QH_DSP:
17057         op2 = MASK_ABSQ_S_QH(ctx->opcode);
17058         switch (op2) {
17059         case OPC_PRECEQ_L_PWL:
17060         case OPC_PRECEQ_L_PWR:
17061         case OPC_PRECEQ_PW_QHL:
17062         case OPC_PRECEQ_PW_QHR:
17063         case OPC_PRECEQ_PW_QHLA:
17064         case OPC_PRECEQ_PW_QHRA:
17065         case OPC_PRECEQU_QH_OBL:
17066         case OPC_PRECEQU_QH_OBR:
17067         case OPC_PRECEQU_QH_OBLA:
17068         case OPC_PRECEQU_QH_OBRA:
17069         case OPC_PRECEU_QH_OBL:
17070         case OPC_PRECEU_QH_OBR:
17071         case OPC_PRECEU_QH_OBLA:
17072         case OPC_PRECEU_QH_OBRA:
17073         case OPC_ABSQ_S_OB:
17074         case OPC_ABSQ_S_PW:
17075         case OPC_ABSQ_S_QH:
17076             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17077             break;
17078         case OPC_REPL_OB:
17079         case OPC_REPL_PW:
17080         case OPC_REPL_QH:
17081         case OPC_REPLV_OB:
17082         case OPC_REPLV_PW:
17083         case OPC_REPLV_QH:
17084             gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17085             break;
17086         default:            /* Invalid */
17087             MIPS_INVAL("MASK ABSQ_S.QH");
17088             generate_exception(ctx, EXCP_RI);
17089             break;
17090         }
17091         break;
17092     case OPC_ADDU_OB_DSP:
17093         op2 = MASK_ADDU_OB(ctx->opcode);
17094         switch (op2) {
17095         case OPC_RADDU_L_OB:
17096         case OPC_SUBQ_PW:
17097         case OPC_SUBQ_S_PW:
17098         case OPC_SUBQ_QH:
17099         case OPC_SUBQ_S_QH:
17100         case OPC_SUBU_OB:
17101         case OPC_SUBU_S_OB:
17102         case OPC_SUBU_QH:
17103         case OPC_SUBU_S_QH:
17104         case OPC_SUBUH_OB:
17105         case OPC_SUBUH_R_OB:
17106         case OPC_ADDQ_PW:
17107         case OPC_ADDQ_S_PW:
17108         case OPC_ADDQ_QH:
17109         case OPC_ADDQ_S_QH:
17110         case OPC_ADDU_OB:
17111         case OPC_ADDU_S_OB:
17112         case OPC_ADDU_QH:
17113         case OPC_ADDU_S_QH:
17114         case OPC_ADDUH_OB:
17115         case OPC_ADDUH_R_OB:
17116             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17117             break;
17118         case OPC_MULEQ_S_PW_QHL:
17119         case OPC_MULEQ_S_PW_QHR:
17120         case OPC_MULEU_S_QH_OBL:
17121         case OPC_MULEU_S_QH_OBR:
17122         case OPC_MULQ_RS_QH:
17123             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17124             break;
17125         default:            /* Invalid */
17126             MIPS_INVAL("MASK ADDU.OB");
17127             generate_exception(ctx, EXCP_RI);
17128             break;
17129         }
17130         break;
17131     case OPC_CMPU_EQ_OB_DSP:
17132         op2 = MASK_CMPU_EQ_OB(ctx->opcode);
17133         switch (op2) {
17134         case OPC_PRECR_SRA_QH_PW:
17135         case OPC_PRECR_SRA_R_QH_PW:
17136             /* Return value is rt. */
17137             gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
17138             break;
17139         case OPC_PRECR_OB_QH:
17140         case OPC_PRECRQ_OB_QH:
17141         case OPC_PRECRQ_PW_L:
17142         case OPC_PRECRQ_QH_PW:
17143         case OPC_PRECRQ_RS_QH_PW:
17144         case OPC_PRECRQU_S_OB_QH:
17145             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17146             break;
17147         case OPC_CMPU_EQ_OB:
17148         case OPC_CMPU_LT_OB:
17149         case OPC_CMPU_LE_OB:
17150         case OPC_CMP_EQ_QH:
17151         case OPC_CMP_LT_QH:
17152         case OPC_CMP_LE_QH:
17153         case OPC_CMP_EQ_PW:
17154         case OPC_CMP_LT_PW:
17155         case OPC_CMP_LE_PW:
17156             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
17157             break;
17158         case OPC_CMPGDU_EQ_OB:
17159         case OPC_CMPGDU_LT_OB:
17160         case OPC_CMPGDU_LE_OB:
17161         case OPC_CMPGU_EQ_OB:
17162         case OPC_CMPGU_LT_OB:
17163         case OPC_CMPGU_LE_OB:
17164         case OPC_PACKRL_PW:
17165         case OPC_PICK_OB:
17166         case OPC_PICK_PW:
17167         case OPC_PICK_QH:
17168             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
17169             break;
17170         default:            /* Invalid */
17171             MIPS_INVAL("MASK CMPU_EQ.OB");
17172             generate_exception(ctx, EXCP_RI);
17173             break;
17174         }
17175         break;
17176     case OPC_DAPPEND_DSP:
17177         gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17178         break;
17179     case OPC_DEXTR_W_DSP:
17180         op2 = MASK_DEXTR_W(ctx->opcode);
17181         switch (op2) {
17182         case OPC_DEXTP:
17183         case OPC_DEXTPDP:
17184         case OPC_DEXTPDPV:
17185         case OPC_DEXTPV:
17186         case OPC_DEXTR_L:
17187         case OPC_DEXTR_R_L:
17188         case OPC_DEXTR_RS_L:
17189         case OPC_DEXTR_W:
17190         case OPC_DEXTR_R_W:
17191         case OPC_DEXTR_RS_W:
17192         case OPC_DEXTR_S_H:
17193         case OPC_DEXTRV_L:
17194         case OPC_DEXTRV_R_L:
17195         case OPC_DEXTRV_RS_L:
17196         case OPC_DEXTRV_S_H:
17197         case OPC_DEXTRV_W:
17198         case OPC_DEXTRV_R_W:
17199         case OPC_DEXTRV_RS_W:
17200             gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
17201             break;
17202         case OPC_DMTHLIP:
17203         case OPC_DSHILO:
17204         case OPC_DSHILOV:
17205             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
17206             break;
17207         default:            /* Invalid */
17208             MIPS_INVAL("MASK EXTR.W");
17209             generate_exception(ctx, EXCP_RI);
17210             break;
17211         }
17212         break;
17213     case OPC_DPAQ_W_QH_DSP:
17214         op2 = MASK_DPAQ_W_QH(ctx->opcode);
17215         switch (op2) {
17216         case OPC_DPAU_H_OBL:
17217         case OPC_DPAU_H_OBR:
17218         case OPC_DPSU_H_OBL:
17219         case OPC_DPSU_H_OBR:
17220         case OPC_DPA_W_QH:
17221         case OPC_DPAQ_S_W_QH:
17222         case OPC_DPS_W_QH:
17223         case OPC_DPSQ_S_W_QH:
17224         case OPC_MULSAQ_S_W_QH:
17225         case OPC_DPAQ_SA_L_PW:
17226         case OPC_DPSQ_SA_L_PW:
17227         case OPC_MULSAQ_S_L_PW:
17228             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17229             break;
17230         case OPC_MAQ_S_W_QHLL:
17231         case OPC_MAQ_S_W_QHLR:
17232         case OPC_MAQ_S_W_QHRL:
17233         case OPC_MAQ_S_W_QHRR:
17234         case OPC_MAQ_SA_W_QHLL:
17235         case OPC_MAQ_SA_W_QHLR:
17236         case OPC_MAQ_SA_W_QHRL:
17237         case OPC_MAQ_SA_W_QHRR:
17238         case OPC_MAQ_S_L_PWL:
17239         case OPC_MAQ_S_L_PWR:
17240         case OPC_DMADD:
17241         case OPC_DMADDU:
17242         case OPC_DMSUB:
17243         case OPC_DMSUBU:
17244             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17245             break;
17246         default:            /* Invalid */
17247             MIPS_INVAL("MASK DPAQ.W.QH");
17248             generate_exception(ctx, EXCP_RI);
17249             break;
17250         }
17251         break;
17252     case OPC_DINSV_DSP:
17253         op2 = MASK_INSV(ctx->opcode);
17254         switch (op2) {
17255         case OPC_DINSV:
17256         {
17257             TCGv t0, t1;
17258 
17259             if (rt == 0) {
17260                 MIPS_DEBUG("NOP");
17261                 break;
17262             }
17263             check_dsp(ctx);
17264 
17265             t0 = tcg_temp_new(tcg_ctx);
17266             t1 = tcg_temp_new(tcg_ctx);
17267 
17268             gen_load_gpr(ctx, t0, rt);
17269             gen_load_gpr(ctx, t1, rs);
17270 
17271             gen_helper_dinsv(tcg_ctx, *cpu_gpr[rt], tcg_ctx->cpu_env, t1, t0);
17272 
17273             tcg_temp_free(tcg_ctx, t0);
17274             tcg_temp_free(tcg_ctx, t1);
17275             break;
17276         }
17277         default:            /* Invalid */
17278             MIPS_INVAL("MASK DINSV");
17279             generate_exception(ctx, EXCP_RI);
17280             break;
17281         }
17282         break;
17283     case OPC_SHLL_OB_DSP:
17284         gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17285         break;
17286 #endif
17287     default:            /* Invalid */
17288         MIPS_INVAL("special3_legacy");
17289         generate_exception(ctx, EXCP_RI);
17290         break;
17291     }
17292 }
17293 
decode_opc_special3(CPUMIPSState * env,DisasContext * ctx)17294 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
17295 {
17296     TCGContext *tcg_ctx = env->uc->tcg_ctx;
17297     int rs, rt, rd, sa;
17298     uint32_t op1, op2;
17299 
17300     rs = (ctx->opcode >> 21) & 0x1f;
17301     rt = (ctx->opcode >> 16) & 0x1f;
17302     rd = (ctx->opcode >> 11) & 0x1f;
17303     sa = (ctx->opcode >> 6) & 0x1f;
17304 
17305     op1 = MASK_SPECIAL3(ctx->opcode);
17306     switch (op1) {
17307     case OPC_EXT:
17308     case OPC_INS:
17309         check_insn(ctx, ISA_MIPS32R2);
17310         gen_bitops(ctx, op1, rt, rs, sa, rd);
17311         break;
17312     case OPC_BSHFL:
17313         op2 = MASK_BSHFL(ctx->opcode);
17314         switch (op2) {
17315         case OPC_ALIGN: case OPC_ALIGN_END:
17316         case OPC_BITSWAP:
17317             check_insn(ctx, ISA_MIPS32R6);
17318             decode_opc_special3_r6(env, ctx);
17319             break;
17320         default:
17321             check_insn(ctx, ISA_MIPS32R2);
17322             gen_bshfl(ctx, op2, rt, rd);
17323             break;
17324         }
17325         break;
17326 #if defined(TARGET_MIPS64)
17327     case OPC_DEXTM: case OPC_DEXTU: case OPC_DEXT:
17328     case OPC_DINSM: case OPC_DINSU: case OPC_DINS:
17329         check_insn(ctx, ISA_MIPS64R2);
17330         check_mips_64(ctx);
17331         gen_bitops(ctx, op1, rt, rs, sa, rd);
17332         break;
17333     case OPC_DBSHFL:
17334         op2 = MASK_DBSHFL(ctx->opcode);
17335         switch (op2) {
17336         case OPC_DALIGN: case OPC_DALIGN_END:
17337         case OPC_DBITSWAP:
17338             check_insn(ctx, ISA_MIPS32R6);
17339             decode_opc_special3_r6(env, ctx);
17340             break;
17341         default:
17342             check_insn(ctx, ISA_MIPS64R2);
17343             check_mips_64(ctx);
17344             op2 = MASK_DBSHFL(ctx->opcode);
17345             gen_bshfl(ctx, op2, rt, rd);
17346             break;
17347         }
17348         break;
17349 #endif
17350     case OPC_RDHWR:
17351         gen_rdhwr(ctx, rt, rd);
17352         break;
17353     case OPC_FORK:
17354         check_insn(ctx, ASE_MT);
17355         {
17356             TCGv t0 = tcg_temp_new(tcg_ctx);
17357             TCGv t1 = tcg_temp_new(tcg_ctx);
17358 
17359             gen_load_gpr(ctx, t0, rt);
17360             gen_load_gpr(ctx, t1, rs);
17361             gen_helper_fork(tcg_ctx, t0, t1);
17362             tcg_temp_free(tcg_ctx, t0);
17363             tcg_temp_free(tcg_ctx, t1);
17364         }
17365         break;
17366     case OPC_YIELD:
17367         check_insn(ctx, ASE_MT);
17368         {
17369             TCGv t0 = tcg_temp_new(tcg_ctx);
17370 
17371             save_cpu_state(ctx, 1);
17372             gen_load_gpr(ctx, t0, rs);
17373             gen_helper_yield(tcg_ctx, t0, tcg_ctx->cpu_env, t0);
17374             gen_store_gpr(tcg_ctx, t0, rd);
17375             tcg_temp_free(tcg_ctx, t0);
17376         }
17377         break;
17378     default:
17379         if (ctx->insn_flags & ISA_MIPS32R6) {
17380             decode_opc_special3_r6(env, ctx);
17381         } else {
17382             decode_opc_special3_legacy(env, ctx);
17383         }
17384     }
17385 }
17386 
17387 /* MIPS SIMD Architecture (MSA)  */
check_msa_access(DisasContext * ctx)17388 static inline int check_msa_access(DisasContext *ctx)
17389 {
17390     if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
17391                  !(ctx->hflags & MIPS_HFLAG_F64))) {
17392         generate_exception(ctx, EXCP_RI);
17393         return 0;
17394     }
17395 
17396     if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
17397         if (ctx->insn_flags & ASE_MSA) {
17398             generate_exception(ctx, EXCP_MSADIS);
17399             return 0;
17400         } else {
17401             generate_exception(ctx, EXCP_RI);
17402             return 0;
17403         }
17404     }
17405     return 1;
17406 }
17407 
gen_check_zero_element(CPUMIPSState * env,TCGv tresult,uint8_t df,uint8_t wt)17408 static void gen_check_zero_element(CPUMIPSState *env, TCGv tresult, uint8_t df, uint8_t wt)
17409 {
17410     TCGContext *tcg_ctx = env->uc->tcg_ctx;
17411     /* generates tcg ops to check if any element is 0 */
17412     /* Note this function only works with MSA_WRLEN = 128 */
17413     uint64_t eval_zero_or_big = 0;
17414     uint64_t eval_big = 0;
17415     TCGv_i64 t0 = tcg_temp_new_i64(tcg_ctx);
17416     TCGv_i64 t1 = tcg_temp_new_i64(tcg_ctx);
17417     switch (df) {
17418     case DF_BYTE:
17419         eval_zero_or_big = 0x0101010101010101ULL;
17420         eval_big = 0x8080808080808080ULL;
17421         break;
17422     case DF_HALF:
17423         eval_zero_or_big = 0x0001000100010001ULL;
17424         eval_big = 0x8000800080008000ULL;
17425         break;
17426     case DF_WORD:
17427         eval_zero_or_big = 0x0000000100000001ULL;
17428         eval_big = 0x8000000080000000ULL;
17429         break;
17430     case DF_DOUBLE:
17431         eval_zero_or_big = 0x0000000000000001ULL;
17432         eval_big = 0x8000000000000000ULL;
17433         break;
17434     }
17435     tcg_gen_subi_i64(tcg_ctx, t0, tcg_ctx->msa_wr_d[wt<<1], eval_zero_or_big);
17436     tcg_gen_andc_i64(tcg_ctx, t0, t0, tcg_ctx->msa_wr_d[wt<<1]);
17437     tcg_gen_andi_i64(tcg_ctx, t0, t0, eval_big);
17438     tcg_gen_subi_i64(tcg_ctx, t1, tcg_ctx->msa_wr_d[(wt<<1)+1], eval_zero_or_big);
17439     tcg_gen_andc_i64(tcg_ctx, t1, t1, tcg_ctx->msa_wr_d[(wt<<1)+1]);
17440     tcg_gen_andi_i64(tcg_ctx, t1, t1, eval_big);
17441     tcg_gen_or_i64(tcg_ctx, t0, t0, t1);
17442     /* if all bits are zero then all elements are not zero */
17443     /* if some bit is non-zero then some element is zero */
17444     tcg_gen_setcondi_i64(tcg_ctx, TCG_COND_NE, t0, t0, 0);
17445     tcg_gen_trunc_i64_tl(tcg_ctx, tresult, t0);
17446     tcg_temp_free_i64(tcg_ctx, t0);
17447     tcg_temp_free_i64(tcg_ctx, t1);
17448 }
17449 
gen_msa_branch(CPUMIPSState * env,DisasContext * ctx,uint32_t op1)17450 static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
17451 {
17452     TCGContext *tcg_ctx = env->uc->tcg_ctx;
17453     uint8_t df = (ctx->opcode >> 21) & 0x3;
17454     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
17455     int64_t s16 = (int16_t)ctx->opcode;
17456 
17457     check_msa_access(ctx);
17458 
17459     if (ctx->insn_flags & ISA_MIPS32R6 && ctx->hflags & MIPS_HFLAG_BMASK) {
17460         MIPS_DEBUG("CTI in delay / forbidden slot");
17461         generate_exception(ctx, EXCP_RI);
17462         return;
17463     }
17464     switch (op1) {
17465     case OPC_BZ_V:
17466     case OPC_BNZ_V:
17467         {
17468             TCGv_i64 t0 = tcg_temp_new_i64(tcg_ctx);
17469             tcg_gen_or_i64(tcg_ctx, t0, tcg_ctx->msa_wr_d[wt<<1], tcg_ctx->msa_wr_d[(wt<<1)+1]);
17470             tcg_gen_setcondi_i64(tcg_ctx, (op1 == OPC_BZ_V) ?
17471                     TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
17472             tcg_gen_trunc_i64_tl(tcg_ctx, *(TCGv *)tcg_ctx->bcond, t0);
17473             tcg_temp_free_i64(tcg_ctx, t0);
17474         }
17475         break;
17476     case OPC_BZ_B:
17477     case OPC_BZ_H:
17478     case OPC_BZ_W:
17479     case OPC_BZ_D:
17480         gen_check_zero_element(env, *(TCGv *)tcg_ctx->bcond, df, wt);
17481         break;
17482     case OPC_BNZ_B:
17483     case OPC_BNZ_H:
17484     case OPC_BNZ_W:
17485     case OPC_BNZ_D:
17486         gen_check_zero_element(env, *(TCGv *)tcg_ctx->bcond, df, wt);
17487         tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_EQ, *(TCGv *)tcg_ctx->bcond, *(TCGv *)tcg_ctx->bcond, 0);
17488         break;
17489     }
17490 
17491     ctx->btarget = ctx->pc + (int64_t)((uint64_t)s16 << 2) + 4;
17492 
17493     ctx->hflags |= MIPS_HFLAG_BC;
17494     ctx->hflags |= MIPS_HFLAG_BDS32;
17495 }
17496 
gen_msa_i8(CPUMIPSState * env,DisasContext * ctx)17497 static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
17498 {
17499 #define MASK_MSA_I8(op)    (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
17500     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
17501     uint8_t i8 = (ctx->opcode >> 16) & 0xff;
17502     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17503     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17504 
17505     TCGv_i32 twd = tcg_const_i32(tcg_ctx, wd);
17506     TCGv_i32 tws = tcg_const_i32(tcg_ctx, ws);
17507     TCGv_i32 ti8 = tcg_const_i32(tcg_ctx, i8);
17508 
17509     switch (MASK_MSA_I8(ctx->opcode)) {
17510     case OPC_ANDI_B:
17511         gen_helper_msa_andi_b(tcg_ctx, tcg_ctx->cpu_env, twd, tws, ti8);
17512         break;
17513     case OPC_ORI_B:
17514         gen_helper_msa_ori_b(tcg_ctx, tcg_ctx->cpu_env, twd, tws, ti8);
17515         break;
17516     case OPC_NORI_B:
17517         gen_helper_msa_nori_b(tcg_ctx, tcg_ctx->cpu_env, twd, tws, ti8);
17518         break;
17519     case OPC_XORI_B:
17520         gen_helper_msa_xori_b(tcg_ctx, tcg_ctx->cpu_env, twd, tws, ti8);
17521         break;
17522     case OPC_BMNZI_B:
17523         gen_helper_msa_bmnzi_b(tcg_ctx, tcg_ctx->cpu_env, twd, tws, ti8);
17524         break;
17525     case OPC_BMZI_B:
17526         gen_helper_msa_bmzi_b(tcg_ctx, tcg_ctx->cpu_env, twd, tws, ti8);
17527         break;
17528     case OPC_BSELI_B:
17529         gen_helper_msa_bseli_b(tcg_ctx, tcg_ctx->cpu_env, twd, tws, ti8);
17530         break;
17531     case OPC_SHF_B:
17532     case OPC_SHF_H:
17533     case OPC_SHF_W:
17534         {
17535             uint8_t df = (ctx->opcode >> 24) & 0x3;
17536             if (df == DF_DOUBLE) {
17537                 generate_exception(ctx, EXCP_RI);
17538             } else {
17539                 TCGv_i32 tdf = tcg_const_i32(tcg_ctx, df);
17540                 gen_helper_msa_shf_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, ti8);
17541                 tcg_temp_free_i32(tcg_ctx, tdf);
17542             }
17543         }
17544         break;
17545     default:
17546         MIPS_INVAL("MSA instruction");
17547         generate_exception(ctx, EXCP_RI);
17548         break;
17549     }
17550 
17551     tcg_temp_free_i32(tcg_ctx, twd);
17552     tcg_temp_free_i32(tcg_ctx, tws);
17553     tcg_temp_free_i32(tcg_ctx, ti8);
17554 }
17555 
gen_msa_i5(CPUMIPSState * env,DisasContext * ctx)17556 static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
17557 {
17558 #define MASK_MSA_I5(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
17559     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
17560     uint8_t df = (ctx->opcode >> 21) & 0x3;
17561     int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
17562     uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
17563     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17564     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17565 
17566     TCGv_i32 tdf = tcg_const_i32(tcg_ctx, df);
17567     TCGv_i32 twd = tcg_const_i32(tcg_ctx, wd);
17568     TCGv_i32 tws = tcg_const_i32(tcg_ctx, ws);
17569     TCGv_i32 timm = tcg_temp_new_i32(tcg_ctx);
17570     tcg_gen_movi_i32(tcg_ctx, timm, u5);
17571 
17572     switch (MASK_MSA_I5(ctx->opcode)) {
17573     case OPC_ADDVI_df:
17574         gen_helper_msa_addvi_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, timm);
17575         break;
17576     case OPC_SUBVI_df:
17577         gen_helper_msa_subvi_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, timm);
17578         break;
17579     case OPC_MAXI_S_df:
17580         tcg_gen_movi_i32(tcg_ctx, timm, s5);
17581         gen_helper_msa_maxi_s_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, timm);
17582         break;
17583     case OPC_MAXI_U_df:
17584         gen_helper_msa_maxi_u_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, timm);
17585         break;
17586     case OPC_MINI_S_df:
17587         tcg_gen_movi_i32(tcg_ctx, timm, s5);
17588         gen_helper_msa_mini_s_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, timm);
17589         break;
17590     case OPC_MINI_U_df:
17591         gen_helper_msa_mini_u_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, timm);
17592         break;
17593     case OPC_CEQI_df:
17594         tcg_gen_movi_i32(tcg_ctx, timm, s5);
17595         gen_helper_msa_ceqi_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, timm);
17596         break;
17597     case OPC_CLTI_S_df:
17598         tcg_gen_movi_i32(tcg_ctx, timm, s5);
17599         gen_helper_msa_clti_s_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, timm);
17600         break;
17601     case OPC_CLTI_U_df:
17602         gen_helper_msa_clti_u_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, timm);
17603         break;
17604     case OPC_CLEI_S_df:
17605         tcg_gen_movi_i32(tcg_ctx, timm, s5);
17606         gen_helper_msa_clei_s_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, timm);
17607         break;
17608     case OPC_CLEI_U_df:
17609         gen_helper_msa_clei_u_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, timm);
17610         break;
17611     case OPC_LDI_df:
17612         {
17613             int32_t s10 = sextract32(ctx->opcode, 11, 10);
17614             tcg_gen_movi_i32(tcg_ctx, timm, s10);
17615             gen_helper_msa_ldi_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, timm);
17616         }
17617         break;
17618     default:
17619         MIPS_INVAL("MSA instruction");
17620         generate_exception(ctx, EXCP_RI);
17621         break;
17622     }
17623 
17624     tcg_temp_free_i32(tcg_ctx, tdf);
17625     tcg_temp_free_i32(tcg_ctx, twd);
17626     tcg_temp_free_i32(tcg_ctx, tws);
17627     tcg_temp_free_i32(tcg_ctx, timm);
17628 }
17629 
gen_msa_bit(CPUMIPSState * env,DisasContext * ctx)17630 static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
17631 {
17632 #define MASK_MSA_BIT(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
17633     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
17634     uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
17635     uint32_t df = 0, m = 0;
17636     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17637     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17638 
17639     TCGv_i32 tdf;
17640     TCGv_i32 tm;
17641     TCGv_i32 twd;
17642     TCGv_i32 tws;
17643 
17644     if ((dfm & 0x40) == 0x00) {
17645         m = dfm & 0x3f;
17646         df = DF_DOUBLE;
17647     } else if ((dfm & 0x60) == 0x40) {
17648         m = dfm & 0x1f;
17649         df = DF_WORD;
17650     } else if ((dfm & 0x70) == 0x60) {
17651         m = dfm & 0x0f;
17652         df = DF_HALF;
17653     } else if ((dfm & 0x78) == 0x70) {
17654         m = dfm & 0x7;
17655         df = DF_BYTE;
17656     } else {
17657         generate_exception(ctx, EXCP_RI);
17658         return;
17659     }
17660 
17661     tdf = tcg_const_i32(tcg_ctx, df);
17662     tm  = tcg_const_i32(tcg_ctx, m);
17663     twd = tcg_const_i32(tcg_ctx, wd);
17664     tws = tcg_const_i32(tcg_ctx, ws);
17665 
17666     switch (MASK_MSA_BIT(ctx->opcode)) {
17667     case OPC_SLLI_df:
17668         gen_helper_msa_slli_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, tm);
17669         break;
17670     case OPC_SRAI_df:
17671         gen_helper_msa_srai_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, tm);
17672         break;
17673     case OPC_SRLI_df:
17674         gen_helper_msa_srli_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, tm);
17675         break;
17676     case OPC_BCLRI_df:
17677         gen_helper_msa_bclri_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, tm);
17678         break;
17679     case OPC_BSETI_df:
17680         gen_helper_msa_bseti_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, tm);
17681         break;
17682     case OPC_BNEGI_df:
17683         gen_helper_msa_bnegi_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, tm);
17684         break;
17685     case OPC_BINSLI_df:
17686         gen_helper_msa_binsli_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, tm);
17687         break;
17688     case OPC_BINSRI_df:
17689         gen_helper_msa_binsri_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, tm);
17690         break;
17691     case OPC_SAT_S_df:
17692         gen_helper_msa_sat_s_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, tm);
17693         break;
17694     case OPC_SAT_U_df:
17695         gen_helper_msa_sat_u_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, tm);
17696         break;
17697     case OPC_SRARI_df:
17698         gen_helper_msa_srari_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, tm);
17699         break;
17700     case OPC_SRLRI_df:
17701         gen_helper_msa_srlri_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, tm);
17702         break;
17703     default:
17704         MIPS_INVAL("MSA instruction");
17705         generate_exception(ctx, EXCP_RI);
17706         break;
17707     }
17708 
17709     tcg_temp_free_i32(tcg_ctx, tdf);
17710     tcg_temp_free_i32(tcg_ctx, tm);
17711     tcg_temp_free_i32(tcg_ctx, twd);
17712     tcg_temp_free_i32(tcg_ctx, tws);
17713 }
17714 
gen_msa_3r(CPUMIPSState * env,DisasContext * ctx)17715 static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
17716 {
17717 #define MASK_MSA_3R(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
17718     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
17719     uint8_t df = (ctx->opcode >> 21) & 0x3;
17720     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
17721     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17722     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17723 
17724     TCGv_i32 tdf = tcg_const_i32(tcg_ctx, df);
17725     TCGv_i32 twd = tcg_const_i32(tcg_ctx, wd);
17726     TCGv_i32 tws = tcg_const_i32(tcg_ctx, ws);
17727     TCGv_i32 twt = tcg_const_i32(tcg_ctx, wt);
17728 
17729     switch (MASK_MSA_3R(ctx->opcode)) {
17730     case OPC_SLL_df:
17731         gen_helper_msa_sll_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17732         break;
17733     case OPC_ADDV_df:
17734         gen_helper_msa_addv_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17735         break;
17736     case OPC_CEQ_df:
17737         gen_helper_msa_ceq_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17738         break;
17739     case OPC_ADD_A_df:
17740         gen_helper_msa_add_a_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17741         break;
17742     case OPC_SUBS_S_df:
17743         gen_helper_msa_subs_s_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17744         break;
17745     case OPC_MULV_df:
17746         gen_helper_msa_mulv_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17747         break;
17748     case OPC_SLD_df:
17749         gen_helper_msa_sld_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17750         break;
17751     case OPC_VSHF_df:
17752         gen_helper_msa_vshf_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17753         break;
17754     case OPC_SRA_df:
17755         gen_helper_msa_sra_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17756         break;
17757     case OPC_SUBV_df:
17758         gen_helper_msa_subv_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17759         break;
17760     case OPC_ADDS_A_df:
17761         gen_helper_msa_adds_a_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17762         break;
17763     case OPC_SUBS_U_df:
17764         gen_helper_msa_subs_u_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17765         break;
17766     case OPC_MADDV_df:
17767         gen_helper_msa_maddv_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17768         break;
17769     case OPC_SPLAT_df:
17770         gen_helper_msa_splat_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17771         break;
17772     case OPC_SRAR_df:
17773         gen_helper_msa_srar_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17774         break;
17775     case OPC_SRL_df:
17776         gen_helper_msa_srl_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17777         break;
17778     case OPC_MAX_S_df:
17779         gen_helper_msa_max_s_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17780         break;
17781     case OPC_CLT_S_df:
17782         gen_helper_msa_clt_s_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17783         break;
17784     case OPC_ADDS_S_df:
17785         gen_helper_msa_adds_s_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17786         break;
17787     case OPC_SUBSUS_U_df:
17788         gen_helper_msa_subsus_u_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17789         break;
17790     case OPC_MSUBV_df:
17791         gen_helper_msa_msubv_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17792         break;
17793     case OPC_PCKEV_df:
17794         gen_helper_msa_pckev_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17795         break;
17796     case OPC_SRLR_df:
17797         gen_helper_msa_srlr_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17798         break;
17799     case OPC_BCLR_df:
17800         gen_helper_msa_bclr_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17801         break;
17802     case OPC_MAX_U_df:
17803         gen_helper_msa_max_u_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17804         break;
17805     case OPC_CLT_U_df:
17806         gen_helper_msa_clt_u_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17807         break;
17808     case OPC_ADDS_U_df:
17809         gen_helper_msa_adds_u_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17810         break;
17811     case OPC_SUBSUU_S_df:
17812         gen_helper_msa_subsuu_s_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17813         break;
17814     case OPC_PCKOD_df:
17815         gen_helper_msa_pckod_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17816         break;
17817     case OPC_BSET_df:
17818         gen_helper_msa_bset_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17819         break;
17820     case OPC_MIN_S_df:
17821         gen_helper_msa_min_s_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17822         break;
17823     case OPC_CLE_S_df:
17824         gen_helper_msa_cle_s_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17825         break;
17826     case OPC_AVE_S_df:
17827         gen_helper_msa_ave_s_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17828         break;
17829     case OPC_ASUB_S_df:
17830         gen_helper_msa_asub_s_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17831         break;
17832     case OPC_DIV_S_df:
17833         gen_helper_msa_div_s_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17834         break;
17835     case OPC_ILVL_df:
17836         gen_helper_msa_ilvl_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17837         break;
17838     case OPC_BNEG_df:
17839         gen_helper_msa_bneg_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17840         break;
17841     case OPC_MIN_U_df:
17842         gen_helper_msa_min_u_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17843         break;
17844     case OPC_CLE_U_df:
17845         gen_helper_msa_cle_u_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17846         break;
17847     case OPC_AVE_U_df:
17848         gen_helper_msa_ave_u_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17849         break;
17850     case OPC_ASUB_U_df:
17851         gen_helper_msa_asub_u_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17852         break;
17853     case OPC_DIV_U_df:
17854         gen_helper_msa_div_u_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17855         break;
17856     case OPC_ILVR_df:
17857         gen_helper_msa_ilvr_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17858         break;
17859     case OPC_BINSL_df:
17860         gen_helper_msa_binsl_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17861         break;
17862     case OPC_MAX_A_df:
17863         gen_helper_msa_max_a_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17864         break;
17865     case OPC_AVER_S_df:
17866         gen_helper_msa_aver_s_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17867         break;
17868     case OPC_MOD_S_df:
17869         gen_helper_msa_mod_s_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17870         break;
17871     case OPC_ILVEV_df:
17872         gen_helper_msa_ilvev_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17873         break;
17874     case OPC_BINSR_df:
17875         gen_helper_msa_binsr_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17876         break;
17877     case OPC_MIN_A_df:
17878         gen_helper_msa_min_a_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17879         break;
17880     case OPC_AVER_U_df:
17881         gen_helper_msa_aver_u_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17882         break;
17883     case OPC_MOD_U_df:
17884         gen_helper_msa_mod_u_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17885         break;
17886     case OPC_ILVOD_df:
17887         gen_helper_msa_ilvod_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17888         break;
17889 
17890     case OPC_DOTP_S_df:
17891     case OPC_DOTP_U_df:
17892     case OPC_DPADD_S_df:
17893     case OPC_DPADD_U_df:
17894     case OPC_DPSUB_S_df:
17895     case OPC_HADD_S_df:
17896     case OPC_DPSUB_U_df:
17897     case OPC_HADD_U_df:
17898     case OPC_HSUB_S_df:
17899     case OPC_HSUB_U_df:
17900         if (df == DF_BYTE) {
17901             generate_exception(ctx, EXCP_RI);
17902         }
17903         switch (MASK_MSA_3R(ctx->opcode)) {
17904         case OPC_DOTP_S_df:
17905             gen_helper_msa_dotp_s_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17906             break;
17907         case OPC_DOTP_U_df:
17908             gen_helper_msa_dotp_u_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17909             break;
17910         case OPC_DPADD_S_df:
17911             gen_helper_msa_dpadd_s_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17912             break;
17913         case OPC_DPADD_U_df:
17914             gen_helper_msa_dpadd_u_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17915             break;
17916         case OPC_DPSUB_S_df:
17917             gen_helper_msa_dpsub_s_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17918             break;
17919         case OPC_HADD_S_df:
17920             gen_helper_msa_hadd_s_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17921             break;
17922         case OPC_DPSUB_U_df:
17923             gen_helper_msa_dpsub_u_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17924             break;
17925         case OPC_HADD_U_df:
17926             gen_helper_msa_hadd_u_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17927             break;
17928         case OPC_HSUB_S_df:
17929             gen_helper_msa_hsub_s_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17930             break;
17931         case OPC_HSUB_U_df:
17932             gen_helper_msa_hsub_u_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
17933             break;
17934         }
17935         break;
17936     default:
17937         MIPS_INVAL("MSA instruction");
17938         generate_exception(ctx, EXCP_RI);
17939         break;
17940     }
17941     tcg_temp_free_i32(tcg_ctx, twd);
17942     tcg_temp_free_i32(tcg_ctx, tws);
17943     tcg_temp_free_i32(tcg_ctx, twt);
17944     tcg_temp_free_i32(tcg_ctx, tdf);
17945 }
17946 
gen_msa_elm_3e(CPUMIPSState * env,DisasContext * ctx)17947 static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
17948 {
17949 #define MASK_MSA_ELM_DF3E(op)   (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
17950     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
17951     uint8_t source = (ctx->opcode >> 11) & 0x1f;
17952     uint8_t dest = (ctx->opcode >> 6) & 0x1f;
17953     TCGv telm = tcg_temp_new(tcg_ctx);
17954     TCGv_i32 tsr = tcg_const_i32(tcg_ctx, source);
17955     TCGv_i32 tdt = tcg_const_i32(tcg_ctx, dest);
17956 
17957     switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
17958     case OPC_CTCMSA:
17959         gen_load_gpr(ctx, telm, source);
17960         gen_helper_msa_ctcmsa(tcg_ctx, tcg_ctx->cpu_env, telm, tdt);
17961         break;
17962     case OPC_CFCMSA:
17963         gen_helper_msa_cfcmsa(tcg_ctx, telm, tcg_ctx->cpu_env, tsr);
17964         gen_store_gpr(tcg_ctx, telm, dest);
17965         break;
17966     case OPC_MOVE_V:
17967         gen_helper_msa_move_v(tcg_ctx, tcg_ctx->cpu_env, tdt, tsr);
17968         break;
17969     default:
17970         MIPS_INVAL("MSA instruction");
17971         generate_exception(ctx, EXCP_RI);
17972         break;
17973     }
17974 
17975     tcg_temp_free(tcg_ctx, telm);
17976     tcg_temp_free_i32(tcg_ctx, tdt);
17977     tcg_temp_free_i32(tcg_ctx, tsr);
17978 }
17979 
gen_msa_elm_df(CPUMIPSState * env,DisasContext * ctx,uint32_t df,uint32_t n)17980 static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
17981         uint32_t n)
17982 {
17983 #define MASK_MSA_ELM(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
17984     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
17985     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17986     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17987 
17988     TCGv_i32 tws = tcg_const_i32(tcg_ctx, ws);
17989     TCGv_i32 twd = tcg_const_i32(tcg_ctx, wd);
17990     TCGv_i32 tn  = tcg_const_i32(tcg_ctx, n);
17991     TCGv_i32 tdf = tcg_const_i32(tcg_ctx, df);
17992 
17993     switch (MASK_MSA_ELM(ctx->opcode)) {
17994     case OPC_SLDI_df:
17995         gen_helper_msa_sldi_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, tn);
17996         break;
17997     case OPC_SPLATI_df:
17998         gen_helper_msa_splati_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, tn);
17999         break;
18000     case OPC_INSVE_df:
18001         gen_helper_msa_insve_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, tn);
18002         break;
18003     case OPC_COPY_S_df:
18004     case OPC_COPY_U_df:
18005     case OPC_INSERT_df:
18006 #if !defined(TARGET_MIPS64)
18007         /* Double format valid only for MIPS64 */
18008         if (df == DF_DOUBLE) {
18009             generate_exception(ctx, EXCP_RI);
18010             break;
18011         }
18012 #endif
18013         switch (MASK_MSA_ELM(ctx->opcode)) {
18014         case OPC_COPY_S_df:
18015             gen_helper_msa_copy_s_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, tn);
18016             break;
18017         case OPC_COPY_U_df:
18018             gen_helper_msa_copy_u_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, tn);
18019             break;
18020         case OPC_INSERT_df:
18021             gen_helper_msa_insert_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, tn);
18022             break;
18023         }
18024         break;
18025     default:
18026         MIPS_INVAL("MSA instruction");
18027         generate_exception(ctx, EXCP_RI);
18028     }
18029     tcg_temp_free_i32(tcg_ctx, twd);
18030     tcg_temp_free_i32(tcg_ctx, tws);
18031     tcg_temp_free_i32(tcg_ctx, tn);
18032     tcg_temp_free_i32(tcg_ctx, tdf);
18033 }
18034 
gen_msa_elm(CPUMIPSState * env,DisasContext * ctx)18035 static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
18036 {
18037     uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
18038     uint32_t df = 0, n = 0;
18039 
18040     if ((dfn & 0x30) == 0x00) {
18041         n = dfn & 0x0f;
18042         df = DF_BYTE;
18043     } else if ((dfn & 0x38) == 0x20) {
18044         n = dfn & 0x07;
18045         df = DF_HALF;
18046     } else if ((dfn & 0x3c) == 0x30) {
18047         n = dfn & 0x03;
18048         df = DF_WORD;
18049     } else if ((dfn & 0x3e) == 0x38) {
18050         n = dfn & 0x01;
18051         df = DF_DOUBLE;
18052     } else if (dfn == 0x3E) {
18053         /* CTCMSA, CFCMSA, MOVE.V */
18054         gen_msa_elm_3e(env, ctx);
18055         return;
18056     } else {
18057         generate_exception(ctx, EXCP_RI);
18058         return;
18059     }
18060 
18061     gen_msa_elm_df(env, ctx, df, n);
18062 }
18063 
gen_msa_3rf(CPUMIPSState * env,DisasContext * ctx)18064 static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
18065 {
18066 #define MASK_MSA_3RF(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18067     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
18068     uint8_t df = (ctx->opcode >> 21) & 0x1;
18069     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18070     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18071     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18072 
18073     TCGv_i32 twd = tcg_const_i32(tcg_ctx, wd);
18074     TCGv_i32 tws = tcg_const_i32(tcg_ctx, ws);
18075     TCGv_i32 twt = tcg_const_i32(tcg_ctx, wt);
18076     TCGv_i32 tdf = tcg_temp_new_i32(tcg_ctx);
18077 
18078     /* adjust df value for floating-point instruction */
18079     tcg_gen_movi_i32(tcg_ctx, tdf, df + 2);
18080 
18081     switch (MASK_MSA_3RF(ctx->opcode)) {
18082     case OPC_FCAF_df:
18083         gen_helper_msa_fcaf_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18084         break;
18085     case OPC_FADD_df:
18086         gen_helper_msa_fadd_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18087         break;
18088     case OPC_FCUN_df:
18089         gen_helper_msa_fcun_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18090         break;
18091     case OPC_FSUB_df:
18092         gen_helper_msa_fsub_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18093         break;
18094     case OPC_FCOR_df:
18095         gen_helper_msa_fcor_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18096         break;
18097     case OPC_FCEQ_df:
18098         gen_helper_msa_fceq_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18099         break;
18100     case OPC_FMUL_df:
18101         gen_helper_msa_fmul_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18102         break;
18103     case OPC_FCUNE_df:
18104         gen_helper_msa_fcune_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18105         break;
18106     case OPC_FCUEQ_df:
18107         gen_helper_msa_fcueq_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18108         break;
18109     case OPC_FDIV_df:
18110         gen_helper_msa_fdiv_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18111         break;
18112     case OPC_FCNE_df:
18113         gen_helper_msa_fcne_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18114         break;
18115     case OPC_FCLT_df:
18116         gen_helper_msa_fclt_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18117         break;
18118     case OPC_FMADD_df:
18119         gen_helper_msa_fmadd_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18120         break;
18121     case OPC_MUL_Q_df:
18122         tcg_gen_movi_i32(tcg_ctx, tdf, df + 1);
18123         gen_helper_msa_mul_q_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18124         break;
18125     case OPC_FCULT_df:
18126         gen_helper_msa_fcult_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18127         break;
18128     case OPC_FMSUB_df:
18129         gen_helper_msa_fmsub_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18130         break;
18131     case OPC_MADD_Q_df:
18132         tcg_gen_movi_i32(tcg_ctx, tdf, df + 1);
18133         gen_helper_msa_madd_q_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18134         break;
18135     case OPC_FCLE_df:
18136         gen_helper_msa_fcle_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18137         break;
18138     case OPC_MSUB_Q_df:
18139         tcg_gen_movi_i32(tcg_ctx, tdf, df + 1);
18140         gen_helper_msa_msub_q_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18141         break;
18142     case OPC_FCULE_df:
18143         gen_helper_msa_fcule_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18144         break;
18145     case OPC_FEXP2_df:
18146         gen_helper_msa_fexp2_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18147         break;
18148     case OPC_FSAF_df:
18149         gen_helper_msa_fsaf_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18150         break;
18151     case OPC_FEXDO_df:
18152         gen_helper_msa_fexdo_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18153         break;
18154     case OPC_FSUN_df:
18155         gen_helper_msa_fsun_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18156         break;
18157     case OPC_FSOR_df:
18158         gen_helper_msa_fsor_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18159         break;
18160     case OPC_FSEQ_df:
18161         gen_helper_msa_fseq_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18162         break;
18163     case OPC_FTQ_df:
18164         gen_helper_msa_ftq_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18165         break;
18166     case OPC_FSUNE_df:
18167         gen_helper_msa_fsune_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18168         break;
18169     case OPC_FSUEQ_df:
18170         gen_helper_msa_fsueq_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18171         break;
18172     case OPC_FSNE_df:
18173         gen_helper_msa_fsne_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18174         break;
18175     case OPC_FSLT_df:
18176         gen_helper_msa_fslt_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18177         break;
18178     case OPC_FMIN_df:
18179         gen_helper_msa_fmin_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18180         break;
18181     case OPC_MULR_Q_df:
18182         tcg_gen_movi_i32(tcg_ctx, tdf, df + 1);
18183         gen_helper_msa_mulr_q_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18184         break;
18185     case OPC_FSULT_df:
18186         gen_helper_msa_fsult_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18187         break;
18188     case OPC_FMIN_A_df:
18189         gen_helper_msa_fmin_a_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18190         break;
18191     case OPC_MADDR_Q_df:
18192         tcg_gen_movi_i32(tcg_ctx, tdf, df + 1);
18193         gen_helper_msa_maddr_q_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18194         break;
18195     case OPC_FSLE_df:
18196         gen_helper_msa_fsle_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18197         break;
18198     case OPC_FMAX_df:
18199         gen_helper_msa_fmax_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18200         break;
18201     case OPC_MSUBR_Q_df:
18202         tcg_gen_movi_i32(tcg_ctx, tdf, df + 1);
18203         gen_helper_msa_msubr_q_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18204         break;
18205     case OPC_FSULE_df:
18206         gen_helper_msa_fsule_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18207         break;
18208     case OPC_FMAX_A_df:
18209         gen_helper_msa_fmax_a_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, twt);
18210         break;
18211     default:
18212         MIPS_INVAL("MSA instruction");
18213         generate_exception(ctx, EXCP_RI);
18214         break;
18215     }
18216 
18217     tcg_temp_free_i32(tcg_ctx, twd);
18218     tcg_temp_free_i32(tcg_ctx, tws);
18219     tcg_temp_free_i32(tcg_ctx, twt);
18220     tcg_temp_free_i32(tcg_ctx, tdf);
18221 }
18222 
gen_msa_2r(CPUMIPSState * env,DisasContext * ctx)18223 static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
18224 {
18225 #define MASK_MSA_2R(op)     (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18226                             (op & (0x7 << 18)))
18227     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
18228     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18229     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18230     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18231     uint8_t df = (ctx->opcode >> 16) & 0x3;
18232     TCGv_i32 twd = tcg_const_i32(tcg_ctx, wd);
18233     TCGv_i32 tws = tcg_const_i32(tcg_ctx, ws);
18234     TCGv_i32 twt = tcg_const_i32(tcg_ctx, wt);
18235     TCGv_i32 tdf = tcg_const_i32(tcg_ctx, df);
18236 
18237     switch (MASK_MSA_2R(ctx->opcode)) {
18238     case OPC_FILL_df:
18239 #if !defined(TARGET_MIPS64)
18240         /* Double format valid only for MIPS64 */
18241         if (df == DF_DOUBLE) {
18242             generate_exception(ctx, EXCP_RI);
18243             break;
18244         }
18245 #endif
18246         gen_helper_msa_fill_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws); /* trs */
18247         break;
18248     case OPC_PCNT_df:
18249         gen_helper_msa_pcnt_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws);
18250         break;
18251     case OPC_NLOC_df:
18252         gen_helper_msa_nloc_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws);
18253         break;
18254     case OPC_NLZC_df:
18255         gen_helper_msa_nlzc_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws);
18256         break;
18257     default:
18258         MIPS_INVAL("MSA instruction");
18259         generate_exception(ctx, EXCP_RI);
18260         break;
18261     }
18262 
18263     tcg_temp_free_i32(tcg_ctx, twd);
18264     tcg_temp_free_i32(tcg_ctx, tws);
18265     tcg_temp_free_i32(tcg_ctx, twt);
18266     tcg_temp_free_i32(tcg_ctx, tdf);
18267 }
18268 
gen_msa_2rf(CPUMIPSState * env,DisasContext * ctx)18269 static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
18270 {
18271 #define MASK_MSA_2RF(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18272                             (op & (0xf << 17)))
18273     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
18274     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18275     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18276     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18277     uint8_t df = (ctx->opcode >> 16) & 0x1;
18278     TCGv_i32 twd = tcg_const_i32(tcg_ctx, wd);
18279     TCGv_i32 tws = tcg_const_i32(tcg_ctx, ws);
18280     TCGv_i32 twt = tcg_const_i32(tcg_ctx, wt);
18281     /* adjust df value for floating-point instruction */
18282     TCGv_i32 tdf = tcg_const_i32(tcg_ctx, df + 2);
18283 
18284     switch (MASK_MSA_2RF(ctx->opcode)) {
18285     case OPC_FCLASS_df:
18286         gen_helper_msa_fclass_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws);
18287         break;
18288     case OPC_FTRUNC_S_df:
18289         gen_helper_msa_ftrunc_s_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws);
18290         break;
18291     case OPC_FTRUNC_U_df:
18292         gen_helper_msa_ftrunc_u_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws);
18293         break;
18294     case OPC_FSQRT_df:
18295         gen_helper_msa_fsqrt_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws);
18296         break;
18297     case OPC_FRSQRT_df:
18298         gen_helper_msa_frsqrt_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws);
18299         break;
18300     case OPC_FRCP_df:
18301         gen_helper_msa_frcp_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws);
18302         break;
18303     case OPC_FRINT_df:
18304         gen_helper_msa_frint_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws);
18305         break;
18306     case OPC_FLOG2_df:
18307         gen_helper_msa_flog2_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws);
18308         break;
18309     case OPC_FEXUPL_df:
18310         gen_helper_msa_fexupl_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws);
18311         break;
18312     case OPC_FEXUPR_df:
18313         gen_helper_msa_fexupr_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws);
18314         break;
18315     case OPC_FFQL_df:
18316         gen_helper_msa_ffql_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws);
18317         break;
18318     case OPC_FFQR_df:
18319         gen_helper_msa_ffqr_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws);
18320         break;
18321     case OPC_FTINT_S_df:
18322         gen_helper_msa_ftint_s_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws);
18323         break;
18324     case OPC_FTINT_U_df:
18325         gen_helper_msa_ftint_u_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws);
18326         break;
18327     case OPC_FFINT_S_df:
18328         gen_helper_msa_ffint_s_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws);
18329         break;
18330     case OPC_FFINT_U_df:
18331         gen_helper_msa_ffint_u_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws);
18332         break;
18333     }
18334 
18335     tcg_temp_free_i32(tcg_ctx, twd);
18336     tcg_temp_free_i32(tcg_ctx, tws);
18337     tcg_temp_free_i32(tcg_ctx, twt);
18338     tcg_temp_free_i32(tcg_ctx, tdf);
18339 }
18340 
gen_msa_vec_v(CPUMIPSState * env,DisasContext * ctx)18341 static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
18342 {
18343 #define MASK_MSA_VEC(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
18344     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
18345     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18346     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18347     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18348     TCGv_i32 twd = tcg_const_i32(tcg_ctx, wd);
18349     TCGv_i32 tws = tcg_const_i32(tcg_ctx, ws);
18350     TCGv_i32 twt = tcg_const_i32(tcg_ctx, wt);
18351 
18352     switch (MASK_MSA_VEC(ctx->opcode)) {
18353     case OPC_AND_V:
18354         gen_helper_msa_and_v(tcg_ctx, tcg_ctx->cpu_env, twd, tws, twt);
18355         break;
18356     case OPC_OR_V:
18357         gen_helper_msa_or_v(tcg_ctx, tcg_ctx->cpu_env, twd, tws, twt);
18358         break;
18359     case OPC_NOR_V:
18360         gen_helper_msa_nor_v(tcg_ctx, tcg_ctx->cpu_env, twd, tws, twt);
18361         break;
18362     case OPC_XOR_V:
18363         gen_helper_msa_xor_v(tcg_ctx, tcg_ctx->cpu_env, twd, tws, twt);
18364         break;
18365     case OPC_BMNZ_V:
18366         gen_helper_msa_bmnz_v(tcg_ctx, tcg_ctx->cpu_env, twd, tws, twt);
18367         break;
18368     case OPC_BMZ_V:
18369         gen_helper_msa_bmz_v(tcg_ctx, tcg_ctx->cpu_env, twd, tws, twt);
18370         break;
18371     case OPC_BSEL_V:
18372         gen_helper_msa_bsel_v(tcg_ctx, tcg_ctx->cpu_env, twd, tws, twt);
18373         break;
18374     default:
18375         MIPS_INVAL("MSA instruction");
18376         generate_exception(ctx, EXCP_RI);
18377         break;
18378     }
18379 
18380     tcg_temp_free_i32(tcg_ctx, twd);
18381     tcg_temp_free_i32(tcg_ctx, tws);
18382     tcg_temp_free_i32(tcg_ctx, twt);
18383 }
18384 
gen_msa_vec(CPUMIPSState * env,DisasContext * ctx)18385 static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
18386 {
18387     switch (MASK_MSA_VEC(ctx->opcode)) {
18388     case OPC_AND_V:
18389     case OPC_OR_V:
18390     case OPC_NOR_V:
18391     case OPC_XOR_V:
18392     case OPC_BMNZ_V:
18393     case OPC_BMZ_V:
18394     case OPC_BSEL_V:
18395         gen_msa_vec_v(env, ctx);
18396         break;
18397     case OPC_MSA_2R:
18398         gen_msa_2r(env, ctx);
18399         break;
18400     case OPC_MSA_2RF:
18401         gen_msa_2rf(env, ctx);
18402         break;
18403     default:
18404         MIPS_INVAL("MSA instruction");
18405         generate_exception(ctx, EXCP_RI);
18406         break;
18407     }
18408 }
18409 
gen_msa(CPUMIPSState * env,DisasContext * ctx)18410 static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
18411 {
18412     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
18413     uint32_t opcode = ctx->opcode;
18414     check_insn(ctx, ASE_MSA);
18415     check_msa_access(ctx);
18416 
18417     switch (MASK_MSA_MINOR(opcode)) {
18418     case OPC_MSA_I8_00:
18419     case OPC_MSA_I8_01:
18420     case OPC_MSA_I8_02:
18421         gen_msa_i8(env, ctx);
18422         break;
18423     case OPC_MSA_I5_06:
18424     case OPC_MSA_I5_07:
18425         gen_msa_i5(env, ctx);
18426         break;
18427     case OPC_MSA_BIT_09:
18428     case OPC_MSA_BIT_0A:
18429         gen_msa_bit(env, ctx);
18430         break;
18431     case OPC_MSA_3R_0D:
18432     case OPC_MSA_3R_0E:
18433     case OPC_MSA_3R_0F:
18434     case OPC_MSA_3R_10:
18435     case OPC_MSA_3R_11:
18436     case OPC_MSA_3R_12:
18437     case OPC_MSA_3R_13:
18438     case OPC_MSA_3R_14:
18439     case OPC_MSA_3R_15:
18440         gen_msa_3r(env, ctx);
18441         break;
18442     case OPC_MSA_ELM:
18443         gen_msa_elm(env, ctx);
18444         break;
18445     case OPC_MSA_3RF_1A:
18446     case OPC_MSA_3RF_1B:
18447     case OPC_MSA_3RF_1C:
18448         gen_msa_3rf(env, ctx);
18449         break;
18450     case OPC_MSA_VEC:
18451         gen_msa_vec(env, ctx);
18452         break;
18453     case OPC_LD_B:
18454     case OPC_LD_H:
18455     case OPC_LD_W:
18456     case OPC_LD_D:
18457     case OPC_ST_B:
18458     case OPC_ST_H:
18459     case OPC_ST_W:
18460     case OPC_ST_D:
18461         {
18462             int32_t s10 = sextract32(ctx->opcode, 16, 10);
18463             uint8_t rs = (ctx->opcode >> 11) & 0x1f;
18464             uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18465             uint8_t df = (ctx->opcode >> 0) & 0x3;
18466 
18467             TCGv_i32 tdf = tcg_const_i32(tcg_ctx, df);
18468             TCGv_i32 twd = tcg_const_i32(tcg_ctx, wd);
18469             TCGv_i32 trs = tcg_const_i32(tcg_ctx, rs);
18470             TCGv_i32 ts10 = tcg_const_i32(tcg_ctx, s10);
18471 
18472             switch (MASK_MSA_MINOR(opcode)) {
18473             case OPC_LD_B:
18474             case OPC_LD_H:
18475             case OPC_LD_W:
18476             case OPC_LD_D:
18477                 gen_helper_msa_ld_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, trs, ts10);
18478                 break;
18479             case OPC_ST_B:
18480             case OPC_ST_H:
18481             case OPC_ST_W:
18482             case OPC_ST_D:
18483                 gen_helper_msa_st_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, trs, ts10);
18484                 break;
18485             }
18486 
18487             tcg_temp_free_i32(tcg_ctx, twd);
18488             tcg_temp_free_i32(tcg_ctx, tdf);
18489             tcg_temp_free_i32(tcg_ctx, trs);
18490             tcg_temp_free_i32(tcg_ctx, ts10);
18491         }
18492         break;
18493     default:
18494         MIPS_INVAL("MSA instruction");
18495         generate_exception(ctx, EXCP_RI);
18496         break;
18497     }
18498 }
18499 
18500 // Unicorn: trace this instruction on request
hook_insn(CPUMIPSState * env,DisasContext * ctx,bool * insn_need_patch,int * insn_patch_offset,int offset_value)18501 static void hook_insn(CPUMIPSState *env, DisasContext *ctx, bool *insn_need_patch, int *insn_patch_offset, int offset_value)
18502 {
18503     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
18504     if (HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_CODE, ctx->pc)) {
18505         gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_CODE_IDX, env->uc, ctx->pc);
18506         *insn_need_patch = true;
18507         // the callback might want to stop emulation immediately
18508         check_exit_request(tcg_ctx);
18509         *insn_patch_offset = offset_value;
18510     }
18511 }
18512 
decode_opc(CPUMIPSState * env,DisasContext * ctx,bool * insn_need_patch,int * insn_patch_offset)18513 static void decode_opc (CPUMIPSState *env, DisasContext *ctx, bool *insn_need_patch, int *insn_patch_offset)
18514 {
18515     TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
18516 #if defined(TARGET_MIPS64)
18517     TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
18518 #endif
18519     int32_t offset;
18520     int rs, rt, rd, sa;
18521     uint32_t op, op1;
18522     int16_t imm;
18523 
18524     /* make sure instructions are on a word boundary */
18525     if (ctx->pc & 0x3) {
18526         env->CP0_BadVAddr = ctx->pc;
18527         generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
18528         return;
18529     }
18530 
18531     /* Handle blikely not taken case */
18532     if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
18533         int l1 = gen_new_label(tcg_ctx);
18534 
18535         MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
18536         tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_NE, *(TCGv *)tcg_ctx->bcond, 0, l1);
18537         tcg_gen_movi_i32(tcg_ctx, tcg_ctx->hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
18538         gen_goto_tb(ctx, 1, ctx->pc + 4);
18539         gen_set_label(tcg_ctx, l1);
18540         hook_insn(env, ctx, insn_need_patch, insn_patch_offset, 14);
18541     } else {
18542         hook_insn(env, ctx, insn_need_patch, insn_patch_offset, 1);
18543     }
18544 
18545     if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
18546         tcg_gen_debug_insn_start(tcg_ctx, ctx->pc);
18547     }
18548 
18549     op = MASK_OP_MAJOR(ctx->opcode);
18550     rs = (ctx->opcode >> 21) & 0x1f;
18551     rt = (ctx->opcode >> 16) & 0x1f;
18552     rd = (ctx->opcode >> 11) & 0x1f;
18553     sa = (ctx->opcode >> 6) & 0x1f;
18554     imm = (int16_t)ctx->opcode;
18555     switch (op) {
18556     case OPC_SPECIAL:
18557         decode_opc_special(env, ctx);
18558         break;
18559     case OPC_SPECIAL2:
18560         decode_opc_special2_legacy(env, ctx);
18561         break;
18562     case OPC_SPECIAL3:
18563         decode_opc_special3(env, ctx);
18564         break;
18565     case OPC_REGIMM:
18566         op1 = MASK_REGIMM(ctx->opcode);
18567         switch (op1) {
18568         case OPC_BLTZL: /* REGIMM branches */
18569         case OPC_BGEZL:
18570         case OPC_BLTZALL:
18571         case OPC_BGEZALL:
18572             check_insn_opc_removed(ctx, ISA_MIPS32R6);
18573         case OPC_BLTZ:
18574         case OPC_BGEZ:
18575             gen_compute_branch(ctx, op1, 4, rs, -1, (uint32_t)imm << 2, 4);
18576             break;
18577         case OPC_BLTZAL:
18578         case OPC_BGEZAL:
18579             if (ctx->insn_flags & ISA_MIPS32R6) {
18580                 if (rs == 0) {
18581                     /* OPC_NAL, OPC_BAL */
18582                     gen_compute_branch(ctx, op1, 4, 0, -1, (uint32_t)imm << 2, 4);
18583                 } else {
18584                     generate_exception(ctx, EXCP_RI);
18585                 }
18586             } else {
18587                 gen_compute_branch(ctx, op1, 4, rs, -1, (uint32_t)imm << 2, 4);
18588             }
18589             break;
18590         case OPC_TGEI: case OPC_TGEIU: case OPC_TLTI: case OPC_TLTIU: case OPC_TEQI: /* REGIMM traps */
18591         case OPC_TNEI:
18592             check_insn_opc_removed(ctx, ISA_MIPS32R6);
18593             gen_trap(ctx, op1, rs, -1, imm);
18594             break;
18595         case OPC_SYNCI:
18596             check_insn(ctx, ISA_MIPS32R2);
18597             /* Break the TB to be able to sync copied instructions
18598                immediately */
18599             ctx->bstate = BS_STOP;
18600             break;
18601         case OPC_BPOSGE32:    /* MIPS DSP branch */
18602 #if defined(TARGET_MIPS64)
18603         case OPC_BPOSGE64:
18604 #endif
18605             check_dsp(ctx);
18606             gen_compute_branch(ctx, op1, 4, -1, -2, (uint32_t)imm << 2, 4);
18607             break;
18608 #if defined(TARGET_MIPS64)
18609         case OPC_DAHI:
18610             check_insn(ctx, ISA_MIPS32R6);
18611             check_mips_64(ctx);
18612             if (rs != 0) {
18613                 tcg_gen_addi_tl(tcg_ctx, *cpu_gpr[rs], *cpu_gpr[rs], (int64_t)imm << 32);
18614             }
18615             MIPS_DEBUG("dahi %s, %04x", regnames[rs], imm);
18616             break;
18617         case OPC_DATI:
18618             check_insn(ctx, ISA_MIPS32R6);
18619             check_mips_64(ctx);
18620             if (rs != 0) {
18621                 tcg_gen_addi_tl(tcg_ctx, *cpu_gpr[rs], *cpu_gpr[rs], (int64_t)imm << 48);
18622             }
18623             MIPS_DEBUG("dati %s, %04x", regnames[rs], imm);
18624             break;
18625 #endif
18626         default:            /* Invalid */
18627             MIPS_INVAL("regimm");
18628             generate_exception(ctx, EXCP_RI);
18629             break;
18630         }
18631         break;
18632     case OPC_CP0:
18633         check_cp0_enabled(ctx);
18634         op1 = MASK_CP0(ctx->opcode);
18635         switch (op1) {
18636         case OPC_MFC0:
18637         case OPC_MTC0:
18638         case OPC_MFTR:
18639         case OPC_MTTR:
18640 #if defined(TARGET_MIPS64)
18641         case OPC_DMFC0:
18642         case OPC_DMTC0:
18643 #endif
18644 #ifndef CONFIG_USER_ONLY
18645             gen_cp0(env, ctx, op1, rt, rd);
18646 #endif /* !CONFIG_USER_ONLY */
18647             break;
18648         case OPC_C0_FIRST: case OPC_C0_LAST:
18649 #ifndef CONFIG_USER_ONLY
18650             gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
18651 #endif /* !CONFIG_USER_ONLY */
18652             break;
18653         case OPC_MFMC0:
18654 #ifndef CONFIG_USER_ONLY
18655             {
18656                 uint32_t op2;
18657                 TCGv t0 = tcg_temp_new(tcg_ctx);
18658 
18659                 op2 = MASK_MFMC0(ctx->opcode);
18660                 switch (op2) {
18661                 case OPC_DMT:
18662                     check_insn(ctx, ASE_MT);
18663                     gen_helper_dmt(tcg_ctx, t0);
18664                     gen_store_gpr(tcg_ctx, t0, rt);
18665                     break;
18666                 case OPC_EMT:
18667                     check_insn(ctx, ASE_MT);
18668                     gen_helper_emt(tcg_ctx, t0);
18669                     gen_store_gpr(tcg_ctx, t0, rt);
18670                     break;
18671                 case OPC_DVPE:
18672                     check_insn(ctx, ASE_MT);
18673                     gen_helper_dvpe(tcg_ctx, t0, tcg_ctx->cpu_env);
18674                     gen_store_gpr(tcg_ctx, t0, rt);
18675                     break;
18676                 case OPC_EVPE:
18677                     check_insn(ctx, ASE_MT);
18678                     gen_helper_evpe(tcg_ctx, t0, tcg_ctx->cpu_env);
18679                     gen_store_gpr(tcg_ctx, t0, rt);
18680                     break;
18681                 case OPC_DI:
18682                     check_insn(ctx, ISA_MIPS32R2);
18683                     save_cpu_state(ctx, 1);
18684                     gen_helper_di(tcg_ctx, t0, tcg_ctx->cpu_env);
18685                     gen_store_gpr(tcg_ctx, t0, rt);
18686                     /* Stop translation as we may have switched the execution mode */
18687                     ctx->bstate = BS_STOP;
18688                     break;
18689                 case OPC_EI:
18690                     check_insn(ctx, ISA_MIPS32R2);
18691                     save_cpu_state(ctx, 1);
18692                     gen_helper_ei(tcg_ctx, t0, tcg_ctx->cpu_env);
18693                     gen_store_gpr(tcg_ctx, t0, rt);
18694                     /* Stop translation as we may have switched the execution mode */
18695                     ctx->bstate = BS_STOP;
18696                     break;
18697                 default:            /* Invalid */
18698                     MIPS_INVAL("mfmc0");
18699                     generate_exception(ctx, EXCP_RI);
18700                     break;
18701                 }
18702                 tcg_temp_free(tcg_ctx, t0);
18703             }
18704 #endif /* !CONFIG_USER_ONLY */
18705             break;
18706         case OPC_RDPGPR:
18707             check_insn(ctx, ISA_MIPS32R2);
18708             gen_load_srsgpr(ctx, rt, rd);
18709             break;
18710         case OPC_WRPGPR:
18711             check_insn(ctx, ISA_MIPS32R2);
18712             gen_store_srsgpr(ctx, rt, rd);
18713             break;
18714         default:
18715             MIPS_INVAL("cp0");
18716             generate_exception(ctx, EXCP_RI);
18717             break;
18718         }
18719         break;
18720     case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
18721         if (ctx->insn_flags & ISA_MIPS32R6) {
18722             /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
18723             gen_compute_compact_branch(ctx, op, rs, rt, (uint32_t)imm << 2);
18724         } else {
18725             /* OPC_ADDI */
18726             /* Arithmetic with immediate opcode */
18727             gen_arith_imm(ctx, op, rt, rs, imm);
18728         }
18729         break;
18730     case OPC_ADDIU:
18731          gen_arith_imm(ctx, op, rt, rs, imm);
18732          break;
18733     case OPC_SLTI: /* Set on less than with immediate opcode */
18734     case OPC_SLTIU:
18735          gen_slt_imm(ctx, op, rt, rs, imm);
18736          break;
18737     case OPC_ANDI: /* Arithmetic with immediate opcode */
18738     case OPC_LUI: /* OPC_AUI */
18739     case OPC_ORI:
18740     case OPC_XORI:
18741          gen_logic_imm(ctx, op, rt, rs, imm);
18742          break;
18743     case OPC_J: case OPC_JAL: /* Jump */
18744          offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
18745          gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
18746          break;
18747     /* Branch */
18748     case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
18749         if (ctx->insn_flags & ISA_MIPS32R6) {
18750             if (rt == 0) {
18751                 generate_exception(ctx, EXCP_RI);
18752                 break;
18753             }
18754             /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
18755             gen_compute_compact_branch(ctx, op, rs, rt, (uint32_t)imm << 2);
18756         } else {
18757             /* OPC_BLEZL */
18758             gen_compute_branch(ctx, op, 4, rs, rt, (uint32_t)imm << 2, 4);
18759         }
18760         break;
18761     case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
18762         if (ctx->insn_flags & ISA_MIPS32R6) {
18763             if (rt == 0) {
18764                 generate_exception(ctx, EXCP_RI);
18765                 break;
18766             }
18767             /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
18768             gen_compute_compact_branch(ctx, op, rs, rt, (uint32_t)imm << 2);
18769         } else {
18770             /* OPC_BGTZL */
18771             gen_compute_branch(ctx, op, 4, rs, rt, (uint32_t)imm << 2, 4);
18772         }
18773         break;
18774     case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
18775         if (rt == 0) {
18776             /* OPC_BLEZ */
18777             gen_compute_branch(ctx, op, 4, rs, rt, (uint32_t)imm << 2, 4);
18778         } else {
18779             check_insn(ctx, ISA_MIPS32R6);
18780             /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
18781             gen_compute_compact_branch(ctx, op, rs, rt, (uint32_t)imm << 2);
18782         }
18783         break;
18784     case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
18785         if (rt == 0) {
18786             /* OPC_BGTZ */
18787             gen_compute_branch(ctx, op, 4, rs, rt, (uint32_t)imm << 2, 4);
18788         } else {
18789             check_insn(ctx, ISA_MIPS32R6);
18790             /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
18791             gen_compute_compact_branch(ctx, op, rs, rt, (uint32_t)imm << 2);
18792         }
18793         break;
18794     case OPC_BEQL:
18795     case OPC_BNEL:
18796          check_insn_opc_removed(ctx, ISA_MIPS32R6);
18797     case OPC_BEQ:
18798     case OPC_BNE:
18799          gen_compute_branch(ctx, op, 4, rs, rt, (uint32_t)imm << 2, 4);
18800          break;
18801     case OPC_LWL: /* Load and stores */
18802     case OPC_LWR:
18803     case OPC_LL:
18804         check_insn_opc_removed(ctx, ISA_MIPS32R6);
18805     case OPC_LB: case OPC_LH:
18806     case OPC_LW: case OPC_LBU: case OPC_LHU:
18807          gen_ld(ctx, op, rt, rs, imm);
18808          break;
18809     case OPC_SWL:
18810     case OPC_SWR:
18811         check_insn_opc_removed(ctx, ISA_MIPS32R6);
18812     case OPC_SB: case OPC_SH:
18813     case OPC_SW:
18814          gen_st(ctx, op, rt, rs, imm);
18815          break;
18816     case OPC_SC:
18817          check_insn_opc_removed(ctx, ISA_MIPS32R6);
18818          gen_st_cond(ctx, op, rt, rs, imm);
18819          break;
18820     case OPC_CACHE:
18821         check_insn_opc_removed(ctx, ISA_MIPS32R6);
18822         check_cp0_enabled(ctx);
18823         check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
18824         /* Treat as NOP. */
18825         break;
18826     case OPC_PREF:
18827         check_insn_opc_removed(ctx, ISA_MIPS32R6);
18828         check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
18829         /* Treat as NOP. */
18830         break;
18831 
18832     /* Floating point (COP1). */
18833     case OPC_LWC1:
18834     case OPC_LDC1:
18835     case OPC_SWC1:
18836     case OPC_SDC1:
18837         gen_cop1_ldst(ctx, op, rt, rs, imm);
18838         break;
18839 
18840     case OPC_CP1:
18841         op1 = MASK_CP1(ctx->opcode);
18842 
18843         switch (op1) {
18844         case OPC_MFHC1:
18845         case OPC_MTHC1:
18846             check_cp1_enabled(ctx);
18847             check_insn(ctx, ISA_MIPS32R2);
18848         case OPC_MFC1:
18849         case OPC_CFC1:
18850         case OPC_MTC1:
18851         case OPC_CTC1:
18852             check_cp1_enabled(ctx);
18853             gen_cp1(ctx, op1, rt, rd);
18854             break;
18855 #if defined(TARGET_MIPS64)
18856         case OPC_DMFC1:
18857         case OPC_DMTC1:
18858             check_cp1_enabled(ctx);
18859             check_insn(ctx, ISA_MIPS3);
18860             gen_cp1(ctx, op1, rt, rd);
18861             break;
18862 #endif
18863         case OPC_BC1EQZ: /* OPC_BC1ANY2 */
18864             check_cp1_enabled(ctx);
18865             if (ctx->insn_flags & ISA_MIPS32R6) {
18866                 /* OPC_BC1EQZ */
18867                 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
18868                                 rt, ((uint16_t)imm) << 2);
18869             } else {
18870                 /* OPC_BC1ANY2 */
18871                 check_cop1x(ctx);
18872                 check_insn(ctx, ASE_MIPS3D);
18873                 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
18874                                     (rt >> 2) & 0x7, ((uint32_t)imm) << 2);
18875             }
18876             break;
18877         case OPC_BC1NEZ:
18878             check_cp1_enabled(ctx);
18879             check_insn(ctx, ISA_MIPS32R6);
18880             gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
18881                             rt, ((uint16_t)imm) << 2);
18882             break;
18883         case OPC_BC1ANY4:
18884             check_cp1_enabled(ctx);
18885             check_insn_opc_removed(ctx, ISA_MIPS32R6);
18886             check_cop1x(ctx);
18887             check_insn(ctx, ASE_MIPS3D);
18888             /* fall through */
18889         case OPC_BC1:
18890             check_cp1_enabled(ctx);
18891             check_insn_opc_removed(ctx, ISA_MIPS32R6);
18892             gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
18893                                 (rt >> 2) & 0x7, (uint32_t)imm << 2);
18894             break;
18895         case OPC_PS_FMT:
18896             check_cp1_enabled(ctx);
18897             check_insn_opc_removed(ctx, ISA_MIPS32R6);
18898         case OPC_S_FMT:
18899         case OPC_D_FMT:
18900             check_cp1_enabled(ctx);
18901             gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
18902                        (imm >> 8) & 0x7);
18903             break;
18904         case OPC_W_FMT:
18905         case OPC_L_FMT:
18906         {
18907             int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
18908             check_cp1_enabled(ctx);
18909             if (ctx->insn_flags & ISA_MIPS32R6) {
18910                 switch (r6_op) {
18911                 case R6_OPC_CMP_AF_S:
18912                 case R6_OPC_CMP_UN_S:
18913                 case R6_OPC_CMP_EQ_S:
18914                 case R6_OPC_CMP_UEQ_S:
18915                 case R6_OPC_CMP_LT_S:
18916                 case R6_OPC_CMP_ULT_S:
18917                 case R6_OPC_CMP_LE_S:
18918                 case R6_OPC_CMP_ULE_S:
18919                 case R6_OPC_CMP_SAF_S:
18920                 case R6_OPC_CMP_SUN_S:
18921                 case R6_OPC_CMP_SEQ_S:
18922                 case R6_OPC_CMP_SEUQ_S:
18923                 case R6_OPC_CMP_SLT_S:
18924                 case R6_OPC_CMP_SULT_S:
18925                 case R6_OPC_CMP_SLE_S:
18926                 case R6_OPC_CMP_SULE_S:
18927                 case R6_OPC_CMP_OR_S:
18928                 case R6_OPC_CMP_UNE_S:
18929                 case R6_OPC_CMP_NE_S:
18930                 case R6_OPC_CMP_SOR_S:
18931                 case R6_OPC_CMP_SUNE_S:
18932                 case R6_OPC_CMP_SNE_S:
18933                     gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
18934                     break;
18935                 case R6_OPC_CMP_AF_D:
18936                 case R6_OPC_CMP_UN_D:
18937                 case R6_OPC_CMP_EQ_D:
18938                 case R6_OPC_CMP_UEQ_D:
18939                 case R6_OPC_CMP_LT_D:
18940                 case R6_OPC_CMP_ULT_D:
18941                 case R6_OPC_CMP_LE_D:
18942                 case R6_OPC_CMP_ULE_D:
18943                 case R6_OPC_CMP_SAF_D:
18944                 case R6_OPC_CMP_SUN_D:
18945                 case R6_OPC_CMP_SEQ_D:
18946                 case R6_OPC_CMP_SEUQ_D:
18947                 case R6_OPC_CMP_SLT_D:
18948                 case R6_OPC_CMP_SULT_D:
18949                 case R6_OPC_CMP_SLE_D:
18950                 case R6_OPC_CMP_SULE_D:
18951                 case R6_OPC_CMP_OR_D:
18952                 case R6_OPC_CMP_UNE_D:
18953                 case R6_OPC_CMP_NE_D:
18954                 case R6_OPC_CMP_SOR_D:
18955                 case R6_OPC_CMP_SUNE_D:
18956                 case R6_OPC_CMP_SNE_D:
18957                     gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
18958                     break;
18959                 default:
18960                     gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
18961                                (imm >> 8) & 0x7);
18962                     break;
18963                 }
18964             } else {
18965                 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
18966                            (imm >> 8) & 0x7);
18967             }
18968             break;
18969         }
18970         case OPC_BZ_V:
18971         case OPC_BNZ_V:
18972         case OPC_BZ_B:
18973         case OPC_BZ_H:
18974         case OPC_BZ_W:
18975         case OPC_BZ_D:
18976         case OPC_BNZ_B:
18977         case OPC_BNZ_H:
18978         case OPC_BNZ_W:
18979         case OPC_BNZ_D:
18980             check_insn(ctx, ASE_MSA);
18981             gen_msa_branch(env, ctx, op1);
18982             break;
18983         default:
18984             MIPS_INVAL("cp1");
18985             generate_exception(ctx, EXCP_RI);
18986             break;
18987         }
18988         break;
18989 
18990     /* Compact branches [R6] and COP2 [non-R6] */
18991     case OPC_BC: /* OPC_LWC2 */
18992     case OPC_BALC: /* OPC_SWC2 */
18993         if (ctx->insn_flags & ISA_MIPS32R6) {
18994             /* OPC_BC, OPC_BALC */
18995             gen_compute_compact_branch(ctx, op, 0, 0,
18996                                        sextract32(ctx->opcode << 2, 0, 28));
18997         } else {
18998             /* OPC_LWC2, OPC_SWC2 */
18999             /* COP2: Not implemented. */
19000             generate_exception_err(ctx, EXCP_CpU, 2);
19001         }
19002         break;
19003     case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
19004     case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
19005         if (ctx->insn_flags & ISA_MIPS32R6) {
19006             if (rs != 0) {
19007                 /* OPC_BEQZC, OPC_BNEZC */
19008                 gen_compute_compact_branch(ctx, op, rs, 0,
19009                                            sextract32(ctx->opcode << 2, 0, 23));
19010             } else {
19011                 /* OPC_JIC, OPC_JIALC */
19012                 gen_compute_compact_branch(ctx, op, 0, rt, imm);
19013             }
19014         } else {
19015             /* OPC_LWC2, OPC_SWC2 */
19016             /* COP2: Not implemented. */
19017             generate_exception_err(ctx, EXCP_CpU, 2);
19018         }
19019         break;
19020     case OPC_CP2:
19021         check_insn(ctx, INSN_LOONGSON2F);
19022         /* Note that these instructions use different fields.  */
19023         gen_loongson_multimedia(ctx, sa, rd, rt);
19024         break;
19025 
19026     case OPC_CP3:
19027         check_insn_opc_removed(ctx, ISA_MIPS32R6);
19028         if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
19029             check_cp1_enabled(ctx);
19030             op1 = MASK_CP3(ctx->opcode);
19031             switch (op1) {
19032             case OPC_LWXC1:
19033             case OPC_LDXC1:
19034             case OPC_LUXC1:
19035             case OPC_SWXC1:
19036             case OPC_SDXC1:
19037             case OPC_SUXC1:
19038                 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
19039                 break;
19040             case OPC_PREFX:
19041                 /* Treat as NOP. */
19042                 break;
19043             case OPC_ALNV_PS:
19044             case OPC_MADD_S:
19045             case OPC_MADD_D:
19046             case OPC_MADD_PS:
19047             case OPC_MSUB_S:
19048             case OPC_MSUB_D:
19049             case OPC_MSUB_PS:
19050             case OPC_NMADD_S:
19051             case OPC_NMADD_D:
19052             case OPC_NMADD_PS:
19053             case OPC_NMSUB_S:
19054             case OPC_NMSUB_D:
19055             case OPC_NMSUB_PS:
19056                 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
19057                 break;
19058             default:
19059                 MIPS_INVAL("cp3");
19060                 generate_exception (ctx, EXCP_RI);
19061                 break;
19062             }
19063         } else {
19064             generate_exception_err(ctx, EXCP_CpU, 1);
19065         }
19066         break;
19067 
19068 #if defined(TARGET_MIPS64)
19069     /* MIPS64 opcodes */
19070     case OPC_LDL: case OPC_LDR:
19071     case OPC_LLD:
19072         check_insn_opc_removed(ctx, ISA_MIPS32R6);
19073     case OPC_LWU:
19074     case OPC_LD:
19075         check_insn(ctx, ISA_MIPS3);
19076         check_mips_64(ctx);
19077         gen_ld(ctx, op, rt, rs, imm);
19078         break;
19079     case OPC_SDL: case OPC_SDR:
19080         check_insn_opc_removed(ctx, ISA_MIPS32R6);
19081     case OPC_SD:
19082         check_insn(ctx, ISA_MIPS3);
19083         check_mips_64(ctx);
19084         gen_st(ctx, op, rt, rs, imm);
19085         break;
19086     case OPC_SCD:
19087         check_insn_opc_removed(ctx, ISA_MIPS32R6);
19088         check_insn(ctx, ISA_MIPS3);
19089         check_mips_64(ctx);
19090         gen_st_cond(ctx, op, rt, rs, imm);
19091         break;
19092     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
19093         if (ctx->insn_flags & ISA_MIPS32R6) {
19094             /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
19095             gen_compute_compact_branch(ctx, op, rs, rt, (uint32_t)imm << 2);
19096         } else {
19097             /* OPC_DADDI */
19098             check_insn(ctx, ISA_MIPS3);
19099             check_mips_64(ctx);
19100             gen_arith_imm(ctx, op, rt, rs, imm);
19101         }
19102         break;
19103     case OPC_DADDIU:
19104         check_insn(ctx, ISA_MIPS3);
19105         check_mips_64(ctx);
19106         gen_arith_imm(ctx, op, rt, rs, imm);
19107         break;
19108 #else
19109     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
19110         if (ctx->insn_flags & ISA_MIPS32R6) {
19111             gen_compute_compact_branch(ctx, op, rs, rt, (uint32_t)imm << 2);
19112         } else {
19113             MIPS_INVAL("major opcode");
19114             generate_exception(ctx, EXCP_RI);
19115         }
19116         break;
19117 #endif
19118     case OPC_DAUI: /* OPC_JALX */
19119         if (ctx->insn_flags & ISA_MIPS32R6) {
19120 #if defined(TARGET_MIPS64)
19121             /* OPC_DAUI */
19122             check_mips_64(ctx);
19123             if (rt != 0) {
19124                 TCGv t0 = tcg_temp_new(tcg_ctx);
19125                 gen_load_gpr(ctx, t0, rs);
19126                 tcg_gen_addi_tl(tcg_ctx, *cpu_gpr[rt], t0, (uint32_t)imm << 16);
19127                 tcg_temp_free(tcg_ctx, t0);
19128             }
19129             MIPS_DEBUG("daui %s, %s, %04x", regnames[rt], regnames[rs], imm);
19130 #else
19131             generate_exception(ctx, EXCP_RI);
19132             MIPS_INVAL("major opcode");
19133 #endif
19134         } else {
19135             /* OPC_JALX */
19136             check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
19137             offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
19138             gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
19139         }
19140         break;
19141     case OPC_MSA: /* OPC_MDMX */
19142         /* MDMX: Not implemented. */
19143         gen_msa(env, ctx);
19144         break;
19145     case OPC_PCREL:
19146         check_insn(ctx, ISA_MIPS32R6);
19147         gen_pcrel(ctx, rs, imm);
19148         break;
19149     default:            /* Invalid */
19150         MIPS_INVAL("major opcode");
19151         generate_exception(ctx, EXCP_RI);
19152         break;
19153     }
19154 }
19155 
19156 static inline void
gen_intermediate_code_internal(MIPSCPU * cpu,TranslationBlock * tb,bool search_pc)19157 gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
19158                                bool search_pc)
19159 {
19160     CPUState *cs = CPU(cpu);
19161     CPUMIPSState *env = &cpu->env;
19162     DisasContext ctx;
19163     target_ulong pc_start;
19164     uint16_t *gen_opc_end;
19165     CPUBreakpoint *bp;
19166     int j, lj = -1;
19167     int num_insns;
19168     int max_insns;
19169     int insn_bytes;
19170     int is_slot = 0;
19171     TCGContext *tcg_ctx = env->uc->tcg_ctx;
19172     TCGArg *save_opparam_ptr = NULL;
19173     bool block_full = false;
19174 
19175     if (search_pc)
19176         qemu_log("search pc %d\n", search_pc);
19177 
19178     pc_start = tb->pc;
19179     gen_opc_end = tcg_ctx->gen_opc_buf + OPC_MAX_SIZE;
19180     ctx.uc = env->uc;
19181     ctx.pc = pc_start;
19182     ctx.saved_pc = -1;
19183     ctx.singlestep_enabled = cs->singlestep_enabled;
19184     ctx.insn_flags = env->insn_flags;
19185     ctx.CP0_Config1 = env->CP0_Config1;
19186     ctx.tb = tb;
19187     ctx.bstate = BS_NONE;
19188     ctx.kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
19189     ctx.rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
19190     ctx.ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
19191     ctx.bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
19192     ctx.bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
19193     /* Restore delay slot state from the tb context.  */
19194     ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
19195     ctx.ulri = env->CP0_Config3 & (1 << CP0C3_ULRI);
19196     restore_cpu_state(env, &ctx);
19197 #ifdef CONFIG_USER_ONLY
19198         ctx.mem_idx = MIPS_HFLAG_UM;
19199 #else
19200         ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
19201 #endif
19202     num_insns = 0;
19203     max_insns = tb->cflags & CF_COUNT_MASK;
19204     if (max_insns == 0)
19205         max_insns = CF_COUNT_MASK;
19206     LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
19207 
19208     // Unicorn: early check to see if the address of this block is the until address
19209     if (tb->pc == env->uc->addr_end) {
19210         gen_tb_start(tcg_ctx);
19211         gen_helper_wait(tcg_ctx, tcg_ctx->cpu_env);
19212         ctx.bstate = BS_EXCP;
19213         goto done_generating;
19214     }
19215 
19216     // Unicorn: trace this block on request
19217     // Only hook this block if it is not broken from previous translation due to
19218     // full translation cache
19219     if (!env->uc->block_full && HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_BLOCK, pc_start)) {
19220         // save block address to see if we need to patch block size later
19221         env->uc->block_addr = pc_start;
19222         env->uc->size_arg = tcg_ctx->gen_opparam_buf - tcg_ctx->gen_opparam_ptr + 1;
19223         gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, env->uc, pc_start);
19224     } else {
19225         env->uc->size_arg = -1;
19226     }
19227 
19228     gen_tb_start(tcg_ctx);
19229     while (ctx.bstate == BS_NONE) {
19230         // printf(">>> mips pc = %x\n", ctx.pc);
19231         if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
19232             QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
19233                 if (bp->pc == ctx.pc) {
19234                     save_cpu_state(&ctx, 1);
19235                     ctx.bstate = BS_BRANCH;
19236                     gen_helper_0e0i(tcg_ctx, raise_exception, EXCP_DEBUG);
19237                     /* Include the breakpoint location or the tb won't
19238                      * be flushed when it must be.  */
19239                     ctx.pc += 4;
19240                     goto done_generating;
19241                 }
19242             }
19243         }
19244 
19245         if (search_pc) {
19246             j = tcg_ctx->gen_opc_ptr - tcg_ctx->gen_opc_buf;
19247             if (lj < j) {
19248                 lj++;
19249                 while (lj < j)
19250                     tcg_ctx->gen_opc_instr_start[lj++] = 0;
19251             }
19252             tcg_ctx->gen_opc_pc[lj] = ctx.pc;
19253             tcg_ctx->gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
19254             tcg_ctx->gen_opc_btarget[lj] = ctx.btarget;
19255             tcg_ctx->gen_opc_instr_start[lj] = 1;
19256             tcg_ctx->gen_opc_icount[lj] = num_insns;
19257         }
19258         //if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
19259         //    gen_io_start();
19260 
19261         // Unicorn: end address tells us to stop emulation
19262         if (ctx.pc == ctx.uc->addr_end) {
19263             gen_helper_wait(tcg_ctx, tcg_ctx->cpu_env);
19264             ctx.bstate = BS_EXCP;
19265             break;
19266         } else {
19267             bool insn_need_patch = false;
19268             int insn_patch_offset = 1;
19269 
19270             // Unicorn: save param buffer
19271             if (HOOK_EXISTS(env->uc, UC_HOOK_CODE))
19272                 save_opparam_ptr = tcg_ctx->gen_opparam_ptr;
19273 
19274             is_slot = ctx.hflags & MIPS_HFLAG_BMASK;
19275 
19276             if (!(ctx.hflags & MIPS_HFLAG_M16)) {
19277                 ctx.opcode = cpu_ldl_code(env, ctx.pc);
19278                 insn_bytes = 4;
19279                 decode_opc(env, &ctx, &insn_need_patch, &insn_patch_offset);
19280             } else if (ctx.insn_flags & ASE_MICROMIPS) {
19281                 ctx.opcode = cpu_lduw_code(env, ctx.pc);
19282                 insn_bytes = decode_micromips_opc(env, &ctx, &insn_need_patch);
19283             } else if (ctx.insn_flags & ASE_MIPS16) {
19284                 ctx.opcode = cpu_lduw_code(env, ctx.pc);
19285                 insn_bytes = decode_mips16_opc(env, &ctx, &insn_need_patch);
19286             } else {
19287                 generate_exception(&ctx, EXCP_RI);
19288                 ctx.bstate = BS_STOP;
19289                 break;
19290             }
19291 
19292             // Unicorn: patch the callback for the instruction size
19293             if (insn_need_patch) {
19294                 /*
19295                    int i;
19296                    for (i = 0; i < 30; i++)
19297                    printf("[%u] = %x\n", i, *(save_opparam_ptr + i));
19298                    printf("\n");
19299                  */
19300                 *(save_opparam_ptr + insn_patch_offset) = insn_bytes;
19301             }
19302         }
19303 
19304         if (ctx.hflags & MIPS_HFLAG_BMASK) {
19305             if (!(ctx.hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
19306                             MIPS_HFLAG_FBNSLOT))) {
19307                 /* force to generate branch as there is neither delay nor
19308                    forbidden slot */
19309                 is_slot = 1;
19310             }
19311         }
19312 
19313         if (is_slot) {
19314             gen_branch(&ctx, insn_bytes);
19315         }
19316         ctx.pc += insn_bytes;
19317 
19318         num_insns++;
19319 
19320         /* Execute a branch and its delay slot as a single instruction.
19321            This is what GDB expects and is consistent with what the
19322            hardware does (e.g. if a delay slot instruction faults, the
19323            reported PC is the PC of the branch).  */
19324         if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
19325             break;
19326         }
19327 
19328         if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
19329             break;
19330 
19331         if (tcg_ctx->gen_opc_ptr >= gen_opc_end) {
19332             break;
19333         }
19334 
19335         if (num_insns >= max_insns)
19336             break;
19337 
19338         //if (singlestep)
19339         //    break;
19340     }
19341 
19342     if (tcg_ctx->gen_opc_ptr >= gen_opc_end || num_insns >= max_insns) {
19343         block_full = true;
19344     }
19345 
19346     //if (tb->cflags & CF_LAST_IO) {
19347     //    gen_io_end();
19348     //}
19349     if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
19350         save_cpu_state(&ctx, ctx.bstate != BS_EXCP);
19351         gen_helper_0e0i(tcg_ctx, raise_exception, EXCP_DEBUG);
19352     } else {
19353         switch (ctx.bstate) {
19354         case BS_STOP:
19355             gen_goto_tb(&ctx, 0, ctx.pc);
19356             env->uc->next_pc = ctx.pc;
19357             break;
19358         case BS_NONE:
19359             save_cpu_state(&ctx, 0);
19360             gen_goto_tb(&ctx, 0, ctx.pc);
19361             break;
19362         case BS_EXCP:
19363             tcg_gen_exit_tb(tcg_ctx, 0);
19364             break;
19365         case BS_BRANCH:
19366         default:
19367             break;
19368         }
19369     }
19370 done_generating:
19371     gen_tb_end(tcg_ctx, tb, num_insns);
19372     *tcg_ctx->gen_opc_ptr = INDEX_op_end;
19373     if (search_pc) {
19374         j = tcg_ctx->gen_opc_ptr - tcg_ctx->gen_opc_buf;
19375         lj++;
19376         while (lj <= j)
19377             tcg_ctx->gen_opc_instr_start[lj++] = 0;
19378     } else {
19379         tb->size = ctx.pc - pc_start;
19380         tb->icount = num_insns;
19381     }
19382 
19383     env->uc->block_full = block_full;
19384 }
19385 
gen_intermediate_code(CPUMIPSState * env,struct TranslationBlock * tb)19386 void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
19387 {
19388     gen_intermediate_code_internal(mips_env_get_cpu(env), tb, false);
19389 }
19390 
gen_intermediate_code_pc(CPUMIPSState * env,struct TranslationBlock * tb)19391 void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
19392 {
19393     gen_intermediate_code_internal(mips_env_get_cpu(env), tb, true);
19394 }
19395 
19396 #if 0
19397 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
19398                            int flags)
19399 {
19400     int i;
19401     int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
19402 
19403 #define printfpr(fp)                                                    \
19404     do {                                                                \
19405         if (is_fpu64)                                                   \
19406             fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
19407                         " fd:%13g fs:%13g psu: %13g\n",                 \
19408                         (fp)->w[FP_ENDIAN_IDX], (fp)->d,                \
19409                         (double)(fp)->fd,                               \
19410                         (double)(fp)->fs[FP_ENDIAN_IDX],                \
19411                         (double)(fp)->fs[!FP_ENDIAN_IDX]);              \
19412         else {                                                          \
19413             fpr_t tmp;                                                  \
19414             tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];              \
19415             tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];       \
19416             fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
19417                         " fd:%13g fs:%13g psu:%13g\n",                  \
19418                         tmp.w[FP_ENDIAN_IDX], tmp.d,                    \
19419                         (double)tmp.fd,                                 \
19420                         (double)tmp.fs[FP_ENDIAN_IDX],                  \
19421                         (double)tmp.fs[!FP_ENDIAN_IDX]);                \
19422         }                                                               \
19423     } while(0)
19424 
19425 
19426     fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%02x\n",
19427                 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
19428                 get_float_exception_flags(&env->active_fpu.fp_status));
19429     for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
19430         fpu_fprintf(f, "%3s: ", fregnames[i]);
19431         printfpr(&env->active_fpu.fpr[i]);
19432     }
19433 
19434 #undef printfpr
19435 }
19436 #endif
19437 
19438 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
19439 /* Debug help: The architecture requires 32bit code to maintain proper
19440    sign-extended values on 64bit machines.  */
19441 
19442 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
19443 
19444 static void
cpu_mips_check_sign_extensions(CPUMIPSState * env,FILE * f,fprintf_function cpu_fprintf,int flags)19445 cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
19446                                 fprintf_function cpu_fprintf,
19447                                 int flags)
19448 {
19449     int i;
19450 
19451     if (!SIGN_EXT_P(env->active_tc.PC))
19452         cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
19453     if (!SIGN_EXT_P(env->active_tc.HI[0]))
19454         cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
19455     if (!SIGN_EXT_P(env->active_tc.LO[0]))
19456         cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
19457     if (!SIGN_EXT_P(env->btarget))
19458         cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
19459 
19460     for (i = 0; i < 32; i++) {
19461         if (!SIGN_EXT_P(env->active_tc.gpr[i]))
19462             cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
19463     }
19464 
19465     if (!SIGN_EXT_P(env->CP0_EPC))
19466         cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
19467     if (!SIGN_EXT_P(env->lladdr))
19468         cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
19469 }
19470 #endif
19471 
mips_tcg_init(struct uc_struct * uc)19472 void mips_tcg_init(struct uc_struct *uc)
19473 {
19474     TCGContext *tcg_ctx = uc->tcg_ctx;
19475     TCGv **cpu_gpr;
19476     int i;
19477 
19478     tcg_ctx->cpu_env = tcg_global_reg_new_ptr(uc->tcg_ctx, TCG_AREG0, "env");
19479 
19480     if (!uc->init_tcg) {
19481         for (i = 0; i < 32; i++) {
19482             tcg_ctx->cpu_gpr[i] = g_malloc0(sizeof(TCGv));
19483             *((TCGv *)tcg_ctx->cpu_gpr[i]) = tcg_global_mem_new(tcg_ctx, TCG_AREG0,
19484                     offsetof(CPUMIPSState, active_tc.gpr[i]),
19485                     regnames[i]);
19486         }
19487     }
19488 
19489     cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
19490     TCGV_UNUSED(*cpu_gpr[0]);
19491 
19492     for (i = 0; i < 32; i++) {
19493         int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
19494         tcg_ctx->msa_wr_d[i * 2] =
19495                 tcg_global_mem_new_i64(tcg_ctx, TCG_AREG0, off, msaregnames[i * 2]);
19496         /* The scalar floating-point unit (FPU) registers are mapped on
19497          * the MSA vector registers. */
19498         tcg_ctx->fpu_f64[i] = tcg_ctx->msa_wr_d[i * 2];
19499         off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
19500         tcg_ctx->msa_wr_d[i * 2 + 1] =
19501                 tcg_global_mem_new_i64(tcg_ctx, TCG_AREG0, off, msaregnames[i * 2 + 1]);
19502     }
19503 
19504     if (!uc->init_tcg)
19505         tcg_ctx->cpu_PC = g_malloc0(sizeof(TCGv));
19506     *((TCGv *)tcg_ctx->cpu_PC) = tcg_global_mem_new(tcg_ctx, TCG_AREG0,
19507                                 offsetof(CPUMIPSState, active_tc.PC), "PC");
19508 
19509     if (!uc->init_tcg) {
19510         for (i = 0; i < MIPS_DSP_ACC; i++) {
19511             tcg_ctx->cpu_HI[i] = g_malloc0(sizeof(TCGv));
19512             *((TCGv *)tcg_ctx->cpu_HI[i]) = tcg_global_mem_new(tcg_ctx, TCG_AREG0,
19513                     offsetof(CPUMIPSState, active_tc.HI[i]),
19514                     regnames_HI[i]);
19515             tcg_ctx->cpu_LO[i] = g_malloc0(sizeof(TCGv));
19516             *((TCGv *)tcg_ctx->cpu_LO[i]) = tcg_global_mem_new(tcg_ctx, TCG_AREG0,
19517                     offsetof(CPUMIPSState, active_tc.LO[i]),
19518                     regnames_LO[i]);
19519         }
19520     }
19521 
19522     if (!uc->init_tcg)
19523         tcg_ctx->cpu_dspctrl = g_malloc0(sizeof(TCGv));
19524     *((TCGv *)tcg_ctx->cpu_dspctrl) = tcg_global_mem_new(tcg_ctx, TCG_AREG0,
19525                                      offsetof(CPUMIPSState, active_tc.DSPControl),
19526                                      "DSPControl");
19527 
19528     if (!uc->init_tcg)
19529         tcg_ctx->bcond = g_malloc0(sizeof(TCGv));
19530     *((TCGv *)tcg_ctx->bcond) = tcg_global_mem_new(tcg_ctx, TCG_AREG0,
19531                                offsetof(CPUMIPSState, bcond), "bcond");
19532 
19533     if (!uc->init_tcg)
19534         tcg_ctx->btarget = g_malloc0(sizeof(TCGv));
19535     *((TCGv *)tcg_ctx->btarget) = tcg_global_mem_new(tcg_ctx, TCG_AREG0,
19536                                  offsetof(CPUMIPSState, btarget), "btarget");
19537 
19538     tcg_ctx->hflags = tcg_global_mem_new_i32(tcg_ctx, TCG_AREG0,
19539                                     offsetof(CPUMIPSState, hflags), "hflags");
19540 
19541     //tcg_ctx->fpu_fcr0 = tcg_global_mem_new_i32(tcg_ctx, TCG_AREG0,
19542     //                                  offsetof(CPUMIPSState, active_fpu.fcr0),
19543     //                                  "fcr0");
19544     tcg_ctx->fpu_fcr31 = tcg_global_mem_new_i32(tcg_ctx, TCG_AREG0,
19545                                        offsetof(CPUMIPSState, active_fpu.fcr31),
19546                                        "fcr31");
19547     uc->init_tcg = true;
19548 }
19549 
19550 #include "translate_init.c"
19551 
cpu_mips_init(struct uc_struct * uc,const char * cpu_model)19552 MIPSCPU *cpu_mips_init(struct uc_struct *uc, const char *cpu_model)
19553 {
19554     MIPSCPU *cpu;
19555     CPUMIPSState *env;
19556     const mips_def_t *def;
19557 
19558     def = cpu_mips_find_by_name(cpu_model);
19559     if (!def)
19560         return NULL;
19561     cpu = MIPS_CPU(uc, object_new(uc, TYPE_MIPS_CPU));
19562     env = &cpu->env;
19563     env->cpu_model = def;
19564 
19565 #ifndef CONFIG_USER_ONLY
19566     mmu_init(env, def);
19567 #endif
19568     fpu_init(env, def);
19569     mvp_init(env, def);
19570 
19571     object_property_set_bool(uc, OBJECT(cpu), true, "realized", NULL);
19572 
19573     return cpu;
19574 }
19575 
cpu_state_reset(CPUMIPSState * env)19576 void cpu_state_reset(CPUMIPSState *env)
19577 {
19578     MIPSCPU *cpu = mips_env_get_cpu(env);
19579     CPUState *cs = CPU(cpu);
19580 
19581     /* Reset registers to their default values */
19582     env->CP0_PRid = env->cpu_model->CP0_PRid;
19583     env->CP0_Config0 = env->cpu_model->CP0_Config0;
19584 #ifdef TARGET_WORDS_BIGENDIAN
19585     env->CP0_Config0 |= (1 << CP0C0_BE);
19586 #endif
19587     env->CP0_Config1 = env->cpu_model->CP0_Config1;
19588     env->CP0_Config2 = env->cpu_model->CP0_Config2;
19589     env->CP0_Config3 = env->cpu_model->CP0_Config3;
19590     env->CP0_Config4 = env->cpu_model->CP0_Config4;
19591     env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
19592     env->CP0_Config5 = env->cpu_model->CP0_Config5;
19593     env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
19594     env->CP0_Config6 = env->cpu_model->CP0_Config6;
19595     env->CP0_Config7 = env->cpu_model->CP0_Config7;
19596     env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
19597                                  << env->cpu_model->CP0_LLAddr_shift;
19598     env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
19599     env->SYNCI_Step = env->cpu_model->SYNCI_Step;
19600     env->CCRes = env->cpu_model->CCRes;
19601     env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
19602     env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
19603     env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
19604     env->current_tc = 0;
19605     env->SEGBITS = env->cpu_model->SEGBITS;
19606     env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
19607 #if defined(TARGET_MIPS64)
19608     if (env->cpu_model->insn_flags & ISA_MIPS3) {
19609         env->SEGMask |= 3ULL << 62;
19610     }
19611 #endif
19612     env->PABITS = env->cpu_model->PABITS;
19613     env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
19614     env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
19615     env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
19616     env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
19617     env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
19618     env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
19619     env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
19620     env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
19621     env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
19622     env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
19623     env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
19624     env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
19625     env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
19626     env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
19627     env->msair = env->cpu_model->MSAIR;
19628     env->insn_flags = env->cpu_model->insn_flags;
19629 
19630 #if defined(CONFIG_USER_ONLY)
19631     env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
19632 # ifdef TARGET_MIPS64
19633     /* Enable 64-bit register mode.  */
19634     env->CP0_Status |= (1 << CP0St_PX);
19635 # endif
19636 # ifdef TARGET_ABI_MIPSN64
19637     /* Enable 64-bit address mode.  */
19638     env->CP0_Status |= (1 << CP0St_UX);
19639 # endif
19640     /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
19641        hardware registers.  */
19642     env->CP0_HWREna |= 0x0000000F;
19643     if (env->CP0_Config1 & (1 << CP0C1_FP)) {
19644         env->CP0_Status |= (1 << CP0St_CU1);
19645     }
19646     if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
19647         env->CP0_Status |= (1 << CP0St_MX);
19648     }
19649 # if defined(TARGET_MIPS64)
19650     /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
19651     if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
19652         (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
19653         env->CP0_Status |= (1 << CP0St_FR);
19654     }
19655 # endif
19656 #else
19657     if (env->hflags & MIPS_HFLAG_BMASK) {
19658         /* If the exception was raised from a delay slot,
19659            come back to the jump.  */
19660         env->CP0_ErrorEPC = env->active_tc.PC - 4;
19661     } else {
19662         env->CP0_ErrorEPC = env->active_tc.PC;
19663     }
19664     env->active_tc.PC = (int32_t)0xBFC00000;
19665     env->CP0_Random = env->tlb->nb_tlb - 1;
19666     env->tlb->tlb_in_use = env->tlb->nb_tlb;
19667     env->CP0_Wired = 0;
19668     env->CP0_EBase = (cs->cpu_index & 0x3FF);
19669     env->CP0_EBase |= 0x80000000;
19670     env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
19671     /* vectored interrupts not implemented, timer on int 7,
19672        no performance counters. */
19673     env->CP0_IntCtl = 0xe0000000;
19674     {
19675         int i;
19676 
19677         for (i = 0; i < 7; i++) {
19678             env->CP0_WatchLo[i] = 0;
19679             env->CP0_WatchHi[i] = 0x80000000;
19680         }
19681         env->CP0_WatchLo[7] = 0;
19682         env->CP0_WatchHi[7] = 0;
19683     }
19684     /* Count register increments in debug mode, EJTAG version 1 */
19685     env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
19686 
19687     cpu_mips_store_count(env, 1);
19688 
19689     if (env->CP0_Config3 & (1 << CP0C3_MT)) {
19690         int i;
19691 
19692         /* Only TC0 on VPE 0 starts as active.  */
19693         for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
19694             env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
19695             env->tcs[i].CP0_TCHalt = 1;
19696         }
19697         env->active_tc.CP0_TCHalt = 1;
19698         cs->halted = 1;
19699 
19700         if (cs->cpu_index == 0) {
19701             /* VPE0 starts up enabled.  */
19702             env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
19703             env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
19704 
19705             /* TC0 starts up unhalted.  */
19706             cs->halted = 0;
19707             env->active_tc.CP0_TCHalt = 0;
19708             env->tcs[0].CP0_TCHalt = 0;
19709             /* With thread 0 active.  */
19710             env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
19711             env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
19712         }
19713     }
19714     if (env->CP0_Config1 & (1 << CP0C1_FP)) {
19715         env->CP0_Status |= (1 << CP0St_CU1);
19716     }
19717 #endif
19718     if ((env->insn_flags & ISA_MIPS32R6) &&
19719         (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
19720         /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
19721         env->CP0_Status |= (1 << CP0St_FR);
19722     }
19723 
19724     /* MSA */
19725     if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
19726         msa_reset(env);
19727     }
19728 
19729     compute_hflags(env);
19730     cs->exception_index = EXCP_NONE;
19731 }
19732 
restore_state_to_opc(CPUMIPSState * env,TranslationBlock * tb,int pc_pos)19733 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
19734 {
19735     TCGContext *tcg_ctx = env->uc->tcg_ctx;
19736     env->active_tc.PC = tcg_ctx->gen_opc_pc[pc_pos];
19737     env->hflags &= ~MIPS_HFLAG_BMASK;
19738     env->hflags |= tcg_ctx->gen_opc_hflags[pc_pos];
19739     switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
19740     case MIPS_HFLAG_BR:
19741         break;
19742     case MIPS_HFLAG_BC:
19743     case MIPS_HFLAG_BL:
19744     case MIPS_HFLAG_B:
19745         env->btarget = tcg_ctx->gen_opc_btarget[pc_pos];
19746         break;
19747     }
19748 }
19749