xref: /qemu/target/mips/tcg/translate.c (revision 962a145c)
1 /*
2  *  MIPS emulation for QEMU - main translation routines
3  *
4  *  Copyright (c) 2004-2005 Jocelyn Mayer
5  *  Copyright (c) 2006 Marius Groeger (FPU operations)
6  *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7  *  Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
8  *  Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
9  *  Copyright (c) 2020 Philippe Mathieu-Daudé
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
23  */
24 
25 #include "qemu/osdep.h"
26 #include "translate.h"
27 #include "internal.h"
28 #include "exec/helper-proto.h"
29 #include "exec/translation-block.h"
30 #include "semihosting/semihost.h"
31 #include "trace.h"
32 #include "fpu_helper.h"
33 
34 #define HELPER_H "helper.h"
35 #include "exec/helper-info.c.inc"
36 #undef  HELPER_H
37 
38 
39 /*
40  * Many sysemu-only helpers are not reachable for user-only.
41  * Define stub generators here, so that we need not either sprinkle
42  * ifdefs through the translator, nor provide the helper function.
43  */
44 #define STUB_HELPER(NAME, ...) \
45     static inline void gen_helper_##NAME(__VA_ARGS__) \
46     { g_assert_not_reached(); }
47 
48 #ifdef CONFIG_USER_ONLY
49 STUB_HELPER(cache, TCGv_env env, TCGv val, TCGv_i32 reg)
50 #endif
51 
52 enum {
53     /* indirect opcode tables */
54     OPC_SPECIAL  = (0x00 << 26),
55     OPC_REGIMM   = (0x01 << 26),
56     OPC_CP0      = (0x10 << 26),
57     OPC_CP2      = (0x12 << 26),
58     OPC_CP3      = (0x13 << 26),
59     OPC_SPECIAL2 = (0x1C << 26),
60     OPC_SPECIAL3 = (0x1F << 26),
61     /* arithmetic with immediate */
62     OPC_ADDI     = (0x08 << 26),
63     OPC_ADDIU    = (0x09 << 26),
64     OPC_SLTI     = (0x0A << 26),
65     OPC_SLTIU    = (0x0B << 26),
66     /* logic with immediate */
67     OPC_ANDI     = (0x0C << 26),
68     OPC_ORI      = (0x0D << 26),
69     OPC_XORI     = (0x0E << 26),
70     OPC_LUI      = (0x0F << 26),
71     /* arithmetic with immediate */
72     OPC_DADDI    = (0x18 << 26),
73     OPC_DADDIU   = (0x19 << 26),
74     /* Jump and branches */
75     OPC_J        = (0x02 << 26),
76     OPC_JAL      = (0x03 << 26),
77     OPC_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
78     OPC_BEQL     = (0x14 << 26),
79     OPC_BNE      = (0x05 << 26),
80     OPC_BNEL     = (0x15 << 26),
81     OPC_BLEZ     = (0x06 << 26),
82     OPC_BLEZL    = (0x16 << 26),
83     OPC_BGTZ     = (0x07 << 26),
84     OPC_BGTZL    = (0x17 << 26),
85     OPC_JALX     = (0x1D << 26),
86     OPC_DAUI     = (0x1D << 26),
87     /* Load and stores */
88     OPC_LDL      = (0x1A << 26),
89     OPC_LDR      = (0x1B << 26),
90     OPC_LB       = (0x20 << 26),
91     OPC_LH       = (0x21 << 26),
92     OPC_LWL      = (0x22 << 26),
93     OPC_LW       = (0x23 << 26),
94     OPC_LWPC     = OPC_LW | 0x5,
95     OPC_LBU      = (0x24 << 26),
96     OPC_LHU      = (0x25 << 26),
97     OPC_LWR      = (0x26 << 26),
98     OPC_LWU      = (0x27 << 26),
99     OPC_SB       = (0x28 << 26),
100     OPC_SH       = (0x29 << 26),
101     OPC_SWL      = (0x2A << 26),
102     OPC_SW       = (0x2B << 26),
103     OPC_SDL      = (0x2C << 26),
104     OPC_SDR      = (0x2D << 26),
105     OPC_SWR      = (0x2E << 26),
106     OPC_LL       = (0x30 << 26),
107     OPC_LLD      = (0x34 << 26),
108     OPC_LD       = (0x37 << 26),
109     OPC_LDPC     = OPC_LD | 0x5,
110     OPC_SC       = (0x38 << 26),
111     OPC_SCD      = (0x3C << 26),
112     OPC_SD       = (0x3F << 26),
113     /* Floating point load/store */
114     OPC_LWC1     = (0x31 << 26),
115     OPC_LWC2     = (0x32 << 26),
116     OPC_LDC1     = (0x35 << 26),
117     OPC_LDC2     = (0x36 << 26),
118     OPC_SWC1     = (0x39 << 26),
119     OPC_SWC2     = (0x3A << 26),
120     OPC_SDC1     = (0x3D << 26),
121     OPC_SDC2     = (0x3E << 26),
122     /* Compact Branches */
123     OPC_BLEZALC  = (0x06 << 26),
124     OPC_BGEZALC  = (0x06 << 26),
125     OPC_BGEUC    = (0x06 << 26),
126     OPC_BGTZALC  = (0x07 << 26),
127     OPC_BLTZALC  = (0x07 << 26),
128     OPC_BLTUC    = (0x07 << 26),
129     OPC_BOVC     = (0x08 << 26),
130     OPC_BEQZALC  = (0x08 << 26),
131     OPC_BEQC     = (0x08 << 26),
132     OPC_BLEZC    = (0x16 << 26),
133     OPC_BGEZC    = (0x16 << 26),
134     OPC_BGEC     = (0x16 << 26),
135     OPC_BGTZC    = (0x17 << 26),
136     OPC_BLTZC    = (0x17 << 26),
137     OPC_BLTC     = (0x17 << 26),
138     OPC_BNVC     = (0x18 << 26),
139     OPC_BNEZALC  = (0x18 << 26),
140     OPC_BNEC     = (0x18 << 26),
141     OPC_BC       = (0x32 << 26),
142     OPC_BEQZC    = (0x36 << 26),
143     OPC_JIC      = (0x36 << 26),
144     OPC_BALC     = (0x3A << 26),
145     OPC_BNEZC    = (0x3E << 26),
146     OPC_JIALC    = (0x3E << 26),
147     /* MDMX ASE specific */
148     OPC_MDMX     = (0x1E << 26),
149     /* Cache and prefetch */
150     OPC_CACHE    = (0x2F << 26),
151     OPC_PREF     = (0x33 << 26),
152     /* PC-relative address computation / loads */
153     OPC_PCREL    = (0x3B << 26),
154 };
155 
156 /* PC-relative address computation / loads  */
157 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
158 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
159 enum {
160     /* Instructions determined by bits 19 and 20 */
161     OPC_ADDIUPC = OPC_PCREL | (0 << 19),
162     R6_OPC_LWPC = OPC_PCREL | (1 << 19),
163     OPC_LWUPC   = OPC_PCREL | (2 << 19),
164 
165     /* Instructions determined by bits 16 ... 20 */
166     OPC_AUIPC   = OPC_PCREL | (0x1e << 16),
167     OPC_ALUIPC  = OPC_PCREL | (0x1f << 16),
168 
169     /* Other */
170     R6_OPC_LDPC = OPC_PCREL | (6 << 18),
171 };
172 
173 /* MIPS special opcodes */
174 #define MASK_SPECIAL(op)            (MASK_OP_MAJOR(op) | (op & 0x3F))
175 
176 enum {
177     /* Shifts */
178     OPC_SLL      = 0x00 | OPC_SPECIAL,
179     /* NOP is SLL r0, r0, 0   */
180     /* SSNOP is SLL r0, r0, 1 */
181     /* EHB is SLL r0, r0, 3 */
182     OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
183     OPC_ROTR     = OPC_SRL | (1 << 21),
184     OPC_SRA      = 0x03 | OPC_SPECIAL,
185     OPC_SLLV     = 0x04 | OPC_SPECIAL,
186     OPC_SRLV     = 0x06 | OPC_SPECIAL, /* also ROTRV */
187     OPC_ROTRV    = OPC_SRLV | (1 << 6),
188     OPC_SRAV     = 0x07 | OPC_SPECIAL,
189     OPC_DSLLV    = 0x14 | OPC_SPECIAL,
190     OPC_DSRLV    = 0x16 | OPC_SPECIAL, /* also DROTRV */
191     OPC_DROTRV   = OPC_DSRLV | (1 << 6),
192     OPC_DSRAV    = 0x17 | OPC_SPECIAL,
193     OPC_DSLL     = 0x38 | OPC_SPECIAL,
194     OPC_DSRL     = 0x3A | OPC_SPECIAL, /* also DROTR */
195     OPC_DROTR    = OPC_DSRL | (1 << 21),
196     OPC_DSRA     = 0x3B | OPC_SPECIAL,
197     OPC_DSLL32   = 0x3C | OPC_SPECIAL,
198     OPC_DSRL32   = 0x3E | OPC_SPECIAL, /* also DROTR32 */
199     OPC_DROTR32  = OPC_DSRL32 | (1 << 21),
200     OPC_DSRA32   = 0x3F | OPC_SPECIAL,
201     /* Multiplication / division */
202     OPC_MULT     = 0x18 | OPC_SPECIAL,
203     OPC_MULTU    = 0x19 | OPC_SPECIAL,
204     OPC_DIV      = 0x1A | OPC_SPECIAL,
205     OPC_DIVU     = 0x1B | OPC_SPECIAL,
206     OPC_DMULT    = 0x1C | OPC_SPECIAL,
207     OPC_DMULTU   = 0x1D | OPC_SPECIAL,
208     OPC_DDIV     = 0x1E | OPC_SPECIAL,
209     OPC_DDIVU    = 0x1F | OPC_SPECIAL,
210 
211     /* 2 registers arithmetic / logic */
212     OPC_ADD      = 0x20 | OPC_SPECIAL,
213     OPC_ADDU     = 0x21 | OPC_SPECIAL,
214     OPC_SUB      = 0x22 | OPC_SPECIAL,
215     OPC_SUBU     = 0x23 | OPC_SPECIAL,
216     OPC_AND      = 0x24 | OPC_SPECIAL,
217     OPC_OR       = 0x25 | OPC_SPECIAL,
218     OPC_XOR      = 0x26 | OPC_SPECIAL,
219     OPC_NOR      = 0x27 | OPC_SPECIAL,
220     OPC_SLT      = 0x2A | OPC_SPECIAL,
221     OPC_SLTU     = 0x2B | OPC_SPECIAL,
222     OPC_DADD     = 0x2C | OPC_SPECIAL,
223     OPC_DADDU    = 0x2D | OPC_SPECIAL,
224     OPC_DSUB     = 0x2E | OPC_SPECIAL,
225     OPC_DSUBU    = 0x2F | OPC_SPECIAL,
226     /* Jumps */
227     OPC_JR       = 0x08 | OPC_SPECIAL, /* Also JR.HB */
228     OPC_JALR     = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
229     /* Traps */
230     OPC_TGE      = 0x30 | OPC_SPECIAL,
231     OPC_TGEU     = 0x31 | OPC_SPECIAL,
232     OPC_TLT      = 0x32 | OPC_SPECIAL,
233     OPC_TLTU     = 0x33 | OPC_SPECIAL,
234     OPC_TEQ      = 0x34 | OPC_SPECIAL,
235     OPC_TNE      = 0x36 | OPC_SPECIAL,
236     /* HI / LO registers load & stores */
237     OPC_MFHI     = 0x10 | OPC_SPECIAL,
238     OPC_MTHI     = 0x11 | OPC_SPECIAL,
239     OPC_MFLO     = 0x12 | OPC_SPECIAL,
240     OPC_MTLO     = 0x13 | OPC_SPECIAL,
241     /* Conditional moves */
242     OPC_MOVZ     = 0x0A | OPC_SPECIAL,
243     OPC_MOVN     = 0x0B | OPC_SPECIAL,
244 
245     OPC_SELEQZ   = 0x35 | OPC_SPECIAL,
246     OPC_SELNEZ   = 0x37 | OPC_SPECIAL,
247 
248     OPC_MOVCI    = 0x01 | OPC_SPECIAL,
249 
250     /* Special */
251     OPC_PMON     = 0x05 | OPC_SPECIAL, /* unofficial */
252     OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
253     OPC_BREAK    = 0x0D | OPC_SPECIAL,
254     OPC_SPIM     = 0x0E | OPC_SPECIAL, /* unofficial */
255     OPC_SYNC     = 0x0F | OPC_SPECIAL,
256 
257     OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
258     OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
259     OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
260     OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
261 };
262 
263 /*
264  * R6 Multiply and Divide instructions have the same opcode
265  * and function field as legacy OPC_MULT[U]/OPC_DIV[U]
266  */
267 #define MASK_R6_MULDIV(op)          (MASK_SPECIAL(op) | (op & (0x7ff)))
268 
269 enum {
270     R6_OPC_MUL   = OPC_MULT  | (2 << 6),
271     R6_OPC_MUH   = OPC_MULT  | (3 << 6),
272     R6_OPC_MULU  = OPC_MULTU | (2 << 6),
273     R6_OPC_MUHU  = OPC_MULTU | (3 << 6),
274     R6_OPC_DIV   = OPC_DIV   | (2 << 6),
275     R6_OPC_MOD   = OPC_DIV   | (3 << 6),
276     R6_OPC_DIVU  = OPC_DIVU  | (2 << 6),
277     R6_OPC_MODU  = OPC_DIVU  | (3 << 6),
278 
279     R6_OPC_DMUL   = OPC_DMULT  | (2 << 6),
280     R6_OPC_DMUH   = OPC_DMULT  | (3 << 6),
281     R6_OPC_DMULU  = OPC_DMULTU | (2 << 6),
282     R6_OPC_DMUHU  = OPC_DMULTU | (3 << 6),
283     R6_OPC_DDIV   = OPC_DDIV   | (2 << 6),
284     R6_OPC_DMOD   = OPC_DDIV   | (3 << 6),
285     R6_OPC_DDIVU  = OPC_DDIVU  | (2 << 6),
286     R6_OPC_DMODU  = OPC_DDIVU  | (3 << 6),
287 
288     R6_OPC_CLZ      = 0x10 | OPC_SPECIAL,
289     R6_OPC_CLO      = 0x11 | OPC_SPECIAL,
290     R6_OPC_DCLZ     = 0x12 | OPC_SPECIAL,
291     R6_OPC_DCLO     = 0x13 | OPC_SPECIAL,
292     R6_OPC_SDBBP    = 0x0e | OPC_SPECIAL,
293 };
294 
295 /* REGIMM (rt field) opcodes */
296 #define MASK_REGIMM(op)             (MASK_OP_MAJOR(op) | (op & (0x1F << 16)))
297 
298 enum {
299     OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
300     OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
301     OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
302     OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
303     OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
304     OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
305     OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
306     OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
307     OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
308     OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
309     OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
310     OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
311     OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
312     OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
313     OPC_SIGRIE   = (0x17 << 16) | OPC_REGIMM,
314     OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
315 
316     OPC_DAHI     = (0x06 << 16) | OPC_REGIMM,
317     OPC_DATI     = (0x1e << 16) | OPC_REGIMM,
318 };
319 
320 /* Special2 opcodes */
321 #define MASK_SPECIAL2(op)           (MASK_OP_MAJOR(op) | (op & 0x3F))
322 
323 enum {
324     /* Multiply & xxx operations */
325     OPC_MADD     = 0x00 | OPC_SPECIAL2,
326     OPC_MADDU    = 0x01 | OPC_SPECIAL2,
327     OPC_MUL      = 0x02 | OPC_SPECIAL2,
328     OPC_MSUB     = 0x04 | OPC_SPECIAL2,
329     OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
330     /* Loongson 2F */
331     OPC_MULT_G_2F   = 0x10 | OPC_SPECIAL2,
332     OPC_DMULT_G_2F  = 0x11 | OPC_SPECIAL2,
333     OPC_MULTU_G_2F  = 0x12 | OPC_SPECIAL2,
334     OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
335     OPC_DIV_G_2F    = 0x14 | OPC_SPECIAL2,
336     OPC_DDIV_G_2F   = 0x15 | OPC_SPECIAL2,
337     OPC_DIVU_G_2F   = 0x16 | OPC_SPECIAL2,
338     OPC_DDIVU_G_2F  = 0x17 | OPC_SPECIAL2,
339     OPC_MOD_G_2F    = 0x1c | OPC_SPECIAL2,
340     OPC_DMOD_G_2F   = 0x1d | OPC_SPECIAL2,
341     OPC_MODU_G_2F   = 0x1e | OPC_SPECIAL2,
342     OPC_DMODU_G_2F  = 0x1f | OPC_SPECIAL2,
343     /* Misc */
344     OPC_CLZ      = 0x20 | OPC_SPECIAL2,
345     OPC_CLO      = 0x21 | OPC_SPECIAL2,
346     OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
347     OPC_DCLO     = 0x25 | OPC_SPECIAL2,
348     /* Special */
349     OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
350 };
351 
352 /* Special3 opcodes */
353 #define MASK_SPECIAL3(op)           (MASK_OP_MAJOR(op) | (op & 0x3F))
354 
355 enum {
356     OPC_EXT      = 0x00 | OPC_SPECIAL3,
357     OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
358     OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
359     OPC_DEXT     = 0x03 | OPC_SPECIAL3,
360     OPC_INS      = 0x04 | OPC_SPECIAL3,
361     OPC_DINSM    = 0x05 | OPC_SPECIAL3,
362     OPC_DINSU    = 0x06 | OPC_SPECIAL3,
363     OPC_DINS     = 0x07 | OPC_SPECIAL3,
364     OPC_FORK     = 0x08 | OPC_SPECIAL3,
365     OPC_YIELD    = 0x09 | OPC_SPECIAL3,
366     OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
367     OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
368     OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
369     OPC_GINV     = 0x3D | OPC_SPECIAL3,
370 
371     /* Loongson 2E */
372     OPC_MULT_G_2E   = 0x18 | OPC_SPECIAL3,
373     OPC_MULTU_G_2E  = 0x19 | OPC_SPECIAL3,
374     OPC_DIV_G_2E    = 0x1A | OPC_SPECIAL3,
375     OPC_DIVU_G_2E   = 0x1B | OPC_SPECIAL3,
376     OPC_DMULT_G_2E  = 0x1C | OPC_SPECIAL3,
377     OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
378     OPC_DDIV_G_2E   = 0x1E | OPC_SPECIAL3,
379     OPC_DDIVU_G_2E  = 0x1F | OPC_SPECIAL3,
380     OPC_MOD_G_2E    = 0x22 | OPC_SPECIAL3,
381     OPC_MODU_G_2E   = 0x23 | OPC_SPECIAL3,
382     OPC_DMOD_G_2E   = 0x26 | OPC_SPECIAL3,
383     OPC_DMODU_G_2E  = 0x27 | OPC_SPECIAL3,
384 
385     /* MIPS DSP Load */
386     OPC_LX_DSP         = 0x0A | OPC_SPECIAL3,
387     /* MIPS DSP Arithmetic */
388     OPC_ADDU_QB_DSP    = 0x10 | OPC_SPECIAL3,
389     OPC_ADDU_OB_DSP    = 0x14 | OPC_SPECIAL3,
390     OPC_ABSQ_S_PH_DSP  = 0x12 | OPC_SPECIAL3,
391     OPC_ABSQ_S_QH_DSP  = 0x16 | OPC_SPECIAL3,
392     /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E.  */
393     /* OPC_ADDUH_QB_DSP   = 0x18 | OPC_SPECIAL3,  */
394     OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
395     OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
396     /* MIPS DSP GPR-Based Shift Sub-class */
397     OPC_SHLL_QB_DSP    = 0x13 | OPC_SPECIAL3,
398     OPC_SHLL_OB_DSP    = 0x17 | OPC_SPECIAL3,
399     /* MIPS DSP Multiply Sub-class insns */
400     /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP.  */
401     /* OPC_MUL_PH_DSP     = 0x18 | OPC_SPECIAL3,  */
402     OPC_DPA_W_PH_DSP   = 0x30 | OPC_SPECIAL3,
403     OPC_DPAQ_W_QH_DSP  = 0x34 | OPC_SPECIAL3,
404     /* DSP Bit/Manipulation Sub-class */
405     OPC_INSV_DSP       = 0x0C | OPC_SPECIAL3,
406     OPC_DINSV_DSP      = 0x0D | OPC_SPECIAL3,
407     /* MIPS DSP Append Sub-class */
408     OPC_APPEND_DSP     = 0x31 | OPC_SPECIAL3,
409     OPC_DAPPEND_DSP    = 0x35 | OPC_SPECIAL3,
410     /* MIPS DSP Accumulator and DSPControl Access Sub-class */
411     OPC_EXTR_W_DSP     = 0x38 | OPC_SPECIAL3,
412     OPC_DEXTR_W_DSP    = 0x3C | OPC_SPECIAL3,
413 
414     /* EVA */
415     OPC_LWLE           = 0x19 | OPC_SPECIAL3,
416     OPC_LWRE           = 0x1A | OPC_SPECIAL3,
417     OPC_CACHEE         = 0x1B | OPC_SPECIAL3,
418     OPC_SBE            = 0x1C | OPC_SPECIAL3,
419     OPC_SHE            = 0x1D | OPC_SPECIAL3,
420     OPC_SCE            = 0x1E | OPC_SPECIAL3,
421     OPC_SWE            = 0x1F | OPC_SPECIAL3,
422     OPC_SWLE           = 0x21 | OPC_SPECIAL3,
423     OPC_SWRE           = 0x22 | OPC_SPECIAL3,
424     OPC_PREFE          = 0x23 | OPC_SPECIAL3,
425     OPC_LBUE           = 0x28 | OPC_SPECIAL3,
426     OPC_LHUE           = 0x29 | OPC_SPECIAL3,
427     OPC_LBE            = 0x2C | OPC_SPECIAL3,
428     OPC_LHE            = 0x2D | OPC_SPECIAL3,
429     OPC_LLE            = 0x2E | OPC_SPECIAL3,
430     OPC_LWE            = 0x2F | OPC_SPECIAL3,
431 
432     /* R6 */
433     R6_OPC_PREF        = 0x35 | OPC_SPECIAL3,
434     R6_OPC_CACHE       = 0x25 | OPC_SPECIAL3,
435     R6_OPC_LL          = 0x36 | OPC_SPECIAL3,
436     R6_OPC_SC          = 0x26 | OPC_SPECIAL3,
437     R6_OPC_LLD         = 0x37 | OPC_SPECIAL3,
438     R6_OPC_SCD         = 0x27 | OPC_SPECIAL3,
439 };
440 
441 /* Loongson EXT load/store quad word opcodes */
442 #define MASK_LOONGSON_GSLSQ(op)           (MASK_OP_MAJOR(op) | (op & 0x8020))
443 enum {
444     OPC_GSLQ        = 0x0020 | OPC_LWC2,
445     OPC_GSLQC1      = 0x8020 | OPC_LWC2,
446     OPC_GSSHFL      = OPC_LWC2,
447     OPC_GSSQ        = 0x0020 | OPC_SWC2,
448     OPC_GSSQC1      = 0x8020 | OPC_SWC2,
449     OPC_GSSHFS      = OPC_SWC2,
450 };
451 
452 /* Loongson EXT shifted load/store opcodes */
453 #define MASK_LOONGSON_GSSHFLS(op)         (MASK_OP_MAJOR(op) | (op & 0xc03f))
454 enum {
455     OPC_GSLWLC1     = 0x4 | OPC_GSSHFL,
456     OPC_GSLWRC1     = 0x5 | OPC_GSSHFL,
457     OPC_GSLDLC1     = 0x6 | OPC_GSSHFL,
458     OPC_GSLDRC1     = 0x7 | OPC_GSSHFL,
459     OPC_GSSWLC1     = 0x4 | OPC_GSSHFS,
460     OPC_GSSWRC1     = 0x5 | OPC_GSSHFS,
461     OPC_GSSDLC1     = 0x6 | OPC_GSSHFS,
462     OPC_GSSDRC1     = 0x7 | OPC_GSSHFS,
463 };
464 
465 /* Loongson EXT LDC2/SDC2 opcodes */
466 #define MASK_LOONGSON_LSDC2(op)           (MASK_OP_MAJOR(op) | (op & 0x7))
467 
468 enum {
469     OPC_GSLBX      = 0x0 | OPC_LDC2,
470     OPC_GSLHX      = 0x1 | OPC_LDC2,
471     OPC_GSLWX      = 0x2 | OPC_LDC2,
472     OPC_GSLDX      = 0x3 | OPC_LDC2,
473     OPC_GSLWXC1    = 0x6 | OPC_LDC2,
474     OPC_GSLDXC1    = 0x7 | OPC_LDC2,
475     OPC_GSSBX      = 0x0 | OPC_SDC2,
476     OPC_GSSHX      = 0x1 | OPC_SDC2,
477     OPC_GSSWX      = 0x2 | OPC_SDC2,
478     OPC_GSSDX      = 0x3 | OPC_SDC2,
479     OPC_GSSWXC1    = 0x6 | OPC_SDC2,
480     OPC_GSSDXC1    = 0x7 | OPC_SDC2,
481 };
482 
483 /* BSHFL opcodes */
484 #define MASK_BSHFL(op)              (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
485 
486 enum {
487     OPC_WSBH      = (0x02 << 6) | OPC_BSHFL,
488     OPC_SEB       = (0x10 << 6) | OPC_BSHFL,
489     OPC_SEH       = (0x18 << 6) | OPC_BSHFL,
490     OPC_ALIGN     = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */
491     OPC_ALIGN_1   = (0x09 << 6) | OPC_BSHFL,
492     OPC_ALIGN_2   = (0x0A << 6) | OPC_BSHFL,
493     OPC_ALIGN_3   = (0x0B << 6) | OPC_BSHFL,
494     OPC_BITSWAP   = (0x00 << 6) | OPC_BSHFL  /* 00000 */
495 };
496 
497 /* DBSHFL opcodes */
498 #define MASK_DBSHFL(op)             (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
499 
500 enum {
501     OPC_DSBH       = (0x02 << 6) | OPC_DBSHFL,
502     OPC_DSHD       = (0x05 << 6) | OPC_DBSHFL,
503     OPC_DALIGN     = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */
504     OPC_DALIGN_1   = (0x09 << 6) | OPC_DBSHFL,
505     OPC_DALIGN_2   = (0x0A << 6) | OPC_DBSHFL,
506     OPC_DALIGN_3   = (0x0B << 6) | OPC_DBSHFL,
507     OPC_DALIGN_4   = (0x0C << 6) | OPC_DBSHFL,
508     OPC_DALIGN_5   = (0x0D << 6) | OPC_DBSHFL,
509     OPC_DALIGN_6   = (0x0E << 6) | OPC_DBSHFL,
510     OPC_DALIGN_7   = (0x0F << 6) | OPC_DBSHFL,
511     OPC_DBITSWAP   = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
512 };
513 
514 /* MIPS DSP REGIMM opcodes */
515 enum {
516     OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
517     OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
518 };
519 
520 #define MASK_LX(op)                 (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
521 /* MIPS DSP Load */
522 enum {
523     OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
524     OPC_LHX  = (0x04 << 6) | OPC_LX_DSP,
525     OPC_LWX  = (0x00 << 6) | OPC_LX_DSP,
526     OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
527 };
528 
529 #define MASK_ADDU_QB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
530 enum {
531     /* MIPS DSP Arithmetic Sub-class */
532     OPC_ADDQ_PH        = (0x0A << 6) | OPC_ADDU_QB_DSP,
533     OPC_ADDQ_S_PH      = (0x0E << 6) | OPC_ADDU_QB_DSP,
534     OPC_ADDQ_S_W       = (0x16 << 6) | OPC_ADDU_QB_DSP,
535     OPC_ADDU_QB        = (0x00 << 6) | OPC_ADDU_QB_DSP,
536     OPC_ADDU_S_QB      = (0x04 << 6) | OPC_ADDU_QB_DSP,
537     OPC_ADDU_PH        = (0x08 << 6) | OPC_ADDU_QB_DSP,
538     OPC_ADDU_S_PH      = (0x0C << 6) | OPC_ADDU_QB_DSP,
539     OPC_SUBQ_PH        = (0x0B << 6) | OPC_ADDU_QB_DSP,
540     OPC_SUBQ_S_PH      = (0x0F << 6) | OPC_ADDU_QB_DSP,
541     OPC_SUBQ_S_W       = (0x17 << 6) | OPC_ADDU_QB_DSP,
542     OPC_SUBU_QB        = (0x01 << 6) | OPC_ADDU_QB_DSP,
543     OPC_SUBU_S_QB      = (0x05 << 6) | OPC_ADDU_QB_DSP,
544     OPC_SUBU_PH        = (0x09 << 6) | OPC_ADDU_QB_DSP,
545     OPC_SUBU_S_PH      = (0x0D << 6) | OPC_ADDU_QB_DSP,
546     OPC_ADDSC          = (0x10 << 6) | OPC_ADDU_QB_DSP,
547     OPC_ADDWC          = (0x11 << 6) | OPC_ADDU_QB_DSP,
548     OPC_MODSUB         = (0x12 << 6) | OPC_ADDU_QB_DSP,
549     OPC_RADDU_W_QB     = (0x14 << 6) | OPC_ADDU_QB_DSP,
550     /* MIPS DSP Multiply Sub-class insns */
551     OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
552     OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
553     OPC_MULQ_RS_PH     = (0x1F << 6) | OPC_ADDU_QB_DSP,
554     OPC_MULEQ_S_W_PHL  = (0x1C << 6) | OPC_ADDU_QB_DSP,
555     OPC_MULEQ_S_W_PHR  = (0x1D << 6) | OPC_ADDU_QB_DSP,
556     OPC_MULQ_S_PH      = (0x1E << 6) | OPC_ADDU_QB_DSP,
557 };
558 
559 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
560 #define MASK_ADDUH_QB(op)           (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
561 enum {
562     /* MIPS DSP Arithmetic Sub-class */
563     OPC_ADDUH_QB   = (0x00 << 6) | OPC_ADDUH_QB_DSP,
564     OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
565     OPC_ADDQH_PH   = (0x08 << 6) | OPC_ADDUH_QB_DSP,
566     OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
567     OPC_ADDQH_W    = (0x10 << 6) | OPC_ADDUH_QB_DSP,
568     OPC_ADDQH_R_W  = (0x12 << 6) | OPC_ADDUH_QB_DSP,
569     OPC_SUBUH_QB   = (0x01 << 6) | OPC_ADDUH_QB_DSP,
570     OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
571     OPC_SUBQH_PH   = (0x09 << 6) | OPC_ADDUH_QB_DSP,
572     OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
573     OPC_SUBQH_W    = (0x11 << 6) | OPC_ADDUH_QB_DSP,
574     OPC_SUBQH_R_W  = (0x13 << 6) | OPC_ADDUH_QB_DSP,
575     /* MIPS DSP Multiply Sub-class insns */
576     OPC_MUL_PH     = (0x0C << 6) | OPC_ADDUH_QB_DSP,
577     OPC_MUL_S_PH   = (0x0E << 6) | OPC_ADDUH_QB_DSP,
578     OPC_MULQ_S_W   = (0x16 << 6) | OPC_ADDUH_QB_DSP,
579     OPC_MULQ_RS_W  = (0x17 << 6) | OPC_ADDUH_QB_DSP,
580 };
581 
582 #define MASK_ABSQ_S_PH(op)          (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
583 enum {
584     /* MIPS DSP Arithmetic Sub-class */
585     OPC_ABSQ_S_QB       = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
586     OPC_ABSQ_S_PH       = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
587     OPC_ABSQ_S_W        = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
588     OPC_PRECEQ_W_PHL    = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
589     OPC_PRECEQ_W_PHR    = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
590     OPC_PRECEQU_PH_QBL  = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
591     OPC_PRECEQU_PH_QBR  = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
592     OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
593     OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
594     OPC_PRECEU_PH_QBL   = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
595     OPC_PRECEU_PH_QBR   = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
596     OPC_PRECEU_PH_QBLA  = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
597     OPC_PRECEU_PH_QBRA  = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
598     /* DSP Bit/Manipulation Sub-class */
599     OPC_BITREV          = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
600     OPC_REPL_QB         = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
601     OPC_REPLV_QB        = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
602     OPC_REPL_PH         = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
603     OPC_REPLV_PH        = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
604 };
605 
606 #define MASK_CMPU_EQ_QB(op)         (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
607 enum {
608     /* MIPS DSP Arithmetic Sub-class */
609     OPC_PRECR_QB_PH      = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
610     OPC_PRECRQ_QB_PH     = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
611     OPC_PRECR_SRA_PH_W   = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
612     OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
613     OPC_PRECRQ_PH_W      = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
614     OPC_PRECRQ_RS_PH_W   = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
615     OPC_PRECRQU_S_QB_PH  = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
616     /* DSP Compare-Pick Sub-class */
617     OPC_CMPU_EQ_QB       = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
618     OPC_CMPU_LT_QB       = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
619     OPC_CMPU_LE_QB       = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
620     OPC_CMPGU_EQ_QB      = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
621     OPC_CMPGU_LT_QB      = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
622     OPC_CMPGU_LE_QB      = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
623     OPC_CMPGDU_EQ_QB     = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
624     OPC_CMPGDU_LT_QB     = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
625     OPC_CMPGDU_LE_QB     = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
626     OPC_CMP_EQ_PH        = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
627     OPC_CMP_LT_PH        = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
628     OPC_CMP_LE_PH        = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
629     OPC_PICK_QB          = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
630     OPC_PICK_PH          = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
631     OPC_PACKRL_PH        = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
632 };
633 
634 #define MASK_SHLL_QB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
635 enum {
636     /* MIPS DSP GPR-Based Shift Sub-class */
637     OPC_SHLL_QB    = (0x00 << 6) | OPC_SHLL_QB_DSP,
638     OPC_SHLLV_QB   = (0x02 << 6) | OPC_SHLL_QB_DSP,
639     OPC_SHLL_PH    = (0x08 << 6) | OPC_SHLL_QB_DSP,
640     OPC_SHLLV_PH   = (0x0A << 6) | OPC_SHLL_QB_DSP,
641     OPC_SHLL_S_PH  = (0x0C << 6) | OPC_SHLL_QB_DSP,
642     OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
643     OPC_SHLL_S_W   = (0x14 << 6) | OPC_SHLL_QB_DSP,
644     OPC_SHLLV_S_W  = (0x16 << 6) | OPC_SHLL_QB_DSP,
645     OPC_SHRL_QB    = (0x01 << 6) | OPC_SHLL_QB_DSP,
646     OPC_SHRLV_QB   = (0x03 << 6) | OPC_SHLL_QB_DSP,
647     OPC_SHRL_PH    = (0x19 << 6) | OPC_SHLL_QB_DSP,
648     OPC_SHRLV_PH   = (0x1B << 6) | OPC_SHLL_QB_DSP,
649     OPC_SHRA_QB    = (0x04 << 6) | OPC_SHLL_QB_DSP,
650     OPC_SHRA_R_QB  = (0x05 << 6) | OPC_SHLL_QB_DSP,
651     OPC_SHRAV_QB   = (0x06 << 6) | OPC_SHLL_QB_DSP,
652     OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
653     OPC_SHRA_PH    = (0x09 << 6) | OPC_SHLL_QB_DSP,
654     OPC_SHRAV_PH   = (0x0B << 6) | OPC_SHLL_QB_DSP,
655     OPC_SHRA_R_PH  = (0x0D << 6) | OPC_SHLL_QB_DSP,
656     OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
657     OPC_SHRA_R_W   = (0x15 << 6) | OPC_SHLL_QB_DSP,
658     OPC_SHRAV_R_W  = (0x17 << 6) | OPC_SHLL_QB_DSP,
659 };
660 
661 #define MASK_DPA_W_PH(op)           (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
662 enum {
663     /* MIPS DSP Multiply Sub-class insns */
664     OPC_DPAU_H_QBL    = (0x03 << 6) | OPC_DPA_W_PH_DSP,
665     OPC_DPAU_H_QBR    = (0x07 << 6) | OPC_DPA_W_PH_DSP,
666     OPC_DPSU_H_QBL    = (0x0B << 6) | OPC_DPA_W_PH_DSP,
667     OPC_DPSU_H_QBR    = (0x0F << 6) | OPC_DPA_W_PH_DSP,
668     OPC_DPA_W_PH      = (0x00 << 6) | OPC_DPA_W_PH_DSP,
669     OPC_DPAX_W_PH     = (0x08 << 6) | OPC_DPA_W_PH_DSP,
670     OPC_DPAQ_S_W_PH   = (0x04 << 6) | OPC_DPA_W_PH_DSP,
671     OPC_DPAQX_S_W_PH  = (0x18 << 6) | OPC_DPA_W_PH_DSP,
672     OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
673     OPC_DPS_W_PH      = (0x01 << 6) | OPC_DPA_W_PH_DSP,
674     OPC_DPSX_W_PH     = (0x09 << 6) | OPC_DPA_W_PH_DSP,
675     OPC_DPSQ_S_W_PH   = (0x05 << 6) | OPC_DPA_W_PH_DSP,
676     OPC_DPSQX_S_W_PH  = (0x19 << 6) | OPC_DPA_W_PH_DSP,
677     OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
678     OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
679     OPC_DPAQ_SA_L_W   = (0x0C << 6) | OPC_DPA_W_PH_DSP,
680     OPC_DPSQ_SA_L_W   = (0x0D << 6) | OPC_DPA_W_PH_DSP,
681     OPC_MAQ_S_W_PHL   = (0x14 << 6) | OPC_DPA_W_PH_DSP,
682     OPC_MAQ_S_W_PHR   = (0x16 << 6) | OPC_DPA_W_PH_DSP,
683     OPC_MAQ_SA_W_PHL  = (0x10 << 6) | OPC_DPA_W_PH_DSP,
684     OPC_MAQ_SA_W_PHR  = (0x12 << 6) | OPC_DPA_W_PH_DSP,
685     OPC_MULSA_W_PH    = (0x02 << 6) | OPC_DPA_W_PH_DSP,
686 };
687 
688 #define MASK_INSV(op)               (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
689 enum {
690     /* DSP Bit/Manipulation Sub-class */
691     OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
692 };
693 
694 #define MASK_APPEND(op)             (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
695 enum {
696     /* MIPS DSP Append Sub-class */
697     OPC_APPEND  = (0x00 << 6) | OPC_APPEND_DSP,
698     OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
699     OPC_BALIGN  = (0x10 << 6) | OPC_APPEND_DSP,
700 };
701 
702 #define MASK_EXTR_W(op)             (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
703 enum {
704     /* MIPS DSP Accumulator and DSPControl Access Sub-class */
705     OPC_EXTR_W     = (0x00 << 6) | OPC_EXTR_W_DSP,
706     OPC_EXTR_R_W   = (0x04 << 6) | OPC_EXTR_W_DSP,
707     OPC_EXTR_RS_W  = (0x06 << 6) | OPC_EXTR_W_DSP,
708     OPC_EXTR_S_H   = (0x0E << 6) | OPC_EXTR_W_DSP,
709     OPC_EXTRV_S_H  = (0x0F << 6) | OPC_EXTR_W_DSP,
710     OPC_EXTRV_W    = (0x01 << 6) | OPC_EXTR_W_DSP,
711     OPC_EXTRV_R_W  = (0x05 << 6) | OPC_EXTR_W_DSP,
712     OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
713     OPC_EXTP       = (0x02 << 6) | OPC_EXTR_W_DSP,
714     OPC_EXTPV      = (0x03 << 6) | OPC_EXTR_W_DSP,
715     OPC_EXTPDP     = (0x0A << 6) | OPC_EXTR_W_DSP,
716     OPC_EXTPDPV    = (0x0B << 6) | OPC_EXTR_W_DSP,
717     OPC_SHILO      = (0x1A << 6) | OPC_EXTR_W_DSP,
718     OPC_SHILOV     = (0x1B << 6) | OPC_EXTR_W_DSP,
719     OPC_MTHLIP     = (0x1F << 6) | OPC_EXTR_W_DSP,
720     OPC_WRDSP      = (0x13 << 6) | OPC_EXTR_W_DSP,
721     OPC_RDDSP      = (0x12 << 6) | OPC_EXTR_W_DSP,
722 };
723 
724 #define MASK_ABSQ_S_QH(op)          (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
725 enum {
726     /* MIPS DSP Arithmetic Sub-class */
727     OPC_PRECEQ_L_PWL    = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
728     OPC_PRECEQ_L_PWR    = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
729     OPC_PRECEQ_PW_QHL   = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
730     OPC_PRECEQ_PW_QHR   = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
731     OPC_PRECEQ_PW_QHLA  = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
732     OPC_PRECEQ_PW_QHRA  = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
733     OPC_PRECEQU_QH_OBL  = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
734     OPC_PRECEQU_QH_OBR  = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
735     OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
736     OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
737     OPC_PRECEU_QH_OBL   = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
738     OPC_PRECEU_QH_OBR   = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
739     OPC_PRECEU_QH_OBLA  = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
740     OPC_PRECEU_QH_OBRA  = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
741     OPC_ABSQ_S_OB       = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
742     OPC_ABSQ_S_PW       = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
743     OPC_ABSQ_S_QH       = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
744     /* DSP Bit/Manipulation Sub-class */
745     OPC_REPL_OB         = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
746     OPC_REPL_PW         = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
747     OPC_REPL_QH         = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
748     OPC_REPLV_OB        = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
749     OPC_REPLV_PW        = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
750     OPC_REPLV_QH        = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
751 };
752 
753 #define MASK_ADDU_OB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
754 enum {
755     /* MIPS DSP Multiply Sub-class insns */
756     OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
757     OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
758     OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
759     OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
760     OPC_MULQ_RS_QH     = (0x1F << 6) | OPC_ADDU_OB_DSP,
761     /* MIPS DSP Arithmetic Sub-class */
762     OPC_RADDU_L_OB     = (0x14 << 6) | OPC_ADDU_OB_DSP,
763     OPC_SUBQ_PW        = (0x13 << 6) | OPC_ADDU_OB_DSP,
764     OPC_SUBQ_S_PW      = (0x17 << 6) | OPC_ADDU_OB_DSP,
765     OPC_SUBQ_QH        = (0x0B << 6) | OPC_ADDU_OB_DSP,
766     OPC_SUBQ_S_QH      = (0x0F << 6) | OPC_ADDU_OB_DSP,
767     OPC_SUBU_OB        = (0x01 << 6) | OPC_ADDU_OB_DSP,
768     OPC_SUBU_S_OB      = (0x05 << 6) | OPC_ADDU_OB_DSP,
769     OPC_SUBU_QH        = (0x09 << 6) | OPC_ADDU_OB_DSP,
770     OPC_SUBU_S_QH      = (0x0D << 6) | OPC_ADDU_OB_DSP,
771     OPC_SUBUH_OB       = (0x19 << 6) | OPC_ADDU_OB_DSP,
772     OPC_SUBUH_R_OB     = (0x1B << 6) | OPC_ADDU_OB_DSP,
773     OPC_ADDQ_PW        = (0x12 << 6) | OPC_ADDU_OB_DSP,
774     OPC_ADDQ_S_PW      = (0x16 << 6) | OPC_ADDU_OB_DSP,
775     OPC_ADDQ_QH        = (0x0A << 6) | OPC_ADDU_OB_DSP,
776     OPC_ADDQ_S_QH      = (0x0E << 6) | OPC_ADDU_OB_DSP,
777     OPC_ADDU_OB        = (0x00 << 6) | OPC_ADDU_OB_DSP,
778     OPC_ADDU_S_OB      = (0x04 << 6) | OPC_ADDU_OB_DSP,
779     OPC_ADDU_QH        = (0x08 << 6) | OPC_ADDU_OB_DSP,
780     OPC_ADDU_S_QH      = (0x0C << 6) | OPC_ADDU_OB_DSP,
781     OPC_ADDUH_OB       = (0x18 << 6) | OPC_ADDU_OB_DSP,
782     OPC_ADDUH_R_OB     = (0x1A << 6) | OPC_ADDU_OB_DSP,
783 };
784 
785 #define MASK_CMPU_EQ_OB(op)         (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
786 enum {
787     /* DSP Compare-Pick Sub-class */
788     OPC_CMP_EQ_PW         = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
789     OPC_CMP_LT_PW         = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
790     OPC_CMP_LE_PW         = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
791     OPC_CMP_EQ_QH         = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
792     OPC_CMP_LT_QH         = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
793     OPC_CMP_LE_QH         = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
794     OPC_CMPGDU_EQ_OB      = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
795     OPC_CMPGDU_LT_OB      = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
796     OPC_CMPGDU_LE_OB      = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
797     OPC_CMPGU_EQ_OB       = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
798     OPC_CMPGU_LT_OB       = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
799     OPC_CMPGU_LE_OB       = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
800     OPC_CMPU_EQ_OB        = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
801     OPC_CMPU_LT_OB        = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
802     OPC_CMPU_LE_OB        = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
803     OPC_PACKRL_PW         = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
804     OPC_PICK_OB           = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
805     OPC_PICK_PW           = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
806     OPC_PICK_QH           = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
807     /* MIPS DSP Arithmetic Sub-class */
808     OPC_PRECR_OB_QH       = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
809     OPC_PRECR_SRA_QH_PW   = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
810     OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
811     OPC_PRECRQ_OB_QH      = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
812     OPC_PRECRQ_PW_L       = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
813     OPC_PRECRQ_QH_PW      = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
814     OPC_PRECRQ_RS_QH_PW   = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
815     OPC_PRECRQU_S_OB_QH   = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
816 };
817 
818 #define MASK_DAPPEND(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
819 enum {
820     /* DSP Append Sub-class */
821     OPC_DAPPEND  = (0x00 << 6) | OPC_DAPPEND_DSP,
822     OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
823     OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
824     OPC_DBALIGN  = (0x10 << 6) | OPC_DAPPEND_DSP,
825 };
826 
827 #define MASK_DEXTR_W(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
828 enum {
829     /* MIPS DSP Accumulator and DSPControl Access Sub-class */
830     OPC_DMTHLIP     = (0x1F << 6) | OPC_DEXTR_W_DSP,
831     OPC_DSHILO      = (0x1A << 6) | OPC_DEXTR_W_DSP,
832     OPC_DEXTP       = (0x02 << 6) | OPC_DEXTR_W_DSP,
833     OPC_DEXTPDP     = (0x0A << 6) | OPC_DEXTR_W_DSP,
834     OPC_DEXTPDPV    = (0x0B << 6) | OPC_DEXTR_W_DSP,
835     OPC_DEXTPV      = (0x03 << 6) | OPC_DEXTR_W_DSP,
836     OPC_DEXTR_L     = (0x10 << 6) | OPC_DEXTR_W_DSP,
837     OPC_DEXTR_R_L   = (0x14 << 6) | OPC_DEXTR_W_DSP,
838     OPC_DEXTR_RS_L  = (0x16 << 6) | OPC_DEXTR_W_DSP,
839     OPC_DEXTR_W     = (0x00 << 6) | OPC_DEXTR_W_DSP,
840     OPC_DEXTR_R_W   = (0x04 << 6) | OPC_DEXTR_W_DSP,
841     OPC_DEXTR_RS_W  = (0x06 << 6) | OPC_DEXTR_W_DSP,
842     OPC_DEXTR_S_H   = (0x0E << 6) | OPC_DEXTR_W_DSP,
843     OPC_DEXTRV_L    = (0x11 << 6) | OPC_DEXTR_W_DSP,
844     OPC_DEXTRV_R_L  = (0x15 << 6) | OPC_DEXTR_W_DSP,
845     OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
846     OPC_DEXTRV_S_H  = (0x0F << 6) | OPC_DEXTR_W_DSP,
847     OPC_DEXTRV_W    = (0x01 << 6) | OPC_DEXTR_W_DSP,
848     OPC_DEXTRV_R_W  = (0x05 << 6) | OPC_DEXTR_W_DSP,
849     OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
850     OPC_DSHILOV     = (0x1B << 6) | OPC_DEXTR_W_DSP,
851 };
852 
853 #define MASK_DINSV(op)              (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
854 enum {
855     /* DSP Bit/Manipulation Sub-class */
856     OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
857 };
858 
859 #define MASK_DPAQ_W_QH(op)          (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
860 enum {
861     /* MIPS DSP Multiply Sub-class insns */
862     OPC_DMADD         = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
863     OPC_DMADDU        = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
864     OPC_DMSUB         = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
865     OPC_DMSUBU        = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
866     OPC_DPA_W_QH      = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
867     OPC_DPAQ_S_W_QH   = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
868     OPC_DPAQ_SA_L_PW  = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
869     OPC_DPAU_H_OBL    = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
870     OPC_DPAU_H_OBR    = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
871     OPC_DPS_W_QH      = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
872     OPC_DPSQ_S_W_QH   = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
873     OPC_DPSQ_SA_L_PW  = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
874     OPC_DPSU_H_OBL    = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
875     OPC_DPSU_H_OBR    = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
876     OPC_MAQ_S_L_PWL   = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
877     OPC_MAQ_S_L_PWR   = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
878     OPC_MAQ_S_W_QHLL  = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
879     OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
880     OPC_MAQ_S_W_QHLR  = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
881     OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
882     OPC_MAQ_S_W_QHRL  = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
883     OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
884     OPC_MAQ_S_W_QHRR  = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
885     OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
886     OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
887     OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
888 };
889 
890 #define MASK_SHLL_OB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
891 enum {
892     /* MIPS DSP GPR-Based Shift Sub-class */
893     OPC_SHLL_PW    = (0x10 << 6) | OPC_SHLL_OB_DSP,
894     OPC_SHLL_S_PW  = (0x14 << 6) | OPC_SHLL_OB_DSP,
895     OPC_SHLLV_OB   = (0x02 << 6) | OPC_SHLL_OB_DSP,
896     OPC_SHLLV_PW   = (0x12 << 6) | OPC_SHLL_OB_DSP,
897     OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
898     OPC_SHLLV_QH   = (0x0A << 6) | OPC_SHLL_OB_DSP,
899     OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
900     OPC_SHRA_PW    = (0x11 << 6) | OPC_SHLL_OB_DSP,
901     OPC_SHRA_R_PW  = (0x15 << 6) | OPC_SHLL_OB_DSP,
902     OPC_SHRAV_OB   = (0x06 << 6) | OPC_SHLL_OB_DSP,
903     OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
904     OPC_SHRAV_PW   = (0x13 << 6) | OPC_SHLL_OB_DSP,
905     OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
906     OPC_SHRAV_QH   = (0x0B << 6) | OPC_SHLL_OB_DSP,
907     OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
908     OPC_SHRLV_OB   = (0x03 << 6) | OPC_SHLL_OB_DSP,
909     OPC_SHRLV_QH   = (0x1B << 6) | OPC_SHLL_OB_DSP,
910     OPC_SHLL_OB    = (0x00 << 6) | OPC_SHLL_OB_DSP,
911     OPC_SHLL_QH    = (0x08 << 6) | OPC_SHLL_OB_DSP,
912     OPC_SHLL_S_QH  = (0x0C << 6) | OPC_SHLL_OB_DSP,
913     OPC_SHRA_OB    = (0x04 << 6) | OPC_SHLL_OB_DSP,
914     OPC_SHRA_R_OB  = (0x05 << 6) | OPC_SHLL_OB_DSP,
915     OPC_SHRA_QH    = (0x09 << 6) | OPC_SHLL_OB_DSP,
916     OPC_SHRA_R_QH  = (0x0D << 6) | OPC_SHLL_OB_DSP,
917     OPC_SHRL_OB    = (0x01 << 6) | OPC_SHLL_OB_DSP,
918     OPC_SHRL_QH    = (0x19 << 6) | OPC_SHLL_OB_DSP,
919 };
920 
921 /* Coprocessor 0 (rs field) */
922 #define MASK_CP0(op)                (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
923 
924 enum {
925     OPC_MFC0     = (0x00 << 21) | OPC_CP0,
926     OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
927     OPC_MFHC0    = (0x02 << 21) | OPC_CP0,
928     OPC_MTC0     = (0x04 << 21) | OPC_CP0,
929     OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
930     OPC_MTHC0    = (0x06 << 21) | OPC_CP0,
931     OPC_MFTR     = (0x08 << 21) | OPC_CP0,
932     OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
933     OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
934     OPC_MTTR     = (0x0C << 21) | OPC_CP0,
935     OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
936     OPC_C0       = (0x10 << 21) | OPC_CP0,
937     OPC_C0_1     = (0x11 << 21) | OPC_CP0,
938     OPC_C0_2     = (0x12 << 21) | OPC_CP0,
939     OPC_C0_3     = (0x13 << 21) | OPC_CP0,
940     OPC_C0_4     = (0x14 << 21) | OPC_CP0,
941     OPC_C0_5     = (0x15 << 21) | OPC_CP0,
942     OPC_C0_6     = (0x16 << 21) | OPC_CP0,
943     OPC_C0_7     = (0x17 << 21) | OPC_CP0,
944     OPC_C0_8     = (0x18 << 21) | OPC_CP0,
945     OPC_C0_9     = (0x19 << 21) | OPC_CP0,
946     OPC_C0_A     = (0x1A << 21) | OPC_CP0,
947     OPC_C0_B     = (0x1B << 21) | OPC_CP0,
948     OPC_C0_C     = (0x1C << 21) | OPC_CP0,
949     OPC_C0_D     = (0x1D << 21) | OPC_CP0,
950     OPC_C0_E     = (0x1E << 21) | OPC_CP0,
951     OPC_C0_F     = (0x1F << 21) | OPC_CP0,
952 };
953 
954 /* MFMC0 opcodes */
955 #define MASK_MFMC0(op)              (MASK_CP0(op) | (op & 0xFFFF))
956 
957 enum {
958     OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
959     OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
960     OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
961     OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
962     OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
963     OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
964     OPC_DVP      = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
965     OPC_EVP      = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
966 };
967 
968 /* Coprocessor 0 (with rs == C0) */
969 #define MASK_C0(op)                 (MASK_CP0(op) | (op & 0x3F))
970 
971 enum {
972     OPC_TLBR     = 0x01 | OPC_C0,
973     OPC_TLBWI    = 0x02 | OPC_C0,
974     OPC_TLBINV   = 0x03 | OPC_C0,
975     OPC_TLBINVF  = 0x04 | OPC_C0,
976     OPC_TLBWR    = 0x06 | OPC_C0,
977     OPC_TLBP     = 0x08 | OPC_C0,
978     OPC_RFE      = 0x10 | OPC_C0,
979     OPC_ERET     = 0x18 | OPC_C0,
980     OPC_DERET    = 0x1F | OPC_C0,
981     OPC_WAIT     = 0x20 | OPC_C0,
982 };
983 
984 #define MASK_CP2(op)                (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
985 
986 enum {
987     OPC_MFC2    = (0x00 << 21) | OPC_CP2,
988     OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
989     OPC_CFC2    = (0x02 << 21) | OPC_CP2,
990     OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
991     OPC_MTC2    = (0x04 << 21) | OPC_CP2,
992     OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
993     OPC_CTC2    = (0x06 << 21) | OPC_CP2,
994     OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
995     OPC_BC2     = (0x08 << 21) | OPC_CP2,
996     OPC_BC2EQZ  = (0x09 << 21) | OPC_CP2,
997     OPC_BC2NEZ  = (0x0D << 21) | OPC_CP2,
998 };
999 
1000 #define MASK_LMMI(op)    (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1001 
1002 enum {
1003     OPC_PADDSH      = (24 << 21) | (0x00) | OPC_CP2,
1004     OPC_PADDUSH     = (25 << 21) | (0x00) | OPC_CP2,
1005     OPC_PADDH       = (26 << 21) | (0x00) | OPC_CP2,
1006     OPC_PADDW       = (27 << 21) | (0x00) | OPC_CP2,
1007     OPC_PADDSB      = (28 << 21) | (0x00) | OPC_CP2,
1008     OPC_PADDUSB     = (29 << 21) | (0x00) | OPC_CP2,
1009     OPC_PADDB       = (30 << 21) | (0x00) | OPC_CP2,
1010     OPC_PADDD       = (31 << 21) | (0x00) | OPC_CP2,
1011 
1012     OPC_PSUBSH      = (24 << 21) | (0x01) | OPC_CP2,
1013     OPC_PSUBUSH     = (25 << 21) | (0x01) | OPC_CP2,
1014     OPC_PSUBH       = (26 << 21) | (0x01) | OPC_CP2,
1015     OPC_PSUBW       = (27 << 21) | (0x01) | OPC_CP2,
1016     OPC_PSUBSB      = (28 << 21) | (0x01) | OPC_CP2,
1017     OPC_PSUBUSB     = (29 << 21) | (0x01) | OPC_CP2,
1018     OPC_PSUBB       = (30 << 21) | (0x01) | OPC_CP2,
1019     OPC_PSUBD       = (31 << 21) | (0x01) | OPC_CP2,
1020 
1021     OPC_PSHUFH      = (24 << 21) | (0x02) | OPC_CP2,
1022     OPC_PACKSSWH    = (25 << 21) | (0x02) | OPC_CP2,
1023     OPC_PACKSSHB    = (26 << 21) | (0x02) | OPC_CP2,
1024     OPC_PACKUSHB    = (27 << 21) | (0x02) | OPC_CP2,
1025     OPC_XOR_CP2     = (28 << 21) | (0x02) | OPC_CP2,
1026     OPC_NOR_CP2     = (29 << 21) | (0x02) | OPC_CP2,
1027     OPC_AND_CP2     = (30 << 21) | (0x02) | OPC_CP2,
1028     OPC_PANDN       = (31 << 21) | (0x02) | OPC_CP2,
1029 
1030     OPC_PUNPCKLHW   = (24 << 21) | (0x03) | OPC_CP2,
1031     OPC_PUNPCKHHW   = (25 << 21) | (0x03) | OPC_CP2,
1032     OPC_PUNPCKLBH   = (26 << 21) | (0x03) | OPC_CP2,
1033     OPC_PUNPCKHBH   = (27 << 21) | (0x03) | OPC_CP2,
1034     OPC_PINSRH_0    = (28 << 21) | (0x03) | OPC_CP2,
1035     OPC_PINSRH_1    = (29 << 21) | (0x03) | OPC_CP2,
1036     OPC_PINSRH_2    = (30 << 21) | (0x03) | OPC_CP2,
1037     OPC_PINSRH_3    = (31 << 21) | (0x03) | OPC_CP2,
1038 
1039     OPC_PAVGH       = (24 << 21) | (0x08) | OPC_CP2,
1040     OPC_PAVGB       = (25 << 21) | (0x08) | OPC_CP2,
1041     OPC_PMAXSH      = (26 << 21) | (0x08) | OPC_CP2,
1042     OPC_PMINSH      = (27 << 21) | (0x08) | OPC_CP2,
1043     OPC_PMAXUB      = (28 << 21) | (0x08) | OPC_CP2,
1044     OPC_PMINUB      = (29 << 21) | (0x08) | OPC_CP2,
1045 
1046     OPC_PCMPEQW     = (24 << 21) | (0x09) | OPC_CP2,
1047     OPC_PCMPGTW     = (25 << 21) | (0x09) | OPC_CP2,
1048     OPC_PCMPEQH     = (26 << 21) | (0x09) | OPC_CP2,
1049     OPC_PCMPGTH     = (27 << 21) | (0x09) | OPC_CP2,
1050     OPC_PCMPEQB     = (28 << 21) | (0x09) | OPC_CP2,
1051     OPC_PCMPGTB     = (29 << 21) | (0x09) | OPC_CP2,
1052 
1053     OPC_PSLLW       = (24 << 21) | (0x0A) | OPC_CP2,
1054     OPC_PSLLH       = (25 << 21) | (0x0A) | OPC_CP2,
1055     OPC_PMULLH      = (26 << 21) | (0x0A) | OPC_CP2,
1056     OPC_PMULHH      = (27 << 21) | (0x0A) | OPC_CP2,
1057     OPC_PMULUW      = (28 << 21) | (0x0A) | OPC_CP2,
1058     OPC_PMULHUH     = (29 << 21) | (0x0A) | OPC_CP2,
1059 
1060     OPC_PSRLW       = (24 << 21) | (0x0B) | OPC_CP2,
1061     OPC_PSRLH       = (25 << 21) | (0x0B) | OPC_CP2,
1062     OPC_PSRAW       = (26 << 21) | (0x0B) | OPC_CP2,
1063     OPC_PSRAH       = (27 << 21) | (0x0B) | OPC_CP2,
1064     OPC_PUNPCKLWD   = (28 << 21) | (0x0B) | OPC_CP2,
1065     OPC_PUNPCKHWD   = (29 << 21) | (0x0B) | OPC_CP2,
1066 
1067     OPC_ADDU_CP2    = (24 << 21) | (0x0C) | OPC_CP2,
1068     OPC_OR_CP2      = (25 << 21) | (0x0C) | OPC_CP2,
1069     OPC_ADD_CP2     = (26 << 21) | (0x0C) | OPC_CP2,
1070     OPC_DADD_CP2    = (27 << 21) | (0x0C) | OPC_CP2,
1071     OPC_SEQU_CP2    = (28 << 21) | (0x0C) | OPC_CP2,
1072     OPC_SEQ_CP2     = (29 << 21) | (0x0C) | OPC_CP2,
1073 
1074     OPC_SUBU_CP2    = (24 << 21) | (0x0D) | OPC_CP2,
1075     OPC_PASUBUB     = (25 << 21) | (0x0D) | OPC_CP2,
1076     OPC_SUB_CP2     = (26 << 21) | (0x0D) | OPC_CP2,
1077     OPC_DSUB_CP2    = (27 << 21) | (0x0D) | OPC_CP2,
1078     OPC_SLTU_CP2    = (28 << 21) | (0x0D) | OPC_CP2,
1079     OPC_SLT_CP2     = (29 << 21) | (0x0D) | OPC_CP2,
1080 
1081     OPC_SLL_CP2     = (24 << 21) | (0x0E) | OPC_CP2,
1082     OPC_DSLL_CP2    = (25 << 21) | (0x0E) | OPC_CP2,
1083     OPC_PEXTRH      = (26 << 21) | (0x0E) | OPC_CP2,
1084     OPC_PMADDHW     = (27 << 21) | (0x0E) | OPC_CP2,
1085     OPC_SLEU_CP2    = (28 << 21) | (0x0E) | OPC_CP2,
1086     OPC_SLE_CP2     = (29 << 21) | (0x0E) | OPC_CP2,
1087 
1088     OPC_SRL_CP2     = (24 << 21) | (0x0F) | OPC_CP2,
1089     OPC_DSRL_CP2    = (25 << 21) | (0x0F) | OPC_CP2,
1090     OPC_SRA_CP2     = (26 << 21) | (0x0F) | OPC_CP2,
1091     OPC_DSRA_CP2    = (27 << 21) | (0x0F) | OPC_CP2,
1092     OPC_BIADD       = (28 << 21) | (0x0F) | OPC_CP2,
1093     OPC_PMOVMSKB    = (29 << 21) | (0x0F) | OPC_CP2,
1094 };
1095 
1096 
1097 #define MASK_CP3(op)                (MASK_OP_MAJOR(op) | (op & 0x3F))
1098 
1099 enum {
1100     OPC_LWXC1       = 0x00 | OPC_CP3,
1101     OPC_LDXC1       = 0x01 | OPC_CP3,
1102     OPC_LUXC1       = 0x05 | OPC_CP3,
1103     OPC_SWXC1       = 0x08 | OPC_CP3,
1104     OPC_SDXC1       = 0x09 | OPC_CP3,
1105     OPC_SUXC1       = 0x0D | OPC_CP3,
1106     OPC_PREFX       = 0x0F | OPC_CP3,
1107     OPC_ALNV_PS     = 0x1E | OPC_CP3,
1108     OPC_MADD_S      = 0x20 | OPC_CP3,
1109     OPC_MADD_D      = 0x21 | OPC_CP3,
1110     OPC_MADD_PS     = 0x26 | OPC_CP3,
1111     OPC_MSUB_S      = 0x28 | OPC_CP3,
1112     OPC_MSUB_D      = 0x29 | OPC_CP3,
1113     OPC_MSUB_PS     = 0x2E | OPC_CP3,
1114     OPC_NMADD_S     = 0x30 | OPC_CP3,
1115     OPC_NMADD_D     = 0x31 | OPC_CP3,
1116     OPC_NMADD_PS    = 0x36 | OPC_CP3,
1117     OPC_NMSUB_S     = 0x38 | OPC_CP3,
1118     OPC_NMSUB_D     = 0x39 | OPC_CP3,
1119     OPC_NMSUB_PS    = 0x3E | OPC_CP3,
1120 };
1121 
1122 /*
1123  *     MMI (MultiMedia Instruction) encodings
1124  *     ======================================
1125  *
1126  * MMI instructions encoding table keys:
1127  *
1128  *     *   This code is reserved for future use. An attempt to execute it
1129  *         causes a Reserved Instruction exception.
1130  *     %   This code indicates an instruction class. The instruction word
1131  *         must be further decoded by examining additional tables that show
1132  *         the values for other instruction fields.
1133  *     #   This code is reserved for the unsupported instructions DMULT,
1134  *         DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
1135  *         to execute it causes a Reserved Instruction exception.
1136  *
1137  * MMI instructions encoded by opcode field (MMI, LQ, SQ):
1138  *
1139  *  31    26                                        0
1140  * +--------+----------------------------------------+
1141  * | opcode |                                        |
1142  * +--------+----------------------------------------+
1143  *
1144  *   opcode  bits 28..26
1145  *     bits |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7
1146  *   31..29 |  000  |  001  |  010  |  011  |  100  |  101  |  110  |  111
1147  *   -------+-------+-------+-------+-------+-------+-------+-------+-------
1148  *    0 000 |SPECIAL| REGIMM|   J   |  JAL  |  BEQ  |  BNE  |  BLEZ |  BGTZ
1149  *    1 001 |  ADDI | ADDIU |  SLTI | SLTIU |  ANDI |  ORI  |  XORI |  LUI
1150  *    2 010 |  COP0 |  COP1 |   *   |   *   |  BEQL |  BNEL | BLEZL | BGTZL
1151  *    3 011 | DADDI | DADDIU|  LDL  |  LDR  |  MMI% |   *   |   LQ  |   SQ
1152  *    4 100 |   LB  |   LH  |  LWL  |   LW  |  LBU  |  LHU  |  LWR  |  LWU
1153  *    5 101 |   SB  |   SH  |  SWL  |   SW  |  SDL  |  SDR  |  SWR  | CACHE
1154  *    6 110 |   #   |  LWC1 |   #   |  PREF |   #   |  LDC1 |   #   |   LD
1155  *    7 111 |   #   |  SWC1 |   #   |   *   |   #   |  SDC1 |   #   |   SD
1156  */
1157 
1158 enum {
1159     MMI_OPC_CLASS_MMI = 0x1C << 26,    /* Same as OPC_SPECIAL2 */
1160     MMI_OPC_SQ        = 0x1F << 26,    /* Same as OPC_SPECIAL3 */
1161 };
1162 
1163 /*
1164  * MMI instructions with opcode field = MMI:
1165  *
1166  *  31    26                                 5      0
1167  * +--------+-------------------------------+--------+
1168  * |   MMI  |                               |function|
1169  * +--------+-------------------------------+--------+
1170  *
1171  * function  bits 2..0
1172  *     bits |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7
1173  *     5..3 |  000  |  001  |  010  |  011  |  100  |  101  |  110  |  111
1174  *   -------+-------+-------+-------+-------+-------+-------+-------+-------
1175  *    0 000 |  MADD | MADDU |   *   |   *   | PLZCW |   *   |   *   |   *
1176  *    1 001 | MMI0% | MMI2% |   *   |   *   |   *   |   *   |   *   |   *
1177  *    2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 |   *   |   *   |   *   |   *
1178  *    3 011 | MULT1 | MULTU1|  DIV1 | DIVU1 |   *   |   *   |   *   |   *
1179  *    4 100 | MADD1 | MADDU1|   *   |   *   |   *   |   *   |   *   |   *
1180  *    5 101 | MMI1% | MMI3% |   *   |   *   |   *   |   *   |   *   |   *
1181  *    6 110 | PMFHL | PMTHL |   *   |   *   | PSLLH |   *   | PSRLH | PSRAH
1182  *    7 111 |   *   |   *   |   *   |   *   | PSLLW |   *   | PSRLW | PSRAW
1183  */
1184 
1185 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
1186 enum {
1187     MMI_OPC_MADD       = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */
1188     MMI_OPC_MADDU      = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */
1189     MMI_OPC_MULT1      = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */
1190     MMI_OPC_MULTU1     = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */
1191     MMI_OPC_DIV1       = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV  */
1192     MMI_OPC_DIVU1      = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */
1193     MMI_OPC_MADD1      = 0x20 | MMI_OPC_CLASS_MMI,
1194     MMI_OPC_MADDU1     = 0x21 | MMI_OPC_CLASS_MMI,
1195 };
1196 
1197 /* global register indices */
1198 TCGv cpu_gpr[32], cpu_PC;
1199 /*
1200  * For CPUs using 128-bit GPR registers, we put the lower halves in cpu_gpr[])
1201  * and the upper halves in cpu_gpr_hi[].
1202  */
1203 TCGv_i64 cpu_gpr_hi[32];
1204 TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
1205 static TCGv cpu_dspctrl, btarget;
1206 TCGv bcond;
1207 static TCGv cpu_lladdr, cpu_llval;
1208 static TCGv_i32 hflags;
1209 TCGv_i32 fpu_fcr0, fpu_fcr31;
1210 TCGv_i64 fpu_f64[32];
1211 
1212 static const char regnames_HI[][4] = {
1213     "HI0", "HI1", "HI2", "HI3",
1214 };
1215 
1216 static const char regnames_LO[][4] = {
1217     "LO0", "LO1", "LO2", "LO3",
1218 };
1219 
1220 /* General purpose registers moves. */
gen_load_gpr(TCGv t,int reg)1221 void gen_load_gpr(TCGv t, int reg)
1222 {
1223     assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr));
1224     if (reg == 0) {
1225         tcg_gen_movi_tl(t, 0);
1226     } else {
1227         tcg_gen_mov_tl(t, cpu_gpr[reg]);
1228     }
1229 }
1230 
gen_store_gpr(TCGv t,int reg)1231 void gen_store_gpr(TCGv t, int reg)
1232 {
1233     assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr));
1234     if (reg != 0) {
1235         tcg_gen_mov_tl(cpu_gpr[reg], t);
1236     }
1237 }
1238 
1239 #if defined(TARGET_MIPS64)
gen_load_gpr_hi(TCGv_i64 t,int reg)1240 void gen_load_gpr_hi(TCGv_i64 t, int reg)
1241 {
1242     assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr_hi));
1243     if (reg == 0) {
1244         tcg_gen_movi_i64(t, 0);
1245     } else {
1246         tcg_gen_mov_i64(t, cpu_gpr_hi[reg]);
1247     }
1248 }
1249 
gen_store_gpr_hi(TCGv_i64 t,int reg)1250 void gen_store_gpr_hi(TCGv_i64 t, int reg)
1251 {
1252     assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr_hi));
1253     if (reg != 0) {
1254         tcg_gen_mov_i64(cpu_gpr_hi[reg], t);
1255     }
1256 }
1257 #endif /* TARGET_MIPS64 */
1258 
1259 /* Moves to/from shadow registers. */
gen_load_srsgpr(int from,int to)1260 static inline void gen_load_srsgpr(int from, int to)
1261 {
1262     TCGv t0 = tcg_temp_new();
1263 
1264     if (from == 0) {
1265         tcg_gen_movi_tl(t0, 0);
1266     } else {
1267         TCGv_i32 t2 = tcg_temp_new_i32();
1268         TCGv_ptr addr = tcg_temp_new_ptr();
1269 
1270         tcg_gen_ld_i32(t2, tcg_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1271         tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1272         tcg_gen_andi_i32(t2, t2, 0xf);
1273         tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1274         tcg_gen_ext_i32_ptr(addr, t2);
1275         tcg_gen_add_ptr(addr, tcg_env, addr);
1276 
1277         tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1278     }
1279     gen_store_gpr(t0, to);
1280 }
1281 
gen_store_srsgpr(int from,int to)1282 static inline void gen_store_srsgpr(int from, int to)
1283 {
1284     if (to != 0) {
1285         TCGv t0 = tcg_temp_new();
1286         TCGv_i32 t2 = tcg_temp_new_i32();
1287         TCGv_ptr addr = tcg_temp_new_ptr();
1288 
1289         gen_load_gpr(t0, from);
1290         tcg_gen_ld_i32(t2, tcg_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1291         tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1292         tcg_gen_andi_i32(t2, t2, 0xf);
1293         tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1294         tcg_gen_ext_i32_ptr(addr, t2);
1295         tcg_gen_add_ptr(addr, tcg_env, addr);
1296 
1297         tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1298     }
1299 }
1300 
1301 /* Tests */
gen_save_pc(target_ulong pc)1302 static inline void gen_save_pc(target_ulong pc)
1303 {
1304     tcg_gen_movi_tl(cpu_PC, pc);
1305 }
1306 
save_cpu_state(DisasContext * ctx,int do_save_pc)1307 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1308 {
1309     LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1310     if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
1311         gen_save_pc(ctx->base.pc_next);
1312         ctx->saved_pc = ctx->base.pc_next;
1313     }
1314     if (ctx->hflags != ctx->saved_hflags) {
1315         tcg_gen_movi_i32(hflags, ctx->hflags);
1316         ctx->saved_hflags = ctx->hflags;
1317         switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1318         case MIPS_HFLAG_BR:
1319             break;
1320         case MIPS_HFLAG_BC:
1321         case MIPS_HFLAG_BL:
1322         case MIPS_HFLAG_B:
1323             tcg_gen_movi_tl(btarget, ctx->btarget);
1324             break;
1325         }
1326     }
1327 }
1328 
restore_cpu_state(CPUMIPSState * env,DisasContext * ctx)1329 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1330 {
1331     ctx->saved_hflags = ctx->hflags;
1332     switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1333     case MIPS_HFLAG_BR:
1334         break;
1335     case MIPS_HFLAG_BC:
1336     case MIPS_HFLAG_BL:
1337     case MIPS_HFLAG_B:
1338         ctx->btarget = env->btarget;
1339         break;
1340     }
1341 }
1342 
generate_exception_err(DisasContext * ctx,int excp,int err)1343 void generate_exception_err(DisasContext *ctx, int excp, int err)
1344 {
1345     save_cpu_state(ctx, 1);
1346     gen_helper_raise_exception_err(tcg_env, tcg_constant_i32(excp),
1347                                    tcg_constant_i32(err));
1348     ctx->base.is_jmp = DISAS_NORETURN;
1349 }
1350 
generate_exception(DisasContext * ctx,int excp)1351 void generate_exception(DisasContext *ctx, int excp)
1352 {
1353     gen_helper_raise_exception(tcg_env, tcg_constant_i32(excp));
1354 }
1355 
generate_exception_end(DisasContext * ctx,int excp)1356 void generate_exception_end(DisasContext *ctx, int excp)
1357 {
1358     generate_exception_err(ctx, excp, 0);
1359 }
1360 
generate_exception_break(DisasContext * ctx,int code)1361 void generate_exception_break(DisasContext *ctx, int code)
1362 {
1363 #ifdef CONFIG_USER_ONLY
1364     /* Pass the break code along to cpu_loop. */
1365     tcg_gen_st_i32(tcg_constant_i32(code), tcg_env,
1366                    offsetof(CPUMIPSState, error_code));
1367 #endif
1368     generate_exception_end(ctx, EXCP_BREAK);
1369 }
1370 
gen_reserved_instruction(DisasContext * ctx)1371 void gen_reserved_instruction(DisasContext *ctx)
1372 {
1373     generate_exception_end(ctx, EXCP_RI);
1374 }
1375 
1376 /* Floating point register moves. */
gen_load_fpr32(DisasContext * ctx,TCGv_i32 t,int reg)1377 void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1378 {
1379     if (ctx->hflags & MIPS_HFLAG_FRE) {
1380         generate_exception(ctx, EXCP_RI);
1381     }
1382     tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
1383 }
1384 
gen_store_fpr32(DisasContext * ctx,TCGv_i32 t,int reg)1385 void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1386 {
1387     TCGv_i64 t64;
1388     if (ctx->hflags & MIPS_HFLAG_FRE) {
1389         generate_exception(ctx, EXCP_RI);
1390     }
1391     t64 = tcg_temp_new_i64();
1392     tcg_gen_extu_i32_i64(t64, t);
1393     tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1394 }
1395 
gen_load_fpr32h(DisasContext * ctx,TCGv_i32 t,int reg)1396 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1397 {
1398     if (ctx->hflags & MIPS_HFLAG_F64) {
1399         tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
1400     } else {
1401         gen_load_fpr32(ctx, t, reg | 1);
1402     }
1403 }
1404 
gen_store_fpr32h(DisasContext * ctx,TCGv_i32 t,int reg)1405 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1406 {
1407     if (ctx->hflags & MIPS_HFLAG_F64) {
1408         TCGv_i64 t64 = tcg_temp_new_i64();
1409         tcg_gen_extu_i32_i64(t64, t);
1410         tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1411     } else {
1412         gen_store_fpr32(ctx, t, reg | 1);
1413     }
1414 }
1415 
gen_load_fpr64(DisasContext * ctx,TCGv_i64 t,int reg)1416 void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1417 {
1418     if (ctx->hflags & MIPS_HFLAG_F64) {
1419         tcg_gen_mov_i64(t, fpu_f64[reg]);
1420     } else {
1421         tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1422     }
1423 }
1424 
gen_store_fpr64(DisasContext * ctx,TCGv_i64 t,int reg)1425 void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1426 {
1427     if (ctx->hflags & MIPS_HFLAG_F64) {
1428         tcg_gen_mov_i64(fpu_f64[reg], t);
1429     } else {
1430         TCGv_i64 t0;
1431         tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1432         t0 = tcg_temp_new_i64();
1433         tcg_gen_shri_i64(t0, t, 32);
1434         tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1435     }
1436 }
1437 
get_fp_bit(int cc)1438 int get_fp_bit(int cc)
1439 {
1440     if (cc) {
1441         return 24 + cc;
1442     } else {
1443         return 23;
1444     }
1445 }
1446 
1447 /* Addresses computation */
gen_op_addr_add(DisasContext * ctx,TCGv ret,TCGv arg0,TCGv arg1)1448 void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1449 {
1450     tcg_gen_add_tl(ret, arg0, arg1);
1451 
1452 #if defined(TARGET_MIPS64)
1453     if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1454         tcg_gen_ext32s_i64(ret, ret);
1455     }
1456 #endif
1457 }
1458 
gen_op_addr_addi(DisasContext * ctx,TCGv ret,TCGv base,target_long ofs)1459 static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
1460                                     target_long ofs)
1461 {
1462     tcg_gen_addi_tl(ret, base, ofs);
1463 
1464 #if defined(TARGET_MIPS64)
1465     if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1466         tcg_gen_ext32s_i64(ret, ret);
1467     }
1468 #endif
1469 }
1470 
1471 /* Addresses computation (translation time) */
addr_add(DisasContext * ctx,target_long base,target_long offset)1472 static target_long addr_add(DisasContext *ctx, target_long base,
1473                             target_long offset)
1474 {
1475     target_long sum = base + offset;
1476 
1477 #if defined(TARGET_MIPS64)
1478     if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1479         sum = (int32_t)sum;
1480     }
1481 #endif
1482     return sum;
1483 }
1484 
1485 /* Sign-extract the low 32-bits to a target_long.  */
gen_move_low32(TCGv ret,TCGv_i64 arg)1486 void gen_move_low32(TCGv ret, TCGv_i64 arg)
1487 {
1488 #if defined(TARGET_MIPS64)
1489     tcg_gen_ext32s_i64(ret, arg);
1490 #else
1491     tcg_gen_extrl_i64_i32(ret, arg);
1492 #endif
1493 }
1494 
1495 /* Sign-extract the high 32-bits to a target_long.  */
gen_move_high32(TCGv ret,TCGv_i64 arg)1496 void gen_move_high32(TCGv ret, TCGv_i64 arg)
1497 {
1498 #if defined(TARGET_MIPS64)
1499     tcg_gen_sari_i64(ret, arg, 32);
1500 #else
1501     tcg_gen_extrh_i64_i32(ret, arg);
1502 #endif
1503 }
1504 
check_cp0_enabled(DisasContext * ctx)1505 bool check_cp0_enabled(DisasContext *ctx)
1506 {
1507     if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
1508         generate_exception_end(ctx, EXCP_CpU);
1509         return false;
1510     }
1511     return true;
1512 }
1513 
check_cp1_enabled(DisasContext * ctx)1514 void check_cp1_enabled(DisasContext *ctx)
1515 {
1516     if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) {
1517         generate_exception_err(ctx, EXCP_CpU, 1);
1518     }
1519 }
1520 
1521 /*
1522  * Verify that the processor is running with COP1X instructions enabled.
1523  * This is associated with the nabla symbol in the MIPS32 and MIPS64
1524  * opcode tables.
1525  */
check_cop1x(DisasContext * ctx)1526 void check_cop1x(DisasContext *ctx)
1527 {
1528     if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) {
1529         gen_reserved_instruction(ctx);
1530     }
1531 }
1532 
1533 /*
1534  * Verify that the processor is running with 64-bit floating-point
1535  * operations enabled.
1536  */
check_cp1_64bitmode(DisasContext * ctx)1537 void check_cp1_64bitmode(DisasContext *ctx)
1538 {
1539     if (unlikely(~ctx->hflags & MIPS_HFLAG_F64)) {
1540         gen_reserved_instruction(ctx);
1541     }
1542 }
1543 
1544 /*
1545  * Verify if floating point register is valid; an operation is not defined
1546  * if bit 0 of any register specification is set and the FR bit in the
1547  * Status register equals zero, since the register numbers specify an
1548  * even-odd pair of adjacent coprocessor general registers. When the FR bit
1549  * in the Status register equals one, both even and odd register numbers
1550  * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1551  *
1552  * Multiple 64 bit wide registers can be checked by calling
1553  * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1554  */
check_cp1_registers(DisasContext * ctx,int regs)1555 void check_cp1_registers(DisasContext *ctx, int regs)
1556 {
1557     if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) {
1558         gen_reserved_instruction(ctx);
1559     }
1560 }
1561 
1562 /*
1563  * Verify that the processor is running with DSP instructions enabled.
1564  * This is enabled by CP0 Status register MX(24) bit.
1565  */
check_dsp(DisasContext * ctx)1566 static inline void check_dsp(DisasContext *ctx)
1567 {
1568     if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1569         if (ctx->insn_flags & ASE_DSP) {
1570             generate_exception_end(ctx, EXCP_DSPDIS);
1571         } else {
1572             gen_reserved_instruction(ctx);
1573         }
1574     }
1575 }
1576 
check_dsp_r2(DisasContext * ctx)1577 static inline void check_dsp_r2(DisasContext *ctx)
1578 {
1579     if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
1580         if (ctx->insn_flags & ASE_DSP) {
1581             generate_exception_end(ctx, EXCP_DSPDIS);
1582         } else {
1583             gen_reserved_instruction(ctx);
1584         }
1585     }
1586 }
1587 
check_dsp_r3(DisasContext * ctx)1588 static inline void check_dsp_r3(DisasContext *ctx)
1589 {
1590     if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
1591         if (ctx->insn_flags & ASE_DSP) {
1592             generate_exception_end(ctx, EXCP_DSPDIS);
1593         } else {
1594             gen_reserved_instruction(ctx);
1595         }
1596     }
1597 }
1598 
1599 /*
1600  * This code generates a "reserved instruction" exception if the
1601  * CPU does not support the instruction set corresponding to flags.
1602  */
check_insn(DisasContext * ctx,uint64_t flags)1603 void check_insn(DisasContext *ctx, uint64_t flags)
1604 {
1605     if (unlikely(!(ctx->insn_flags & flags))) {
1606         gen_reserved_instruction(ctx);
1607     }
1608 }
1609 
1610 /*
1611  * This code generates a "reserved instruction" exception if the
1612  * CPU has corresponding flag set which indicates that the instruction
1613  * has been removed.
1614  */
check_insn_opc_removed(DisasContext * ctx,uint64_t flags)1615 static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
1616 {
1617     if (unlikely(ctx->insn_flags & flags)) {
1618         gen_reserved_instruction(ctx);
1619     }
1620 }
1621 
1622 /*
1623  * The Linux kernel traps certain reserved instruction exceptions to
1624  * emulate the corresponding instructions. QEMU is the kernel in user
1625  * mode, so those traps are emulated by accepting the instructions.
1626  *
1627  * A reserved instruction exception is generated for flagged CPUs if
1628  * QEMU runs in system mode.
1629  */
check_insn_opc_user_only(DisasContext * ctx,uint64_t flags)1630 static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
1631 {
1632 #ifndef CONFIG_USER_ONLY
1633     check_insn_opc_removed(ctx, flags);
1634 #endif
1635 }
1636 
1637 /*
1638  * This code generates a "reserved instruction" exception if the
1639  * CPU does not support 64-bit paired-single (PS) floating point data type.
1640  */
check_ps(DisasContext * ctx)1641 static inline void check_ps(DisasContext *ctx)
1642 {
1643     if (unlikely(!ctx->ps)) {
1644         generate_exception(ctx, EXCP_RI);
1645     }
1646     check_cp1_64bitmode(ctx);
1647 }
1648 
1649 /*
1650  * This code generates a "reserved instruction" exception if cpu is not
1651  * 64-bit or 64-bit instructions are not enabled.
1652  */
check_mips_64(DisasContext * ctx)1653 void check_mips_64(DisasContext *ctx)
1654 {
1655     if (unlikely((TARGET_LONG_BITS != 64) || !(ctx->hflags & MIPS_HFLAG_64))) {
1656         gen_reserved_instruction(ctx);
1657     }
1658 }
1659 
1660 #ifndef CONFIG_USER_ONLY
check_mvh(DisasContext * ctx)1661 static inline void check_mvh(DisasContext *ctx)
1662 {
1663     if (unlikely(!ctx->mvh)) {
1664         generate_exception(ctx, EXCP_RI);
1665     }
1666 }
1667 #endif
1668 
1669 /*
1670  * This code generates a "reserved instruction" exception if the
1671  * Config5 XNP bit is set.
1672  */
check_xnp(DisasContext * ctx)1673 static inline void check_xnp(DisasContext *ctx)
1674 {
1675     if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
1676         gen_reserved_instruction(ctx);
1677     }
1678 }
1679 
1680 #ifndef CONFIG_USER_ONLY
1681 /*
1682  * This code generates a "reserved instruction" exception if the
1683  * Config3 PW bit is NOT set.
1684  */
check_pw(DisasContext * ctx)1685 static inline void check_pw(DisasContext *ctx)
1686 {
1687     if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
1688         gen_reserved_instruction(ctx);
1689     }
1690 }
1691 #endif
1692 
1693 /*
1694  * This code generates a "reserved instruction" exception if the
1695  * Config3 MT bit is NOT set.
1696  */
check_mt(DisasContext * ctx)1697 static inline void check_mt(DisasContext *ctx)
1698 {
1699     if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
1700         gen_reserved_instruction(ctx);
1701     }
1702 }
1703 
1704 #ifndef CONFIG_USER_ONLY
1705 /*
1706  * This code generates a "coprocessor unusable" exception if CP0 is not
1707  * available, and, if that is not the case, generates a "reserved instruction"
1708  * exception if the Config5 MT bit is NOT set. This is needed for availability
1709  * control of some of MT ASE instructions.
1710  */
check_cp0_mt(DisasContext * ctx)1711 static inline void check_cp0_mt(DisasContext *ctx)
1712 {
1713     if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
1714         generate_exception_end(ctx, EXCP_CpU);
1715     } else {
1716         if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
1717             gen_reserved_instruction(ctx);
1718         }
1719     }
1720 }
1721 #endif
1722 
1723 /*
1724  * This code generates a "reserved instruction" exception if the
1725  * Config5 NMS bit is set.
1726  */
check_nms(DisasContext * ctx)1727 static inline void check_nms(DisasContext *ctx)
1728 {
1729     if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
1730         gen_reserved_instruction(ctx);
1731     }
1732 }
1733 
1734 /*
1735  * This code generates a "reserved instruction" exception if the
1736  * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
1737  * Config2 TL, and Config5 L2C are unset.
1738  */
check_nms_dl_il_sl_tl_l2c(DisasContext * ctx)1739 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
1740 {
1741     if (unlikely((ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
1742                  !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
1743                  !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
1744                  !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
1745                  !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
1746                  !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))) {
1747         gen_reserved_instruction(ctx);
1748     }
1749 }
1750 
1751 /*
1752  * This code generates a "reserved instruction" exception if the
1753  * Config5 EVA bit is NOT set.
1754  */
check_eva(DisasContext * ctx)1755 static inline void check_eva(DisasContext *ctx)
1756 {
1757     if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
1758         gen_reserved_instruction(ctx);
1759     }
1760 }
1761 
1762 
1763 /*
1764  * Define small wrappers for gen_load_fpr* so that we have a uniform
1765  * calling interface for 32 and 64-bit FPRs.  No sense in changing
1766  * all callers for gen_load_fpr32 when we need the CTX parameter for
1767  * this one use.
1768  */
1769 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
1770 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1771 #define FOP_CONDS(type, abs, fmt, ifmt, bits)                                 \
1772 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
1773                                                int ft, int fs, int cc)        \
1774 {                                                                             \
1775     TCGv_i##bits fp0 = tcg_temp_new_i##bits();                                \
1776     TCGv_i##bits fp1 = tcg_temp_new_i##bits();                                \
1777     switch (ifmt) {                                                           \
1778     case FMT_PS:                                                              \
1779         check_ps(ctx);                                                        \
1780         break;                                                                \
1781     case FMT_D:                                                               \
1782         if (abs) {                                                            \
1783             check_cop1x(ctx);                                                 \
1784         }                                                                     \
1785         check_cp1_registers(ctx, fs | ft);                                    \
1786         break;                                                                \
1787     case FMT_S:                                                               \
1788         if (abs) {                                                            \
1789             check_cop1x(ctx);                                                 \
1790         }                                                                     \
1791         break;                                                                \
1792     }                                                                         \
1793     gen_ldcmp_fpr##bits(ctx, fp0, fs);                                        \
1794     gen_ldcmp_fpr##bits(ctx, fp1, ft);                                        \
1795     switch (n) {                                                              \
1796     case  0:                                                                  \
1797         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc);         \
1798     break;                                                                    \
1799     case  1:                                                                  \
1800         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc);        \
1801     break;                                                                    \
1802     case  2:                                                                  \
1803         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc);        \
1804     break;                                                                    \
1805     case  3:                                                                  \
1806         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc);       \
1807     break;                                                                    \
1808     case  4:                                                                  \
1809         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc);       \
1810     break;                                                                    \
1811     case  5:                                                                  \
1812         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc);       \
1813     break;                                                                    \
1814     case  6:                                                                  \
1815         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc);       \
1816     break;                                                                    \
1817     case  7:                                                                  \
1818         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc);       \
1819     break;                                                                    \
1820     case  8:                                                                  \
1821         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc);        \
1822     break;                                                                    \
1823     case  9:                                                                  \
1824         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc);      \
1825     break;                                                                    \
1826     case 10:                                                                  \
1827         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc);       \
1828     break;                                                                    \
1829     case 11:                                                                  \
1830         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc);       \
1831     break;                                                                    \
1832     case 12:                                                                  \
1833         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc);        \
1834     break;                                                                    \
1835     case 13:                                                                  \
1836         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc);       \
1837     break;                                                                    \
1838     case 14:                                                                  \
1839         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc);        \
1840     break;                                                                    \
1841     case 15:                                                                  \
1842         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc);       \
1843     break;                                                                    \
1844     default:                                                                  \
1845         abort();                                                              \
1846     }                                                                         \
1847 }
1848 
1849 FOP_CONDS(, 0, d, FMT_D, 64)
1850 FOP_CONDS(abs, 1, d, FMT_D, 64)
1851 FOP_CONDS(, 0, s, FMT_S, 32)
1852 FOP_CONDS(abs, 1, s, FMT_S, 32)
1853 FOP_CONDS(, 0, ps, FMT_PS, 64)
1854 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1855 #undef FOP_CONDS
1856 
1857 #define FOP_CONDNS(fmt, ifmt, bits, STORE)                              \
1858 static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n,         \
1859                                       int ft, int fs, int fd)           \
1860 {                                                                       \
1861     TCGv_i ## bits fp0 = tcg_temp_new_i ## bits();                      \
1862     TCGv_i ## bits fp1 = tcg_temp_new_i ## bits();                      \
1863     if (ifmt == FMT_D) {                                                \
1864         check_cp1_registers(ctx, fs | ft | fd);                         \
1865     }                                                                   \
1866     gen_ldcmp_fpr ## bits(ctx, fp0, fs);                                \
1867     gen_ldcmp_fpr ## bits(ctx, fp1, ft);                                \
1868     switch (n) {                                                        \
1869     case  0:                                                            \
1870         gen_helper_r6_cmp_ ## fmt ## _af(fp0, tcg_env, fp0, fp1);       \
1871         break;                                                          \
1872     case  1:                                                            \
1873         gen_helper_r6_cmp_ ## fmt ## _un(fp0, tcg_env, fp0, fp1);       \
1874         break;                                                          \
1875     case  2:                                                            \
1876         gen_helper_r6_cmp_ ## fmt ## _eq(fp0, tcg_env, fp0, fp1);       \
1877         break;                                                          \
1878     case  3:                                                            \
1879         gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, tcg_env, fp0, fp1);      \
1880         break;                                                          \
1881     case  4:                                                            \
1882         gen_helper_r6_cmp_ ## fmt ## _lt(fp0, tcg_env, fp0, fp1);       \
1883         break;                                                          \
1884     case  5:                                                            \
1885         gen_helper_r6_cmp_ ## fmt ## _ult(fp0, tcg_env, fp0, fp1);      \
1886         break;                                                          \
1887     case  6:                                                            \
1888         gen_helper_r6_cmp_ ## fmt ## _le(fp0, tcg_env, fp0, fp1);       \
1889         break;                                                          \
1890     case  7:                                                            \
1891         gen_helper_r6_cmp_ ## fmt ## _ule(fp0, tcg_env, fp0, fp1);      \
1892         break;                                                          \
1893     case  8:                                                            \
1894         gen_helper_r6_cmp_ ## fmt ## _saf(fp0, tcg_env, fp0, fp1);      \
1895         break;                                                          \
1896     case  9:                                                            \
1897         gen_helper_r6_cmp_ ## fmt ## _sun(fp0, tcg_env, fp0, fp1);      \
1898         break;                                                          \
1899     case 10:                                                            \
1900         gen_helper_r6_cmp_ ## fmt ## _seq(fp0, tcg_env, fp0, fp1);      \
1901         break;                                                          \
1902     case 11:                                                            \
1903         gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, tcg_env, fp0, fp1);     \
1904         break;                                                          \
1905     case 12:                                                            \
1906         gen_helper_r6_cmp_ ## fmt ## _slt(fp0, tcg_env, fp0, fp1);      \
1907         break;                                                          \
1908     case 13:                                                            \
1909         gen_helper_r6_cmp_ ## fmt ## _sult(fp0, tcg_env, fp0, fp1);     \
1910         break;                                                          \
1911     case 14:                                                            \
1912         gen_helper_r6_cmp_ ## fmt ## _sle(fp0, tcg_env, fp0, fp1);      \
1913         break;                                                          \
1914     case 15:                                                            \
1915         gen_helper_r6_cmp_ ## fmt ## _sule(fp0, tcg_env, fp0, fp1);     \
1916         break;                                                          \
1917     case 17:                                                            \
1918         gen_helper_r6_cmp_ ## fmt ## _or(fp0, tcg_env, fp0, fp1);       \
1919         break;                                                          \
1920     case 18:                                                            \
1921         gen_helper_r6_cmp_ ## fmt ## _une(fp0, tcg_env, fp0, fp1);      \
1922         break;                                                          \
1923     case 19:                                                            \
1924         gen_helper_r6_cmp_ ## fmt ## _ne(fp0, tcg_env, fp0, fp1);       \
1925         break;                                                          \
1926     case 25:                                                            \
1927         gen_helper_r6_cmp_ ## fmt ## _sor(fp0, tcg_env, fp0, fp1);      \
1928         break;                                                          \
1929     case 26:                                                            \
1930         gen_helper_r6_cmp_ ## fmt ## _sune(fp0, tcg_env, fp0, fp1);     \
1931         break;                                                          \
1932     case 27:                                                            \
1933         gen_helper_r6_cmp_ ## fmt ## _sne(fp0, tcg_env, fp0, fp1);      \
1934         break;                                                          \
1935     default:                                                            \
1936         abort();                                                        \
1937     }                                                                   \
1938     STORE;                                                              \
1939 }
1940 
1941 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
1942 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
1943 #undef FOP_CONDNS
1944 #undef gen_ldcmp_fpr32
1945 #undef gen_ldcmp_fpr64
1946 
1947 /* load/store instructions. */
1948 #ifdef CONFIG_USER_ONLY
1949 #define OP_LD_ATOMIC(insn, memop)                                          \
1950 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
1951                                 DisasContext *ctx)                         \
1952 {                                                                          \
1953     TCGv t0 = tcg_temp_new();                                              \
1954     tcg_gen_mov_tl(t0, arg1);                                              \
1955     tcg_gen_qemu_ld_tl(ret, arg1, ctx->mem_idx, memop);                    \
1956     tcg_gen_st_tl(t0, tcg_env, offsetof(CPUMIPSState, lladdr));            \
1957     tcg_gen_st_tl(ret, tcg_env, offsetof(CPUMIPSState, llval));            \
1958 }
1959 #else
1960 #define OP_LD_ATOMIC(insn, fname)                                          \
1961 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
1962                                 DisasContext *ctx)                         \
1963 {                                                                          \
1964     gen_helper_##insn(ret, tcg_env, arg1, tcg_constant_i32(mem_idx));      \
1965 }
1966 #endif
1967 OP_LD_ATOMIC(ll, MO_TESL);
1968 #if defined(TARGET_MIPS64)
1969 OP_LD_ATOMIC(lld, MO_TEUQ);
1970 #endif
1971 #undef OP_LD_ATOMIC
1972 
gen_base_offset_addr(DisasContext * ctx,TCGv addr,int base,int offset)1973 void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset)
1974 {
1975     if (base == 0) {
1976         tcg_gen_movi_tl(addr, offset);
1977     } else if (offset == 0) {
1978         gen_load_gpr(addr, base);
1979     } else {
1980         tcg_gen_movi_tl(addr, offset);
1981         gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1982     }
1983 }
1984 
pc_relative_pc(DisasContext * ctx)1985 static target_ulong pc_relative_pc(DisasContext *ctx)
1986 {
1987     target_ulong pc = ctx->base.pc_next;
1988 
1989     if (ctx->hflags & MIPS_HFLAG_BMASK) {
1990         int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1991 
1992         pc -= branch_bytes;
1993     }
1994 
1995     pc &= ~(target_ulong)3;
1996     return pc;
1997 }
1998 
1999 /* LWL or LDL, depending on MemOp. */
gen_lxl(DisasContext * ctx,TCGv reg,TCGv addr,int mem_idx,MemOp mop)2000 static void gen_lxl(DisasContext *ctx, TCGv reg, TCGv addr,
2001                      int mem_idx, MemOp mop)
2002 {
2003     int sizem1 = memop_size(mop) - 1;
2004     TCGv t0 = tcg_temp_new();
2005     TCGv t1 = tcg_temp_new();
2006 
2007     /*
2008      * Do a byte access to possibly trigger a page
2009      * fault with the unaligned address.
2010      */
2011     tcg_gen_qemu_ld_tl(t1, addr, mem_idx, MO_UB);
2012     tcg_gen_andi_tl(t1, addr, sizem1);
2013     if (!cpu_is_bigendian(ctx)) {
2014         tcg_gen_xori_tl(t1, t1, sizem1);
2015     }
2016     tcg_gen_shli_tl(t1, t1, 3);
2017     tcg_gen_andi_tl(t0, addr, ~sizem1);
2018     tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mop);
2019     tcg_gen_shl_tl(t0, t0, t1);
2020     tcg_gen_shl_tl(t1, tcg_constant_tl(-1), t1);
2021     tcg_gen_andc_tl(t1, reg, t1);
2022     tcg_gen_or_tl(reg, t0, t1);
2023 }
2024 
2025 /* LWR or LDR, depending on MemOp. */
gen_lxr(DisasContext * ctx,TCGv reg,TCGv addr,int mem_idx,MemOp mop)2026 static void gen_lxr(DisasContext *ctx, TCGv reg, TCGv addr,
2027                      int mem_idx, MemOp mop)
2028 {
2029     int size = memop_size(mop);
2030     int sizem1 = size - 1;
2031     TCGv t0 = tcg_temp_new();
2032     TCGv t1 = tcg_temp_new();
2033 
2034     /*
2035      * Do a byte access to possibly trigger a page
2036      * fault with the unaligned address.
2037      */
2038     tcg_gen_qemu_ld_tl(t1, addr, mem_idx, MO_UB);
2039     tcg_gen_andi_tl(t1, addr, sizem1);
2040     if (cpu_is_bigendian(ctx)) {
2041         tcg_gen_xori_tl(t1, t1, sizem1);
2042     }
2043     tcg_gen_shli_tl(t1, t1, 3);
2044     tcg_gen_andi_tl(t0, addr, ~sizem1);
2045     tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mop);
2046     tcg_gen_shr_tl(t0, t0, t1);
2047     tcg_gen_xori_tl(t1, t1, size * 8 - 1);
2048     tcg_gen_shl_tl(t1, tcg_constant_tl(~1), t1);
2049     tcg_gen_and_tl(t1, reg, t1);
2050     tcg_gen_or_tl(reg, t0, t1);
2051 }
2052 
2053 /* Load */
gen_ld(DisasContext * ctx,uint32_t opc,int rt,int base,int offset)2054 static void gen_ld(DisasContext *ctx, uint32_t opc,
2055                    int rt, int base, int offset)
2056 {
2057     TCGv t0, t1;
2058     int mem_idx = ctx->mem_idx;
2059 
2060     if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F |
2061                                       INSN_LOONGSON3A)) {
2062         /*
2063          * Loongson CPU uses a load to zero register for prefetch.
2064          * We emulate it as a NOP. On other CPU we must perform the
2065          * actual memory access.
2066          */
2067         return;
2068     }
2069 
2070     t0 = tcg_temp_new();
2071     gen_base_offset_addr(ctx, t0, base, offset);
2072 
2073     switch (opc) {
2074 #if defined(TARGET_MIPS64)
2075     case OPC_LWU:
2076         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
2077                            ctx->default_tcg_memop_mask);
2078         gen_store_gpr(t0, rt);
2079         break;
2080     case OPC_LD:
2081         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ |
2082                            ctx->default_tcg_memop_mask);
2083         gen_store_gpr(t0, rt);
2084         break;
2085     case OPC_LLD:
2086     case R6_OPC_LLD:
2087         op_ld_lld(t0, t0, mem_idx, ctx);
2088         gen_store_gpr(t0, rt);
2089         break;
2090     case OPC_LDL:
2091         t1 = tcg_temp_new();
2092         gen_load_gpr(t1, rt);
2093         gen_lxl(ctx, t1, t0, mem_idx, MO_TEUQ);
2094         gen_store_gpr(t1, rt);
2095         break;
2096     case OPC_LDR:
2097         t1 = tcg_temp_new();
2098         gen_load_gpr(t1, rt);
2099         gen_lxr(ctx, t1, t0, mem_idx, MO_TEUQ);
2100         gen_store_gpr(t1, rt);
2101         break;
2102     case OPC_LDPC:
2103         t1 = tcg_constant_tl(pc_relative_pc(ctx));
2104         gen_op_addr_add(ctx, t0, t0, t1);
2105         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ);
2106         gen_store_gpr(t0, rt);
2107         break;
2108 #endif
2109     case OPC_LWPC:
2110         t1 = tcg_constant_tl(pc_relative_pc(ctx));
2111         gen_op_addr_add(ctx, t0, t0, t1);
2112         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
2113         gen_store_gpr(t0, rt);
2114         break;
2115     case OPC_LWE:
2116         mem_idx = MIPS_HFLAG_UM;
2117         /* fall through */
2118     case OPC_LW:
2119         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
2120                            ctx->default_tcg_memop_mask);
2121         gen_store_gpr(t0, rt);
2122         break;
2123     case OPC_LHE:
2124         mem_idx = MIPS_HFLAG_UM;
2125         /* fall through */
2126     case OPC_LH:
2127         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
2128                            ctx->default_tcg_memop_mask);
2129         gen_store_gpr(t0, rt);
2130         break;
2131     case OPC_LHUE:
2132         mem_idx = MIPS_HFLAG_UM;
2133         /* fall through */
2134     case OPC_LHU:
2135         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
2136                            ctx->default_tcg_memop_mask);
2137         gen_store_gpr(t0, rt);
2138         break;
2139     case OPC_LBE:
2140         mem_idx = MIPS_HFLAG_UM;
2141         /* fall through */
2142     case OPC_LB:
2143         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
2144         gen_store_gpr(t0, rt);
2145         break;
2146     case OPC_LBUE:
2147         mem_idx = MIPS_HFLAG_UM;
2148         /* fall through */
2149     case OPC_LBU:
2150         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
2151         gen_store_gpr(t0, rt);
2152         break;
2153     case OPC_LWLE:
2154         mem_idx = MIPS_HFLAG_UM;
2155         /* fall through */
2156     case OPC_LWL:
2157         t1 = tcg_temp_new();
2158         gen_load_gpr(t1, rt);
2159         gen_lxl(ctx, t1, t0, mem_idx, MO_TEUL);
2160         tcg_gen_ext32s_tl(t1, t1);
2161         gen_store_gpr(t1, rt);
2162         break;
2163     case OPC_LWRE:
2164         mem_idx = MIPS_HFLAG_UM;
2165         /* fall through */
2166     case OPC_LWR:
2167         t1 = tcg_temp_new();
2168         gen_load_gpr(t1, rt);
2169         gen_lxr(ctx, t1, t0, mem_idx, MO_TEUL);
2170         tcg_gen_ext32s_tl(t1, t1);
2171         gen_store_gpr(t1, rt);
2172         break;
2173     case OPC_LLE:
2174         mem_idx = MIPS_HFLAG_UM;
2175         /* fall through */
2176     case OPC_LL:
2177     case R6_OPC_LL:
2178         op_ld_ll(t0, t0, mem_idx, ctx);
2179         gen_store_gpr(t0, rt);
2180         break;
2181     }
2182 }
2183 
2184 /* Store */
gen_st(DisasContext * ctx,uint32_t opc,int rt,int base,int offset)2185 static void gen_st(DisasContext *ctx, uint32_t opc, int rt,
2186                    int base, int offset)
2187 {
2188     TCGv t0 = tcg_temp_new();
2189     TCGv t1 = tcg_temp_new();
2190     int mem_idx = ctx->mem_idx;
2191 
2192     gen_base_offset_addr(ctx, t0, base, offset);
2193     gen_load_gpr(t1, rt);
2194     switch (opc) {
2195 #if defined(TARGET_MIPS64)
2196     case OPC_SD:
2197         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUQ |
2198                            ctx->default_tcg_memop_mask);
2199         break;
2200     case OPC_SDL:
2201         gen_helper_0e2i(sdl, t1, t0, mem_idx);
2202         break;
2203     case OPC_SDR:
2204         gen_helper_0e2i(sdr, t1, t0, mem_idx);
2205         break;
2206 #endif
2207     case OPC_SWE:
2208         mem_idx = MIPS_HFLAG_UM;
2209         /* fall through */
2210     case OPC_SW:
2211         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
2212                            ctx->default_tcg_memop_mask);
2213         break;
2214     case OPC_SHE:
2215         mem_idx = MIPS_HFLAG_UM;
2216         /* fall through */
2217     case OPC_SH:
2218         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
2219                            ctx->default_tcg_memop_mask);
2220         break;
2221     case OPC_SBE:
2222         mem_idx = MIPS_HFLAG_UM;
2223         /* fall through */
2224     case OPC_SB:
2225         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
2226         break;
2227     case OPC_SWLE:
2228         mem_idx = MIPS_HFLAG_UM;
2229         /* fall through */
2230     case OPC_SWL:
2231         gen_helper_0e2i(swl, t1, t0, mem_idx);
2232         break;
2233     case OPC_SWRE:
2234         mem_idx = MIPS_HFLAG_UM;
2235         /* fall through */
2236     case OPC_SWR:
2237         gen_helper_0e2i(swr, t1, t0, mem_idx);
2238         break;
2239     }
2240 }
2241 
2242 
2243 /* Store conditional */
gen_st_cond(DisasContext * ctx,int rt,int base,int offset,MemOp tcg_mo,bool eva)2244 static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset,
2245                         MemOp tcg_mo, bool eva)
2246 {
2247     TCGv addr, t0, val;
2248     TCGLabel *l1 = gen_new_label();
2249     TCGLabel *done = gen_new_label();
2250 
2251     t0 = tcg_temp_new();
2252     addr = tcg_temp_new();
2253     /* compare the address against that of the preceding LL */
2254     gen_base_offset_addr(ctx, addr, base, offset);
2255     tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1);
2256     tcg_gen_movi_tl(t0, 0);
2257     gen_store_gpr(t0, rt);
2258     tcg_gen_br(done);
2259 
2260     gen_set_label(l1);
2261     /* generate cmpxchg */
2262     val = tcg_temp_new();
2263     gen_load_gpr(val, rt);
2264     tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val,
2265                               eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo);
2266     tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval);
2267     gen_store_gpr(t0, rt);
2268 
2269     gen_set_label(done);
2270 }
2271 
2272 /* Load and store */
gen_flt_ldst(DisasContext * ctx,uint32_t opc,int ft,TCGv t0)2273 static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft,
2274                          TCGv t0)
2275 {
2276     /*
2277      * Don't do NOP if destination is zero: we must perform the actual
2278      * memory access.
2279      */
2280     switch (opc) {
2281     case OPC_LWC1:
2282         {
2283             TCGv_i32 fp0 = tcg_temp_new_i32();
2284             tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2285                                 ctx->default_tcg_memop_mask);
2286             gen_store_fpr32(ctx, fp0, ft);
2287         }
2288         break;
2289     case OPC_SWC1:
2290         {
2291             TCGv_i32 fp0 = tcg_temp_new_i32();
2292             gen_load_fpr32(ctx, fp0, ft);
2293             tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2294                                 ctx->default_tcg_memop_mask);
2295         }
2296         break;
2297     case OPC_LDC1:
2298         {
2299             TCGv_i64 fp0 = tcg_temp_new_i64();
2300             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEUQ |
2301                                 ctx->default_tcg_memop_mask);
2302             gen_store_fpr64(ctx, fp0, ft);
2303         }
2304         break;
2305     case OPC_SDC1:
2306         {
2307             TCGv_i64 fp0 = tcg_temp_new_i64();
2308             gen_load_fpr64(ctx, fp0, ft);
2309             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEUQ |
2310                                 ctx->default_tcg_memop_mask);
2311         }
2312         break;
2313     default:
2314         MIPS_INVAL("flt_ldst");
2315         gen_reserved_instruction(ctx);
2316         break;
2317     }
2318 }
2319 
gen_cop1_ldst(DisasContext * ctx,uint32_t op,int rt,int rs,int16_t imm)2320 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2321                           int rs, int16_t imm)
2322 {
2323     TCGv t0 = tcg_temp_new();
2324 
2325     if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
2326         check_cp1_enabled(ctx);
2327         switch (op) {
2328         case OPC_LDC1:
2329         case OPC_SDC1:
2330             check_insn(ctx, ISA_MIPS2);
2331             /* Fallthrough */
2332         default:
2333             gen_base_offset_addr(ctx, t0, rs, imm);
2334             gen_flt_ldst(ctx, op, rt, t0);
2335         }
2336     } else {
2337         generate_exception_err(ctx, EXCP_CpU, 1);
2338     }
2339 }
2340 
2341 /* Arithmetic with immediate operand */
gen_arith_imm(DisasContext * ctx,uint32_t opc,int rt,int rs,int imm)2342 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2343                           int rt, int rs, int imm)
2344 {
2345     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2346 
2347     if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
2348         /*
2349          * If no destination, treat it as a NOP.
2350          * For addi, we must generate the overflow exception when needed.
2351          */
2352         return;
2353     }
2354     switch (opc) {
2355     case OPC_ADDI:
2356         {
2357             TCGv t0 = tcg_temp_new();
2358             TCGv t1 = tcg_temp_new();
2359             TCGv t2 = tcg_temp_new();
2360             TCGLabel *l1 = gen_new_label();
2361 
2362             gen_load_gpr(t1, rs);
2363             tcg_gen_addi_tl(t0, t1, uimm);
2364             tcg_gen_ext32s_tl(t0, t0);
2365 
2366             tcg_gen_xori_tl(t1, t1, ~uimm);
2367             tcg_gen_xori_tl(t2, t0, uimm);
2368             tcg_gen_and_tl(t1, t1, t2);
2369             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2370             /* operands of same sign, result different sign */
2371             generate_exception(ctx, EXCP_OVERFLOW);
2372             gen_set_label(l1);
2373             tcg_gen_ext32s_tl(t0, t0);
2374             gen_store_gpr(t0, rt);
2375         }
2376         break;
2377     case OPC_ADDIU:
2378         if (rs != 0) {
2379             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2380             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2381         } else {
2382             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2383         }
2384         break;
2385 #if defined(TARGET_MIPS64)
2386     case OPC_DADDI:
2387         {
2388             TCGv t0 = tcg_temp_new();
2389             TCGv t1 = tcg_temp_new();
2390             TCGv t2 = tcg_temp_new();
2391             TCGLabel *l1 = gen_new_label();
2392 
2393             gen_load_gpr(t1, rs);
2394             tcg_gen_addi_tl(t0, t1, uimm);
2395 
2396             tcg_gen_xori_tl(t1, t1, ~uimm);
2397             tcg_gen_xori_tl(t2, t0, uimm);
2398             tcg_gen_and_tl(t1, t1, t2);
2399             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2400             /* operands of same sign, result different sign */
2401             generate_exception(ctx, EXCP_OVERFLOW);
2402             gen_set_label(l1);
2403             gen_store_gpr(t0, rt);
2404         }
2405         break;
2406     case OPC_DADDIU:
2407         if (rs != 0) {
2408             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2409         } else {
2410             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2411         }
2412         break;
2413 #endif
2414     }
2415 }
2416 
2417 /* Logic with immediate operand */
gen_logic_imm(DisasContext * ctx,uint32_t opc,int rt,int rs,int16_t imm)2418 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2419                           int rt, int rs, int16_t imm)
2420 {
2421     target_ulong uimm;
2422 
2423     if (rt == 0) {
2424         /* If no destination, treat it as a NOP. */
2425         return;
2426     }
2427     uimm = (uint16_t)imm;
2428     switch (opc) {
2429     case OPC_ANDI:
2430         if (likely(rs != 0)) {
2431             tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2432         } else {
2433             tcg_gen_movi_tl(cpu_gpr[rt], 0);
2434         }
2435         break;
2436     case OPC_ORI:
2437         if (rs != 0) {
2438             tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2439         } else {
2440             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2441         }
2442         break;
2443     case OPC_XORI:
2444         if (likely(rs != 0)) {
2445             tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2446         } else {
2447             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2448         }
2449         break;
2450     case OPC_LUI:
2451         if (rs != 0 && (ctx->insn_flags & ISA_MIPS_R6)) {
2452             /* OPC_AUI */
2453             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2454             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2455         } else {
2456             tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2457         }
2458         break;
2459 
2460     default:
2461         break;
2462     }
2463 }
2464 
2465 /* Set on less than with immediate operand */
gen_slt_imm(DisasContext * ctx,uint32_t opc,int rt,int rs,int16_t imm)2466 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2467                         int rt, int rs, int16_t imm)
2468 {
2469     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2470     TCGv t0;
2471 
2472     if (rt == 0) {
2473         /* If no destination, treat it as a NOP. */
2474         return;
2475     }
2476     t0 = tcg_temp_new();
2477     gen_load_gpr(t0, rs);
2478     switch (opc) {
2479     case OPC_SLTI:
2480         tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2481         break;
2482     case OPC_SLTIU:
2483         tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2484         break;
2485     }
2486 }
2487 
2488 /* Shifts with immediate operand */
gen_shift_imm(DisasContext * ctx,uint32_t opc,int rt,int rs,int16_t imm)2489 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2490                           int rt, int rs, int16_t imm)
2491 {
2492     target_ulong uimm = ((uint16_t)imm) & 0x1f;
2493     TCGv t0;
2494 
2495     if (rt == 0) {
2496         /* If no destination, treat it as a NOP. */
2497         return;
2498     }
2499 
2500     t0 = tcg_temp_new();
2501     gen_load_gpr(t0, rs);
2502     switch (opc) {
2503     case OPC_SLL:
2504         tcg_gen_shli_tl(t0, t0, uimm);
2505         tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2506         break;
2507     case OPC_SRA:
2508         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2509         break;
2510     case OPC_SRL:
2511         if (uimm != 0) {
2512             tcg_gen_ext32u_tl(t0, t0);
2513             tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2514         } else {
2515             tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2516         }
2517         break;
2518     case OPC_ROTR:
2519         if (uimm != 0) {
2520             TCGv_i32 t1 = tcg_temp_new_i32();
2521 
2522             tcg_gen_trunc_tl_i32(t1, t0);
2523             tcg_gen_rotri_i32(t1, t1, uimm);
2524             tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2525         } else {
2526             tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2527         }
2528         break;
2529 #if defined(TARGET_MIPS64)
2530     case OPC_DSLL:
2531         tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2532         break;
2533     case OPC_DSRA:
2534         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2535         break;
2536     case OPC_DSRL:
2537         tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2538         break;
2539     case OPC_DROTR:
2540         if (uimm != 0) {
2541             tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2542         } else {
2543             tcg_gen_mov_tl(cpu_gpr[rt], t0);
2544         }
2545         break;
2546     case OPC_DSLL32:
2547         tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2548         break;
2549     case OPC_DSRA32:
2550         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2551         break;
2552     case OPC_DSRL32:
2553         tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2554         break;
2555     case OPC_DROTR32:
2556         tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2557         break;
2558 #endif
2559     }
2560 }
2561 
2562 /* Arithmetic */
gen_arith(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)2563 static void gen_arith(DisasContext *ctx, uint32_t opc,
2564                       int rd, int rs, int rt)
2565 {
2566     if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2567        && opc != OPC_DADD && opc != OPC_DSUB) {
2568         /*
2569          * If no destination, treat it as a NOP.
2570          * For add & sub, we must generate the overflow exception when needed.
2571          */
2572         return;
2573     }
2574 
2575     switch (opc) {
2576     case OPC_ADD:
2577         {
2578             TCGv t0 = tcg_temp_new();
2579             TCGv t1 = tcg_temp_new();
2580             TCGv t2 = tcg_temp_new();
2581             TCGLabel *l1 = gen_new_label();
2582 
2583             gen_load_gpr(t1, rs);
2584             gen_load_gpr(t2, rt);
2585             tcg_gen_add_tl(t0, t1, t2);
2586             tcg_gen_ext32s_tl(t0, t0);
2587             tcg_gen_xor_tl(t1, t1, t2);
2588             tcg_gen_xor_tl(t2, t0, t2);
2589             tcg_gen_andc_tl(t1, t2, t1);
2590             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2591             /* operands of same sign, result different sign */
2592             generate_exception(ctx, EXCP_OVERFLOW);
2593             gen_set_label(l1);
2594             gen_store_gpr(t0, rd);
2595         }
2596         break;
2597     case OPC_ADDU:
2598         if (rs != 0 && rt != 0) {
2599             tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2600             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2601         } else if (rs == 0 && rt != 0) {
2602             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2603         } else if (rs != 0 && rt == 0) {
2604             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2605         } else {
2606             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2607         }
2608         break;
2609     case OPC_SUB:
2610         {
2611             TCGv t0 = tcg_temp_new();
2612             TCGv t1 = tcg_temp_new();
2613             TCGv t2 = tcg_temp_new();
2614             TCGLabel *l1 = gen_new_label();
2615 
2616             gen_load_gpr(t1, rs);
2617             gen_load_gpr(t2, rt);
2618             tcg_gen_sub_tl(t0, t1, t2);
2619             tcg_gen_ext32s_tl(t0, t0);
2620             tcg_gen_xor_tl(t2, t1, t2);
2621             tcg_gen_xor_tl(t1, t0, t1);
2622             tcg_gen_and_tl(t1, t1, t2);
2623             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2624             /*
2625              * operands of different sign, first operand and the result
2626              * of different sign
2627              */
2628             generate_exception(ctx, EXCP_OVERFLOW);
2629             gen_set_label(l1);
2630             gen_store_gpr(t0, rd);
2631         }
2632         break;
2633     case OPC_SUBU:
2634         if (rs != 0 && rt != 0) {
2635             tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2636             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2637         } else if (rs == 0 && rt != 0) {
2638             tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2639             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2640         } else if (rs != 0 && rt == 0) {
2641             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2642         } else {
2643             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2644         }
2645         break;
2646 #if defined(TARGET_MIPS64)
2647     case OPC_DADD:
2648         {
2649             TCGv t0 = tcg_temp_new();
2650             TCGv t1 = tcg_temp_new();
2651             TCGv t2 = tcg_temp_new();
2652             TCGLabel *l1 = gen_new_label();
2653 
2654             gen_load_gpr(t1, rs);
2655             gen_load_gpr(t2, rt);
2656             tcg_gen_add_tl(t0, t1, t2);
2657             tcg_gen_xor_tl(t1, t1, t2);
2658             tcg_gen_xor_tl(t2, t0, t2);
2659             tcg_gen_andc_tl(t1, t2, t1);
2660             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2661             /* operands of same sign, result different sign */
2662             generate_exception(ctx, EXCP_OVERFLOW);
2663             gen_set_label(l1);
2664             gen_store_gpr(t0, rd);
2665         }
2666         break;
2667     case OPC_DADDU:
2668         if (rs != 0 && rt != 0) {
2669             tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2670         } else if (rs == 0 && rt != 0) {
2671             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2672         } else if (rs != 0 && rt == 0) {
2673             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2674         } else {
2675             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2676         }
2677         break;
2678     case OPC_DSUB:
2679         {
2680             TCGv t0 = tcg_temp_new();
2681             TCGv t1 = tcg_temp_new();
2682             TCGv t2 = tcg_temp_new();
2683             TCGLabel *l1 = gen_new_label();
2684 
2685             gen_load_gpr(t1, rs);
2686             gen_load_gpr(t2, rt);
2687             tcg_gen_sub_tl(t0, t1, t2);
2688             tcg_gen_xor_tl(t2, t1, t2);
2689             tcg_gen_xor_tl(t1, t0, t1);
2690             tcg_gen_and_tl(t1, t1, t2);
2691             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2692             /*
2693              * Operands of different sign, first operand and result different
2694              * sign.
2695              */
2696             generate_exception(ctx, EXCP_OVERFLOW);
2697             gen_set_label(l1);
2698             gen_store_gpr(t0, rd);
2699         }
2700         break;
2701     case OPC_DSUBU:
2702         if (rs != 0 && rt != 0) {
2703             tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2704         } else if (rs == 0 && rt != 0) {
2705             tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2706         } else if (rs != 0 && rt == 0) {
2707             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2708         } else {
2709             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2710         }
2711         break;
2712 #endif
2713     case OPC_MUL:
2714         if (likely(rs != 0 && rt != 0)) {
2715             tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2716             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2717         } else {
2718             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2719         }
2720         break;
2721     }
2722 }
2723 
2724 /* Conditional move */
gen_cond_move(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)2725 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2726                           int rd, int rs, int rt)
2727 {
2728     TCGv t0, t1, t2;
2729 
2730     if (rd == 0) {
2731         /* If no destination, treat it as a NOP. */
2732         return;
2733     }
2734 
2735     t0 = tcg_temp_new();
2736     gen_load_gpr(t0, rt);
2737     t1 = tcg_constant_tl(0);
2738     t2 = tcg_temp_new();
2739     gen_load_gpr(t2, rs);
2740     switch (opc) {
2741     case OPC_MOVN:
2742         tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2743         break;
2744     case OPC_MOVZ:
2745         tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2746         break;
2747     case OPC_SELNEZ:
2748         tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2749         break;
2750     case OPC_SELEQZ:
2751         tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2752         break;
2753     }
2754 }
2755 
2756 /* Logic */
gen_logic(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)2757 static void gen_logic(DisasContext *ctx, uint32_t opc,
2758                       int rd, int rs, int rt)
2759 {
2760     if (rd == 0) {
2761         /* If no destination, treat it as a NOP. */
2762         return;
2763     }
2764 
2765     switch (opc) {
2766     case OPC_AND:
2767         if (likely(rs != 0 && rt != 0)) {
2768             tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2769         } else {
2770             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2771         }
2772         break;
2773     case OPC_NOR:
2774         if (rs != 0 && rt != 0) {
2775             tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2776         } else if (rs == 0 && rt != 0) {
2777             tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2778         } else if (rs != 0 && rt == 0) {
2779             tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2780         } else {
2781             tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2782         }
2783         break;
2784     case OPC_OR:
2785         if (likely(rs != 0 && rt != 0)) {
2786             tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2787         } else if (rs == 0 && rt != 0) {
2788             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2789         } else if (rs != 0 && rt == 0) {
2790             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2791         } else {
2792             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2793         }
2794         break;
2795     case OPC_XOR:
2796         if (likely(rs != 0 && rt != 0)) {
2797             tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2798         } else if (rs == 0 && rt != 0) {
2799             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2800         } else if (rs != 0 && rt == 0) {
2801             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2802         } else {
2803             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2804         }
2805         break;
2806     }
2807 }
2808 
2809 /* Set on lower than */
gen_slt(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)2810 static void gen_slt(DisasContext *ctx, uint32_t opc,
2811                     int rd, int rs, int rt)
2812 {
2813     TCGv t0, t1;
2814 
2815     if (rd == 0) {
2816         /* If no destination, treat it as a NOP. */
2817         return;
2818     }
2819 
2820     t0 = tcg_temp_new();
2821     t1 = tcg_temp_new();
2822     gen_load_gpr(t0, rs);
2823     gen_load_gpr(t1, rt);
2824     switch (opc) {
2825     case OPC_SLT:
2826         tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2827         break;
2828     case OPC_SLTU:
2829         tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2830         break;
2831     }
2832 }
2833 
2834 /* Shifts */
gen_shift(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)2835 static void gen_shift(DisasContext *ctx, uint32_t opc,
2836                       int rd, int rs, int rt)
2837 {
2838     TCGv t0, t1;
2839 
2840     if (rd == 0) {
2841         /*
2842          * If no destination, treat it as a NOP.
2843          * For add & sub, we must generate the overflow exception when needed.
2844          */
2845         return;
2846     }
2847 
2848     t0 = tcg_temp_new();
2849     t1 = tcg_temp_new();
2850     gen_load_gpr(t0, rs);
2851     gen_load_gpr(t1, rt);
2852     switch (opc) {
2853     case OPC_SLLV:
2854         tcg_gen_andi_tl(t0, t0, 0x1f);
2855         tcg_gen_shl_tl(t0, t1, t0);
2856         tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2857         break;
2858     case OPC_SRAV:
2859         tcg_gen_andi_tl(t0, t0, 0x1f);
2860         tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2861         break;
2862     case OPC_SRLV:
2863         tcg_gen_ext32u_tl(t1, t1);
2864         tcg_gen_andi_tl(t0, t0, 0x1f);
2865         tcg_gen_shr_tl(t0, t1, t0);
2866         tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2867         break;
2868     case OPC_ROTRV:
2869         {
2870             TCGv_i32 t2 = tcg_temp_new_i32();
2871             TCGv_i32 t3 = tcg_temp_new_i32();
2872 
2873             tcg_gen_trunc_tl_i32(t2, t0);
2874             tcg_gen_trunc_tl_i32(t3, t1);
2875             tcg_gen_andi_i32(t2, t2, 0x1f);
2876             tcg_gen_rotr_i32(t2, t3, t2);
2877             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2878         }
2879         break;
2880 #if defined(TARGET_MIPS64)
2881     case OPC_DSLLV:
2882         tcg_gen_andi_tl(t0, t0, 0x3f);
2883         tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2884         break;
2885     case OPC_DSRAV:
2886         tcg_gen_andi_tl(t0, t0, 0x3f);
2887         tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2888         break;
2889     case OPC_DSRLV:
2890         tcg_gen_andi_tl(t0, t0, 0x3f);
2891         tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2892         break;
2893     case OPC_DROTRV:
2894         tcg_gen_andi_tl(t0, t0, 0x3f);
2895         tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2896         break;
2897 #endif
2898     }
2899 }
2900 
2901 /* Arithmetic on HI/LO registers */
gen_HILO(DisasContext * ctx,uint32_t opc,int acc,int reg)2902 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
2903 {
2904     if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2905         /* Treat as NOP. */
2906         return;
2907     }
2908 
2909     if (acc != 0) {
2910         check_dsp(ctx);
2911     }
2912 
2913     switch (opc) {
2914     case OPC_MFHI:
2915 #if defined(TARGET_MIPS64)
2916         if (acc != 0) {
2917             tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2918         } else
2919 #endif
2920         {
2921             tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2922         }
2923         break;
2924     case OPC_MFLO:
2925 #if defined(TARGET_MIPS64)
2926         if (acc != 0) {
2927             tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2928         } else
2929 #endif
2930         {
2931             tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2932         }
2933         break;
2934     case OPC_MTHI:
2935         if (reg != 0) {
2936 #if defined(TARGET_MIPS64)
2937             if (acc != 0) {
2938                 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2939             } else
2940 #endif
2941             {
2942                 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2943             }
2944         } else {
2945             tcg_gen_movi_tl(cpu_HI[acc], 0);
2946         }
2947         break;
2948     case OPC_MTLO:
2949         if (reg != 0) {
2950 #if defined(TARGET_MIPS64)
2951             if (acc != 0) {
2952                 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2953             } else
2954 #endif
2955             {
2956                 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2957             }
2958         } else {
2959             tcg_gen_movi_tl(cpu_LO[acc], 0);
2960         }
2961         break;
2962     }
2963 }
2964 
gen_r6_ld(target_long addr,int reg,int memidx,MemOp memop)2965 static inline void gen_r6_ld(target_long addr, int reg, int memidx,
2966                              MemOp memop)
2967 {
2968     TCGv t0 = tcg_temp_new();
2969     tcg_gen_qemu_ld_tl(t0, tcg_constant_tl(addr), memidx, memop);
2970     gen_store_gpr(t0, reg);
2971 }
2972 
gen_pcrel(DisasContext * ctx,int opc,target_ulong pc,int rs)2973 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
2974                              int rs)
2975 {
2976     target_long offset;
2977     target_long addr;
2978 
2979     switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
2980     case OPC_ADDIUPC:
2981         if (rs != 0) {
2982             offset = sextract32(ctx->opcode << 2, 0, 21);
2983             addr = addr_add(ctx, pc, offset);
2984             tcg_gen_movi_tl(cpu_gpr[rs], addr);
2985         }
2986         break;
2987     case R6_OPC_LWPC:
2988         offset = sextract32(ctx->opcode << 2, 0, 21);
2989         addr = addr_add(ctx, pc, offset);
2990         gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
2991         break;
2992 #if defined(TARGET_MIPS64)
2993     case OPC_LWUPC:
2994         check_mips_64(ctx);
2995         offset = sextract32(ctx->opcode << 2, 0, 21);
2996         addr = addr_add(ctx, pc, offset);
2997         gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
2998         break;
2999 #endif
3000     default:
3001         switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
3002         case OPC_AUIPC:
3003             if (rs != 0) {
3004                 offset = sextract32(ctx->opcode, 0, 16) << 16;
3005                 addr = addr_add(ctx, pc, offset);
3006                 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3007             }
3008             break;
3009         case OPC_ALUIPC:
3010             if (rs != 0) {
3011                 offset = sextract32(ctx->opcode, 0, 16) << 16;
3012                 addr = ~0xFFFF & addr_add(ctx, pc, offset);
3013                 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3014             }
3015             break;
3016 #if defined(TARGET_MIPS64)
3017         case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3018         case R6_OPC_LDPC + (1 << 16):
3019         case R6_OPC_LDPC + (2 << 16):
3020         case R6_OPC_LDPC + (3 << 16):
3021             check_mips_64(ctx);
3022             offset = sextract32(ctx->opcode << 3, 0, 21);
3023             addr = addr_add(ctx, (pc & ~0x7), offset);
3024             gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUQ);
3025             break;
3026 #endif
3027         default:
3028             MIPS_INVAL("OPC_PCREL");
3029             gen_reserved_instruction(ctx);
3030             break;
3031         }
3032         break;
3033     }
3034 }
3035 
gen_r6_muldiv(DisasContext * ctx,int opc,int rd,int rs,int rt)3036 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3037 {
3038     TCGv t0, t1;
3039 
3040     if (rd == 0) {
3041         /* Treat as NOP. */
3042         return;
3043     }
3044 
3045     t0 = tcg_temp_new();
3046     t1 = tcg_temp_new();
3047 
3048     gen_load_gpr(t0, rs);
3049     gen_load_gpr(t1, rt);
3050 
3051     switch (opc) {
3052     case R6_OPC_DIV:
3053         {
3054             TCGv t2 = tcg_temp_new();
3055             TCGv t3 = tcg_temp_new();
3056             tcg_gen_ext32s_tl(t0, t0);
3057             tcg_gen_ext32s_tl(t1, t1);
3058             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3059             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3060             tcg_gen_and_tl(t2, t2, t3);
3061             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3062             tcg_gen_or_tl(t2, t2, t3);
3063             tcg_gen_movi_tl(t3, 0);
3064             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3065             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3066             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3067         }
3068         break;
3069     case R6_OPC_MOD:
3070         {
3071             TCGv t2 = tcg_temp_new();
3072             TCGv t3 = tcg_temp_new();
3073             tcg_gen_ext32s_tl(t0, t0);
3074             tcg_gen_ext32s_tl(t1, t1);
3075             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3076             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3077             tcg_gen_and_tl(t2, t2, t3);
3078             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3079             tcg_gen_or_tl(t2, t2, t3);
3080             tcg_gen_movi_tl(t3, 0);
3081             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3082             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3083             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3084         }
3085         break;
3086     case R6_OPC_DIVU:
3087         {
3088             TCGv t2 = tcg_constant_tl(0);
3089             TCGv t3 = tcg_constant_tl(1);
3090             tcg_gen_ext32u_tl(t0, t0);
3091             tcg_gen_ext32u_tl(t1, t1);
3092             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3093             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3094             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3095         }
3096         break;
3097     case R6_OPC_MODU:
3098         {
3099             TCGv t2 = tcg_constant_tl(0);
3100             TCGv t3 = tcg_constant_tl(1);
3101             tcg_gen_ext32u_tl(t0, t0);
3102             tcg_gen_ext32u_tl(t1, t1);
3103             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3104             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3105             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3106         }
3107         break;
3108     case R6_OPC_MUL:
3109         {
3110             TCGv_i32 t2 = tcg_temp_new_i32();
3111             TCGv_i32 t3 = tcg_temp_new_i32();
3112             tcg_gen_trunc_tl_i32(t2, t0);
3113             tcg_gen_trunc_tl_i32(t3, t1);
3114             tcg_gen_mul_i32(t2, t2, t3);
3115             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3116         }
3117         break;
3118     case R6_OPC_MUH:
3119         {
3120             TCGv_i32 t2 = tcg_temp_new_i32();
3121             TCGv_i32 t3 = tcg_temp_new_i32();
3122             tcg_gen_trunc_tl_i32(t2, t0);
3123             tcg_gen_trunc_tl_i32(t3, t1);
3124             tcg_gen_muls2_i32(t2, t3, t2, t3);
3125             tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3126         }
3127         break;
3128     case R6_OPC_MULU:
3129         {
3130             TCGv_i32 t2 = tcg_temp_new_i32();
3131             TCGv_i32 t3 = tcg_temp_new_i32();
3132             tcg_gen_trunc_tl_i32(t2, t0);
3133             tcg_gen_trunc_tl_i32(t3, t1);
3134             tcg_gen_mul_i32(t2, t2, t3);
3135             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3136         }
3137         break;
3138     case R6_OPC_MUHU:
3139         {
3140             TCGv_i32 t2 = tcg_temp_new_i32();
3141             TCGv_i32 t3 = tcg_temp_new_i32();
3142             tcg_gen_trunc_tl_i32(t2, t0);
3143             tcg_gen_trunc_tl_i32(t3, t1);
3144             tcg_gen_mulu2_i32(t2, t3, t2, t3);
3145             tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3146         }
3147         break;
3148 #if defined(TARGET_MIPS64)
3149     case R6_OPC_DDIV:
3150         {
3151             TCGv t2 = tcg_temp_new();
3152             TCGv t3 = tcg_temp_new();
3153             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3154             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3155             tcg_gen_and_tl(t2, t2, t3);
3156             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3157             tcg_gen_or_tl(t2, t2, t3);
3158             tcg_gen_movi_tl(t3, 0);
3159             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3160             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3161         }
3162         break;
3163     case R6_OPC_DMOD:
3164         {
3165             TCGv t2 = tcg_temp_new();
3166             TCGv t3 = tcg_temp_new();
3167             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3168             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3169             tcg_gen_and_tl(t2, t2, t3);
3170             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3171             tcg_gen_or_tl(t2, t2, t3);
3172             tcg_gen_movi_tl(t3, 0);
3173             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3174             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3175         }
3176         break;
3177     case R6_OPC_DDIVU:
3178         {
3179             TCGv t2 = tcg_constant_tl(0);
3180             TCGv t3 = tcg_constant_tl(1);
3181             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3182             tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3183         }
3184         break;
3185     case R6_OPC_DMODU:
3186         {
3187             TCGv t2 = tcg_constant_tl(0);
3188             TCGv t3 = tcg_constant_tl(1);
3189             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3190             tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3191         }
3192         break;
3193     case R6_OPC_DMUL:
3194         tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3195         break;
3196     case R6_OPC_DMUH:
3197         {
3198             TCGv t2 = tcg_temp_new();
3199             tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3200         }
3201         break;
3202     case R6_OPC_DMULU:
3203         tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3204         break;
3205     case R6_OPC_DMUHU:
3206         {
3207             TCGv t2 = tcg_temp_new();
3208             tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3209         }
3210         break;
3211 #endif
3212     default:
3213         MIPS_INVAL("r6 mul/div");
3214         gen_reserved_instruction(ctx);
3215         break;
3216     }
3217 }
3218 
3219 #if defined(TARGET_MIPS64)
gen_div1_tx79(DisasContext * ctx,uint32_t opc,int rs,int rt)3220 static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
3221 {
3222     TCGv t0, t1;
3223 
3224     t0 = tcg_temp_new();
3225     t1 = tcg_temp_new();
3226 
3227     gen_load_gpr(t0, rs);
3228     gen_load_gpr(t1, rt);
3229 
3230     switch (opc) {
3231     case MMI_OPC_DIV1:
3232         {
3233             TCGv t2 = tcg_temp_new();
3234             TCGv t3 = tcg_temp_new();
3235             tcg_gen_ext32s_tl(t0, t0);
3236             tcg_gen_ext32s_tl(t1, t1);
3237             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3238             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3239             tcg_gen_and_tl(t2, t2, t3);
3240             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3241             tcg_gen_or_tl(t2, t2, t3);
3242             tcg_gen_movi_tl(t3, 0);
3243             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3244             tcg_gen_div_tl(cpu_LO[1], t0, t1);
3245             tcg_gen_rem_tl(cpu_HI[1], t0, t1);
3246             tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
3247             tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
3248         }
3249         break;
3250     case MMI_OPC_DIVU1:
3251         {
3252             TCGv t2 = tcg_constant_tl(0);
3253             TCGv t3 = tcg_constant_tl(1);
3254             tcg_gen_ext32u_tl(t0, t0);
3255             tcg_gen_ext32u_tl(t1, t1);
3256             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3257             tcg_gen_divu_tl(cpu_LO[1], t0, t1);
3258             tcg_gen_remu_tl(cpu_HI[1], t0, t1);
3259             tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
3260             tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
3261         }
3262         break;
3263     default:
3264         MIPS_INVAL("div1 TX79");
3265         gen_reserved_instruction(ctx);
3266         break;
3267     }
3268 }
3269 #endif
3270 
gen_muldiv(DisasContext * ctx,uint32_t opc,int acc,int rs,int rt)3271 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3272                        int acc, int rs, int rt)
3273 {
3274     TCGv t0, t1;
3275 
3276     t0 = tcg_temp_new();
3277     t1 = tcg_temp_new();
3278 
3279     gen_load_gpr(t0, rs);
3280     gen_load_gpr(t1, rt);
3281 
3282     if (acc != 0) {
3283         check_dsp(ctx);
3284     }
3285 
3286     switch (opc) {
3287     case OPC_DIV:
3288         {
3289             TCGv t2 = tcg_temp_new();
3290             TCGv t3 = tcg_temp_new();
3291             tcg_gen_ext32s_tl(t0, t0);
3292             tcg_gen_ext32s_tl(t1, t1);
3293             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3294             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3295             tcg_gen_and_tl(t2, t2, t3);
3296             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3297             tcg_gen_or_tl(t2, t2, t3);
3298             tcg_gen_movi_tl(t3, 0);
3299             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3300             tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3301             tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3302             tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3303             tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3304         }
3305         break;
3306     case OPC_DIVU:
3307         {
3308             TCGv t2 = tcg_constant_tl(0);
3309             TCGv t3 = tcg_constant_tl(1);
3310             tcg_gen_ext32u_tl(t0, t0);
3311             tcg_gen_ext32u_tl(t1, t1);
3312             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3313             tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3314             tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3315             tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3316             tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3317         }
3318         break;
3319     case OPC_MULT:
3320         {
3321             TCGv_i32 t2 = tcg_temp_new_i32();
3322             TCGv_i32 t3 = tcg_temp_new_i32();
3323             tcg_gen_trunc_tl_i32(t2, t0);
3324             tcg_gen_trunc_tl_i32(t3, t1);
3325             tcg_gen_muls2_i32(t2, t3, t2, t3);
3326             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3327             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3328         }
3329         break;
3330     case OPC_MULTU:
3331         {
3332             TCGv_i32 t2 = tcg_temp_new_i32();
3333             TCGv_i32 t3 = tcg_temp_new_i32();
3334             tcg_gen_trunc_tl_i32(t2, t0);
3335             tcg_gen_trunc_tl_i32(t3, t1);
3336             tcg_gen_mulu2_i32(t2, t3, t2, t3);
3337             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3338             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3339         }
3340         break;
3341 #if defined(TARGET_MIPS64)
3342     case OPC_DDIV:
3343         {
3344             TCGv t2 = tcg_temp_new();
3345             TCGv t3 = tcg_temp_new();
3346             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3347             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3348             tcg_gen_and_tl(t2, t2, t3);
3349             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3350             tcg_gen_or_tl(t2, t2, t3);
3351             tcg_gen_movi_tl(t3, 0);
3352             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3353             tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3354             tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3355         }
3356         break;
3357     case OPC_DDIVU:
3358         {
3359             TCGv t2 = tcg_constant_tl(0);
3360             TCGv t3 = tcg_constant_tl(1);
3361             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3362             tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3363             tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
3364         }
3365         break;
3366     case OPC_DMULT:
3367         tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3368         break;
3369     case OPC_DMULTU:
3370         tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3371         break;
3372 #endif
3373     case OPC_MADD:
3374         {
3375             TCGv_i64 t2 = tcg_temp_new_i64();
3376             TCGv_i64 t3 = tcg_temp_new_i64();
3377 
3378             tcg_gen_ext_tl_i64(t2, t0);
3379             tcg_gen_ext_tl_i64(t3, t1);
3380             tcg_gen_mul_i64(t2, t2, t3);
3381             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3382             tcg_gen_add_i64(t2, t2, t3);
3383             gen_move_low32(cpu_LO[acc], t2);
3384             gen_move_high32(cpu_HI[acc], t2);
3385         }
3386         break;
3387     case OPC_MADDU:
3388         {
3389             TCGv_i64 t2 = tcg_temp_new_i64();
3390             TCGv_i64 t3 = tcg_temp_new_i64();
3391 
3392             tcg_gen_ext32u_tl(t0, t0);
3393             tcg_gen_ext32u_tl(t1, t1);
3394             tcg_gen_extu_tl_i64(t2, t0);
3395             tcg_gen_extu_tl_i64(t3, t1);
3396             tcg_gen_mul_i64(t2, t2, t3);
3397             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3398             tcg_gen_add_i64(t2, t2, t3);
3399             gen_move_low32(cpu_LO[acc], t2);
3400             gen_move_high32(cpu_HI[acc], t2);
3401         }
3402         break;
3403     case OPC_MSUB:
3404         {
3405             TCGv_i64 t2 = tcg_temp_new_i64();
3406             TCGv_i64 t3 = tcg_temp_new_i64();
3407 
3408             tcg_gen_ext_tl_i64(t2, t0);
3409             tcg_gen_ext_tl_i64(t3, t1);
3410             tcg_gen_mul_i64(t2, t2, t3);
3411             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3412             tcg_gen_sub_i64(t2, t3, t2);
3413             gen_move_low32(cpu_LO[acc], t2);
3414             gen_move_high32(cpu_HI[acc], t2);
3415         }
3416         break;
3417     case OPC_MSUBU:
3418         {
3419             TCGv_i64 t2 = tcg_temp_new_i64();
3420             TCGv_i64 t3 = tcg_temp_new_i64();
3421 
3422             tcg_gen_ext32u_tl(t0, t0);
3423             tcg_gen_ext32u_tl(t1, t1);
3424             tcg_gen_extu_tl_i64(t2, t0);
3425             tcg_gen_extu_tl_i64(t3, t1);
3426             tcg_gen_mul_i64(t2, t2, t3);
3427             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3428             tcg_gen_sub_i64(t2, t3, t2);
3429             gen_move_low32(cpu_LO[acc], t2);
3430             gen_move_high32(cpu_HI[acc], t2);
3431         }
3432         break;
3433     default:
3434         MIPS_INVAL("mul/div");
3435         gen_reserved_instruction(ctx);
3436         break;
3437     }
3438 }
3439 
3440 /*
3441  * These MULT[U] and MADD[U] instructions implemented in for example
3442  * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
3443  * architectures are special three-operand variants with the syntax
3444  *
3445  *     MULT[U][1] rd, rs, rt
3446  *
3447  * such that
3448  *
3449  *     (rd, LO, HI) <- rs * rt
3450  *
3451  * and
3452  *
3453  *     MADD[U][1] rd, rs, rt
3454  *
3455  * such that
3456  *
3457  *     (rd, LO, HI) <- (LO, HI) + rs * rt
3458  *
3459  * where the low-order 32-bits of the result is placed into both the
3460  * GPR rd and the special register LO. The high-order 32-bits of the
3461  * result is placed into the special register HI.
3462  *
3463  * If the GPR rd is omitted in assembly language, it is taken to be 0,
3464  * which is the zero register that always reads as 0.
3465  */
gen_mul_txx9(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)3466 static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
3467                          int rd, int rs, int rt)
3468 {
3469     TCGv t0 = tcg_temp_new();
3470     TCGv t1 = tcg_temp_new();
3471     int acc = 0;
3472 
3473     gen_load_gpr(t0, rs);
3474     gen_load_gpr(t1, rt);
3475 
3476     switch (opc) {
3477     case MMI_OPC_MULT1:
3478         acc = 1;
3479         /* Fall through */
3480     case OPC_MULT:
3481         {
3482             TCGv_i32 t2 = tcg_temp_new_i32();
3483             TCGv_i32 t3 = tcg_temp_new_i32();
3484             tcg_gen_trunc_tl_i32(t2, t0);
3485             tcg_gen_trunc_tl_i32(t3, t1);
3486             tcg_gen_muls2_i32(t2, t3, t2, t3);
3487             if (rd) {
3488                 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3489             }
3490             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3491             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3492         }
3493         break;
3494     case MMI_OPC_MULTU1:
3495         acc = 1;
3496         /* Fall through */
3497     case OPC_MULTU:
3498         {
3499             TCGv_i32 t2 = tcg_temp_new_i32();
3500             TCGv_i32 t3 = tcg_temp_new_i32();
3501             tcg_gen_trunc_tl_i32(t2, t0);
3502             tcg_gen_trunc_tl_i32(t3, t1);
3503             tcg_gen_mulu2_i32(t2, t3, t2, t3);
3504             if (rd) {
3505                 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3506             }
3507             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3508             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3509         }
3510         break;
3511     case MMI_OPC_MADD1:
3512         acc = 1;
3513         /* Fall through */
3514     case MMI_OPC_MADD:
3515         {
3516             TCGv_i64 t2 = tcg_temp_new_i64();
3517             TCGv_i64 t3 = tcg_temp_new_i64();
3518 
3519             tcg_gen_ext_tl_i64(t2, t0);
3520             tcg_gen_ext_tl_i64(t3, t1);
3521             tcg_gen_mul_i64(t2, t2, t3);
3522             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3523             tcg_gen_add_i64(t2, t2, t3);
3524             gen_move_low32(cpu_LO[acc], t2);
3525             gen_move_high32(cpu_HI[acc], t2);
3526             if (rd) {
3527                 gen_move_low32(cpu_gpr[rd], t2);
3528             }
3529         }
3530         break;
3531     case MMI_OPC_MADDU1:
3532         acc = 1;
3533         /* Fall through */
3534     case MMI_OPC_MADDU:
3535         {
3536             TCGv_i64 t2 = tcg_temp_new_i64();
3537             TCGv_i64 t3 = tcg_temp_new_i64();
3538 
3539             tcg_gen_ext32u_tl(t0, t0);
3540             tcg_gen_ext32u_tl(t1, t1);
3541             tcg_gen_extu_tl_i64(t2, t0);
3542             tcg_gen_extu_tl_i64(t3, t1);
3543             tcg_gen_mul_i64(t2, t2, t3);
3544             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3545             tcg_gen_add_i64(t2, t2, t3);
3546             gen_move_low32(cpu_LO[acc], t2);
3547             gen_move_high32(cpu_HI[acc], t2);
3548             if (rd) {
3549                 gen_move_low32(cpu_gpr[rd], t2);
3550             }
3551         }
3552         break;
3553     default:
3554         MIPS_INVAL("mul/madd TXx9");
3555         gen_reserved_instruction(ctx);
3556         break;
3557     }
3558 }
3559 
gen_cl(DisasContext * ctx,uint32_t opc,int rd,int rs)3560 static void gen_cl(DisasContext *ctx, uint32_t opc,
3561                    int rd, int rs)
3562 {
3563     TCGv t0;
3564 
3565     if (rd == 0) {
3566         /* Treat as NOP. */
3567         return;
3568     }
3569     t0 = cpu_gpr[rd];
3570     gen_load_gpr(t0, rs);
3571 
3572     switch (opc) {
3573     case OPC_CLO:
3574     case R6_OPC_CLO:
3575 #if defined(TARGET_MIPS64)
3576     case OPC_DCLO:
3577     case R6_OPC_DCLO:
3578 #endif
3579         tcg_gen_not_tl(t0, t0);
3580         break;
3581     }
3582 
3583     switch (opc) {
3584     case OPC_CLO:
3585     case R6_OPC_CLO:
3586     case OPC_CLZ:
3587     case R6_OPC_CLZ:
3588         tcg_gen_ext32u_tl(t0, t0);
3589         tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
3590         tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
3591         break;
3592 #if defined(TARGET_MIPS64)
3593     case OPC_DCLO:
3594     case R6_OPC_DCLO:
3595     case OPC_DCLZ:
3596     case R6_OPC_DCLZ:
3597         tcg_gen_clzi_i64(t0, t0, 64);
3598         break;
3599 #endif
3600     }
3601 }
3602 
3603 /* Godson integer instructions */
gen_loongson_integer(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)3604 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3605                                  int rd, int rs, int rt)
3606 {
3607     TCGv t0, t1;
3608 
3609     if (rd == 0) {
3610         /* Treat as NOP. */
3611         return;
3612     }
3613 
3614     t0 = tcg_temp_new();
3615     t1 = tcg_temp_new();
3616     gen_load_gpr(t0, rs);
3617     gen_load_gpr(t1, rt);
3618 
3619     switch (opc) {
3620     case OPC_MULT_G_2E:
3621     case OPC_MULT_G_2F:
3622         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3623         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3624         break;
3625     case OPC_MULTU_G_2E:
3626     case OPC_MULTU_G_2F:
3627         tcg_gen_ext32u_tl(t0, t0);
3628         tcg_gen_ext32u_tl(t1, t1);
3629         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3630         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3631         break;
3632     case OPC_DIV_G_2E:
3633     case OPC_DIV_G_2F:
3634         {
3635             TCGLabel *l1 = gen_new_label();
3636             TCGLabel *l2 = gen_new_label();
3637             TCGLabel *l3 = gen_new_label();
3638             tcg_gen_ext32s_tl(t0, t0);
3639             tcg_gen_ext32s_tl(t1, t1);
3640             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3641             tcg_gen_movi_tl(cpu_gpr[rd], 0);
3642             tcg_gen_br(l3);
3643             gen_set_label(l1);
3644             tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3645             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3646             tcg_gen_mov_tl(cpu_gpr[rd], t0);
3647             tcg_gen_br(l3);
3648             gen_set_label(l2);
3649             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3650             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3651             gen_set_label(l3);
3652         }
3653         break;
3654     case OPC_DIVU_G_2E:
3655     case OPC_DIVU_G_2F:
3656         {
3657             TCGLabel *l1 = gen_new_label();
3658             TCGLabel *l2 = gen_new_label();
3659             tcg_gen_ext32u_tl(t0, t0);
3660             tcg_gen_ext32u_tl(t1, t1);
3661             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3662             tcg_gen_movi_tl(cpu_gpr[rd], 0);
3663             tcg_gen_br(l2);
3664             gen_set_label(l1);
3665             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3666             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3667             gen_set_label(l2);
3668         }
3669         break;
3670     case OPC_MOD_G_2E:
3671     case OPC_MOD_G_2F:
3672         {
3673             TCGLabel *l1 = gen_new_label();
3674             TCGLabel *l2 = gen_new_label();
3675             TCGLabel *l3 = gen_new_label();
3676             tcg_gen_ext32u_tl(t0, t0);
3677             tcg_gen_ext32u_tl(t1, t1);
3678             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3679             tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3680             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3681             gen_set_label(l1);
3682             tcg_gen_movi_tl(cpu_gpr[rd], 0);
3683             tcg_gen_br(l3);
3684             gen_set_label(l2);
3685             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3686             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3687             gen_set_label(l3);
3688         }
3689         break;
3690     case OPC_MODU_G_2E:
3691     case OPC_MODU_G_2F:
3692         {
3693             TCGLabel *l1 = gen_new_label();
3694             TCGLabel *l2 = gen_new_label();
3695             tcg_gen_ext32u_tl(t0, t0);
3696             tcg_gen_ext32u_tl(t1, t1);
3697             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3698             tcg_gen_movi_tl(cpu_gpr[rd], 0);
3699             tcg_gen_br(l2);
3700             gen_set_label(l1);
3701             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3702             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3703             gen_set_label(l2);
3704         }
3705         break;
3706 #if defined(TARGET_MIPS64)
3707     case OPC_DMULT_G_2E:
3708     case OPC_DMULT_G_2F:
3709         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3710         break;
3711     case OPC_DMULTU_G_2E:
3712     case OPC_DMULTU_G_2F:
3713         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3714         break;
3715     case OPC_DDIV_G_2E:
3716     case OPC_DDIV_G_2F:
3717         {
3718             TCGLabel *l1 = gen_new_label();
3719             TCGLabel *l2 = gen_new_label();
3720             TCGLabel *l3 = gen_new_label();
3721             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3722             tcg_gen_movi_tl(cpu_gpr[rd], 0);
3723             tcg_gen_br(l3);
3724             gen_set_label(l1);
3725             tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3726             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3727             tcg_gen_mov_tl(cpu_gpr[rd], t0);
3728             tcg_gen_br(l3);
3729             gen_set_label(l2);
3730             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3731             gen_set_label(l3);
3732         }
3733         break;
3734     case OPC_DDIVU_G_2E:
3735     case OPC_DDIVU_G_2F:
3736         {
3737             TCGLabel *l1 = gen_new_label();
3738             TCGLabel *l2 = gen_new_label();
3739             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3740             tcg_gen_movi_tl(cpu_gpr[rd], 0);
3741             tcg_gen_br(l2);
3742             gen_set_label(l1);
3743             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3744             gen_set_label(l2);
3745         }
3746         break;
3747     case OPC_DMOD_G_2E:
3748     case OPC_DMOD_G_2F:
3749         {
3750             TCGLabel *l1 = gen_new_label();
3751             TCGLabel *l2 = gen_new_label();
3752             TCGLabel *l3 = gen_new_label();
3753             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3754             tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3755             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3756             gen_set_label(l1);
3757             tcg_gen_movi_tl(cpu_gpr[rd], 0);
3758             tcg_gen_br(l3);
3759             gen_set_label(l2);
3760             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3761             gen_set_label(l3);
3762         }
3763         break;
3764     case OPC_DMODU_G_2E:
3765     case OPC_DMODU_G_2F:
3766         {
3767             TCGLabel *l1 = gen_new_label();
3768             TCGLabel *l2 = gen_new_label();
3769             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3770             tcg_gen_movi_tl(cpu_gpr[rd], 0);
3771             tcg_gen_br(l2);
3772             gen_set_label(l1);
3773             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3774             gen_set_label(l2);
3775         }
3776         break;
3777 #endif
3778     }
3779 }
3780 
3781 /* Loongson multimedia instructions */
gen_loongson_multimedia(DisasContext * ctx,int rd,int rs,int rt)3782 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3783 {
3784     uint32_t opc, shift_max;
3785     TCGv_i64 t0, t1;
3786     TCGCond cond;
3787 
3788     opc = MASK_LMMI(ctx->opcode);
3789     check_cp1_enabled(ctx);
3790 
3791     t0 = tcg_temp_new_i64();
3792     t1 = tcg_temp_new_i64();
3793     gen_load_fpr64(ctx, t0, rs);
3794     gen_load_fpr64(ctx, t1, rt);
3795 
3796     switch (opc) {
3797     case OPC_PADDSH:
3798         gen_helper_paddsh(t0, t0, t1);
3799         break;
3800     case OPC_PADDUSH:
3801         gen_helper_paddush(t0, t0, t1);
3802         break;
3803     case OPC_PADDH:
3804         gen_helper_paddh(t0, t0, t1);
3805         break;
3806     case OPC_PADDW:
3807         gen_helper_paddw(t0, t0, t1);
3808         break;
3809     case OPC_PADDSB:
3810         gen_helper_paddsb(t0, t0, t1);
3811         break;
3812     case OPC_PADDUSB:
3813         gen_helper_paddusb(t0, t0, t1);
3814         break;
3815     case OPC_PADDB:
3816         gen_helper_paddb(t0, t0, t1);
3817         break;
3818 
3819     case OPC_PSUBSH:
3820         gen_helper_psubsh(t0, t0, t1);
3821         break;
3822     case OPC_PSUBUSH:
3823         gen_helper_psubush(t0, t0, t1);
3824         break;
3825     case OPC_PSUBH:
3826         gen_helper_psubh(t0, t0, t1);
3827         break;
3828     case OPC_PSUBW:
3829         gen_helper_psubw(t0, t0, t1);
3830         break;
3831     case OPC_PSUBSB:
3832         gen_helper_psubsb(t0, t0, t1);
3833         break;
3834     case OPC_PSUBUSB:
3835         gen_helper_psubusb(t0, t0, t1);
3836         break;
3837     case OPC_PSUBB:
3838         gen_helper_psubb(t0, t0, t1);
3839         break;
3840 
3841     case OPC_PSHUFH:
3842         gen_helper_pshufh(t0, t0, t1);
3843         break;
3844     case OPC_PACKSSWH:
3845         gen_helper_packsswh(t0, t0, t1);
3846         break;
3847     case OPC_PACKSSHB:
3848         gen_helper_packsshb(t0, t0, t1);
3849         break;
3850     case OPC_PACKUSHB:
3851         gen_helper_packushb(t0, t0, t1);
3852         break;
3853 
3854     case OPC_PUNPCKLHW:
3855         gen_helper_punpcklhw(t0, t0, t1);
3856         break;
3857     case OPC_PUNPCKHHW:
3858         gen_helper_punpckhhw(t0, t0, t1);
3859         break;
3860     case OPC_PUNPCKLBH:
3861         gen_helper_punpcklbh(t0, t0, t1);
3862         break;
3863     case OPC_PUNPCKHBH:
3864         gen_helper_punpckhbh(t0, t0, t1);
3865         break;
3866     case OPC_PUNPCKLWD:
3867         gen_helper_punpcklwd(t0, t0, t1);
3868         break;
3869     case OPC_PUNPCKHWD:
3870         gen_helper_punpckhwd(t0, t0, t1);
3871         break;
3872 
3873     case OPC_PAVGH:
3874         gen_helper_pavgh(t0, t0, t1);
3875         break;
3876     case OPC_PAVGB:
3877         gen_helper_pavgb(t0, t0, t1);
3878         break;
3879     case OPC_PMAXSH:
3880         gen_helper_pmaxsh(t0, t0, t1);
3881         break;
3882     case OPC_PMINSH:
3883         gen_helper_pminsh(t0, t0, t1);
3884         break;
3885     case OPC_PMAXUB:
3886         gen_helper_pmaxub(t0, t0, t1);
3887         break;
3888     case OPC_PMINUB:
3889         gen_helper_pminub(t0, t0, t1);
3890         break;
3891 
3892     case OPC_PCMPEQW:
3893         gen_helper_pcmpeqw(t0, t0, t1);
3894         break;
3895     case OPC_PCMPGTW:
3896         gen_helper_pcmpgtw(t0, t0, t1);
3897         break;
3898     case OPC_PCMPEQH:
3899         gen_helper_pcmpeqh(t0, t0, t1);
3900         break;
3901     case OPC_PCMPGTH:
3902         gen_helper_pcmpgth(t0, t0, t1);
3903         break;
3904     case OPC_PCMPEQB:
3905         gen_helper_pcmpeqb(t0, t0, t1);
3906         break;
3907     case OPC_PCMPGTB:
3908         gen_helper_pcmpgtb(t0, t0, t1);
3909         break;
3910 
3911     case OPC_PSLLW:
3912         gen_helper_psllw(t0, t0, t1);
3913         break;
3914     case OPC_PSLLH:
3915         gen_helper_psllh(t0, t0, t1);
3916         break;
3917     case OPC_PSRLW:
3918         gen_helper_psrlw(t0, t0, t1);
3919         break;
3920     case OPC_PSRLH:
3921         gen_helper_psrlh(t0, t0, t1);
3922         break;
3923     case OPC_PSRAW:
3924         gen_helper_psraw(t0, t0, t1);
3925         break;
3926     case OPC_PSRAH:
3927         gen_helper_psrah(t0, t0, t1);
3928         break;
3929 
3930     case OPC_PMULLH:
3931         gen_helper_pmullh(t0, t0, t1);
3932         break;
3933     case OPC_PMULHH:
3934         gen_helper_pmulhh(t0, t0, t1);
3935         break;
3936     case OPC_PMULHUH:
3937         gen_helper_pmulhuh(t0, t0, t1);
3938         break;
3939     case OPC_PMADDHW:
3940         gen_helper_pmaddhw(t0, t0, t1);
3941         break;
3942 
3943     case OPC_PASUBUB:
3944         gen_helper_pasubub(t0, t0, t1);
3945         break;
3946     case OPC_BIADD:
3947         gen_helper_biadd(t0, t0);
3948         break;
3949     case OPC_PMOVMSKB:
3950         gen_helper_pmovmskb(t0, t0);
3951         break;
3952 
3953     case OPC_PADDD:
3954         tcg_gen_add_i64(t0, t0, t1);
3955         break;
3956     case OPC_PSUBD:
3957         tcg_gen_sub_i64(t0, t0, t1);
3958         break;
3959     case OPC_XOR_CP2:
3960         tcg_gen_xor_i64(t0, t0, t1);
3961         break;
3962     case OPC_NOR_CP2:
3963         tcg_gen_nor_i64(t0, t0, t1);
3964         break;
3965     case OPC_AND_CP2:
3966         tcg_gen_and_i64(t0, t0, t1);
3967         break;
3968     case OPC_OR_CP2:
3969         tcg_gen_or_i64(t0, t0, t1);
3970         break;
3971 
3972     case OPC_PANDN:
3973         tcg_gen_andc_i64(t0, t1, t0);
3974         break;
3975 
3976     case OPC_PINSRH_0:
3977         tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3978         break;
3979     case OPC_PINSRH_1:
3980         tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3981         break;
3982     case OPC_PINSRH_2:
3983         tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3984         break;
3985     case OPC_PINSRH_3:
3986         tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3987         break;
3988 
3989     case OPC_PEXTRH:
3990         tcg_gen_andi_i64(t1, t1, 3);
3991         tcg_gen_shli_i64(t1, t1, 4);
3992         tcg_gen_shr_i64(t0, t0, t1);
3993         tcg_gen_ext16u_i64(t0, t0);
3994         break;
3995 
3996     case OPC_ADDU_CP2:
3997         tcg_gen_add_i64(t0, t0, t1);
3998         tcg_gen_ext32s_i64(t0, t0);
3999         break;
4000     case OPC_SUBU_CP2:
4001         tcg_gen_sub_i64(t0, t0, t1);
4002         tcg_gen_ext32s_i64(t0, t0);
4003         break;
4004 
4005     case OPC_SLL_CP2:
4006         shift_max = 32;
4007         goto do_shift;
4008     case OPC_SRL_CP2:
4009         shift_max = 32;
4010         goto do_shift;
4011     case OPC_SRA_CP2:
4012         shift_max = 32;
4013         goto do_shift;
4014     case OPC_DSLL_CP2:
4015         shift_max = 64;
4016         goto do_shift;
4017     case OPC_DSRL_CP2:
4018         shift_max = 64;
4019         goto do_shift;
4020     case OPC_DSRA_CP2:
4021         shift_max = 64;
4022         goto do_shift;
4023     do_shift:
4024         /* Make sure shift count isn't TCG undefined behaviour.  */
4025         tcg_gen_andi_i64(t1, t1, shift_max - 1);
4026 
4027         switch (opc) {
4028         case OPC_SLL_CP2:
4029         case OPC_DSLL_CP2:
4030             tcg_gen_shl_i64(t0, t0, t1);
4031             break;
4032         case OPC_SRA_CP2:
4033         case OPC_DSRA_CP2:
4034             /*
4035              * Since SRA is UndefinedResult without sign-extended inputs,
4036              * we can treat SRA and DSRA the same.
4037              */
4038             tcg_gen_sar_i64(t0, t0, t1);
4039             break;
4040         case OPC_SRL_CP2:
4041             /* We want to shift in zeros for SRL; zero-extend first.  */
4042             tcg_gen_ext32u_i64(t0, t0);
4043             /* FALLTHRU */
4044         case OPC_DSRL_CP2:
4045             tcg_gen_shr_i64(t0, t0, t1);
4046             break;
4047         }
4048 
4049         if (shift_max == 32) {
4050             tcg_gen_ext32s_i64(t0, t0);
4051         }
4052 
4053         /* Shifts larger than MAX produce zero.  */
4054         tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4055         tcg_gen_neg_i64(t1, t1);
4056         tcg_gen_and_i64(t0, t0, t1);
4057         break;
4058 
4059     case OPC_ADD_CP2:
4060     case OPC_DADD_CP2:
4061         {
4062             TCGv_i64 t2 = tcg_temp_new_i64();
4063             TCGLabel *lab = gen_new_label();
4064 
4065             tcg_gen_mov_i64(t2, t0);
4066             tcg_gen_add_i64(t0, t1, t2);
4067             if (opc == OPC_ADD_CP2) {
4068                 tcg_gen_ext32s_i64(t0, t0);
4069             }
4070             tcg_gen_xor_i64(t1, t1, t2);
4071             tcg_gen_xor_i64(t2, t2, t0);
4072             tcg_gen_andc_i64(t1, t2, t1);
4073             tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4074             generate_exception(ctx, EXCP_OVERFLOW);
4075             gen_set_label(lab);
4076             break;
4077         }
4078 
4079     case OPC_SUB_CP2:
4080     case OPC_DSUB_CP2:
4081         {
4082             TCGv_i64 t2 = tcg_temp_new_i64();
4083             TCGLabel *lab = gen_new_label();
4084 
4085             tcg_gen_mov_i64(t2, t0);
4086             tcg_gen_sub_i64(t0, t1, t2);
4087             if (opc == OPC_SUB_CP2) {
4088                 tcg_gen_ext32s_i64(t0, t0);
4089             }
4090             tcg_gen_xor_i64(t1, t1, t2);
4091             tcg_gen_xor_i64(t2, t2, t0);
4092             tcg_gen_and_i64(t1, t1, t2);
4093             tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4094             generate_exception(ctx, EXCP_OVERFLOW);
4095             gen_set_label(lab);
4096             break;
4097         }
4098 
4099     case OPC_PMULUW:
4100         tcg_gen_ext32u_i64(t0, t0);
4101         tcg_gen_ext32u_i64(t1, t1);
4102         tcg_gen_mul_i64(t0, t0, t1);
4103         break;
4104 
4105     case OPC_SEQU_CP2:
4106     case OPC_SEQ_CP2:
4107         cond = TCG_COND_EQ;
4108         goto do_cc_cond;
4109         break;
4110     case OPC_SLTU_CP2:
4111         cond = TCG_COND_LTU;
4112         goto do_cc_cond;
4113         break;
4114     case OPC_SLT_CP2:
4115         cond = TCG_COND_LT;
4116         goto do_cc_cond;
4117         break;
4118     case OPC_SLEU_CP2:
4119         cond = TCG_COND_LEU;
4120         goto do_cc_cond;
4121         break;
4122     case OPC_SLE_CP2:
4123         cond = TCG_COND_LE;
4124     do_cc_cond:
4125         {
4126             int cc = (ctx->opcode >> 8) & 0x7;
4127             TCGv_i64 t64 = tcg_temp_new_i64();
4128             TCGv_i32 t32 = tcg_temp_new_i32();
4129 
4130             tcg_gen_setcond_i64(cond, t64, t0, t1);
4131             tcg_gen_extrl_i64_i32(t32, t64);
4132             tcg_gen_deposit_i32(fpu_fcr31, fpu_fcr31, t32,
4133                                 get_fp_bit(cc), 1);
4134         }
4135         return;
4136     default:
4137         MIPS_INVAL("loongson_cp2");
4138         gen_reserved_instruction(ctx);
4139         return;
4140     }
4141 
4142     gen_store_fpr64(ctx, t0, rd);
4143 }
4144 
gen_loongson_lswc2(DisasContext * ctx,int rt,int rs,int rd)4145 static void gen_loongson_lswc2(DisasContext *ctx, int rt,
4146                                int rs, int rd)
4147 {
4148     TCGv t0, t1;
4149     TCGv_i32 fp0;
4150 #if defined(TARGET_MIPS64)
4151     int lsq_rt1 = ctx->opcode & 0x1f;
4152     int lsq_offset = sextract32(ctx->opcode, 6, 9) << 4;
4153 #endif
4154     int shf_offset = sextract32(ctx->opcode, 6, 8);
4155 
4156     t0 = tcg_temp_new();
4157 
4158     switch (MASK_LOONGSON_GSLSQ(ctx->opcode)) {
4159 #if defined(TARGET_MIPS64)
4160     case OPC_GSLQ:
4161         t1 = tcg_temp_new();
4162         gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4163         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4164                            ctx->default_tcg_memop_mask);
4165         gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4166         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ |
4167                            ctx->default_tcg_memop_mask);
4168         gen_store_gpr(t1, rt);
4169         gen_store_gpr(t0, lsq_rt1);
4170         break;
4171     case OPC_GSLQC1:
4172         check_cp1_enabled(ctx);
4173         t1 = tcg_temp_new();
4174         gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4175         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4176                            ctx->default_tcg_memop_mask);
4177         gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4178         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ |
4179                            ctx->default_tcg_memop_mask);
4180         gen_store_fpr64(ctx, t1, rt);
4181         gen_store_fpr64(ctx, t0, lsq_rt1);
4182         break;
4183     case OPC_GSSQ:
4184         t1 = tcg_temp_new();
4185         gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4186         gen_load_gpr(t1, rt);
4187         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4188                            ctx->default_tcg_memop_mask);
4189         gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4190         gen_load_gpr(t1, lsq_rt1);
4191         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4192                            ctx->default_tcg_memop_mask);
4193         break;
4194     case OPC_GSSQC1:
4195         check_cp1_enabled(ctx);
4196         t1 = tcg_temp_new();
4197         gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4198         gen_load_fpr64(ctx, t1, rt);
4199         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4200                            ctx->default_tcg_memop_mask);
4201         gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4202         gen_load_fpr64(ctx, t1, lsq_rt1);
4203         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4204                            ctx->default_tcg_memop_mask);
4205         break;
4206 #endif
4207     case OPC_GSSHFL:
4208         switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
4209         case OPC_GSLWLC1:
4210             check_cp1_enabled(ctx);
4211             gen_base_offset_addr(ctx, t0, rs, shf_offset);
4212             fp0 = tcg_temp_new_i32();
4213             gen_load_fpr32(ctx, fp0, rt);
4214             t1 = tcg_temp_new();
4215             tcg_gen_ext_i32_tl(t1, fp0);
4216             gen_lxl(ctx, t1, t0, ctx->mem_idx, MO_TEUL);
4217             tcg_gen_trunc_tl_i32(fp0, t1);
4218             gen_store_fpr32(ctx, fp0, rt);
4219             break;
4220         case OPC_GSLWRC1:
4221             check_cp1_enabled(ctx);
4222             gen_base_offset_addr(ctx, t0, rs, shf_offset);
4223             fp0 = tcg_temp_new_i32();
4224             gen_load_fpr32(ctx, fp0, rt);
4225             t1 = tcg_temp_new();
4226             tcg_gen_ext_i32_tl(t1, fp0);
4227             gen_lxr(ctx, t1, t0, ctx->mem_idx, MO_TEUL);
4228             tcg_gen_trunc_tl_i32(fp0, t1);
4229             gen_store_fpr32(ctx, fp0, rt);
4230             break;
4231 #if defined(TARGET_MIPS64)
4232         case OPC_GSLDLC1:
4233             check_cp1_enabled(ctx);
4234             gen_base_offset_addr(ctx, t0, rs, shf_offset);
4235             t1 = tcg_temp_new();
4236             gen_load_fpr64(ctx, t1, rt);
4237             gen_lxl(ctx, t1, t0, ctx->mem_idx, MO_TEUQ);
4238             gen_store_fpr64(ctx, t1, rt);
4239             break;
4240         case OPC_GSLDRC1:
4241             check_cp1_enabled(ctx);
4242             gen_base_offset_addr(ctx, t0, rs, shf_offset);
4243             t1 = tcg_temp_new();
4244             gen_load_fpr64(ctx, t1, rt);
4245             gen_lxr(ctx, t1, t0, ctx->mem_idx, MO_TEUQ);
4246             gen_store_fpr64(ctx, t1, rt);
4247             break;
4248 #endif
4249         default:
4250             MIPS_INVAL("loongson_gsshfl");
4251             gen_reserved_instruction(ctx);
4252             break;
4253         }
4254         break;
4255     case OPC_GSSHFS:
4256         switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
4257         case OPC_GSSWLC1:
4258             check_cp1_enabled(ctx);
4259             t1 = tcg_temp_new();
4260             gen_base_offset_addr(ctx, t0, rs, shf_offset);
4261             fp0 = tcg_temp_new_i32();
4262             gen_load_fpr32(ctx, fp0, rt);
4263             tcg_gen_ext_i32_tl(t1, fp0);
4264             gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
4265             break;
4266         case OPC_GSSWRC1:
4267             check_cp1_enabled(ctx);
4268             t1 = tcg_temp_new();
4269             gen_base_offset_addr(ctx, t0, rs, shf_offset);
4270             fp0 = tcg_temp_new_i32();
4271             gen_load_fpr32(ctx, fp0, rt);
4272             tcg_gen_ext_i32_tl(t1, fp0);
4273             gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
4274             break;
4275 #if defined(TARGET_MIPS64)
4276         case OPC_GSSDLC1:
4277             check_cp1_enabled(ctx);
4278             t1 = tcg_temp_new();
4279             gen_base_offset_addr(ctx, t0, rs, shf_offset);
4280             gen_load_fpr64(ctx, t1, rt);
4281             gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
4282             break;
4283         case OPC_GSSDRC1:
4284             check_cp1_enabled(ctx);
4285             t1 = tcg_temp_new();
4286             gen_base_offset_addr(ctx, t0, rs, shf_offset);
4287             gen_load_fpr64(ctx, t1, rt);
4288             gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
4289             break;
4290 #endif
4291         default:
4292             MIPS_INVAL("loongson_gsshfs");
4293             gen_reserved_instruction(ctx);
4294             break;
4295         }
4296         break;
4297     default:
4298         MIPS_INVAL("loongson_gslsq");
4299         gen_reserved_instruction(ctx);
4300         break;
4301     }
4302 }
4303 
4304 /* Loongson EXT LDC2/SDC2 */
gen_loongson_lsdc2(DisasContext * ctx,int rt,int rs,int rd)4305 static void gen_loongson_lsdc2(DisasContext *ctx, int rt,
4306                                int rs, int rd)
4307 {
4308     int offset = sextract32(ctx->opcode, 3, 8);
4309     uint32_t opc = MASK_LOONGSON_LSDC2(ctx->opcode);
4310     TCGv t0, t1;
4311     TCGv_i32 fp0;
4312 
4313     /* Pre-conditions */
4314     switch (opc) {
4315     case OPC_GSLBX:
4316     case OPC_GSLHX:
4317     case OPC_GSLWX:
4318     case OPC_GSLDX:
4319         /* prefetch, implement as NOP */
4320         if (rt == 0) {
4321             return;
4322         }
4323         break;
4324     case OPC_GSSBX:
4325     case OPC_GSSHX:
4326     case OPC_GSSWX:
4327     case OPC_GSSDX:
4328         break;
4329     case OPC_GSLWXC1:
4330 #if defined(TARGET_MIPS64)
4331     case OPC_GSLDXC1:
4332 #endif
4333         check_cp1_enabled(ctx);
4334         /* prefetch, implement as NOP */
4335         if (rt == 0) {
4336             return;
4337         }
4338         break;
4339     case OPC_GSSWXC1:
4340 #if defined(TARGET_MIPS64)
4341     case OPC_GSSDXC1:
4342 #endif
4343         check_cp1_enabled(ctx);
4344         break;
4345     default:
4346         MIPS_INVAL("loongson_lsdc2");
4347         gen_reserved_instruction(ctx);
4348         return;
4349         break;
4350     }
4351 
4352     t0 = tcg_temp_new();
4353 
4354     gen_base_offset_addr(ctx, t0, rs, offset);
4355     gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4356 
4357     switch (opc) {
4358     case OPC_GSLBX:
4359         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
4360         gen_store_gpr(t0, rt);
4361         break;
4362     case OPC_GSLHX:
4363         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
4364                            ctx->default_tcg_memop_mask);
4365         gen_store_gpr(t0, rt);
4366         break;
4367     case OPC_GSLWX:
4368         gen_base_offset_addr(ctx, t0, rs, offset);
4369         if (rd) {
4370             gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4371         }
4372         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
4373                            ctx->default_tcg_memop_mask);
4374         gen_store_gpr(t0, rt);
4375         break;
4376 #if defined(TARGET_MIPS64)
4377     case OPC_GSLDX:
4378         gen_base_offset_addr(ctx, t0, rs, offset);
4379         if (rd) {
4380             gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4381         }
4382         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ |
4383                            ctx->default_tcg_memop_mask);
4384         gen_store_gpr(t0, rt);
4385         break;
4386 #endif
4387     case OPC_GSLWXC1:
4388         gen_base_offset_addr(ctx, t0, rs, offset);
4389         if (rd) {
4390             gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4391         }
4392         fp0 = tcg_temp_new_i32();
4393         tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
4394                             ctx->default_tcg_memop_mask);
4395         gen_store_fpr32(ctx, fp0, rt);
4396         break;
4397 #if defined(TARGET_MIPS64)
4398     case OPC_GSLDXC1:
4399         gen_base_offset_addr(ctx, t0, rs, offset);
4400         if (rd) {
4401             gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4402         }
4403         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ |
4404                            ctx->default_tcg_memop_mask);
4405         gen_store_fpr64(ctx, t0, rt);
4406         break;
4407 #endif
4408     case OPC_GSSBX:
4409         t1 = tcg_temp_new();
4410         gen_load_gpr(t1, rt);
4411         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_SB);
4412         break;
4413     case OPC_GSSHX:
4414         t1 = tcg_temp_new();
4415         gen_load_gpr(t1, rt);
4416         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
4417                            ctx->default_tcg_memop_mask);
4418         break;
4419     case OPC_GSSWX:
4420         t1 = tcg_temp_new();
4421         gen_load_gpr(t1, rt);
4422         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
4423                            ctx->default_tcg_memop_mask);
4424         break;
4425 #if defined(TARGET_MIPS64)
4426     case OPC_GSSDX:
4427         t1 = tcg_temp_new();
4428         gen_load_gpr(t1, rt);
4429         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4430                            ctx->default_tcg_memop_mask);
4431         break;
4432 #endif
4433     case OPC_GSSWXC1:
4434         fp0 = tcg_temp_new_i32();
4435         gen_load_fpr32(ctx, fp0, rt);
4436         tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
4437                             ctx->default_tcg_memop_mask);
4438         break;
4439 #if defined(TARGET_MIPS64)
4440     case OPC_GSSDXC1:
4441         t1 = tcg_temp_new();
4442         gen_load_fpr64(ctx, t1, rt);
4443         tcg_gen_qemu_st_i64(t1, t0, ctx->mem_idx, MO_TEUQ |
4444                             ctx->default_tcg_memop_mask);
4445         break;
4446 #endif
4447     default:
4448         break;
4449     }
4450 }
4451 
4452 /* Traps */
gen_trap(DisasContext * ctx,uint32_t opc,int rs,int rt,int16_t imm,int code)4453 static void gen_trap(DisasContext *ctx, uint32_t opc,
4454                      int rs, int rt, int16_t imm, int code)
4455 {
4456     int cond;
4457     TCGv t0 = tcg_temp_new();
4458     TCGv t1 = tcg_temp_new();
4459 
4460     cond = 0;
4461     /* Load needed operands */
4462     switch (opc) {
4463     case OPC_TEQ:
4464     case OPC_TGE:
4465     case OPC_TGEU:
4466     case OPC_TLT:
4467     case OPC_TLTU:
4468     case OPC_TNE:
4469         /* Compare two registers */
4470         if (rs != rt) {
4471             gen_load_gpr(t0, rs);
4472             gen_load_gpr(t1, rt);
4473             cond = 1;
4474         }
4475         break;
4476     case OPC_TEQI:
4477     case OPC_TGEI:
4478     case OPC_TGEIU:
4479     case OPC_TLTI:
4480     case OPC_TLTIU:
4481     case OPC_TNEI:
4482         /* Compare register to immediate */
4483         if (rs != 0 || imm != 0) {
4484             gen_load_gpr(t0, rs);
4485             tcg_gen_movi_tl(t1, (int32_t)imm);
4486             cond = 1;
4487         }
4488         break;
4489     }
4490     if (cond == 0) {
4491         switch (opc) {
4492         case OPC_TEQ:   /* rs == rs */
4493         case OPC_TEQI:  /* r0 == 0  */
4494         case OPC_TGE:   /* rs >= rs */
4495         case OPC_TGEI:  /* r0 >= 0  */
4496         case OPC_TGEU:  /* rs >= rs unsigned */
4497         case OPC_TGEIU: /* r0 >= 0  unsigned */
4498             /* Always trap */
4499 #ifdef CONFIG_USER_ONLY
4500             /* Pass the break code along to cpu_loop. */
4501             tcg_gen_st_i32(tcg_constant_i32(code), tcg_env,
4502                            offsetof(CPUMIPSState, error_code));
4503 #endif
4504             generate_exception_end(ctx, EXCP_TRAP);
4505             break;
4506         case OPC_TLT:   /* rs < rs           */
4507         case OPC_TLTI:  /* r0 < 0            */
4508         case OPC_TLTU:  /* rs < rs unsigned  */
4509         case OPC_TLTIU: /* r0 < 0  unsigned  */
4510         case OPC_TNE:   /* rs != rs          */
4511         case OPC_TNEI:  /* r0 != 0           */
4512             /* Never trap: treat as NOP. */
4513             break;
4514         }
4515     } else {
4516         TCGLabel *l1 = gen_new_label();
4517 
4518         switch (opc) {
4519         case OPC_TEQ:
4520         case OPC_TEQI:
4521             tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
4522             break;
4523         case OPC_TGE:
4524         case OPC_TGEI:
4525             tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
4526             break;
4527         case OPC_TGEU:
4528         case OPC_TGEIU:
4529             tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
4530             break;
4531         case OPC_TLT:
4532         case OPC_TLTI:
4533             tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4534             break;
4535         case OPC_TLTU:
4536         case OPC_TLTIU:
4537             tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
4538             break;
4539         case OPC_TNE:
4540         case OPC_TNEI:
4541             tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
4542             break;
4543         }
4544 #ifdef CONFIG_USER_ONLY
4545         /* Pass the break code along to cpu_loop. */
4546         tcg_gen_st_i32(tcg_constant_i32(code), tcg_env,
4547                        offsetof(CPUMIPSState, error_code));
4548 #endif
4549         /* Like save_cpu_state, only don't update saved values. */
4550         if (ctx->base.pc_next != ctx->saved_pc) {
4551             gen_save_pc(ctx->base.pc_next);
4552         }
4553         if (ctx->hflags != ctx->saved_hflags) {
4554             tcg_gen_movi_i32(hflags, ctx->hflags);
4555         }
4556         generate_exception(ctx, EXCP_TRAP);
4557         gen_set_label(l1);
4558     }
4559 }
4560 
gen_goto_tb(DisasContext * ctx,int n,target_ulong dest)4561 static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
4562 {
4563     if (translator_use_goto_tb(&ctx->base, dest)) {
4564         tcg_gen_goto_tb(n);
4565         gen_save_pc(dest);
4566         tcg_gen_exit_tb(ctx->base.tb, n);
4567     } else {
4568         gen_save_pc(dest);
4569         tcg_gen_lookup_and_goto_ptr();
4570     }
4571 }
4572 
4573 /* 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)4574 static void gen_compute_branch(DisasContext *ctx, uint32_t opc,
4575                                int insn_bytes,
4576                                int rs, int rt, int32_t offset,
4577                                int delayslot_size)
4578 {
4579     target_ulong btgt = -1;
4580     int blink = 0;
4581     int bcond_compute = 0;
4582     TCGv t0 = tcg_temp_new();
4583     TCGv t1 = tcg_temp_new();
4584 
4585     if (ctx->hflags & MIPS_HFLAG_BMASK) {
4586 #ifdef MIPS_DEBUG_DISAS
4587         LOG_DISAS("Branch in delay / forbidden slot at PC 0x%016"
4588                   VADDR_PRIx "\n", ctx->base.pc_next);
4589 #endif
4590         gen_reserved_instruction(ctx);
4591         goto out;
4592     }
4593 
4594     /* Load needed operands */
4595     switch (opc) {
4596     case OPC_BEQ:
4597     case OPC_BEQL:
4598     case OPC_BNE:
4599     case OPC_BNEL:
4600         /* Compare two registers */
4601         if (rs != rt) {
4602             gen_load_gpr(t0, rs);
4603             gen_load_gpr(t1, rt);
4604             bcond_compute = 1;
4605         }
4606         btgt = ctx->base.pc_next + insn_bytes + offset;
4607         break;
4608     case OPC_BGEZ:
4609     case OPC_BGEZAL:
4610     case OPC_BGEZALL:
4611     case OPC_BGEZL:
4612     case OPC_BGTZ:
4613     case OPC_BGTZL:
4614     case OPC_BLEZ:
4615     case OPC_BLEZL:
4616     case OPC_BLTZ:
4617     case OPC_BLTZAL:
4618     case OPC_BLTZALL:
4619     case OPC_BLTZL:
4620         /* Compare to zero */
4621         if (rs != 0) {
4622             gen_load_gpr(t0, rs);
4623             bcond_compute = 1;
4624         }
4625         btgt = ctx->base.pc_next + insn_bytes + offset;
4626         break;
4627     case OPC_BPOSGE32:
4628 #if defined(TARGET_MIPS64)
4629     case OPC_BPOSGE64:
4630         tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4631 #else
4632         tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4633 #endif
4634         bcond_compute = 1;
4635         btgt = ctx->base.pc_next + insn_bytes + offset;
4636         break;
4637     case OPC_J:
4638     case OPC_JAL:
4639         {
4640             /* Jump to immediate */
4641             int jal_mask = ctx->hflags & MIPS_HFLAG_M16 ? 0xF8000000
4642                                                         : 0xF0000000;
4643             btgt = ((ctx->base.pc_next + insn_bytes) & jal_mask)
4644                    | (uint32_t)offset;
4645             break;
4646         }
4647     case OPC_JALX:
4648         /* Jump to immediate */
4649         btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
4650             (uint32_t)offset;
4651         break;
4652     case OPC_JR:
4653     case OPC_JALR:
4654         /* Jump to register */
4655         if (offset != 0 && offset != 16) {
4656             /*
4657              * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
4658              * others are reserved.
4659              */
4660             MIPS_INVAL("jump hint");
4661             gen_reserved_instruction(ctx);
4662             goto out;
4663         }
4664         gen_load_gpr(btarget, rs);
4665         break;
4666     default:
4667         MIPS_INVAL("branch/jump");
4668         gen_reserved_instruction(ctx);
4669         goto out;
4670     }
4671     if (bcond_compute == 0) {
4672         /* No condition to be computed */
4673         switch (opc) {
4674         case OPC_BEQ:     /* rx == rx        */
4675         case OPC_BEQL:    /* rx == rx likely */
4676         case OPC_BGEZ:    /* 0 >= 0          */
4677         case OPC_BGEZL:   /* 0 >= 0 likely   */
4678         case OPC_BLEZ:    /* 0 <= 0          */
4679         case OPC_BLEZL:   /* 0 <= 0 likely   */
4680             /* Always take */
4681             ctx->hflags |= MIPS_HFLAG_B;
4682             break;
4683         case OPC_BGEZAL:  /* 0 >= 0          */
4684         case OPC_BGEZALL: /* 0 >= 0 likely   */
4685             /* Always take and link */
4686             blink = 31;
4687             ctx->hflags |= MIPS_HFLAG_B;
4688             break;
4689         case OPC_BNE:     /* rx != rx        */
4690         case OPC_BGTZ:    /* 0 > 0           */
4691         case OPC_BLTZ:    /* 0 < 0           */
4692             /* Treat as NOP. */
4693             goto out;
4694         case OPC_BLTZAL:  /* 0 < 0           */
4695             /*
4696              * Handle as an unconditional branch to get correct delay
4697              * slot checking.
4698              */
4699             blink = 31;
4700             btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
4701             ctx->hflags |= MIPS_HFLAG_B;
4702             break;
4703         case OPC_BLTZALL: /* 0 < 0 likely */
4704             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
4705             /* Skip the instruction in the delay slot */
4706             ctx->base.pc_next += 4;
4707             goto out;
4708         case OPC_BNEL:    /* rx != rx likely */
4709         case OPC_BGTZL:   /* 0 > 0 likely */
4710         case OPC_BLTZL:   /* 0 < 0 likely */
4711             /* Skip the instruction in the delay slot */
4712             ctx->base.pc_next += 4;
4713             goto out;
4714         case OPC_J:
4715             ctx->hflags |= MIPS_HFLAG_B;
4716             break;
4717         case OPC_JALX:
4718             ctx->hflags |= MIPS_HFLAG_BX;
4719             /* Fallthrough */
4720         case OPC_JAL:
4721             blink = 31;
4722             ctx->hflags |= MIPS_HFLAG_B;
4723             break;
4724         case OPC_JR:
4725             ctx->hflags |= MIPS_HFLAG_BR;
4726             break;
4727         case OPC_JALR:
4728             blink = rt;
4729             ctx->hflags |= MIPS_HFLAG_BR;
4730             break;
4731         default:
4732             MIPS_INVAL("branch/jump");
4733             gen_reserved_instruction(ctx);
4734             goto out;
4735         }
4736     } else {
4737         switch (opc) {
4738         case OPC_BEQ:
4739             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4740             goto not_likely;
4741         case OPC_BEQL:
4742             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4743             goto likely;
4744         case OPC_BNE:
4745             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4746             goto not_likely;
4747         case OPC_BNEL:
4748             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4749             goto likely;
4750         case OPC_BGEZ:
4751             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4752             goto not_likely;
4753         case OPC_BGEZL:
4754             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4755             goto likely;
4756         case OPC_BGEZAL:
4757             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4758             blink = 31;
4759             goto not_likely;
4760         case OPC_BGEZALL:
4761             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4762             blink = 31;
4763             goto likely;
4764         case OPC_BGTZ:
4765             tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4766             goto not_likely;
4767         case OPC_BGTZL:
4768             tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4769             goto likely;
4770         case OPC_BLEZ:
4771             tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4772             goto not_likely;
4773         case OPC_BLEZL:
4774             tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4775             goto likely;
4776         case OPC_BLTZ:
4777             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4778             goto not_likely;
4779         case OPC_BLTZL:
4780             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4781             goto likely;
4782         case OPC_BPOSGE32:
4783             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
4784             goto not_likely;
4785 #if defined(TARGET_MIPS64)
4786         case OPC_BPOSGE64:
4787             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
4788             goto not_likely;
4789 #endif
4790         case OPC_BLTZAL:
4791             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4792             blink = 31;
4793         not_likely:
4794             ctx->hflags |= MIPS_HFLAG_BC;
4795             break;
4796         case OPC_BLTZALL:
4797             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4798             blink = 31;
4799         likely:
4800             ctx->hflags |= MIPS_HFLAG_BL;
4801             break;
4802         default:
4803             MIPS_INVAL("conditional branch/jump");
4804             gen_reserved_instruction(ctx);
4805             goto out;
4806         }
4807     }
4808 
4809     ctx->btarget = btgt;
4810 
4811     switch (delayslot_size) {
4812     case 2:
4813         ctx->hflags |= MIPS_HFLAG_BDS16;
4814         break;
4815     case 4:
4816         ctx->hflags |= MIPS_HFLAG_BDS32;
4817         break;
4818     }
4819 
4820     if (blink > 0) {
4821         int post_delay = insn_bytes + delayslot_size;
4822         int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4823 
4824         tcg_gen_movi_tl(cpu_gpr[blink],
4825                         ctx->base.pc_next + post_delay + lowbit);
4826     }
4827 
4828  out:
4829     if (insn_bytes == 2) {
4830         ctx->hflags |= MIPS_HFLAG_B16;
4831     }
4832 }
4833 
4834 
4835 /* special3 bitfield operations */
gen_bitops(DisasContext * ctx,uint32_t opc,int rt,int rs,int lsb,int msb)4836 static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt,
4837                        int rs, int lsb, int msb)
4838 {
4839     TCGv t0 = tcg_temp_new();
4840     TCGv t1 = tcg_temp_new();
4841 
4842     gen_load_gpr(t1, rs);
4843     switch (opc) {
4844     case OPC_EXT:
4845         if (lsb + msb > 31) {
4846             goto fail;
4847         }
4848         if (msb != 31) {
4849             tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
4850         } else {
4851             /*
4852              * The two checks together imply that lsb == 0,
4853              * so this is a simple sign-extension.
4854              */
4855             tcg_gen_ext32s_tl(t0, t1);
4856         }
4857         break;
4858 #if defined(TARGET_MIPS64)
4859     case OPC_DEXTU:
4860         lsb += 32;
4861         goto do_dext;
4862     case OPC_DEXTM:
4863         msb += 32;
4864         goto do_dext;
4865     case OPC_DEXT:
4866     do_dext:
4867         if (lsb + msb > 63) {
4868             goto fail;
4869         }
4870         tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
4871         break;
4872 #endif
4873     case OPC_INS:
4874         if (lsb > msb) {
4875             goto fail;
4876         }
4877         gen_load_gpr(t0, rt);
4878         tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4879         tcg_gen_ext32s_tl(t0, t0);
4880         break;
4881 #if defined(TARGET_MIPS64)
4882     case OPC_DINSU:
4883         lsb += 32;
4884         /* FALLTHRU */
4885     case OPC_DINSM:
4886         msb += 32;
4887         /* FALLTHRU */
4888     case OPC_DINS:
4889         if (lsb > msb) {
4890             goto fail;
4891         }
4892         gen_load_gpr(t0, rt);
4893         tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4894         break;
4895 #endif
4896     default:
4897 fail:
4898         MIPS_INVAL("bitops");
4899         gen_reserved_instruction(ctx);
4900         return;
4901     }
4902     gen_store_gpr(t0, rt);
4903 }
4904 
gen_bshfl(DisasContext * ctx,uint32_t op2,int rt,int rd)4905 static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd)
4906 {
4907     TCGv t0;
4908 
4909     if (rd == 0) {
4910         /* If no destination, treat it as a NOP. */
4911         return;
4912     }
4913 
4914     t0 = tcg_temp_new();
4915     gen_load_gpr(t0, rt);
4916     switch (op2) {
4917     case OPC_WSBH:
4918         {
4919             TCGv t1 = tcg_temp_new();
4920             TCGv t2 = tcg_constant_tl(0x00FF00FF);
4921 
4922             tcg_gen_shri_tl(t1, t0, 8);
4923             tcg_gen_and_tl(t1, t1, t2);
4924             tcg_gen_and_tl(t0, t0, t2);
4925             tcg_gen_shli_tl(t0, t0, 8);
4926             tcg_gen_or_tl(t0, t0, t1);
4927             tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4928         }
4929         break;
4930     case OPC_SEB:
4931         tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4932         break;
4933     case OPC_SEH:
4934         tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4935         break;
4936 #if defined(TARGET_MIPS64)
4937     case OPC_DSBH:
4938         {
4939             TCGv t1 = tcg_temp_new();
4940             TCGv t2 = tcg_constant_tl(0x00FF00FF00FF00FFULL);
4941 
4942             tcg_gen_shri_tl(t1, t0, 8);
4943             tcg_gen_and_tl(t1, t1, t2);
4944             tcg_gen_and_tl(t0, t0, t2);
4945             tcg_gen_shli_tl(t0, t0, 8);
4946             tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4947         }
4948         break;
4949     case OPC_DSHD:
4950         {
4951             TCGv t1 = tcg_temp_new();
4952             TCGv t2 = tcg_constant_tl(0x0000FFFF0000FFFFULL);
4953 
4954             tcg_gen_shri_tl(t1, t0, 16);
4955             tcg_gen_and_tl(t1, t1, t2);
4956             tcg_gen_and_tl(t0, t0, t2);
4957             tcg_gen_shli_tl(t0, t0, 16);
4958             tcg_gen_or_tl(t0, t0, t1);
4959             tcg_gen_shri_tl(t1, t0, 32);
4960             tcg_gen_shli_tl(t0, t0, 32);
4961             tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4962         }
4963         break;
4964 #endif
4965     default:
4966         MIPS_INVAL("bsfhl");
4967         gen_reserved_instruction(ctx);
4968         return;
4969     }
4970 }
4971 
gen_align_bits(DisasContext * ctx,int wordsz,int rd,int rs,int rt,int bits)4972 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
4973                            int rt, int bits)
4974 {
4975     TCGv t0;
4976     if (rd == 0) {
4977         /* Treat as NOP. */
4978         return;
4979     }
4980     t0 = tcg_temp_new();
4981     if (bits == 0 || bits == wordsz) {
4982         if (bits == 0) {
4983             gen_load_gpr(t0, rt);
4984         } else {
4985             gen_load_gpr(t0, rs);
4986         }
4987         switch (wordsz) {
4988         case 32:
4989             tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4990             break;
4991 #if defined(TARGET_MIPS64)
4992         case 64:
4993             tcg_gen_mov_tl(cpu_gpr[rd], t0);
4994             break;
4995 #endif
4996         }
4997     } else {
4998         TCGv t1 = tcg_temp_new();
4999         gen_load_gpr(t0, rt);
5000         gen_load_gpr(t1, rs);
5001         switch (wordsz) {
5002         case 32:
5003             {
5004                 TCGv_i64 t2 = tcg_temp_new_i64();
5005                 tcg_gen_concat_tl_i64(t2, t1, t0);
5006                 tcg_gen_shri_i64(t2, t2, 32 - bits);
5007                 gen_move_low32(cpu_gpr[rd], t2);
5008             }
5009             break;
5010 #if defined(TARGET_MIPS64)
5011         case 64:
5012             tcg_gen_shli_tl(t0, t0, bits);
5013             tcg_gen_shri_tl(t1, t1, 64 - bits);
5014             tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
5015             break;
5016 #endif
5017         }
5018     }
5019 }
5020 
gen_align(DisasContext * ctx,int wordsz,int rd,int rs,int rt,int bp)5021 void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt, int bp)
5022 {
5023     gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
5024 }
5025 
gen_bitswap(DisasContext * ctx,int opc,int rd,int rt)5026 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
5027 {
5028     TCGv t0;
5029     if (rd == 0) {
5030         /* Treat as NOP. */
5031         return;
5032     }
5033     t0 = tcg_temp_new();
5034     gen_load_gpr(t0, rt);
5035     switch (opc) {
5036     case OPC_BITSWAP:
5037         gen_helper_bitswap(cpu_gpr[rd], t0);
5038         break;
5039 #if defined(TARGET_MIPS64)
5040     case OPC_DBITSWAP:
5041         gen_helper_dbitswap(cpu_gpr[rd], t0);
5042         break;
5043 #endif
5044     }
5045 }
5046 
5047 #ifndef CONFIG_USER_ONLY
5048 /* CP0 (MMU and control) */
gen_mthc0_entrylo(TCGv arg,target_ulong off)5049 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
5050 {
5051     TCGv_i64 t0 = tcg_temp_new_i64();
5052     TCGv_i64 t1 = tcg_temp_new_i64();
5053 
5054     tcg_gen_ext_tl_i64(t0, arg);
5055     tcg_gen_ld_i64(t1, tcg_env, off);
5056 #if defined(TARGET_MIPS64)
5057     tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
5058 #else
5059     tcg_gen_concat32_i64(t1, t1, t0);
5060 #endif
5061     tcg_gen_st_i64(t1, tcg_env, off);
5062 }
5063 
gen_mthc0_store64(TCGv arg,target_ulong off)5064 static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
5065 {
5066     TCGv_i64 t0 = tcg_temp_new_i64();
5067     TCGv_i64 t1 = tcg_temp_new_i64();
5068 
5069     tcg_gen_ext_tl_i64(t0, arg);
5070     tcg_gen_ld_i64(t1, tcg_env, off);
5071     tcg_gen_concat32_i64(t1, t1, t0);
5072     tcg_gen_st_i64(t1, tcg_env, off);
5073 }
5074 
gen_mfhc0_entrylo(TCGv arg,target_ulong off)5075 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
5076 {
5077     TCGv_i64 t0 = tcg_temp_new_i64();
5078 
5079     tcg_gen_ld_i64(t0, tcg_env, off);
5080 #if defined(TARGET_MIPS64)
5081     tcg_gen_shri_i64(t0, t0, 30);
5082 #else
5083     tcg_gen_shri_i64(t0, t0, 32);
5084 #endif
5085     gen_move_low32(arg, t0);
5086 }
5087 
gen_mfhc0_load64(TCGv arg,target_ulong off,int shift)5088 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
5089 {
5090     TCGv_i64 t0 = tcg_temp_new_i64();
5091 
5092     tcg_gen_ld_i64(t0, tcg_env, off);
5093     tcg_gen_shri_i64(t0, t0, 32 + shift);
5094     gen_move_low32(arg, t0);
5095 }
5096 
gen_mfc0_load32(TCGv arg,target_ulong off)5097 static inline void gen_mfc0_load32(TCGv arg, target_ulong off)
5098 {
5099     TCGv_i32 t0 = tcg_temp_new_i32();
5100 
5101     tcg_gen_ld_i32(t0, tcg_env, off);
5102     tcg_gen_ext_i32_tl(arg, t0);
5103 }
5104 
gen_mfc0_load64(TCGv arg,target_ulong off)5105 static inline void gen_mfc0_load64(TCGv arg, target_ulong off)
5106 {
5107     tcg_gen_ld_tl(arg, tcg_env, off);
5108     tcg_gen_ext32s_tl(arg, arg);
5109 }
5110 
gen_mtc0_store32(TCGv arg,target_ulong off)5111 static inline void gen_mtc0_store32(TCGv arg, target_ulong off)
5112 {
5113     TCGv_i32 t0 = tcg_temp_new_i32();
5114 
5115     tcg_gen_trunc_tl_i32(t0, arg);
5116     tcg_gen_st_i32(t0, tcg_env, off);
5117 }
5118 
5119 #define CP0_CHECK(c)                            \
5120     do {                                        \
5121         if (!(c)) {                             \
5122             goto cp0_unimplemented;             \
5123         }                                       \
5124     } while (0)
5125 
gen_mfhc0(DisasContext * ctx,TCGv arg,int reg,int sel)5126 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5127 {
5128     const char *register_name = "invalid";
5129 
5130     switch (reg) {
5131     case CP0_REGISTER_02:
5132         switch (sel) {
5133         case 0:
5134             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5135             gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5136             register_name = "EntryLo0";
5137             break;
5138         default:
5139             goto cp0_unimplemented;
5140         }
5141         break;
5142     case CP0_REGISTER_03:
5143         switch (sel) {
5144         case CP0_REG03__ENTRYLO1:
5145             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5146             gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5147             register_name = "EntryLo1";
5148             break;
5149         default:
5150             goto cp0_unimplemented;
5151         }
5152         break;
5153     case CP0_REGISTER_17:
5154         switch (sel) {
5155         case CP0_REG17__LLADDR:
5156             gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr),
5157                              ctx->CP0_LLAddr_shift);
5158             register_name = "LLAddr";
5159             break;
5160         case CP0_REG17__MAAR:
5161             CP0_CHECK(ctx->mrp);
5162             gen_helper_mfhc0_maar(arg, tcg_env);
5163             register_name = "MAAR";
5164             break;
5165         default:
5166             goto cp0_unimplemented;
5167         }
5168         break;
5169     case CP0_REGISTER_19:
5170         switch (sel) {
5171         case CP0_REG19__WATCHHI0:
5172         case CP0_REG19__WATCHHI1:
5173         case CP0_REG19__WATCHHI2:
5174         case CP0_REG19__WATCHHI3:
5175         case CP0_REG19__WATCHHI4:
5176         case CP0_REG19__WATCHHI5:
5177         case CP0_REG19__WATCHHI6:
5178         case CP0_REG19__WATCHHI7:
5179             /* upper 32 bits are only available when Config5MI != 0 */
5180             CP0_CHECK(ctx->mi);
5181             gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_WatchHi[sel]), 0);
5182             register_name = "WatchHi";
5183             break;
5184         default:
5185             goto cp0_unimplemented;
5186         }
5187         break;
5188     case CP0_REGISTER_28:
5189         switch (sel) {
5190         case 0:
5191         case 2:
5192         case 4:
5193         case 6:
5194             gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
5195             register_name = "TagLo";
5196             break;
5197         default:
5198             goto cp0_unimplemented;
5199         }
5200         break;
5201     default:
5202         goto cp0_unimplemented;
5203     }
5204     trace_mips_translate_c0("mfhc0", register_name, reg, sel);
5205     return;
5206 
5207 cp0_unimplemented:
5208     qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n",
5209                   register_name, reg, sel);
5210     tcg_gen_movi_tl(arg, 0);
5211 }
5212 
gen_mthc0(DisasContext * ctx,TCGv arg,int reg,int sel)5213 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5214 {
5215     const char *register_name = "invalid";
5216     uint64_t mask = ctx->PAMask >> 36;
5217 
5218     switch (reg) {
5219     case CP0_REGISTER_02:
5220         switch (sel) {
5221         case 0:
5222             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5223             tcg_gen_andi_tl(arg, arg, mask);
5224             gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5225             register_name = "EntryLo0";
5226             break;
5227         default:
5228             goto cp0_unimplemented;
5229         }
5230         break;
5231     case CP0_REGISTER_03:
5232         switch (sel) {
5233         case CP0_REG03__ENTRYLO1:
5234             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5235             tcg_gen_andi_tl(arg, arg, mask);
5236             gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5237             register_name = "EntryLo1";
5238             break;
5239         default:
5240             goto cp0_unimplemented;
5241         }
5242         break;
5243     case CP0_REGISTER_17:
5244         switch (sel) {
5245         case CP0_REG17__LLADDR:
5246             /*
5247              * LLAddr is read-only (the only exception is bit 0 if LLB is
5248              * supported); the CP0_LLAddr_rw_bitmask does not seem to be
5249              * relevant for modern MIPS cores supporting MTHC0, therefore
5250              * treating MTHC0 to LLAddr as NOP.
5251              */
5252             register_name = "LLAddr";
5253             break;
5254         case CP0_REG17__MAAR:
5255             CP0_CHECK(ctx->mrp);
5256             gen_helper_mthc0_maar(tcg_env, arg);
5257             register_name = "MAAR";
5258             break;
5259         default:
5260             goto cp0_unimplemented;
5261         }
5262         break;
5263     case CP0_REGISTER_19:
5264         switch (sel) {
5265         case CP0_REG19__WATCHHI0:
5266         case CP0_REG19__WATCHHI1:
5267         case CP0_REG19__WATCHHI2:
5268         case CP0_REG19__WATCHHI3:
5269         case CP0_REG19__WATCHHI4:
5270         case CP0_REG19__WATCHHI5:
5271         case CP0_REG19__WATCHHI6:
5272         case CP0_REG19__WATCHHI7:
5273             /* upper 32 bits are only available when Config5MI != 0 */
5274             CP0_CHECK(ctx->mi);
5275             gen_helper_0e1i(mthc0_watchhi, arg, sel);
5276             register_name = "WatchHi";
5277             break;
5278         default:
5279             goto cp0_unimplemented;
5280         }
5281         break;
5282     case CP0_REGISTER_28:
5283         switch (sel) {
5284         case 0:
5285         case 2:
5286         case 4:
5287         case 6:
5288             tcg_gen_andi_tl(arg, arg, mask);
5289             gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
5290             register_name = "TagLo";
5291             break;
5292         default:
5293             goto cp0_unimplemented;
5294         }
5295         break;
5296     default:
5297         goto cp0_unimplemented;
5298     }
5299     trace_mips_translate_c0("mthc0", register_name, reg, sel);
5300     return;
5301 
5302 cp0_unimplemented:
5303     qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n",
5304                   register_name, reg, sel);
5305 }
5306 
gen_mfc0_unimplemented(DisasContext * ctx,TCGv arg)5307 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
5308 {
5309     if (ctx->insn_flags & ISA_MIPS_R6) {
5310         tcg_gen_movi_tl(arg, 0);
5311     } else {
5312         tcg_gen_movi_tl(arg, ~0);
5313     }
5314 }
5315 
gen_mfc0(DisasContext * ctx,TCGv arg,int reg,int sel)5316 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5317 {
5318     const char *register_name = "invalid";
5319 
5320     if (sel != 0) {
5321         check_insn(ctx, ISA_MIPS_R1);
5322     }
5323 
5324     switch (reg) {
5325     case CP0_REGISTER_00:
5326         switch (sel) {
5327         case CP0_REG00__INDEX:
5328             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5329             register_name = "Index";
5330             break;
5331         case CP0_REG00__MVPCONTROL:
5332             CP0_CHECK(ctx->insn_flags & ASE_MT);
5333             gen_helper_mfc0_mvpcontrol(arg, tcg_env);
5334             register_name = "MVPControl";
5335             break;
5336         case CP0_REG00__MVPCONF0:
5337             CP0_CHECK(ctx->insn_flags & ASE_MT);
5338             gen_helper_mfc0_mvpconf0(arg, tcg_env);
5339             register_name = "MVPConf0";
5340             break;
5341         case CP0_REG00__MVPCONF1:
5342             CP0_CHECK(ctx->insn_flags & ASE_MT);
5343             gen_helper_mfc0_mvpconf1(arg, tcg_env);
5344             register_name = "MVPConf1";
5345             break;
5346         case CP0_REG00__VPCONTROL:
5347             CP0_CHECK(ctx->vp);
5348             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
5349             register_name = "VPControl";
5350             break;
5351         default:
5352             goto cp0_unimplemented;
5353         }
5354         break;
5355     case CP0_REGISTER_01:
5356         switch (sel) {
5357         case CP0_REG01__RANDOM:
5358             CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
5359             gen_helper_mfc0_random(arg, tcg_env);
5360             register_name = "Random";
5361             break;
5362         case CP0_REG01__VPECONTROL:
5363             CP0_CHECK(ctx->insn_flags & ASE_MT);
5364             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5365             register_name = "VPEControl";
5366             break;
5367         case CP0_REG01__VPECONF0:
5368             CP0_CHECK(ctx->insn_flags & ASE_MT);
5369             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5370             register_name = "VPEConf0";
5371             break;
5372         case CP0_REG01__VPECONF1:
5373             CP0_CHECK(ctx->insn_flags & ASE_MT);
5374             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5375             register_name = "VPEConf1";
5376             break;
5377         case CP0_REG01__YQMASK:
5378             CP0_CHECK(ctx->insn_flags & ASE_MT);
5379             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
5380             register_name = "YQMask";
5381             break;
5382         case CP0_REG01__VPESCHEDULE:
5383             CP0_CHECK(ctx->insn_flags & ASE_MT);
5384             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
5385             register_name = "VPESchedule";
5386             break;
5387         case CP0_REG01__VPESCHEFBACK:
5388             CP0_CHECK(ctx->insn_flags & ASE_MT);
5389             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5390             register_name = "VPEScheFBack";
5391             break;
5392         case CP0_REG01__VPEOPT:
5393             CP0_CHECK(ctx->insn_flags & ASE_MT);
5394             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5395             register_name = "VPEOpt";
5396             break;
5397         default:
5398             goto cp0_unimplemented;
5399         }
5400         break;
5401     case CP0_REGISTER_02:
5402         switch (sel) {
5403         case CP0_REG02__ENTRYLO0:
5404             {
5405                 TCGv_i64 tmp = tcg_temp_new_i64();
5406                 tcg_gen_ld_i64(tmp, tcg_env,
5407                                offsetof(CPUMIPSState, CP0_EntryLo0));
5408 #if defined(TARGET_MIPS64)
5409                 if (ctx->rxi) {
5410                     /* Move RI/XI fields to bits 31:30 */
5411                     tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5412                     tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5413                 }
5414 #endif
5415                 gen_move_low32(arg, tmp);
5416             }
5417             register_name = "EntryLo0";
5418             break;
5419         case CP0_REG02__TCSTATUS:
5420             CP0_CHECK(ctx->insn_flags & ASE_MT);
5421             gen_helper_mfc0_tcstatus(arg, tcg_env);
5422             register_name = "TCStatus";
5423             break;
5424         case CP0_REG02__TCBIND:
5425             CP0_CHECK(ctx->insn_flags & ASE_MT);
5426             gen_helper_mfc0_tcbind(arg, tcg_env);
5427             register_name = "TCBind";
5428             break;
5429         case CP0_REG02__TCRESTART:
5430             CP0_CHECK(ctx->insn_flags & ASE_MT);
5431             gen_helper_mfc0_tcrestart(arg, tcg_env);
5432             register_name = "TCRestart";
5433             break;
5434         case CP0_REG02__TCHALT:
5435             CP0_CHECK(ctx->insn_flags & ASE_MT);
5436             gen_helper_mfc0_tchalt(arg, tcg_env);
5437             register_name = "TCHalt";
5438             break;
5439         case CP0_REG02__TCCONTEXT:
5440             CP0_CHECK(ctx->insn_flags & ASE_MT);
5441             gen_helper_mfc0_tccontext(arg, tcg_env);
5442             register_name = "TCContext";
5443             break;
5444         case CP0_REG02__TCSCHEDULE:
5445             CP0_CHECK(ctx->insn_flags & ASE_MT);
5446             gen_helper_mfc0_tcschedule(arg, tcg_env);
5447             register_name = "TCSchedule";
5448             break;
5449         case CP0_REG02__TCSCHEFBACK:
5450             CP0_CHECK(ctx->insn_flags & ASE_MT);
5451             gen_helper_mfc0_tcschefback(arg, tcg_env);
5452             register_name = "TCScheFBack";
5453             break;
5454         default:
5455             goto cp0_unimplemented;
5456         }
5457         break;
5458     case CP0_REGISTER_03:
5459         switch (sel) {
5460         case CP0_REG03__ENTRYLO1:
5461             {
5462                 TCGv_i64 tmp = tcg_temp_new_i64();
5463                 tcg_gen_ld_i64(tmp, tcg_env,
5464                                offsetof(CPUMIPSState, CP0_EntryLo1));
5465 #if defined(TARGET_MIPS64)
5466                 if (ctx->rxi) {
5467                     /* Move RI/XI fields to bits 31:30 */
5468                     tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5469                     tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5470                 }
5471 #endif
5472                 gen_move_low32(arg, tmp);
5473             }
5474             register_name = "EntryLo1";
5475             break;
5476         case CP0_REG03__GLOBALNUM:
5477             CP0_CHECK(ctx->vp);
5478             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
5479             register_name = "GlobalNumber";
5480             break;
5481         default:
5482             goto cp0_unimplemented;
5483         }
5484         break;
5485     case CP0_REGISTER_04:
5486         switch (sel) {
5487         case CP0_REG04__CONTEXT:
5488             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_Context));
5489             tcg_gen_ext32s_tl(arg, arg);
5490             register_name = "Context";
5491             break;
5492         case CP0_REG04__CONTEXTCONFIG:
5493             /* SmartMIPS ASE */
5494             /* gen_helper_mfc0_contextconfig(arg); */
5495             register_name = "ContextConfig";
5496             goto cp0_unimplemented;
5497         case CP0_REG04__USERLOCAL:
5498             CP0_CHECK(ctx->ulri);
5499             tcg_gen_ld_tl(arg, tcg_env,
5500                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5501             tcg_gen_ext32s_tl(arg, arg);
5502             register_name = "UserLocal";
5503             break;
5504         case CP0_REG04__MMID:
5505             CP0_CHECK(ctx->mi);
5506             gen_helper_mtc0_memorymapid(tcg_env, arg);
5507             register_name = "MMID";
5508             break;
5509         default:
5510             goto cp0_unimplemented;
5511         }
5512         break;
5513     case CP0_REGISTER_05:
5514         switch (sel) {
5515         case CP0_REG05__PAGEMASK:
5516             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5517             register_name = "PageMask";
5518             break;
5519         case CP0_REG05__PAGEGRAIN:
5520             check_insn(ctx, ISA_MIPS_R2);
5521             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5522             register_name = "PageGrain";
5523             break;
5524         case CP0_REG05__SEGCTL0:
5525             CP0_CHECK(ctx->sc);
5526             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl0));
5527             tcg_gen_ext32s_tl(arg, arg);
5528             register_name = "SegCtl0";
5529             break;
5530         case CP0_REG05__SEGCTL1:
5531             CP0_CHECK(ctx->sc);
5532             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl1));
5533             tcg_gen_ext32s_tl(arg, arg);
5534             register_name = "SegCtl1";
5535             break;
5536         case CP0_REG05__SEGCTL2:
5537             CP0_CHECK(ctx->sc);
5538             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl2));
5539             tcg_gen_ext32s_tl(arg, arg);
5540             register_name = "SegCtl2";
5541             break;
5542         case CP0_REG05__PWBASE:
5543             check_pw(ctx);
5544             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
5545             register_name = "PWBase";
5546             break;
5547         case CP0_REG05__PWFIELD:
5548             check_pw(ctx);
5549             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
5550             register_name = "PWField";
5551             break;
5552         case CP0_REG05__PWSIZE:
5553             check_pw(ctx);
5554             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
5555             register_name = "PWSize";
5556             break;
5557         default:
5558             goto cp0_unimplemented;
5559         }
5560         break;
5561     case CP0_REGISTER_06:
5562         switch (sel) {
5563         case CP0_REG06__WIRED:
5564             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5565             register_name = "Wired";
5566             break;
5567         case CP0_REG06__SRSCONF0:
5568             check_insn(ctx, ISA_MIPS_R2);
5569             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5570             register_name = "SRSConf0";
5571             break;
5572         case CP0_REG06__SRSCONF1:
5573             check_insn(ctx, ISA_MIPS_R2);
5574             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5575             register_name = "SRSConf1";
5576             break;
5577         case CP0_REG06__SRSCONF2:
5578             check_insn(ctx, ISA_MIPS_R2);
5579             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5580             register_name = "SRSConf2";
5581             break;
5582         case CP0_REG06__SRSCONF3:
5583             check_insn(ctx, ISA_MIPS_R2);
5584             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5585             register_name = "SRSConf3";
5586             break;
5587         case CP0_REG06__SRSCONF4:
5588             check_insn(ctx, ISA_MIPS_R2);
5589             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5590             register_name = "SRSConf4";
5591             break;
5592         case CP0_REG06__PWCTL:
5593             check_pw(ctx);
5594             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
5595             register_name = "PWCtl";
5596             break;
5597         default:
5598             goto cp0_unimplemented;
5599         }
5600         break;
5601     case CP0_REGISTER_07:
5602         switch (sel) {
5603         case CP0_REG07__HWRENA:
5604             check_insn(ctx, ISA_MIPS_R2);
5605             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5606             register_name = "HWREna";
5607             break;
5608         default:
5609             goto cp0_unimplemented;
5610         }
5611         break;
5612     case CP0_REGISTER_08:
5613         switch (sel) {
5614         case CP0_REG08__BADVADDR:
5615             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5616             tcg_gen_ext32s_tl(arg, arg);
5617             register_name = "BadVAddr";
5618             break;
5619         case CP0_REG08__BADINSTR:
5620             CP0_CHECK(ctx->bi);
5621             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5622             register_name = "BadInstr";
5623             break;
5624         case CP0_REG08__BADINSTRP:
5625             CP0_CHECK(ctx->bp);
5626             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5627             register_name = "BadInstrP";
5628             break;
5629         case CP0_REG08__BADINSTRX:
5630             CP0_CHECK(ctx->bi);
5631             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
5632             tcg_gen_andi_tl(arg, arg, ~0xffff);
5633             register_name = "BadInstrX";
5634             break;
5635         default:
5636             goto cp0_unimplemented;
5637         }
5638         break;
5639     case CP0_REGISTER_09:
5640         switch (sel) {
5641         case CP0_REG09__COUNT:
5642             /* Mark as an IO operation because we read the time.  */
5643             translator_io_start(&ctx->base);
5644 
5645             gen_helper_mfc0_count(arg, tcg_env);
5646             /*
5647              * Break the TB to be able to take timer interrupts immediately
5648              * after reading count. DISAS_STOP isn't sufficient, we need to
5649              * ensure we break completely out of translated code.
5650              */
5651             gen_save_pc(ctx->base.pc_next + 4);
5652             ctx->base.is_jmp = DISAS_EXIT;
5653             register_name = "Count";
5654             break;
5655         default:
5656             goto cp0_unimplemented;
5657         }
5658         break;
5659     case CP0_REGISTER_10:
5660         switch (sel) {
5661         case CP0_REG10__ENTRYHI:
5662             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EntryHi));
5663             tcg_gen_ext32s_tl(arg, arg);
5664             register_name = "EntryHi";
5665             break;
5666         default:
5667             goto cp0_unimplemented;
5668         }
5669         break;
5670     case CP0_REGISTER_11:
5671         switch (sel) {
5672         case CP0_REG11__COMPARE:
5673             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5674             register_name = "Compare";
5675             break;
5676         /* 6,7 are implementation dependent */
5677         default:
5678             goto cp0_unimplemented;
5679         }
5680         break;
5681     case CP0_REGISTER_12:
5682         switch (sel) {
5683         case CP0_REG12__STATUS:
5684             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5685             register_name = "Status";
5686             break;
5687         case CP0_REG12__INTCTL:
5688             check_insn(ctx, ISA_MIPS_R2);
5689             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5690             register_name = "IntCtl";
5691             break;
5692         case CP0_REG12__SRSCTL:
5693             check_insn(ctx, ISA_MIPS_R2);
5694             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5695             register_name = "SRSCtl";
5696             break;
5697         case CP0_REG12__SRSMAP:
5698             check_insn(ctx, ISA_MIPS_R2);
5699             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5700             register_name = "SRSMap";
5701             break;
5702         default:
5703             goto cp0_unimplemented;
5704        }
5705         break;
5706     case CP0_REGISTER_13:
5707         switch (sel) {
5708         case CP0_REG13__CAUSE:
5709             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5710             register_name = "Cause";
5711             break;
5712         default:
5713             goto cp0_unimplemented;
5714        }
5715         break;
5716     case CP0_REGISTER_14:
5717         switch (sel) {
5718         case CP0_REG14__EPC:
5719             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC));
5720             tcg_gen_ext32s_tl(arg, arg);
5721             register_name = "EPC";
5722             break;
5723         default:
5724             goto cp0_unimplemented;
5725         }
5726         break;
5727     case CP0_REGISTER_15:
5728         switch (sel) {
5729         case CP0_REG15__PRID:
5730             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5731             register_name = "PRid";
5732             break;
5733         case CP0_REG15__EBASE:
5734             check_insn(ctx, ISA_MIPS_R2);
5735             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EBase));
5736             tcg_gen_ext32s_tl(arg, arg);
5737             register_name = "EBase";
5738             break;
5739         case CP0_REG15__CMGCRBASE:
5740             check_insn(ctx, ISA_MIPS_R2);
5741             CP0_CHECK(ctx->cmgcr);
5742             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
5743             tcg_gen_ext32s_tl(arg, arg);
5744             register_name = "CMGCRBase";
5745             break;
5746         default:
5747             goto cp0_unimplemented;
5748        }
5749         break;
5750     case CP0_REGISTER_16:
5751         switch (sel) {
5752         case CP0_REG16__CONFIG:
5753             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5754             register_name = "Config";
5755             break;
5756         case CP0_REG16__CONFIG1:
5757             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5758             register_name = "Config1";
5759             break;
5760         case CP0_REG16__CONFIG2:
5761             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5762             register_name = "Config2";
5763             break;
5764         case CP0_REG16__CONFIG3:
5765             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5766             register_name = "Config3";
5767             break;
5768         case CP0_REG16__CONFIG4:
5769             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
5770             register_name = "Config4";
5771             break;
5772         case CP0_REG16__CONFIG5:
5773             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
5774             register_name = "Config5";
5775             break;
5776         /* 6,7 are implementation dependent */
5777         case CP0_REG16__CONFIG6:
5778             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5779             register_name = "Config6";
5780             break;
5781         case CP0_REG16__CONFIG7:
5782             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5783             register_name = "Config7";
5784             break;
5785         default:
5786             goto cp0_unimplemented;
5787         }
5788         break;
5789     case CP0_REGISTER_17:
5790         switch (sel) {
5791         case CP0_REG17__LLADDR:
5792             gen_helper_mfc0_lladdr(arg, tcg_env);
5793             register_name = "LLAddr";
5794             break;
5795         case CP0_REG17__MAAR:
5796             CP0_CHECK(ctx->mrp);
5797             gen_helper_mfc0_maar(arg, tcg_env);
5798             register_name = "MAAR";
5799             break;
5800         case CP0_REG17__MAARI:
5801             CP0_CHECK(ctx->mrp);
5802             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
5803             register_name = "MAARI";
5804             break;
5805         default:
5806             goto cp0_unimplemented;
5807         }
5808         break;
5809     case CP0_REGISTER_18:
5810         switch (sel) {
5811         case CP0_REG18__WATCHLO0:
5812         case CP0_REG18__WATCHLO1:
5813         case CP0_REG18__WATCHLO2:
5814         case CP0_REG18__WATCHLO3:
5815         case CP0_REG18__WATCHLO4:
5816         case CP0_REG18__WATCHLO5:
5817         case CP0_REG18__WATCHLO6:
5818         case CP0_REG18__WATCHLO7:
5819             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
5820             gen_helper_1e0i(mfc0_watchlo, arg, sel);
5821             register_name = "WatchLo";
5822             break;
5823         default:
5824             goto cp0_unimplemented;
5825         }
5826         break;
5827     case CP0_REGISTER_19:
5828         switch (sel) {
5829         case CP0_REG19__WATCHHI0:
5830         case CP0_REG19__WATCHHI1:
5831         case CP0_REG19__WATCHHI2:
5832         case CP0_REG19__WATCHHI3:
5833         case CP0_REG19__WATCHHI4:
5834         case CP0_REG19__WATCHHI5:
5835         case CP0_REG19__WATCHHI6:
5836         case CP0_REG19__WATCHHI7:
5837             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
5838             gen_helper_1e0i(mfc0_watchhi, arg, sel);
5839             register_name = "WatchHi";
5840             break;
5841         default:
5842             goto cp0_unimplemented;
5843         }
5844         break;
5845     case CP0_REGISTER_20:
5846         switch (sel) {
5847         case CP0_REG20__XCONTEXT:
5848 #if defined(TARGET_MIPS64)
5849             check_insn(ctx, ISA_MIPS3);
5850             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_XContext));
5851             tcg_gen_ext32s_tl(arg, arg);
5852             register_name = "XContext";
5853             break;
5854 #endif
5855         default:
5856             goto cp0_unimplemented;
5857         }
5858         break;
5859     case CP0_REGISTER_21:
5860        /* Officially reserved, but sel 0 is used for R1x000 framemask */
5861         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
5862         switch (sel) {
5863         case 0:
5864             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5865             register_name = "Framemask";
5866             break;
5867         default:
5868             goto cp0_unimplemented;
5869         }
5870         break;
5871     case CP0_REGISTER_22:
5872         tcg_gen_movi_tl(arg, 0); /* unimplemented */
5873         register_name = "'Diagnostic"; /* implementation dependent */
5874         break;
5875     case CP0_REGISTER_23:
5876         switch (sel) {
5877         case CP0_REG23__DEBUG:
5878             gen_helper_mfc0_debug(arg, tcg_env); /* EJTAG support */
5879             register_name = "Debug";
5880             break;
5881         case CP0_REG23__TRACECONTROL:
5882             /* PDtrace support */
5883             /* gen_helper_mfc0_tracecontrol(arg);  */
5884             register_name = "TraceControl";
5885             goto cp0_unimplemented;
5886         case CP0_REG23__TRACECONTROL2:
5887             /* PDtrace support */
5888             /* gen_helper_mfc0_tracecontrol2(arg); */
5889             register_name = "TraceControl2";
5890             goto cp0_unimplemented;
5891         case CP0_REG23__USERTRACEDATA1:
5892             /* PDtrace support */
5893             /* gen_helper_mfc0_usertracedata1(arg);*/
5894             register_name = "UserTraceData1";
5895             goto cp0_unimplemented;
5896         case CP0_REG23__TRACEIBPC:
5897             /* PDtrace support */
5898             /* gen_helper_mfc0_traceibpc(arg);     */
5899             register_name = "TraceIBPC";
5900             goto cp0_unimplemented;
5901         case CP0_REG23__TRACEDBPC:
5902             /* PDtrace support */
5903             /* gen_helper_mfc0_tracedbpc(arg);     */
5904             register_name = "TraceDBPC";
5905             goto cp0_unimplemented;
5906         default:
5907             goto cp0_unimplemented;
5908         }
5909         break;
5910     case CP0_REGISTER_24:
5911         switch (sel) {
5912         case CP0_REG24__DEPC:
5913             /* EJTAG support */
5914             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC));
5915             tcg_gen_ext32s_tl(arg, arg);
5916             register_name = "DEPC";
5917             break;
5918         default:
5919             goto cp0_unimplemented;
5920         }
5921         break;
5922     case CP0_REGISTER_25:
5923         switch (sel) {
5924         case CP0_REG25__PERFCTL0:
5925             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5926             register_name = "Performance0";
5927             break;
5928         case CP0_REG25__PERFCNT0:
5929             /* gen_helper_mfc0_performance1(arg); */
5930             register_name = "Performance1";
5931             goto cp0_unimplemented;
5932         case CP0_REG25__PERFCTL1:
5933             /* gen_helper_mfc0_performance2(arg); */
5934             register_name = "Performance2";
5935             goto cp0_unimplemented;
5936         case CP0_REG25__PERFCNT1:
5937             /* gen_helper_mfc0_performance3(arg); */
5938             register_name = "Performance3";
5939             goto cp0_unimplemented;
5940         case CP0_REG25__PERFCTL2:
5941             /* gen_helper_mfc0_performance4(arg); */
5942             register_name = "Performance4";
5943             goto cp0_unimplemented;
5944         case CP0_REG25__PERFCNT2:
5945             /* gen_helper_mfc0_performance5(arg); */
5946             register_name = "Performance5";
5947             goto cp0_unimplemented;
5948         case CP0_REG25__PERFCTL3:
5949             /* gen_helper_mfc0_performance6(arg); */
5950             register_name = "Performance6";
5951             goto cp0_unimplemented;
5952         case CP0_REG25__PERFCNT3:
5953             /* gen_helper_mfc0_performance7(arg); */
5954             register_name = "Performance7";
5955             goto cp0_unimplemented;
5956         default:
5957             goto cp0_unimplemented;
5958         }
5959         break;
5960     case CP0_REGISTER_26:
5961         switch (sel) {
5962         case CP0_REG26__ERRCTL:
5963             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
5964             register_name = "ErrCtl";
5965             break;
5966         default:
5967             goto cp0_unimplemented;
5968         }
5969         break;
5970     case CP0_REGISTER_27:
5971         switch (sel) {
5972         case CP0_REG27__CACHERR:
5973             tcg_gen_movi_tl(arg, 0); /* unimplemented */
5974             register_name = "CacheErr";
5975             break;
5976         default:
5977             goto cp0_unimplemented;
5978         }
5979         break;
5980     case CP0_REGISTER_28:
5981         switch (sel) {
5982         case CP0_REG28__TAGLO:
5983         case CP0_REG28__TAGLO1:
5984         case CP0_REG28__TAGLO2:
5985         case CP0_REG28__TAGLO3:
5986             {
5987                 TCGv_i64 tmp = tcg_temp_new_i64();
5988                 tcg_gen_ld_i64(tmp, tcg_env, offsetof(CPUMIPSState, CP0_TagLo));
5989                 gen_move_low32(arg, tmp);
5990             }
5991             register_name = "TagLo";
5992             break;
5993         case CP0_REG28__DATALO:
5994         case CP0_REG28__DATALO1:
5995         case CP0_REG28__DATALO2:
5996         case CP0_REG28__DATALO3:
5997             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5998             register_name = "DataLo";
5999             break;
6000         default:
6001             goto cp0_unimplemented;
6002         }
6003         break;
6004     case CP0_REGISTER_29:
6005         switch (sel) {
6006         case CP0_REG29__TAGHI:
6007         case CP0_REG29__TAGHI1:
6008         case CP0_REG29__TAGHI2:
6009         case CP0_REG29__TAGHI3:
6010             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
6011             register_name = "TagHi";
6012             break;
6013         case CP0_REG29__DATAHI:
6014         case CP0_REG29__DATAHI1:
6015         case CP0_REG29__DATAHI2:
6016         case CP0_REG29__DATAHI3:
6017             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
6018             register_name = "DataHi";
6019             break;
6020         default:
6021             goto cp0_unimplemented;
6022         }
6023         break;
6024     case CP0_REGISTER_30:
6025         switch (sel) {
6026         case CP0_REG30__ERROREPC:
6027             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6028             tcg_gen_ext32s_tl(arg, arg);
6029             register_name = "ErrorEPC";
6030             break;
6031         default:
6032             goto cp0_unimplemented;
6033         }
6034         break;
6035     case CP0_REGISTER_31:
6036         switch (sel) {
6037         case CP0_REG31__DESAVE:
6038             /* EJTAG support */
6039             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6040             register_name = "DESAVE";
6041             break;
6042         case CP0_REG31__KSCRATCH1:
6043         case CP0_REG31__KSCRATCH2:
6044         case CP0_REG31__KSCRATCH3:
6045         case CP0_REG31__KSCRATCH4:
6046         case CP0_REG31__KSCRATCH5:
6047         case CP0_REG31__KSCRATCH6:
6048             CP0_CHECK(ctx->kscrexist & (1 << sel));
6049             tcg_gen_ld_tl(arg, tcg_env,
6050                           offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
6051             tcg_gen_ext32s_tl(arg, arg);
6052             register_name = "KScratch";
6053             break;
6054         default:
6055             goto cp0_unimplemented;
6056         }
6057         break;
6058     default:
6059        goto cp0_unimplemented;
6060     }
6061     trace_mips_translate_c0("mfc0", register_name, reg, sel);
6062     return;
6063 
6064 cp0_unimplemented:
6065     qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n",
6066                   register_name, reg, sel);
6067     gen_mfc0_unimplemented(ctx, arg);
6068 }
6069 
gen_mtc0(DisasContext * ctx,TCGv arg,int reg,int sel)6070 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6071 {
6072     const char *register_name = "invalid";
6073     bool icount;
6074 
6075     if (sel != 0) {
6076         check_insn(ctx, ISA_MIPS_R1);
6077     }
6078 
6079     icount = translator_io_start(&ctx->base);
6080 
6081     switch (reg) {
6082     case CP0_REGISTER_00:
6083         switch (sel) {
6084         case CP0_REG00__INDEX:
6085             gen_helper_mtc0_index(tcg_env, arg);
6086             register_name = "Index";
6087             break;
6088         case CP0_REG00__MVPCONTROL:
6089             CP0_CHECK(ctx->insn_flags & ASE_MT);
6090             gen_helper_mtc0_mvpcontrol(tcg_env, arg);
6091             register_name = "MVPControl";
6092             break;
6093         case CP0_REG00__MVPCONF0:
6094             CP0_CHECK(ctx->insn_flags & ASE_MT);
6095             /* ignored */
6096             register_name = "MVPConf0";
6097             break;
6098         case CP0_REG00__MVPCONF1:
6099             CP0_CHECK(ctx->insn_flags & ASE_MT);
6100             /* ignored */
6101             register_name = "MVPConf1";
6102             break;
6103         case CP0_REG00__VPCONTROL:
6104             CP0_CHECK(ctx->vp);
6105             /* ignored */
6106             register_name = "VPControl";
6107             break;
6108         default:
6109             goto cp0_unimplemented;
6110         }
6111         break;
6112     case CP0_REGISTER_01:
6113         switch (sel) {
6114         case CP0_REG01__RANDOM:
6115             /* ignored */
6116             register_name = "Random";
6117             break;
6118         case CP0_REG01__VPECONTROL:
6119             CP0_CHECK(ctx->insn_flags & ASE_MT);
6120             gen_helper_mtc0_vpecontrol(tcg_env, arg);
6121             register_name = "VPEControl";
6122             break;
6123         case CP0_REG01__VPECONF0:
6124             CP0_CHECK(ctx->insn_flags & ASE_MT);
6125             gen_helper_mtc0_vpeconf0(tcg_env, arg);
6126             register_name = "VPEConf0";
6127             break;
6128         case CP0_REG01__VPECONF1:
6129             CP0_CHECK(ctx->insn_flags & ASE_MT);
6130             gen_helper_mtc0_vpeconf1(tcg_env, arg);
6131             register_name = "VPEConf1";
6132             break;
6133         case CP0_REG01__YQMASK:
6134             CP0_CHECK(ctx->insn_flags & ASE_MT);
6135             gen_helper_mtc0_yqmask(tcg_env, arg);
6136             register_name = "YQMask";
6137             break;
6138         case CP0_REG01__VPESCHEDULE:
6139             CP0_CHECK(ctx->insn_flags & ASE_MT);
6140             tcg_gen_st_tl(arg, tcg_env,
6141                           offsetof(CPUMIPSState, CP0_VPESchedule));
6142             register_name = "VPESchedule";
6143             break;
6144         case CP0_REG01__VPESCHEFBACK:
6145             CP0_CHECK(ctx->insn_flags & ASE_MT);
6146             tcg_gen_st_tl(arg, tcg_env,
6147                           offsetof(CPUMIPSState, CP0_VPEScheFBack));
6148             register_name = "VPEScheFBack";
6149             break;
6150         case CP0_REG01__VPEOPT:
6151             CP0_CHECK(ctx->insn_flags & ASE_MT);
6152             gen_helper_mtc0_vpeopt(tcg_env, arg);
6153             register_name = "VPEOpt";
6154             break;
6155         default:
6156             goto cp0_unimplemented;
6157         }
6158         break;
6159     case CP0_REGISTER_02:
6160         switch (sel) {
6161         case CP0_REG02__ENTRYLO0:
6162             gen_helper_mtc0_entrylo0(tcg_env, arg);
6163             register_name = "EntryLo0";
6164             break;
6165         case CP0_REG02__TCSTATUS:
6166             CP0_CHECK(ctx->insn_flags & ASE_MT);
6167             gen_helper_mtc0_tcstatus(tcg_env, arg);
6168             register_name = "TCStatus";
6169             break;
6170         case CP0_REG02__TCBIND:
6171             CP0_CHECK(ctx->insn_flags & ASE_MT);
6172             gen_helper_mtc0_tcbind(tcg_env, arg);
6173             register_name = "TCBind";
6174             break;
6175         case CP0_REG02__TCRESTART:
6176             CP0_CHECK(ctx->insn_flags & ASE_MT);
6177             gen_helper_mtc0_tcrestart(tcg_env, arg);
6178             register_name = "TCRestart";
6179             break;
6180         case CP0_REG02__TCHALT:
6181             CP0_CHECK(ctx->insn_flags & ASE_MT);
6182             gen_helper_mtc0_tchalt(tcg_env, arg);
6183             register_name = "TCHalt";
6184             break;
6185         case CP0_REG02__TCCONTEXT:
6186             CP0_CHECK(ctx->insn_flags & ASE_MT);
6187             gen_helper_mtc0_tccontext(tcg_env, arg);
6188             register_name = "TCContext";
6189             break;
6190         case CP0_REG02__TCSCHEDULE:
6191             CP0_CHECK(ctx->insn_flags & ASE_MT);
6192             gen_helper_mtc0_tcschedule(tcg_env, arg);
6193             register_name = "TCSchedule";
6194             break;
6195         case CP0_REG02__TCSCHEFBACK:
6196             CP0_CHECK(ctx->insn_flags & ASE_MT);
6197             gen_helper_mtc0_tcschefback(tcg_env, arg);
6198             register_name = "TCScheFBack";
6199             break;
6200         default:
6201             goto cp0_unimplemented;
6202         }
6203         break;
6204     case CP0_REGISTER_03:
6205         switch (sel) {
6206         case CP0_REG03__ENTRYLO1:
6207             gen_helper_mtc0_entrylo1(tcg_env, arg);
6208             register_name = "EntryLo1";
6209             break;
6210         case CP0_REG03__GLOBALNUM:
6211             CP0_CHECK(ctx->vp);
6212             /* ignored */
6213             register_name = "GlobalNumber";
6214             break;
6215         default:
6216             goto cp0_unimplemented;
6217         }
6218         break;
6219     case CP0_REGISTER_04:
6220         switch (sel) {
6221         case CP0_REG04__CONTEXT:
6222             gen_helper_mtc0_context(tcg_env, arg);
6223             register_name = "Context";
6224             break;
6225         case CP0_REG04__CONTEXTCONFIG:
6226             /* SmartMIPS ASE */
6227             /* gen_helper_mtc0_contextconfig(arg); */
6228             register_name = "ContextConfig";
6229             goto cp0_unimplemented;
6230         case CP0_REG04__USERLOCAL:
6231             CP0_CHECK(ctx->ulri);
6232             tcg_gen_st_tl(arg, tcg_env,
6233                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6234             register_name = "UserLocal";
6235             break;
6236         case CP0_REG04__MMID:
6237             CP0_CHECK(ctx->mi);
6238             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID));
6239             register_name = "MMID";
6240             break;
6241         default:
6242             goto cp0_unimplemented;
6243         }
6244         break;
6245     case CP0_REGISTER_05:
6246         switch (sel) {
6247         case CP0_REG05__PAGEMASK:
6248             gen_helper_mtc0_pagemask(tcg_env, arg);
6249             register_name = "PageMask";
6250             break;
6251         case CP0_REG05__PAGEGRAIN:
6252             check_insn(ctx, ISA_MIPS_R2);
6253             gen_helper_mtc0_pagegrain(tcg_env, arg);
6254             register_name = "PageGrain";
6255             ctx->base.is_jmp = DISAS_STOP;
6256             break;
6257         case CP0_REG05__SEGCTL0:
6258             CP0_CHECK(ctx->sc);
6259             gen_helper_mtc0_segctl0(tcg_env, arg);
6260             register_name = "SegCtl0";
6261             break;
6262         case CP0_REG05__SEGCTL1:
6263             CP0_CHECK(ctx->sc);
6264             gen_helper_mtc0_segctl1(tcg_env, arg);
6265             register_name = "SegCtl1";
6266             break;
6267         case CP0_REG05__SEGCTL2:
6268             CP0_CHECK(ctx->sc);
6269             gen_helper_mtc0_segctl2(tcg_env, arg);
6270             register_name = "SegCtl2";
6271             break;
6272         case CP0_REG05__PWBASE:
6273             check_pw(ctx);
6274             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6275             register_name = "PWBase";
6276             break;
6277         case CP0_REG05__PWFIELD:
6278             check_pw(ctx);
6279             gen_helper_mtc0_pwfield(tcg_env, arg);
6280             register_name = "PWField";
6281             break;
6282         case CP0_REG05__PWSIZE:
6283             check_pw(ctx);
6284             gen_helper_mtc0_pwsize(tcg_env, arg);
6285             register_name = "PWSize";
6286             break;
6287         default:
6288             goto cp0_unimplemented;
6289         }
6290         break;
6291     case CP0_REGISTER_06:
6292         switch (sel) {
6293         case CP0_REG06__WIRED:
6294             gen_helper_mtc0_wired(tcg_env, arg);
6295             register_name = "Wired";
6296             break;
6297         case CP0_REG06__SRSCONF0:
6298             check_insn(ctx, ISA_MIPS_R2);
6299             gen_helper_mtc0_srsconf0(tcg_env, arg);
6300             register_name = "SRSConf0";
6301             break;
6302         case CP0_REG06__SRSCONF1:
6303             check_insn(ctx, ISA_MIPS_R2);
6304             gen_helper_mtc0_srsconf1(tcg_env, arg);
6305             register_name = "SRSConf1";
6306             break;
6307         case CP0_REG06__SRSCONF2:
6308             check_insn(ctx, ISA_MIPS_R2);
6309             gen_helper_mtc0_srsconf2(tcg_env, arg);
6310             register_name = "SRSConf2";
6311             break;
6312         case CP0_REG06__SRSCONF3:
6313             check_insn(ctx, ISA_MIPS_R2);
6314             gen_helper_mtc0_srsconf3(tcg_env, arg);
6315             register_name = "SRSConf3";
6316             break;
6317         case CP0_REG06__SRSCONF4:
6318             check_insn(ctx, ISA_MIPS_R2);
6319             gen_helper_mtc0_srsconf4(tcg_env, arg);
6320             register_name = "SRSConf4";
6321             break;
6322         case CP0_REG06__PWCTL:
6323             check_pw(ctx);
6324             gen_helper_mtc0_pwctl(tcg_env, arg);
6325             register_name = "PWCtl";
6326             break;
6327         default:
6328             goto cp0_unimplemented;
6329         }
6330         break;
6331     case CP0_REGISTER_07:
6332         switch (sel) {
6333         case CP0_REG07__HWRENA:
6334             check_insn(ctx, ISA_MIPS_R2);
6335             gen_helper_mtc0_hwrena(tcg_env, arg);
6336             ctx->base.is_jmp = DISAS_STOP;
6337             register_name = "HWREna";
6338             break;
6339         default:
6340             goto cp0_unimplemented;
6341         }
6342         break;
6343     case CP0_REGISTER_08:
6344         switch (sel) {
6345         case CP0_REG08__BADVADDR:
6346             /* ignored */
6347             register_name = "BadVAddr";
6348             break;
6349         case CP0_REG08__BADINSTR:
6350             /* ignored */
6351             register_name = "BadInstr";
6352             break;
6353         case CP0_REG08__BADINSTRP:
6354             /* ignored */
6355             register_name = "BadInstrP";
6356             break;
6357         case CP0_REG08__BADINSTRX:
6358             /* ignored */
6359             register_name = "BadInstrX";
6360             break;
6361         default:
6362             goto cp0_unimplemented;
6363         }
6364         break;
6365     case CP0_REGISTER_09:
6366         switch (sel) {
6367         case CP0_REG09__COUNT:
6368             gen_helper_mtc0_count(tcg_env, arg);
6369             register_name = "Count";
6370             break;
6371         default:
6372             goto cp0_unimplemented;
6373         }
6374         break;
6375     case CP0_REGISTER_10:
6376         switch (sel) {
6377         case CP0_REG10__ENTRYHI:
6378             gen_helper_mtc0_entryhi(tcg_env, arg);
6379             register_name = "EntryHi";
6380             break;
6381         default:
6382             goto cp0_unimplemented;
6383         }
6384         break;
6385     case CP0_REGISTER_11:
6386         switch (sel) {
6387         case CP0_REG11__COMPARE:
6388             gen_helper_mtc0_compare(tcg_env, arg);
6389             register_name = "Compare";
6390             break;
6391         /* 6,7 are implementation dependent */
6392         default:
6393             goto cp0_unimplemented;
6394         }
6395         break;
6396     case CP0_REGISTER_12:
6397         switch (sel) {
6398         case CP0_REG12__STATUS:
6399             save_cpu_state(ctx, 1);
6400             gen_helper_mtc0_status(tcg_env, arg);
6401             /* DISAS_STOP isn't good enough here, hflags may have changed. */
6402             gen_save_pc(ctx->base.pc_next + 4);
6403             ctx->base.is_jmp = DISAS_EXIT;
6404             register_name = "Status";
6405             break;
6406         case CP0_REG12__INTCTL:
6407             check_insn(ctx, ISA_MIPS_R2);
6408             gen_helper_mtc0_intctl(tcg_env, arg);
6409             /* Stop translation as we may have switched the execution mode */
6410             ctx->base.is_jmp = DISAS_STOP;
6411             register_name = "IntCtl";
6412             break;
6413         case CP0_REG12__SRSCTL:
6414             check_insn(ctx, ISA_MIPS_R2);
6415             gen_helper_mtc0_srsctl(tcg_env, arg);
6416             /* Stop translation as we may have switched the execution mode */
6417             ctx->base.is_jmp = DISAS_STOP;
6418             register_name = "SRSCtl";
6419             break;
6420         case CP0_REG12__SRSMAP:
6421             check_insn(ctx, ISA_MIPS_R2);
6422             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6423             /* Stop translation as we may have switched the execution mode */
6424             ctx->base.is_jmp = DISAS_STOP;
6425             register_name = "SRSMap";
6426             break;
6427         default:
6428             goto cp0_unimplemented;
6429         }
6430         break;
6431     case CP0_REGISTER_13:
6432         switch (sel) {
6433         case CP0_REG13__CAUSE:
6434             save_cpu_state(ctx, 1);
6435             gen_helper_mtc0_cause(tcg_env, arg);
6436             /*
6437              * Stop translation as we may have triggered an interrupt.
6438              * DISAS_STOP isn't sufficient, we need to ensure we break out of
6439              * translated code to check for pending interrupts.
6440              */
6441             gen_save_pc(ctx->base.pc_next + 4);
6442             ctx->base.is_jmp = DISAS_EXIT;
6443             register_name = "Cause";
6444             break;
6445         default:
6446             goto cp0_unimplemented;
6447         }
6448         break;
6449     case CP0_REGISTER_14:
6450         switch (sel) {
6451         case CP0_REG14__EPC:
6452             tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC));
6453             register_name = "EPC";
6454             break;
6455         default:
6456             goto cp0_unimplemented;
6457         }
6458         break;
6459     case CP0_REGISTER_15:
6460         switch (sel) {
6461         case CP0_REG15__PRID:
6462             /* ignored */
6463             register_name = "PRid";
6464             break;
6465         case CP0_REG15__EBASE:
6466             check_insn(ctx, ISA_MIPS_R2);
6467             gen_helper_mtc0_ebase(tcg_env, arg);
6468             register_name = "EBase";
6469             break;
6470         default:
6471             goto cp0_unimplemented;
6472         }
6473         break;
6474     case CP0_REGISTER_16:
6475         switch (sel) {
6476         case CP0_REG16__CONFIG:
6477             gen_helper_mtc0_config0(tcg_env, arg);
6478             register_name = "Config";
6479             /* Stop translation as we may have switched the execution mode */
6480             ctx->base.is_jmp = DISAS_STOP;
6481             break;
6482         case CP0_REG16__CONFIG1:
6483             /* ignored, read only */
6484             register_name = "Config1";
6485             break;
6486         case CP0_REG16__CONFIG2:
6487             gen_helper_mtc0_config2(tcg_env, arg);
6488             register_name = "Config2";
6489             /* Stop translation as we may have switched the execution mode */
6490             ctx->base.is_jmp = DISAS_STOP;
6491             break;
6492         case CP0_REG16__CONFIG3:
6493             gen_helper_mtc0_config3(tcg_env, arg);
6494             register_name = "Config3";
6495             /* Stop translation as we may have switched the execution mode */
6496             ctx->base.is_jmp = DISAS_STOP;
6497             break;
6498         case CP0_REG16__CONFIG4:
6499             gen_helper_mtc0_config4(tcg_env, arg);
6500             register_name = "Config4";
6501             ctx->base.is_jmp = DISAS_STOP;
6502             break;
6503         case CP0_REG16__CONFIG5:
6504             gen_helper_mtc0_config5(tcg_env, arg);
6505             register_name = "Config5";
6506             /* Stop translation as we may have switched the execution mode */
6507             ctx->base.is_jmp = DISAS_STOP;
6508             break;
6509         /* 6,7 are implementation dependent */
6510         case CP0_REG16__CONFIG6:
6511             /* ignored */
6512             register_name = "Config6";
6513             break;
6514         case CP0_REG16__CONFIG7:
6515             /* ignored */
6516             register_name = "Config7";
6517             break;
6518         default:
6519             register_name = "Invalid config selector";
6520             goto cp0_unimplemented;
6521         }
6522         break;
6523     case CP0_REGISTER_17:
6524         switch (sel) {
6525         case CP0_REG17__LLADDR:
6526             gen_helper_mtc0_lladdr(tcg_env, arg);
6527             register_name = "LLAddr";
6528             break;
6529         case CP0_REG17__MAAR:
6530             CP0_CHECK(ctx->mrp);
6531             gen_helper_mtc0_maar(tcg_env, arg);
6532             register_name = "MAAR";
6533             break;
6534         case CP0_REG17__MAARI:
6535             CP0_CHECK(ctx->mrp);
6536             gen_helper_mtc0_maari(tcg_env, arg);
6537             register_name = "MAARI";
6538             break;
6539         default:
6540             goto cp0_unimplemented;
6541         }
6542         break;
6543     case CP0_REGISTER_18:
6544         switch (sel) {
6545         case CP0_REG18__WATCHLO0:
6546         case CP0_REG18__WATCHLO1:
6547         case CP0_REG18__WATCHLO2:
6548         case CP0_REG18__WATCHLO3:
6549         case CP0_REG18__WATCHLO4:
6550         case CP0_REG18__WATCHLO5:
6551         case CP0_REG18__WATCHLO6:
6552         case CP0_REG18__WATCHLO7:
6553             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6554             gen_helper_0e1i(mtc0_watchlo, arg, sel);
6555             register_name = "WatchLo";
6556             break;
6557         default:
6558             goto cp0_unimplemented;
6559         }
6560         break;
6561     case CP0_REGISTER_19:
6562         switch (sel) {
6563         case CP0_REG19__WATCHHI0:
6564         case CP0_REG19__WATCHHI1:
6565         case CP0_REG19__WATCHHI2:
6566         case CP0_REG19__WATCHHI3:
6567         case CP0_REG19__WATCHHI4:
6568         case CP0_REG19__WATCHHI5:
6569         case CP0_REG19__WATCHHI6:
6570         case CP0_REG19__WATCHHI7:
6571             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6572             gen_helper_0e1i(mtc0_watchhi, arg, sel);
6573             register_name = "WatchHi";
6574             break;
6575         default:
6576             goto cp0_unimplemented;
6577         }
6578         break;
6579     case CP0_REGISTER_20:
6580         switch (sel) {
6581         case CP0_REG20__XCONTEXT:
6582 #if defined(TARGET_MIPS64)
6583             check_insn(ctx, ISA_MIPS3);
6584             gen_helper_mtc0_xcontext(tcg_env, arg);
6585             register_name = "XContext";
6586             break;
6587 #endif
6588         default:
6589             goto cp0_unimplemented;
6590         }
6591         break;
6592     case CP0_REGISTER_21:
6593        /* Officially reserved, but sel 0 is used for R1x000 framemask */
6594         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
6595         switch (sel) {
6596         case 0:
6597             gen_helper_mtc0_framemask(tcg_env, arg);
6598             register_name = "Framemask";
6599             break;
6600         default:
6601             goto cp0_unimplemented;
6602         }
6603         break;
6604     case CP0_REGISTER_22:
6605         /* ignored */
6606         register_name = "Diagnostic"; /* implementation dependent */
6607         break;
6608     case CP0_REGISTER_23:
6609         switch (sel) {
6610         case CP0_REG23__DEBUG:
6611             gen_helper_mtc0_debug(tcg_env, arg); /* EJTAG support */
6612             /* DISAS_STOP isn't good enough here, hflags may have changed. */
6613             gen_save_pc(ctx->base.pc_next + 4);
6614             ctx->base.is_jmp = DISAS_EXIT;
6615             register_name = "Debug";
6616             break;
6617         case CP0_REG23__TRACECONTROL:
6618             /* PDtrace support */
6619             /* gen_helper_mtc0_tracecontrol(tcg_env, arg);  */
6620             register_name = "TraceControl";
6621             /* Stop translation as we may have switched the execution mode */
6622             ctx->base.is_jmp = DISAS_STOP;
6623             goto cp0_unimplemented;
6624         case CP0_REG23__TRACECONTROL2:
6625             /* PDtrace support */
6626             /* gen_helper_mtc0_tracecontrol2(tcg_env, arg); */
6627             register_name = "TraceControl2";
6628             /* Stop translation as we may have switched the execution mode */
6629             ctx->base.is_jmp = DISAS_STOP;
6630             goto cp0_unimplemented;
6631         case CP0_REG23__USERTRACEDATA1:
6632             /* Stop translation as we may have switched the execution mode */
6633             ctx->base.is_jmp = DISAS_STOP;
6634             /* PDtrace support */
6635             /* gen_helper_mtc0_usertracedata1(tcg_env, arg);*/
6636             register_name = "UserTraceData";
6637             /* Stop translation as we may have switched the execution mode */
6638             ctx->base.is_jmp = DISAS_STOP;
6639             goto cp0_unimplemented;
6640         case CP0_REG23__TRACEIBPC:
6641             /* PDtrace support */
6642             /* gen_helper_mtc0_traceibpc(tcg_env, arg);     */
6643             /* Stop translation as we may have switched the execution mode */
6644             ctx->base.is_jmp = DISAS_STOP;
6645             register_name = "TraceIBPC";
6646             goto cp0_unimplemented;
6647         case CP0_REG23__TRACEDBPC:
6648             /* PDtrace support */
6649             /* gen_helper_mtc0_tracedbpc(tcg_env, arg);     */
6650             /* Stop translation as we may have switched the execution mode */
6651             ctx->base.is_jmp = DISAS_STOP;
6652             register_name = "TraceDBPC";
6653             goto cp0_unimplemented;
6654         default:
6655             goto cp0_unimplemented;
6656         }
6657         break;
6658     case CP0_REGISTER_24:
6659         switch (sel) {
6660         case CP0_REG24__DEPC:
6661             /* EJTAG support */
6662             tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC));
6663             register_name = "DEPC";
6664             break;
6665         default:
6666             goto cp0_unimplemented;
6667         }
6668         break;
6669     case CP0_REGISTER_25:
6670         switch (sel) {
6671         case CP0_REG25__PERFCTL0:
6672             gen_helper_mtc0_performance0(tcg_env, arg);
6673             register_name = "Performance0";
6674             break;
6675         case CP0_REG25__PERFCNT0:
6676             /* gen_helper_mtc0_performance1(arg); */
6677             register_name = "Performance1";
6678             goto cp0_unimplemented;
6679         case CP0_REG25__PERFCTL1:
6680             /* gen_helper_mtc0_performance2(arg); */
6681             register_name = "Performance2";
6682             goto cp0_unimplemented;
6683         case CP0_REG25__PERFCNT1:
6684             /* gen_helper_mtc0_performance3(arg); */
6685             register_name = "Performance3";
6686             goto cp0_unimplemented;
6687         case CP0_REG25__PERFCTL2:
6688             /* gen_helper_mtc0_performance4(arg); */
6689             register_name = "Performance4";
6690             goto cp0_unimplemented;
6691         case CP0_REG25__PERFCNT2:
6692             /* gen_helper_mtc0_performance5(arg); */
6693             register_name = "Performance5";
6694             goto cp0_unimplemented;
6695         case CP0_REG25__PERFCTL3:
6696             /* gen_helper_mtc0_performance6(arg); */
6697             register_name = "Performance6";
6698             goto cp0_unimplemented;
6699         case CP0_REG25__PERFCNT3:
6700             /* gen_helper_mtc0_performance7(arg); */
6701             register_name = "Performance7";
6702             goto cp0_unimplemented;
6703         default:
6704             goto cp0_unimplemented;
6705         }
6706        break;
6707     case CP0_REGISTER_26:
6708         switch (sel) {
6709         case CP0_REG26__ERRCTL:
6710             gen_helper_mtc0_errctl(tcg_env, arg);
6711             ctx->base.is_jmp = DISAS_STOP;
6712             register_name = "ErrCtl";
6713             break;
6714         default:
6715             goto cp0_unimplemented;
6716         }
6717         break;
6718     case CP0_REGISTER_27:
6719         switch (sel) {
6720         case CP0_REG27__CACHERR:
6721             /* ignored */
6722             register_name = "CacheErr";
6723             break;
6724         default:
6725             goto cp0_unimplemented;
6726         }
6727        break;
6728     case CP0_REGISTER_28:
6729         switch (sel) {
6730         case CP0_REG28__TAGLO:
6731         case CP0_REG28__TAGLO1:
6732         case CP0_REG28__TAGLO2:
6733         case CP0_REG28__TAGLO3:
6734             gen_helper_mtc0_taglo(tcg_env, arg);
6735             register_name = "TagLo";
6736             break;
6737         case CP0_REG28__DATALO:
6738         case CP0_REG28__DATALO1:
6739         case CP0_REG28__DATALO2:
6740         case CP0_REG28__DATALO3:
6741             gen_helper_mtc0_datalo(tcg_env, arg);
6742             register_name = "DataLo";
6743             break;
6744         default:
6745             goto cp0_unimplemented;
6746         }
6747         break;
6748     case CP0_REGISTER_29:
6749         switch (sel) {
6750         case CP0_REG29__TAGHI:
6751         case CP0_REG29__TAGHI1:
6752         case CP0_REG29__TAGHI2:
6753         case CP0_REG29__TAGHI3:
6754             gen_helper_mtc0_taghi(tcg_env, arg);
6755             register_name = "TagHi";
6756             break;
6757         case CP0_REG29__DATAHI:
6758         case CP0_REG29__DATAHI1:
6759         case CP0_REG29__DATAHI2:
6760         case CP0_REG29__DATAHI3:
6761             gen_helper_mtc0_datahi(tcg_env, arg);
6762             register_name = "DataHi";
6763             break;
6764         default:
6765             register_name = "invalid sel";
6766             goto cp0_unimplemented;
6767         }
6768        break;
6769     case CP0_REGISTER_30:
6770         switch (sel) {
6771         case CP0_REG30__ERROREPC:
6772             tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6773             register_name = "ErrorEPC";
6774             break;
6775         default:
6776             goto cp0_unimplemented;
6777         }
6778         break;
6779     case CP0_REGISTER_31:
6780         switch (sel) {
6781         case CP0_REG31__DESAVE:
6782             /* EJTAG support */
6783             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6784             register_name = "DESAVE";
6785             break;
6786         case CP0_REG31__KSCRATCH1:
6787         case CP0_REG31__KSCRATCH2:
6788         case CP0_REG31__KSCRATCH3:
6789         case CP0_REG31__KSCRATCH4:
6790         case CP0_REG31__KSCRATCH5:
6791         case CP0_REG31__KSCRATCH6:
6792             CP0_CHECK(ctx->kscrexist & (1 << sel));
6793             tcg_gen_st_tl(arg, tcg_env,
6794                           offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
6795             register_name = "KScratch";
6796             break;
6797         default:
6798             goto cp0_unimplemented;
6799         }
6800         break;
6801     default:
6802        goto cp0_unimplemented;
6803     }
6804     trace_mips_translate_c0("mtc0", register_name, reg, sel);
6805 
6806     /* For simplicity assume that all writes can cause interrupts.  */
6807     if (icount) {
6808         /*
6809          * DISAS_STOP isn't sufficient, we need to ensure we break out of
6810          * translated code to check for pending interrupts.
6811          */
6812         gen_save_pc(ctx->base.pc_next + 4);
6813         ctx->base.is_jmp = DISAS_EXIT;
6814     }
6815     return;
6816 
6817 cp0_unimplemented:
6818     qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n",
6819                   register_name, reg, sel);
6820 }
6821 
6822 #if defined(TARGET_MIPS64)
gen_dmfc0(DisasContext * ctx,TCGv arg,int reg,int sel)6823 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6824 {
6825     const char *register_name = "invalid";
6826 
6827     if (sel != 0) {
6828         check_insn(ctx, ISA_MIPS_R1);
6829     }
6830 
6831     switch (reg) {
6832     case CP0_REGISTER_00:
6833         switch (sel) {
6834         case CP0_REG00__INDEX:
6835             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
6836             register_name = "Index";
6837             break;
6838         case CP0_REG00__MVPCONTROL:
6839             CP0_CHECK(ctx->insn_flags & ASE_MT);
6840             gen_helper_mfc0_mvpcontrol(arg, tcg_env);
6841             register_name = "MVPControl";
6842             break;
6843         case CP0_REG00__MVPCONF0:
6844             CP0_CHECK(ctx->insn_flags & ASE_MT);
6845             gen_helper_mfc0_mvpconf0(arg, tcg_env);
6846             register_name = "MVPConf0";
6847             break;
6848         case CP0_REG00__MVPCONF1:
6849             CP0_CHECK(ctx->insn_flags & ASE_MT);
6850             gen_helper_mfc0_mvpconf1(arg, tcg_env);
6851             register_name = "MVPConf1";
6852             break;
6853         case CP0_REG00__VPCONTROL:
6854             CP0_CHECK(ctx->vp);
6855             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6856             register_name = "VPControl";
6857             break;
6858         default:
6859             goto cp0_unimplemented;
6860         }
6861         break;
6862     case CP0_REGISTER_01:
6863         switch (sel) {
6864         case CP0_REG01__RANDOM:
6865             CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
6866             gen_helper_mfc0_random(arg, tcg_env);
6867             register_name = "Random";
6868             break;
6869         case CP0_REG01__VPECONTROL:
6870             CP0_CHECK(ctx->insn_flags & ASE_MT);
6871             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
6872             register_name = "VPEControl";
6873             break;
6874         case CP0_REG01__VPECONF0:
6875             CP0_CHECK(ctx->insn_flags & ASE_MT);
6876             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
6877             register_name = "VPEConf0";
6878             break;
6879         case CP0_REG01__VPECONF1:
6880             CP0_CHECK(ctx->insn_flags & ASE_MT);
6881             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
6882             register_name = "VPEConf1";
6883             break;
6884         case CP0_REG01__YQMASK:
6885             CP0_CHECK(ctx->insn_flags & ASE_MT);
6886             tcg_gen_ld_tl(arg, tcg_env,
6887                           offsetof(CPUMIPSState, CP0_YQMask));
6888             register_name = "YQMask";
6889             break;
6890         case CP0_REG01__VPESCHEDULE:
6891             CP0_CHECK(ctx->insn_flags & ASE_MT);
6892             tcg_gen_ld_tl(arg, tcg_env,
6893                           offsetof(CPUMIPSState, CP0_VPESchedule));
6894             register_name = "VPESchedule";
6895             break;
6896         case CP0_REG01__VPESCHEFBACK:
6897             CP0_CHECK(ctx->insn_flags & ASE_MT);
6898             tcg_gen_ld_tl(arg, tcg_env,
6899                           offsetof(CPUMIPSState, CP0_VPEScheFBack));
6900             register_name = "VPEScheFBack";
6901             break;
6902         case CP0_REG01__VPEOPT:
6903             CP0_CHECK(ctx->insn_flags & ASE_MT);
6904             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
6905             register_name = "VPEOpt";
6906             break;
6907         default:
6908             goto cp0_unimplemented;
6909         }
6910         break;
6911     case CP0_REGISTER_02:
6912         switch (sel) {
6913         case CP0_REG02__ENTRYLO0:
6914             tcg_gen_ld_tl(arg, tcg_env,
6915                           offsetof(CPUMIPSState, CP0_EntryLo0));
6916             register_name = "EntryLo0";
6917             break;
6918         case CP0_REG02__TCSTATUS:
6919             CP0_CHECK(ctx->insn_flags & ASE_MT);
6920             gen_helper_mfc0_tcstatus(arg, tcg_env);
6921             register_name = "TCStatus";
6922             break;
6923         case CP0_REG02__TCBIND:
6924             CP0_CHECK(ctx->insn_flags & ASE_MT);
6925             gen_helper_mfc0_tcbind(arg, tcg_env);
6926             register_name = "TCBind";
6927             break;
6928         case CP0_REG02__TCRESTART:
6929             CP0_CHECK(ctx->insn_flags & ASE_MT);
6930             gen_helper_dmfc0_tcrestart(arg, tcg_env);
6931             register_name = "TCRestart";
6932             break;
6933         case CP0_REG02__TCHALT:
6934             CP0_CHECK(ctx->insn_flags & ASE_MT);
6935             gen_helper_dmfc0_tchalt(arg, tcg_env);
6936             register_name = "TCHalt";
6937             break;
6938         case CP0_REG02__TCCONTEXT:
6939             CP0_CHECK(ctx->insn_flags & ASE_MT);
6940             gen_helper_dmfc0_tccontext(arg, tcg_env);
6941             register_name = "TCContext";
6942             break;
6943         case CP0_REG02__TCSCHEDULE:
6944             CP0_CHECK(ctx->insn_flags & ASE_MT);
6945             gen_helper_dmfc0_tcschedule(arg, tcg_env);
6946             register_name = "TCSchedule";
6947             break;
6948         case CP0_REG02__TCSCHEFBACK:
6949             CP0_CHECK(ctx->insn_flags & ASE_MT);
6950             gen_helper_dmfc0_tcschefback(arg, tcg_env);
6951             register_name = "TCScheFBack";
6952             break;
6953         default:
6954             goto cp0_unimplemented;
6955         }
6956         break;
6957     case CP0_REGISTER_03:
6958         switch (sel) {
6959         case CP0_REG03__ENTRYLO1:
6960             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EntryLo1));
6961             register_name = "EntryLo1";
6962             break;
6963         case CP0_REG03__GLOBALNUM:
6964             CP0_CHECK(ctx->vp);
6965             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6966             register_name = "GlobalNumber";
6967             break;
6968         default:
6969             goto cp0_unimplemented;
6970         }
6971         break;
6972     case CP0_REGISTER_04:
6973         switch (sel) {
6974         case CP0_REG04__CONTEXT:
6975             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_Context));
6976             register_name = "Context";
6977             break;
6978         case CP0_REG04__CONTEXTCONFIG:
6979             /* SmartMIPS ASE */
6980             /* gen_helper_dmfc0_contextconfig(arg); */
6981             register_name = "ContextConfig";
6982             goto cp0_unimplemented;
6983         case CP0_REG04__USERLOCAL:
6984             CP0_CHECK(ctx->ulri);
6985             tcg_gen_ld_tl(arg, tcg_env,
6986                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6987             register_name = "UserLocal";
6988             break;
6989         case CP0_REG04__MMID:
6990             CP0_CHECK(ctx->mi);
6991             gen_helper_mtc0_memorymapid(tcg_env, arg);
6992             register_name = "MMID";
6993             break;
6994         default:
6995             goto cp0_unimplemented;
6996         }
6997         break;
6998     case CP0_REGISTER_05:
6999         switch (sel) {
7000         case CP0_REG05__PAGEMASK:
7001             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
7002             register_name = "PageMask";
7003             break;
7004         case CP0_REG05__PAGEGRAIN:
7005             check_insn(ctx, ISA_MIPS_R2);
7006             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
7007             register_name = "PageGrain";
7008             break;
7009         case CP0_REG05__SEGCTL0:
7010             CP0_CHECK(ctx->sc);
7011             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl0));
7012             register_name = "SegCtl0";
7013             break;
7014         case CP0_REG05__SEGCTL1:
7015             CP0_CHECK(ctx->sc);
7016             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl1));
7017             register_name = "SegCtl1";
7018             break;
7019         case CP0_REG05__SEGCTL2:
7020             CP0_CHECK(ctx->sc);
7021             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl2));
7022             register_name = "SegCtl2";
7023             break;
7024         case CP0_REG05__PWBASE:
7025             check_pw(ctx);
7026             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWBase));
7027             register_name = "PWBase";
7028             break;
7029         case CP0_REG05__PWFIELD:
7030             check_pw(ctx);
7031             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWField));
7032             register_name = "PWField";
7033             break;
7034         case CP0_REG05__PWSIZE:
7035             check_pw(ctx);
7036             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWSize));
7037             register_name = "PWSize";
7038             break;
7039         default:
7040             goto cp0_unimplemented;
7041         }
7042         break;
7043     case CP0_REGISTER_06:
7044         switch (sel) {
7045         case CP0_REG06__WIRED:
7046             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
7047             register_name = "Wired";
7048             break;
7049         case CP0_REG06__SRSCONF0:
7050             check_insn(ctx, ISA_MIPS_R2);
7051             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
7052             register_name = "SRSConf0";
7053             break;
7054         case CP0_REG06__SRSCONF1:
7055             check_insn(ctx, ISA_MIPS_R2);
7056             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
7057             register_name = "SRSConf1";
7058             break;
7059         case CP0_REG06__SRSCONF2:
7060             check_insn(ctx, ISA_MIPS_R2);
7061             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
7062             register_name = "SRSConf2";
7063             break;
7064         case CP0_REG06__SRSCONF3:
7065             check_insn(ctx, ISA_MIPS_R2);
7066             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
7067             register_name = "SRSConf3";
7068             break;
7069         case CP0_REG06__SRSCONF4:
7070             check_insn(ctx, ISA_MIPS_R2);
7071             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
7072             register_name = "SRSConf4";
7073             break;
7074         case CP0_REG06__PWCTL:
7075             check_pw(ctx);
7076             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
7077             register_name = "PWCtl";
7078             break;
7079         default:
7080             goto cp0_unimplemented;
7081         }
7082         break;
7083     case CP0_REGISTER_07:
7084         switch (sel) {
7085         case CP0_REG07__HWRENA:
7086             check_insn(ctx, ISA_MIPS_R2);
7087             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
7088             register_name = "HWREna";
7089             break;
7090         default:
7091             goto cp0_unimplemented;
7092         }
7093         break;
7094     case CP0_REGISTER_08:
7095         switch (sel) {
7096         case CP0_REG08__BADVADDR:
7097             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_BadVAddr));
7098             register_name = "BadVAddr";
7099             break;
7100         case CP0_REG08__BADINSTR:
7101             CP0_CHECK(ctx->bi);
7102             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
7103             register_name = "BadInstr";
7104             break;
7105         case CP0_REG08__BADINSTRP:
7106             CP0_CHECK(ctx->bp);
7107             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
7108             register_name = "BadInstrP";
7109             break;
7110         case CP0_REG08__BADINSTRX:
7111             CP0_CHECK(ctx->bi);
7112             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
7113             tcg_gen_andi_tl(arg, arg, ~0xffff);
7114             register_name = "BadInstrX";
7115             break;
7116         default:
7117             goto cp0_unimplemented;
7118         }
7119         break;
7120     case CP0_REGISTER_09:
7121         switch (sel) {
7122         case CP0_REG09__COUNT:
7123             /* Mark as an IO operation because we read the time.  */
7124             translator_io_start(&ctx->base);
7125             gen_helper_mfc0_count(arg, tcg_env);
7126             /*
7127              * Break the TB to be able to take timer interrupts immediately
7128              * after reading count. DISAS_STOP isn't sufficient, we need to
7129              * ensure we break completely out of translated code.
7130              */
7131             gen_save_pc(ctx->base.pc_next + 4);
7132             ctx->base.is_jmp = DISAS_EXIT;
7133             register_name = "Count";
7134             break;
7135         default:
7136             goto cp0_unimplemented;
7137         }
7138         break;
7139     case CP0_REGISTER_10:
7140         switch (sel) {
7141         case CP0_REG10__ENTRYHI:
7142             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EntryHi));
7143             register_name = "EntryHi";
7144             break;
7145         default:
7146             goto cp0_unimplemented;
7147         }
7148         break;
7149     case CP0_REGISTER_11:
7150         switch (sel) {
7151         case CP0_REG11__COMPARE:
7152             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
7153             register_name = "Compare";
7154             break;
7155         /* 6,7 are implementation dependent */
7156         default:
7157             goto cp0_unimplemented;
7158         }
7159         break;
7160     case CP0_REGISTER_12:
7161         switch (sel) {
7162         case CP0_REG12__STATUS:
7163             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
7164             register_name = "Status";
7165             break;
7166         case CP0_REG12__INTCTL:
7167             check_insn(ctx, ISA_MIPS_R2);
7168             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
7169             register_name = "IntCtl";
7170             break;
7171         case CP0_REG12__SRSCTL:
7172             check_insn(ctx, ISA_MIPS_R2);
7173             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
7174             register_name = "SRSCtl";
7175             break;
7176         case CP0_REG12__SRSMAP:
7177             check_insn(ctx, ISA_MIPS_R2);
7178             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7179             register_name = "SRSMap";
7180             break;
7181         default:
7182             goto cp0_unimplemented;
7183         }
7184         break;
7185     case CP0_REGISTER_13:
7186         switch (sel) {
7187         case CP0_REG13__CAUSE:
7188             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
7189             register_name = "Cause";
7190             break;
7191         default:
7192             goto cp0_unimplemented;
7193         }
7194         break;
7195     case CP0_REGISTER_14:
7196         switch (sel) {
7197         case CP0_REG14__EPC:
7198             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC));
7199             register_name = "EPC";
7200             break;
7201         default:
7202             goto cp0_unimplemented;
7203         }
7204         break;
7205     case CP0_REGISTER_15:
7206         switch (sel) {
7207         case CP0_REG15__PRID:
7208             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
7209             register_name = "PRid";
7210             break;
7211         case CP0_REG15__EBASE:
7212             check_insn(ctx, ISA_MIPS_R2);
7213             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EBase));
7214             register_name = "EBase";
7215             break;
7216         case CP0_REG15__CMGCRBASE:
7217             check_insn(ctx, ISA_MIPS_R2);
7218             CP0_CHECK(ctx->cmgcr);
7219             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7220             register_name = "CMGCRBase";
7221             break;
7222         default:
7223             goto cp0_unimplemented;
7224         }
7225         break;
7226     case CP0_REGISTER_16:
7227         switch (sel) {
7228         case CP0_REG16__CONFIG:
7229             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
7230             register_name = "Config";
7231             break;
7232         case CP0_REG16__CONFIG1:
7233             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
7234             register_name = "Config1";
7235             break;
7236         case CP0_REG16__CONFIG2:
7237             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7238             register_name = "Config2";
7239             break;
7240         case CP0_REG16__CONFIG3:
7241             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7242             register_name = "Config3";
7243             break;
7244         case CP0_REG16__CONFIG4:
7245             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7246             register_name = "Config4";
7247             break;
7248         case CP0_REG16__CONFIG5:
7249             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7250             register_name = "Config5";
7251             break;
7252         /* 6,7 are implementation dependent */
7253         case CP0_REG16__CONFIG6:
7254             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
7255             register_name = "Config6";
7256             break;
7257         case CP0_REG16__CONFIG7:
7258             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
7259             register_name = "Config7";
7260             break;
7261         default:
7262             goto cp0_unimplemented;
7263         }
7264         break;
7265     case CP0_REGISTER_17:
7266         switch (sel) {
7267         case CP0_REG17__LLADDR:
7268             gen_helper_dmfc0_lladdr(arg, tcg_env);
7269             register_name = "LLAddr";
7270             break;
7271         case CP0_REG17__MAAR:
7272             CP0_CHECK(ctx->mrp);
7273             gen_helper_dmfc0_maar(arg, tcg_env);
7274             register_name = "MAAR";
7275             break;
7276         case CP0_REG17__MAARI:
7277             CP0_CHECK(ctx->mrp);
7278             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7279             register_name = "MAARI";
7280             break;
7281         default:
7282             goto cp0_unimplemented;
7283         }
7284         break;
7285     case CP0_REGISTER_18:
7286         switch (sel) {
7287         case CP0_REG18__WATCHLO0:
7288         case CP0_REG18__WATCHLO1:
7289         case CP0_REG18__WATCHLO2:
7290         case CP0_REG18__WATCHLO3:
7291         case CP0_REG18__WATCHLO4:
7292         case CP0_REG18__WATCHLO5:
7293         case CP0_REG18__WATCHLO6:
7294         case CP0_REG18__WATCHLO7:
7295             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7296             gen_helper_1e0i(dmfc0_watchlo, arg, sel);
7297             register_name = "WatchLo";
7298             break;
7299         default:
7300             goto cp0_unimplemented;
7301         }
7302         break;
7303     case CP0_REGISTER_19:
7304         switch (sel) {
7305         case CP0_REG19__WATCHHI0:
7306         case CP0_REG19__WATCHHI1:
7307         case CP0_REG19__WATCHHI2:
7308         case CP0_REG19__WATCHHI3:
7309         case CP0_REG19__WATCHHI4:
7310         case CP0_REG19__WATCHHI5:
7311         case CP0_REG19__WATCHHI6:
7312         case CP0_REG19__WATCHHI7:
7313             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7314             gen_helper_1e0i(dmfc0_watchhi, arg, sel);
7315             register_name = "WatchHi";
7316             break;
7317         default:
7318             goto cp0_unimplemented;
7319         }
7320         break;
7321     case CP0_REGISTER_20:
7322         switch (sel) {
7323         case CP0_REG20__XCONTEXT:
7324             check_insn(ctx, ISA_MIPS3);
7325             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_XContext));
7326             register_name = "XContext";
7327             break;
7328         default:
7329             goto cp0_unimplemented;
7330         }
7331         break;
7332     case CP0_REGISTER_21:
7333         /* Officially reserved, but sel 0 is used for R1x000 framemask */
7334         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
7335         switch (sel) {
7336         case 0:
7337             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
7338             register_name = "Framemask";
7339             break;
7340         default:
7341             goto cp0_unimplemented;
7342         }
7343         break;
7344     case CP0_REGISTER_22:
7345         tcg_gen_movi_tl(arg, 0); /* unimplemented */
7346         register_name = "'Diagnostic"; /* implementation dependent */
7347         break;
7348     case CP0_REGISTER_23:
7349         switch (sel) {
7350         case CP0_REG23__DEBUG:
7351             gen_helper_mfc0_debug(arg, tcg_env); /* EJTAG support */
7352             register_name = "Debug";
7353             break;
7354         case CP0_REG23__TRACECONTROL:
7355             /* PDtrace support */
7356             /* gen_helper_dmfc0_tracecontrol(arg, tcg_env);  */
7357             register_name = "TraceControl";
7358             goto cp0_unimplemented;
7359         case CP0_REG23__TRACECONTROL2:
7360             /* PDtrace support */
7361             /* gen_helper_dmfc0_tracecontrol2(arg, tcg_env); */
7362             register_name = "TraceControl2";
7363             goto cp0_unimplemented;
7364         case CP0_REG23__USERTRACEDATA1:
7365             /* PDtrace support */
7366             /* gen_helper_dmfc0_usertracedata1(arg, tcg_env);*/
7367             register_name = "UserTraceData1";
7368             goto cp0_unimplemented;
7369         case CP0_REG23__TRACEIBPC:
7370             /* PDtrace support */
7371             /* gen_helper_dmfc0_traceibpc(arg, tcg_env);     */
7372             register_name = "TraceIBPC";
7373             goto cp0_unimplemented;
7374         case CP0_REG23__TRACEDBPC:
7375             /* PDtrace support */
7376             /* gen_helper_dmfc0_tracedbpc(arg, tcg_env);     */
7377             register_name = "TraceDBPC";
7378             goto cp0_unimplemented;
7379         default:
7380             goto cp0_unimplemented;
7381         }
7382         break;
7383     case CP0_REGISTER_24:
7384         switch (sel) {
7385         case CP0_REG24__DEPC:
7386             /* EJTAG support */
7387             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC));
7388             register_name = "DEPC";
7389             break;
7390         default:
7391             goto cp0_unimplemented;
7392         }
7393         break;
7394     case CP0_REGISTER_25:
7395         switch (sel) {
7396         case CP0_REG25__PERFCTL0:
7397             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
7398             register_name = "Performance0";
7399             break;
7400         case CP0_REG25__PERFCNT0:
7401             /* gen_helper_dmfc0_performance1(arg); */
7402             register_name = "Performance1";
7403             goto cp0_unimplemented;
7404         case CP0_REG25__PERFCTL1:
7405             /* gen_helper_dmfc0_performance2(arg); */
7406             register_name = "Performance2";
7407             goto cp0_unimplemented;
7408         case CP0_REG25__PERFCNT1:
7409             /* gen_helper_dmfc0_performance3(arg); */
7410             register_name = "Performance3";
7411             goto cp0_unimplemented;
7412         case CP0_REG25__PERFCTL2:
7413             /* gen_helper_dmfc0_performance4(arg); */
7414             register_name = "Performance4";
7415             goto cp0_unimplemented;
7416         case CP0_REG25__PERFCNT2:
7417             /* gen_helper_dmfc0_performance5(arg); */
7418             register_name = "Performance5";
7419             goto cp0_unimplemented;
7420         case CP0_REG25__PERFCTL3:
7421             /* gen_helper_dmfc0_performance6(arg); */
7422             register_name = "Performance6";
7423             goto cp0_unimplemented;
7424         case CP0_REG25__PERFCNT3:
7425             /* gen_helper_dmfc0_performance7(arg); */
7426             register_name = "Performance7";
7427             goto cp0_unimplemented;
7428         default:
7429             goto cp0_unimplemented;
7430         }
7431         break;
7432     case CP0_REGISTER_26:
7433         switch (sel) {
7434         case CP0_REG26__ERRCTL:
7435             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7436             register_name = "ErrCtl";
7437             break;
7438         default:
7439             goto cp0_unimplemented;
7440         }
7441         break;
7442     case CP0_REGISTER_27:
7443         switch (sel) {
7444         /* ignored */
7445         case CP0_REG27__CACHERR:
7446             tcg_gen_movi_tl(arg, 0); /* unimplemented */
7447             register_name = "CacheErr";
7448             break;
7449         default:
7450             goto cp0_unimplemented;
7451         }
7452         break;
7453     case CP0_REGISTER_28:
7454         switch (sel) {
7455         case CP0_REG28__TAGLO:
7456         case CP0_REG28__TAGLO1:
7457         case CP0_REG28__TAGLO2:
7458         case CP0_REG28__TAGLO3:
7459             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
7460             register_name = "TagLo";
7461             break;
7462         case CP0_REG28__DATALO:
7463         case CP0_REG28__DATALO1:
7464         case CP0_REG28__DATALO2:
7465         case CP0_REG28__DATALO3:
7466             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
7467             register_name = "DataLo";
7468             break;
7469         default:
7470             goto cp0_unimplemented;
7471         }
7472         break;
7473     case CP0_REGISTER_29:
7474         switch (sel) {
7475         case CP0_REG29__TAGHI:
7476         case CP0_REG29__TAGHI1:
7477         case CP0_REG29__TAGHI2:
7478         case CP0_REG29__TAGHI3:
7479             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7480             register_name = "TagHi";
7481             break;
7482         case CP0_REG29__DATAHI:
7483         case CP0_REG29__DATAHI1:
7484         case CP0_REG29__DATAHI2:
7485         case CP0_REG29__DATAHI3:
7486             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7487             register_name = "DataHi";
7488             break;
7489         default:
7490             goto cp0_unimplemented;
7491         }
7492         break;
7493     case CP0_REGISTER_30:
7494         switch (sel) {
7495         case CP0_REG30__ERROREPC:
7496             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7497             register_name = "ErrorEPC";
7498             break;
7499         default:
7500             goto cp0_unimplemented;
7501         }
7502         break;
7503     case CP0_REGISTER_31:
7504         switch (sel) {
7505         case CP0_REG31__DESAVE:
7506             /* EJTAG support */
7507             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7508             register_name = "DESAVE";
7509             break;
7510         case CP0_REG31__KSCRATCH1:
7511         case CP0_REG31__KSCRATCH2:
7512         case CP0_REG31__KSCRATCH3:
7513         case CP0_REG31__KSCRATCH4:
7514         case CP0_REG31__KSCRATCH5:
7515         case CP0_REG31__KSCRATCH6:
7516             CP0_CHECK(ctx->kscrexist & (1 << sel));
7517             tcg_gen_ld_tl(arg, tcg_env,
7518                           offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
7519             register_name = "KScratch";
7520             break;
7521         default:
7522             goto cp0_unimplemented;
7523         }
7524         break;
7525     default:
7526         goto cp0_unimplemented;
7527     }
7528     trace_mips_translate_c0("dmfc0", register_name, reg, sel);
7529     return;
7530 
7531 cp0_unimplemented:
7532     qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n",
7533                   register_name, reg, sel);
7534     gen_mfc0_unimplemented(ctx, arg);
7535 }
7536 
gen_dmtc0(DisasContext * ctx,TCGv arg,int reg,int sel)7537 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7538 {
7539     const char *register_name = "invalid";
7540     bool icount;
7541 
7542     if (sel != 0) {
7543         check_insn(ctx, ISA_MIPS_R1);
7544     }
7545 
7546     icount = translator_io_start(&ctx->base);
7547 
7548     switch (reg) {
7549     case CP0_REGISTER_00:
7550         switch (sel) {
7551         case CP0_REG00__INDEX:
7552             gen_helper_mtc0_index(tcg_env, arg);
7553             register_name = "Index";
7554             break;
7555         case CP0_REG00__MVPCONTROL:
7556             CP0_CHECK(ctx->insn_flags & ASE_MT);
7557             gen_helper_mtc0_mvpcontrol(tcg_env, arg);
7558             register_name = "MVPControl";
7559             break;
7560         case CP0_REG00__MVPCONF0:
7561             CP0_CHECK(ctx->insn_flags & ASE_MT);
7562             /* ignored */
7563             register_name = "MVPConf0";
7564             break;
7565         case CP0_REG00__MVPCONF1:
7566             CP0_CHECK(ctx->insn_flags & ASE_MT);
7567             /* ignored */
7568             register_name = "MVPConf1";
7569             break;
7570         case CP0_REG00__VPCONTROL:
7571             CP0_CHECK(ctx->vp);
7572             /* ignored */
7573             register_name = "VPControl";
7574             break;
7575         default:
7576             goto cp0_unimplemented;
7577         }
7578         break;
7579     case CP0_REGISTER_01:
7580         switch (sel) {
7581         case CP0_REG01__RANDOM:
7582             /* ignored */
7583             register_name = "Random";
7584             break;
7585         case CP0_REG01__VPECONTROL:
7586             CP0_CHECK(ctx->insn_flags & ASE_MT);
7587             gen_helper_mtc0_vpecontrol(tcg_env, arg);
7588             register_name = "VPEControl";
7589             break;
7590         case CP0_REG01__VPECONF0:
7591             CP0_CHECK(ctx->insn_flags & ASE_MT);
7592             gen_helper_mtc0_vpeconf0(tcg_env, arg);
7593             register_name = "VPEConf0";
7594             break;
7595         case CP0_REG01__VPECONF1:
7596             CP0_CHECK(ctx->insn_flags & ASE_MT);
7597             gen_helper_mtc0_vpeconf1(tcg_env, arg);
7598             register_name = "VPEConf1";
7599             break;
7600         case CP0_REG01__YQMASK:
7601             CP0_CHECK(ctx->insn_flags & ASE_MT);
7602             gen_helper_mtc0_yqmask(tcg_env, arg);
7603             register_name = "YQMask";
7604             break;
7605         case CP0_REG01__VPESCHEDULE:
7606             CP0_CHECK(ctx->insn_flags & ASE_MT);
7607             tcg_gen_st_tl(arg, tcg_env,
7608                           offsetof(CPUMIPSState, CP0_VPESchedule));
7609             register_name = "VPESchedule";
7610             break;
7611         case CP0_REG01__VPESCHEFBACK:
7612             CP0_CHECK(ctx->insn_flags & ASE_MT);
7613             tcg_gen_st_tl(arg, tcg_env,
7614                           offsetof(CPUMIPSState, CP0_VPEScheFBack));
7615             register_name = "VPEScheFBack";
7616             break;
7617         case CP0_REG01__VPEOPT:
7618             CP0_CHECK(ctx->insn_flags & ASE_MT);
7619             gen_helper_mtc0_vpeopt(tcg_env, arg);
7620             register_name = "VPEOpt";
7621             break;
7622         default:
7623             goto cp0_unimplemented;
7624         }
7625         break;
7626     case CP0_REGISTER_02:
7627         switch (sel) {
7628         case CP0_REG02__ENTRYLO0:
7629             gen_helper_dmtc0_entrylo0(tcg_env, arg);
7630             register_name = "EntryLo0";
7631             break;
7632         case CP0_REG02__TCSTATUS:
7633             CP0_CHECK(ctx->insn_flags & ASE_MT);
7634             gen_helper_mtc0_tcstatus(tcg_env, arg);
7635             register_name = "TCStatus";
7636             break;
7637         case CP0_REG02__TCBIND:
7638             CP0_CHECK(ctx->insn_flags & ASE_MT);
7639             gen_helper_mtc0_tcbind(tcg_env, arg);
7640             register_name = "TCBind";
7641             break;
7642         case CP0_REG02__TCRESTART:
7643             CP0_CHECK(ctx->insn_flags & ASE_MT);
7644             gen_helper_mtc0_tcrestart(tcg_env, arg);
7645             register_name = "TCRestart";
7646             break;
7647         case CP0_REG02__TCHALT:
7648             CP0_CHECK(ctx->insn_flags & ASE_MT);
7649             gen_helper_mtc0_tchalt(tcg_env, arg);
7650             register_name = "TCHalt";
7651             break;
7652         case CP0_REG02__TCCONTEXT:
7653             CP0_CHECK(ctx->insn_flags & ASE_MT);
7654             gen_helper_mtc0_tccontext(tcg_env, arg);
7655             register_name = "TCContext";
7656             break;
7657         case CP0_REG02__TCSCHEDULE:
7658             CP0_CHECK(ctx->insn_flags & ASE_MT);
7659             gen_helper_mtc0_tcschedule(tcg_env, arg);
7660             register_name = "TCSchedule";
7661             break;
7662         case CP0_REG02__TCSCHEFBACK:
7663             CP0_CHECK(ctx->insn_flags & ASE_MT);
7664             gen_helper_mtc0_tcschefback(tcg_env, arg);
7665             register_name = "TCScheFBack";
7666             break;
7667         default:
7668             goto cp0_unimplemented;
7669         }
7670         break;
7671     case CP0_REGISTER_03:
7672         switch (sel) {
7673         case CP0_REG03__ENTRYLO1:
7674             gen_helper_dmtc0_entrylo1(tcg_env, arg);
7675             register_name = "EntryLo1";
7676             break;
7677         case CP0_REG03__GLOBALNUM:
7678             CP0_CHECK(ctx->vp);
7679             /* ignored */
7680             register_name = "GlobalNumber";
7681             break;
7682         default:
7683             goto cp0_unimplemented;
7684         }
7685         break;
7686     case CP0_REGISTER_04:
7687         switch (sel) {
7688         case CP0_REG04__CONTEXT:
7689             gen_helper_mtc0_context(tcg_env, arg);
7690             register_name = "Context";
7691             break;
7692         case CP0_REG04__CONTEXTCONFIG:
7693             /* SmartMIPS ASE */
7694             /* gen_helper_dmtc0_contextconfig(arg); */
7695             register_name = "ContextConfig";
7696             goto cp0_unimplemented;
7697         case CP0_REG04__USERLOCAL:
7698             CP0_CHECK(ctx->ulri);
7699             tcg_gen_st_tl(arg, tcg_env,
7700                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7701             register_name = "UserLocal";
7702             break;
7703         case CP0_REG04__MMID:
7704             CP0_CHECK(ctx->mi);
7705             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID));
7706             register_name = "MMID";
7707             break;
7708         default:
7709             goto cp0_unimplemented;
7710         }
7711         break;
7712     case CP0_REGISTER_05:
7713         switch (sel) {
7714         case CP0_REG05__PAGEMASK:
7715             gen_helper_mtc0_pagemask(tcg_env, arg);
7716             register_name = "PageMask";
7717             break;
7718         case CP0_REG05__PAGEGRAIN:
7719             check_insn(ctx, ISA_MIPS_R2);
7720             gen_helper_mtc0_pagegrain(tcg_env, arg);
7721             register_name = "PageGrain";
7722             break;
7723         case CP0_REG05__SEGCTL0:
7724             CP0_CHECK(ctx->sc);
7725             gen_helper_mtc0_segctl0(tcg_env, arg);
7726             register_name = "SegCtl0";
7727             break;
7728         case CP0_REG05__SEGCTL1:
7729             CP0_CHECK(ctx->sc);
7730             gen_helper_mtc0_segctl1(tcg_env, arg);
7731             register_name = "SegCtl1";
7732             break;
7733         case CP0_REG05__SEGCTL2:
7734             CP0_CHECK(ctx->sc);
7735             gen_helper_mtc0_segctl2(tcg_env, arg);
7736             register_name = "SegCtl2";
7737             break;
7738         case CP0_REG05__PWBASE:
7739             check_pw(ctx);
7740             tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWBase));
7741             register_name = "PWBase";
7742             break;
7743         case CP0_REG05__PWFIELD:
7744             check_pw(ctx);
7745             gen_helper_mtc0_pwfield(tcg_env, arg);
7746             register_name = "PWField";
7747             break;
7748         case CP0_REG05__PWSIZE:
7749             check_pw(ctx);
7750             gen_helper_mtc0_pwsize(tcg_env, arg);
7751             register_name = "PWSize";
7752             break;
7753         default:
7754             goto cp0_unimplemented;
7755         }
7756         break;
7757     case CP0_REGISTER_06:
7758         switch (sel) {
7759         case CP0_REG06__WIRED:
7760             gen_helper_mtc0_wired(tcg_env, arg);
7761             register_name = "Wired";
7762             break;
7763         case CP0_REG06__SRSCONF0:
7764             check_insn(ctx, ISA_MIPS_R2);
7765             gen_helper_mtc0_srsconf0(tcg_env, arg);
7766             register_name = "SRSConf0";
7767             break;
7768         case CP0_REG06__SRSCONF1:
7769             check_insn(ctx, ISA_MIPS_R2);
7770             gen_helper_mtc0_srsconf1(tcg_env, arg);
7771             register_name = "SRSConf1";
7772             break;
7773         case CP0_REG06__SRSCONF2:
7774             check_insn(ctx, ISA_MIPS_R2);
7775             gen_helper_mtc0_srsconf2(tcg_env, arg);
7776             register_name = "SRSConf2";
7777             break;
7778         case CP0_REG06__SRSCONF3:
7779             check_insn(ctx, ISA_MIPS_R2);
7780             gen_helper_mtc0_srsconf3(tcg_env, arg);
7781             register_name = "SRSConf3";
7782             break;
7783         case CP0_REG06__SRSCONF4:
7784             check_insn(ctx, ISA_MIPS_R2);
7785             gen_helper_mtc0_srsconf4(tcg_env, arg);
7786             register_name = "SRSConf4";
7787             break;
7788         case CP0_REG06__PWCTL:
7789             check_pw(ctx);
7790             gen_helper_mtc0_pwctl(tcg_env, arg);
7791             register_name = "PWCtl";
7792             break;
7793         default:
7794             goto cp0_unimplemented;
7795         }
7796         break;
7797     case CP0_REGISTER_07:
7798         switch (sel) {
7799         case CP0_REG07__HWRENA:
7800             check_insn(ctx, ISA_MIPS_R2);
7801             gen_helper_mtc0_hwrena(tcg_env, arg);
7802             ctx->base.is_jmp = DISAS_STOP;
7803             register_name = "HWREna";
7804             break;
7805         default:
7806             goto cp0_unimplemented;
7807         }
7808         break;
7809     case CP0_REGISTER_08:
7810         switch (sel) {
7811         case CP0_REG08__BADVADDR:
7812             /* ignored */
7813             register_name = "BadVAddr";
7814             break;
7815         case CP0_REG08__BADINSTR:
7816             /* ignored */
7817             register_name = "BadInstr";
7818             break;
7819         case CP0_REG08__BADINSTRP:
7820             /* ignored */
7821             register_name = "BadInstrP";
7822             break;
7823         case CP0_REG08__BADINSTRX:
7824             /* ignored */
7825             register_name = "BadInstrX";
7826             break;
7827         default:
7828             goto cp0_unimplemented;
7829         }
7830         break;
7831     case CP0_REGISTER_09:
7832         switch (sel) {
7833         case CP0_REG09__COUNT:
7834             gen_helper_mtc0_count(tcg_env, arg);
7835             register_name = "Count";
7836             break;
7837         default:
7838             goto cp0_unimplemented;
7839         }
7840         /* Stop translation as we may have switched the execution mode */
7841         ctx->base.is_jmp = DISAS_STOP;
7842         break;
7843     case CP0_REGISTER_10:
7844         switch (sel) {
7845         case CP0_REG10__ENTRYHI:
7846             gen_helper_mtc0_entryhi(tcg_env, arg);
7847             register_name = "EntryHi";
7848             break;
7849         default:
7850             goto cp0_unimplemented;
7851         }
7852         break;
7853     case CP0_REGISTER_11:
7854         switch (sel) {
7855         case CP0_REG11__COMPARE:
7856             gen_helper_mtc0_compare(tcg_env, arg);
7857             register_name = "Compare";
7858             break;
7859         /* 6,7 are implementation dependent */
7860         default:
7861             goto cp0_unimplemented;
7862         }
7863         /* Stop translation as we may have switched the execution mode */
7864         ctx->base.is_jmp = DISAS_STOP;
7865         break;
7866     case CP0_REGISTER_12:
7867         switch (sel) {
7868         case CP0_REG12__STATUS:
7869             save_cpu_state(ctx, 1);
7870             gen_helper_mtc0_status(tcg_env, arg);
7871             /* DISAS_STOP isn't good enough here, hflags may have changed. */
7872             gen_save_pc(ctx->base.pc_next + 4);
7873             ctx->base.is_jmp = DISAS_EXIT;
7874             register_name = "Status";
7875             break;
7876         case CP0_REG12__INTCTL:
7877             check_insn(ctx, ISA_MIPS_R2);
7878             gen_helper_mtc0_intctl(tcg_env, arg);
7879             /* Stop translation as we may have switched the execution mode */
7880             ctx->base.is_jmp = DISAS_STOP;
7881             register_name = "IntCtl";
7882             break;
7883         case CP0_REG12__SRSCTL:
7884             check_insn(ctx, ISA_MIPS_R2);
7885             gen_helper_mtc0_srsctl(tcg_env, arg);
7886             /* Stop translation as we may have switched the execution mode */
7887             ctx->base.is_jmp = DISAS_STOP;
7888             register_name = "SRSCtl";
7889             break;
7890         case CP0_REG12__SRSMAP:
7891             check_insn(ctx, ISA_MIPS_R2);
7892             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7893             /* Stop translation as we may have switched the execution mode */
7894             ctx->base.is_jmp = DISAS_STOP;
7895             register_name = "SRSMap";
7896             break;
7897         default:
7898             goto cp0_unimplemented;
7899         }
7900         break;
7901     case CP0_REGISTER_13:
7902         switch (sel) {
7903         case CP0_REG13__CAUSE:
7904             save_cpu_state(ctx, 1);
7905             gen_helper_mtc0_cause(tcg_env, arg);
7906             /*
7907              * Stop translation as we may have triggered an interrupt.
7908              * DISAS_STOP isn't sufficient, we need to ensure we break out of
7909              * translated code to check for pending interrupts.
7910              */
7911             gen_save_pc(ctx->base.pc_next + 4);
7912             ctx->base.is_jmp = DISAS_EXIT;
7913             register_name = "Cause";
7914             break;
7915         default:
7916             goto cp0_unimplemented;
7917         }
7918         break;
7919     case CP0_REGISTER_14:
7920         switch (sel) {
7921         case CP0_REG14__EPC:
7922             tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC));
7923             register_name = "EPC";
7924             break;
7925         default:
7926             goto cp0_unimplemented;
7927         }
7928         break;
7929     case CP0_REGISTER_15:
7930         switch (sel) {
7931         case CP0_REG15__PRID:
7932             /* ignored */
7933             register_name = "PRid";
7934             break;
7935         case CP0_REG15__EBASE:
7936             check_insn(ctx, ISA_MIPS_R2);
7937             gen_helper_mtc0_ebase(tcg_env, arg);
7938             register_name = "EBase";
7939             break;
7940         default:
7941             goto cp0_unimplemented;
7942         }
7943         break;
7944     case CP0_REGISTER_16:
7945         switch (sel) {
7946         case CP0_REG16__CONFIG:
7947             gen_helper_mtc0_config0(tcg_env, arg);
7948             register_name = "Config";
7949             /* Stop translation as we may have switched the execution mode */
7950             ctx->base.is_jmp = DISAS_STOP;
7951             break;
7952         case CP0_REG16__CONFIG1:
7953             /* ignored, read only */
7954             register_name = "Config1";
7955             break;
7956         case CP0_REG16__CONFIG2:
7957             gen_helper_mtc0_config2(tcg_env, arg);
7958             register_name = "Config2";
7959             /* Stop translation as we may have switched the execution mode */
7960             ctx->base.is_jmp = DISAS_STOP;
7961             break;
7962         case CP0_REG16__CONFIG3:
7963             gen_helper_mtc0_config3(tcg_env, arg);
7964             register_name = "Config3";
7965             /* Stop translation as we may have switched the execution mode */
7966             ctx->base.is_jmp = DISAS_STOP;
7967             break;
7968         case CP0_REG16__CONFIG4:
7969             /* currently ignored */
7970             register_name = "Config4";
7971             break;
7972         case CP0_REG16__CONFIG5:
7973             gen_helper_mtc0_config5(tcg_env, arg);
7974             register_name = "Config5";
7975             /* Stop translation as we may have switched the execution mode */
7976             ctx->base.is_jmp = DISAS_STOP;
7977             break;
7978         /* 6,7 are implementation dependent */
7979         default:
7980             register_name = "Invalid config selector";
7981             goto cp0_unimplemented;
7982         }
7983         break;
7984     case CP0_REGISTER_17:
7985         switch (sel) {
7986         case CP0_REG17__LLADDR:
7987             gen_helper_mtc0_lladdr(tcg_env, arg);
7988             register_name = "LLAddr";
7989             break;
7990         case CP0_REG17__MAAR:
7991             CP0_CHECK(ctx->mrp);
7992             gen_helper_mtc0_maar(tcg_env, arg);
7993             register_name = "MAAR";
7994             break;
7995         case CP0_REG17__MAARI:
7996             CP0_CHECK(ctx->mrp);
7997             gen_helper_mtc0_maari(tcg_env, arg);
7998             register_name = "MAARI";
7999             break;
8000         default:
8001             goto cp0_unimplemented;
8002         }
8003         break;
8004     case CP0_REGISTER_18:
8005         switch (sel) {
8006         case CP0_REG18__WATCHLO0:
8007         case CP0_REG18__WATCHLO1:
8008         case CP0_REG18__WATCHLO2:
8009         case CP0_REG18__WATCHLO3:
8010         case CP0_REG18__WATCHLO4:
8011         case CP0_REG18__WATCHLO5:
8012         case CP0_REG18__WATCHLO6:
8013         case CP0_REG18__WATCHLO7:
8014             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8015             gen_helper_0e1i(mtc0_watchlo, arg, sel);
8016             register_name = "WatchLo";
8017             break;
8018         default:
8019             goto cp0_unimplemented;
8020         }
8021         break;
8022     case CP0_REGISTER_19:
8023         switch (sel) {
8024         case CP0_REG19__WATCHHI0:
8025         case CP0_REG19__WATCHHI1:
8026         case CP0_REG19__WATCHHI2:
8027         case CP0_REG19__WATCHHI3:
8028         case CP0_REG19__WATCHHI4:
8029         case CP0_REG19__WATCHHI5:
8030         case CP0_REG19__WATCHHI6:
8031         case CP0_REG19__WATCHHI7:
8032             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8033             gen_helper_0e1i(mtc0_watchhi, arg, sel);
8034             register_name = "WatchHi";
8035             break;
8036         default:
8037             goto cp0_unimplemented;
8038         }
8039         break;
8040     case CP0_REGISTER_20:
8041         switch (sel) {
8042         case CP0_REG20__XCONTEXT:
8043             check_insn(ctx, ISA_MIPS3);
8044             gen_helper_mtc0_xcontext(tcg_env, arg);
8045             register_name = "XContext";
8046             break;
8047         default:
8048             goto cp0_unimplemented;
8049         }
8050         break;
8051     case CP0_REGISTER_21:
8052        /* Officially reserved, but sel 0 is used for R1x000 framemask */
8053         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
8054         switch (sel) {
8055         case 0:
8056             gen_helper_mtc0_framemask(tcg_env, arg);
8057             register_name = "Framemask";
8058             break;
8059         default:
8060             goto cp0_unimplemented;
8061         }
8062         break;
8063     case CP0_REGISTER_22:
8064         /* ignored */
8065         register_name = "Diagnostic"; /* implementation dependent */
8066         break;
8067     case CP0_REGISTER_23:
8068         switch (sel) {
8069         case CP0_REG23__DEBUG:
8070             gen_helper_mtc0_debug(tcg_env, arg); /* EJTAG support */
8071             /* DISAS_STOP isn't good enough here, hflags may have changed. */
8072             gen_save_pc(ctx->base.pc_next + 4);
8073             ctx->base.is_jmp = DISAS_EXIT;
8074             register_name = "Debug";
8075             break;
8076         case CP0_REG23__TRACECONTROL:
8077             /* PDtrace support */
8078             /* gen_helper_mtc0_tracecontrol(tcg_env, arg);  */
8079             /* Stop translation as we may have switched the execution mode */
8080             ctx->base.is_jmp = DISAS_STOP;
8081             register_name = "TraceControl";
8082             goto cp0_unimplemented;
8083         case CP0_REG23__TRACECONTROL2:
8084             /* PDtrace support */
8085             /* gen_helper_mtc0_tracecontrol2(tcg_env, arg); */
8086             /* Stop translation as we may have switched the execution mode */
8087             ctx->base.is_jmp = DISAS_STOP;
8088             register_name = "TraceControl2";
8089             goto cp0_unimplemented;
8090         case CP0_REG23__USERTRACEDATA1:
8091             /* PDtrace support */
8092             /* gen_helper_mtc0_usertracedata1(tcg_env, arg);*/
8093             /* Stop translation as we may have switched the execution mode */
8094             ctx->base.is_jmp = DISAS_STOP;
8095             register_name = "UserTraceData1";
8096             goto cp0_unimplemented;
8097         case CP0_REG23__TRACEIBPC:
8098             /* PDtrace support */
8099             /* gen_helper_mtc0_traceibpc(tcg_env, arg);     */
8100             /* Stop translation as we may have switched the execution mode */
8101             ctx->base.is_jmp = DISAS_STOP;
8102             register_name = "TraceIBPC";
8103             goto cp0_unimplemented;
8104         case CP0_REG23__TRACEDBPC:
8105             /* PDtrace support */
8106             /* gen_helper_mtc0_tracedbpc(tcg_env, arg);     */
8107             /* Stop translation as we may have switched the execution mode */
8108             ctx->base.is_jmp = DISAS_STOP;
8109             register_name = "TraceDBPC";
8110             goto cp0_unimplemented;
8111         default:
8112             goto cp0_unimplemented;
8113         }
8114         break;
8115     case CP0_REGISTER_24:
8116         switch (sel) {
8117         case CP0_REG24__DEPC:
8118             /* EJTAG support */
8119             tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC));
8120             register_name = "DEPC";
8121             break;
8122         default:
8123             goto cp0_unimplemented;
8124         }
8125         break;
8126     case CP0_REGISTER_25:
8127         switch (sel) {
8128         case CP0_REG25__PERFCTL0:
8129             gen_helper_mtc0_performance0(tcg_env, arg);
8130             register_name = "Performance0";
8131             break;
8132         case CP0_REG25__PERFCNT0:
8133             /* gen_helper_mtc0_performance1(tcg_env, arg); */
8134             register_name = "Performance1";
8135             goto cp0_unimplemented;
8136         case CP0_REG25__PERFCTL1:
8137             /* gen_helper_mtc0_performance2(tcg_env, arg); */
8138             register_name = "Performance2";
8139             goto cp0_unimplemented;
8140         case CP0_REG25__PERFCNT1:
8141             /* gen_helper_mtc0_performance3(tcg_env, arg); */
8142             register_name = "Performance3";
8143             goto cp0_unimplemented;
8144         case CP0_REG25__PERFCTL2:
8145             /* gen_helper_mtc0_performance4(tcg_env, arg); */
8146             register_name = "Performance4";
8147             goto cp0_unimplemented;
8148         case CP0_REG25__PERFCNT2:
8149             /* gen_helper_mtc0_performance5(tcg_env, arg); */
8150             register_name = "Performance5";
8151             goto cp0_unimplemented;
8152         case CP0_REG25__PERFCTL3:
8153             /* gen_helper_mtc0_performance6(tcg_env, arg); */
8154             register_name = "Performance6";
8155             goto cp0_unimplemented;
8156         case CP0_REG25__PERFCNT3:
8157             /* gen_helper_mtc0_performance7(tcg_env, arg); */
8158             register_name = "Performance7";
8159             goto cp0_unimplemented;
8160         default:
8161             goto cp0_unimplemented;
8162         }
8163         break;
8164     case CP0_REGISTER_26:
8165         switch (sel) {
8166         case CP0_REG26__ERRCTL:
8167             gen_helper_mtc0_errctl(tcg_env, arg);
8168             ctx->base.is_jmp = DISAS_STOP;
8169             register_name = "ErrCtl";
8170             break;
8171         default:
8172             goto cp0_unimplemented;
8173         }
8174         break;
8175     case CP0_REGISTER_27:
8176         switch (sel) {
8177         case CP0_REG27__CACHERR:
8178             /* ignored */
8179             register_name = "CacheErr";
8180             break;
8181         default:
8182             goto cp0_unimplemented;
8183         }
8184         break;
8185     case CP0_REGISTER_28:
8186         switch (sel) {
8187         case CP0_REG28__TAGLO:
8188         case CP0_REG28__TAGLO1:
8189         case CP0_REG28__TAGLO2:
8190         case CP0_REG28__TAGLO3:
8191             gen_helper_mtc0_taglo(tcg_env, arg);
8192             register_name = "TagLo";
8193             break;
8194         case CP0_REG28__DATALO:
8195         case CP0_REG28__DATALO1:
8196         case CP0_REG28__DATALO2:
8197         case CP0_REG28__DATALO3:
8198             gen_helper_mtc0_datalo(tcg_env, arg);
8199             register_name = "DataLo";
8200             break;
8201         default:
8202             goto cp0_unimplemented;
8203         }
8204         break;
8205     case CP0_REGISTER_29:
8206         switch (sel) {
8207         case CP0_REG29__TAGHI:
8208         case CP0_REG29__TAGHI1:
8209         case CP0_REG29__TAGHI2:
8210         case CP0_REG29__TAGHI3:
8211             gen_helper_mtc0_taghi(tcg_env, arg);
8212             register_name = "TagHi";
8213             break;
8214         case CP0_REG29__DATAHI:
8215         case CP0_REG29__DATAHI1:
8216         case CP0_REG29__DATAHI2:
8217         case CP0_REG29__DATAHI3:
8218             gen_helper_mtc0_datahi(tcg_env, arg);
8219             register_name = "DataHi";
8220             break;
8221         default:
8222             register_name = "invalid sel";
8223             goto cp0_unimplemented;
8224         }
8225         break;
8226     case CP0_REGISTER_30:
8227         switch (sel) {
8228         case CP0_REG30__ERROREPC:
8229             tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8230             register_name = "ErrorEPC";
8231             break;
8232         default:
8233             goto cp0_unimplemented;
8234         }
8235         break;
8236     case CP0_REGISTER_31:
8237         switch (sel) {
8238         case CP0_REG31__DESAVE:
8239             /* EJTAG support */
8240             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8241             register_name = "DESAVE";
8242             break;
8243         case CP0_REG31__KSCRATCH1:
8244         case CP0_REG31__KSCRATCH2:
8245         case CP0_REG31__KSCRATCH3:
8246         case CP0_REG31__KSCRATCH4:
8247         case CP0_REG31__KSCRATCH5:
8248         case CP0_REG31__KSCRATCH6:
8249             CP0_CHECK(ctx->kscrexist & (1 << sel));
8250             tcg_gen_st_tl(arg, tcg_env,
8251                           offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
8252             register_name = "KScratch";
8253             break;
8254         default:
8255             goto cp0_unimplemented;
8256         }
8257         break;
8258     default:
8259         goto cp0_unimplemented;
8260     }
8261     trace_mips_translate_c0("dmtc0", register_name, reg, sel);
8262 
8263     /* For simplicity assume that all writes can cause interrupts.  */
8264     if (icount) {
8265         /*
8266          * DISAS_STOP isn't sufficient, we need to ensure we break out of
8267          * translated code to check for pending interrupts.
8268          */
8269         gen_save_pc(ctx->base.pc_next + 4);
8270         ctx->base.is_jmp = DISAS_EXIT;
8271     }
8272     return;
8273 
8274 cp0_unimplemented:
8275     qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n",
8276                   register_name, reg, sel);
8277 }
8278 #endif /* TARGET_MIPS64 */
8279 
gen_mftr(CPUMIPSState * env,DisasContext * ctx,int rt,int rd,int u,int sel,int h)8280 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
8281                      int u, int sel, int h)
8282 {
8283     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
8284     TCGv t0 = tcg_temp_new();
8285 
8286     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
8287         ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8288          (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
8289         tcg_gen_movi_tl(t0, -1);
8290     } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8291                (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
8292         tcg_gen_movi_tl(t0, -1);
8293     } else if (u == 0) {
8294         switch (rt) {
8295         case 1:
8296             switch (sel) {
8297             case 1:
8298                 gen_helper_mftc0_vpecontrol(t0, tcg_env);
8299                 break;
8300             case 2:
8301                 gen_helper_mftc0_vpeconf0(t0, tcg_env);
8302                 break;
8303             default:
8304                 goto die;
8305                 break;
8306             }
8307             break;
8308         case 2:
8309             switch (sel) {
8310             case 1:
8311                 gen_helper_mftc0_tcstatus(t0, tcg_env);
8312                 break;
8313             case 2:
8314                 gen_helper_mftc0_tcbind(t0, tcg_env);
8315                 break;
8316             case 3:
8317                 gen_helper_mftc0_tcrestart(t0, tcg_env);
8318                 break;
8319             case 4:
8320                 gen_helper_mftc0_tchalt(t0, tcg_env);
8321                 break;
8322             case 5:
8323                 gen_helper_mftc0_tccontext(t0, tcg_env);
8324                 break;
8325             case 6:
8326                 gen_helper_mftc0_tcschedule(t0, tcg_env);
8327                 break;
8328             case 7:
8329                 gen_helper_mftc0_tcschefback(t0, tcg_env);
8330                 break;
8331             default:
8332                 gen_mfc0(ctx, t0, rt, sel);
8333                 break;
8334             }
8335             break;
8336         case 10:
8337             switch (sel) {
8338             case 0:
8339                 gen_helper_mftc0_entryhi(t0, tcg_env);
8340                 break;
8341             default:
8342                 gen_mfc0(ctx, t0, rt, sel);
8343                 break;
8344             }
8345             break;
8346         case 12:
8347             switch (sel) {
8348             case 0:
8349                 gen_helper_mftc0_status(t0, tcg_env);
8350                 break;
8351             default:
8352                 gen_mfc0(ctx, t0, rt, sel);
8353                 break;
8354             }
8355             break;
8356         case 13:
8357             switch (sel) {
8358             case 0:
8359                 gen_helper_mftc0_cause(t0, tcg_env);
8360                 break;
8361             default:
8362                 goto die;
8363                 break;
8364             }
8365             break;
8366         case 14:
8367             switch (sel) {
8368             case 0:
8369                 gen_helper_mftc0_epc(t0, tcg_env);
8370                 break;
8371             default:
8372                 goto die;
8373                 break;
8374             }
8375             break;
8376         case 15:
8377             switch (sel) {
8378             case 1:
8379                 gen_helper_mftc0_ebase(t0, tcg_env);
8380                 break;
8381             default:
8382                 goto die;
8383                 break;
8384             }
8385             break;
8386         case 16:
8387             switch (sel) {
8388             case 0:
8389             case 1:
8390             case 2:
8391             case 3:
8392             case 4:
8393             case 5:
8394             case 6:
8395             case 7:
8396                 gen_helper_mftc0_configx(t0, tcg_env, tcg_constant_tl(sel));
8397                 break;
8398             default:
8399                 goto die;
8400                 break;
8401             }
8402             break;
8403         case 23:
8404             switch (sel) {
8405             case 0:
8406                 gen_helper_mftc0_debug(t0, tcg_env);
8407                 break;
8408             default:
8409                 gen_mfc0(ctx, t0, rt, sel);
8410                 break;
8411             }
8412             break;
8413         default:
8414             gen_mfc0(ctx, t0, rt, sel);
8415         }
8416     } else {
8417         switch (sel) {
8418         /* GPR registers. */
8419         case 0:
8420             gen_helper_1e0i(mftgpr, t0, rt);
8421             break;
8422         /* Auxiliary CPU registers */
8423         case 1:
8424             switch (rt) {
8425             case 0:
8426                 gen_helper_1e0i(mftlo, t0, 0);
8427                 break;
8428             case 1:
8429                 gen_helper_1e0i(mfthi, t0, 0);
8430                 break;
8431             case 2:
8432                 gen_helper_1e0i(mftacx, t0, 0);
8433                 break;
8434             case 4:
8435                 gen_helper_1e0i(mftlo, t0, 1);
8436                 break;
8437             case 5:
8438                 gen_helper_1e0i(mfthi, t0, 1);
8439                 break;
8440             case 6:
8441                 gen_helper_1e0i(mftacx, t0, 1);
8442                 break;
8443             case 8:
8444                 gen_helper_1e0i(mftlo, t0, 2);
8445                 break;
8446             case 9:
8447                 gen_helper_1e0i(mfthi, t0, 2);
8448                 break;
8449             case 10:
8450                 gen_helper_1e0i(mftacx, t0, 2);
8451                 break;
8452             case 12:
8453                 gen_helper_1e0i(mftlo, t0, 3);
8454                 break;
8455             case 13:
8456                 gen_helper_1e0i(mfthi, t0, 3);
8457                 break;
8458             case 14:
8459                 gen_helper_1e0i(mftacx, t0, 3);
8460                 break;
8461             case 16:
8462                 gen_helper_mftdsp(t0, tcg_env);
8463                 break;
8464             default:
8465                 goto die;
8466             }
8467             break;
8468         /* Floating point (COP1). */
8469         case 2:
8470             /* XXX: For now we support only a single FPU context. */
8471             if (h == 0) {
8472                 TCGv_i32 fp0 = tcg_temp_new_i32();
8473 
8474                 gen_load_fpr32(ctx, fp0, rt);
8475                 tcg_gen_ext_i32_tl(t0, fp0);
8476             } else {
8477                 TCGv_i32 fp0 = tcg_temp_new_i32();
8478 
8479                 gen_load_fpr32h(ctx, fp0, rt);
8480                 tcg_gen_ext_i32_tl(t0, fp0);
8481             }
8482             break;
8483         case 3:
8484             /* XXX: For now we support only a single FPU context. */
8485             gen_helper_1e0i(cfc1, t0, rt);
8486             break;
8487         /* COP2: Not implemented. */
8488         case 4:
8489         case 5:
8490             /* fall through */
8491         default:
8492             goto die;
8493         }
8494     }
8495     trace_mips_translate_tr("mftr", rt, u, sel, h);
8496     gen_store_gpr(t0, rd);
8497     return;
8498 
8499 die:
8500     LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
8501     gen_reserved_instruction(ctx);
8502 }
8503 
gen_mttr(CPUMIPSState * env,DisasContext * ctx,int rd,int rt,int u,int sel,int h)8504 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
8505                      int u, int sel, int h)
8506 {
8507     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
8508     TCGv t0 = tcg_temp_new();
8509 
8510     gen_load_gpr(t0, rt);
8511     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
8512         ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8513          (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
8514         /* NOP */
8515         ;
8516     } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8517              (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
8518         /* NOP */
8519         ;
8520     } else if (u == 0) {
8521         switch (rd) {
8522         case 1:
8523             switch (sel) {
8524             case 1:
8525                 gen_helper_mttc0_vpecontrol(tcg_env, t0);
8526                 break;
8527             case 2:
8528                 gen_helper_mttc0_vpeconf0(tcg_env, t0);
8529                 break;
8530             default:
8531                 goto die;
8532                 break;
8533             }
8534             break;
8535         case 2:
8536             switch (sel) {
8537             case 1:
8538                 gen_helper_mttc0_tcstatus(tcg_env, t0);
8539                 break;
8540             case 2:
8541                 gen_helper_mttc0_tcbind(tcg_env, t0);
8542                 break;
8543             case 3:
8544                 gen_helper_mttc0_tcrestart(tcg_env, t0);
8545                 break;
8546             case 4:
8547                 gen_helper_mttc0_tchalt(tcg_env, t0);
8548                 break;
8549             case 5:
8550                 gen_helper_mttc0_tccontext(tcg_env, t0);
8551                 break;
8552             case 6:
8553                 gen_helper_mttc0_tcschedule(tcg_env, t0);
8554                 break;
8555             case 7:
8556                 gen_helper_mttc0_tcschefback(tcg_env, t0);
8557                 break;
8558             default:
8559                 gen_mtc0(ctx, t0, rd, sel);
8560                 break;
8561             }
8562             break;
8563         case 10:
8564             switch (sel) {
8565             case 0:
8566                 gen_helper_mttc0_entryhi(tcg_env, t0);
8567                 break;
8568             default:
8569                 gen_mtc0(ctx, t0, rd, sel);
8570                 break;
8571             }
8572             break;
8573         case 12:
8574             switch (sel) {
8575             case 0:
8576                 gen_helper_mttc0_status(tcg_env, t0);
8577                 break;
8578             default:
8579                 gen_mtc0(ctx, t0, rd, sel);
8580                 break;
8581             }
8582             break;
8583         case 13:
8584             switch (sel) {
8585             case 0:
8586                 gen_helper_mttc0_cause(tcg_env, t0);
8587                 break;
8588             default:
8589                 goto die;
8590                 break;
8591             }
8592             break;
8593         case 15:
8594             switch (sel) {
8595             case 1:
8596                 gen_helper_mttc0_ebase(tcg_env, t0);
8597                 break;
8598             default:
8599                 goto die;
8600                 break;
8601             }
8602             break;
8603         case 23:
8604             switch (sel) {
8605             case 0:
8606                 gen_helper_mttc0_debug(tcg_env, t0);
8607                 break;
8608             default:
8609                 gen_mtc0(ctx, t0, rd, sel);
8610                 break;
8611             }
8612             break;
8613         default:
8614             gen_mtc0(ctx, t0, rd, sel);
8615         }
8616     } else {
8617         switch (sel) {
8618         /* GPR registers. */
8619         case 0:
8620             gen_helper_0e1i(mttgpr, t0, rd);
8621             break;
8622         /* Auxiliary CPU registers */
8623         case 1:
8624             switch (rd) {
8625             case 0:
8626                 gen_helper_0e1i(mttlo, t0, 0);
8627                 break;
8628             case 1:
8629                 gen_helper_0e1i(mtthi, t0, 0);
8630                 break;
8631             case 2:
8632                 gen_helper_0e1i(mttacx, t0, 0);
8633                 break;
8634             case 4:
8635                 gen_helper_0e1i(mttlo, t0, 1);
8636                 break;
8637             case 5:
8638                 gen_helper_0e1i(mtthi, t0, 1);
8639                 break;
8640             case 6:
8641                 gen_helper_0e1i(mttacx, t0, 1);
8642                 break;
8643             case 8:
8644                 gen_helper_0e1i(mttlo, t0, 2);
8645                 break;
8646             case 9:
8647                 gen_helper_0e1i(mtthi, t0, 2);
8648                 break;
8649             case 10:
8650                 gen_helper_0e1i(mttacx, t0, 2);
8651                 break;
8652             case 12:
8653                 gen_helper_0e1i(mttlo, t0, 3);
8654                 break;
8655             case 13:
8656                 gen_helper_0e1i(mtthi, t0, 3);
8657                 break;
8658             case 14:
8659                 gen_helper_0e1i(mttacx, t0, 3);
8660                 break;
8661             case 16:
8662                 gen_helper_mttdsp(tcg_env, t0);
8663                 break;
8664             default:
8665                 goto die;
8666             }
8667             break;
8668         /* Floating point (COP1). */
8669         case 2:
8670             /* XXX: For now we support only a single FPU context. */
8671             if (h == 0) {
8672                 TCGv_i32 fp0 = tcg_temp_new_i32();
8673 
8674                 tcg_gen_trunc_tl_i32(fp0, t0);
8675                 gen_store_fpr32(ctx, fp0, rd);
8676             } else {
8677                 TCGv_i32 fp0 = tcg_temp_new_i32();
8678 
8679                 tcg_gen_trunc_tl_i32(fp0, t0);
8680                 gen_store_fpr32h(ctx, fp0, rd);
8681             }
8682             break;
8683         case 3:
8684             /* XXX: For now we support only a single FPU context. */
8685             gen_helper_0e2i(ctc1, t0, tcg_constant_i32(rd), rt);
8686             /* Stop translation as we may have changed hflags */
8687             ctx->base.is_jmp = DISAS_STOP;
8688             break;
8689         /* COP2: Not implemented. */
8690         case 4:
8691         case 5:
8692             /* fall through */
8693         default:
8694             goto die;
8695         }
8696     }
8697     trace_mips_translate_tr("mttr", rd, u, sel, h);
8698     return;
8699 
8700 die:
8701     LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
8702     gen_reserved_instruction(ctx);
8703 }
8704 
gen_cp0(CPUMIPSState * env,DisasContext * ctx,uint32_t opc,int rt,int rd)8705 static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
8706                     int rt, int rd)
8707 {
8708     const char *opn = "ldst";
8709 
8710     check_cp0_enabled(ctx);
8711     switch (opc) {
8712     case OPC_MFC0:
8713         if (rt == 0) {
8714             /* Treat as NOP. */
8715             return;
8716         }
8717         gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8718         opn = "mfc0";
8719         break;
8720     case OPC_MTC0:
8721         {
8722             TCGv t0 = tcg_temp_new();
8723 
8724             gen_load_gpr(t0, rt);
8725             gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
8726         }
8727         opn = "mtc0";
8728         break;
8729 #if defined(TARGET_MIPS64)
8730     case OPC_DMFC0:
8731         check_insn(ctx, ISA_MIPS3);
8732         if (rt == 0) {
8733             /* Treat as NOP. */
8734             return;
8735         }
8736         gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8737         opn = "dmfc0";
8738         break;
8739     case OPC_DMTC0:
8740         check_insn(ctx, ISA_MIPS3);
8741         {
8742             TCGv t0 = tcg_temp_new();
8743 
8744             gen_load_gpr(t0, rt);
8745             gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
8746         }
8747         opn = "dmtc0";
8748         break;
8749 #endif
8750     case OPC_MFHC0:
8751         check_mvh(ctx);
8752         if (rt == 0) {
8753             /* Treat as NOP. */
8754             return;
8755         }
8756         gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8757         opn = "mfhc0";
8758         break;
8759     case OPC_MTHC0:
8760         check_mvh(ctx);
8761         {
8762             TCGv t0 = tcg_temp_new();
8763             gen_load_gpr(t0, rt);
8764             gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
8765         }
8766         opn = "mthc0";
8767         break;
8768     case OPC_MFTR:
8769         check_cp0_enabled(ctx);
8770         if (rd == 0) {
8771             /* Treat as NOP. */
8772             return;
8773         }
8774         gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
8775                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8776         opn = "mftr";
8777         break;
8778     case OPC_MTTR:
8779         check_cp0_enabled(ctx);
8780         gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
8781                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8782         opn = "mttr";
8783         break;
8784     case OPC_TLBWI:
8785         opn = "tlbwi";
8786         if (!env->tlb->helper_tlbwi) {
8787             goto die;
8788         }
8789         gen_helper_tlbwi(tcg_env);
8790         break;
8791     case OPC_TLBINV:
8792         opn = "tlbinv";
8793         if (ctx->ie >= 2) {
8794             if (!env->tlb->helper_tlbinv) {
8795                 goto die;
8796             }
8797             gen_helper_tlbinv(tcg_env);
8798         } /* treat as nop if TLBINV not supported */
8799         break;
8800     case OPC_TLBINVF:
8801         opn = "tlbinvf";
8802         if (ctx->ie >= 2) {
8803             if (!env->tlb->helper_tlbinvf) {
8804                 goto die;
8805             }
8806             gen_helper_tlbinvf(tcg_env);
8807         } /* treat as nop if TLBINV not supported */
8808         break;
8809     case OPC_TLBWR:
8810         opn = "tlbwr";
8811         if (!env->tlb->helper_tlbwr) {
8812             goto die;
8813         }
8814         gen_helper_tlbwr(tcg_env);
8815         break;
8816     case OPC_TLBP:
8817         opn = "tlbp";
8818         if (!env->tlb->helper_tlbp) {
8819             goto die;
8820         }
8821         gen_helper_tlbp(tcg_env);
8822         break;
8823     case OPC_TLBR:
8824         opn = "tlbr";
8825         if (!env->tlb->helper_tlbr) {
8826             goto die;
8827         }
8828         gen_helper_tlbr(tcg_env);
8829         break;
8830     case OPC_ERET: /* OPC_ERETNC */
8831         if ((ctx->insn_flags & ISA_MIPS_R6) &&
8832             (ctx->hflags & MIPS_HFLAG_BMASK)) {
8833             goto die;
8834         } else {
8835             int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
8836             if (ctx->opcode & (1 << bit_shift)) {
8837                 /* OPC_ERETNC */
8838                 opn = "eretnc";
8839                 check_insn(ctx, ISA_MIPS_R5);
8840                 gen_helper_eretnc(tcg_env);
8841             } else {
8842                 /* OPC_ERET */
8843                 opn = "eret";
8844                 check_insn(ctx, ISA_MIPS2);
8845                 gen_helper_eret(tcg_env);
8846             }
8847             ctx->base.is_jmp = DISAS_EXIT;
8848         }
8849         break;
8850     case OPC_DERET:
8851         opn = "deret";
8852         check_insn(ctx, ISA_MIPS_R1);
8853         if ((ctx->insn_flags & ISA_MIPS_R6) &&
8854             (ctx->hflags & MIPS_HFLAG_BMASK)) {
8855             goto die;
8856         }
8857         if (!(ctx->hflags & MIPS_HFLAG_DM)) {
8858             MIPS_INVAL(opn);
8859             gen_reserved_instruction(ctx);
8860         } else {
8861             gen_helper_deret(tcg_env);
8862             ctx->base.is_jmp = DISAS_EXIT;
8863         }
8864         break;
8865     case OPC_WAIT:
8866         opn = "wait";
8867         check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1);
8868         if ((ctx->insn_flags & ISA_MIPS_R6) &&
8869             (ctx->hflags & MIPS_HFLAG_BMASK)) {
8870             goto die;
8871         }
8872         /* If we get an exception, we want to restart at next instruction */
8873         ctx->base.pc_next += 4;
8874         save_cpu_state(ctx, 1);
8875         ctx->base.pc_next -= 4;
8876         gen_helper_wait(tcg_env);
8877         ctx->base.is_jmp = DISAS_NORETURN;
8878         break;
8879     default:
8880  die:
8881         MIPS_INVAL(opn);
8882         gen_reserved_instruction(ctx);
8883         return;
8884     }
8885     (void)opn; /* avoid a compiler warning */
8886 }
8887 #endif /* !CONFIG_USER_ONLY */
8888 
8889 /* CP1 Branches (before delay slot) */
gen_compute_branch1(DisasContext * ctx,uint32_t op,int32_t cc,int32_t offset)8890 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
8891                                 int32_t cc, int32_t offset)
8892 {
8893     target_ulong btarget;
8894     TCGv_i32 t0 = tcg_temp_new_i32();
8895 
8896     if ((ctx->insn_flags & ISA_MIPS_R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8897         gen_reserved_instruction(ctx);
8898         return;
8899     }
8900 
8901     if (cc != 0) {
8902         check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1);
8903     }
8904 
8905     btarget = ctx->base.pc_next + 4 + offset;
8906 
8907     switch (op) {
8908     case OPC_BC1F:
8909         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8910         tcg_gen_not_i32(t0, t0);
8911         tcg_gen_andi_i32(t0, t0, 1);
8912         tcg_gen_extu_i32_tl(bcond, t0);
8913         goto not_likely;
8914     case OPC_BC1FL:
8915         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8916         tcg_gen_not_i32(t0, t0);
8917         tcg_gen_andi_i32(t0, t0, 1);
8918         tcg_gen_extu_i32_tl(bcond, t0);
8919         goto likely;
8920     case OPC_BC1T:
8921         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8922         tcg_gen_andi_i32(t0, t0, 1);
8923         tcg_gen_extu_i32_tl(bcond, t0);
8924         goto not_likely;
8925     case OPC_BC1TL:
8926         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8927         tcg_gen_andi_i32(t0, t0, 1);
8928         tcg_gen_extu_i32_tl(bcond, t0);
8929     likely:
8930         ctx->hflags |= MIPS_HFLAG_BL;
8931         break;
8932     case OPC_BC1FANY2:
8933         {
8934             TCGv_i32 t1 = tcg_temp_new_i32();
8935             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8936             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
8937             tcg_gen_nand_i32(t0, t0, t1);
8938             tcg_gen_andi_i32(t0, t0, 1);
8939             tcg_gen_extu_i32_tl(bcond, t0);
8940         }
8941         goto not_likely;
8942     case OPC_BC1TANY2:
8943         {
8944             TCGv_i32 t1 = tcg_temp_new_i32();
8945             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8946             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
8947             tcg_gen_or_i32(t0, t0, t1);
8948             tcg_gen_andi_i32(t0, t0, 1);
8949             tcg_gen_extu_i32_tl(bcond, t0);
8950         }
8951         goto not_likely;
8952     case OPC_BC1FANY4:
8953         {
8954             TCGv_i32 t1 = tcg_temp_new_i32();
8955             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8956             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
8957             tcg_gen_and_i32(t0, t0, t1);
8958             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
8959             tcg_gen_and_i32(t0, t0, t1);
8960             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
8961             tcg_gen_nand_i32(t0, t0, t1);
8962             tcg_gen_andi_i32(t0, t0, 1);
8963             tcg_gen_extu_i32_tl(bcond, t0);
8964         }
8965         goto not_likely;
8966     case OPC_BC1TANY4:
8967         {
8968             TCGv_i32 t1 = tcg_temp_new_i32();
8969             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8970             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
8971             tcg_gen_or_i32(t0, t0, t1);
8972             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
8973             tcg_gen_or_i32(t0, t0, t1);
8974             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
8975             tcg_gen_or_i32(t0, t0, t1);
8976             tcg_gen_andi_i32(t0, t0, 1);
8977             tcg_gen_extu_i32_tl(bcond, t0);
8978         }
8979     not_likely:
8980         ctx->hflags |= MIPS_HFLAG_BC;
8981         break;
8982     default:
8983         MIPS_INVAL("cp1 cond branch");
8984         gen_reserved_instruction(ctx);
8985         return;
8986     }
8987     ctx->btarget = btarget;
8988     ctx->hflags |= MIPS_HFLAG_BDS32;
8989 }
8990 
8991 /* R6 CP1 Branches */
gen_compute_branch1_r6(DisasContext * ctx,uint32_t op,int32_t ft,int32_t offset,int delayslot_size)8992 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
8993                                    int32_t ft, int32_t offset,
8994                                    int delayslot_size)
8995 {
8996     target_ulong btarget;
8997     TCGv_i64 t0 = tcg_temp_new_i64();
8998 
8999     if (ctx->hflags & MIPS_HFLAG_BMASK) {
9000 #ifdef MIPS_DEBUG_DISAS
9001         LOG_DISAS("Branch in delay / forbidden slot at PC 0x%016"
9002                   VADDR_PRIx "\n", ctx->base.pc_next);
9003 #endif
9004         gen_reserved_instruction(ctx);
9005         return;
9006     }
9007 
9008     gen_load_fpr64(ctx, t0, ft);
9009     tcg_gen_andi_i64(t0, t0, 1);
9010 
9011     btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
9012 
9013     switch (op) {
9014     case OPC_BC1EQZ:
9015         tcg_gen_xori_i64(t0, t0, 1);
9016         ctx->hflags |= MIPS_HFLAG_BC;
9017         break;
9018     case OPC_BC1NEZ:
9019         /* t0 already set */
9020         ctx->hflags |= MIPS_HFLAG_BC;
9021         break;
9022     default:
9023         MIPS_INVAL("cp1 cond branch");
9024         gen_reserved_instruction(ctx);
9025         return;
9026     }
9027 
9028     tcg_gen_trunc_i64_tl(bcond, t0);
9029 
9030     ctx->btarget = btarget;
9031 
9032     switch (delayslot_size) {
9033     case 2:
9034         ctx->hflags |= MIPS_HFLAG_BDS16;
9035         break;
9036     case 4:
9037         ctx->hflags |= MIPS_HFLAG_BDS32;
9038         break;
9039     }
9040 }
9041 
9042 /* Coprocessor 1 (FPU) */
9043 
9044 #define FOP(func, fmt) (((fmt) << 21) | (func))
9045 
9046 enum fopcode {
9047     OPC_ADD_S = FOP(0, FMT_S),
9048     OPC_SUB_S = FOP(1, FMT_S),
9049     OPC_MUL_S = FOP(2, FMT_S),
9050     OPC_DIV_S = FOP(3, FMT_S),
9051     OPC_SQRT_S = FOP(4, FMT_S),
9052     OPC_ABS_S = FOP(5, FMT_S),
9053     OPC_MOV_S = FOP(6, FMT_S),
9054     OPC_NEG_S = FOP(7, FMT_S),
9055     OPC_ROUND_L_S = FOP(8, FMT_S),
9056     OPC_TRUNC_L_S = FOP(9, FMT_S),
9057     OPC_CEIL_L_S = FOP(10, FMT_S),
9058     OPC_FLOOR_L_S = FOP(11, FMT_S),
9059     OPC_ROUND_W_S = FOP(12, FMT_S),
9060     OPC_TRUNC_W_S = FOP(13, FMT_S),
9061     OPC_CEIL_W_S = FOP(14, FMT_S),
9062     OPC_FLOOR_W_S = FOP(15, FMT_S),
9063     OPC_SEL_S = FOP(16, FMT_S),
9064     OPC_MOVCF_S = FOP(17, FMT_S),
9065     OPC_MOVZ_S = FOP(18, FMT_S),
9066     OPC_MOVN_S = FOP(19, FMT_S),
9067     OPC_SELEQZ_S = FOP(20, FMT_S),
9068     OPC_RECIP_S = FOP(21, FMT_S),
9069     OPC_RSQRT_S = FOP(22, FMT_S),
9070     OPC_SELNEZ_S = FOP(23, FMT_S),
9071     OPC_MADDF_S = FOP(24, FMT_S),
9072     OPC_MSUBF_S = FOP(25, FMT_S),
9073     OPC_RINT_S = FOP(26, FMT_S),
9074     OPC_CLASS_S = FOP(27, FMT_S),
9075     OPC_MIN_S = FOP(28, FMT_S),
9076     OPC_RECIP2_S = FOP(28, FMT_S),
9077     OPC_MINA_S = FOP(29, FMT_S),
9078     OPC_RECIP1_S = FOP(29, FMT_S),
9079     OPC_MAX_S = FOP(30, FMT_S),
9080     OPC_RSQRT1_S = FOP(30, FMT_S),
9081     OPC_MAXA_S = FOP(31, FMT_S),
9082     OPC_RSQRT2_S = FOP(31, FMT_S),
9083     OPC_CVT_D_S = FOP(33, FMT_S),
9084     OPC_CVT_W_S = FOP(36, FMT_S),
9085     OPC_CVT_L_S = FOP(37, FMT_S),
9086     OPC_CVT_PS_S = FOP(38, FMT_S),
9087     OPC_CMP_F_S = FOP(48, FMT_S),
9088     OPC_CMP_UN_S = FOP(49, FMT_S),
9089     OPC_CMP_EQ_S = FOP(50, FMT_S),
9090     OPC_CMP_UEQ_S = FOP(51, FMT_S),
9091     OPC_CMP_OLT_S = FOP(52, FMT_S),
9092     OPC_CMP_ULT_S = FOP(53, FMT_S),
9093     OPC_CMP_OLE_S = FOP(54, FMT_S),
9094     OPC_CMP_ULE_S = FOP(55, FMT_S),
9095     OPC_CMP_SF_S = FOP(56, FMT_S),
9096     OPC_CMP_NGLE_S = FOP(57, FMT_S),
9097     OPC_CMP_SEQ_S = FOP(58, FMT_S),
9098     OPC_CMP_NGL_S = FOP(59, FMT_S),
9099     OPC_CMP_LT_S = FOP(60, FMT_S),
9100     OPC_CMP_NGE_S = FOP(61, FMT_S),
9101     OPC_CMP_LE_S = FOP(62, FMT_S),
9102     OPC_CMP_NGT_S = FOP(63, FMT_S),
9103 
9104     OPC_ADD_D = FOP(0, FMT_D),
9105     OPC_SUB_D = FOP(1, FMT_D),
9106     OPC_MUL_D = FOP(2, FMT_D),
9107     OPC_DIV_D = FOP(3, FMT_D),
9108     OPC_SQRT_D = FOP(4, FMT_D),
9109     OPC_ABS_D = FOP(5, FMT_D),
9110     OPC_MOV_D = FOP(6, FMT_D),
9111     OPC_NEG_D = FOP(7, FMT_D),
9112     OPC_ROUND_L_D = FOP(8, FMT_D),
9113     OPC_TRUNC_L_D = FOP(9, FMT_D),
9114     OPC_CEIL_L_D = FOP(10, FMT_D),
9115     OPC_FLOOR_L_D = FOP(11, FMT_D),
9116     OPC_ROUND_W_D = FOP(12, FMT_D),
9117     OPC_TRUNC_W_D = FOP(13, FMT_D),
9118     OPC_CEIL_W_D = FOP(14, FMT_D),
9119     OPC_FLOOR_W_D = FOP(15, FMT_D),
9120     OPC_SEL_D = FOP(16, FMT_D),
9121     OPC_MOVCF_D = FOP(17, FMT_D),
9122     OPC_MOVZ_D = FOP(18, FMT_D),
9123     OPC_MOVN_D = FOP(19, FMT_D),
9124     OPC_SELEQZ_D = FOP(20, FMT_D),
9125     OPC_RECIP_D = FOP(21, FMT_D),
9126     OPC_RSQRT_D = FOP(22, FMT_D),
9127     OPC_SELNEZ_D = FOP(23, FMT_D),
9128     OPC_MADDF_D = FOP(24, FMT_D),
9129     OPC_MSUBF_D = FOP(25, FMT_D),
9130     OPC_RINT_D = FOP(26, FMT_D),
9131     OPC_CLASS_D = FOP(27, FMT_D),
9132     OPC_MIN_D = FOP(28, FMT_D),
9133     OPC_RECIP2_D = FOP(28, FMT_D),
9134     OPC_MINA_D = FOP(29, FMT_D),
9135     OPC_RECIP1_D = FOP(29, FMT_D),
9136     OPC_MAX_D = FOP(30, FMT_D),
9137     OPC_RSQRT1_D = FOP(30, FMT_D),
9138     OPC_MAXA_D = FOP(31, FMT_D),
9139     OPC_RSQRT2_D = FOP(31, FMT_D),
9140     OPC_CVT_S_D = FOP(32, FMT_D),
9141     OPC_CVT_W_D = FOP(36, FMT_D),
9142     OPC_CVT_L_D = FOP(37, FMT_D),
9143     OPC_CMP_F_D = FOP(48, FMT_D),
9144     OPC_CMP_UN_D = FOP(49, FMT_D),
9145     OPC_CMP_EQ_D = FOP(50, FMT_D),
9146     OPC_CMP_UEQ_D = FOP(51, FMT_D),
9147     OPC_CMP_OLT_D = FOP(52, FMT_D),
9148     OPC_CMP_ULT_D = FOP(53, FMT_D),
9149     OPC_CMP_OLE_D = FOP(54, FMT_D),
9150     OPC_CMP_ULE_D = FOP(55, FMT_D),
9151     OPC_CMP_SF_D = FOP(56, FMT_D),
9152     OPC_CMP_NGLE_D = FOP(57, FMT_D),
9153     OPC_CMP_SEQ_D = FOP(58, FMT_D),
9154     OPC_CMP_NGL_D = FOP(59, FMT_D),
9155     OPC_CMP_LT_D = FOP(60, FMT_D),
9156     OPC_CMP_NGE_D = FOP(61, FMT_D),
9157     OPC_CMP_LE_D = FOP(62, FMT_D),
9158     OPC_CMP_NGT_D = FOP(63, FMT_D),
9159 
9160     OPC_CVT_S_W = FOP(32, FMT_W),
9161     OPC_CVT_D_W = FOP(33, FMT_W),
9162     OPC_CVT_S_L = FOP(32, FMT_L),
9163     OPC_CVT_D_L = FOP(33, FMT_L),
9164     OPC_CVT_PS_PW = FOP(38, FMT_W),
9165 
9166     OPC_ADD_PS = FOP(0, FMT_PS),
9167     OPC_SUB_PS = FOP(1, FMT_PS),
9168     OPC_MUL_PS = FOP(2, FMT_PS),
9169     OPC_DIV_PS = FOP(3, FMT_PS),
9170     OPC_ABS_PS = FOP(5, FMT_PS),
9171     OPC_MOV_PS = FOP(6, FMT_PS),
9172     OPC_NEG_PS = FOP(7, FMT_PS),
9173     OPC_MOVCF_PS = FOP(17, FMT_PS),
9174     OPC_MOVZ_PS = FOP(18, FMT_PS),
9175     OPC_MOVN_PS = FOP(19, FMT_PS),
9176     OPC_ADDR_PS = FOP(24, FMT_PS),
9177     OPC_MULR_PS = FOP(26, FMT_PS),
9178     OPC_RECIP2_PS = FOP(28, FMT_PS),
9179     OPC_RECIP1_PS = FOP(29, FMT_PS),
9180     OPC_RSQRT1_PS = FOP(30, FMT_PS),
9181     OPC_RSQRT2_PS = FOP(31, FMT_PS),
9182 
9183     OPC_CVT_S_PU = FOP(32, FMT_PS),
9184     OPC_CVT_PW_PS = FOP(36, FMT_PS),
9185     OPC_CVT_S_PL = FOP(40, FMT_PS),
9186     OPC_PLL_PS = FOP(44, FMT_PS),
9187     OPC_PLU_PS = FOP(45, FMT_PS),
9188     OPC_PUL_PS = FOP(46, FMT_PS),
9189     OPC_PUU_PS = FOP(47, FMT_PS),
9190     OPC_CMP_F_PS = FOP(48, FMT_PS),
9191     OPC_CMP_UN_PS = FOP(49, FMT_PS),
9192     OPC_CMP_EQ_PS = FOP(50, FMT_PS),
9193     OPC_CMP_UEQ_PS = FOP(51, FMT_PS),
9194     OPC_CMP_OLT_PS = FOP(52, FMT_PS),
9195     OPC_CMP_ULT_PS = FOP(53, FMT_PS),
9196     OPC_CMP_OLE_PS = FOP(54, FMT_PS),
9197     OPC_CMP_ULE_PS = FOP(55, FMT_PS),
9198     OPC_CMP_SF_PS = FOP(56, FMT_PS),
9199     OPC_CMP_NGLE_PS = FOP(57, FMT_PS),
9200     OPC_CMP_SEQ_PS = FOP(58, FMT_PS),
9201     OPC_CMP_NGL_PS = FOP(59, FMT_PS),
9202     OPC_CMP_LT_PS = FOP(60, FMT_PS),
9203     OPC_CMP_NGE_PS = FOP(61, FMT_PS),
9204     OPC_CMP_LE_PS = FOP(62, FMT_PS),
9205     OPC_CMP_NGT_PS = FOP(63, FMT_PS),
9206 };
9207 
9208 enum r6_f_cmp_op {
9209     R6_OPC_CMP_AF_S   = FOP(0, FMT_W),
9210     R6_OPC_CMP_UN_S   = FOP(1, FMT_W),
9211     R6_OPC_CMP_EQ_S   = FOP(2, FMT_W),
9212     R6_OPC_CMP_UEQ_S  = FOP(3, FMT_W),
9213     R6_OPC_CMP_LT_S   = FOP(4, FMT_W),
9214     R6_OPC_CMP_ULT_S  = FOP(5, FMT_W),
9215     R6_OPC_CMP_LE_S   = FOP(6, FMT_W),
9216     R6_OPC_CMP_ULE_S  = FOP(7, FMT_W),
9217     R6_OPC_CMP_SAF_S  = FOP(8, FMT_W),
9218     R6_OPC_CMP_SUN_S  = FOP(9, FMT_W),
9219     R6_OPC_CMP_SEQ_S  = FOP(10, FMT_W),
9220     R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
9221     R6_OPC_CMP_SLT_S  = FOP(12, FMT_W),
9222     R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
9223     R6_OPC_CMP_SLE_S  = FOP(14, FMT_W),
9224     R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
9225     R6_OPC_CMP_OR_S   = FOP(17, FMT_W),
9226     R6_OPC_CMP_UNE_S  = FOP(18, FMT_W),
9227     R6_OPC_CMP_NE_S   = FOP(19, FMT_W),
9228     R6_OPC_CMP_SOR_S  = FOP(25, FMT_W),
9229     R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
9230     R6_OPC_CMP_SNE_S  = FOP(27, FMT_W),
9231 
9232     R6_OPC_CMP_AF_D   = FOP(0, FMT_L),
9233     R6_OPC_CMP_UN_D   = FOP(1, FMT_L),
9234     R6_OPC_CMP_EQ_D   = FOP(2, FMT_L),
9235     R6_OPC_CMP_UEQ_D  = FOP(3, FMT_L),
9236     R6_OPC_CMP_LT_D   = FOP(4, FMT_L),
9237     R6_OPC_CMP_ULT_D  = FOP(5, FMT_L),
9238     R6_OPC_CMP_LE_D   = FOP(6, FMT_L),
9239     R6_OPC_CMP_ULE_D  = FOP(7, FMT_L),
9240     R6_OPC_CMP_SAF_D  = FOP(8, FMT_L),
9241     R6_OPC_CMP_SUN_D  = FOP(9, FMT_L),
9242     R6_OPC_CMP_SEQ_D  = FOP(10, FMT_L),
9243     R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
9244     R6_OPC_CMP_SLT_D  = FOP(12, FMT_L),
9245     R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
9246     R6_OPC_CMP_SLE_D  = FOP(14, FMT_L),
9247     R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
9248     R6_OPC_CMP_OR_D   = FOP(17, FMT_L),
9249     R6_OPC_CMP_UNE_D  = FOP(18, FMT_L),
9250     R6_OPC_CMP_NE_D   = FOP(19, FMT_L),
9251     R6_OPC_CMP_SOR_D  = FOP(25, FMT_L),
9252     R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
9253     R6_OPC_CMP_SNE_D  = FOP(27, FMT_L),
9254 };
9255 
gen_cp1(DisasContext * ctx,uint32_t opc,int rt,int fs)9256 static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs)
9257 {
9258     TCGv t0 = tcg_temp_new();
9259 
9260     switch (opc) {
9261     case OPC_MFC1:
9262         {
9263             TCGv_i32 fp0 = tcg_temp_new_i32();
9264 
9265             gen_load_fpr32(ctx, fp0, fs);
9266             tcg_gen_ext_i32_tl(t0, fp0);
9267         }
9268         gen_store_gpr(t0, rt);
9269         break;
9270     case OPC_MTC1:
9271         gen_load_gpr(t0, rt);
9272         {
9273             TCGv_i32 fp0 = tcg_temp_new_i32();
9274 
9275             tcg_gen_trunc_tl_i32(fp0, t0);
9276             gen_store_fpr32(ctx, fp0, fs);
9277         }
9278         break;
9279     case OPC_CFC1:
9280         gen_helper_1e0i(cfc1, t0, fs);
9281         gen_store_gpr(t0, rt);
9282         break;
9283     case OPC_CTC1:
9284         gen_load_gpr(t0, rt);
9285         save_cpu_state(ctx, 0);
9286         gen_helper_0e2i(ctc1, t0, tcg_constant_i32(fs), rt);
9287         /* Stop translation as we may have changed hflags */
9288         ctx->base.is_jmp = DISAS_STOP;
9289         break;
9290 #if defined(TARGET_MIPS64)
9291     case OPC_DMFC1:
9292         gen_load_fpr64(ctx, t0, fs);
9293         gen_store_gpr(t0, rt);
9294         break;
9295     case OPC_DMTC1:
9296         gen_load_gpr(t0, rt);
9297         gen_store_fpr64(ctx, t0, fs);
9298         break;
9299 #endif
9300     case OPC_MFHC1:
9301         {
9302             TCGv_i32 fp0 = tcg_temp_new_i32();
9303 
9304             gen_load_fpr32h(ctx, fp0, fs);
9305             tcg_gen_ext_i32_tl(t0, fp0);
9306         }
9307         gen_store_gpr(t0, rt);
9308         break;
9309     case OPC_MTHC1:
9310         gen_load_gpr(t0, rt);
9311         {
9312             TCGv_i32 fp0 = tcg_temp_new_i32();
9313 
9314             tcg_gen_trunc_tl_i32(fp0, t0);
9315             gen_store_fpr32h(ctx, fp0, fs);
9316         }
9317         break;
9318     default:
9319         MIPS_INVAL("cp1 move");
9320         gen_reserved_instruction(ctx);
9321         return;
9322     }
9323 }
9324 
gen_movci(DisasContext * ctx,int rd,int rs,int cc,int tf)9325 static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf)
9326 {
9327     TCGLabel *l1;
9328     TCGCond cond;
9329     TCGv_i32 t0;
9330 
9331     if (rd == 0) {
9332         /* Treat as NOP. */
9333         return;
9334     }
9335 
9336     if (tf) {
9337         cond = TCG_COND_EQ;
9338     } else {
9339         cond = TCG_COND_NE;
9340     }
9341 
9342     l1 = gen_new_label();
9343     t0 = tcg_temp_new_i32();
9344     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9345     tcg_gen_brcondi_i32(cond, t0, 0, l1);
9346     gen_load_gpr(cpu_gpr[rd], rs);
9347     gen_set_label(l1);
9348 }
9349 
gen_movcf_s(DisasContext * ctx,int fs,int fd,int cc,int tf)9350 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
9351                                int tf)
9352 {
9353     int cond;
9354     TCGv_i32 t0 = tcg_temp_new_i32();
9355     TCGLabel *l1 = gen_new_label();
9356 
9357     if (tf) {
9358         cond = TCG_COND_EQ;
9359     } else {
9360         cond = TCG_COND_NE;
9361     }
9362 
9363     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9364     tcg_gen_brcondi_i32(cond, t0, 0, l1);
9365     gen_load_fpr32(ctx, t0, fs);
9366     gen_store_fpr32(ctx, t0, fd);
9367     gen_set_label(l1);
9368 }
9369 
gen_movcf_d(DisasContext * ctx,int fs,int fd,int cc,int tf)9370 static inline void gen_movcf_d(DisasContext *ctx, int fs, int fd, int cc,
9371                                int tf)
9372 {
9373     int cond;
9374     TCGv_i32 t0 = tcg_temp_new_i32();
9375     TCGv_i64 fp0;
9376     TCGLabel *l1 = gen_new_label();
9377 
9378     if (tf) {
9379         cond = TCG_COND_EQ;
9380     } else {
9381         cond = TCG_COND_NE;
9382     }
9383 
9384     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9385     tcg_gen_brcondi_i32(cond, t0, 0, l1);
9386     fp0 = tcg_temp_new_i64();
9387     gen_load_fpr64(ctx, fp0, fs);
9388     gen_store_fpr64(ctx, fp0, fd);
9389     gen_set_label(l1);
9390 }
9391 
gen_movcf_ps(DisasContext * ctx,int fs,int fd,int cc,int tf)9392 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
9393                                 int cc, int tf)
9394 {
9395     int cond;
9396     TCGv_i32 t0 = tcg_temp_new_i32();
9397     TCGLabel *l1 = gen_new_label();
9398     TCGLabel *l2 = gen_new_label();
9399 
9400     if (tf) {
9401         cond = TCG_COND_EQ;
9402     } else {
9403         cond = TCG_COND_NE;
9404     }
9405 
9406     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9407     tcg_gen_brcondi_i32(cond, t0, 0, l1);
9408     gen_load_fpr32(ctx, t0, fs);
9409     gen_store_fpr32(ctx, t0, fd);
9410     gen_set_label(l1);
9411 
9412     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc + 1));
9413     tcg_gen_brcondi_i32(cond, t0, 0, l2);
9414     gen_load_fpr32h(ctx, t0, fs);
9415     gen_store_fpr32h(ctx, t0, fd);
9416     gen_set_label(l2);
9417 }
9418 
gen_sel_s(DisasContext * ctx,enum fopcode op1,int fd,int ft,int fs)9419 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9420                       int fs)
9421 {
9422     TCGv_i32 t1 = tcg_constant_i32(0);
9423     TCGv_i32 fp0 = tcg_temp_new_i32();
9424     TCGv_i32 fp1 = tcg_temp_new_i32();
9425     TCGv_i32 fp2 = tcg_temp_new_i32();
9426     gen_load_fpr32(ctx, fp0, fd);
9427     gen_load_fpr32(ctx, fp1, ft);
9428     gen_load_fpr32(ctx, fp2, fs);
9429 
9430     switch (op1) {
9431     case OPC_SEL_S:
9432         tcg_gen_andi_i32(fp0, fp0, 1);
9433         tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9434         break;
9435     case OPC_SELEQZ_S:
9436         tcg_gen_andi_i32(fp1, fp1, 1);
9437         tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9438         break;
9439     case OPC_SELNEZ_S:
9440         tcg_gen_andi_i32(fp1, fp1, 1);
9441         tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9442         break;
9443     default:
9444         MIPS_INVAL("gen_sel_s");
9445         gen_reserved_instruction(ctx);
9446         break;
9447     }
9448 
9449     gen_store_fpr32(ctx, fp0, fd);
9450 }
9451 
gen_sel_d(DisasContext * ctx,enum fopcode op1,int fd,int ft,int fs)9452 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9453                       int fs)
9454 {
9455     TCGv_i64 t1 = tcg_constant_i64(0);
9456     TCGv_i64 fp0 = tcg_temp_new_i64();
9457     TCGv_i64 fp1 = tcg_temp_new_i64();
9458     TCGv_i64 fp2 = tcg_temp_new_i64();
9459     gen_load_fpr64(ctx, fp0, fd);
9460     gen_load_fpr64(ctx, fp1, ft);
9461     gen_load_fpr64(ctx, fp2, fs);
9462 
9463     switch (op1) {
9464     case OPC_SEL_D:
9465         tcg_gen_andi_i64(fp0, fp0, 1);
9466         tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9467         break;
9468     case OPC_SELEQZ_D:
9469         tcg_gen_andi_i64(fp1, fp1, 1);
9470         tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9471         break;
9472     case OPC_SELNEZ_D:
9473         tcg_gen_andi_i64(fp1, fp1, 1);
9474         tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9475         break;
9476     default:
9477         MIPS_INVAL("gen_sel_d");
9478         gen_reserved_instruction(ctx);
9479         break;
9480     }
9481 
9482     gen_store_fpr64(ctx, fp0, fd);
9483 }
9484 
gen_farith(DisasContext * ctx,enum fopcode op1,int ft,int fs,int fd,int cc)9485 static void gen_farith(DisasContext *ctx, enum fopcode op1,
9486                        int ft, int fs, int fd, int cc)
9487 {
9488     uint32_t func = ctx->opcode & 0x3f;
9489     switch (op1) {
9490     case OPC_ADD_S:
9491         {
9492             TCGv_i32 fp0 = tcg_temp_new_i32();
9493             TCGv_i32 fp1 = tcg_temp_new_i32();
9494 
9495             gen_load_fpr32(ctx, fp0, fs);
9496             gen_load_fpr32(ctx, fp1, ft);
9497             gen_helper_float_add_s(fp0, tcg_env, fp0, fp1);
9498             gen_store_fpr32(ctx, fp0, fd);
9499         }
9500         break;
9501     case OPC_SUB_S:
9502         {
9503             TCGv_i32 fp0 = tcg_temp_new_i32();
9504             TCGv_i32 fp1 = tcg_temp_new_i32();
9505 
9506             gen_load_fpr32(ctx, fp0, fs);
9507             gen_load_fpr32(ctx, fp1, ft);
9508             gen_helper_float_sub_s(fp0, tcg_env, fp0, fp1);
9509             gen_store_fpr32(ctx, fp0, fd);
9510         }
9511         break;
9512     case OPC_MUL_S:
9513         {
9514             TCGv_i32 fp0 = tcg_temp_new_i32();
9515             TCGv_i32 fp1 = tcg_temp_new_i32();
9516 
9517             gen_load_fpr32(ctx, fp0, fs);
9518             gen_load_fpr32(ctx, fp1, ft);
9519             gen_helper_float_mul_s(fp0, tcg_env, fp0, fp1);
9520             gen_store_fpr32(ctx, fp0, fd);
9521         }
9522         break;
9523     case OPC_DIV_S:
9524         {
9525             TCGv_i32 fp0 = tcg_temp_new_i32();
9526             TCGv_i32 fp1 = tcg_temp_new_i32();
9527 
9528             gen_load_fpr32(ctx, fp0, fs);
9529             gen_load_fpr32(ctx, fp1, ft);
9530             gen_helper_float_div_s(fp0, tcg_env, fp0, fp1);
9531             gen_store_fpr32(ctx, fp0, fd);
9532         }
9533         break;
9534     case OPC_SQRT_S:
9535         {
9536             TCGv_i32 fp0 = tcg_temp_new_i32();
9537 
9538             gen_load_fpr32(ctx, fp0, fs);
9539             gen_helper_float_sqrt_s(fp0, tcg_env, fp0);
9540             gen_store_fpr32(ctx, fp0, fd);
9541         }
9542         break;
9543     case OPC_ABS_S:
9544         {
9545             TCGv_i32 fp0 = tcg_temp_new_i32();
9546 
9547             gen_load_fpr32(ctx, fp0, fs);
9548             if (ctx->abs2008) {
9549                 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
9550             } else {
9551                 gen_helper_float_abs_s(fp0, fp0);
9552             }
9553             gen_store_fpr32(ctx, fp0, fd);
9554         }
9555         break;
9556     case OPC_MOV_S:
9557         {
9558             TCGv_i32 fp0 = tcg_temp_new_i32();
9559 
9560             gen_load_fpr32(ctx, fp0, fs);
9561             gen_store_fpr32(ctx, fp0, fd);
9562         }
9563         break;
9564     case OPC_NEG_S:
9565         {
9566             TCGv_i32 fp0 = tcg_temp_new_i32();
9567 
9568             gen_load_fpr32(ctx, fp0, fs);
9569             if (ctx->abs2008) {
9570                 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
9571             } else {
9572                 gen_helper_float_chs_s(fp0, fp0);
9573             }
9574             gen_store_fpr32(ctx, fp0, fd);
9575         }
9576         break;
9577     case OPC_ROUND_L_S:
9578         check_cp1_64bitmode(ctx);
9579         {
9580             TCGv_i32 fp32 = tcg_temp_new_i32();
9581             TCGv_i64 fp64 = tcg_temp_new_i64();
9582 
9583             gen_load_fpr32(ctx, fp32, fs);
9584             if (ctx->nan2008) {
9585                 gen_helper_float_round_2008_l_s(fp64, tcg_env, fp32);
9586             } else {
9587                 gen_helper_float_round_l_s(fp64, tcg_env, fp32);
9588             }
9589             gen_store_fpr64(ctx, fp64, fd);
9590         }
9591         break;
9592     case OPC_TRUNC_L_S:
9593         check_cp1_64bitmode(ctx);
9594         {
9595             TCGv_i32 fp32 = tcg_temp_new_i32();
9596             TCGv_i64 fp64 = tcg_temp_new_i64();
9597 
9598             gen_load_fpr32(ctx, fp32, fs);
9599             if (ctx->nan2008) {
9600                 gen_helper_float_trunc_2008_l_s(fp64, tcg_env, fp32);
9601             } else {
9602                 gen_helper_float_trunc_l_s(fp64, tcg_env, fp32);
9603             }
9604             gen_store_fpr64(ctx, fp64, fd);
9605         }
9606         break;
9607     case OPC_CEIL_L_S:
9608         check_cp1_64bitmode(ctx);
9609         {
9610             TCGv_i32 fp32 = tcg_temp_new_i32();
9611             TCGv_i64 fp64 = tcg_temp_new_i64();
9612 
9613             gen_load_fpr32(ctx, fp32, fs);
9614             if (ctx->nan2008) {
9615                 gen_helper_float_ceil_2008_l_s(fp64, tcg_env, fp32);
9616             } else {
9617                 gen_helper_float_ceil_l_s(fp64, tcg_env, fp32);
9618             }
9619             gen_store_fpr64(ctx, fp64, fd);
9620         }
9621         break;
9622     case OPC_FLOOR_L_S:
9623         check_cp1_64bitmode(ctx);
9624         {
9625             TCGv_i32 fp32 = tcg_temp_new_i32();
9626             TCGv_i64 fp64 = tcg_temp_new_i64();
9627 
9628             gen_load_fpr32(ctx, fp32, fs);
9629             if (ctx->nan2008) {
9630                 gen_helper_float_floor_2008_l_s(fp64, tcg_env, fp32);
9631             } else {
9632                 gen_helper_float_floor_l_s(fp64, tcg_env, fp32);
9633             }
9634             gen_store_fpr64(ctx, fp64, fd);
9635         }
9636         break;
9637     case OPC_ROUND_W_S:
9638         {
9639             TCGv_i32 fp0 = tcg_temp_new_i32();
9640 
9641             gen_load_fpr32(ctx, fp0, fs);
9642             if (ctx->nan2008) {
9643                 gen_helper_float_round_2008_w_s(fp0, tcg_env, fp0);
9644             } else {
9645                 gen_helper_float_round_w_s(fp0, tcg_env, fp0);
9646             }
9647             gen_store_fpr32(ctx, fp0, fd);
9648         }
9649         break;
9650     case OPC_TRUNC_W_S:
9651         {
9652             TCGv_i32 fp0 = tcg_temp_new_i32();
9653 
9654             gen_load_fpr32(ctx, fp0, fs);
9655             if (ctx->nan2008) {
9656                 gen_helper_float_trunc_2008_w_s(fp0, tcg_env, fp0);
9657             } else {
9658                 gen_helper_float_trunc_w_s(fp0, tcg_env, fp0);
9659             }
9660             gen_store_fpr32(ctx, fp0, fd);
9661         }
9662         break;
9663     case OPC_CEIL_W_S:
9664         {
9665             TCGv_i32 fp0 = tcg_temp_new_i32();
9666 
9667             gen_load_fpr32(ctx, fp0, fs);
9668             if (ctx->nan2008) {
9669                 gen_helper_float_ceil_2008_w_s(fp0, tcg_env, fp0);
9670             } else {
9671                 gen_helper_float_ceil_w_s(fp0, tcg_env, fp0);
9672             }
9673             gen_store_fpr32(ctx, fp0, fd);
9674         }
9675         break;
9676     case OPC_FLOOR_W_S:
9677         {
9678             TCGv_i32 fp0 = tcg_temp_new_i32();
9679 
9680             gen_load_fpr32(ctx, fp0, fs);
9681             if (ctx->nan2008) {
9682                 gen_helper_float_floor_2008_w_s(fp0, tcg_env, fp0);
9683             } else {
9684                 gen_helper_float_floor_w_s(fp0, tcg_env, fp0);
9685             }
9686             gen_store_fpr32(ctx, fp0, fd);
9687         }
9688         break;
9689     case OPC_SEL_S:
9690         check_insn(ctx, ISA_MIPS_R6);
9691         gen_sel_s(ctx, op1, fd, ft, fs);
9692         break;
9693     case OPC_SELEQZ_S:
9694         check_insn(ctx, ISA_MIPS_R6);
9695         gen_sel_s(ctx, op1, fd, ft, fs);
9696         break;
9697     case OPC_SELNEZ_S:
9698         check_insn(ctx, ISA_MIPS_R6);
9699         gen_sel_s(ctx, op1, fd, ft, fs);
9700         break;
9701     case OPC_MOVCF_S:
9702         check_insn_opc_removed(ctx, ISA_MIPS_R6);
9703         gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9704         break;
9705     case OPC_MOVZ_S:
9706         check_insn_opc_removed(ctx, ISA_MIPS_R6);
9707         {
9708             TCGLabel *l1 = gen_new_label();
9709             TCGv_i32 fp0;
9710 
9711             if (ft != 0) {
9712                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9713             }
9714             fp0 = tcg_temp_new_i32();
9715             gen_load_fpr32(ctx, fp0, fs);
9716             gen_store_fpr32(ctx, fp0, fd);
9717             gen_set_label(l1);
9718         }
9719         break;
9720     case OPC_MOVN_S:
9721         check_insn_opc_removed(ctx, ISA_MIPS_R6);
9722         {
9723             TCGLabel *l1 = gen_new_label();
9724             TCGv_i32 fp0;
9725 
9726             if (ft != 0) {
9727                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9728                 fp0 = tcg_temp_new_i32();
9729                 gen_load_fpr32(ctx, fp0, fs);
9730                 gen_store_fpr32(ctx, fp0, fd);
9731                 gen_set_label(l1);
9732             }
9733         }
9734         break;
9735     case OPC_RECIP_S:
9736         {
9737             TCGv_i32 fp0 = tcg_temp_new_i32();
9738 
9739             gen_load_fpr32(ctx, fp0, fs);
9740             gen_helper_float_recip_s(fp0, tcg_env, fp0);
9741             gen_store_fpr32(ctx, fp0, fd);
9742         }
9743         break;
9744     case OPC_RSQRT_S:
9745         {
9746             TCGv_i32 fp0 = tcg_temp_new_i32();
9747 
9748             gen_load_fpr32(ctx, fp0, fs);
9749             gen_helper_float_rsqrt_s(fp0, tcg_env, fp0);
9750             gen_store_fpr32(ctx, fp0, fd);
9751         }
9752         break;
9753     case OPC_MADDF_S:
9754         check_insn(ctx, ISA_MIPS_R6);
9755         {
9756             TCGv_i32 fp0 = tcg_temp_new_i32();
9757             TCGv_i32 fp1 = tcg_temp_new_i32();
9758             TCGv_i32 fp2 = tcg_temp_new_i32();
9759             gen_load_fpr32(ctx, fp0, fs);
9760             gen_load_fpr32(ctx, fp1, ft);
9761             gen_load_fpr32(ctx, fp2, fd);
9762             gen_helper_float_maddf_s(fp2, tcg_env, fp0, fp1, fp2);
9763             gen_store_fpr32(ctx, fp2, fd);
9764         }
9765         break;
9766     case OPC_MSUBF_S:
9767         check_insn(ctx, ISA_MIPS_R6);
9768         {
9769             TCGv_i32 fp0 = tcg_temp_new_i32();
9770             TCGv_i32 fp1 = tcg_temp_new_i32();
9771             TCGv_i32 fp2 = tcg_temp_new_i32();
9772             gen_load_fpr32(ctx, fp0, fs);
9773             gen_load_fpr32(ctx, fp1, ft);
9774             gen_load_fpr32(ctx, fp2, fd);
9775             gen_helper_float_msubf_s(fp2, tcg_env, fp0, fp1, fp2);
9776             gen_store_fpr32(ctx, fp2, fd);
9777         }
9778         break;
9779     case OPC_RINT_S:
9780         check_insn(ctx, ISA_MIPS_R6);
9781         {
9782             TCGv_i32 fp0 = tcg_temp_new_i32();
9783             gen_load_fpr32(ctx, fp0, fs);
9784             gen_helper_float_rint_s(fp0, tcg_env, fp0);
9785             gen_store_fpr32(ctx, fp0, fd);
9786         }
9787         break;
9788     case OPC_CLASS_S:
9789         check_insn(ctx, ISA_MIPS_R6);
9790         {
9791             TCGv_i32 fp0 = tcg_temp_new_i32();
9792             gen_load_fpr32(ctx, fp0, fs);
9793             gen_helper_float_class_s(fp0, tcg_env, fp0);
9794             gen_store_fpr32(ctx, fp0, fd);
9795         }
9796         break;
9797     case OPC_MIN_S: /* OPC_RECIP2_S */
9798         if (ctx->insn_flags & ISA_MIPS_R6) {
9799             /* OPC_MIN_S */
9800             TCGv_i32 fp0 = tcg_temp_new_i32();
9801             TCGv_i32 fp1 = tcg_temp_new_i32();
9802             TCGv_i32 fp2 = tcg_temp_new_i32();
9803             gen_load_fpr32(ctx, fp0, fs);
9804             gen_load_fpr32(ctx, fp1, ft);
9805             gen_helper_float_min_s(fp2, tcg_env, fp0, fp1);
9806             gen_store_fpr32(ctx, fp2, fd);
9807         } else {
9808             /* OPC_RECIP2_S */
9809             check_cp1_64bitmode(ctx);
9810             {
9811                 TCGv_i32 fp0 = tcg_temp_new_i32();
9812                 TCGv_i32 fp1 = tcg_temp_new_i32();
9813 
9814                 gen_load_fpr32(ctx, fp0, fs);
9815                 gen_load_fpr32(ctx, fp1, ft);
9816                 gen_helper_float_recip2_s(fp0, tcg_env, fp0, fp1);
9817                 gen_store_fpr32(ctx, fp0, fd);
9818             }
9819         }
9820         break;
9821     case OPC_MINA_S: /* OPC_RECIP1_S */
9822         if (ctx->insn_flags & ISA_MIPS_R6) {
9823             /* OPC_MINA_S */
9824             TCGv_i32 fp0 = tcg_temp_new_i32();
9825             TCGv_i32 fp1 = tcg_temp_new_i32();
9826             TCGv_i32 fp2 = tcg_temp_new_i32();
9827             gen_load_fpr32(ctx, fp0, fs);
9828             gen_load_fpr32(ctx, fp1, ft);
9829             gen_helper_float_mina_s(fp2, tcg_env, fp0, fp1);
9830             gen_store_fpr32(ctx, fp2, fd);
9831         } else {
9832             /* OPC_RECIP1_S */
9833             check_cp1_64bitmode(ctx);
9834             {
9835                 TCGv_i32 fp0 = tcg_temp_new_i32();
9836 
9837                 gen_load_fpr32(ctx, fp0, fs);
9838                 gen_helper_float_recip1_s(fp0, tcg_env, fp0);
9839                 gen_store_fpr32(ctx, fp0, fd);
9840             }
9841         }
9842         break;
9843     case OPC_MAX_S: /* OPC_RSQRT1_S */
9844         if (ctx->insn_flags & ISA_MIPS_R6) {
9845             /* OPC_MAX_S */
9846             TCGv_i32 fp0 = tcg_temp_new_i32();
9847             TCGv_i32 fp1 = tcg_temp_new_i32();
9848             gen_load_fpr32(ctx, fp0, fs);
9849             gen_load_fpr32(ctx, fp1, ft);
9850             gen_helper_float_max_s(fp1, tcg_env, fp0, fp1);
9851             gen_store_fpr32(ctx, fp1, fd);
9852         } else {
9853             /* OPC_RSQRT1_S */
9854             check_cp1_64bitmode(ctx);
9855             {
9856                 TCGv_i32 fp0 = tcg_temp_new_i32();
9857 
9858                 gen_load_fpr32(ctx, fp0, fs);
9859                 gen_helper_float_rsqrt1_s(fp0, tcg_env, fp0);
9860                 gen_store_fpr32(ctx, fp0, fd);
9861             }
9862         }
9863         break;
9864     case OPC_MAXA_S: /* OPC_RSQRT2_S */
9865         if (ctx->insn_flags & ISA_MIPS_R6) {
9866             /* OPC_MAXA_S */
9867             TCGv_i32 fp0 = tcg_temp_new_i32();
9868             TCGv_i32 fp1 = tcg_temp_new_i32();
9869             gen_load_fpr32(ctx, fp0, fs);
9870             gen_load_fpr32(ctx, fp1, ft);
9871             gen_helper_float_maxa_s(fp1, tcg_env, fp0, fp1);
9872             gen_store_fpr32(ctx, fp1, fd);
9873         } else {
9874             /* OPC_RSQRT2_S */
9875             check_cp1_64bitmode(ctx);
9876             {
9877                 TCGv_i32 fp0 = tcg_temp_new_i32();
9878                 TCGv_i32 fp1 = tcg_temp_new_i32();
9879 
9880                 gen_load_fpr32(ctx, fp0, fs);
9881                 gen_load_fpr32(ctx, fp1, ft);
9882                 gen_helper_float_rsqrt2_s(fp0, tcg_env, fp0, fp1);
9883                 gen_store_fpr32(ctx, fp0, fd);
9884             }
9885         }
9886         break;
9887     case OPC_CVT_D_S:
9888         check_cp1_registers(ctx, fd);
9889         {
9890             TCGv_i32 fp32 = tcg_temp_new_i32();
9891             TCGv_i64 fp64 = tcg_temp_new_i64();
9892 
9893             gen_load_fpr32(ctx, fp32, fs);
9894             gen_helper_float_cvtd_s(fp64, tcg_env, fp32);
9895             gen_store_fpr64(ctx, fp64, fd);
9896         }
9897         break;
9898     case OPC_CVT_W_S:
9899         {
9900             TCGv_i32 fp0 = tcg_temp_new_i32();
9901 
9902             gen_load_fpr32(ctx, fp0, fs);
9903             if (ctx->nan2008) {
9904                 gen_helper_float_cvt_2008_w_s(fp0, tcg_env, fp0);
9905             } else {
9906                 gen_helper_float_cvt_w_s(fp0, tcg_env, fp0);
9907             }
9908             gen_store_fpr32(ctx, fp0, fd);
9909         }
9910         break;
9911     case OPC_CVT_L_S:
9912         check_cp1_64bitmode(ctx);
9913         {
9914             TCGv_i32 fp32 = tcg_temp_new_i32();
9915             TCGv_i64 fp64 = tcg_temp_new_i64();
9916 
9917             gen_load_fpr32(ctx, fp32, fs);
9918             if (ctx->nan2008) {
9919                 gen_helper_float_cvt_2008_l_s(fp64, tcg_env, fp32);
9920             } else {
9921                 gen_helper_float_cvt_l_s(fp64, tcg_env, fp32);
9922             }
9923             gen_store_fpr64(ctx, fp64, fd);
9924         }
9925         break;
9926     case OPC_CVT_PS_S:
9927         check_ps(ctx);
9928         {
9929             TCGv_i64 fp64 = tcg_temp_new_i64();
9930             TCGv_i32 fp32_0 = tcg_temp_new_i32();
9931             TCGv_i32 fp32_1 = tcg_temp_new_i32();
9932 
9933             gen_load_fpr32(ctx, fp32_0, fs);
9934             gen_load_fpr32(ctx, fp32_1, ft);
9935             tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
9936             gen_store_fpr64(ctx, fp64, fd);
9937         }
9938         break;
9939     case OPC_CMP_F_S:
9940     case OPC_CMP_UN_S:
9941     case OPC_CMP_EQ_S:
9942     case OPC_CMP_UEQ_S:
9943     case OPC_CMP_OLT_S:
9944     case OPC_CMP_ULT_S:
9945     case OPC_CMP_OLE_S:
9946     case OPC_CMP_ULE_S:
9947     case OPC_CMP_SF_S:
9948     case OPC_CMP_NGLE_S:
9949     case OPC_CMP_SEQ_S:
9950     case OPC_CMP_NGL_S:
9951     case OPC_CMP_LT_S:
9952     case OPC_CMP_NGE_S:
9953     case OPC_CMP_LE_S:
9954     case OPC_CMP_NGT_S:
9955         check_insn_opc_removed(ctx, ISA_MIPS_R6);
9956         if (ctx->opcode & (1 << 6)) {
9957             gen_cmpabs_s(ctx, func - 48, ft, fs, cc);
9958         } else {
9959             gen_cmp_s(ctx, func - 48, ft, fs, cc);
9960         }
9961         break;
9962     case OPC_ADD_D:
9963         check_cp1_registers(ctx, fs | ft | fd);
9964         {
9965             TCGv_i64 fp0 = tcg_temp_new_i64();
9966             TCGv_i64 fp1 = tcg_temp_new_i64();
9967 
9968             gen_load_fpr64(ctx, fp0, fs);
9969             gen_load_fpr64(ctx, fp1, ft);
9970             gen_helper_float_add_d(fp0, tcg_env, fp0, fp1);
9971             gen_store_fpr64(ctx, fp0, fd);
9972         }
9973         break;
9974     case OPC_SUB_D:
9975         check_cp1_registers(ctx, fs | ft | fd);
9976         {
9977             TCGv_i64 fp0 = tcg_temp_new_i64();
9978             TCGv_i64 fp1 = tcg_temp_new_i64();
9979 
9980             gen_load_fpr64(ctx, fp0, fs);
9981             gen_load_fpr64(ctx, fp1, ft);
9982             gen_helper_float_sub_d(fp0, tcg_env, fp0, fp1);
9983             gen_store_fpr64(ctx, fp0, fd);
9984         }
9985         break;
9986     case OPC_MUL_D:
9987         check_cp1_registers(ctx, fs | ft | fd);
9988         {
9989             TCGv_i64 fp0 = tcg_temp_new_i64();
9990             TCGv_i64 fp1 = tcg_temp_new_i64();
9991 
9992             gen_load_fpr64(ctx, fp0, fs);
9993             gen_load_fpr64(ctx, fp1, ft);
9994             gen_helper_float_mul_d(fp0, tcg_env, fp0, fp1);
9995             gen_store_fpr64(ctx, fp0, fd);
9996         }
9997         break;
9998     case OPC_DIV_D:
9999         check_cp1_registers(ctx, fs | ft | fd);
10000         {
10001             TCGv_i64 fp0 = tcg_temp_new_i64();
10002             TCGv_i64 fp1 = tcg_temp_new_i64();
10003 
10004             gen_load_fpr64(ctx, fp0, fs);
10005             gen_load_fpr64(ctx, fp1, ft);
10006             gen_helper_float_div_d(fp0, tcg_env, fp0, fp1);
10007             gen_store_fpr64(ctx, fp0, fd);
10008         }
10009         break;
10010     case OPC_SQRT_D:
10011         check_cp1_registers(ctx, fs | fd);
10012         {
10013             TCGv_i64 fp0 = tcg_temp_new_i64();
10014 
10015             gen_load_fpr64(ctx, fp0, fs);
10016             gen_helper_float_sqrt_d(fp0, tcg_env, fp0);
10017             gen_store_fpr64(ctx, fp0, fd);
10018         }
10019         break;
10020     case OPC_ABS_D:
10021         check_cp1_registers(ctx, fs | fd);
10022         {
10023             TCGv_i64 fp0 = tcg_temp_new_i64();
10024 
10025             gen_load_fpr64(ctx, fp0, fs);
10026             if (ctx->abs2008) {
10027                 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
10028             } else {
10029                 gen_helper_float_abs_d(fp0, fp0);
10030             }
10031             gen_store_fpr64(ctx, fp0, fd);
10032         }
10033         break;
10034     case OPC_MOV_D:
10035         check_cp1_registers(ctx, fs | fd);
10036         {
10037             TCGv_i64 fp0 = tcg_temp_new_i64();
10038 
10039             gen_load_fpr64(ctx, fp0, fs);
10040             gen_store_fpr64(ctx, fp0, fd);
10041         }
10042         break;
10043     case OPC_NEG_D:
10044         check_cp1_registers(ctx, fs | fd);
10045         {
10046             TCGv_i64 fp0 = tcg_temp_new_i64();
10047 
10048             gen_load_fpr64(ctx, fp0, fs);
10049             if (ctx->abs2008) {
10050                 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
10051             } else {
10052                 gen_helper_float_chs_d(fp0, fp0);
10053             }
10054             gen_store_fpr64(ctx, fp0, fd);
10055         }
10056         break;
10057     case OPC_ROUND_L_D:
10058         check_cp1_64bitmode(ctx);
10059         {
10060             TCGv_i64 fp0 = tcg_temp_new_i64();
10061 
10062             gen_load_fpr64(ctx, fp0, fs);
10063             if (ctx->nan2008) {
10064                 gen_helper_float_round_2008_l_d(fp0, tcg_env, fp0);
10065             } else {
10066                 gen_helper_float_round_l_d(fp0, tcg_env, fp0);
10067             }
10068             gen_store_fpr64(ctx, fp0, fd);
10069         }
10070         break;
10071     case OPC_TRUNC_L_D:
10072         check_cp1_64bitmode(ctx);
10073         {
10074             TCGv_i64 fp0 = tcg_temp_new_i64();
10075 
10076             gen_load_fpr64(ctx, fp0, fs);
10077             if (ctx->nan2008) {
10078                 gen_helper_float_trunc_2008_l_d(fp0, tcg_env, fp0);
10079             } else {
10080                 gen_helper_float_trunc_l_d(fp0, tcg_env, fp0);
10081             }
10082             gen_store_fpr64(ctx, fp0, fd);
10083         }
10084         break;
10085     case OPC_CEIL_L_D:
10086         check_cp1_64bitmode(ctx);
10087         {
10088             TCGv_i64 fp0 = tcg_temp_new_i64();
10089 
10090             gen_load_fpr64(ctx, fp0, fs);
10091             if (ctx->nan2008) {
10092                 gen_helper_float_ceil_2008_l_d(fp0, tcg_env, fp0);
10093             } else {
10094                 gen_helper_float_ceil_l_d(fp0, tcg_env, fp0);
10095             }
10096             gen_store_fpr64(ctx, fp0, fd);
10097         }
10098         break;
10099     case OPC_FLOOR_L_D:
10100         check_cp1_64bitmode(ctx);
10101         {
10102             TCGv_i64 fp0 = tcg_temp_new_i64();
10103 
10104             gen_load_fpr64(ctx, fp0, fs);
10105             if (ctx->nan2008) {
10106                 gen_helper_float_floor_2008_l_d(fp0, tcg_env, fp0);
10107             } else {
10108                 gen_helper_float_floor_l_d(fp0, tcg_env, fp0);
10109             }
10110             gen_store_fpr64(ctx, fp0, fd);
10111         }
10112         break;
10113     case OPC_ROUND_W_D:
10114         check_cp1_registers(ctx, fs);
10115         {
10116             TCGv_i32 fp32 = tcg_temp_new_i32();
10117             TCGv_i64 fp64 = tcg_temp_new_i64();
10118 
10119             gen_load_fpr64(ctx, fp64, fs);
10120             if (ctx->nan2008) {
10121                 gen_helper_float_round_2008_w_d(fp32, tcg_env, fp64);
10122             } else {
10123                 gen_helper_float_round_w_d(fp32, tcg_env, fp64);
10124             }
10125             gen_store_fpr32(ctx, fp32, fd);
10126         }
10127         break;
10128     case OPC_TRUNC_W_D:
10129         check_cp1_registers(ctx, fs);
10130         {
10131             TCGv_i32 fp32 = tcg_temp_new_i32();
10132             TCGv_i64 fp64 = tcg_temp_new_i64();
10133 
10134             gen_load_fpr64(ctx, fp64, fs);
10135             if (ctx->nan2008) {
10136                 gen_helper_float_trunc_2008_w_d(fp32, tcg_env, fp64);
10137             } else {
10138                 gen_helper_float_trunc_w_d(fp32, tcg_env, fp64);
10139             }
10140             gen_store_fpr32(ctx, fp32, fd);
10141         }
10142         break;
10143     case OPC_CEIL_W_D:
10144         check_cp1_registers(ctx, fs);
10145         {
10146             TCGv_i32 fp32 = tcg_temp_new_i32();
10147             TCGv_i64 fp64 = tcg_temp_new_i64();
10148 
10149             gen_load_fpr64(ctx, fp64, fs);
10150             if (ctx->nan2008) {
10151                 gen_helper_float_ceil_2008_w_d(fp32, tcg_env, fp64);
10152             } else {
10153                 gen_helper_float_ceil_w_d(fp32, tcg_env, fp64);
10154             }
10155             gen_store_fpr32(ctx, fp32, fd);
10156         }
10157         break;
10158     case OPC_FLOOR_W_D:
10159         check_cp1_registers(ctx, fs);
10160         {
10161             TCGv_i32 fp32 = tcg_temp_new_i32();
10162             TCGv_i64 fp64 = tcg_temp_new_i64();
10163 
10164             gen_load_fpr64(ctx, fp64, fs);
10165             if (ctx->nan2008) {
10166                 gen_helper_float_floor_2008_w_d(fp32, tcg_env, fp64);
10167             } else {
10168                 gen_helper_float_floor_w_d(fp32, tcg_env, fp64);
10169             }
10170             gen_store_fpr32(ctx, fp32, fd);
10171         }
10172         break;
10173     case OPC_SEL_D:
10174         check_insn(ctx, ISA_MIPS_R6);
10175         gen_sel_d(ctx, op1, fd, ft, fs);
10176         break;
10177     case OPC_SELEQZ_D:
10178         check_insn(ctx, ISA_MIPS_R6);
10179         gen_sel_d(ctx, op1, fd, ft, fs);
10180         break;
10181     case OPC_SELNEZ_D:
10182         check_insn(ctx, ISA_MIPS_R6);
10183         gen_sel_d(ctx, op1, fd, ft, fs);
10184         break;
10185     case OPC_MOVCF_D:
10186         check_insn_opc_removed(ctx, ISA_MIPS_R6);
10187         gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10188         break;
10189     case OPC_MOVZ_D:
10190         check_insn_opc_removed(ctx, ISA_MIPS_R6);
10191         {
10192             TCGLabel *l1 = gen_new_label();
10193             TCGv_i64 fp0;
10194 
10195             if (ft != 0) {
10196                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10197             }
10198             fp0 = tcg_temp_new_i64();
10199             gen_load_fpr64(ctx, fp0, fs);
10200             gen_store_fpr64(ctx, fp0, fd);
10201             gen_set_label(l1);
10202         }
10203         break;
10204     case OPC_MOVN_D:
10205         check_insn_opc_removed(ctx, ISA_MIPS_R6);
10206         {
10207             TCGLabel *l1 = gen_new_label();
10208             TCGv_i64 fp0;
10209 
10210             if (ft != 0) {
10211                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10212                 fp0 = tcg_temp_new_i64();
10213                 gen_load_fpr64(ctx, fp0, fs);
10214                 gen_store_fpr64(ctx, fp0, fd);
10215                 gen_set_label(l1);
10216             }
10217         }
10218         break;
10219     case OPC_RECIP_D:
10220         check_cp1_registers(ctx, fs | fd);
10221         {
10222             TCGv_i64 fp0 = tcg_temp_new_i64();
10223 
10224             gen_load_fpr64(ctx, fp0, fs);
10225             gen_helper_float_recip_d(fp0, tcg_env, fp0);
10226             gen_store_fpr64(ctx, fp0, fd);
10227         }
10228         break;
10229     case OPC_RSQRT_D:
10230         check_cp1_registers(ctx, fs | fd);
10231         {
10232             TCGv_i64 fp0 = tcg_temp_new_i64();
10233 
10234             gen_load_fpr64(ctx, fp0, fs);
10235             gen_helper_float_rsqrt_d(fp0, tcg_env, fp0);
10236             gen_store_fpr64(ctx, fp0, fd);
10237         }
10238         break;
10239     case OPC_MADDF_D:
10240         check_insn(ctx, ISA_MIPS_R6);
10241         {
10242             TCGv_i64 fp0 = tcg_temp_new_i64();
10243             TCGv_i64 fp1 = tcg_temp_new_i64();
10244             TCGv_i64 fp2 = tcg_temp_new_i64();
10245             gen_load_fpr64(ctx, fp0, fs);
10246             gen_load_fpr64(ctx, fp1, ft);
10247             gen_load_fpr64(ctx, fp2, fd);
10248             gen_helper_float_maddf_d(fp2, tcg_env, fp0, fp1, fp2);
10249             gen_store_fpr64(ctx, fp2, fd);
10250         }
10251         break;
10252     case OPC_MSUBF_D:
10253         check_insn(ctx, ISA_MIPS_R6);
10254         {
10255             TCGv_i64 fp0 = tcg_temp_new_i64();
10256             TCGv_i64 fp1 = tcg_temp_new_i64();
10257             TCGv_i64 fp2 = tcg_temp_new_i64();
10258             gen_load_fpr64(ctx, fp0, fs);
10259             gen_load_fpr64(ctx, fp1, ft);
10260             gen_load_fpr64(ctx, fp2, fd);
10261             gen_helper_float_msubf_d(fp2, tcg_env, fp0, fp1, fp2);
10262             gen_store_fpr64(ctx, fp2, fd);
10263         }
10264         break;
10265     case OPC_RINT_D:
10266         check_insn(ctx, ISA_MIPS_R6);
10267         {
10268             TCGv_i64 fp0 = tcg_temp_new_i64();
10269             gen_load_fpr64(ctx, fp0, fs);
10270             gen_helper_float_rint_d(fp0, tcg_env, fp0);
10271             gen_store_fpr64(ctx, fp0, fd);
10272         }
10273         break;
10274     case OPC_CLASS_D:
10275         check_insn(ctx, ISA_MIPS_R6);
10276         {
10277             TCGv_i64 fp0 = tcg_temp_new_i64();
10278             gen_load_fpr64(ctx, fp0, fs);
10279             gen_helper_float_class_d(fp0, tcg_env, fp0);
10280             gen_store_fpr64(ctx, fp0, fd);
10281         }
10282         break;
10283     case OPC_MIN_D: /* OPC_RECIP2_D */
10284         if (ctx->insn_flags & ISA_MIPS_R6) {
10285             /* OPC_MIN_D */
10286             TCGv_i64 fp0 = tcg_temp_new_i64();
10287             TCGv_i64 fp1 = tcg_temp_new_i64();
10288             gen_load_fpr64(ctx, fp0, fs);
10289             gen_load_fpr64(ctx, fp1, ft);
10290             gen_helper_float_min_d(fp1, tcg_env, fp0, fp1);
10291             gen_store_fpr64(ctx, fp1, fd);
10292         } else {
10293             /* OPC_RECIP2_D */
10294             check_cp1_64bitmode(ctx);
10295             {
10296                 TCGv_i64 fp0 = tcg_temp_new_i64();
10297                 TCGv_i64 fp1 = tcg_temp_new_i64();
10298 
10299                 gen_load_fpr64(ctx, fp0, fs);
10300                 gen_load_fpr64(ctx, fp1, ft);
10301                 gen_helper_float_recip2_d(fp0, tcg_env, fp0, fp1);
10302                 gen_store_fpr64(ctx, fp0, fd);
10303             }
10304         }
10305         break;
10306     case OPC_MINA_D: /* OPC_RECIP1_D */
10307         if (ctx->insn_flags & ISA_MIPS_R6) {
10308             /* OPC_MINA_D */
10309             TCGv_i64 fp0 = tcg_temp_new_i64();
10310             TCGv_i64 fp1 = tcg_temp_new_i64();
10311             gen_load_fpr64(ctx, fp0, fs);
10312             gen_load_fpr64(ctx, fp1, ft);
10313             gen_helper_float_mina_d(fp1, tcg_env, fp0, fp1);
10314             gen_store_fpr64(ctx, fp1, fd);
10315         } else {
10316             /* OPC_RECIP1_D */
10317             check_cp1_64bitmode(ctx);
10318             {
10319                 TCGv_i64 fp0 = tcg_temp_new_i64();
10320 
10321                 gen_load_fpr64(ctx, fp0, fs);
10322                 gen_helper_float_recip1_d(fp0, tcg_env, fp0);
10323                 gen_store_fpr64(ctx, fp0, fd);
10324             }
10325         }
10326         break;
10327     case OPC_MAX_D: /*  OPC_RSQRT1_D */
10328         if (ctx->insn_flags & ISA_MIPS_R6) {
10329             /* OPC_MAX_D */
10330             TCGv_i64 fp0 = tcg_temp_new_i64();
10331             TCGv_i64 fp1 = tcg_temp_new_i64();
10332             gen_load_fpr64(ctx, fp0, fs);
10333             gen_load_fpr64(ctx, fp1, ft);
10334             gen_helper_float_max_d(fp1, tcg_env, fp0, fp1);
10335             gen_store_fpr64(ctx, fp1, fd);
10336         } else {
10337             /* OPC_RSQRT1_D */
10338             check_cp1_64bitmode(ctx);
10339             {
10340                 TCGv_i64 fp0 = tcg_temp_new_i64();
10341 
10342                 gen_load_fpr64(ctx, fp0, fs);
10343                 gen_helper_float_rsqrt1_d(fp0, tcg_env, fp0);
10344                 gen_store_fpr64(ctx, fp0, fd);
10345             }
10346         }
10347         break;
10348     case OPC_MAXA_D: /* OPC_RSQRT2_D */
10349         if (ctx->insn_flags & ISA_MIPS_R6) {
10350             /* OPC_MAXA_D */
10351             TCGv_i64 fp0 = tcg_temp_new_i64();
10352             TCGv_i64 fp1 = tcg_temp_new_i64();
10353             gen_load_fpr64(ctx, fp0, fs);
10354             gen_load_fpr64(ctx, fp1, ft);
10355             gen_helper_float_maxa_d(fp1, tcg_env, fp0, fp1);
10356             gen_store_fpr64(ctx, fp1, fd);
10357         } else {
10358             /* OPC_RSQRT2_D */
10359             check_cp1_64bitmode(ctx);
10360             {
10361                 TCGv_i64 fp0 = tcg_temp_new_i64();
10362                 TCGv_i64 fp1 = tcg_temp_new_i64();
10363 
10364                 gen_load_fpr64(ctx, fp0, fs);
10365                 gen_load_fpr64(ctx, fp1, ft);
10366                 gen_helper_float_rsqrt2_d(fp0, tcg_env, fp0, fp1);
10367                 gen_store_fpr64(ctx, fp0, fd);
10368             }
10369         }
10370         break;
10371     case OPC_CMP_F_D:
10372     case OPC_CMP_UN_D:
10373     case OPC_CMP_EQ_D:
10374     case OPC_CMP_UEQ_D:
10375     case OPC_CMP_OLT_D:
10376     case OPC_CMP_ULT_D:
10377     case OPC_CMP_OLE_D:
10378     case OPC_CMP_ULE_D:
10379     case OPC_CMP_SF_D:
10380     case OPC_CMP_NGLE_D:
10381     case OPC_CMP_SEQ_D:
10382     case OPC_CMP_NGL_D:
10383     case OPC_CMP_LT_D:
10384     case OPC_CMP_NGE_D:
10385     case OPC_CMP_LE_D:
10386     case OPC_CMP_NGT_D:
10387         check_insn_opc_removed(ctx, ISA_MIPS_R6);
10388         if (ctx->opcode & (1 << 6)) {
10389             gen_cmpabs_d(ctx, func - 48, ft, fs, cc);
10390         } else {
10391             gen_cmp_d(ctx, func - 48, ft, fs, cc);
10392         }
10393         break;
10394     case OPC_CVT_S_D:
10395         check_cp1_registers(ctx, fs);
10396         {
10397             TCGv_i32 fp32 = tcg_temp_new_i32();
10398             TCGv_i64 fp64 = tcg_temp_new_i64();
10399 
10400             gen_load_fpr64(ctx, fp64, fs);
10401             gen_helper_float_cvts_d(fp32, tcg_env, fp64);
10402             gen_store_fpr32(ctx, fp32, fd);
10403         }
10404         break;
10405     case OPC_CVT_W_D:
10406         check_cp1_registers(ctx, fs);
10407         {
10408             TCGv_i32 fp32 = tcg_temp_new_i32();
10409             TCGv_i64 fp64 = tcg_temp_new_i64();
10410 
10411             gen_load_fpr64(ctx, fp64, fs);
10412             if (ctx->nan2008) {
10413                 gen_helper_float_cvt_2008_w_d(fp32, tcg_env, fp64);
10414             } else {
10415                 gen_helper_float_cvt_w_d(fp32, tcg_env, fp64);
10416             }
10417             gen_store_fpr32(ctx, fp32, fd);
10418         }
10419         break;
10420     case OPC_CVT_L_D:
10421         check_cp1_64bitmode(ctx);
10422         {
10423             TCGv_i64 fp0 = tcg_temp_new_i64();
10424 
10425             gen_load_fpr64(ctx, fp0, fs);
10426             if (ctx->nan2008) {
10427                 gen_helper_float_cvt_2008_l_d(fp0, tcg_env, fp0);
10428             } else {
10429                 gen_helper_float_cvt_l_d(fp0, tcg_env, fp0);
10430             }
10431             gen_store_fpr64(ctx, fp0, fd);
10432         }
10433         break;
10434     case OPC_CVT_S_W:
10435         {
10436             TCGv_i32 fp0 = tcg_temp_new_i32();
10437 
10438             gen_load_fpr32(ctx, fp0, fs);
10439             gen_helper_float_cvts_w(fp0, tcg_env, fp0);
10440             gen_store_fpr32(ctx, fp0, fd);
10441         }
10442         break;
10443     case OPC_CVT_D_W:
10444         check_cp1_registers(ctx, fd);
10445         {
10446             TCGv_i32 fp32 = tcg_temp_new_i32();
10447             TCGv_i64 fp64 = tcg_temp_new_i64();
10448 
10449             gen_load_fpr32(ctx, fp32, fs);
10450             gen_helper_float_cvtd_w(fp64, tcg_env, fp32);
10451             gen_store_fpr64(ctx, fp64, fd);
10452         }
10453         break;
10454     case OPC_CVT_S_L:
10455         check_cp1_64bitmode(ctx);
10456         {
10457             TCGv_i32 fp32 = tcg_temp_new_i32();
10458             TCGv_i64 fp64 = tcg_temp_new_i64();
10459 
10460             gen_load_fpr64(ctx, fp64, fs);
10461             gen_helper_float_cvts_l(fp32, tcg_env, fp64);
10462             gen_store_fpr32(ctx, fp32, fd);
10463         }
10464         break;
10465     case OPC_CVT_D_L:
10466         check_cp1_64bitmode(ctx);
10467         {
10468             TCGv_i64 fp0 = tcg_temp_new_i64();
10469 
10470             gen_load_fpr64(ctx, fp0, fs);
10471             gen_helper_float_cvtd_l(fp0, tcg_env, fp0);
10472             gen_store_fpr64(ctx, fp0, fd);
10473         }
10474         break;
10475     case OPC_CVT_PS_PW:
10476         check_ps(ctx);
10477         {
10478             TCGv_i64 fp0 = tcg_temp_new_i64();
10479 
10480             gen_load_fpr64(ctx, fp0, fs);
10481             gen_helper_float_cvtps_pw(fp0, tcg_env, fp0);
10482             gen_store_fpr64(ctx, fp0, fd);
10483         }
10484         break;
10485     case OPC_ADD_PS:
10486         check_ps(ctx);
10487         {
10488             TCGv_i64 fp0 = tcg_temp_new_i64();
10489             TCGv_i64 fp1 = tcg_temp_new_i64();
10490 
10491             gen_load_fpr64(ctx, fp0, fs);
10492             gen_load_fpr64(ctx, fp1, ft);
10493             gen_helper_float_add_ps(fp0, tcg_env, fp0, fp1);
10494             gen_store_fpr64(ctx, fp0, fd);
10495         }
10496         break;
10497     case OPC_SUB_PS:
10498         check_ps(ctx);
10499         {
10500             TCGv_i64 fp0 = tcg_temp_new_i64();
10501             TCGv_i64 fp1 = tcg_temp_new_i64();
10502 
10503             gen_load_fpr64(ctx, fp0, fs);
10504             gen_load_fpr64(ctx, fp1, ft);
10505             gen_helper_float_sub_ps(fp0, tcg_env, fp0, fp1);
10506             gen_store_fpr64(ctx, fp0, fd);
10507         }
10508         break;
10509     case OPC_MUL_PS:
10510         check_ps(ctx);
10511         {
10512             TCGv_i64 fp0 = tcg_temp_new_i64();
10513             TCGv_i64 fp1 = tcg_temp_new_i64();
10514 
10515             gen_load_fpr64(ctx, fp0, fs);
10516             gen_load_fpr64(ctx, fp1, ft);
10517             gen_helper_float_mul_ps(fp0, tcg_env, fp0, fp1);
10518             gen_store_fpr64(ctx, fp0, fd);
10519         }
10520         break;
10521     case OPC_ABS_PS:
10522         check_ps(ctx);
10523         {
10524             TCGv_i64 fp0 = tcg_temp_new_i64();
10525 
10526             gen_load_fpr64(ctx, fp0, fs);
10527             gen_helper_float_abs_ps(fp0, fp0);
10528             gen_store_fpr64(ctx, fp0, fd);
10529         }
10530         break;
10531     case OPC_MOV_PS:
10532         check_ps(ctx);
10533         {
10534             TCGv_i64 fp0 = tcg_temp_new_i64();
10535 
10536             gen_load_fpr64(ctx, fp0, fs);
10537             gen_store_fpr64(ctx, fp0, fd);
10538         }
10539         break;
10540     case OPC_NEG_PS:
10541         check_ps(ctx);
10542         {
10543             TCGv_i64 fp0 = tcg_temp_new_i64();
10544 
10545             gen_load_fpr64(ctx, fp0, fs);
10546             gen_helper_float_chs_ps(fp0, fp0);
10547             gen_store_fpr64(ctx, fp0, fd);
10548         }
10549         break;
10550     case OPC_MOVCF_PS:
10551         check_ps(ctx);
10552         gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10553         break;
10554     case OPC_MOVZ_PS:
10555         check_ps(ctx);
10556         {
10557             TCGLabel *l1 = gen_new_label();
10558             TCGv_i64 fp0;
10559 
10560             if (ft != 0) {
10561                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10562             }
10563             fp0 = tcg_temp_new_i64();
10564             gen_load_fpr64(ctx, fp0, fs);
10565             gen_store_fpr64(ctx, fp0, fd);
10566             gen_set_label(l1);
10567         }
10568         break;
10569     case OPC_MOVN_PS:
10570         check_ps(ctx);
10571         {
10572             TCGLabel *l1 = gen_new_label();
10573             TCGv_i64 fp0;
10574 
10575             if (ft != 0) {
10576                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10577                 fp0 = tcg_temp_new_i64();
10578                 gen_load_fpr64(ctx, fp0, fs);
10579                 gen_store_fpr64(ctx, fp0, fd);
10580                 gen_set_label(l1);
10581             }
10582         }
10583         break;
10584     case OPC_ADDR_PS:
10585         check_ps(ctx);
10586         {
10587             TCGv_i64 fp0 = tcg_temp_new_i64();
10588             TCGv_i64 fp1 = tcg_temp_new_i64();
10589 
10590             gen_load_fpr64(ctx, fp0, ft);
10591             gen_load_fpr64(ctx, fp1, fs);
10592             gen_helper_float_addr_ps(fp0, tcg_env, fp0, fp1);
10593             gen_store_fpr64(ctx, fp0, fd);
10594         }
10595         break;
10596     case OPC_MULR_PS:
10597         check_ps(ctx);
10598         {
10599             TCGv_i64 fp0 = tcg_temp_new_i64();
10600             TCGv_i64 fp1 = tcg_temp_new_i64();
10601 
10602             gen_load_fpr64(ctx, fp0, ft);
10603             gen_load_fpr64(ctx, fp1, fs);
10604             gen_helper_float_mulr_ps(fp0, tcg_env, fp0, fp1);
10605             gen_store_fpr64(ctx, fp0, fd);
10606         }
10607         break;
10608     case OPC_RECIP2_PS:
10609         check_ps(ctx);
10610         {
10611             TCGv_i64 fp0 = tcg_temp_new_i64();
10612             TCGv_i64 fp1 = tcg_temp_new_i64();
10613 
10614             gen_load_fpr64(ctx, fp0, fs);
10615             gen_load_fpr64(ctx, fp1, ft);
10616             gen_helper_float_recip2_ps(fp0, tcg_env, fp0, fp1);
10617             gen_store_fpr64(ctx, fp0, fd);
10618         }
10619         break;
10620     case OPC_RECIP1_PS:
10621         check_ps(ctx);
10622         {
10623             TCGv_i64 fp0 = tcg_temp_new_i64();
10624 
10625             gen_load_fpr64(ctx, fp0, fs);
10626             gen_helper_float_recip1_ps(fp0, tcg_env, fp0);
10627             gen_store_fpr64(ctx, fp0, fd);
10628         }
10629         break;
10630     case OPC_RSQRT1_PS:
10631         check_ps(ctx);
10632         {
10633             TCGv_i64 fp0 = tcg_temp_new_i64();
10634 
10635             gen_load_fpr64(ctx, fp0, fs);
10636             gen_helper_float_rsqrt1_ps(fp0, tcg_env, fp0);
10637             gen_store_fpr64(ctx, fp0, fd);
10638         }
10639         break;
10640     case OPC_RSQRT2_PS:
10641         check_ps(ctx);
10642         {
10643             TCGv_i64 fp0 = tcg_temp_new_i64();
10644             TCGv_i64 fp1 = tcg_temp_new_i64();
10645 
10646             gen_load_fpr64(ctx, fp0, fs);
10647             gen_load_fpr64(ctx, fp1, ft);
10648             gen_helper_float_rsqrt2_ps(fp0, tcg_env, fp0, fp1);
10649             gen_store_fpr64(ctx, fp0, fd);
10650         }
10651         break;
10652     case OPC_CVT_S_PU:
10653         check_cp1_64bitmode(ctx);
10654         {
10655             TCGv_i32 fp0 = tcg_temp_new_i32();
10656 
10657             gen_load_fpr32h(ctx, fp0, fs);
10658             gen_helper_float_cvts_pu(fp0, tcg_env, fp0);
10659             gen_store_fpr32(ctx, fp0, fd);
10660         }
10661         break;
10662     case OPC_CVT_PW_PS:
10663         check_ps(ctx);
10664         {
10665             TCGv_i64 fp0 = tcg_temp_new_i64();
10666 
10667             gen_load_fpr64(ctx, fp0, fs);
10668             gen_helper_float_cvtpw_ps(fp0, tcg_env, fp0);
10669             gen_store_fpr64(ctx, fp0, fd);
10670         }
10671         break;
10672     case OPC_CVT_S_PL:
10673         check_cp1_64bitmode(ctx);
10674         {
10675             TCGv_i32 fp0 = tcg_temp_new_i32();
10676 
10677             gen_load_fpr32(ctx, fp0, fs);
10678             gen_helper_float_cvts_pl(fp0, tcg_env, fp0);
10679             gen_store_fpr32(ctx, fp0, fd);
10680         }
10681         break;
10682     case OPC_PLL_PS:
10683         check_ps(ctx);
10684         {
10685             TCGv_i32 fp0 = tcg_temp_new_i32();
10686             TCGv_i32 fp1 = tcg_temp_new_i32();
10687 
10688             gen_load_fpr32(ctx, fp0, fs);
10689             gen_load_fpr32(ctx, fp1, ft);
10690             gen_store_fpr32h(ctx, fp0, fd);
10691             gen_store_fpr32(ctx, fp1, fd);
10692         }
10693         break;
10694     case OPC_PLU_PS:
10695         check_ps(ctx);
10696         {
10697             TCGv_i32 fp0 = tcg_temp_new_i32();
10698             TCGv_i32 fp1 = tcg_temp_new_i32();
10699 
10700             gen_load_fpr32(ctx, fp0, fs);
10701             gen_load_fpr32h(ctx, fp1, ft);
10702             gen_store_fpr32(ctx, fp1, fd);
10703             gen_store_fpr32h(ctx, fp0, fd);
10704         }
10705         break;
10706     case OPC_PUL_PS:
10707         check_ps(ctx);
10708         {
10709             TCGv_i32 fp0 = tcg_temp_new_i32();
10710             TCGv_i32 fp1 = tcg_temp_new_i32();
10711 
10712             gen_load_fpr32h(ctx, fp0, fs);
10713             gen_load_fpr32(ctx, fp1, ft);
10714             gen_store_fpr32(ctx, fp1, fd);
10715             gen_store_fpr32h(ctx, fp0, fd);
10716         }
10717         break;
10718     case OPC_PUU_PS:
10719         check_ps(ctx);
10720         {
10721             TCGv_i32 fp0 = tcg_temp_new_i32();
10722             TCGv_i32 fp1 = tcg_temp_new_i32();
10723 
10724             gen_load_fpr32h(ctx, fp0, fs);
10725             gen_load_fpr32h(ctx, fp1, ft);
10726             gen_store_fpr32(ctx, fp1, fd);
10727             gen_store_fpr32h(ctx, fp0, fd);
10728         }
10729         break;
10730     case OPC_CMP_F_PS:
10731     case OPC_CMP_UN_PS:
10732     case OPC_CMP_EQ_PS:
10733     case OPC_CMP_UEQ_PS:
10734     case OPC_CMP_OLT_PS:
10735     case OPC_CMP_ULT_PS:
10736     case OPC_CMP_OLE_PS:
10737     case OPC_CMP_ULE_PS:
10738     case OPC_CMP_SF_PS:
10739     case OPC_CMP_NGLE_PS:
10740     case OPC_CMP_SEQ_PS:
10741     case OPC_CMP_NGL_PS:
10742     case OPC_CMP_LT_PS:
10743     case OPC_CMP_NGE_PS:
10744     case OPC_CMP_LE_PS:
10745     case OPC_CMP_NGT_PS:
10746         if (ctx->opcode & (1 << 6)) {
10747             gen_cmpabs_ps(ctx, func - 48, ft, fs, cc);
10748         } else {
10749             gen_cmp_ps(ctx, func - 48, ft, fs, cc);
10750         }
10751         break;
10752     default:
10753         MIPS_INVAL("farith");
10754         gen_reserved_instruction(ctx);
10755         return;
10756     }
10757 }
10758 
10759 /* Coprocessor 3 (FPU) */
gen_flt3_ldst(DisasContext * ctx,uint32_t opc,int fd,int fs,int base,int index)10760 static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc,
10761                           int fd, int fs, int base, int index)
10762 {
10763     TCGv t0 = tcg_temp_new();
10764 
10765     if (base == 0) {
10766         gen_load_gpr(t0, index);
10767     } else if (index == 0) {
10768         gen_load_gpr(t0, base);
10769     } else {
10770         gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
10771     }
10772     /*
10773      * Don't do NOP if destination is zero: we must perform the actual
10774      * memory access.
10775      */
10776     switch (opc) {
10777     case OPC_LWXC1:
10778         check_cop1x(ctx);
10779         {
10780             TCGv_i32 fp0 = tcg_temp_new_i32();
10781 
10782             tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
10783             tcg_gen_trunc_tl_i32(fp0, t0);
10784             gen_store_fpr32(ctx, fp0, fd);
10785         }
10786         break;
10787     case OPC_LDXC1:
10788         check_cop1x(ctx);
10789         check_cp1_registers(ctx, fd);
10790         {
10791             TCGv_i64 fp0 = tcg_temp_new_i64();
10792             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEUQ);
10793             gen_store_fpr64(ctx, fp0, fd);
10794         }
10795         break;
10796     case OPC_LUXC1:
10797         check_cp1_64bitmode(ctx);
10798         tcg_gen_andi_tl(t0, t0, ~0x7);
10799         {
10800             TCGv_i64 fp0 = tcg_temp_new_i64();
10801 
10802             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEUQ);
10803             gen_store_fpr64(ctx, fp0, fd);
10804         }
10805         break;
10806     case OPC_SWXC1:
10807         check_cop1x(ctx);
10808         {
10809             TCGv_i32 fp0 = tcg_temp_new_i32();
10810             gen_load_fpr32(ctx, fp0, fs);
10811             tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
10812         }
10813         break;
10814     case OPC_SDXC1:
10815         check_cop1x(ctx);
10816         check_cp1_registers(ctx, fs);
10817         {
10818             TCGv_i64 fp0 = tcg_temp_new_i64();
10819             gen_load_fpr64(ctx, fp0, fs);
10820             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEUQ);
10821         }
10822         break;
10823     case OPC_SUXC1:
10824         check_cp1_64bitmode(ctx);
10825         tcg_gen_andi_tl(t0, t0, ~0x7);
10826         {
10827             TCGv_i64 fp0 = tcg_temp_new_i64();
10828             gen_load_fpr64(ctx, fp0, fs);
10829             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEUQ);
10830         }
10831         break;
10832     }
10833 }
10834 
gen_flt3_arith(DisasContext * ctx,uint32_t opc,int fd,int fr,int fs,int ft)10835 static void gen_flt3_arith(DisasContext *ctx, uint32_t opc,
10836                            int fd, int fr, int fs, int ft)
10837 {
10838     switch (opc) {
10839     case OPC_ALNV_PS:
10840         check_ps(ctx);
10841         {
10842             TCGv t0 = tcg_temp_new();
10843             TCGv_i32 fp = tcg_temp_new_i32();
10844             TCGv_i32 fph = tcg_temp_new_i32();
10845             TCGLabel *l1 = gen_new_label();
10846             TCGLabel *l2 = gen_new_label();
10847 
10848             gen_load_gpr(t0, fr);
10849             tcg_gen_andi_tl(t0, t0, 0x7);
10850 
10851             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
10852             gen_load_fpr32(ctx, fp, fs);
10853             gen_load_fpr32h(ctx, fph, fs);
10854             gen_store_fpr32(ctx, fp, fd);
10855             gen_store_fpr32h(ctx, fph, fd);
10856             tcg_gen_br(l2);
10857             gen_set_label(l1);
10858             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
10859             if (cpu_is_bigendian(ctx)) {
10860                 gen_load_fpr32(ctx, fp, fs);
10861                 gen_load_fpr32h(ctx, fph, ft);
10862                 gen_store_fpr32h(ctx, fp, fd);
10863                 gen_store_fpr32(ctx, fph, fd);
10864             } else {
10865                 gen_load_fpr32h(ctx, fph, fs);
10866                 gen_load_fpr32(ctx, fp, ft);
10867                 gen_store_fpr32(ctx, fph, fd);
10868                 gen_store_fpr32h(ctx, fp, fd);
10869             }
10870             gen_set_label(l2);
10871         }
10872         break;
10873     case OPC_MADD_S:
10874         check_cop1x(ctx);
10875         {
10876             TCGv_i32 fp0 = tcg_temp_new_i32();
10877             TCGv_i32 fp1 = tcg_temp_new_i32();
10878             TCGv_i32 fp2 = tcg_temp_new_i32();
10879 
10880             gen_load_fpr32(ctx, fp0, fs);
10881             gen_load_fpr32(ctx, fp1, ft);
10882             gen_load_fpr32(ctx, fp2, fr);
10883             gen_helper_float_madd_s(fp2, tcg_env, fp0, fp1, fp2);
10884             gen_store_fpr32(ctx, fp2, fd);
10885         }
10886         break;
10887     case OPC_MADD_D:
10888         check_cop1x(ctx);
10889         check_cp1_registers(ctx, fd | fs | ft | fr);
10890         {
10891             TCGv_i64 fp0 = tcg_temp_new_i64();
10892             TCGv_i64 fp1 = tcg_temp_new_i64();
10893             TCGv_i64 fp2 = tcg_temp_new_i64();
10894 
10895             gen_load_fpr64(ctx, fp0, fs);
10896             gen_load_fpr64(ctx, fp1, ft);
10897             gen_load_fpr64(ctx, fp2, fr);
10898             gen_helper_float_madd_d(fp2, tcg_env, fp0, fp1, fp2);
10899             gen_store_fpr64(ctx, fp2, fd);
10900         }
10901         break;
10902     case OPC_MADD_PS:
10903         check_ps(ctx);
10904         {
10905             TCGv_i64 fp0 = tcg_temp_new_i64();
10906             TCGv_i64 fp1 = tcg_temp_new_i64();
10907             TCGv_i64 fp2 = tcg_temp_new_i64();
10908 
10909             gen_load_fpr64(ctx, fp0, fs);
10910             gen_load_fpr64(ctx, fp1, ft);
10911             gen_load_fpr64(ctx, fp2, fr);
10912             gen_helper_float_madd_ps(fp2, tcg_env, fp0, fp1, fp2);
10913             gen_store_fpr64(ctx, fp2, fd);
10914         }
10915         break;
10916     case OPC_MSUB_S:
10917         check_cop1x(ctx);
10918         {
10919             TCGv_i32 fp0 = tcg_temp_new_i32();
10920             TCGv_i32 fp1 = tcg_temp_new_i32();
10921             TCGv_i32 fp2 = tcg_temp_new_i32();
10922 
10923             gen_load_fpr32(ctx, fp0, fs);
10924             gen_load_fpr32(ctx, fp1, ft);
10925             gen_load_fpr32(ctx, fp2, fr);
10926             gen_helper_float_msub_s(fp2, tcg_env, fp0, fp1, fp2);
10927             gen_store_fpr32(ctx, fp2, fd);
10928         }
10929         break;
10930     case OPC_MSUB_D:
10931         check_cop1x(ctx);
10932         check_cp1_registers(ctx, fd | fs | ft | fr);
10933         {
10934             TCGv_i64 fp0 = tcg_temp_new_i64();
10935             TCGv_i64 fp1 = tcg_temp_new_i64();
10936             TCGv_i64 fp2 = tcg_temp_new_i64();
10937 
10938             gen_load_fpr64(ctx, fp0, fs);
10939             gen_load_fpr64(ctx, fp1, ft);
10940             gen_load_fpr64(ctx, fp2, fr);
10941             gen_helper_float_msub_d(fp2, tcg_env, fp0, fp1, fp2);
10942             gen_store_fpr64(ctx, fp2, fd);
10943         }
10944         break;
10945     case OPC_MSUB_PS:
10946         check_ps(ctx);
10947         {
10948             TCGv_i64 fp0 = tcg_temp_new_i64();
10949             TCGv_i64 fp1 = tcg_temp_new_i64();
10950             TCGv_i64 fp2 = tcg_temp_new_i64();
10951 
10952             gen_load_fpr64(ctx, fp0, fs);
10953             gen_load_fpr64(ctx, fp1, ft);
10954             gen_load_fpr64(ctx, fp2, fr);
10955             gen_helper_float_msub_ps(fp2, tcg_env, fp0, fp1, fp2);
10956             gen_store_fpr64(ctx, fp2, fd);
10957         }
10958         break;
10959     case OPC_NMADD_S:
10960         check_cop1x(ctx);
10961         {
10962             TCGv_i32 fp0 = tcg_temp_new_i32();
10963             TCGv_i32 fp1 = tcg_temp_new_i32();
10964             TCGv_i32 fp2 = tcg_temp_new_i32();
10965 
10966             gen_load_fpr32(ctx, fp0, fs);
10967             gen_load_fpr32(ctx, fp1, ft);
10968             gen_load_fpr32(ctx, fp2, fr);
10969             gen_helper_float_nmadd_s(fp2, tcg_env, fp0, fp1, fp2);
10970             gen_store_fpr32(ctx, fp2, fd);
10971         }
10972         break;
10973     case OPC_NMADD_D:
10974         check_cop1x(ctx);
10975         check_cp1_registers(ctx, fd | fs | ft | fr);
10976         {
10977             TCGv_i64 fp0 = tcg_temp_new_i64();
10978             TCGv_i64 fp1 = tcg_temp_new_i64();
10979             TCGv_i64 fp2 = tcg_temp_new_i64();
10980 
10981             gen_load_fpr64(ctx, fp0, fs);
10982             gen_load_fpr64(ctx, fp1, ft);
10983             gen_load_fpr64(ctx, fp2, fr);
10984             gen_helper_float_nmadd_d(fp2, tcg_env, fp0, fp1, fp2);
10985             gen_store_fpr64(ctx, fp2, fd);
10986         }
10987         break;
10988     case OPC_NMADD_PS:
10989         check_ps(ctx);
10990         {
10991             TCGv_i64 fp0 = tcg_temp_new_i64();
10992             TCGv_i64 fp1 = tcg_temp_new_i64();
10993             TCGv_i64 fp2 = tcg_temp_new_i64();
10994 
10995             gen_load_fpr64(ctx, fp0, fs);
10996             gen_load_fpr64(ctx, fp1, ft);
10997             gen_load_fpr64(ctx, fp2, fr);
10998             gen_helper_float_nmadd_ps(fp2, tcg_env, fp0, fp1, fp2);
10999             gen_store_fpr64(ctx, fp2, fd);
11000         }
11001         break;
11002     case OPC_NMSUB_S:
11003         check_cop1x(ctx);
11004         {
11005             TCGv_i32 fp0 = tcg_temp_new_i32();
11006             TCGv_i32 fp1 = tcg_temp_new_i32();
11007             TCGv_i32 fp2 = tcg_temp_new_i32();
11008 
11009             gen_load_fpr32(ctx, fp0, fs);
11010             gen_load_fpr32(ctx, fp1, ft);
11011             gen_load_fpr32(ctx, fp2, fr);
11012             gen_helper_float_nmsub_s(fp2, tcg_env, fp0, fp1, fp2);
11013             gen_store_fpr32(ctx, fp2, fd);
11014         }
11015         break;
11016     case OPC_NMSUB_D:
11017         check_cop1x(ctx);
11018         check_cp1_registers(ctx, fd | fs | ft | fr);
11019         {
11020             TCGv_i64 fp0 = tcg_temp_new_i64();
11021             TCGv_i64 fp1 = tcg_temp_new_i64();
11022             TCGv_i64 fp2 = tcg_temp_new_i64();
11023 
11024             gen_load_fpr64(ctx, fp0, fs);
11025             gen_load_fpr64(ctx, fp1, ft);
11026             gen_load_fpr64(ctx, fp2, fr);
11027             gen_helper_float_nmsub_d(fp2, tcg_env, fp0, fp1, fp2);
11028             gen_store_fpr64(ctx, fp2, fd);
11029         }
11030         break;
11031     case OPC_NMSUB_PS:
11032         check_ps(ctx);
11033         {
11034             TCGv_i64 fp0 = tcg_temp_new_i64();
11035             TCGv_i64 fp1 = tcg_temp_new_i64();
11036             TCGv_i64 fp2 = tcg_temp_new_i64();
11037 
11038             gen_load_fpr64(ctx, fp0, fs);
11039             gen_load_fpr64(ctx, fp1, ft);
11040             gen_load_fpr64(ctx, fp2, fr);
11041             gen_helper_float_nmsub_ps(fp2, tcg_env, fp0, fp1, fp2);
11042             gen_store_fpr64(ctx, fp2, fd);
11043         }
11044         break;
11045     default:
11046         MIPS_INVAL("flt3_arith");
11047         gen_reserved_instruction(ctx);
11048         return;
11049     }
11050 }
11051 
gen_rdhwr(DisasContext * ctx,int rt,int rd,int sel)11052 void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
11053 {
11054     TCGv t0;
11055 
11056 #if !defined(CONFIG_USER_ONLY)
11057     /*
11058      * The Linux kernel will emulate rdhwr if it's not supported natively.
11059      * Therefore only check the ISA in system mode.
11060      */
11061     check_insn(ctx, ISA_MIPS_R2);
11062 #endif
11063     t0 = tcg_temp_new();
11064 
11065     switch (rd) {
11066     case 0:
11067         gen_helper_rdhwr_cpunum(t0, tcg_env);
11068         gen_store_gpr(t0, rt);
11069         break;
11070     case 1:
11071         gen_helper_rdhwr_synci_step(t0, tcg_env);
11072         gen_store_gpr(t0, rt);
11073         break;
11074     case 2:
11075         translator_io_start(&ctx->base);
11076         gen_helper_rdhwr_cc(t0, tcg_env);
11077         gen_store_gpr(t0, rt);
11078         /*
11079          * Break the TB to be able to take timer interrupts immediately
11080          * after reading count. DISAS_STOP isn't sufficient, we need to ensure
11081          * we break completely out of translated code.
11082          */
11083         gen_save_pc(ctx->base.pc_next + 4);
11084         ctx->base.is_jmp = DISAS_EXIT;
11085         break;
11086     case 3:
11087         gen_helper_rdhwr_ccres(t0, tcg_env);
11088         gen_store_gpr(t0, rt);
11089         break;
11090     case 4:
11091         check_insn(ctx, ISA_MIPS_R6);
11092         if (sel != 0) {
11093             /*
11094              * Performance counter registers are not implemented other than
11095              * control register 0.
11096              */
11097             generate_exception(ctx, EXCP_RI);
11098         }
11099         gen_helper_rdhwr_performance(t0, tcg_env);
11100         gen_store_gpr(t0, rt);
11101         break;
11102     case 5:
11103         check_insn(ctx, ISA_MIPS_R6);
11104         gen_helper_rdhwr_xnp(t0, tcg_env);
11105         gen_store_gpr(t0, rt);
11106         break;
11107     case 29:
11108 #if defined(CONFIG_USER_ONLY)
11109         tcg_gen_ld_tl(t0, tcg_env,
11110                       offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
11111         gen_store_gpr(t0, rt);
11112         break;
11113 #else
11114         if ((ctx->hflags & MIPS_HFLAG_CP0) ||
11115             (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
11116             tcg_gen_ld_tl(t0, tcg_env,
11117                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
11118             gen_store_gpr(t0, rt);
11119         } else {
11120             gen_reserved_instruction(ctx);
11121         }
11122         break;
11123 #endif
11124     default:            /* Invalid */
11125         MIPS_INVAL("rdhwr");
11126         gen_reserved_instruction(ctx);
11127         break;
11128     }
11129 }
11130 
clear_branch_hflags(DisasContext * ctx)11131 static inline void clear_branch_hflags(DisasContext *ctx)
11132 {
11133     ctx->hflags &= ~MIPS_HFLAG_BMASK;
11134     if (ctx->base.is_jmp == DISAS_NEXT) {
11135         save_cpu_state(ctx, 0);
11136     } else {
11137         /*
11138          * It is not safe to save ctx->hflags as hflags may be changed
11139          * in execution time by the instruction in delay / forbidden slot.
11140          */
11141         tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
11142     }
11143 }
11144 
gen_branch(DisasContext * ctx,int insn_bytes)11145 static void gen_branch(DisasContext *ctx, int insn_bytes)
11146 {
11147     if (ctx->hflags & MIPS_HFLAG_BMASK) {
11148         int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
11149         /* Branches completion */
11150         clear_branch_hflags(ctx);
11151         ctx->base.is_jmp = DISAS_NORETURN;
11152         switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
11153         case MIPS_HFLAG_FBNSLOT:
11154             gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
11155             break;
11156         case MIPS_HFLAG_B:
11157             /* unconditional branch */
11158             if (proc_hflags & MIPS_HFLAG_BX) {
11159                 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
11160             }
11161             gen_goto_tb(ctx, 0, ctx->btarget);
11162             break;
11163         case MIPS_HFLAG_BL:
11164             /* blikely taken case */
11165             gen_goto_tb(ctx, 0, ctx->btarget);
11166             break;
11167         case MIPS_HFLAG_BC:
11168             /* Conditional branch */
11169             {
11170                 TCGLabel *l1 = gen_new_label();
11171 
11172                 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
11173                 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
11174                 gen_set_label(l1);
11175                 gen_goto_tb(ctx, 0, ctx->btarget);
11176             }
11177             break;
11178         case MIPS_HFLAG_BR:
11179             /* unconditional branch to register */
11180             if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
11181                 TCGv t0 = tcg_temp_new();
11182                 TCGv_i32 t1 = tcg_temp_new_i32();
11183 
11184                 tcg_gen_andi_tl(t0, btarget, 0x1);
11185                 tcg_gen_trunc_tl_i32(t1, t0);
11186                 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
11187                 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
11188                 tcg_gen_or_i32(hflags, hflags, t1);
11189 
11190                 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
11191             } else {
11192                 tcg_gen_mov_tl(cpu_PC, btarget);
11193             }
11194             tcg_gen_lookup_and_goto_ptr();
11195             break;
11196         default:
11197             LOG_DISAS("unknown branch 0x%x\n", proc_hflags);
11198             gen_reserved_instruction(ctx);
11199         }
11200     }
11201 }
11202 
11203 /* Compact Branches */
gen_compute_compact_branch(DisasContext * ctx,uint32_t opc,int rs,int rt,int32_t offset)11204 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
11205                                        int rs, int rt, int32_t offset)
11206 {
11207     int bcond_compute = 0;
11208     TCGv t0 = tcg_temp_new();
11209     TCGv t1 = tcg_temp_new();
11210     int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
11211 
11212     if (ctx->hflags & MIPS_HFLAG_BMASK) {
11213 #ifdef MIPS_DEBUG_DISAS
11214         LOG_DISAS("Branch in delay / forbidden slot at PC 0x%016"
11215                   VADDR_PRIx "\n", ctx->base.pc_next);
11216 #endif
11217         gen_reserved_instruction(ctx);
11218         return;
11219     }
11220 
11221     /* Load needed operands and calculate btarget */
11222     switch (opc) {
11223     /* compact branch */
11224     case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11225     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11226         gen_load_gpr(t0, rs);
11227         gen_load_gpr(t1, rt);
11228         bcond_compute = 1;
11229         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11230         if (rs <= rt && rs == 0) {
11231             /* OPC_BEQZALC, OPC_BNEZALC */
11232             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11233         }
11234         break;
11235     case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11236     case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11237         gen_load_gpr(t0, rs);
11238         gen_load_gpr(t1, rt);
11239         bcond_compute = 1;
11240         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11241         break;
11242     case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11243     case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11244         if (rs == 0 || rs == rt) {
11245             /* OPC_BLEZALC, OPC_BGEZALC */
11246             /* OPC_BGTZALC, OPC_BLTZALC */
11247             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11248         }
11249         gen_load_gpr(t0, rs);
11250         gen_load_gpr(t1, rt);
11251         bcond_compute = 1;
11252         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11253         break;
11254     case OPC_BC:
11255     case OPC_BALC:
11256         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11257         break;
11258     case OPC_BEQZC:
11259     case OPC_BNEZC:
11260         if (rs != 0) {
11261             /* OPC_BEQZC, OPC_BNEZC */
11262             gen_load_gpr(t0, rs);
11263             bcond_compute = 1;
11264             ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11265         } else {
11266             /* OPC_JIC, OPC_JIALC */
11267             TCGv tbase = tcg_temp_new();
11268             TCGv toffset = tcg_constant_tl(offset);
11269 
11270             gen_load_gpr(tbase, rt);
11271             gen_op_addr_add(ctx, btarget, tbase, toffset);
11272         }
11273         break;
11274     default:
11275         MIPS_INVAL("Compact branch/jump");
11276         gen_reserved_instruction(ctx);
11277         return;
11278     }
11279 
11280     if (bcond_compute == 0) {
11281         /* Unconditional compact branch */
11282         switch (opc) {
11283         case OPC_JIALC:
11284             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11285             /* Fallthrough */
11286         case OPC_JIC:
11287             ctx->hflags |= MIPS_HFLAG_BR;
11288             break;
11289         case OPC_BALC:
11290             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11291             /* Fallthrough */
11292         case OPC_BC:
11293             ctx->hflags |= MIPS_HFLAG_B;
11294             break;
11295         default:
11296             MIPS_INVAL("Compact branch/jump");
11297             gen_reserved_instruction(ctx);
11298             return;
11299         }
11300 
11301         /* Generating branch here as compact branches don't have delay slot */
11302         gen_branch(ctx, 4);
11303     } else {
11304         /* Conditional compact branch */
11305         TCGLabel *fs = gen_new_label();
11306         save_cpu_state(ctx, 0);
11307 
11308         switch (opc) {
11309         case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11310             if (rs == 0 && rt != 0) {
11311                 /* OPC_BLEZALC */
11312                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11313             } else if (rs != 0 && rt != 0 && rs == rt) {
11314                 /* OPC_BGEZALC */
11315                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11316             } else {
11317                 /* OPC_BGEUC */
11318                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
11319             }
11320             break;
11321         case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11322             if (rs == 0 && rt != 0) {
11323                 /* OPC_BGTZALC */
11324                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11325             } else if (rs != 0 && rt != 0 && rs == rt) {
11326                 /* OPC_BLTZALC */
11327                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11328             } else {
11329                 /* OPC_BLTUC */
11330                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
11331             }
11332             break;
11333         case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11334             if (rs == 0 && rt != 0) {
11335                 /* OPC_BLEZC */
11336                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11337             } else if (rs != 0 && rt != 0 && rs == rt) {
11338                 /* OPC_BGEZC */
11339                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11340             } else {
11341                 /* OPC_BGEC */
11342                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
11343             }
11344             break;
11345         case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11346             if (rs == 0 && rt != 0) {
11347                 /* OPC_BGTZC */
11348                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11349             } else if (rs != 0 && rt != 0 && rs == rt) {
11350                 /* OPC_BLTZC */
11351                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11352             } else {
11353                 /* OPC_BLTC */
11354                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
11355             }
11356             break;
11357         case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11358         case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11359             if (rs >= rt) {
11360                 /* OPC_BOVC, OPC_BNVC */
11361                 TCGv t2 = tcg_temp_new();
11362                 TCGv t3 = tcg_temp_new();
11363                 TCGv t4 = tcg_temp_new();
11364                 TCGv input_overflow = tcg_temp_new();
11365 
11366                 gen_load_gpr(t0, rs);
11367                 gen_load_gpr(t1, rt);
11368                 tcg_gen_ext32s_tl(t2, t0);
11369                 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
11370                 tcg_gen_ext32s_tl(t3, t1);
11371                 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
11372                 tcg_gen_or_tl(input_overflow, input_overflow, t4);
11373 
11374                 tcg_gen_add_tl(t4, t2, t3);
11375                 tcg_gen_ext32s_tl(t4, t4);
11376                 tcg_gen_xor_tl(t2, t2, t3);
11377                 tcg_gen_xor_tl(t3, t4, t3);
11378                 tcg_gen_andc_tl(t2, t3, t2);
11379                 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
11380                 tcg_gen_or_tl(t4, t4, input_overflow);
11381                 if (opc == OPC_BOVC) {
11382                     /* OPC_BOVC */
11383                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
11384                 } else {
11385                     /* OPC_BNVC */
11386                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
11387                 }
11388             } else if (rs < rt && rs == 0) {
11389                 /* OPC_BEQZALC, OPC_BNEZALC */
11390                 if (opc == OPC_BEQZALC) {
11391                     /* OPC_BEQZALC */
11392                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
11393                 } else {
11394                     /* OPC_BNEZALC */
11395                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
11396                 }
11397             } else {
11398                 /* OPC_BEQC, OPC_BNEC */
11399                 if (opc == OPC_BEQC) {
11400                     /* OPC_BEQC */
11401                     tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
11402                 } else {
11403                     /* OPC_BNEC */
11404                     tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
11405                 }
11406             }
11407             break;
11408         case OPC_BEQZC:
11409             tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
11410             break;
11411         case OPC_BNEZC:
11412             tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
11413             break;
11414         default:
11415             MIPS_INVAL("Compact conditional branch/jump");
11416             gen_reserved_instruction(ctx);
11417             return;
11418         }
11419 
11420         /* Generating branch here as compact branches don't have delay slot */
11421         gen_goto_tb(ctx, 1, ctx->btarget);
11422         gen_set_label(fs);
11423 
11424         ctx->hflags |= MIPS_HFLAG_FBNSLOT;
11425     }
11426 }
11427 
gen_addiupc(DisasContext * ctx,int rx,int imm,int is_64_bit,int extended)11428 void gen_addiupc(DisasContext *ctx, int rx, int imm,
11429                  int is_64_bit, int extended)
11430 {
11431     TCGv t0;
11432 
11433     if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11434         gen_reserved_instruction(ctx);
11435         return;
11436     }
11437 
11438     t0 = tcg_temp_new();
11439 
11440     tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
11441     tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
11442     if (!is_64_bit) {
11443         tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11444     }
11445 }
11446 
gen_cache_operation(DisasContext * ctx,uint32_t op,int base,int16_t offset)11447 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
11448                                 int16_t offset)
11449 {
11450     TCGv_i32 t0 = tcg_constant_i32(op);
11451     TCGv t1 = tcg_temp_new();
11452     gen_base_offset_addr(ctx, t1, base, offset);
11453     gen_helper_cache(tcg_env, t1, t0);
11454 }
11455 
is_uhi(DisasContext * ctx,int sdbbp_code)11456 static inline bool is_uhi(DisasContext *ctx, int sdbbp_code)
11457 {
11458 #ifdef CONFIG_USER_ONLY
11459     return false;
11460 #else
11461     bool is_user = (ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM;
11462     return semihosting_enabled(is_user) && sdbbp_code == 1;
11463 #endif
11464 }
11465 
gen_ldxs(DisasContext * ctx,int base,int index,int rd)11466 void gen_ldxs(DisasContext *ctx, int base, int index, int rd)
11467 {
11468     TCGv t0 = tcg_temp_new();
11469     TCGv t1 = tcg_temp_new();
11470 
11471     gen_load_gpr(t0, base);
11472 
11473     if (index != 0) {
11474         gen_load_gpr(t1, index);
11475         tcg_gen_shli_tl(t1, t1, 2);
11476         gen_op_addr_add(ctx, t0, t1, t0);
11477     }
11478 
11479     tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
11480     gen_store_gpr(t1, rd);
11481 }
11482 
gen_sync(int stype)11483 static void gen_sync(int stype)
11484 {
11485     TCGBar tcg_mo = TCG_BAR_SC;
11486 
11487     switch (stype) {
11488     case 0x4: /* SYNC_WMB */
11489         tcg_mo |= TCG_MO_ST_ST;
11490         break;
11491     case 0x10: /* SYNC_MB */
11492         tcg_mo |= TCG_MO_ALL;
11493         break;
11494     case 0x11: /* SYNC_ACQUIRE */
11495         tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
11496         break;
11497     case 0x12: /* SYNC_RELEASE */
11498         tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
11499         break;
11500     case 0x13: /* SYNC_RMB */
11501         tcg_mo |= TCG_MO_LD_LD;
11502         break;
11503     default:
11504         tcg_mo |= TCG_MO_ALL;
11505         break;
11506     }
11507 
11508     tcg_gen_mb(tcg_mo);
11509 }
11510 
11511 /* ISA extensions (ASEs) */
11512 
11513 /* MIPS16 extension to MIPS32 */
11514 #include "mips16e_translate.c.inc"
11515 
11516 /* microMIPS extension to MIPS32/MIPS64 */
11517 
11518 /*
11519  * Values for microMIPS fmt field.  Variable-width, depending on which
11520  * formats the instruction supports.
11521  */
11522 enum {
11523     FMT_SD_S = 0,
11524     FMT_SD_D = 1,
11525 
11526     FMT_SDPS_S = 0,
11527     FMT_SDPS_D = 1,
11528     FMT_SDPS_PS = 2,
11529 
11530     FMT_SWL_S = 0,
11531     FMT_SWL_W = 1,
11532     FMT_SWL_L = 2,
11533 
11534     FMT_DWL_D = 0,
11535     FMT_DWL_W = 1,
11536     FMT_DWL_L = 2
11537 };
11538 
11539 #include "micromips_translate.c.inc"
11540 
11541 #include "nanomips_translate.c.inc"
11542 
11543 /* MIPSDSP functions. */
11544 
11545 /* Indexed load is not for DSP only */
gen_mips_lx(DisasContext * ctx,uint32_t opc,int rd,int base,int offset)11546 static void gen_mips_lx(DisasContext *ctx, uint32_t opc,
11547                         int rd, int base, int offset)
11548 {
11549     TCGv t0;
11550 
11551     if (!(ctx->insn_flags & INSN_OCTEON)) {
11552         check_dsp(ctx);
11553     }
11554     t0 = tcg_temp_new();
11555 
11556     if (base == 0) {
11557         gen_load_gpr(t0, offset);
11558     } else if (offset == 0) {
11559         gen_load_gpr(t0, base);
11560     } else {
11561         gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
11562     }
11563 
11564     switch (opc) {
11565     case OPC_LBUX:
11566         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
11567         gen_store_gpr(t0, rd);
11568         break;
11569     case OPC_LHX:
11570         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
11571         gen_store_gpr(t0, rd);
11572         break;
11573     case OPC_LWX:
11574         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
11575         gen_store_gpr(t0, rd);
11576         break;
11577 #if defined(TARGET_MIPS64)
11578     case OPC_LDX:
11579         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ);
11580         gen_store_gpr(t0, rd);
11581         break;
11582 #endif
11583     }
11584 }
11585 
gen_mipsdsp_arith(DisasContext * ctx,uint32_t op1,uint32_t op2,int ret,int v1,int v2)11586 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
11587                               int ret, int v1, int v2)
11588 {
11589     TCGv v1_t;
11590     TCGv v2_t;
11591 
11592     if (ret == 0) {
11593         /* Treat as NOP. */
11594         return;
11595     }
11596 
11597     v1_t = tcg_temp_new();
11598     v2_t = tcg_temp_new();
11599 
11600     gen_load_gpr(v1_t, v1);
11601     gen_load_gpr(v2_t, v2);
11602 
11603     switch (op1) {
11604     /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
11605     case OPC_MULT_G_2E:
11606         check_dsp_r2(ctx);
11607         switch (op2) {
11608         case OPC_ADDUH_QB:
11609             gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
11610             break;
11611         case OPC_ADDUH_R_QB:
11612             gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
11613             break;
11614         case OPC_ADDQH_PH:
11615             gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
11616             break;
11617         case OPC_ADDQH_R_PH:
11618             gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
11619             break;
11620         case OPC_ADDQH_W:
11621             gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
11622             break;
11623         case OPC_ADDQH_R_W:
11624             gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
11625             break;
11626         case OPC_SUBUH_QB:
11627             gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
11628             break;
11629         case OPC_SUBUH_R_QB:
11630             gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
11631             break;
11632         case OPC_SUBQH_PH:
11633             gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
11634             break;
11635         case OPC_SUBQH_R_PH:
11636             gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
11637             break;
11638         case OPC_SUBQH_W:
11639             gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
11640             break;
11641         case OPC_SUBQH_R_W:
11642             gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
11643             break;
11644         }
11645         break;
11646     case OPC_ABSQ_S_PH_DSP:
11647         switch (op2) {
11648         case OPC_ABSQ_S_QB:
11649             check_dsp_r2(ctx);
11650             gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, tcg_env);
11651             break;
11652         case OPC_ABSQ_S_PH:
11653             check_dsp(ctx);
11654             gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, tcg_env);
11655             break;
11656         case OPC_ABSQ_S_W:
11657             check_dsp(ctx);
11658             gen_helper_absq_s_w(cpu_gpr[ret], v2_t, tcg_env);
11659             break;
11660         case OPC_PRECEQ_W_PHL:
11661             check_dsp(ctx);
11662             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
11663             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
11664             break;
11665         case OPC_PRECEQ_W_PHR:
11666             check_dsp(ctx);
11667             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
11668             tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
11669             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
11670             break;
11671         case OPC_PRECEQU_PH_QBL:
11672             check_dsp(ctx);
11673             gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
11674             break;
11675         case OPC_PRECEQU_PH_QBR:
11676             check_dsp(ctx);
11677             gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
11678             break;
11679         case OPC_PRECEQU_PH_QBLA:
11680             check_dsp(ctx);
11681             gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
11682             break;
11683         case OPC_PRECEQU_PH_QBRA:
11684             check_dsp(ctx);
11685             gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
11686             break;
11687         case OPC_PRECEU_PH_QBL:
11688             check_dsp(ctx);
11689             gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
11690             break;
11691         case OPC_PRECEU_PH_QBR:
11692             check_dsp(ctx);
11693             gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
11694             break;
11695         case OPC_PRECEU_PH_QBLA:
11696             check_dsp(ctx);
11697             gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
11698             break;
11699         case OPC_PRECEU_PH_QBRA:
11700             check_dsp(ctx);
11701             gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
11702             break;
11703         }
11704         break;
11705     case OPC_ADDU_QB_DSP:
11706         switch (op2) {
11707         case OPC_ADDQ_PH:
11708             check_dsp(ctx);
11709             gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11710             break;
11711         case OPC_ADDQ_S_PH:
11712             check_dsp(ctx);
11713             gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11714             break;
11715         case OPC_ADDQ_S_W:
11716             check_dsp(ctx);
11717             gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11718             break;
11719         case OPC_ADDU_QB:
11720             check_dsp(ctx);
11721             gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11722             break;
11723         case OPC_ADDU_S_QB:
11724             check_dsp(ctx);
11725             gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11726             break;
11727         case OPC_ADDU_PH:
11728             check_dsp_r2(ctx);
11729             gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11730             break;
11731         case OPC_ADDU_S_PH:
11732             check_dsp_r2(ctx);
11733             gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11734             break;
11735         case OPC_SUBQ_PH:
11736             check_dsp(ctx);
11737             gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11738             break;
11739         case OPC_SUBQ_S_PH:
11740             check_dsp(ctx);
11741             gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11742             break;
11743         case OPC_SUBQ_S_W:
11744             check_dsp(ctx);
11745             gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11746             break;
11747         case OPC_SUBU_QB:
11748             check_dsp(ctx);
11749             gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11750             break;
11751         case OPC_SUBU_S_QB:
11752             check_dsp(ctx);
11753             gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11754             break;
11755         case OPC_SUBU_PH:
11756             check_dsp_r2(ctx);
11757             gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11758             break;
11759         case OPC_SUBU_S_PH:
11760             check_dsp_r2(ctx);
11761             gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11762             break;
11763         case OPC_ADDSC:
11764             check_dsp(ctx);
11765             gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11766             break;
11767         case OPC_ADDWC:
11768             check_dsp(ctx);
11769             gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11770             break;
11771         case OPC_MODSUB:
11772             check_dsp(ctx);
11773             gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
11774             break;
11775         case OPC_RADDU_W_QB:
11776             check_dsp(ctx);
11777             gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
11778             break;
11779         }
11780         break;
11781     case OPC_CMPU_EQ_QB_DSP:
11782         switch (op2) {
11783         case OPC_PRECR_QB_PH:
11784             check_dsp_r2(ctx);
11785             gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
11786             break;
11787         case OPC_PRECRQ_QB_PH:
11788             check_dsp(ctx);
11789             gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
11790             break;
11791         case OPC_PRECR_SRA_PH_W:
11792             check_dsp_r2(ctx);
11793             {
11794                 TCGv_i32 sa_t = tcg_constant_i32(v2);
11795                 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
11796                                           cpu_gpr[ret]);
11797                 break;
11798             }
11799         case OPC_PRECR_SRA_R_PH_W:
11800             check_dsp_r2(ctx);
11801             {
11802                 TCGv_i32 sa_t = tcg_constant_i32(v2);
11803                 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
11804                                             cpu_gpr[ret]);
11805                 break;
11806             }
11807         case OPC_PRECRQ_PH_W:
11808             check_dsp(ctx);
11809             gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
11810             break;
11811         case OPC_PRECRQ_RS_PH_W:
11812             check_dsp(ctx);
11813             gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11814             break;
11815         case OPC_PRECRQU_S_QB_PH:
11816             check_dsp(ctx);
11817             gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11818             break;
11819         }
11820         break;
11821 #ifdef TARGET_MIPS64
11822     case OPC_ABSQ_S_QH_DSP:
11823         switch (op2) {
11824         case OPC_PRECEQ_L_PWL:
11825             check_dsp(ctx);
11826             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
11827             break;
11828         case OPC_PRECEQ_L_PWR:
11829             check_dsp(ctx);
11830             tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
11831             break;
11832         case OPC_PRECEQ_PW_QHL:
11833             check_dsp(ctx);
11834             gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
11835             break;
11836         case OPC_PRECEQ_PW_QHR:
11837             check_dsp(ctx);
11838             gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
11839             break;
11840         case OPC_PRECEQ_PW_QHLA:
11841             check_dsp(ctx);
11842             gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
11843             break;
11844         case OPC_PRECEQ_PW_QHRA:
11845             check_dsp(ctx);
11846             gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
11847             break;
11848         case OPC_PRECEQU_QH_OBL:
11849             check_dsp(ctx);
11850             gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
11851             break;
11852         case OPC_PRECEQU_QH_OBR:
11853             check_dsp(ctx);
11854             gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
11855             break;
11856         case OPC_PRECEQU_QH_OBLA:
11857             check_dsp(ctx);
11858             gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
11859             break;
11860         case OPC_PRECEQU_QH_OBRA:
11861             check_dsp(ctx);
11862             gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
11863             break;
11864         case OPC_PRECEU_QH_OBL:
11865             check_dsp(ctx);
11866             gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
11867             break;
11868         case OPC_PRECEU_QH_OBR:
11869             check_dsp(ctx);
11870             gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
11871             break;
11872         case OPC_PRECEU_QH_OBLA:
11873             check_dsp(ctx);
11874             gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
11875             break;
11876         case OPC_PRECEU_QH_OBRA:
11877             check_dsp(ctx);
11878             gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
11879             break;
11880         case OPC_ABSQ_S_OB:
11881             check_dsp_r2(ctx);
11882             gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, tcg_env);
11883             break;
11884         case OPC_ABSQ_S_PW:
11885             check_dsp(ctx);
11886             gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, tcg_env);
11887             break;
11888         case OPC_ABSQ_S_QH:
11889             check_dsp(ctx);
11890             gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, tcg_env);
11891             break;
11892         }
11893         break;
11894     case OPC_ADDU_OB_DSP:
11895         switch (op2) {
11896         case OPC_RADDU_L_OB:
11897             check_dsp(ctx);
11898             gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
11899             break;
11900         case OPC_SUBQ_PW:
11901             check_dsp(ctx);
11902             gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11903             break;
11904         case OPC_SUBQ_S_PW:
11905             check_dsp(ctx);
11906             gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11907             break;
11908         case OPC_SUBQ_QH:
11909             check_dsp(ctx);
11910             gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11911             break;
11912         case OPC_SUBQ_S_QH:
11913             check_dsp(ctx);
11914             gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11915             break;
11916         case OPC_SUBU_OB:
11917             check_dsp(ctx);
11918             gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11919             break;
11920         case OPC_SUBU_S_OB:
11921             check_dsp(ctx);
11922             gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11923             break;
11924         case OPC_SUBU_QH:
11925             check_dsp_r2(ctx);
11926             gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11927             break;
11928         case OPC_SUBU_S_QH:
11929             check_dsp_r2(ctx);
11930             gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11931             break;
11932         case OPC_SUBUH_OB:
11933             check_dsp_r2(ctx);
11934             gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
11935             break;
11936         case OPC_SUBUH_R_OB:
11937             check_dsp_r2(ctx);
11938             gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
11939             break;
11940         case OPC_ADDQ_PW:
11941             check_dsp(ctx);
11942             gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11943             break;
11944         case OPC_ADDQ_S_PW:
11945             check_dsp(ctx);
11946             gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11947             break;
11948         case OPC_ADDQ_QH:
11949             check_dsp(ctx);
11950             gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11951             break;
11952         case OPC_ADDQ_S_QH:
11953             check_dsp(ctx);
11954             gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11955             break;
11956         case OPC_ADDU_OB:
11957             check_dsp(ctx);
11958             gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11959             break;
11960         case OPC_ADDU_S_OB:
11961             check_dsp(ctx);
11962             gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11963             break;
11964         case OPC_ADDU_QH:
11965             check_dsp_r2(ctx);
11966             gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11967             break;
11968         case OPC_ADDU_S_QH:
11969             check_dsp_r2(ctx);
11970             gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11971             break;
11972         case OPC_ADDUH_OB:
11973             check_dsp_r2(ctx);
11974             gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
11975             break;
11976         case OPC_ADDUH_R_OB:
11977             check_dsp_r2(ctx);
11978             gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
11979             break;
11980         }
11981         break;
11982     case OPC_CMPU_EQ_OB_DSP:
11983         switch (op2) {
11984         case OPC_PRECR_OB_QH:
11985             check_dsp_r2(ctx);
11986             gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
11987             break;
11988         case OPC_PRECR_SRA_QH_PW:
11989             check_dsp_r2(ctx);
11990             {
11991                 TCGv_i32 ret_t = tcg_constant_i32(ret);
11992                 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
11993                 break;
11994             }
11995         case OPC_PRECR_SRA_R_QH_PW:
11996             check_dsp_r2(ctx);
11997             {
11998                 TCGv_i32 sa_v = tcg_constant_i32(ret);
11999                 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
12000                 break;
12001             }
12002         case OPC_PRECRQ_OB_QH:
12003             check_dsp(ctx);
12004             gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
12005             break;
12006         case OPC_PRECRQ_PW_L:
12007             check_dsp(ctx);
12008             gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
12009             break;
12010         case OPC_PRECRQ_QH_PW:
12011             check_dsp(ctx);
12012             gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
12013             break;
12014         case OPC_PRECRQ_RS_QH_PW:
12015             check_dsp(ctx);
12016             gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12017             break;
12018         case OPC_PRECRQU_S_OB_QH:
12019             check_dsp(ctx);
12020             gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12021             break;
12022         }
12023         break;
12024 #endif
12025     }
12026 }
12027 
gen_mipsdsp_shift(DisasContext * ctx,uint32_t opc,int ret,int v1,int v2)12028 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
12029                               int ret, int v1, int v2)
12030 {
12031     uint32_t op2;
12032     TCGv t0;
12033     TCGv v1_t;
12034     TCGv v2_t;
12035 
12036     if (ret == 0) {
12037         /* Treat as NOP. */
12038         return;
12039     }
12040 
12041     t0 = tcg_temp_new();
12042     v1_t = tcg_temp_new();
12043     v2_t = tcg_temp_new();
12044 
12045     tcg_gen_movi_tl(t0, v1);
12046     gen_load_gpr(v1_t, v1);
12047     gen_load_gpr(v2_t, v2);
12048 
12049     switch (opc) {
12050     case OPC_SHLL_QB_DSP:
12051         {
12052             op2 = MASK_SHLL_QB(ctx->opcode);
12053             switch (op2) {
12054             case OPC_SHLL_QB:
12055                 check_dsp(ctx);
12056                 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, tcg_env);
12057                 break;
12058             case OPC_SHLLV_QB:
12059                 check_dsp(ctx);
12060                 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12061                 break;
12062             case OPC_SHLL_PH:
12063                 check_dsp(ctx);
12064                 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, tcg_env);
12065                 break;
12066             case OPC_SHLLV_PH:
12067                 check_dsp(ctx);
12068                 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12069                 break;
12070             case OPC_SHLL_S_PH:
12071                 check_dsp(ctx);
12072                 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, tcg_env);
12073                 break;
12074             case OPC_SHLLV_S_PH:
12075                 check_dsp(ctx);
12076                 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12077                 break;
12078             case OPC_SHLL_S_W:
12079                 check_dsp(ctx);
12080                 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, tcg_env);
12081                 break;
12082             case OPC_SHLLV_S_W:
12083                 check_dsp(ctx);
12084                 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12085                 break;
12086             case OPC_SHRL_QB:
12087                 check_dsp(ctx);
12088                 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
12089                 break;
12090             case OPC_SHRLV_QB:
12091                 check_dsp(ctx);
12092                 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
12093                 break;
12094             case OPC_SHRL_PH:
12095                 check_dsp_r2(ctx);
12096                 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
12097                 break;
12098             case OPC_SHRLV_PH:
12099                 check_dsp_r2(ctx);
12100                 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
12101                 break;
12102             case OPC_SHRA_QB:
12103                 check_dsp_r2(ctx);
12104                 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
12105                 break;
12106             case OPC_SHRA_R_QB:
12107                 check_dsp_r2(ctx);
12108                 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
12109                 break;
12110             case OPC_SHRAV_QB:
12111                 check_dsp_r2(ctx);
12112                 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
12113                 break;
12114             case OPC_SHRAV_R_QB:
12115                 check_dsp_r2(ctx);
12116                 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
12117                 break;
12118             case OPC_SHRA_PH:
12119                 check_dsp(ctx);
12120                 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
12121                 break;
12122             case OPC_SHRA_R_PH:
12123                 check_dsp(ctx);
12124                 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
12125                 break;
12126             case OPC_SHRAV_PH:
12127                 check_dsp(ctx);
12128                 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
12129                 break;
12130             case OPC_SHRAV_R_PH:
12131                 check_dsp(ctx);
12132                 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
12133                 break;
12134             case OPC_SHRA_R_W:
12135                 check_dsp(ctx);
12136                 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
12137                 break;
12138             case OPC_SHRAV_R_W:
12139                 check_dsp(ctx);
12140                 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
12141                 break;
12142             default:            /* Invalid */
12143                 MIPS_INVAL("MASK SHLL.QB");
12144                 gen_reserved_instruction(ctx);
12145                 break;
12146             }
12147             break;
12148         }
12149 #ifdef TARGET_MIPS64
12150     case OPC_SHLL_OB_DSP:
12151         op2 = MASK_SHLL_OB(ctx->opcode);
12152         switch (op2) {
12153         case OPC_SHLL_PW:
12154             check_dsp(ctx);
12155             gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, tcg_env);
12156             break;
12157         case OPC_SHLLV_PW:
12158             check_dsp(ctx);
12159             gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, tcg_env);
12160             break;
12161         case OPC_SHLL_S_PW:
12162             check_dsp(ctx);
12163             gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, tcg_env);
12164             break;
12165         case OPC_SHLLV_S_PW:
12166             check_dsp(ctx);
12167             gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, tcg_env);
12168             break;
12169         case OPC_SHLL_OB:
12170             check_dsp(ctx);
12171             gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, tcg_env);
12172             break;
12173         case OPC_SHLLV_OB:
12174             check_dsp(ctx);
12175             gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, tcg_env);
12176             break;
12177         case OPC_SHLL_QH:
12178             check_dsp(ctx);
12179             gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, tcg_env);
12180             break;
12181         case OPC_SHLLV_QH:
12182             check_dsp(ctx);
12183             gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, tcg_env);
12184             break;
12185         case OPC_SHLL_S_QH:
12186             check_dsp(ctx);
12187             gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, tcg_env);
12188             break;
12189         case OPC_SHLLV_S_QH:
12190             check_dsp(ctx);
12191             gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, tcg_env);
12192             break;
12193         case OPC_SHRA_OB:
12194             check_dsp_r2(ctx);
12195             gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
12196             break;
12197         case OPC_SHRAV_OB:
12198             check_dsp_r2(ctx);
12199             gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
12200             break;
12201         case OPC_SHRA_R_OB:
12202             check_dsp_r2(ctx);
12203             gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
12204             break;
12205         case OPC_SHRAV_R_OB:
12206             check_dsp_r2(ctx);
12207             gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
12208             break;
12209         case OPC_SHRA_PW:
12210             check_dsp(ctx);
12211             gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
12212             break;
12213         case OPC_SHRAV_PW:
12214             check_dsp(ctx);
12215             gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
12216             break;
12217         case OPC_SHRA_R_PW:
12218             check_dsp(ctx);
12219             gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
12220             break;
12221         case OPC_SHRAV_R_PW:
12222             check_dsp(ctx);
12223             gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
12224             break;
12225         case OPC_SHRA_QH:
12226             check_dsp(ctx);
12227             gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
12228             break;
12229         case OPC_SHRAV_QH:
12230             check_dsp(ctx);
12231             gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
12232             break;
12233         case OPC_SHRA_R_QH:
12234             check_dsp(ctx);
12235             gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
12236             break;
12237         case OPC_SHRAV_R_QH:
12238             check_dsp(ctx);
12239             gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
12240             break;
12241         case OPC_SHRL_OB:
12242             check_dsp(ctx);
12243             gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
12244             break;
12245         case OPC_SHRLV_OB:
12246             check_dsp(ctx);
12247             gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
12248             break;
12249         case OPC_SHRL_QH:
12250             check_dsp_r2(ctx);
12251             gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
12252             break;
12253         case OPC_SHRLV_QH:
12254             check_dsp_r2(ctx);
12255             gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
12256             break;
12257         default:            /* Invalid */
12258             MIPS_INVAL("MASK SHLL.OB");
12259             gen_reserved_instruction(ctx);
12260             break;
12261         }
12262         break;
12263 #endif
12264     }
12265 }
12266 
gen_mipsdsp_multiply(DisasContext * ctx,uint32_t op1,uint32_t op2,int ret,int v1,int v2,int check_ret)12267 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
12268                                  int ret, int v1, int v2, int check_ret)
12269 {
12270     TCGv_i32 t0;
12271     TCGv v1_t;
12272     TCGv v2_t;
12273 
12274     if ((ret == 0) && (check_ret == 1)) {
12275         /* Treat as NOP. */
12276         return;
12277     }
12278 
12279     t0 = tcg_temp_new_i32();
12280     v1_t = tcg_temp_new();
12281     v2_t = tcg_temp_new();
12282 
12283     tcg_gen_movi_i32(t0, ret);
12284     gen_load_gpr(v1_t, v1);
12285     gen_load_gpr(v2_t, v2);
12286 
12287     switch (op1) {
12288     /*
12289      * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
12290      * the same mask and op1.
12291      */
12292     case OPC_MULT_G_2E:
12293         check_dsp_r2(ctx);
12294         switch (op2) {
12295         case  OPC_MUL_PH:
12296             gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12297             break;
12298         case  OPC_MUL_S_PH:
12299             gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12300             break;
12301         case OPC_MULQ_S_W:
12302             gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12303             break;
12304         case OPC_MULQ_RS_W:
12305             gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12306             break;
12307         }
12308         break;
12309     case OPC_DPA_W_PH_DSP:
12310         switch (op2) {
12311         case OPC_DPAU_H_QBL:
12312             check_dsp(ctx);
12313             gen_helper_dpau_h_qbl(t0, v1_t, v2_t, tcg_env);
12314             break;
12315         case OPC_DPAU_H_QBR:
12316             check_dsp(ctx);
12317             gen_helper_dpau_h_qbr(t0, v1_t, v2_t, tcg_env);
12318             break;
12319         case OPC_DPSU_H_QBL:
12320             check_dsp(ctx);
12321             gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, tcg_env);
12322             break;
12323         case OPC_DPSU_H_QBR:
12324             check_dsp(ctx);
12325             gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, tcg_env);
12326             break;
12327         case OPC_DPA_W_PH:
12328             check_dsp_r2(ctx);
12329             gen_helper_dpa_w_ph(t0, v1_t, v2_t, tcg_env);
12330             break;
12331         case OPC_DPAX_W_PH:
12332             check_dsp_r2(ctx);
12333             gen_helper_dpax_w_ph(t0, v1_t, v2_t, tcg_env);
12334             break;
12335         case OPC_DPAQ_S_W_PH:
12336             check_dsp(ctx);
12337             gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, tcg_env);
12338             break;
12339         case OPC_DPAQX_S_W_PH:
12340             check_dsp_r2(ctx);
12341             gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, tcg_env);
12342             break;
12343         case OPC_DPAQX_SA_W_PH:
12344             check_dsp_r2(ctx);
12345             gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, tcg_env);
12346             break;
12347         case OPC_DPS_W_PH:
12348             check_dsp_r2(ctx);
12349             gen_helper_dps_w_ph(t0, v1_t, v2_t, tcg_env);
12350             break;
12351         case OPC_DPSX_W_PH:
12352             check_dsp_r2(ctx);
12353             gen_helper_dpsx_w_ph(t0, v1_t, v2_t, tcg_env);
12354             break;
12355         case OPC_DPSQ_S_W_PH:
12356             check_dsp(ctx);
12357             gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, tcg_env);
12358             break;
12359         case OPC_DPSQX_S_W_PH:
12360             check_dsp_r2(ctx);
12361             gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, tcg_env);
12362             break;
12363         case OPC_DPSQX_SA_W_PH:
12364             check_dsp_r2(ctx);
12365             gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, tcg_env);
12366             break;
12367         case OPC_MULSAQ_S_W_PH:
12368             check_dsp(ctx);
12369             gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, tcg_env);
12370             break;
12371         case OPC_DPAQ_SA_L_W:
12372             check_dsp(ctx);
12373             gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, tcg_env);
12374             break;
12375         case OPC_DPSQ_SA_L_W:
12376             check_dsp(ctx);
12377             gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, tcg_env);
12378             break;
12379         case OPC_MAQ_S_W_PHL:
12380             check_dsp(ctx);
12381             gen_helper_maq_s_w_phl(t0, v1_t, v2_t, tcg_env);
12382             break;
12383         case OPC_MAQ_S_W_PHR:
12384             check_dsp(ctx);
12385             gen_helper_maq_s_w_phr(t0, v1_t, v2_t, tcg_env);
12386             break;
12387         case OPC_MAQ_SA_W_PHL:
12388             check_dsp(ctx);
12389             gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, tcg_env);
12390             break;
12391         case OPC_MAQ_SA_W_PHR:
12392             check_dsp(ctx);
12393             gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, tcg_env);
12394             break;
12395         case OPC_MULSA_W_PH:
12396             check_dsp_r2(ctx);
12397             gen_helper_mulsa_w_ph(t0, v1_t, v2_t, tcg_env);
12398             break;
12399         }
12400         break;
12401 #ifdef TARGET_MIPS64
12402     case OPC_DPAQ_W_QH_DSP:
12403         {
12404             int ac = ret & 0x03;
12405             tcg_gen_movi_i32(t0, ac);
12406 
12407             switch (op2) {
12408             case OPC_DMADD:
12409                 check_dsp(ctx);
12410                 gen_helper_dmadd(v1_t, v2_t, t0, tcg_env);
12411                 break;
12412             case OPC_DMADDU:
12413                 check_dsp(ctx);
12414                 gen_helper_dmaddu(v1_t, v2_t, t0, tcg_env);
12415                 break;
12416             case OPC_DMSUB:
12417                 check_dsp(ctx);
12418                 gen_helper_dmsub(v1_t, v2_t, t0, tcg_env);
12419                 break;
12420             case OPC_DMSUBU:
12421                 check_dsp(ctx);
12422                 gen_helper_dmsubu(v1_t, v2_t, t0, tcg_env);
12423                 break;
12424             case OPC_DPA_W_QH:
12425                 check_dsp_r2(ctx);
12426                 gen_helper_dpa_w_qh(v1_t, v2_t, t0, tcg_env);
12427                 break;
12428             case OPC_DPAQ_S_W_QH:
12429                 check_dsp(ctx);
12430                 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, tcg_env);
12431                 break;
12432             case OPC_DPAQ_SA_L_PW:
12433                 check_dsp(ctx);
12434                 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, tcg_env);
12435                 break;
12436             case OPC_DPAU_H_OBL:
12437                 check_dsp(ctx);
12438                 gen_helper_dpau_h_obl(v1_t, v2_t, t0, tcg_env);
12439                 break;
12440             case OPC_DPAU_H_OBR:
12441                 check_dsp(ctx);
12442                 gen_helper_dpau_h_obr(v1_t, v2_t, t0, tcg_env);
12443                 break;
12444             case OPC_DPS_W_QH:
12445                 check_dsp_r2(ctx);
12446                 gen_helper_dps_w_qh(v1_t, v2_t, t0, tcg_env);
12447                 break;
12448             case OPC_DPSQ_S_W_QH:
12449                 check_dsp(ctx);
12450                 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, tcg_env);
12451                 break;
12452             case OPC_DPSQ_SA_L_PW:
12453                 check_dsp(ctx);
12454                 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, tcg_env);
12455                 break;
12456             case OPC_DPSU_H_OBL:
12457                 check_dsp(ctx);
12458                 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, tcg_env);
12459                 break;
12460             case OPC_DPSU_H_OBR:
12461                 check_dsp(ctx);
12462                 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, tcg_env);
12463                 break;
12464             case OPC_MAQ_S_L_PWL:
12465                 check_dsp(ctx);
12466                 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, tcg_env);
12467                 break;
12468             case OPC_MAQ_S_L_PWR:
12469                 check_dsp(ctx);
12470                 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, tcg_env);
12471                 break;
12472             case OPC_MAQ_S_W_QHLL:
12473                 check_dsp(ctx);
12474                 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, tcg_env);
12475                 break;
12476             case OPC_MAQ_SA_W_QHLL:
12477                 check_dsp(ctx);
12478                 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, tcg_env);
12479                 break;
12480             case OPC_MAQ_S_W_QHLR:
12481                 check_dsp(ctx);
12482                 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, tcg_env);
12483                 break;
12484             case OPC_MAQ_SA_W_QHLR:
12485                 check_dsp(ctx);
12486                 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, tcg_env);
12487                 break;
12488             case OPC_MAQ_S_W_QHRL:
12489                 check_dsp(ctx);
12490                 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, tcg_env);
12491                 break;
12492             case OPC_MAQ_SA_W_QHRL:
12493                 check_dsp(ctx);
12494                 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, tcg_env);
12495                 break;
12496             case OPC_MAQ_S_W_QHRR:
12497                 check_dsp(ctx);
12498                 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, tcg_env);
12499                 break;
12500             case OPC_MAQ_SA_W_QHRR:
12501                 check_dsp(ctx);
12502                 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, tcg_env);
12503                 break;
12504             case OPC_MULSAQ_S_L_PW:
12505                 check_dsp(ctx);
12506                 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, tcg_env);
12507                 break;
12508             case OPC_MULSAQ_S_W_QH:
12509                 check_dsp(ctx);
12510                 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, tcg_env);
12511                 break;
12512             }
12513         }
12514         break;
12515 #endif
12516     case OPC_ADDU_QB_DSP:
12517         switch (op2) {
12518         case OPC_MULEU_S_PH_QBL:
12519             check_dsp(ctx);
12520             gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12521             break;
12522         case OPC_MULEU_S_PH_QBR:
12523             check_dsp(ctx);
12524             gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12525             break;
12526         case OPC_MULQ_RS_PH:
12527             check_dsp(ctx);
12528             gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12529             break;
12530         case OPC_MULEQ_S_W_PHL:
12531             check_dsp(ctx);
12532             gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12533             break;
12534         case OPC_MULEQ_S_W_PHR:
12535             check_dsp(ctx);
12536             gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12537             break;
12538         case OPC_MULQ_S_PH:
12539             check_dsp_r2(ctx);
12540             gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12541             break;
12542         }
12543         break;
12544 #ifdef TARGET_MIPS64
12545     case OPC_ADDU_OB_DSP:
12546         switch (op2) {
12547         case OPC_MULEQ_S_PW_QHL:
12548             check_dsp(ctx);
12549             gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12550             break;
12551         case OPC_MULEQ_S_PW_QHR:
12552             check_dsp(ctx);
12553             gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12554             break;
12555         case OPC_MULEU_S_QH_OBL:
12556             check_dsp(ctx);
12557             gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12558             break;
12559         case OPC_MULEU_S_QH_OBR:
12560             check_dsp(ctx);
12561             gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12562             break;
12563         case OPC_MULQ_RS_QH:
12564             check_dsp(ctx);
12565             gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12566             break;
12567         }
12568         break;
12569 #endif
12570     }
12571 }
12572 
gen_mipsdsp_bitinsn(DisasContext * ctx,uint32_t op1,uint32_t op2,int ret,int val)12573 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
12574                                 int ret, int val)
12575 {
12576     int16_t imm;
12577     TCGv t0;
12578     TCGv val_t;
12579 
12580     if (ret == 0) {
12581         /* Treat as NOP. */
12582         return;
12583     }
12584 
12585     t0 = tcg_temp_new();
12586     val_t = tcg_temp_new();
12587     gen_load_gpr(val_t, val);
12588 
12589     switch (op1) {
12590     case OPC_ABSQ_S_PH_DSP:
12591         switch (op2) {
12592         case OPC_BITREV:
12593             check_dsp(ctx);
12594             gen_helper_bitrev(cpu_gpr[ret], val_t);
12595             break;
12596         case OPC_REPL_QB:
12597             check_dsp(ctx);
12598             {
12599                 target_long result;
12600                 imm = (ctx->opcode >> 16) & 0xFF;
12601                 result = (uint32_t)imm << 24 |
12602                          (uint32_t)imm << 16 |
12603                          (uint32_t)imm << 8  |
12604                          (uint32_t)imm;
12605                 result = (int32_t)result;
12606                 tcg_gen_movi_tl(cpu_gpr[ret], result);
12607             }
12608             break;
12609         case OPC_REPLV_QB:
12610             check_dsp(ctx);
12611             tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
12612             tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
12613             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12614             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
12615             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12616             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12617             break;
12618         case OPC_REPL_PH:
12619             check_dsp(ctx);
12620             {
12621                 imm = (ctx->opcode >> 16) & 0x03FF;
12622                 imm = (int16_t)(imm << 6) >> 6;
12623                 tcg_gen_movi_tl(cpu_gpr[ret], \
12624                                 (target_long)((int32_t)imm << 16 | \
12625                                 (uint16_t)imm));
12626             }
12627             break;
12628         case OPC_REPLV_PH:
12629             check_dsp(ctx);
12630             tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
12631             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
12632             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12633             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12634             break;
12635         }
12636         break;
12637 #ifdef TARGET_MIPS64
12638     case OPC_ABSQ_S_QH_DSP:
12639         switch (op2) {
12640         case OPC_REPL_OB:
12641             check_dsp(ctx);
12642             {
12643                 target_long temp;
12644 
12645                 imm = (ctx->opcode >> 16) & 0xFF;
12646                 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
12647                 temp = (temp << 16) | temp;
12648                 temp = (temp << 32) | temp;
12649                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
12650                 break;
12651             }
12652         case OPC_REPL_PW:
12653             check_dsp(ctx);
12654             {
12655                 target_long temp;
12656 
12657                 imm = (ctx->opcode >> 16) & 0x03FF;
12658                 imm = (int16_t)(imm << 6) >> 6;
12659                 temp = ((target_long)imm << 32) \
12660                        | ((target_long)imm & 0xFFFFFFFF);
12661                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
12662                 break;
12663             }
12664         case OPC_REPL_QH:
12665             check_dsp(ctx);
12666             {
12667                 target_long temp;
12668 
12669                 imm = (ctx->opcode >> 16) & 0x03FF;
12670                 imm = (int16_t)(imm << 6) >> 6;
12671 
12672                 temp = ((uint64_t)(uint16_t)imm << 48) |
12673                        ((uint64_t)(uint16_t)imm << 32) |
12674                        ((uint64_t)(uint16_t)imm << 16) |
12675                        (uint64_t)(uint16_t)imm;
12676                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
12677                 break;
12678             }
12679         case OPC_REPLV_OB:
12680             check_dsp(ctx);
12681             tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
12682             tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
12683             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12684             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
12685             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12686             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
12687             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12688             break;
12689         case OPC_REPLV_PW:
12690             check_dsp(ctx);
12691             tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
12692             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
12693             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12694             break;
12695         case OPC_REPLV_QH:
12696             check_dsp(ctx);
12697             tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
12698             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
12699             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12700             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
12701             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12702             break;
12703         }
12704         break;
12705 #endif
12706     }
12707 }
12708 
gen_mipsdsp_add_cmp_pick(DisasContext * ctx,uint32_t op1,uint32_t op2,int ret,int v1,int v2,int check_ret)12709 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
12710                                      uint32_t op1, uint32_t op2,
12711                                      int ret, int v1, int v2, int check_ret)
12712 {
12713     TCGv t1;
12714     TCGv v1_t;
12715     TCGv v2_t;
12716 
12717     if ((ret == 0) && (check_ret == 1)) {
12718         /* Treat as NOP. */
12719         return;
12720     }
12721 
12722     t1 = tcg_temp_new();
12723     v1_t = tcg_temp_new();
12724     v2_t = tcg_temp_new();
12725 
12726     gen_load_gpr(v1_t, v1);
12727     gen_load_gpr(v2_t, v2);
12728 
12729     switch (op1) {
12730     case OPC_CMPU_EQ_QB_DSP:
12731         switch (op2) {
12732         case OPC_CMPU_EQ_QB:
12733             check_dsp(ctx);
12734             gen_helper_cmpu_eq_qb(v1_t, v2_t, tcg_env);
12735             break;
12736         case OPC_CMPU_LT_QB:
12737             check_dsp(ctx);
12738             gen_helper_cmpu_lt_qb(v1_t, v2_t, tcg_env);
12739             break;
12740         case OPC_CMPU_LE_QB:
12741             check_dsp(ctx);
12742             gen_helper_cmpu_le_qb(v1_t, v2_t, tcg_env);
12743             break;
12744         case OPC_CMPGU_EQ_QB:
12745             check_dsp(ctx);
12746             gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
12747             break;
12748         case OPC_CMPGU_LT_QB:
12749             check_dsp(ctx);
12750             gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
12751             break;
12752         case OPC_CMPGU_LE_QB:
12753             check_dsp(ctx);
12754             gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
12755             break;
12756         case OPC_CMPGDU_EQ_QB:
12757             check_dsp_r2(ctx);
12758             gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
12759             tcg_gen_mov_tl(cpu_gpr[ret], t1);
12760             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
12761             tcg_gen_shli_tl(t1, t1, 24);
12762             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
12763             break;
12764         case OPC_CMPGDU_LT_QB:
12765             check_dsp_r2(ctx);
12766             gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
12767             tcg_gen_mov_tl(cpu_gpr[ret], t1);
12768             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
12769             tcg_gen_shli_tl(t1, t1, 24);
12770             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
12771             break;
12772         case OPC_CMPGDU_LE_QB:
12773             check_dsp_r2(ctx);
12774             gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
12775             tcg_gen_mov_tl(cpu_gpr[ret], t1);
12776             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
12777             tcg_gen_shli_tl(t1, t1, 24);
12778             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
12779             break;
12780         case OPC_CMP_EQ_PH:
12781             check_dsp(ctx);
12782             gen_helper_cmp_eq_ph(v1_t, v2_t, tcg_env);
12783             break;
12784         case OPC_CMP_LT_PH:
12785             check_dsp(ctx);
12786             gen_helper_cmp_lt_ph(v1_t, v2_t, tcg_env);
12787             break;
12788         case OPC_CMP_LE_PH:
12789             check_dsp(ctx);
12790             gen_helper_cmp_le_ph(v1_t, v2_t, tcg_env);
12791             break;
12792         case OPC_PICK_QB:
12793             check_dsp(ctx);
12794             gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12795             break;
12796         case OPC_PICK_PH:
12797             check_dsp(ctx);
12798             gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12799             break;
12800         case OPC_PACKRL_PH:
12801             check_dsp(ctx);
12802             gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
12803             break;
12804         }
12805         break;
12806 #ifdef TARGET_MIPS64
12807     case OPC_CMPU_EQ_OB_DSP:
12808         switch (op2) {
12809         case OPC_CMP_EQ_PW:
12810             check_dsp(ctx);
12811             gen_helper_cmp_eq_pw(v1_t, v2_t, tcg_env);
12812             break;
12813         case OPC_CMP_LT_PW:
12814             check_dsp(ctx);
12815             gen_helper_cmp_lt_pw(v1_t, v2_t, tcg_env);
12816             break;
12817         case OPC_CMP_LE_PW:
12818             check_dsp(ctx);
12819             gen_helper_cmp_le_pw(v1_t, v2_t, tcg_env);
12820             break;
12821         case OPC_CMP_EQ_QH:
12822             check_dsp(ctx);
12823             gen_helper_cmp_eq_qh(v1_t, v2_t, tcg_env);
12824             break;
12825         case OPC_CMP_LT_QH:
12826             check_dsp(ctx);
12827             gen_helper_cmp_lt_qh(v1_t, v2_t, tcg_env);
12828             break;
12829         case OPC_CMP_LE_QH:
12830             check_dsp(ctx);
12831             gen_helper_cmp_le_qh(v1_t, v2_t, tcg_env);
12832             break;
12833         case OPC_CMPGDU_EQ_OB:
12834             check_dsp_r2(ctx);
12835             gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12836             break;
12837         case OPC_CMPGDU_LT_OB:
12838             check_dsp_r2(ctx);
12839             gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12840             break;
12841         case OPC_CMPGDU_LE_OB:
12842             check_dsp_r2(ctx);
12843             gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12844             break;
12845         case OPC_CMPGU_EQ_OB:
12846             check_dsp(ctx);
12847             gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
12848             break;
12849         case OPC_CMPGU_LT_OB:
12850             check_dsp(ctx);
12851             gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
12852             break;
12853         case OPC_CMPGU_LE_OB:
12854             check_dsp(ctx);
12855             gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
12856             break;
12857         case OPC_CMPU_EQ_OB:
12858             check_dsp(ctx);
12859             gen_helper_cmpu_eq_ob(v1_t, v2_t, tcg_env);
12860             break;
12861         case OPC_CMPU_LT_OB:
12862             check_dsp(ctx);
12863             gen_helper_cmpu_lt_ob(v1_t, v2_t, tcg_env);
12864             break;
12865         case OPC_CMPU_LE_OB:
12866             check_dsp(ctx);
12867             gen_helper_cmpu_le_ob(v1_t, v2_t, tcg_env);
12868             break;
12869         case OPC_PACKRL_PW:
12870             check_dsp(ctx);
12871             gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
12872             break;
12873         case OPC_PICK_OB:
12874             check_dsp(ctx);
12875             gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12876             break;
12877         case OPC_PICK_PW:
12878             check_dsp(ctx);
12879             gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12880             break;
12881         case OPC_PICK_QH:
12882             check_dsp(ctx);
12883             gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12884             break;
12885         }
12886         break;
12887 #endif
12888     }
12889 }
12890 
gen_mipsdsp_append(CPUMIPSState * env,DisasContext * ctx,uint32_t op1,int rt,int rs,int sa)12891 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
12892                                uint32_t op1, int rt, int rs, int sa)
12893 {
12894     TCGv t0;
12895 
12896     check_dsp_r2(ctx);
12897 
12898     if (rt == 0) {
12899         /* Treat as NOP. */
12900         return;
12901     }
12902 
12903     t0 = tcg_temp_new();
12904     gen_load_gpr(t0, rs);
12905 
12906     switch (op1) {
12907     case OPC_APPEND_DSP:
12908         switch (MASK_APPEND(ctx->opcode)) {
12909         case OPC_APPEND:
12910             if (sa != 0) {
12911                 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
12912             }
12913             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
12914             break;
12915         case OPC_PREPEND:
12916             if (sa != 0) {
12917                 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
12918                 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
12919                 tcg_gen_shli_tl(t0, t0, 32 - sa);
12920                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
12921             }
12922             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
12923             break;
12924         case OPC_BALIGN:
12925             sa &= 3;
12926             if (sa != 0 && sa != 2) {
12927                 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
12928                 tcg_gen_ext32u_tl(t0, t0);
12929                 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
12930                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
12931             }
12932             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
12933             break;
12934         default:            /* Invalid */
12935             MIPS_INVAL("MASK APPEND");
12936             gen_reserved_instruction(ctx);
12937             break;
12938         }
12939         break;
12940 #ifdef TARGET_MIPS64
12941     case OPC_DAPPEND_DSP:
12942         switch (MASK_DAPPEND(ctx->opcode)) {
12943         case OPC_DAPPEND:
12944             if (sa != 0) {
12945                 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
12946             }
12947             break;
12948         case OPC_PREPENDD:
12949             tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
12950             tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
12951             tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
12952             break;
12953         case OPC_PREPENDW:
12954             if (sa != 0) {
12955                 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
12956                 tcg_gen_shli_tl(t0, t0, 64 - sa);
12957                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
12958             }
12959             break;
12960         case OPC_DBALIGN:
12961             sa &= 7;
12962             if (sa != 0 && sa != 2 && sa != 4) {
12963                 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
12964                 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
12965                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
12966             }
12967             break;
12968         default:            /* Invalid */
12969             MIPS_INVAL("MASK DAPPEND");
12970             gen_reserved_instruction(ctx);
12971             break;
12972         }
12973         break;
12974 #endif
12975     }
12976 }
12977 
gen_mipsdsp_accinsn(DisasContext * ctx,uint32_t op1,uint32_t op2,int ret,int v1,int v2,int check_ret)12978 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
12979                                 int ret, int v1, int v2, int check_ret)
12980 
12981 {
12982     TCGv t0;
12983     TCGv t1;
12984     TCGv v1_t;
12985     int16_t imm;
12986 
12987     if ((ret == 0) && (check_ret == 1)) {
12988         /* Treat as NOP. */
12989         return;
12990     }
12991 
12992     t0 = tcg_temp_new();
12993     t1 = tcg_temp_new();
12994     v1_t = tcg_temp_new();
12995 
12996     gen_load_gpr(v1_t, v1);
12997 
12998     switch (op1) {
12999     case OPC_EXTR_W_DSP:
13000         check_dsp(ctx);
13001         switch (op2) {
13002         case OPC_EXTR_W:
13003             tcg_gen_movi_tl(t0, v2);
13004             tcg_gen_movi_tl(t1, v1);
13005             gen_helper_extr_w(cpu_gpr[ret], t0, t1, tcg_env);
13006             break;
13007         case OPC_EXTR_R_W:
13008             tcg_gen_movi_tl(t0, v2);
13009             tcg_gen_movi_tl(t1, v1);
13010             gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, tcg_env);
13011             break;
13012         case OPC_EXTR_RS_W:
13013             tcg_gen_movi_tl(t0, v2);
13014             tcg_gen_movi_tl(t1, v1);
13015             gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, tcg_env);
13016             break;
13017         case OPC_EXTR_S_H:
13018             tcg_gen_movi_tl(t0, v2);
13019             tcg_gen_movi_tl(t1, v1);
13020             gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, tcg_env);
13021             break;
13022         case OPC_EXTRV_S_H:
13023             tcg_gen_movi_tl(t0, v2);
13024             gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, tcg_env);
13025             break;
13026         case OPC_EXTRV_W:
13027             tcg_gen_movi_tl(t0, v2);
13028             gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, tcg_env);
13029             break;
13030         case OPC_EXTRV_R_W:
13031             tcg_gen_movi_tl(t0, v2);
13032             gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, tcg_env);
13033             break;
13034         case OPC_EXTRV_RS_W:
13035             tcg_gen_movi_tl(t0, v2);
13036             gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, tcg_env);
13037             break;
13038         case OPC_EXTP:
13039             tcg_gen_movi_tl(t0, v2);
13040             tcg_gen_movi_tl(t1, v1);
13041             gen_helper_extp(cpu_gpr[ret], t0, t1, tcg_env);
13042             break;
13043         case OPC_EXTPV:
13044             tcg_gen_movi_tl(t0, v2);
13045             gen_helper_extp(cpu_gpr[ret], t0, v1_t, tcg_env);
13046             break;
13047         case OPC_EXTPDP:
13048             tcg_gen_movi_tl(t0, v2);
13049             tcg_gen_movi_tl(t1, v1);
13050             gen_helper_extpdp(cpu_gpr[ret], t0, t1, tcg_env);
13051             break;
13052         case OPC_EXTPDPV:
13053             tcg_gen_movi_tl(t0, v2);
13054             gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, tcg_env);
13055             break;
13056         case OPC_SHILO:
13057             imm = (ctx->opcode >> 20) & 0x3F;
13058             tcg_gen_movi_tl(t0, ret);
13059             tcg_gen_movi_tl(t1, imm);
13060             gen_helper_shilo(t0, t1, tcg_env);
13061             break;
13062         case OPC_SHILOV:
13063             tcg_gen_movi_tl(t0, ret);
13064             gen_helper_shilo(t0, v1_t, tcg_env);
13065             break;
13066         case OPC_MTHLIP:
13067             tcg_gen_movi_tl(t0, ret);
13068             gen_helper_mthlip(t0, v1_t, tcg_env);
13069             break;
13070         case OPC_WRDSP:
13071             imm = (ctx->opcode >> 11) & 0x3FF;
13072             tcg_gen_movi_tl(t0, imm);
13073             gen_helper_wrdsp(v1_t, t0, tcg_env);
13074             break;
13075         case OPC_RDDSP:
13076             imm = (ctx->opcode >> 16) & 0x03FF;
13077             tcg_gen_movi_tl(t0, imm);
13078             gen_helper_rddsp(cpu_gpr[ret], t0, tcg_env);
13079             break;
13080         }
13081         break;
13082 #ifdef TARGET_MIPS64
13083     case OPC_DEXTR_W_DSP:
13084         check_dsp(ctx);
13085         switch (op2) {
13086         case OPC_DMTHLIP:
13087             tcg_gen_movi_tl(t0, ret);
13088             gen_helper_dmthlip(v1_t, t0, tcg_env);
13089             break;
13090         case OPC_DSHILO:
13091             {
13092                 int shift = (ctx->opcode >> 19) & 0x7F;
13093                 int ac = (ctx->opcode >> 11) & 0x03;
13094                 tcg_gen_movi_tl(t0, shift);
13095                 tcg_gen_movi_tl(t1, ac);
13096                 gen_helper_dshilo(t0, t1, tcg_env);
13097                 break;
13098             }
13099         case OPC_DSHILOV:
13100             {
13101                 int ac = (ctx->opcode >> 11) & 0x03;
13102                 tcg_gen_movi_tl(t0, ac);
13103                 gen_helper_dshilo(v1_t, t0, tcg_env);
13104                 break;
13105             }
13106         case OPC_DEXTP:
13107             tcg_gen_movi_tl(t0, v2);
13108             tcg_gen_movi_tl(t1, v1);
13109 
13110             gen_helper_dextp(cpu_gpr[ret], t0, t1, tcg_env);
13111             break;
13112         case OPC_DEXTPV:
13113             tcg_gen_movi_tl(t0, v2);
13114             gen_helper_dextp(cpu_gpr[ret], t0, v1_t, tcg_env);
13115             break;
13116         case OPC_DEXTPDP:
13117             tcg_gen_movi_tl(t0, v2);
13118             tcg_gen_movi_tl(t1, v1);
13119             gen_helper_dextpdp(cpu_gpr[ret], t0, t1, tcg_env);
13120             break;
13121         case OPC_DEXTPDPV:
13122             tcg_gen_movi_tl(t0, v2);
13123             gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, tcg_env);
13124             break;
13125         case OPC_DEXTR_L:
13126             tcg_gen_movi_tl(t0, v2);
13127             tcg_gen_movi_tl(t1, v1);
13128             gen_helper_dextr_l(cpu_gpr[ret], t0, t1, tcg_env);
13129             break;
13130         case OPC_DEXTR_R_L:
13131             tcg_gen_movi_tl(t0, v2);
13132             tcg_gen_movi_tl(t1, v1);
13133             gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, tcg_env);
13134             break;
13135         case OPC_DEXTR_RS_L:
13136             tcg_gen_movi_tl(t0, v2);
13137             tcg_gen_movi_tl(t1, v1);
13138             gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, tcg_env);
13139             break;
13140         case OPC_DEXTR_W:
13141             tcg_gen_movi_tl(t0, v2);
13142             tcg_gen_movi_tl(t1, v1);
13143             gen_helper_dextr_w(cpu_gpr[ret], t0, t1, tcg_env);
13144             break;
13145         case OPC_DEXTR_R_W:
13146             tcg_gen_movi_tl(t0, v2);
13147             tcg_gen_movi_tl(t1, v1);
13148             gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, tcg_env);
13149             break;
13150         case OPC_DEXTR_RS_W:
13151             tcg_gen_movi_tl(t0, v2);
13152             tcg_gen_movi_tl(t1, v1);
13153             gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, tcg_env);
13154             break;
13155         case OPC_DEXTR_S_H:
13156             tcg_gen_movi_tl(t0, v2);
13157             tcg_gen_movi_tl(t1, v1);
13158             gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, tcg_env);
13159             break;
13160         case OPC_DEXTRV_S_H:
13161             tcg_gen_movi_tl(t0, v2);
13162             gen_helper_dextr_s_h(cpu_gpr[ret], t0, v1_t, tcg_env);
13163             break;
13164         case OPC_DEXTRV_L:
13165             tcg_gen_movi_tl(t0, v2);
13166             gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, tcg_env);
13167             break;
13168         case OPC_DEXTRV_R_L:
13169             tcg_gen_movi_tl(t0, v2);
13170             gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, tcg_env);
13171             break;
13172         case OPC_DEXTRV_RS_L:
13173             tcg_gen_movi_tl(t0, v2);
13174             gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, tcg_env);
13175             break;
13176         case OPC_DEXTRV_W:
13177             tcg_gen_movi_tl(t0, v2);
13178             gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, tcg_env);
13179             break;
13180         case OPC_DEXTRV_R_W:
13181             tcg_gen_movi_tl(t0, v2);
13182             gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, tcg_env);
13183             break;
13184         case OPC_DEXTRV_RS_W:
13185             tcg_gen_movi_tl(t0, v2);
13186             gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, tcg_env);
13187             break;
13188         }
13189         break;
13190 #endif
13191     }
13192 }
13193 
13194 /* End MIPSDSP functions. */
13195 
decode_opc_special_r6(CPUMIPSState * env,DisasContext * ctx)13196 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
13197 {
13198     int rs, rt, rd, sa;
13199     uint32_t op1, op2;
13200 
13201     rs = (ctx->opcode >> 21) & 0x1f;
13202     rt = (ctx->opcode >> 16) & 0x1f;
13203     rd = (ctx->opcode >> 11) & 0x1f;
13204     sa = (ctx->opcode >> 6) & 0x1f;
13205 
13206     op1 = MASK_SPECIAL(ctx->opcode);
13207     switch (op1) {
13208     case OPC_MULT:
13209     case OPC_MULTU:
13210     case OPC_DIV:
13211     case OPC_DIVU:
13212         op2 = MASK_R6_MULDIV(ctx->opcode);
13213         switch (op2) {
13214         case R6_OPC_MUL:
13215         case R6_OPC_MUH:
13216         case R6_OPC_MULU:
13217         case R6_OPC_MUHU:
13218         case R6_OPC_DIV:
13219         case R6_OPC_MOD:
13220         case R6_OPC_DIVU:
13221         case R6_OPC_MODU:
13222             gen_r6_muldiv(ctx, op2, rd, rs, rt);
13223             break;
13224         default:
13225             MIPS_INVAL("special_r6 muldiv");
13226             gen_reserved_instruction(ctx);
13227             break;
13228         }
13229         break;
13230     case OPC_SELEQZ:
13231     case OPC_SELNEZ:
13232         gen_cond_move(ctx, op1, rd, rs, rt);
13233         break;
13234     case R6_OPC_CLO:
13235     case R6_OPC_CLZ:
13236         if (rt == 0 && sa == 1) {
13237             /*
13238              * Major opcode and function field is shared with preR6 MFHI/MTHI.
13239              * We need additionally to check other fields.
13240              */
13241             gen_cl(ctx, op1, rd, rs);
13242         } else {
13243             gen_reserved_instruction(ctx);
13244         }
13245         break;
13246     case R6_OPC_SDBBP:
13247         if (is_uhi(ctx, extract32(ctx->opcode, 6, 20))) {
13248             ctx->base.is_jmp = DISAS_SEMIHOST;
13249         } else {
13250             if (ctx->hflags & MIPS_HFLAG_SBRI) {
13251                 gen_reserved_instruction(ctx);
13252             } else {
13253                 generate_exception_end(ctx, EXCP_DBp);
13254             }
13255         }
13256         break;
13257 #if defined(TARGET_MIPS64)
13258     case R6_OPC_DCLO:
13259     case R6_OPC_DCLZ:
13260         if (rt == 0 && sa == 1) {
13261             /*
13262              * Major opcode and function field is shared with preR6 MFHI/MTHI.
13263              * We need additionally to check other fields.
13264              */
13265             check_mips_64(ctx);
13266             gen_cl(ctx, op1, rd, rs);
13267         } else {
13268             gen_reserved_instruction(ctx);
13269         }
13270         break;
13271     case OPC_DMULT:
13272     case OPC_DMULTU:
13273     case OPC_DDIV:
13274     case OPC_DDIVU:
13275 
13276         op2 = MASK_R6_MULDIV(ctx->opcode);
13277         switch (op2) {
13278         case R6_OPC_DMUL:
13279         case R6_OPC_DMUH:
13280         case R6_OPC_DMULU:
13281         case R6_OPC_DMUHU:
13282         case R6_OPC_DDIV:
13283         case R6_OPC_DMOD:
13284         case R6_OPC_DDIVU:
13285         case R6_OPC_DMODU:
13286             check_mips_64(ctx);
13287             gen_r6_muldiv(ctx, op2, rd, rs, rt);
13288             break;
13289         default:
13290             MIPS_INVAL("special_r6 muldiv");
13291             gen_reserved_instruction(ctx);
13292             break;
13293         }
13294         break;
13295 #endif
13296     default:            /* Invalid */
13297         MIPS_INVAL("special_r6");
13298         gen_reserved_instruction(ctx);
13299         break;
13300     }
13301 }
13302 
decode_opc_special_tx79(CPUMIPSState * env,DisasContext * ctx)13303 static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx)
13304 {
13305     int rs = extract32(ctx->opcode, 21, 5);
13306     int rt = extract32(ctx->opcode, 16, 5);
13307     int rd = extract32(ctx->opcode, 11, 5);
13308     uint32_t op1 = MASK_SPECIAL(ctx->opcode);
13309 
13310     switch (op1) {
13311     case OPC_MOVN:         /* Conditional move */
13312     case OPC_MOVZ:
13313         gen_cond_move(ctx, op1, rd, rs, rt);
13314         break;
13315     case OPC_MFHI:          /* Move from HI/LO */
13316     case OPC_MFLO:
13317         gen_HILO(ctx, op1, 0, rd);
13318         break;
13319     case OPC_MTHI:
13320     case OPC_MTLO:          /* Move to HI/LO */
13321         gen_HILO(ctx, op1, 0, rs);
13322         break;
13323     case OPC_MULT:
13324     case OPC_MULTU:
13325         gen_mul_txx9(ctx, op1, rd, rs, rt);
13326         break;
13327     case OPC_DIV:
13328     case OPC_DIVU:
13329         gen_muldiv(ctx, op1, 0, rs, rt);
13330         break;
13331 #if defined(TARGET_MIPS64)
13332     case OPC_DMULT:
13333     case OPC_DMULTU:
13334     case OPC_DDIV:
13335     case OPC_DDIVU:
13336         check_insn_opc_user_only(ctx, INSN_R5900);
13337         gen_muldiv(ctx, op1, 0, rs, rt);
13338         break;
13339 #endif
13340     case OPC_JR:
13341         gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
13342         break;
13343     default:            /* Invalid */
13344         MIPS_INVAL("special_tx79");
13345         gen_reserved_instruction(ctx);
13346         break;
13347     }
13348 }
13349 
decode_opc_special_legacy(CPUMIPSState * env,DisasContext * ctx)13350 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
13351 {
13352     int rs, rt, rd;
13353     uint32_t op1;
13354 
13355     rs = (ctx->opcode >> 21) & 0x1f;
13356     rt = (ctx->opcode >> 16) & 0x1f;
13357     rd = (ctx->opcode >> 11) & 0x1f;
13358 
13359     op1 = MASK_SPECIAL(ctx->opcode);
13360     switch (op1) {
13361     case OPC_MOVN:         /* Conditional move */
13362     case OPC_MOVZ:
13363         check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 |
13364                    INSN_LOONGSON2E | INSN_LOONGSON2F);
13365         gen_cond_move(ctx, op1, rd, rs, rt);
13366         break;
13367     case OPC_MFHI:          /* Move from HI/LO */
13368     case OPC_MFLO:
13369         gen_HILO(ctx, op1, rs & 3, rd);
13370         break;
13371     case OPC_MTHI:
13372     case OPC_MTLO:          /* Move to HI/LO */
13373         gen_HILO(ctx, op1, rd & 3, rs);
13374         break;
13375     case OPC_MOVCI:
13376         check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1);
13377         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
13378             check_cp1_enabled(ctx);
13379             gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
13380                       (ctx->opcode >> 16) & 1);
13381         } else {
13382             generate_exception_err(ctx, EXCP_CpU, 1);
13383         }
13384         break;
13385     case OPC_MULT:
13386     case OPC_MULTU:
13387         gen_muldiv(ctx, op1, rd & 3, rs, rt);
13388         break;
13389     case OPC_DIV:
13390     case OPC_DIVU:
13391         gen_muldiv(ctx, op1, 0, rs, rt);
13392         break;
13393 #if defined(TARGET_MIPS64)
13394     case OPC_DMULT:
13395     case OPC_DMULTU:
13396     case OPC_DDIV:
13397     case OPC_DDIVU:
13398         check_insn(ctx, ISA_MIPS3);
13399         check_mips_64(ctx);
13400         gen_muldiv(ctx, op1, 0, rs, rt);
13401         break;
13402 #endif
13403     case OPC_JR:
13404         gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
13405         break;
13406     case OPC_SPIM:
13407 #ifdef MIPS_STRICT_STANDARD
13408         MIPS_INVAL("SPIM");
13409         gen_reserved_instruction(ctx);
13410 #else
13411         /* Implemented as RI exception for now. */
13412         MIPS_INVAL("spim (unofficial)");
13413         gen_reserved_instruction(ctx);
13414 #endif
13415         break;
13416     default:            /* Invalid */
13417         MIPS_INVAL("special_legacy");
13418         gen_reserved_instruction(ctx);
13419         break;
13420     }
13421 }
13422 
decode_opc_special(CPUMIPSState * env,DisasContext * ctx)13423 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
13424 {
13425     int rs, rt, rd, sa;
13426     uint32_t op1;
13427 
13428     rs = (ctx->opcode >> 21) & 0x1f;
13429     rt = (ctx->opcode >> 16) & 0x1f;
13430     rd = (ctx->opcode >> 11) & 0x1f;
13431     sa = (ctx->opcode >> 6) & 0x1f;
13432 
13433     op1 = MASK_SPECIAL(ctx->opcode);
13434     switch (op1) {
13435     case OPC_SLL:          /* Shift with immediate */
13436         if (sa == 5 && rd == 0 &&
13437             rs == 0 && rt == 0) { /* PAUSE */
13438             if ((ctx->insn_flags & ISA_MIPS_R6) &&
13439                 (ctx->hflags & MIPS_HFLAG_BMASK)) {
13440                 gen_reserved_instruction(ctx);
13441                 break;
13442             }
13443         }
13444         /* Fallthrough */
13445     case OPC_SRA:
13446         gen_shift_imm(ctx, op1, rd, rt, sa);
13447         break;
13448     case OPC_SRL:
13449         switch ((ctx->opcode >> 21) & 0x1f) {
13450         case 1:
13451             /* rotr is decoded as srl on non-R2 CPUs */
13452             if (ctx->insn_flags & ISA_MIPS_R2) {
13453                 op1 = OPC_ROTR;
13454             }
13455             /* Fallthrough */
13456         case 0:
13457             gen_shift_imm(ctx, op1, rd, rt, sa);
13458             break;
13459         default:
13460             gen_reserved_instruction(ctx);
13461             break;
13462         }
13463         break;
13464     case OPC_ADD:
13465     case OPC_ADDU:
13466     case OPC_SUB:
13467     case OPC_SUBU:
13468         gen_arith(ctx, op1, rd, rs, rt);
13469         break;
13470     case OPC_SLLV:         /* Shifts */
13471     case OPC_SRAV:
13472         gen_shift(ctx, op1, rd, rs, rt);
13473         break;
13474     case OPC_SRLV:
13475         switch ((ctx->opcode >> 6) & 0x1f) {
13476         case 1:
13477             /* rotrv is decoded as srlv on non-R2 CPUs */
13478             if (ctx->insn_flags & ISA_MIPS_R2) {
13479                 op1 = OPC_ROTRV;
13480             }
13481             /* Fallthrough */
13482         case 0:
13483             gen_shift(ctx, op1, rd, rs, rt);
13484             break;
13485         default:
13486             gen_reserved_instruction(ctx);
13487             break;
13488         }
13489         break;
13490     case OPC_SLT:          /* Set on less than */
13491     case OPC_SLTU:
13492         gen_slt(ctx, op1, rd, rs, rt);
13493         break;
13494     case OPC_AND:          /* Logic*/
13495     case OPC_OR:
13496     case OPC_NOR:
13497     case OPC_XOR:
13498         gen_logic(ctx, op1, rd, rs, rt);
13499         break;
13500     case OPC_JALR:
13501         gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
13502         break;
13503     case OPC_TGE: /* Traps */
13504     case OPC_TGEU:
13505     case OPC_TLT:
13506     case OPC_TLTU:
13507     case OPC_TEQ:
13508     case OPC_TNE:
13509         check_insn(ctx, ISA_MIPS2);
13510         gen_trap(ctx, op1, rs, rt, -1, extract32(ctx->opcode, 6, 10));
13511         break;
13512     case OPC_PMON:
13513         /* Pmon entry point, also R4010 selsl */
13514 #ifdef MIPS_STRICT_STANDARD
13515         MIPS_INVAL("PMON / selsl");
13516         gen_reserved_instruction(ctx);
13517 #else
13518         gen_helper_pmon(tcg_env, tcg_constant_i32(sa));
13519 #endif
13520         break;
13521     case OPC_SYSCALL:
13522         generate_exception_end(ctx, EXCP_SYSCALL);
13523         break;
13524     case OPC_BREAK:
13525         generate_exception_break(ctx, extract32(ctx->opcode, 6, 20));
13526         break;
13527     case OPC_SYNC:
13528         check_insn(ctx, ISA_MIPS2);
13529         gen_sync(extract32(ctx->opcode, 6, 5));
13530         break;
13531 
13532 #if defined(TARGET_MIPS64)
13533         /* MIPS64 specific opcodes */
13534     case OPC_DSLL:
13535     case OPC_DSRA:
13536     case OPC_DSLL32:
13537     case OPC_DSRA32:
13538         check_insn(ctx, ISA_MIPS3);
13539         check_mips_64(ctx);
13540         gen_shift_imm(ctx, op1, rd, rt, sa);
13541         break;
13542     case OPC_DSRL:
13543         switch ((ctx->opcode >> 21) & 0x1f) {
13544         case 1:
13545             /* drotr is decoded as dsrl on non-R2 CPUs */
13546             if (ctx->insn_flags & ISA_MIPS_R2) {
13547                 op1 = OPC_DROTR;
13548             }
13549             /* Fallthrough */
13550         case 0:
13551             check_insn(ctx, ISA_MIPS3);
13552             check_mips_64(ctx);
13553             gen_shift_imm(ctx, op1, rd, rt, sa);
13554             break;
13555         default:
13556             gen_reserved_instruction(ctx);
13557             break;
13558         }
13559         break;
13560     case OPC_DSRL32:
13561         switch ((ctx->opcode >> 21) & 0x1f) {
13562         case 1:
13563             /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
13564             if (ctx->insn_flags & ISA_MIPS_R2) {
13565                 op1 = OPC_DROTR32;
13566             }
13567             /* Fallthrough */
13568         case 0:
13569             check_insn(ctx, ISA_MIPS3);
13570             check_mips_64(ctx);
13571             gen_shift_imm(ctx, op1, rd, rt, sa);
13572             break;
13573         default:
13574             gen_reserved_instruction(ctx);
13575             break;
13576         }
13577         break;
13578     case OPC_DADD:
13579     case OPC_DADDU:
13580     case OPC_DSUB:
13581     case OPC_DSUBU:
13582         check_insn(ctx, ISA_MIPS3);
13583         check_mips_64(ctx);
13584         gen_arith(ctx, op1, rd, rs, rt);
13585         break;
13586     case OPC_DSLLV:
13587     case OPC_DSRAV:
13588         check_insn(ctx, ISA_MIPS3);
13589         check_mips_64(ctx);
13590         gen_shift(ctx, op1, rd, rs, rt);
13591         break;
13592     case OPC_DSRLV:
13593         switch ((ctx->opcode >> 6) & 0x1f) {
13594         case 1:
13595             /* drotrv is decoded as dsrlv on non-R2 CPUs */
13596             if (ctx->insn_flags & ISA_MIPS_R2) {
13597                 op1 = OPC_DROTRV;
13598             }
13599             /* Fallthrough */
13600         case 0:
13601             check_insn(ctx, ISA_MIPS3);
13602             check_mips_64(ctx);
13603             gen_shift(ctx, op1, rd, rs, rt);
13604             break;
13605         default:
13606             gen_reserved_instruction(ctx);
13607             break;
13608         }
13609         break;
13610 #endif
13611     default:
13612         if (ctx->insn_flags & ISA_MIPS_R6) {
13613             decode_opc_special_r6(env, ctx);
13614         } else if (ctx->insn_flags & INSN_R5900) {
13615             decode_opc_special_tx79(env, ctx);
13616         } else {
13617             decode_opc_special_legacy(env, ctx);
13618         }
13619     }
13620 }
13621 
13622 
decode_opc_special2_legacy(CPUMIPSState * env,DisasContext * ctx)13623 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
13624 {
13625     int rs, rt, rd;
13626     uint32_t op1;
13627 
13628     rs = (ctx->opcode >> 21) & 0x1f;
13629     rt = (ctx->opcode >> 16) & 0x1f;
13630     rd = (ctx->opcode >> 11) & 0x1f;
13631 
13632     op1 = MASK_SPECIAL2(ctx->opcode);
13633     switch (op1) {
13634     case OPC_MADD: /* Multiply and add/sub */
13635     case OPC_MADDU:
13636     case OPC_MSUB:
13637     case OPC_MSUBU:
13638         check_insn(ctx, ISA_MIPS_R1);
13639         gen_muldiv(ctx, op1, rd & 3, rs, rt);
13640         break;
13641     case OPC_MUL:
13642         gen_arith(ctx, op1, rd, rs, rt);
13643         break;
13644     case OPC_DIV_G_2F:
13645     case OPC_DIVU_G_2F:
13646     case OPC_MULT_G_2F:
13647     case OPC_MULTU_G_2F:
13648     case OPC_MOD_G_2F:
13649     case OPC_MODU_G_2F:
13650         check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT);
13651         gen_loongson_integer(ctx, op1, rd, rs, rt);
13652         break;
13653     case OPC_CLO:
13654     case OPC_CLZ:
13655         check_insn(ctx, ISA_MIPS_R1);
13656         gen_cl(ctx, op1, rd, rs);
13657         break;
13658     case OPC_SDBBP:
13659         if (is_uhi(ctx, extract32(ctx->opcode, 6, 20))) {
13660             ctx->base.is_jmp = DISAS_SEMIHOST;
13661         } else {
13662             /*
13663              * XXX: not clear which exception should be raised
13664              *      when in debug mode...
13665              */
13666             check_insn(ctx, ISA_MIPS_R1);
13667             generate_exception_end(ctx, EXCP_DBp);
13668         }
13669         break;
13670 #if defined(TARGET_MIPS64)
13671     case OPC_DCLO:
13672     case OPC_DCLZ:
13673         check_insn(ctx, ISA_MIPS_R1);
13674         check_mips_64(ctx);
13675         gen_cl(ctx, op1, rd, rs);
13676         break;
13677     case OPC_DMULT_G_2F:
13678     case OPC_DMULTU_G_2F:
13679     case OPC_DDIV_G_2F:
13680     case OPC_DDIVU_G_2F:
13681     case OPC_DMOD_G_2F:
13682     case OPC_DMODU_G_2F:
13683         check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT);
13684         gen_loongson_integer(ctx, op1, rd, rs, rt);
13685         break;
13686 #endif
13687     default:            /* Invalid */
13688         MIPS_INVAL("special2_legacy");
13689         gen_reserved_instruction(ctx);
13690         break;
13691     }
13692 }
13693 
decode_opc_special3_r6(CPUMIPSState * env,DisasContext * ctx)13694 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
13695 {
13696     int rs, rt, rd, sa;
13697     uint32_t op1, op2;
13698     int16_t imm;
13699 
13700     rs = (ctx->opcode >> 21) & 0x1f;
13701     rt = (ctx->opcode >> 16) & 0x1f;
13702     rd = (ctx->opcode >> 11) & 0x1f;
13703     sa = (ctx->opcode >> 6) & 0x1f;
13704     imm = (int16_t)ctx->opcode >> 7;
13705 
13706     op1 = MASK_SPECIAL3(ctx->opcode);
13707     switch (op1) {
13708     case R6_OPC_PREF:
13709         if (rt >= 24) {
13710             /* hint codes 24-31 are reserved and signal RI */
13711             gen_reserved_instruction(ctx);
13712         }
13713         /* Treat as NOP. */
13714         break;
13715     case R6_OPC_CACHE:
13716         check_cp0_enabled(ctx);
13717         if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
13718             gen_cache_operation(ctx, rt, rs, imm);
13719         }
13720         break;
13721     case R6_OPC_SC:
13722         gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
13723         break;
13724     case R6_OPC_LL:
13725         gen_ld(ctx, op1, rt, rs, imm);
13726         break;
13727     case OPC_BSHFL:
13728         {
13729             if (rd == 0) {
13730                 /* Treat as NOP. */
13731                 break;
13732             }
13733             op2 = MASK_BSHFL(ctx->opcode);
13734             switch (op2) {
13735             case OPC_ALIGN:
13736             case OPC_ALIGN_1:
13737             case OPC_ALIGN_2:
13738             case OPC_ALIGN_3:
13739                 gen_align(ctx, 32, rd, rs, rt, sa & 3);
13740                 break;
13741             case OPC_BITSWAP:
13742                 gen_bitswap(ctx, op2, rd, rt);
13743                 break;
13744             }
13745         }
13746         break;
13747 #ifndef CONFIG_USER_ONLY
13748     case OPC_GINV:
13749         if (unlikely(ctx->gi <= 1)) {
13750             gen_reserved_instruction(ctx);
13751         }
13752         check_cp0_enabled(ctx);
13753         switch ((ctx->opcode >> 6) & 3) {
13754         case 0:    /* GINVI */
13755             /* Treat as NOP. */
13756             break;
13757         case 2:    /* GINVT */
13758             gen_helper_0e1i(ginvt, cpu_gpr[rs], extract32(ctx->opcode, 8, 2));
13759             break;
13760         default:
13761             gen_reserved_instruction(ctx);
13762             break;
13763         }
13764         break;
13765 #endif
13766 #if defined(TARGET_MIPS64)
13767     case R6_OPC_SCD:
13768         gen_st_cond(ctx, rt, rs, imm, MO_TEUQ, false);
13769         break;
13770     case R6_OPC_LLD:
13771         gen_ld(ctx, op1, rt, rs, imm);
13772         break;
13773     case OPC_DBSHFL:
13774         check_mips_64(ctx);
13775         {
13776             if (rd == 0) {
13777                 /* Treat as NOP. */
13778                 break;
13779             }
13780             op2 = MASK_DBSHFL(ctx->opcode);
13781             switch (op2) {
13782             case OPC_DALIGN:
13783             case OPC_DALIGN_1:
13784             case OPC_DALIGN_2:
13785             case OPC_DALIGN_3:
13786             case OPC_DALIGN_4:
13787             case OPC_DALIGN_5:
13788             case OPC_DALIGN_6:
13789             case OPC_DALIGN_7:
13790                 gen_align(ctx, 64, rd, rs, rt, sa & 7);
13791                 break;
13792             case OPC_DBITSWAP:
13793                 gen_bitswap(ctx, op2, rd, rt);
13794                 break;
13795             }
13796 
13797         }
13798         break;
13799 #endif
13800     default:            /* Invalid */
13801         MIPS_INVAL("special3_r6");
13802         gen_reserved_instruction(ctx);
13803         break;
13804     }
13805 }
13806 
decode_opc_special3_legacy(CPUMIPSState * env,DisasContext * ctx)13807 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
13808 {
13809     int rs, rt, rd;
13810     uint32_t op1, op2;
13811 
13812     rs = (ctx->opcode >> 21) & 0x1f;
13813     rt = (ctx->opcode >> 16) & 0x1f;
13814     rd = (ctx->opcode >> 11) & 0x1f;
13815 
13816     op1 = MASK_SPECIAL3(ctx->opcode);
13817     switch (op1) {
13818     case OPC_DIV_G_2E:
13819     case OPC_DIVU_G_2E:
13820     case OPC_MOD_G_2E:
13821     case OPC_MODU_G_2E:
13822     case OPC_MULT_G_2E:
13823     case OPC_MULTU_G_2E:
13824         /*
13825          * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13826          * the same mask and op1.
13827          */
13828         if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
13829             op2 = MASK_ADDUH_QB(ctx->opcode);
13830             switch (op2) {
13831             case OPC_ADDUH_QB:
13832             case OPC_ADDUH_R_QB:
13833             case OPC_ADDQH_PH:
13834             case OPC_ADDQH_R_PH:
13835             case OPC_ADDQH_W:
13836             case OPC_ADDQH_R_W:
13837             case OPC_SUBUH_QB:
13838             case OPC_SUBUH_R_QB:
13839             case OPC_SUBQH_PH:
13840             case OPC_SUBQH_R_PH:
13841             case OPC_SUBQH_W:
13842             case OPC_SUBQH_R_W:
13843                 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
13844                 break;
13845             case OPC_MUL_PH:
13846             case OPC_MUL_S_PH:
13847             case OPC_MULQ_S_W:
13848             case OPC_MULQ_RS_W:
13849                 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
13850                 break;
13851             default:
13852                 MIPS_INVAL("MASK ADDUH.QB");
13853                 gen_reserved_instruction(ctx);
13854                 break;
13855             }
13856         } else if (ctx->insn_flags & INSN_LOONGSON2E) {
13857             gen_loongson_integer(ctx, op1, rd, rs, rt);
13858         } else {
13859             gen_reserved_instruction(ctx);
13860         }
13861         break;
13862     case OPC_LX_DSP:
13863         op2 = MASK_LX(ctx->opcode);
13864         switch (op2) {
13865 #if defined(TARGET_MIPS64)
13866         case OPC_LDX:
13867 #endif
13868         case OPC_LBUX:
13869         case OPC_LHX:
13870         case OPC_LWX:
13871             gen_mips_lx(ctx, op2, rd, rs, rt);
13872             break;
13873         default:            /* Invalid */
13874             MIPS_INVAL("MASK LX");
13875             gen_reserved_instruction(ctx);
13876             break;
13877         }
13878         break;
13879     case OPC_ABSQ_S_PH_DSP:
13880         op2 = MASK_ABSQ_S_PH(ctx->opcode);
13881         switch (op2) {
13882         case OPC_ABSQ_S_QB:
13883         case OPC_ABSQ_S_PH:
13884         case OPC_ABSQ_S_W:
13885         case OPC_PRECEQ_W_PHL:
13886         case OPC_PRECEQ_W_PHR:
13887         case OPC_PRECEQU_PH_QBL:
13888         case OPC_PRECEQU_PH_QBR:
13889         case OPC_PRECEQU_PH_QBLA:
13890         case OPC_PRECEQU_PH_QBRA:
13891         case OPC_PRECEU_PH_QBL:
13892         case OPC_PRECEU_PH_QBR:
13893         case OPC_PRECEU_PH_QBLA:
13894         case OPC_PRECEU_PH_QBRA:
13895             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
13896             break;
13897         case OPC_BITREV:
13898         case OPC_REPL_QB:
13899         case OPC_REPLV_QB:
13900         case OPC_REPL_PH:
13901         case OPC_REPLV_PH:
13902             gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
13903             break;
13904         default:
13905             MIPS_INVAL("MASK ABSQ_S.PH");
13906             gen_reserved_instruction(ctx);
13907             break;
13908         }
13909         break;
13910     case OPC_ADDU_QB_DSP:
13911         op2 = MASK_ADDU_QB(ctx->opcode);
13912         switch (op2) {
13913         case OPC_ADDQ_PH:
13914         case OPC_ADDQ_S_PH:
13915         case OPC_ADDQ_S_W:
13916         case OPC_ADDU_QB:
13917         case OPC_ADDU_S_QB:
13918         case OPC_ADDU_PH:
13919         case OPC_ADDU_S_PH:
13920         case OPC_SUBQ_PH:
13921         case OPC_SUBQ_S_PH:
13922         case OPC_SUBQ_S_W:
13923         case OPC_SUBU_QB:
13924         case OPC_SUBU_S_QB:
13925         case OPC_SUBU_PH:
13926         case OPC_SUBU_S_PH:
13927         case OPC_ADDSC:
13928         case OPC_ADDWC:
13929         case OPC_MODSUB:
13930         case OPC_RADDU_W_QB:
13931             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
13932             break;
13933         case OPC_MULEU_S_PH_QBL:
13934         case OPC_MULEU_S_PH_QBR:
13935         case OPC_MULQ_RS_PH:
13936         case OPC_MULEQ_S_W_PHL:
13937         case OPC_MULEQ_S_W_PHR:
13938         case OPC_MULQ_S_PH:
13939             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
13940             break;
13941         default:            /* Invalid */
13942             MIPS_INVAL("MASK ADDU.QB");
13943             gen_reserved_instruction(ctx);
13944             break;
13945 
13946         }
13947         break;
13948     case OPC_CMPU_EQ_QB_DSP:
13949         op2 = MASK_CMPU_EQ_QB(ctx->opcode);
13950         switch (op2) {
13951         case OPC_PRECR_SRA_PH_W:
13952         case OPC_PRECR_SRA_R_PH_W:
13953             gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
13954             break;
13955         case OPC_PRECR_QB_PH:
13956         case OPC_PRECRQ_QB_PH:
13957         case OPC_PRECRQ_PH_W:
13958         case OPC_PRECRQ_RS_PH_W:
13959         case OPC_PRECRQU_S_QB_PH:
13960             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
13961             break;
13962         case OPC_CMPU_EQ_QB:
13963         case OPC_CMPU_LT_QB:
13964         case OPC_CMPU_LE_QB:
13965         case OPC_CMP_EQ_PH:
13966         case OPC_CMP_LT_PH:
13967         case OPC_CMP_LE_PH:
13968             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
13969             break;
13970         case OPC_CMPGU_EQ_QB:
13971         case OPC_CMPGU_LT_QB:
13972         case OPC_CMPGU_LE_QB:
13973         case OPC_CMPGDU_EQ_QB:
13974         case OPC_CMPGDU_LT_QB:
13975         case OPC_CMPGDU_LE_QB:
13976         case OPC_PICK_QB:
13977         case OPC_PICK_PH:
13978         case OPC_PACKRL_PH:
13979             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
13980             break;
13981         default:            /* Invalid */
13982             MIPS_INVAL("MASK CMPU.EQ.QB");
13983             gen_reserved_instruction(ctx);
13984             break;
13985         }
13986         break;
13987     case OPC_SHLL_QB_DSP:
13988         gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
13989         break;
13990     case OPC_DPA_W_PH_DSP:
13991         op2 = MASK_DPA_W_PH(ctx->opcode);
13992         switch (op2) {
13993         case OPC_DPAU_H_QBL:
13994         case OPC_DPAU_H_QBR:
13995         case OPC_DPSU_H_QBL:
13996         case OPC_DPSU_H_QBR:
13997         case OPC_DPA_W_PH:
13998         case OPC_DPAX_W_PH:
13999         case OPC_DPAQ_S_W_PH:
14000         case OPC_DPAQX_S_W_PH:
14001         case OPC_DPAQX_SA_W_PH:
14002         case OPC_DPS_W_PH:
14003         case OPC_DPSX_W_PH:
14004         case OPC_DPSQ_S_W_PH:
14005         case OPC_DPSQX_S_W_PH:
14006         case OPC_DPSQX_SA_W_PH:
14007         case OPC_MULSAQ_S_W_PH:
14008         case OPC_DPAQ_SA_L_W:
14009         case OPC_DPSQ_SA_L_W:
14010         case OPC_MAQ_S_W_PHL:
14011         case OPC_MAQ_S_W_PHR:
14012         case OPC_MAQ_SA_W_PHL:
14013         case OPC_MAQ_SA_W_PHR:
14014         case OPC_MULSA_W_PH:
14015             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14016             break;
14017         default:            /* Invalid */
14018             MIPS_INVAL("MASK DPAW.PH");
14019             gen_reserved_instruction(ctx);
14020             break;
14021         }
14022         break;
14023     case OPC_INSV_DSP:
14024         op2 = MASK_INSV(ctx->opcode);
14025         switch (op2) {
14026         case OPC_INSV:
14027             check_dsp(ctx);
14028             {
14029                 TCGv t0, t1;
14030 
14031                 if (rt == 0) {
14032                     break;
14033                 }
14034 
14035                 t0 = tcg_temp_new();
14036                 t1 = tcg_temp_new();
14037 
14038                 gen_load_gpr(t0, rt);
14039                 gen_load_gpr(t1, rs);
14040 
14041                 gen_helper_insv(cpu_gpr[rt], tcg_env, t1, t0);
14042                 break;
14043             }
14044         default:            /* Invalid */
14045             MIPS_INVAL("MASK INSV");
14046             gen_reserved_instruction(ctx);
14047             break;
14048         }
14049         break;
14050     case OPC_APPEND_DSP:
14051         gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
14052         break;
14053     case OPC_EXTR_W_DSP:
14054         op2 = MASK_EXTR_W(ctx->opcode);
14055         switch (op2) {
14056         case OPC_EXTR_W:
14057         case OPC_EXTR_R_W:
14058         case OPC_EXTR_RS_W:
14059         case OPC_EXTR_S_H:
14060         case OPC_EXTRV_S_H:
14061         case OPC_EXTRV_W:
14062         case OPC_EXTRV_R_W:
14063         case OPC_EXTRV_RS_W:
14064         case OPC_EXTP:
14065         case OPC_EXTPV:
14066         case OPC_EXTPDP:
14067         case OPC_EXTPDPV:
14068             gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14069             break;
14070         case OPC_RDDSP:
14071             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14072             break;
14073         case OPC_SHILO:
14074         case OPC_SHILOV:
14075         case OPC_MTHLIP:
14076         case OPC_WRDSP:
14077             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14078             break;
14079         default:            /* Invalid */
14080             MIPS_INVAL("MASK EXTR.W");
14081             gen_reserved_instruction(ctx);
14082             break;
14083         }
14084         break;
14085 #if defined(TARGET_MIPS64)
14086     case OPC_DDIV_G_2E:
14087     case OPC_DDIVU_G_2E:
14088     case OPC_DMULT_G_2E:
14089     case OPC_DMULTU_G_2E:
14090     case OPC_DMOD_G_2E:
14091     case OPC_DMODU_G_2E:
14092         check_insn(ctx, INSN_LOONGSON2E);
14093         gen_loongson_integer(ctx, op1, rd, rs, rt);
14094         break;
14095     case OPC_ABSQ_S_QH_DSP:
14096         op2 = MASK_ABSQ_S_QH(ctx->opcode);
14097         switch (op2) {
14098         case OPC_PRECEQ_L_PWL:
14099         case OPC_PRECEQ_L_PWR:
14100         case OPC_PRECEQ_PW_QHL:
14101         case OPC_PRECEQ_PW_QHR:
14102         case OPC_PRECEQ_PW_QHLA:
14103         case OPC_PRECEQ_PW_QHRA:
14104         case OPC_PRECEQU_QH_OBL:
14105         case OPC_PRECEQU_QH_OBR:
14106         case OPC_PRECEQU_QH_OBLA:
14107         case OPC_PRECEQU_QH_OBRA:
14108         case OPC_PRECEU_QH_OBL:
14109         case OPC_PRECEU_QH_OBR:
14110         case OPC_PRECEU_QH_OBLA:
14111         case OPC_PRECEU_QH_OBRA:
14112         case OPC_ABSQ_S_OB:
14113         case OPC_ABSQ_S_PW:
14114         case OPC_ABSQ_S_QH:
14115             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14116             break;
14117         case OPC_REPL_OB:
14118         case OPC_REPL_PW:
14119         case OPC_REPL_QH:
14120         case OPC_REPLV_OB:
14121         case OPC_REPLV_PW:
14122         case OPC_REPLV_QH:
14123             gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
14124             break;
14125         default:            /* Invalid */
14126             MIPS_INVAL("MASK ABSQ_S.QH");
14127             gen_reserved_instruction(ctx);
14128             break;
14129         }
14130         break;
14131     case OPC_ADDU_OB_DSP:
14132         op2 = MASK_ADDU_OB(ctx->opcode);
14133         switch (op2) {
14134         case OPC_RADDU_L_OB:
14135         case OPC_SUBQ_PW:
14136         case OPC_SUBQ_S_PW:
14137         case OPC_SUBQ_QH:
14138         case OPC_SUBQ_S_QH:
14139         case OPC_SUBU_OB:
14140         case OPC_SUBU_S_OB:
14141         case OPC_SUBU_QH:
14142         case OPC_SUBU_S_QH:
14143         case OPC_SUBUH_OB:
14144         case OPC_SUBUH_R_OB:
14145         case OPC_ADDQ_PW:
14146         case OPC_ADDQ_S_PW:
14147         case OPC_ADDQ_QH:
14148         case OPC_ADDQ_S_QH:
14149         case OPC_ADDU_OB:
14150         case OPC_ADDU_S_OB:
14151         case OPC_ADDU_QH:
14152         case OPC_ADDU_S_QH:
14153         case OPC_ADDUH_OB:
14154         case OPC_ADDUH_R_OB:
14155             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14156             break;
14157         case OPC_MULEQ_S_PW_QHL:
14158         case OPC_MULEQ_S_PW_QHR:
14159         case OPC_MULEU_S_QH_OBL:
14160         case OPC_MULEU_S_QH_OBR:
14161         case OPC_MULQ_RS_QH:
14162             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14163             break;
14164         default:            /* Invalid */
14165             MIPS_INVAL("MASK ADDU.OB");
14166             gen_reserved_instruction(ctx);
14167             break;
14168         }
14169         break;
14170     case OPC_CMPU_EQ_OB_DSP:
14171         op2 = MASK_CMPU_EQ_OB(ctx->opcode);
14172         switch (op2) {
14173         case OPC_PRECR_SRA_QH_PW:
14174         case OPC_PRECR_SRA_R_QH_PW:
14175             /* Return value is rt. */
14176             gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14177             break;
14178         case OPC_PRECR_OB_QH:
14179         case OPC_PRECRQ_OB_QH:
14180         case OPC_PRECRQ_PW_L:
14181         case OPC_PRECRQ_QH_PW:
14182         case OPC_PRECRQ_RS_QH_PW:
14183         case OPC_PRECRQU_S_OB_QH:
14184             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14185             break;
14186         case OPC_CMPU_EQ_OB:
14187         case OPC_CMPU_LT_OB:
14188         case OPC_CMPU_LE_OB:
14189         case OPC_CMP_EQ_QH:
14190         case OPC_CMP_LT_QH:
14191         case OPC_CMP_LE_QH:
14192         case OPC_CMP_EQ_PW:
14193         case OPC_CMP_LT_PW:
14194         case OPC_CMP_LE_PW:
14195             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14196             break;
14197         case OPC_CMPGDU_EQ_OB:
14198         case OPC_CMPGDU_LT_OB:
14199         case OPC_CMPGDU_LE_OB:
14200         case OPC_CMPGU_EQ_OB:
14201         case OPC_CMPGU_LT_OB:
14202         case OPC_CMPGU_LE_OB:
14203         case OPC_PACKRL_PW:
14204         case OPC_PICK_OB:
14205         case OPC_PICK_PW:
14206         case OPC_PICK_QH:
14207             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14208             break;
14209         default:            /* Invalid */
14210             MIPS_INVAL("MASK CMPU_EQ.OB");
14211             gen_reserved_instruction(ctx);
14212             break;
14213         }
14214         break;
14215     case OPC_DAPPEND_DSP:
14216         gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
14217         break;
14218     case OPC_DEXTR_W_DSP:
14219         op2 = MASK_DEXTR_W(ctx->opcode);
14220         switch (op2) {
14221         case OPC_DEXTP:
14222         case OPC_DEXTPDP:
14223         case OPC_DEXTPDPV:
14224         case OPC_DEXTPV:
14225         case OPC_DEXTR_L:
14226         case OPC_DEXTR_R_L:
14227         case OPC_DEXTR_RS_L:
14228         case OPC_DEXTR_W:
14229         case OPC_DEXTR_R_W:
14230         case OPC_DEXTR_RS_W:
14231         case OPC_DEXTR_S_H:
14232         case OPC_DEXTRV_L:
14233         case OPC_DEXTRV_R_L:
14234         case OPC_DEXTRV_RS_L:
14235         case OPC_DEXTRV_S_H:
14236         case OPC_DEXTRV_W:
14237         case OPC_DEXTRV_R_W:
14238         case OPC_DEXTRV_RS_W:
14239             gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14240             break;
14241         case OPC_DMTHLIP:
14242         case OPC_DSHILO:
14243         case OPC_DSHILOV:
14244             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14245             break;
14246         default:            /* Invalid */
14247             MIPS_INVAL("MASK EXTR.W");
14248             gen_reserved_instruction(ctx);
14249             break;
14250         }
14251         break;
14252     case OPC_DPAQ_W_QH_DSP:
14253         op2 = MASK_DPAQ_W_QH(ctx->opcode);
14254         switch (op2) {
14255         case OPC_DPAU_H_OBL:
14256         case OPC_DPAU_H_OBR:
14257         case OPC_DPSU_H_OBL:
14258         case OPC_DPSU_H_OBR:
14259         case OPC_DPA_W_QH:
14260         case OPC_DPAQ_S_W_QH:
14261         case OPC_DPS_W_QH:
14262         case OPC_DPSQ_S_W_QH:
14263         case OPC_MULSAQ_S_W_QH:
14264         case OPC_DPAQ_SA_L_PW:
14265         case OPC_DPSQ_SA_L_PW:
14266         case OPC_MULSAQ_S_L_PW:
14267             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14268             break;
14269         case OPC_MAQ_S_W_QHLL:
14270         case OPC_MAQ_S_W_QHLR:
14271         case OPC_MAQ_S_W_QHRL:
14272         case OPC_MAQ_S_W_QHRR:
14273         case OPC_MAQ_SA_W_QHLL:
14274         case OPC_MAQ_SA_W_QHLR:
14275         case OPC_MAQ_SA_W_QHRL:
14276         case OPC_MAQ_SA_W_QHRR:
14277         case OPC_MAQ_S_L_PWL:
14278         case OPC_MAQ_S_L_PWR:
14279         case OPC_DMADD:
14280         case OPC_DMADDU:
14281         case OPC_DMSUB:
14282         case OPC_DMSUBU:
14283             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14284             break;
14285         default:            /* Invalid */
14286             MIPS_INVAL("MASK DPAQ.W.QH");
14287             gen_reserved_instruction(ctx);
14288             break;
14289         }
14290         break;
14291     case OPC_DINSV_DSP:
14292         op2 = MASK_INSV(ctx->opcode);
14293         switch (op2) {
14294         case OPC_DINSV:
14295         {
14296             TCGv t0, t1;
14297 
14298             check_dsp(ctx);
14299 
14300             if (rt == 0) {
14301                 break;
14302             }
14303 
14304             t0 = tcg_temp_new();
14305             t1 = tcg_temp_new();
14306 
14307             gen_load_gpr(t0, rt);
14308             gen_load_gpr(t1, rs);
14309 
14310             gen_helper_dinsv(cpu_gpr[rt], tcg_env, t1, t0);
14311             break;
14312         }
14313         default:            /* Invalid */
14314             MIPS_INVAL("MASK DINSV");
14315             gen_reserved_instruction(ctx);
14316             break;
14317         }
14318         break;
14319     case OPC_SHLL_OB_DSP:
14320         gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14321         break;
14322 #endif
14323     default:            /* Invalid */
14324         MIPS_INVAL("special3_legacy");
14325         gen_reserved_instruction(ctx);
14326         break;
14327     }
14328 }
14329 
14330 
14331 #if defined(TARGET_MIPS64)
14332 
decode_mmi(CPUMIPSState * env,DisasContext * ctx)14333 static void decode_mmi(CPUMIPSState *env, DisasContext *ctx)
14334 {
14335     uint32_t opc = MASK_MMI(ctx->opcode);
14336     int rs = extract32(ctx->opcode, 21, 5);
14337     int rt = extract32(ctx->opcode, 16, 5);
14338     int rd = extract32(ctx->opcode, 11, 5);
14339 
14340     switch (opc) {
14341     case MMI_OPC_MULT1:
14342     case MMI_OPC_MULTU1:
14343     case MMI_OPC_MADD:
14344     case MMI_OPC_MADDU:
14345     case MMI_OPC_MADD1:
14346     case MMI_OPC_MADDU1:
14347         gen_mul_txx9(ctx, opc, rd, rs, rt);
14348         break;
14349     case MMI_OPC_DIV1:
14350     case MMI_OPC_DIVU1:
14351         gen_div1_tx79(ctx, opc, rs, rt);
14352         break;
14353     default:
14354         MIPS_INVAL("TX79 MMI class");
14355         gen_reserved_instruction(ctx);
14356         break;
14357     }
14358 }
14359 
gen_mmi_sq(DisasContext * ctx,int base,int rt,int offset)14360 static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset)
14361 {
14362     gen_reserved_instruction(ctx);    /* TODO: MMI_OPC_SQ */
14363 }
14364 
14365 /*
14366  * The TX79-specific instruction Store Quadword
14367  *
14368  * +--------+-------+-------+------------------------+
14369  * | 011111 |  base |   rt  |           offset       | SQ
14370  * +--------+-------+-------+------------------------+
14371  *      6       5       5                 16
14372  *
14373  * has the same opcode as the Read Hardware Register instruction
14374  *
14375  * +--------+-------+-------+-------+-------+--------+
14376  * | 011111 | 00000 |   rt  |   rd  | 00000 | 111011 | RDHWR
14377  * +--------+-------+-------+-------+-------+--------+
14378  *      6       5       5       5       5        6
14379  *
14380  * that is required, trapped and emulated by the Linux kernel. However, all
14381  * RDHWR encodings yield address error exceptions on the TX79 since the SQ
14382  * offset is odd. Therefore all valid SQ instructions can execute normally.
14383  * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
14384  * between SQ and RDHWR, as the Linux kernel does.
14385  */
decode_mmi_sq(CPUMIPSState * env,DisasContext * ctx)14386 static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx)
14387 {
14388     int base = extract32(ctx->opcode, 21, 5);
14389     int rt = extract32(ctx->opcode, 16, 5);
14390     int offset = extract32(ctx->opcode, 0, 16);
14391 
14392 #ifdef CONFIG_USER_ONLY
14393     uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
14394     uint32_t op2 = extract32(ctx->opcode, 6, 5);
14395 
14396     if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
14397         int rd = extract32(ctx->opcode, 11, 5);
14398 
14399         gen_rdhwr(ctx, rt, rd, 0);
14400         return;
14401     }
14402 #endif
14403 
14404     gen_mmi_sq(ctx, base, rt, offset);
14405 }
14406 
14407 #endif
14408 
decode_opc_special3(CPUMIPSState * env,DisasContext * ctx)14409 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
14410 {
14411     int rs, rt, rd, sa;
14412     uint32_t op1, op2;
14413     int16_t imm;
14414 
14415     rs = (ctx->opcode >> 21) & 0x1f;
14416     rt = (ctx->opcode >> 16) & 0x1f;
14417     rd = (ctx->opcode >> 11) & 0x1f;
14418     sa = (ctx->opcode >> 6) & 0x1f;
14419     imm = sextract32(ctx->opcode, 7, 9);
14420 
14421     op1 = MASK_SPECIAL3(ctx->opcode);
14422 
14423     /*
14424      * EVA loads and stores overlap Loongson 2E instructions decoded by
14425      * decode_opc_special3_legacy(), so be careful to allow their decoding when
14426      * EVA is absent.
14427      */
14428     if (ctx->eva) {
14429         switch (op1) {
14430         case OPC_LWLE:
14431         case OPC_LWRE:
14432         case OPC_LBUE:
14433         case OPC_LHUE:
14434         case OPC_LBE:
14435         case OPC_LHE:
14436         case OPC_LLE:
14437         case OPC_LWE:
14438             check_cp0_enabled(ctx);
14439             gen_ld(ctx, op1, rt, rs, imm);
14440             return;
14441         case OPC_SWLE:
14442         case OPC_SWRE:
14443         case OPC_SBE:
14444         case OPC_SHE:
14445         case OPC_SWE:
14446             check_cp0_enabled(ctx);
14447             gen_st(ctx, op1, rt, rs, imm);
14448             return;
14449         case OPC_SCE:
14450             check_cp0_enabled(ctx);
14451             gen_st_cond(ctx, rt, rs, imm, MO_TESL, true);
14452             return;
14453         case OPC_CACHEE:
14454             check_eva(ctx);
14455             check_cp0_enabled(ctx);
14456             if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
14457                 gen_cache_operation(ctx, rt, rs, imm);
14458             }
14459             return;
14460         case OPC_PREFE:
14461             check_cp0_enabled(ctx);
14462             /* Treat as NOP. */
14463             return;
14464         }
14465     }
14466 
14467     switch (op1) {
14468     case OPC_EXT:
14469     case OPC_INS:
14470         check_insn(ctx, ISA_MIPS_R2);
14471         gen_bitops(ctx, op1, rt, rs, sa, rd);
14472         break;
14473     case OPC_BSHFL:
14474         op2 = MASK_BSHFL(ctx->opcode);
14475         switch (op2) {
14476         case OPC_ALIGN:
14477         case OPC_ALIGN_1:
14478         case OPC_ALIGN_2:
14479         case OPC_ALIGN_3:
14480         case OPC_BITSWAP:
14481             check_insn(ctx, ISA_MIPS_R6);
14482             decode_opc_special3_r6(env, ctx);
14483             break;
14484         default:
14485             check_insn(ctx, ISA_MIPS_R2);
14486             gen_bshfl(ctx, op2, rt, rd);
14487             break;
14488         }
14489         break;
14490 #if defined(TARGET_MIPS64)
14491     case OPC_DEXTM:
14492     case OPC_DEXTU:
14493     case OPC_DEXT:
14494     case OPC_DINSM:
14495     case OPC_DINSU:
14496     case OPC_DINS:
14497         check_insn(ctx, ISA_MIPS_R2);
14498         check_mips_64(ctx);
14499         gen_bitops(ctx, op1, rt, rs, sa, rd);
14500         break;
14501     case OPC_DBSHFL:
14502         op2 = MASK_DBSHFL(ctx->opcode);
14503         switch (op2) {
14504         case OPC_DALIGN:
14505         case OPC_DALIGN_1:
14506         case OPC_DALIGN_2:
14507         case OPC_DALIGN_3:
14508         case OPC_DALIGN_4:
14509         case OPC_DALIGN_5:
14510         case OPC_DALIGN_6:
14511         case OPC_DALIGN_7:
14512         case OPC_DBITSWAP:
14513             check_insn(ctx, ISA_MIPS_R6);
14514             decode_opc_special3_r6(env, ctx);
14515             break;
14516         default:
14517             check_insn(ctx, ISA_MIPS_R2);
14518             check_mips_64(ctx);
14519             op2 = MASK_DBSHFL(ctx->opcode);
14520             gen_bshfl(ctx, op2, rt, rd);
14521             break;
14522         }
14523         break;
14524 #endif
14525     case OPC_RDHWR:
14526         gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
14527         break;
14528     case OPC_FORK:
14529         check_mt(ctx);
14530         {
14531             TCGv t0 = tcg_temp_new();
14532             TCGv t1 = tcg_temp_new();
14533 
14534             gen_load_gpr(t0, rt);
14535             gen_load_gpr(t1, rs);
14536             gen_helper_fork(t0, t1);
14537         }
14538         break;
14539     case OPC_YIELD:
14540         check_mt(ctx);
14541         {
14542             TCGv t0 = tcg_temp_new();
14543 
14544             gen_load_gpr(t0, rs);
14545             gen_helper_yield(t0, tcg_env, t0);
14546             gen_store_gpr(t0, rd);
14547         }
14548         break;
14549     default:
14550         if (ctx->insn_flags & ISA_MIPS_R6) {
14551             decode_opc_special3_r6(env, ctx);
14552         } else {
14553             decode_opc_special3_legacy(env, ctx);
14554         }
14555     }
14556 }
14557 
decode_opc_legacy(CPUMIPSState * env,DisasContext * ctx)14558 static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx)
14559 {
14560     int32_t offset;
14561     int rs, rt, rd, sa;
14562     uint32_t op, op1;
14563     int16_t imm;
14564 
14565     op = MASK_OP_MAJOR(ctx->opcode);
14566     rs = (ctx->opcode >> 21) & 0x1f;
14567     rt = (ctx->opcode >> 16) & 0x1f;
14568     rd = (ctx->opcode >> 11) & 0x1f;
14569     sa = (ctx->opcode >> 6) & 0x1f;
14570     imm = (int16_t)ctx->opcode;
14571     switch (op) {
14572     case OPC_SPECIAL:
14573         decode_opc_special(env, ctx);
14574         break;
14575     case OPC_SPECIAL2:
14576 #if defined(TARGET_MIPS64)
14577         if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
14578             decode_mmi(env, ctx);
14579             break;
14580         }
14581 #endif
14582         if (TARGET_LONG_BITS == 32 && (ctx->insn_flags & ASE_MXU)) {
14583             if (decode_ase_mxu(ctx, ctx->opcode)) {
14584                 break;
14585             }
14586         }
14587         decode_opc_special2_legacy(env, ctx);
14588         break;
14589     case OPC_SPECIAL3:
14590 #if defined(TARGET_MIPS64)
14591         if (ctx->insn_flags & INSN_R5900) {
14592             decode_mmi_sq(env, ctx);    /* MMI_OPC_SQ */
14593         } else {
14594             decode_opc_special3(env, ctx);
14595         }
14596 #else
14597         decode_opc_special3(env, ctx);
14598 #endif
14599         break;
14600     case OPC_REGIMM:
14601         op1 = MASK_REGIMM(ctx->opcode);
14602         switch (op1) {
14603         case OPC_BLTZL: /* REGIMM branches */
14604         case OPC_BGEZL:
14605         case OPC_BLTZALL:
14606         case OPC_BGEZALL:
14607             check_insn(ctx, ISA_MIPS2);
14608             check_insn_opc_removed(ctx, ISA_MIPS_R6);
14609             /* Fallthrough */
14610         case OPC_BLTZ:
14611         case OPC_BGEZ:
14612             gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
14613             break;
14614         case OPC_BLTZAL:
14615         case OPC_BGEZAL:
14616             if (ctx->insn_flags & ISA_MIPS_R6) {
14617                 if (rs == 0) {
14618                     /* OPC_NAL, OPC_BAL */
14619                     gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
14620                 } else {
14621                     gen_reserved_instruction(ctx);
14622                 }
14623             } else {
14624                 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
14625             }
14626             break;
14627         case OPC_TGEI: /* REGIMM traps */
14628         case OPC_TGEIU:
14629         case OPC_TLTI:
14630         case OPC_TLTIU:
14631         case OPC_TEQI:
14632         case OPC_TNEI:
14633             check_insn(ctx, ISA_MIPS2);
14634             check_insn_opc_removed(ctx, ISA_MIPS_R6);
14635             gen_trap(ctx, op1, rs, -1, imm, 0);
14636             break;
14637         case OPC_SIGRIE:
14638             check_insn(ctx, ISA_MIPS_R6);
14639             gen_reserved_instruction(ctx);
14640             break;
14641         case OPC_SYNCI:
14642             check_insn(ctx, ISA_MIPS_R2);
14643             /*
14644              * Break the TB to be able to sync copied instructions
14645              * immediately.
14646              */
14647             ctx->base.is_jmp = DISAS_STOP;
14648             break;
14649         case OPC_BPOSGE32:    /* MIPS DSP branch */
14650 #if defined(TARGET_MIPS64)
14651         case OPC_BPOSGE64:
14652 #endif
14653             check_dsp(ctx);
14654             gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
14655             break;
14656 #if defined(TARGET_MIPS64)
14657         case OPC_DAHI:
14658             check_insn(ctx, ISA_MIPS_R6);
14659             check_mips_64(ctx);
14660             if (rs != 0) {
14661                 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
14662             }
14663             break;
14664         case OPC_DATI:
14665             check_insn(ctx, ISA_MIPS_R6);
14666             check_mips_64(ctx);
14667             if (rs != 0) {
14668                 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
14669             }
14670             break;
14671 #endif
14672         default:            /* Invalid */
14673             MIPS_INVAL("regimm");
14674             gen_reserved_instruction(ctx);
14675             break;
14676         }
14677         break;
14678     case OPC_CP0:
14679         check_cp0_enabled(ctx);
14680         op1 = MASK_CP0(ctx->opcode);
14681         switch (op1) {
14682         case OPC_MFC0:
14683         case OPC_MTC0:
14684         case OPC_MFTR:
14685         case OPC_MTTR:
14686         case OPC_MFHC0:
14687         case OPC_MTHC0:
14688 #if defined(TARGET_MIPS64)
14689         case OPC_DMFC0:
14690         case OPC_DMTC0:
14691 #endif
14692 #ifndef CONFIG_USER_ONLY
14693             gen_cp0(env, ctx, op1, rt, rd);
14694 #endif /* !CONFIG_USER_ONLY */
14695             break;
14696         case OPC_C0:
14697         case OPC_C0_1:
14698         case OPC_C0_2:
14699         case OPC_C0_3:
14700         case OPC_C0_4:
14701         case OPC_C0_5:
14702         case OPC_C0_6:
14703         case OPC_C0_7:
14704         case OPC_C0_8:
14705         case OPC_C0_9:
14706         case OPC_C0_A:
14707         case OPC_C0_B:
14708         case OPC_C0_C:
14709         case OPC_C0_D:
14710         case OPC_C0_E:
14711         case OPC_C0_F:
14712 #ifndef CONFIG_USER_ONLY
14713             gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
14714 #endif /* !CONFIG_USER_ONLY */
14715             break;
14716         case OPC_MFMC0:
14717 #ifndef CONFIG_USER_ONLY
14718             {
14719                 uint32_t op2;
14720                 TCGv t0 = tcg_temp_new();
14721 
14722                 op2 = MASK_MFMC0(ctx->opcode);
14723                 switch (op2) {
14724                 case OPC_DMT:
14725                     check_cp0_mt(ctx);
14726                     gen_helper_dmt(t0);
14727                     gen_store_gpr(t0, rt);
14728                     break;
14729                 case OPC_EMT:
14730                     check_cp0_mt(ctx);
14731                     gen_helper_emt(t0);
14732                     gen_store_gpr(t0, rt);
14733                     break;
14734                 case OPC_DVPE:
14735                     check_cp0_mt(ctx);
14736                     gen_helper_dvpe(t0, tcg_env);
14737                     gen_store_gpr(t0, rt);
14738                     break;
14739                 case OPC_EVPE:
14740                     check_cp0_mt(ctx);
14741                     gen_helper_evpe(t0, tcg_env);
14742                     gen_store_gpr(t0, rt);
14743                     break;
14744                 case OPC_DVP:
14745                     check_insn(ctx, ISA_MIPS_R6);
14746                     if (ctx->vp) {
14747                         gen_helper_dvp(t0, tcg_env);
14748                         gen_store_gpr(t0, rt);
14749                     }
14750                     break;
14751                 case OPC_EVP:
14752                     check_insn(ctx, ISA_MIPS_R6);
14753                     if (ctx->vp) {
14754                         gen_helper_evp(t0, tcg_env);
14755                         gen_store_gpr(t0, rt);
14756                     }
14757                     break;
14758                 case OPC_DI:
14759                     check_insn(ctx, ISA_MIPS_R2);
14760                     save_cpu_state(ctx, 1);
14761                     gen_helper_di(t0, tcg_env);
14762                     gen_store_gpr(t0, rt);
14763                     /*
14764                      * Stop translation as we may have switched
14765                      * the execution mode.
14766                      */
14767                     ctx->base.is_jmp = DISAS_STOP;
14768                     break;
14769                 case OPC_EI:
14770                     check_insn(ctx, ISA_MIPS_R2);
14771                     save_cpu_state(ctx, 1);
14772                     gen_helper_ei(t0, tcg_env);
14773                     gen_store_gpr(t0, rt);
14774                     /*
14775                      * DISAS_STOP isn't sufficient, we need to ensure we break
14776                      * out of translated code to check for pending interrupts.
14777                      */
14778                     gen_save_pc(ctx->base.pc_next + 4);
14779                     ctx->base.is_jmp = DISAS_EXIT;
14780                     break;
14781                 default:            /* Invalid */
14782                     MIPS_INVAL("mfmc0");
14783                     gen_reserved_instruction(ctx);
14784                     break;
14785                 }
14786             }
14787 #endif /* !CONFIG_USER_ONLY */
14788             break;
14789         case OPC_RDPGPR:
14790             check_insn(ctx, ISA_MIPS_R2);
14791             gen_load_srsgpr(rt, rd);
14792             break;
14793         case OPC_WRPGPR:
14794             check_insn(ctx, ISA_MIPS_R2);
14795             gen_store_srsgpr(rt, rd);
14796             break;
14797         default:
14798             MIPS_INVAL("cp0");
14799             gen_reserved_instruction(ctx);
14800             break;
14801         }
14802         break;
14803     case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
14804         if (ctx->insn_flags & ISA_MIPS_R6) {
14805             /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
14806             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
14807         } else {
14808             /* OPC_ADDI */
14809             /* Arithmetic with immediate opcode */
14810             gen_arith_imm(ctx, op, rt, rs, imm);
14811         }
14812         break;
14813     case OPC_ADDIU:
14814          gen_arith_imm(ctx, op, rt, rs, imm);
14815          break;
14816     case OPC_SLTI: /* Set on less than with immediate opcode */
14817     case OPC_SLTIU:
14818          gen_slt_imm(ctx, op, rt, rs, imm);
14819          break;
14820     case OPC_ANDI: /* Arithmetic with immediate opcode */
14821     case OPC_LUI: /* OPC_AUI */
14822     case OPC_ORI:
14823     case OPC_XORI:
14824          gen_logic_imm(ctx, op, rt, rs, imm);
14825          break;
14826     case OPC_J: /* Jump */
14827     case OPC_JAL:
14828          offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
14829          gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
14830          break;
14831     /* Branch */
14832     case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
14833         if (ctx->insn_flags & ISA_MIPS_R6) {
14834             if (rt == 0) {
14835                 gen_reserved_instruction(ctx);
14836                 break;
14837             }
14838             /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
14839             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
14840         } else {
14841             /* OPC_BLEZL */
14842             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
14843         }
14844         break;
14845     case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
14846         if (ctx->insn_flags & ISA_MIPS_R6) {
14847             if (rt == 0) {
14848                 gen_reserved_instruction(ctx);
14849                 break;
14850             }
14851             /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
14852             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
14853         } else {
14854             /* OPC_BGTZL */
14855             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
14856         }
14857         break;
14858     case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
14859         if (rt == 0) {
14860             /* OPC_BLEZ */
14861             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
14862         } else {
14863             check_insn(ctx, ISA_MIPS_R6);
14864             /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
14865             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
14866         }
14867         break;
14868     case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
14869         if (rt == 0) {
14870             /* OPC_BGTZ */
14871             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
14872         } else {
14873             check_insn(ctx, ISA_MIPS_R6);
14874             /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
14875             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
14876         }
14877         break;
14878     case OPC_BEQL:
14879     case OPC_BNEL:
14880         check_insn(ctx, ISA_MIPS2);
14881          check_insn_opc_removed(ctx, ISA_MIPS_R6);
14882         /* Fallthrough */
14883     case OPC_BEQ:
14884     case OPC_BNE:
14885          gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
14886          break;
14887     case OPC_LL: /* Load and stores */
14888         check_insn(ctx, ISA_MIPS2);
14889         if (ctx->insn_flags & INSN_R5900) {
14890             check_insn_opc_user_only(ctx, INSN_R5900);
14891         }
14892         /* Fallthrough */
14893     case OPC_LWL:
14894     case OPC_LWR:
14895     case OPC_LB:
14896     case OPC_LH:
14897     case OPC_LW:
14898     case OPC_LWPC:
14899     case OPC_LBU:
14900     case OPC_LHU:
14901          gen_ld(ctx, op, rt, rs, imm);
14902          break;
14903     case OPC_SWL:
14904     case OPC_SWR:
14905     case OPC_SB:
14906     case OPC_SH:
14907     case OPC_SW:
14908          gen_st(ctx, op, rt, rs, imm);
14909          break;
14910     case OPC_SC:
14911         check_insn(ctx, ISA_MIPS2);
14912         if (ctx->insn_flags & INSN_R5900) {
14913             check_insn_opc_user_only(ctx, INSN_R5900);
14914         }
14915         gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
14916         break;
14917     case OPC_CACHE:
14918         check_cp0_enabled(ctx);
14919         check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1);
14920         if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
14921             gen_cache_operation(ctx, rt, rs, imm);
14922         }
14923         /* Treat as NOP. */
14924         break;
14925     case OPC_PREF:
14926         check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 | INSN_R5900);
14927         /* Treat as NOP. */
14928         break;
14929 
14930     /* Floating point (COP1). */
14931     case OPC_LWC1:
14932     case OPC_LDC1:
14933     case OPC_SWC1:
14934     case OPC_SDC1:
14935         gen_cop1_ldst(ctx, op, rt, rs, imm);
14936         break;
14937 
14938     case OPC_CP1:
14939         op1 = MASK_CP1(ctx->opcode);
14940 
14941         switch (op1) {
14942         case OPC_MFHC1:
14943         case OPC_MTHC1:
14944             check_cp1_enabled(ctx);
14945             check_insn(ctx, ISA_MIPS_R2);
14946             /* fall through */
14947         case OPC_MFC1:
14948         case OPC_CFC1:
14949         case OPC_MTC1:
14950         case OPC_CTC1:
14951             check_cp1_enabled(ctx);
14952             gen_cp1(ctx, op1, rt, rd);
14953             break;
14954 #if defined(TARGET_MIPS64)
14955         case OPC_DMFC1:
14956         case OPC_DMTC1:
14957             check_cp1_enabled(ctx);
14958             check_insn(ctx, ISA_MIPS3);
14959             check_mips_64(ctx);
14960             gen_cp1(ctx, op1, rt, rd);
14961             break;
14962 #endif
14963         case OPC_BC1EQZ: /* OPC_BC1ANY2 */
14964             check_cp1_enabled(ctx);
14965             if (ctx->insn_flags & ISA_MIPS_R6) {
14966                 /* OPC_BC1EQZ */
14967                 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
14968                                        rt, imm << 2, 4);
14969             } else {
14970                 /* OPC_BC1ANY2 */
14971                 check_cop1x(ctx);
14972                 check_insn(ctx, ASE_MIPS3D);
14973                 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
14974                                     (rt >> 2) & 0x7, imm << 2);
14975             }
14976             break;
14977         case OPC_BC1NEZ:
14978             check_cp1_enabled(ctx);
14979             check_insn(ctx, ISA_MIPS_R6);
14980             gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
14981                                    rt, imm << 2, 4);
14982             break;
14983         case OPC_BC1ANY4:
14984             check_cp1_enabled(ctx);
14985             check_insn_opc_removed(ctx, ISA_MIPS_R6);
14986             check_cop1x(ctx);
14987             check_insn(ctx, ASE_MIPS3D);
14988             /* fall through */
14989         case OPC_BC1:
14990             check_cp1_enabled(ctx);
14991             check_insn_opc_removed(ctx, ISA_MIPS_R6);
14992             gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
14993                                 (rt >> 2) & 0x7, imm << 2);
14994             break;
14995         case OPC_PS_FMT:
14996             check_ps(ctx);
14997             /* fall through */
14998         case OPC_S_FMT:
14999         case OPC_D_FMT:
15000             check_cp1_enabled(ctx);
15001             gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15002                        (imm >> 8) & 0x7);
15003             break;
15004         case OPC_W_FMT:
15005         case OPC_L_FMT:
15006         {
15007             int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
15008             check_cp1_enabled(ctx);
15009             if (ctx->insn_flags & ISA_MIPS_R6) {
15010                 switch (r6_op) {
15011                 case R6_OPC_CMP_AF_S:
15012                 case R6_OPC_CMP_UN_S:
15013                 case R6_OPC_CMP_EQ_S:
15014                 case R6_OPC_CMP_UEQ_S:
15015                 case R6_OPC_CMP_LT_S:
15016                 case R6_OPC_CMP_ULT_S:
15017                 case R6_OPC_CMP_LE_S:
15018                 case R6_OPC_CMP_ULE_S:
15019                 case R6_OPC_CMP_SAF_S:
15020                 case R6_OPC_CMP_SUN_S:
15021                 case R6_OPC_CMP_SEQ_S:
15022                 case R6_OPC_CMP_SEUQ_S:
15023                 case R6_OPC_CMP_SLT_S:
15024                 case R6_OPC_CMP_SULT_S:
15025                 case R6_OPC_CMP_SLE_S:
15026                 case R6_OPC_CMP_SULE_S:
15027                 case R6_OPC_CMP_OR_S:
15028                 case R6_OPC_CMP_UNE_S:
15029                 case R6_OPC_CMP_NE_S:
15030                 case R6_OPC_CMP_SOR_S:
15031                 case R6_OPC_CMP_SUNE_S:
15032                 case R6_OPC_CMP_SNE_S:
15033                     gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
15034                     break;
15035                 case R6_OPC_CMP_AF_D:
15036                 case R6_OPC_CMP_UN_D:
15037                 case R6_OPC_CMP_EQ_D:
15038                 case R6_OPC_CMP_UEQ_D:
15039                 case R6_OPC_CMP_LT_D:
15040                 case R6_OPC_CMP_ULT_D:
15041                 case R6_OPC_CMP_LE_D:
15042                 case R6_OPC_CMP_ULE_D:
15043                 case R6_OPC_CMP_SAF_D:
15044                 case R6_OPC_CMP_SUN_D:
15045                 case R6_OPC_CMP_SEQ_D:
15046                 case R6_OPC_CMP_SEUQ_D:
15047                 case R6_OPC_CMP_SLT_D:
15048                 case R6_OPC_CMP_SULT_D:
15049                 case R6_OPC_CMP_SLE_D:
15050                 case R6_OPC_CMP_SULE_D:
15051                 case R6_OPC_CMP_OR_D:
15052                 case R6_OPC_CMP_UNE_D:
15053                 case R6_OPC_CMP_NE_D:
15054                 case R6_OPC_CMP_SOR_D:
15055                 case R6_OPC_CMP_SUNE_D:
15056                 case R6_OPC_CMP_SNE_D:
15057                     gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
15058                     break;
15059                 default:
15060                     gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
15061                                rt, rd, sa, (imm >> 8) & 0x7);
15062 
15063                     break;
15064                 }
15065             } else {
15066                 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15067                            (imm >> 8) & 0x7);
15068             }
15069             break;
15070         }
15071         default:
15072             MIPS_INVAL("cp1");
15073             gen_reserved_instruction(ctx);
15074             break;
15075         }
15076         break;
15077 
15078     /* Compact branches [R6] and COP2 [non-R6] */
15079     case OPC_BC: /* OPC_LWC2 */
15080     case OPC_BALC: /* OPC_SWC2 */
15081         if (ctx->insn_flags & ISA_MIPS_R6) {
15082             /* OPC_BC, OPC_BALC */
15083             gen_compute_compact_branch(ctx, op, 0, 0,
15084                                        sextract32(ctx->opcode << 2, 0, 28));
15085         } else if (ctx->insn_flags & ASE_LEXT) {
15086             gen_loongson_lswc2(ctx, rt, rs, rd);
15087         } else {
15088             /* OPC_LWC2, OPC_SWC2 */
15089             /* COP2: Not implemented. */
15090             generate_exception_err(ctx, EXCP_CpU, 2);
15091         }
15092         break;
15093     case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
15094     case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
15095         if (ctx->insn_flags & ISA_MIPS_R6) {
15096             if (rs != 0) {
15097                 /* OPC_BEQZC, OPC_BNEZC */
15098                 gen_compute_compact_branch(ctx, op, rs, 0,
15099                                            sextract32(ctx->opcode << 2, 0, 23));
15100             } else {
15101                 /* OPC_JIC, OPC_JIALC */
15102                 gen_compute_compact_branch(ctx, op, 0, rt, imm);
15103             }
15104         } else if (ctx->insn_flags & ASE_LEXT) {
15105             gen_loongson_lsdc2(ctx, rt, rs, rd);
15106         } else {
15107             /* OPC_LWC2, OPC_SWC2 */
15108             /* COP2: Not implemented. */
15109             generate_exception_err(ctx, EXCP_CpU, 2);
15110         }
15111         break;
15112     case OPC_CP2:
15113         check_insn(ctx, ASE_LMMI);
15114         /* Note that these instructions use different fields.  */
15115         gen_loongson_multimedia(ctx, sa, rd, rt);
15116         break;
15117 
15118     case OPC_CP3:
15119         if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
15120             check_cp1_enabled(ctx);
15121             op1 = MASK_CP3(ctx->opcode);
15122             switch (op1) {
15123             case OPC_LUXC1:
15124             case OPC_SUXC1:
15125                 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2);
15126                 /* Fallthrough */
15127             case OPC_LWXC1:
15128             case OPC_LDXC1:
15129             case OPC_SWXC1:
15130             case OPC_SDXC1:
15131                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
15132                 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
15133                 break;
15134             case OPC_PREFX:
15135                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
15136                 /* Treat as NOP. */
15137                 break;
15138             case OPC_ALNV_PS:
15139                 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2);
15140                 /* Fallthrough */
15141             case OPC_MADD_S:
15142             case OPC_MADD_D:
15143             case OPC_MADD_PS:
15144             case OPC_MSUB_S:
15145             case OPC_MSUB_D:
15146             case OPC_MSUB_PS:
15147             case OPC_NMADD_S:
15148             case OPC_NMADD_D:
15149             case OPC_NMADD_PS:
15150             case OPC_NMSUB_S:
15151             case OPC_NMSUB_D:
15152             case OPC_NMSUB_PS:
15153                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
15154                 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15155                 break;
15156             default:
15157                 MIPS_INVAL("cp3");
15158                 gen_reserved_instruction(ctx);
15159                 break;
15160             }
15161         } else {
15162             generate_exception_err(ctx, EXCP_CpU, 1);
15163         }
15164         break;
15165 
15166 #if defined(TARGET_MIPS64)
15167     /* MIPS64 opcodes */
15168     case OPC_LLD:
15169         if (ctx->insn_flags & INSN_R5900) {
15170             check_insn_opc_user_only(ctx, INSN_R5900);
15171         }
15172         /* fall through */
15173     case OPC_LDL:
15174     case OPC_LDR:
15175     case OPC_LWU:
15176     case OPC_LD:
15177         check_insn(ctx, ISA_MIPS3);
15178         check_mips_64(ctx);
15179         gen_ld(ctx, op, rt, rs, imm);
15180         break;
15181     case OPC_SDL:
15182     case OPC_SDR:
15183     case OPC_SD:
15184         check_insn(ctx, ISA_MIPS3);
15185         check_mips_64(ctx);
15186         gen_st(ctx, op, rt, rs, imm);
15187         break;
15188     case OPC_SCD:
15189         check_insn(ctx, ISA_MIPS3);
15190         if (ctx->insn_flags & INSN_R5900) {
15191             check_insn_opc_user_only(ctx, INSN_R5900);
15192         }
15193         check_mips_64(ctx);
15194         gen_st_cond(ctx, rt, rs, imm, MO_TEUQ, false);
15195         break;
15196     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
15197         if (ctx->insn_flags & ISA_MIPS_R6) {
15198             /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
15199             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15200         } else {
15201             /* OPC_DADDI */
15202             check_insn(ctx, ISA_MIPS3);
15203             check_mips_64(ctx);
15204             gen_arith_imm(ctx, op, rt, rs, imm);
15205         }
15206         break;
15207     case OPC_DADDIU:
15208         check_insn(ctx, ISA_MIPS3);
15209         check_mips_64(ctx);
15210         gen_arith_imm(ctx, op, rt, rs, imm);
15211         break;
15212 #else
15213     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
15214         if (ctx->insn_flags & ISA_MIPS_R6) {
15215             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15216         } else {
15217             MIPS_INVAL("major opcode");
15218             gen_reserved_instruction(ctx);
15219         }
15220         break;
15221 #endif
15222     case OPC_DAUI: /* OPC_JALX */
15223         if (ctx->insn_flags & ISA_MIPS_R6) {
15224 #if defined(TARGET_MIPS64)
15225             /* OPC_DAUI */
15226             check_mips_64(ctx);
15227             if (rs == 0) {
15228                 generate_exception(ctx, EXCP_RI);
15229             } else if (rt != 0) {
15230                 TCGv t0 = tcg_temp_new();
15231                 gen_load_gpr(t0, rs);
15232                 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
15233             }
15234 #else
15235             gen_reserved_instruction(ctx);
15236             MIPS_INVAL("major opcode");
15237 #endif
15238         } else {
15239             /* OPC_JALX */
15240             check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
15241             offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15242             gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
15243         }
15244         break;
15245     case OPC_MDMX:
15246         /* MDMX: Not implemented. */
15247         break;
15248     case OPC_PCREL:
15249         check_insn(ctx, ISA_MIPS_R6);
15250         gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
15251         break;
15252     default:            /* Invalid */
15253         MIPS_INVAL("major opcode");
15254         return false;
15255     }
15256     return true;
15257 }
15258 
decode_opc(CPUMIPSState * env,DisasContext * ctx)15259 static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
15260 {
15261     /* make sure instructions are on a word boundary */
15262     if (ctx->base.pc_next & 0x3) {
15263         env->CP0_BadVAddr = ctx->base.pc_next;
15264         generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
15265         return;
15266     }
15267 
15268     /* Handle blikely not taken case */
15269     if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
15270         TCGLabel *l1 = gen_new_label();
15271 
15272         tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
15273         tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
15274         gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
15275         gen_set_label(l1);
15276     }
15277 
15278     /* Transition to the auto-generated decoder.  */
15279 
15280     /* Vendor specific extensions */
15281     if (cpu_supports_isa(env, INSN_R5900) && decode_ext_txx9(ctx, ctx->opcode)) {
15282         return;
15283     }
15284     if (cpu_supports_isa(env, INSN_VR54XX) && decode_ext_vr54xx(ctx, ctx->opcode)) {
15285         return;
15286     }
15287 #if defined(TARGET_MIPS64)
15288     if (ase_lcsr_available(env) && decode_ase_lcsr(ctx, ctx->opcode)) {
15289         return;
15290     }
15291     if (cpu_supports_isa(env, INSN_OCTEON) && decode_ext_octeon(ctx, ctx->opcode)) {
15292         return;
15293     }
15294 #endif
15295 
15296     /* ISA extensions */
15297     if (ase_msa_available(env) && decode_ase_msa(ctx, ctx->opcode)) {
15298         return;
15299     }
15300 
15301     /* ISA (from latest to oldest) */
15302     if (cpu_supports_isa(env, ISA_MIPS_R6) && decode_isa_rel6(ctx, ctx->opcode)) {
15303         return;
15304     }
15305 
15306     if (decode_opc_legacy(env, ctx)) {
15307         return;
15308     }
15309 
15310     gen_reserved_instruction(ctx);
15311 }
15312 
mips_tr_init_disas_context(DisasContextBase * dcbase,CPUState * cs)15313 static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
15314 {
15315     DisasContext *ctx = container_of(dcbase, DisasContext, base);
15316     CPUMIPSState *env = cpu_env(cs);
15317 
15318     ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
15319     ctx->saved_pc = -1;
15320     ctx->insn_flags = env->insn_flags;
15321     ctx->CP0_Config0 = env->CP0_Config0;
15322     ctx->CP0_Config1 = env->CP0_Config1;
15323     ctx->CP0_Config2 = env->CP0_Config2;
15324     ctx->CP0_Config3 = env->CP0_Config3;
15325     ctx->CP0_Config5 = env->CP0_Config5;
15326     ctx->btarget = 0;
15327     ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
15328     ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
15329     ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
15330     ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
15331     ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
15332     ctx->PAMask = env->PAMask;
15333     ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
15334     ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
15335     ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
15336     ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
15337     ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
15338     /* Restore delay slot state from the tb context.  */
15339     ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
15340     ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
15341     ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
15342              (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
15343     ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
15344     ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
15345     ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
15346     ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
15347     ctx->mi = (env->CP0_Config5 >> CP0C5_MI) & 1;
15348     ctx->gi = (env->CP0_Config5 >> CP0C5_GI) & 3;
15349     restore_cpu_state(env, ctx);
15350 #ifdef CONFIG_USER_ONLY
15351         ctx->mem_idx = MIPS_HFLAG_UM;
15352 #else
15353         ctx->mem_idx = hflags_mmu_index(ctx->hflags);
15354 #endif
15355     ctx->default_tcg_memop_mask = (!(ctx->insn_flags & ISA_NANOMIPS32) &&
15356                                   (ctx->insn_flags & (ISA_MIPS_R6 |
15357                                   INSN_LOONGSON3A))) ? MO_UNALN : MO_ALIGN;
15358 
15359     /*
15360      * Execute a branch and its delay slot as a single instruction.
15361      * This is what GDB expects and is consistent with what the
15362      * hardware does (e.g. if a delay slot instruction faults, the
15363      * reported PC is the PC of the branch).
15364      */
15365     if (ctx->base.singlestep_enabled && (ctx->hflags & MIPS_HFLAG_BMASK)) {
15366         ctx->base.max_insns = 2;
15367     }
15368 
15369     LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
15370               ctx->hflags);
15371 }
15372 
mips_tr_tb_start(DisasContextBase * dcbase,CPUState * cs)15373 static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
15374 {
15375 }
15376 
mips_tr_insn_start(DisasContextBase * dcbase,CPUState * cs)15377 static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
15378 {
15379     DisasContext *ctx = container_of(dcbase, DisasContext, base);
15380 
15381     tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
15382                        ctx->btarget);
15383 }
15384 
mips_tr_translate_insn(DisasContextBase * dcbase,CPUState * cs)15385 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
15386 {
15387     CPUMIPSState *env = cpu_env(cs);
15388     DisasContext *ctx = container_of(dcbase, DisasContext, base);
15389     int insn_bytes;
15390     int is_slot;
15391 
15392     is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
15393     if (ctx->insn_flags & ISA_NANOMIPS32) {
15394         ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
15395         insn_bytes = decode_isa_nanomips(env, ctx);
15396     } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
15397         ctx->opcode = translator_ldl(env, &ctx->base, ctx->base.pc_next);
15398         insn_bytes = 4;
15399         decode_opc(env, ctx);
15400     } else if (ctx->insn_flags & ASE_MICROMIPS) {
15401         ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
15402         insn_bytes = decode_isa_micromips(env, ctx);
15403     } else if (ctx->insn_flags & ASE_MIPS16) {
15404         ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
15405         insn_bytes = decode_ase_mips16e(env, ctx);
15406     } else {
15407         gen_reserved_instruction(ctx);
15408         g_assert(ctx->base.is_jmp == DISAS_NORETURN);
15409         return;
15410     }
15411 
15412     if (ctx->hflags & MIPS_HFLAG_BMASK) {
15413         if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
15414                              MIPS_HFLAG_FBNSLOT))) {
15415             /*
15416              * Force to generate branch as there is neither delay nor
15417              * forbidden slot.
15418              */
15419             is_slot = 1;
15420         }
15421         if ((ctx->hflags & MIPS_HFLAG_M16) &&
15422             (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
15423             /*
15424              * Force to generate branch as microMIPS R6 doesn't restrict
15425              * branches in the forbidden slot.
15426              */
15427             is_slot = 1;
15428         }
15429     }
15430     if (is_slot) {
15431         gen_branch(ctx, insn_bytes);
15432     }
15433     if (ctx->base.is_jmp == DISAS_SEMIHOST) {
15434         generate_exception_err(ctx, EXCP_SEMIHOST, insn_bytes);
15435     }
15436     ctx->base.pc_next += insn_bytes;
15437 
15438     if (ctx->base.is_jmp != DISAS_NEXT) {
15439         return;
15440     }
15441 
15442     /*
15443      * End the TB on (most) page crossings.
15444      * See mips_tr_init_disas_context about single-stepping a branch
15445      * together with its delay slot.
15446      */
15447     if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE
15448         && !ctx->base.singlestep_enabled) {
15449         ctx->base.is_jmp = DISAS_TOO_MANY;
15450     }
15451 }
15452 
mips_tr_tb_stop(DisasContextBase * dcbase,CPUState * cs)15453 static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
15454 {
15455     DisasContext *ctx = container_of(dcbase, DisasContext, base);
15456 
15457     switch (ctx->base.is_jmp) {
15458     case DISAS_STOP:
15459         gen_save_pc(ctx->base.pc_next);
15460         tcg_gen_lookup_and_goto_ptr();
15461         break;
15462     case DISAS_NEXT:
15463     case DISAS_TOO_MANY:
15464         save_cpu_state(ctx, 0);
15465         gen_goto_tb(ctx, 0, ctx->base.pc_next);
15466         break;
15467     case DISAS_EXIT:
15468         tcg_gen_exit_tb(NULL, 0);
15469         break;
15470     case DISAS_NORETURN:
15471         break;
15472     default:
15473         g_assert_not_reached();
15474     }
15475 }
15476 
15477 static const TranslatorOps mips_tr_ops = {
15478     .init_disas_context = mips_tr_init_disas_context,
15479     .tb_start           = mips_tr_tb_start,
15480     .insn_start         = mips_tr_insn_start,
15481     .translate_insn     = mips_tr_translate_insn,
15482     .tb_stop            = mips_tr_tb_stop,
15483 };
15484 
gen_intermediate_code(CPUState * cs,TranslationBlock * tb,int * max_insns,vaddr pc,void * host_pc)15485 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
15486                            vaddr pc, void *host_pc)
15487 {
15488     DisasContext ctx;
15489 
15490     translator_loop(cs, tb, max_insns, pc, host_pc, &mips_tr_ops, &ctx.base);
15491 }
15492 
mips_tcg_init(void)15493 void mips_tcg_init(void)
15494 {
15495     cpu_gpr[0] = NULL;
15496     for (unsigned i = 1; i < 32; i++)
15497         cpu_gpr[i] = tcg_global_mem_new(tcg_env,
15498                                         offsetof(CPUMIPSState,
15499                                                  active_tc.gpr[i]),
15500                                         regnames[i]);
15501 #if defined(TARGET_MIPS64)
15502     cpu_gpr_hi[0] = NULL;
15503 
15504     for (unsigned i = 1; i < 32; i++) {
15505         g_autofree char *rname = g_strdup_printf("%s[hi]", regnames[i]);
15506 
15507         cpu_gpr_hi[i] = tcg_global_mem_new_i64(tcg_env,
15508                                                offsetof(CPUMIPSState,
15509                                                         active_tc.gpr_hi[i]),
15510                                                rname);
15511     }
15512 #endif /* !TARGET_MIPS64 */
15513     for (unsigned i = 0; i < 32; i++) {
15514         int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
15515 
15516         fpu_f64[i] = tcg_global_mem_new_i64(tcg_env, off, fregnames[i]);
15517     }
15518     msa_translate_init();
15519     cpu_PC = tcg_global_mem_new(tcg_env,
15520                                 offsetof(CPUMIPSState, active_tc.PC), "PC");
15521     for (unsigned i = 0; i < MIPS_DSP_ACC; i++) {
15522         cpu_HI[i] = tcg_global_mem_new(tcg_env,
15523                                        offsetof(CPUMIPSState, active_tc.HI[i]),
15524                                        regnames_HI[i]);
15525         cpu_LO[i] = tcg_global_mem_new(tcg_env,
15526                                        offsetof(CPUMIPSState, active_tc.LO[i]),
15527                                        regnames_LO[i]);
15528     }
15529     cpu_dspctrl = tcg_global_mem_new(tcg_env,
15530                                      offsetof(CPUMIPSState,
15531                                               active_tc.DSPControl),
15532                                      "DSPControl");
15533     bcond = tcg_global_mem_new(tcg_env,
15534                                offsetof(CPUMIPSState, bcond), "bcond");
15535     btarget = tcg_global_mem_new(tcg_env,
15536                                  offsetof(CPUMIPSState, btarget), "btarget");
15537     hflags = tcg_global_mem_new_i32(tcg_env,
15538                                     offsetof(CPUMIPSState, hflags), "hflags");
15539 
15540     fpu_fcr0 = tcg_global_mem_new_i32(tcg_env,
15541                                       offsetof(CPUMIPSState, active_fpu.fcr0),
15542                                       "fcr0");
15543     fpu_fcr31 = tcg_global_mem_new_i32(tcg_env,
15544                                        offsetof(CPUMIPSState, active_fpu.fcr31),
15545                                        "fcr31");
15546     cpu_lladdr = tcg_global_mem_new(tcg_env, offsetof(CPUMIPSState, lladdr),
15547                                     "lladdr");
15548     cpu_llval = tcg_global_mem_new(tcg_env, offsetof(CPUMIPSState, llval),
15549                                    "llval");
15550 
15551     if (TARGET_LONG_BITS == 32) {
15552         mxu_translate_init();
15553     }
15554 }
15555 
mips_restore_state_to_opc(CPUState * cs,const TranslationBlock * tb,const uint64_t * data)15556 void mips_restore_state_to_opc(CPUState *cs,
15557                                const TranslationBlock *tb,
15558                                const uint64_t *data)
15559 {
15560     CPUMIPSState *env = cpu_env(cs);
15561 
15562     env->active_tc.PC = data[0];
15563     env->hflags &= ~MIPS_HFLAG_BMASK;
15564     env->hflags |= data[1];
15565     switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
15566     case MIPS_HFLAG_BR:
15567         break;
15568     case MIPS_HFLAG_BC:
15569     case MIPS_HFLAG_BL:
15570     case MIPS_HFLAG_B:
15571         env->btarget = data[2];
15572         break;
15573     }
15574 }
15575