xref: /openbmc/qemu/target/mips/tcg/translate.c (revision 804607e8)
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     /* Misc */
331     OPC_CLZ      = 0x20 | OPC_SPECIAL2,
332     OPC_CLO      = 0x21 | OPC_SPECIAL2,
333     OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
334     OPC_DCLO     = 0x25 | OPC_SPECIAL2,
335     /* Special */
336     OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
337 };
338 
339 /* Special3 opcodes */
340 #define MASK_SPECIAL3(op)           (MASK_OP_MAJOR(op) | (op & 0x3F))
341 
342 enum {
343     OPC_EXT      = 0x00 | OPC_SPECIAL3,
344     OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
345     OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
346     OPC_DEXT     = 0x03 | OPC_SPECIAL3,
347     OPC_INS      = 0x04 | OPC_SPECIAL3,
348     OPC_DINSM    = 0x05 | OPC_SPECIAL3,
349     OPC_DINSU    = 0x06 | OPC_SPECIAL3,
350     OPC_DINS     = 0x07 | OPC_SPECIAL3,
351     OPC_FORK     = 0x08 | OPC_SPECIAL3,
352     OPC_YIELD    = 0x09 | OPC_SPECIAL3,
353     OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
354     OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
355     OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
356     OPC_GINV     = 0x3D | OPC_SPECIAL3,
357 
358     /* MIPS DSP Load */
359     OPC_LX_DSP         = 0x0A | OPC_SPECIAL3,
360     /* MIPS DSP Arithmetic */
361     OPC_ADDU_QB_DSP    = 0x10 | OPC_SPECIAL3,
362     OPC_ADDU_OB_DSP    = 0x14 | OPC_SPECIAL3,
363     OPC_ABSQ_S_PH_DSP  = 0x12 | OPC_SPECIAL3,
364     OPC_ABSQ_S_QH_DSP  = 0x16 | OPC_SPECIAL3,
365     OPC_ADDUH_QB_DSP   = 0x18 | OPC_SPECIAL3,
366     OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
367     OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
368     /* MIPS DSP GPR-Based Shift Sub-class */
369     OPC_SHLL_QB_DSP    = 0x13 | OPC_SPECIAL3,
370     OPC_SHLL_OB_DSP    = 0x17 | OPC_SPECIAL3,
371     /* MIPS DSP Multiply Sub-class insns */
372     OPC_MUL_PH_DSP     = 0x18 | OPC_SPECIAL3,
373     OPC_DPA_W_PH_DSP   = 0x30 | OPC_SPECIAL3,
374     OPC_DPAQ_W_QH_DSP  = 0x34 | OPC_SPECIAL3,
375     /* DSP Bit/Manipulation Sub-class */
376     OPC_INSV_DSP       = 0x0C | OPC_SPECIAL3,
377     OPC_DINSV_DSP      = 0x0D | OPC_SPECIAL3,
378     /* MIPS DSP Append Sub-class */
379     OPC_APPEND_DSP     = 0x31 | OPC_SPECIAL3,
380     OPC_DAPPEND_DSP    = 0x35 | OPC_SPECIAL3,
381     /* MIPS DSP Accumulator and DSPControl Access Sub-class */
382     OPC_EXTR_W_DSP     = 0x38 | OPC_SPECIAL3,
383     OPC_DEXTR_W_DSP    = 0x3C | OPC_SPECIAL3,
384 
385     /* EVA */
386     OPC_LWLE           = 0x19 | OPC_SPECIAL3,
387     OPC_LWRE           = 0x1A | OPC_SPECIAL3,
388     OPC_CACHEE         = 0x1B | OPC_SPECIAL3,
389     OPC_SBE            = 0x1C | OPC_SPECIAL3,
390     OPC_SHE            = 0x1D | OPC_SPECIAL3,
391     OPC_SCE            = 0x1E | OPC_SPECIAL3,
392     OPC_SWE            = 0x1F | OPC_SPECIAL3,
393     OPC_SWLE           = 0x21 | OPC_SPECIAL3,
394     OPC_SWRE           = 0x22 | OPC_SPECIAL3,
395     OPC_PREFE          = 0x23 | OPC_SPECIAL3,
396     OPC_LBUE           = 0x28 | OPC_SPECIAL3,
397     OPC_LHUE           = 0x29 | OPC_SPECIAL3,
398     OPC_LBE            = 0x2C | OPC_SPECIAL3,
399     OPC_LHE            = 0x2D | OPC_SPECIAL3,
400     OPC_LLE            = 0x2E | OPC_SPECIAL3,
401     OPC_LWE            = 0x2F | OPC_SPECIAL3,
402 
403     /* R6 */
404     R6_OPC_PREF        = 0x35 | OPC_SPECIAL3,
405     R6_OPC_CACHE       = 0x25 | OPC_SPECIAL3,
406     R6_OPC_LL          = 0x36 | OPC_SPECIAL3,
407     R6_OPC_SC          = 0x26 | OPC_SPECIAL3,
408     R6_OPC_LLD         = 0x37 | OPC_SPECIAL3,
409     R6_OPC_SCD         = 0x27 | OPC_SPECIAL3,
410 };
411 
412 /* Loongson EXT load/store quad word opcodes */
413 #define MASK_LOONGSON_GSLSQ(op)           (MASK_OP_MAJOR(op) | (op & 0x8020))
414 enum {
415     OPC_GSLQ        = 0x0020 | OPC_LWC2,
416     OPC_GSLQC1      = 0x8020 | OPC_LWC2,
417     OPC_GSSHFL      = OPC_LWC2,
418     OPC_GSSQ        = 0x0020 | OPC_SWC2,
419     OPC_GSSQC1      = 0x8020 | OPC_SWC2,
420     OPC_GSSHFS      = OPC_SWC2,
421 };
422 
423 /* Loongson EXT shifted load/store opcodes */
424 #define MASK_LOONGSON_GSSHFLS(op)         (MASK_OP_MAJOR(op) | (op & 0xc03f))
425 enum {
426     OPC_GSLWLC1     = 0x4 | OPC_GSSHFL,
427     OPC_GSLWRC1     = 0x5 | OPC_GSSHFL,
428     OPC_GSLDLC1     = 0x6 | OPC_GSSHFL,
429     OPC_GSLDRC1     = 0x7 | OPC_GSSHFL,
430     OPC_GSSWLC1     = 0x4 | OPC_GSSHFS,
431     OPC_GSSWRC1     = 0x5 | OPC_GSSHFS,
432     OPC_GSSDLC1     = 0x6 | OPC_GSSHFS,
433     OPC_GSSDRC1     = 0x7 | OPC_GSSHFS,
434 };
435 
436 /* Loongson EXT LDC2/SDC2 opcodes */
437 #define MASK_LOONGSON_LSDC2(op)           (MASK_OP_MAJOR(op) | (op & 0x7))
438 
439 enum {
440     OPC_GSLBX      = 0x0 | OPC_LDC2,
441     OPC_GSLHX      = 0x1 | OPC_LDC2,
442     OPC_GSLWX      = 0x2 | OPC_LDC2,
443     OPC_GSLDX      = 0x3 | OPC_LDC2,
444     OPC_GSLWXC1    = 0x6 | OPC_LDC2,
445     OPC_GSLDXC1    = 0x7 | OPC_LDC2,
446     OPC_GSSBX      = 0x0 | OPC_SDC2,
447     OPC_GSSHX      = 0x1 | OPC_SDC2,
448     OPC_GSSWX      = 0x2 | OPC_SDC2,
449     OPC_GSSDX      = 0x3 | OPC_SDC2,
450     OPC_GSSWXC1    = 0x6 | OPC_SDC2,
451     OPC_GSSDXC1    = 0x7 | OPC_SDC2,
452 };
453 
454 /* BSHFL opcodes */
455 #define MASK_BSHFL(op)              (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
456 
457 enum {
458     OPC_WSBH      = (0x02 << 6) | OPC_BSHFL,
459     OPC_SEB       = (0x10 << 6) | OPC_BSHFL,
460     OPC_SEH       = (0x18 << 6) | OPC_BSHFL,
461     OPC_ALIGN     = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */
462     OPC_ALIGN_1   = (0x09 << 6) | OPC_BSHFL,
463     OPC_ALIGN_2   = (0x0A << 6) | OPC_BSHFL,
464     OPC_ALIGN_3   = (0x0B << 6) | OPC_BSHFL,
465     OPC_BITSWAP   = (0x00 << 6) | OPC_BSHFL  /* 00000 */
466 };
467 
468 /* DBSHFL opcodes */
469 #define MASK_DBSHFL(op)             (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
470 
471 enum {
472     OPC_DSBH       = (0x02 << 6) | OPC_DBSHFL,
473     OPC_DSHD       = (0x05 << 6) | OPC_DBSHFL,
474     OPC_DALIGN     = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */
475     OPC_DALIGN_1   = (0x09 << 6) | OPC_DBSHFL,
476     OPC_DALIGN_2   = (0x0A << 6) | OPC_DBSHFL,
477     OPC_DALIGN_3   = (0x0B << 6) | OPC_DBSHFL,
478     OPC_DALIGN_4   = (0x0C << 6) | OPC_DBSHFL,
479     OPC_DALIGN_5   = (0x0D << 6) | OPC_DBSHFL,
480     OPC_DALIGN_6   = (0x0E << 6) | OPC_DBSHFL,
481     OPC_DALIGN_7   = (0x0F << 6) | OPC_DBSHFL,
482     OPC_DBITSWAP   = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
483 };
484 
485 /* MIPS DSP REGIMM opcodes */
486 enum {
487     OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
488     OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
489 };
490 
491 #define MASK_LX(op)                 (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
492 /* MIPS DSP Load */
493 enum {
494     OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
495     OPC_LHX  = (0x04 << 6) | OPC_LX_DSP,
496     OPC_LWX  = (0x00 << 6) | OPC_LX_DSP,
497     OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
498 };
499 
500 #define MASK_ADDU_QB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
501 enum {
502     /* MIPS DSP Arithmetic Sub-class */
503     OPC_ADDQ_PH        = (0x0A << 6) | OPC_ADDU_QB_DSP,
504     OPC_ADDQ_S_PH      = (0x0E << 6) | OPC_ADDU_QB_DSP,
505     OPC_ADDQ_S_W       = (0x16 << 6) | OPC_ADDU_QB_DSP,
506     OPC_ADDU_QB        = (0x00 << 6) | OPC_ADDU_QB_DSP,
507     OPC_ADDU_S_QB      = (0x04 << 6) | OPC_ADDU_QB_DSP,
508     OPC_ADDU_PH        = (0x08 << 6) | OPC_ADDU_QB_DSP,
509     OPC_ADDU_S_PH      = (0x0C << 6) | OPC_ADDU_QB_DSP,
510     OPC_SUBQ_PH        = (0x0B << 6) | OPC_ADDU_QB_DSP,
511     OPC_SUBQ_S_PH      = (0x0F << 6) | OPC_ADDU_QB_DSP,
512     OPC_SUBQ_S_W       = (0x17 << 6) | OPC_ADDU_QB_DSP,
513     OPC_SUBU_QB        = (0x01 << 6) | OPC_ADDU_QB_DSP,
514     OPC_SUBU_S_QB      = (0x05 << 6) | OPC_ADDU_QB_DSP,
515     OPC_SUBU_PH        = (0x09 << 6) | OPC_ADDU_QB_DSP,
516     OPC_SUBU_S_PH      = (0x0D << 6) | OPC_ADDU_QB_DSP,
517     OPC_ADDSC          = (0x10 << 6) | OPC_ADDU_QB_DSP,
518     OPC_ADDWC          = (0x11 << 6) | OPC_ADDU_QB_DSP,
519     OPC_MODSUB         = (0x12 << 6) | OPC_ADDU_QB_DSP,
520     OPC_RADDU_W_QB     = (0x14 << 6) | OPC_ADDU_QB_DSP,
521     /* MIPS DSP Multiply Sub-class insns */
522     OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
523     OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
524     OPC_MULQ_RS_PH     = (0x1F << 6) | OPC_ADDU_QB_DSP,
525     OPC_MULEQ_S_W_PHL  = (0x1C << 6) | OPC_ADDU_QB_DSP,
526     OPC_MULEQ_S_W_PHR  = (0x1D << 6) | OPC_ADDU_QB_DSP,
527     OPC_MULQ_S_PH      = (0x1E << 6) | OPC_ADDU_QB_DSP,
528 };
529 
530 #define MASK_ADDUH_QB(op)           (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
531 enum {
532     /* MIPS DSP Arithmetic Sub-class */
533     OPC_ADDUH_QB   = (0x00 << 6) | OPC_ADDUH_QB_DSP,
534     OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
535     OPC_ADDQH_PH   = (0x08 << 6) | OPC_ADDUH_QB_DSP,
536     OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
537     OPC_ADDQH_W    = (0x10 << 6) | OPC_ADDUH_QB_DSP,
538     OPC_ADDQH_R_W  = (0x12 << 6) | OPC_ADDUH_QB_DSP,
539     OPC_SUBUH_QB   = (0x01 << 6) | OPC_ADDUH_QB_DSP,
540     OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
541     OPC_SUBQH_PH   = (0x09 << 6) | OPC_ADDUH_QB_DSP,
542     OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
543     OPC_SUBQH_W    = (0x11 << 6) | OPC_ADDUH_QB_DSP,
544     OPC_SUBQH_R_W  = (0x13 << 6) | OPC_ADDUH_QB_DSP,
545     /* MIPS DSP Multiply Sub-class insns */
546     OPC_MUL_PH     = (0x0C << 6) | OPC_ADDUH_QB_DSP,
547     OPC_MUL_S_PH   = (0x0E << 6) | OPC_ADDUH_QB_DSP,
548     OPC_MULQ_S_W   = (0x16 << 6) | OPC_ADDUH_QB_DSP,
549     OPC_MULQ_RS_W  = (0x17 << 6) | OPC_ADDUH_QB_DSP,
550 };
551 
552 #define MASK_ABSQ_S_PH(op)          (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
553 enum {
554     /* MIPS DSP Arithmetic Sub-class */
555     OPC_ABSQ_S_QB       = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
556     OPC_ABSQ_S_PH       = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
557     OPC_ABSQ_S_W        = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
558     OPC_PRECEQ_W_PHL    = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
559     OPC_PRECEQ_W_PHR    = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
560     OPC_PRECEQU_PH_QBL  = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
561     OPC_PRECEQU_PH_QBR  = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
562     OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
563     OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
564     OPC_PRECEU_PH_QBL   = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
565     OPC_PRECEU_PH_QBR   = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
566     OPC_PRECEU_PH_QBLA  = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
567     OPC_PRECEU_PH_QBRA  = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
568     /* DSP Bit/Manipulation Sub-class */
569     OPC_BITREV          = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
570     OPC_REPL_QB         = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
571     OPC_REPLV_QB        = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
572     OPC_REPL_PH         = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
573     OPC_REPLV_PH        = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
574 };
575 
576 #define MASK_CMPU_EQ_QB(op)         (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
577 enum {
578     /* MIPS DSP Arithmetic Sub-class */
579     OPC_PRECR_QB_PH      = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
580     OPC_PRECRQ_QB_PH     = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
581     OPC_PRECR_SRA_PH_W   = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
582     OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
583     OPC_PRECRQ_PH_W      = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
584     OPC_PRECRQ_RS_PH_W   = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
585     OPC_PRECRQU_S_QB_PH  = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
586     /* DSP Compare-Pick Sub-class */
587     OPC_CMPU_EQ_QB       = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
588     OPC_CMPU_LT_QB       = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
589     OPC_CMPU_LE_QB       = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
590     OPC_CMPGU_EQ_QB      = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
591     OPC_CMPGU_LT_QB      = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
592     OPC_CMPGU_LE_QB      = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
593     OPC_CMPGDU_EQ_QB     = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
594     OPC_CMPGDU_LT_QB     = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
595     OPC_CMPGDU_LE_QB     = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
596     OPC_CMP_EQ_PH        = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
597     OPC_CMP_LT_PH        = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
598     OPC_CMP_LE_PH        = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
599     OPC_PICK_QB          = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
600     OPC_PICK_PH          = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
601     OPC_PACKRL_PH        = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
602 };
603 
604 #define MASK_SHLL_QB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
605 enum {
606     /* MIPS DSP GPR-Based Shift Sub-class */
607     OPC_SHLL_QB    = (0x00 << 6) | OPC_SHLL_QB_DSP,
608     OPC_SHLLV_QB   = (0x02 << 6) | OPC_SHLL_QB_DSP,
609     OPC_SHLL_PH    = (0x08 << 6) | OPC_SHLL_QB_DSP,
610     OPC_SHLLV_PH   = (0x0A << 6) | OPC_SHLL_QB_DSP,
611     OPC_SHLL_S_PH  = (0x0C << 6) | OPC_SHLL_QB_DSP,
612     OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
613     OPC_SHLL_S_W   = (0x14 << 6) | OPC_SHLL_QB_DSP,
614     OPC_SHLLV_S_W  = (0x16 << 6) | OPC_SHLL_QB_DSP,
615     OPC_SHRL_QB    = (0x01 << 6) | OPC_SHLL_QB_DSP,
616     OPC_SHRLV_QB   = (0x03 << 6) | OPC_SHLL_QB_DSP,
617     OPC_SHRL_PH    = (0x19 << 6) | OPC_SHLL_QB_DSP,
618     OPC_SHRLV_PH   = (0x1B << 6) | OPC_SHLL_QB_DSP,
619     OPC_SHRA_QB    = (0x04 << 6) | OPC_SHLL_QB_DSP,
620     OPC_SHRA_R_QB  = (0x05 << 6) | OPC_SHLL_QB_DSP,
621     OPC_SHRAV_QB   = (0x06 << 6) | OPC_SHLL_QB_DSP,
622     OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
623     OPC_SHRA_PH    = (0x09 << 6) | OPC_SHLL_QB_DSP,
624     OPC_SHRAV_PH   = (0x0B << 6) | OPC_SHLL_QB_DSP,
625     OPC_SHRA_R_PH  = (0x0D << 6) | OPC_SHLL_QB_DSP,
626     OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
627     OPC_SHRA_R_W   = (0x15 << 6) | OPC_SHLL_QB_DSP,
628     OPC_SHRAV_R_W  = (0x17 << 6) | OPC_SHLL_QB_DSP,
629 };
630 
631 #define MASK_DPA_W_PH(op)           (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
632 enum {
633     /* MIPS DSP Multiply Sub-class insns */
634     OPC_DPAU_H_QBL    = (0x03 << 6) | OPC_DPA_W_PH_DSP,
635     OPC_DPAU_H_QBR    = (0x07 << 6) | OPC_DPA_W_PH_DSP,
636     OPC_DPSU_H_QBL    = (0x0B << 6) | OPC_DPA_W_PH_DSP,
637     OPC_DPSU_H_QBR    = (0x0F << 6) | OPC_DPA_W_PH_DSP,
638     OPC_DPA_W_PH      = (0x00 << 6) | OPC_DPA_W_PH_DSP,
639     OPC_DPAX_W_PH     = (0x08 << 6) | OPC_DPA_W_PH_DSP,
640     OPC_DPAQ_S_W_PH   = (0x04 << 6) | OPC_DPA_W_PH_DSP,
641     OPC_DPAQX_S_W_PH  = (0x18 << 6) | OPC_DPA_W_PH_DSP,
642     OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
643     OPC_DPS_W_PH      = (0x01 << 6) | OPC_DPA_W_PH_DSP,
644     OPC_DPSX_W_PH     = (0x09 << 6) | OPC_DPA_W_PH_DSP,
645     OPC_DPSQ_S_W_PH   = (0x05 << 6) | OPC_DPA_W_PH_DSP,
646     OPC_DPSQX_S_W_PH  = (0x19 << 6) | OPC_DPA_W_PH_DSP,
647     OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
648     OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
649     OPC_DPAQ_SA_L_W   = (0x0C << 6) | OPC_DPA_W_PH_DSP,
650     OPC_DPSQ_SA_L_W   = (0x0D << 6) | OPC_DPA_W_PH_DSP,
651     OPC_MAQ_S_W_PHL   = (0x14 << 6) | OPC_DPA_W_PH_DSP,
652     OPC_MAQ_S_W_PHR   = (0x16 << 6) | OPC_DPA_W_PH_DSP,
653     OPC_MAQ_SA_W_PHL  = (0x10 << 6) | OPC_DPA_W_PH_DSP,
654     OPC_MAQ_SA_W_PHR  = (0x12 << 6) | OPC_DPA_W_PH_DSP,
655     OPC_MULSA_W_PH    = (0x02 << 6) | OPC_DPA_W_PH_DSP,
656 };
657 
658 #define MASK_INSV(op)               (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
659 enum {
660     /* DSP Bit/Manipulation Sub-class */
661     OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
662 };
663 
664 #define MASK_APPEND(op)             (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
665 enum {
666     /* MIPS DSP Append Sub-class */
667     OPC_APPEND  = (0x00 << 6) | OPC_APPEND_DSP,
668     OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
669     OPC_BALIGN  = (0x10 << 6) | OPC_APPEND_DSP,
670 };
671 
672 #define MASK_EXTR_W(op)             (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
673 enum {
674     /* MIPS DSP Accumulator and DSPControl Access Sub-class */
675     OPC_EXTR_W     = (0x00 << 6) | OPC_EXTR_W_DSP,
676     OPC_EXTR_R_W   = (0x04 << 6) | OPC_EXTR_W_DSP,
677     OPC_EXTR_RS_W  = (0x06 << 6) | OPC_EXTR_W_DSP,
678     OPC_EXTR_S_H   = (0x0E << 6) | OPC_EXTR_W_DSP,
679     OPC_EXTRV_S_H  = (0x0F << 6) | OPC_EXTR_W_DSP,
680     OPC_EXTRV_W    = (0x01 << 6) | OPC_EXTR_W_DSP,
681     OPC_EXTRV_R_W  = (0x05 << 6) | OPC_EXTR_W_DSP,
682     OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
683     OPC_EXTP       = (0x02 << 6) | OPC_EXTR_W_DSP,
684     OPC_EXTPV      = (0x03 << 6) | OPC_EXTR_W_DSP,
685     OPC_EXTPDP     = (0x0A << 6) | OPC_EXTR_W_DSP,
686     OPC_EXTPDPV    = (0x0B << 6) | OPC_EXTR_W_DSP,
687     OPC_SHILO      = (0x1A << 6) | OPC_EXTR_W_DSP,
688     OPC_SHILOV     = (0x1B << 6) | OPC_EXTR_W_DSP,
689     OPC_MTHLIP     = (0x1F << 6) | OPC_EXTR_W_DSP,
690     OPC_WRDSP      = (0x13 << 6) | OPC_EXTR_W_DSP,
691     OPC_RDDSP      = (0x12 << 6) | OPC_EXTR_W_DSP,
692 };
693 
694 #define MASK_ABSQ_S_QH(op)          (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
695 enum {
696     /* MIPS DSP Arithmetic Sub-class */
697     OPC_PRECEQ_L_PWL    = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
698     OPC_PRECEQ_L_PWR    = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
699     OPC_PRECEQ_PW_QHL   = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
700     OPC_PRECEQ_PW_QHR   = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
701     OPC_PRECEQ_PW_QHLA  = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
702     OPC_PRECEQ_PW_QHRA  = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
703     OPC_PRECEQU_QH_OBL  = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
704     OPC_PRECEQU_QH_OBR  = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
705     OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
706     OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
707     OPC_PRECEU_QH_OBL   = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
708     OPC_PRECEU_QH_OBR   = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
709     OPC_PRECEU_QH_OBLA  = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
710     OPC_PRECEU_QH_OBRA  = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
711     OPC_ABSQ_S_OB       = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
712     OPC_ABSQ_S_PW       = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
713     OPC_ABSQ_S_QH       = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
714     /* DSP Bit/Manipulation Sub-class */
715     OPC_REPL_OB         = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
716     OPC_REPL_PW         = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
717     OPC_REPL_QH         = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
718     OPC_REPLV_OB        = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
719     OPC_REPLV_PW        = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
720     OPC_REPLV_QH        = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
721 };
722 
723 #define MASK_ADDU_OB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
724 enum {
725     /* MIPS DSP Multiply Sub-class insns */
726     OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
727     OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
728     OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
729     OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
730     OPC_MULQ_RS_QH     = (0x1F << 6) | OPC_ADDU_OB_DSP,
731     /* MIPS DSP Arithmetic Sub-class */
732     OPC_RADDU_L_OB     = (0x14 << 6) | OPC_ADDU_OB_DSP,
733     OPC_SUBQ_PW        = (0x13 << 6) | OPC_ADDU_OB_DSP,
734     OPC_SUBQ_S_PW      = (0x17 << 6) | OPC_ADDU_OB_DSP,
735     OPC_SUBQ_QH        = (0x0B << 6) | OPC_ADDU_OB_DSP,
736     OPC_SUBQ_S_QH      = (0x0F << 6) | OPC_ADDU_OB_DSP,
737     OPC_SUBU_OB        = (0x01 << 6) | OPC_ADDU_OB_DSP,
738     OPC_SUBU_S_OB      = (0x05 << 6) | OPC_ADDU_OB_DSP,
739     OPC_SUBU_QH        = (0x09 << 6) | OPC_ADDU_OB_DSP,
740     OPC_SUBU_S_QH      = (0x0D << 6) | OPC_ADDU_OB_DSP,
741     OPC_SUBUH_OB       = (0x19 << 6) | OPC_ADDU_OB_DSP,
742     OPC_SUBUH_R_OB     = (0x1B << 6) | OPC_ADDU_OB_DSP,
743     OPC_ADDQ_PW        = (0x12 << 6) | OPC_ADDU_OB_DSP,
744     OPC_ADDQ_S_PW      = (0x16 << 6) | OPC_ADDU_OB_DSP,
745     OPC_ADDQ_QH        = (0x0A << 6) | OPC_ADDU_OB_DSP,
746     OPC_ADDQ_S_QH      = (0x0E << 6) | OPC_ADDU_OB_DSP,
747     OPC_ADDU_OB        = (0x00 << 6) | OPC_ADDU_OB_DSP,
748     OPC_ADDU_S_OB      = (0x04 << 6) | OPC_ADDU_OB_DSP,
749     OPC_ADDU_QH        = (0x08 << 6) | OPC_ADDU_OB_DSP,
750     OPC_ADDU_S_QH      = (0x0C << 6) | OPC_ADDU_OB_DSP,
751     OPC_ADDUH_OB       = (0x18 << 6) | OPC_ADDU_OB_DSP,
752     OPC_ADDUH_R_OB     = (0x1A << 6) | OPC_ADDU_OB_DSP,
753 };
754 
755 #define MASK_CMPU_EQ_OB(op)         (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
756 enum {
757     /* DSP Compare-Pick Sub-class */
758     OPC_CMP_EQ_PW         = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
759     OPC_CMP_LT_PW         = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
760     OPC_CMP_LE_PW         = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
761     OPC_CMP_EQ_QH         = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
762     OPC_CMP_LT_QH         = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
763     OPC_CMP_LE_QH         = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
764     OPC_CMPGDU_EQ_OB      = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
765     OPC_CMPGDU_LT_OB      = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
766     OPC_CMPGDU_LE_OB      = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
767     OPC_CMPGU_EQ_OB       = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
768     OPC_CMPGU_LT_OB       = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
769     OPC_CMPGU_LE_OB       = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
770     OPC_CMPU_EQ_OB        = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
771     OPC_CMPU_LT_OB        = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
772     OPC_CMPU_LE_OB        = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
773     OPC_PACKRL_PW         = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
774     OPC_PICK_OB           = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
775     OPC_PICK_PW           = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
776     OPC_PICK_QH           = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
777     /* MIPS DSP Arithmetic Sub-class */
778     OPC_PRECR_OB_QH       = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
779     OPC_PRECR_SRA_QH_PW   = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
780     OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
781     OPC_PRECRQ_OB_QH      = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
782     OPC_PRECRQ_PW_L       = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
783     OPC_PRECRQ_QH_PW      = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
784     OPC_PRECRQ_RS_QH_PW   = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
785     OPC_PRECRQU_S_OB_QH   = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
786 };
787 
788 #define MASK_DAPPEND(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
789 enum {
790     /* DSP Append Sub-class */
791     OPC_DAPPEND  = (0x00 << 6) | OPC_DAPPEND_DSP,
792     OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
793     OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
794     OPC_DBALIGN  = (0x10 << 6) | OPC_DAPPEND_DSP,
795 };
796 
797 #define MASK_DEXTR_W(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
798 enum {
799     /* MIPS DSP Accumulator and DSPControl Access Sub-class */
800     OPC_DMTHLIP     = (0x1F << 6) | OPC_DEXTR_W_DSP,
801     OPC_DSHILO      = (0x1A << 6) | OPC_DEXTR_W_DSP,
802     OPC_DEXTP       = (0x02 << 6) | OPC_DEXTR_W_DSP,
803     OPC_DEXTPDP     = (0x0A << 6) | OPC_DEXTR_W_DSP,
804     OPC_DEXTPDPV    = (0x0B << 6) | OPC_DEXTR_W_DSP,
805     OPC_DEXTPV      = (0x03 << 6) | OPC_DEXTR_W_DSP,
806     OPC_DEXTR_L     = (0x10 << 6) | OPC_DEXTR_W_DSP,
807     OPC_DEXTR_R_L   = (0x14 << 6) | OPC_DEXTR_W_DSP,
808     OPC_DEXTR_RS_L  = (0x16 << 6) | OPC_DEXTR_W_DSP,
809     OPC_DEXTR_W     = (0x00 << 6) | OPC_DEXTR_W_DSP,
810     OPC_DEXTR_R_W   = (0x04 << 6) | OPC_DEXTR_W_DSP,
811     OPC_DEXTR_RS_W  = (0x06 << 6) | OPC_DEXTR_W_DSP,
812     OPC_DEXTR_S_H   = (0x0E << 6) | OPC_DEXTR_W_DSP,
813     OPC_DEXTRV_L    = (0x11 << 6) | OPC_DEXTR_W_DSP,
814     OPC_DEXTRV_R_L  = (0x15 << 6) | OPC_DEXTR_W_DSP,
815     OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
816     OPC_DEXTRV_S_H  = (0x0F << 6) | OPC_DEXTR_W_DSP,
817     OPC_DEXTRV_W    = (0x01 << 6) | OPC_DEXTR_W_DSP,
818     OPC_DEXTRV_R_W  = (0x05 << 6) | OPC_DEXTR_W_DSP,
819     OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
820     OPC_DSHILOV     = (0x1B << 6) | OPC_DEXTR_W_DSP,
821 };
822 
823 #define MASK_DINSV(op)              (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
824 enum {
825     /* DSP Bit/Manipulation Sub-class */
826     OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
827 };
828 
829 #define MASK_DPAQ_W_QH(op)          (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
830 enum {
831     /* MIPS DSP Multiply Sub-class insns */
832     OPC_DMADD         = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
833     OPC_DMADDU        = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
834     OPC_DMSUB         = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
835     OPC_DMSUBU        = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
836     OPC_DPA_W_QH      = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
837     OPC_DPAQ_S_W_QH   = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
838     OPC_DPAQ_SA_L_PW  = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
839     OPC_DPAU_H_OBL    = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
840     OPC_DPAU_H_OBR    = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
841     OPC_DPS_W_QH      = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
842     OPC_DPSQ_S_W_QH   = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
843     OPC_DPSQ_SA_L_PW  = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
844     OPC_DPSU_H_OBL    = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
845     OPC_DPSU_H_OBR    = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
846     OPC_MAQ_S_L_PWL   = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
847     OPC_MAQ_S_L_PWR   = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
848     OPC_MAQ_S_W_QHLL  = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
849     OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
850     OPC_MAQ_S_W_QHLR  = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
851     OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
852     OPC_MAQ_S_W_QHRL  = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
853     OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
854     OPC_MAQ_S_W_QHRR  = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
855     OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
856     OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
857     OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
858 };
859 
860 #define MASK_SHLL_OB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
861 enum {
862     /* MIPS DSP GPR-Based Shift Sub-class */
863     OPC_SHLL_PW    = (0x10 << 6) | OPC_SHLL_OB_DSP,
864     OPC_SHLL_S_PW  = (0x14 << 6) | OPC_SHLL_OB_DSP,
865     OPC_SHLLV_OB   = (0x02 << 6) | OPC_SHLL_OB_DSP,
866     OPC_SHLLV_PW   = (0x12 << 6) | OPC_SHLL_OB_DSP,
867     OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
868     OPC_SHLLV_QH   = (0x0A << 6) | OPC_SHLL_OB_DSP,
869     OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
870     OPC_SHRA_PW    = (0x11 << 6) | OPC_SHLL_OB_DSP,
871     OPC_SHRA_R_PW  = (0x15 << 6) | OPC_SHLL_OB_DSP,
872     OPC_SHRAV_OB   = (0x06 << 6) | OPC_SHLL_OB_DSP,
873     OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
874     OPC_SHRAV_PW   = (0x13 << 6) | OPC_SHLL_OB_DSP,
875     OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
876     OPC_SHRAV_QH   = (0x0B << 6) | OPC_SHLL_OB_DSP,
877     OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
878     OPC_SHRLV_OB   = (0x03 << 6) | OPC_SHLL_OB_DSP,
879     OPC_SHRLV_QH   = (0x1B << 6) | OPC_SHLL_OB_DSP,
880     OPC_SHLL_OB    = (0x00 << 6) | OPC_SHLL_OB_DSP,
881     OPC_SHLL_QH    = (0x08 << 6) | OPC_SHLL_OB_DSP,
882     OPC_SHLL_S_QH  = (0x0C << 6) | OPC_SHLL_OB_DSP,
883     OPC_SHRA_OB    = (0x04 << 6) | OPC_SHLL_OB_DSP,
884     OPC_SHRA_R_OB  = (0x05 << 6) | OPC_SHLL_OB_DSP,
885     OPC_SHRA_QH    = (0x09 << 6) | OPC_SHLL_OB_DSP,
886     OPC_SHRA_R_QH  = (0x0D << 6) | OPC_SHLL_OB_DSP,
887     OPC_SHRL_OB    = (0x01 << 6) | OPC_SHLL_OB_DSP,
888     OPC_SHRL_QH    = (0x19 << 6) | OPC_SHLL_OB_DSP,
889 };
890 
891 /* Coprocessor 0 (rs field) */
892 #define MASK_CP0(op)                (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
893 
894 enum {
895     OPC_MFC0     = (0x00 << 21) | OPC_CP0,
896     OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
897     OPC_MFHC0    = (0x02 << 21) | OPC_CP0,
898     OPC_MTC0     = (0x04 << 21) | OPC_CP0,
899     OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
900     OPC_MTHC0    = (0x06 << 21) | OPC_CP0,
901     OPC_MFTR     = (0x08 << 21) | OPC_CP0,
902     OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
903     OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
904     OPC_MTTR     = (0x0C << 21) | OPC_CP0,
905     OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
906     OPC_C0       = (0x10 << 21) | OPC_CP0,
907     OPC_C0_1     = (0x11 << 21) | OPC_CP0,
908     OPC_C0_2     = (0x12 << 21) | OPC_CP0,
909     OPC_C0_3     = (0x13 << 21) | OPC_CP0,
910     OPC_C0_4     = (0x14 << 21) | OPC_CP0,
911     OPC_C0_5     = (0x15 << 21) | OPC_CP0,
912     OPC_C0_6     = (0x16 << 21) | OPC_CP0,
913     OPC_C0_7     = (0x17 << 21) | OPC_CP0,
914     OPC_C0_8     = (0x18 << 21) | OPC_CP0,
915     OPC_C0_9     = (0x19 << 21) | OPC_CP0,
916     OPC_C0_A     = (0x1A << 21) | OPC_CP0,
917     OPC_C0_B     = (0x1B << 21) | OPC_CP0,
918     OPC_C0_C     = (0x1C << 21) | OPC_CP0,
919     OPC_C0_D     = (0x1D << 21) | OPC_CP0,
920     OPC_C0_E     = (0x1E << 21) | OPC_CP0,
921     OPC_C0_F     = (0x1F << 21) | OPC_CP0,
922 };
923 
924 /* MFMC0 opcodes */
925 #define MASK_MFMC0(op)              (MASK_CP0(op) | (op & 0xFFFF))
926 
927 enum {
928     OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
929     OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
930     OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
931     OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
932     OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
933     OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
934     OPC_DVP      = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
935     OPC_EVP      = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
936 };
937 
938 /* Coprocessor 0 (with rs == C0) */
939 #define MASK_C0(op)                 (MASK_CP0(op) | (op & 0x3F))
940 
941 enum {
942     OPC_TLBR     = 0x01 | OPC_C0,
943     OPC_TLBWI    = 0x02 | OPC_C0,
944     OPC_TLBINV   = 0x03 | OPC_C0,
945     OPC_TLBINVF  = 0x04 | OPC_C0,
946     OPC_TLBWR    = 0x06 | OPC_C0,
947     OPC_TLBP     = 0x08 | OPC_C0,
948     OPC_RFE      = 0x10 | OPC_C0,
949     OPC_ERET     = 0x18 | OPC_C0,
950     OPC_DERET    = 0x1F | OPC_C0,
951     OPC_WAIT     = 0x20 | OPC_C0,
952 };
953 
954 #define MASK_CP2(op)                (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
955 
956 enum {
957     OPC_MFC2    = (0x00 << 21) | OPC_CP2,
958     OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
959     OPC_CFC2    = (0x02 << 21) | OPC_CP2,
960     OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
961     OPC_MTC2    = (0x04 << 21) | OPC_CP2,
962     OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
963     OPC_CTC2    = (0x06 << 21) | OPC_CP2,
964     OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
965     OPC_BC2     = (0x08 << 21) | OPC_CP2,
966     OPC_BC2EQZ  = (0x09 << 21) | OPC_CP2,
967     OPC_BC2NEZ  = (0x0D << 21) | OPC_CP2,
968 };
969 
970 #define MASK_LMMI(op)    (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
971 
972 enum {
973     OPC_PADDSH      = (24 << 21) | (0x00) | OPC_CP2,
974     OPC_PADDUSH     = (25 << 21) | (0x00) | OPC_CP2,
975     OPC_PADDH       = (26 << 21) | (0x00) | OPC_CP2,
976     OPC_PADDW       = (27 << 21) | (0x00) | OPC_CP2,
977     OPC_PADDSB      = (28 << 21) | (0x00) | OPC_CP2,
978     OPC_PADDUSB     = (29 << 21) | (0x00) | OPC_CP2,
979     OPC_PADDB       = (30 << 21) | (0x00) | OPC_CP2,
980     OPC_PADDD       = (31 << 21) | (0x00) | OPC_CP2,
981 
982     OPC_PSUBSH      = (24 << 21) | (0x01) | OPC_CP2,
983     OPC_PSUBUSH     = (25 << 21) | (0x01) | OPC_CP2,
984     OPC_PSUBH       = (26 << 21) | (0x01) | OPC_CP2,
985     OPC_PSUBW       = (27 << 21) | (0x01) | OPC_CP2,
986     OPC_PSUBSB      = (28 << 21) | (0x01) | OPC_CP2,
987     OPC_PSUBUSB     = (29 << 21) | (0x01) | OPC_CP2,
988     OPC_PSUBB       = (30 << 21) | (0x01) | OPC_CP2,
989     OPC_PSUBD       = (31 << 21) | (0x01) | OPC_CP2,
990 
991     OPC_PSHUFH      = (24 << 21) | (0x02) | OPC_CP2,
992     OPC_PACKSSWH    = (25 << 21) | (0x02) | OPC_CP2,
993     OPC_PACKSSHB    = (26 << 21) | (0x02) | OPC_CP2,
994     OPC_PACKUSHB    = (27 << 21) | (0x02) | OPC_CP2,
995     OPC_XOR_CP2     = (28 << 21) | (0x02) | OPC_CP2,
996     OPC_NOR_CP2     = (29 << 21) | (0x02) | OPC_CP2,
997     OPC_AND_CP2     = (30 << 21) | (0x02) | OPC_CP2,
998     OPC_PANDN       = (31 << 21) | (0x02) | OPC_CP2,
999 
1000     OPC_PUNPCKLHW   = (24 << 21) | (0x03) | OPC_CP2,
1001     OPC_PUNPCKHHW   = (25 << 21) | (0x03) | OPC_CP2,
1002     OPC_PUNPCKLBH   = (26 << 21) | (0x03) | OPC_CP2,
1003     OPC_PUNPCKHBH   = (27 << 21) | (0x03) | OPC_CP2,
1004     OPC_PINSRH_0    = (28 << 21) | (0x03) | OPC_CP2,
1005     OPC_PINSRH_1    = (29 << 21) | (0x03) | OPC_CP2,
1006     OPC_PINSRH_2    = (30 << 21) | (0x03) | OPC_CP2,
1007     OPC_PINSRH_3    = (31 << 21) | (0x03) | OPC_CP2,
1008 
1009     OPC_PAVGH       = (24 << 21) | (0x08) | OPC_CP2,
1010     OPC_PAVGB       = (25 << 21) | (0x08) | OPC_CP2,
1011     OPC_PMAXSH      = (26 << 21) | (0x08) | OPC_CP2,
1012     OPC_PMINSH      = (27 << 21) | (0x08) | OPC_CP2,
1013     OPC_PMAXUB      = (28 << 21) | (0x08) | OPC_CP2,
1014     OPC_PMINUB      = (29 << 21) | (0x08) | OPC_CP2,
1015 
1016     OPC_PCMPEQW     = (24 << 21) | (0x09) | OPC_CP2,
1017     OPC_PCMPGTW     = (25 << 21) | (0x09) | OPC_CP2,
1018     OPC_PCMPEQH     = (26 << 21) | (0x09) | OPC_CP2,
1019     OPC_PCMPGTH     = (27 << 21) | (0x09) | OPC_CP2,
1020     OPC_PCMPEQB     = (28 << 21) | (0x09) | OPC_CP2,
1021     OPC_PCMPGTB     = (29 << 21) | (0x09) | OPC_CP2,
1022 
1023     OPC_PSLLW       = (24 << 21) | (0x0A) | OPC_CP2,
1024     OPC_PSLLH       = (25 << 21) | (0x0A) | OPC_CP2,
1025     OPC_PMULLH      = (26 << 21) | (0x0A) | OPC_CP2,
1026     OPC_PMULHH      = (27 << 21) | (0x0A) | OPC_CP2,
1027     OPC_PMULUW      = (28 << 21) | (0x0A) | OPC_CP2,
1028     OPC_PMULHUH     = (29 << 21) | (0x0A) | OPC_CP2,
1029 
1030     OPC_PSRLW       = (24 << 21) | (0x0B) | OPC_CP2,
1031     OPC_PSRLH       = (25 << 21) | (0x0B) | OPC_CP2,
1032     OPC_PSRAW       = (26 << 21) | (0x0B) | OPC_CP2,
1033     OPC_PSRAH       = (27 << 21) | (0x0B) | OPC_CP2,
1034     OPC_PUNPCKLWD   = (28 << 21) | (0x0B) | OPC_CP2,
1035     OPC_PUNPCKHWD   = (29 << 21) | (0x0B) | OPC_CP2,
1036 
1037     OPC_ADDU_CP2    = (24 << 21) | (0x0C) | OPC_CP2,
1038     OPC_OR_CP2      = (25 << 21) | (0x0C) | OPC_CP2,
1039     OPC_ADD_CP2     = (26 << 21) | (0x0C) | OPC_CP2,
1040     OPC_DADD_CP2    = (27 << 21) | (0x0C) | OPC_CP2,
1041     OPC_SEQU_CP2    = (28 << 21) | (0x0C) | OPC_CP2,
1042     OPC_SEQ_CP2     = (29 << 21) | (0x0C) | OPC_CP2,
1043 
1044     OPC_SUBU_CP2    = (24 << 21) | (0x0D) | OPC_CP2,
1045     OPC_PASUBUB     = (25 << 21) | (0x0D) | OPC_CP2,
1046     OPC_SUB_CP2     = (26 << 21) | (0x0D) | OPC_CP2,
1047     OPC_DSUB_CP2    = (27 << 21) | (0x0D) | OPC_CP2,
1048     OPC_SLTU_CP2    = (28 << 21) | (0x0D) | OPC_CP2,
1049     OPC_SLT_CP2     = (29 << 21) | (0x0D) | OPC_CP2,
1050 
1051     OPC_SLL_CP2     = (24 << 21) | (0x0E) | OPC_CP2,
1052     OPC_DSLL_CP2    = (25 << 21) | (0x0E) | OPC_CP2,
1053     OPC_PEXTRH      = (26 << 21) | (0x0E) | OPC_CP2,
1054     OPC_PMADDHW     = (27 << 21) | (0x0E) | OPC_CP2,
1055     OPC_SLEU_CP2    = (28 << 21) | (0x0E) | OPC_CP2,
1056     OPC_SLE_CP2     = (29 << 21) | (0x0E) | OPC_CP2,
1057 
1058     OPC_SRL_CP2     = (24 << 21) | (0x0F) | OPC_CP2,
1059     OPC_DSRL_CP2    = (25 << 21) | (0x0F) | OPC_CP2,
1060     OPC_SRA_CP2     = (26 << 21) | (0x0F) | OPC_CP2,
1061     OPC_DSRA_CP2    = (27 << 21) | (0x0F) | OPC_CP2,
1062     OPC_BIADD       = (28 << 21) | (0x0F) | OPC_CP2,
1063     OPC_PMOVMSKB    = (29 << 21) | (0x0F) | OPC_CP2,
1064 };
1065 
1066 
1067 #define MASK_CP3(op)                (MASK_OP_MAJOR(op) | (op & 0x3F))
1068 
1069 enum {
1070     OPC_LWXC1       = 0x00 | OPC_CP3,
1071     OPC_LDXC1       = 0x01 | OPC_CP3,
1072     OPC_LUXC1       = 0x05 | OPC_CP3,
1073     OPC_SWXC1       = 0x08 | OPC_CP3,
1074     OPC_SDXC1       = 0x09 | OPC_CP3,
1075     OPC_SUXC1       = 0x0D | OPC_CP3,
1076     OPC_PREFX       = 0x0F | OPC_CP3,
1077     OPC_ALNV_PS     = 0x1E | OPC_CP3,
1078     OPC_MADD_S      = 0x20 | OPC_CP3,
1079     OPC_MADD_D      = 0x21 | OPC_CP3,
1080     OPC_MADD_PS     = 0x26 | OPC_CP3,
1081     OPC_MSUB_S      = 0x28 | OPC_CP3,
1082     OPC_MSUB_D      = 0x29 | OPC_CP3,
1083     OPC_MSUB_PS     = 0x2E | OPC_CP3,
1084     OPC_NMADD_S     = 0x30 | OPC_CP3,
1085     OPC_NMADD_D     = 0x31 | OPC_CP3,
1086     OPC_NMADD_PS    = 0x36 | OPC_CP3,
1087     OPC_NMSUB_S     = 0x38 | OPC_CP3,
1088     OPC_NMSUB_D     = 0x39 | OPC_CP3,
1089     OPC_NMSUB_PS    = 0x3E | OPC_CP3,
1090 };
1091 
1092 /*
1093  *     MMI (MultiMedia Instruction) encodings
1094  *     ======================================
1095  *
1096  * MMI instructions encoding table keys:
1097  *
1098  *     *   This code is reserved for future use. An attempt to execute it
1099  *         causes a Reserved Instruction exception.
1100  *     %   This code indicates an instruction class. The instruction word
1101  *         must be further decoded by examining additional tables that show
1102  *         the values for other instruction fields.
1103  *     #   This code is reserved for the unsupported instructions DMULT,
1104  *         DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
1105  *         to execute it causes a Reserved Instruction exception.
1106  *
1107  * MMI instructions encoded by opcode field (MMI, LQ, SQ):
1108  *
1109  *  31    26                                        0
1110  * +--------+----------------------------------------+
1111  * | opcode |                                        |
1112  * +--------+----------------------------------------+
1113  *
1114  *   opcode  bits 28..26
1115  *     bits |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7
1116  *   31..29 |  000  |  001  |  010  |  011  |  100  |  101  |  110  |  111
1117  *   -------+-------+-------+-------+-------+-------+-------+-------+-------
1118  *    0 000 |SPECIAL| REGIMM|   J   |  JAL  |  BEQ  |  BNE  |  BLEZ |  BGTZ
1119  *    1 001 |  ADDI | ADDIU |  SLTI | SLTIU |  ANDI |  ORI  |  XORI |  LUI
1120  *    2 010 |  COP0 |  COP1 |   *   |   *   |  BEQL |  BNEL | BLEZL | BGTZL
1121  *    3 011 | DADDI | DADDIU|  LDL  |  LDR  |  MMI% |   *   |   LQ  |   SQ
1122  *    4 100 |   LB  |   LH  |  LWL  |   LW  |  LBU  |  LHU  |  LWR  |  LWU
1123  *    5 101 |   SB  |   SH  |  SWL  |   SW  |  SDL  |  SDR  |  SWR  | CACHE
1124  *    6 110 |   #   |  LWC1 |   #   |  PREF |   #   |  LDC1 |   #   |   LD
1125  *    7 111 |   #   |  SWC1 |   #   |   *   |   #   |  SDC1 |   #   |   SD
1126  */
1127 
1128 enum {
1129     MMI_OPC_CLASS_MMI = 0x1C << 26,    /* Same as OPC_SPECIAL2 */
1130     MMI_OPC_SQ        = 0x1F << 26,    /* Same as OPC_SPECIAL3 */
1131 };
1132 
1133 /*
1134  * MMI instructions with opcode field = MMI:
1135  *
1136  *  31    26                                 5      0
1137  * +--------+-------------------------------+--------+
1138  * |   MMI  |                               |function|
1139  * +--------+-------------------------------+--------+
1140  *
1141  * function  bits 2..0
1142  *     bits |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7
1143  *     5..3 |  000  |  001  |  010  |  011  |  100  |  101  |  110  |  111
1144  *   -------+-------+-------+-------+-------+-------+-------+-------+-------
1145  *    0 000 |  MADD | MADDU |   *   |   *   | PLZCW |   *   |   *   |   *
1146  *    1 001 | MMI0% | MMI2% |   *   |   *   |   *   |   *   |   *   |   *
1147  *    2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 |   *   |   *   |   *   |   *
1148  *    3 011 | MULT1 | MULTU1|  DIV1 | DIVU1 |   *   |   *   |   *   |   *
1149  *    4 100 | MADD1 | MADDU1|   *   |   *   |   *   |   *   |   *   |   *
1150  *    5 101 | MMI1% | MMI3% |   *   |   *   |   *   |   *   |   *   |   *
1151  *    6 110 | PMFHL | PMTHL |   *   |   *   | PSLLH |   *   | PSRLH | PSRAH
1152  *    7 111 |   *   |   *   |   *   |   *   | PSLLW |   *   | PSRLW | PSRAW
1153  */
1154 
1155 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
1156 enum {
1157     MMI_OPC_MADD       = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */
1158     MMI_OPC_MADDU      = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */
1159     MMI_OPC_MULT1      = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */
1160     MMI_OPC_MULTU1     = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */
1161     MMI_OPC_DIV1       = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV  */
1162     MMI_OPC_DIVU1      = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */
1163     MMI_OPC_MADD1      = 0x20 | MMI_OPC_CLASS_MMI,
1164     MMI_OPC_MADDU1     = 0x21 | MMI_OPC_CLASS_MMI,
1165 };
1166 
1167 /* global register indices */
1168 TCGv cpu_gpr[32], cpu_PC;
1169 /*
1170  * For CPUs using 128-bit GPR registers, we put the lower halves in cpu_gpr[])
1171  * and the upper halves in cpu_gpr_hi[].
1172  */
1173 TCGv_i64 cpu_gpr_hi[32];
1174 TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
1175 static TCGv cpu_dspctrl, btarget;
1176 TCGv bcond;
1177 static TCGv cpu_lladdr, cpu_llval;
1178 static TCGv_i32 hflags;
1179 TCGv_i32 fpu_fcr0, fpu_fcr31;
1180 TCGv_i64 fpu_f64[32];
1181 
1182 static const char regnames_HI[][4] = {
1183     "HI0", "HI1", "HI2", "HI3",
1184 };
1185 
1186 static const char regnames_LO[][4] = {
1187     "LO0", "LO1", "LO2", "LO3",
1188 };
1189 
1190 /* General purpose registers moves. */
gen_load_gpr(TCGv t,int reg)1191 void gen_load_gpr(TCGv t, int reg)
1192 {
1193     assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr));
1194     if (reg == 0) {
1195         tcg_gen_movi_tl(t, 0);
1196     } else {
1197         tcg_gen_mov_tl(t, cpu_gpr[reg]);
1198     }
1199 }
1200 
gen_store_gpr(TCGv t,int reg)1201 void gen_store_gpr(TCGv t, int reg)
1202 {
1203     assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr));
1204     if (reg != 0) {
1205         tcg_gen_mov_tl(cpu_gpr[reg], t);
1206     }
1207 }
1208 
1209 #if defined(TARGET_MIPS64)
gen_load_gpr_hi(TCGv_i64 t,int reg)1210 void gen_load_gpr_hi(TCGv_i64 t, int reg)
1211 {
1212     assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr_hi));
1213     if (reg == 0) {
1214         tcg_gen_movi_i64(t, 0);
1215     } else {
1216         tcg_gen_mov_i64(t, cpu_gpr_hi[reg]);
1217     }
1218 }
1219 
gen_store_gpr_hi(TCGv_i64 t,int reg)1220 void gen_store_gpr_hi(TCGv_i64 t, int reg)
1221 {
1222     assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr_hi));
1223     if (reg != 0) {
1224         tcg_gen_mov_i64(cpu_gpr_hi[reg], t);
1225     }
1226 }
1227 #endif /* TARGET_MIPS64 */
1228 
1229 /* Moves to/from shadow registers. */
gen_load_srsgpr(int from,int to)1230 static inline void gen_load_srsgpr(int from, int to)
1231 {
1232     TCGv t0 = tcg_temp_new();
1233 
1234     if (from == 0) {
1235         tcg_gen_movi_tl(t0, 0);
1236     } else {
1237         TCGv_i32 t2 = tcg_temp_new_i32();
1238         TCGv_ptr addr = tcg_temp_new_ptr();
1239 
1240         tcg_gen_ld_i32(t2, tcg_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1241         tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1242         tcg_gen_andi_i32(t2, t2, 0xf);
1243         tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1244         tcg_gen_ext_i32_ptr(addr, t2);
1245         tcg_gen_add_ptr(addr, tcg_env, addr);
1246 
1247         tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1248     }
1249     gen_store_gpr(t0, to);
1250 }
1251 
gen_store_srsgpr(int from,int to)1252 static inline void gen_store_srsgpr(int from, int to)
1253 {
1254     if (to != 0) {
1255         TCGv t0 = tcg_temp_new();
1256         TCGv_i32 t2 = tcg_temp_new_i32();
1257         TCGv_ptr addr = tcg_temp_new_ptr();
1258 
1259         gen_load_gpr(t0, from);
1260         tcg_gen_ld_i32(t2, tcg_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1261         tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1262         tcg_gen_andi_i32(t2, t2, 0xf);
1263         tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1264         tcg_gen_ext_i32_ptr(addr, t2);
1265         tcg_gen_add_ptr(addr, tcg_env, addr);
1266 
1267         tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1268     }
1269 }
1270 
1271 /* Tests */
gen_save_pc(target_ulong pc)1272 static inline void gen_save_pc(target_ulong pc)
1273 {
1274     tcg_gen_movi_tl(cpu_PC, pc);
1275 }
1276 
save_cpu_state(DisasContext * ctx,int do_save_pc)1277 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1278 {
1279     LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1280     if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
1281         gen_save_pc(ctx->base.pc_next);
1282         ctx->saved_pc = ctx->base.pc_next;
1283     }
1284     if (ctx->hflags != ctx->saved_hflags) {
1285         tcg_gen_movi_i32(hflags, ctx->hflags);
1286         ctx->saved_hflags = ctx->hflags;
1287         switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1288         case MIPS_HFLAG_BR:
1289             break;
1290         case MIPS_HFLAG_BC:
1291         case MIPS_HFLAG_BL:
1292         case MIPS_HFLAG_B:
1293             tcg_gen_movi_tl(btarget, ctx->btarget);
1294             break;
1295         }
1296     }
1297 }
1298 
restore_cpu_state(CPUMIPSState * env,DisasContext * ctx)1299 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1300 {
1301     ctx->saved_hflags = ctx->hflags;
1302     switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1303     case MIPS_HFLAG_BR:
1304         break;
1305     case MIPS_HFLAG_BC:
1306     case MIPS_HFLAG_BL:
1307     case MIPS_HFLAG_B:
1308         ctx->btarget = env->btarget;
1309         break;
1310     }
1311 }
1312 
generate_exception_err(DisasContext * ctx,int excp,int err)1313 void generate_exception_err(DisasContext *ctx, int excp, int err)
1314 {
1315     save_cpu_state(ctx, 1);
1316     gen_helper_raise_exception_err(tcg_env, tcg_constant_i32(excp),
1317                                    tcg_constant_i32(err));
1318     ctx->base.is_jmp = DISAS_NORETURN;
1319 }
1320 
generate_exception(DisasContext * ctx,int excp)1321 void generate_exception(DisasContext *ctx, int excp)
1322 {
1323     gen_helper_raise_exception(tcg_env, tcg_constant_i32(excp));
1324 }
1325 
generate_exception_end(DisasContext * ctx,int excp)1326 void generate_exception_end(DisasContext *ctx, int excp)
1327 {
1328     generate_exception_err(ctx, excp, 0);
1329 }
1330 
generate_exception_break(DisasContext * ctx,int code)1331 void generate_exception_break(DisasContext *ctx, int code)
1332 {
1333 #ifdef CONFIG_USER_ONLY
1334     /* Pass the break code along to cpu_loop. */
1335     tcg_gen_st_i32(tcg_constant_i32(code), tcg_env,
1336                    offsetof(CPUMIPSState, error_code));
1337 #endif
1338     generate_exception_end(ctx, EXCP_BREAK);
1339 }
1340 
gen_reserved_instruction(DisasContext * ctx)1341 void gen_reserved_instruction(DisasContext *ctx)
1342 {
1343     generate_exception_end(ctx, EXCP_RI);
1344 }
1345 
1346 /* Floating point register moves. */
gen_load_fpr32(DisasContext * ctx,TCGv_i32 t,int reg)1347 void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1348 {
1349     if (ctx->hflags & MIPS_HFLAG_FRE) {
1350         generate_exception(ctx, EXCP_RI);
1351     }
1352     tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
1353 }
1354 
gen_store_fpr32(DisasContext * ctx,TCGv_i32 t,int reg)1355 void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1356 {
1357     TCGv_i64 t64;
1358     if (ctx->hflags & MIPS_HFLAG_FRE) {
1359         generate_exception(ctx, EXCP_RI);
1360     }
1361     t64 = tcg_temp_new_i64();
1362     tcg_gen_extu_i32_i64(t64, t);
1363     tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1364 }
1365 
gen_load_fpr32h(DisasContext * ctx,TCGv_i32 t,int reg)1366 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1367 {
1368     if (ctx->hflags & MIPS_HFLAG_F64) {
1369         tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
1370     } else {
1371         gen_load_fpr32(ctx, t, reg | 1);
1372     }
1373 }
1374 
gen_store_fpr32h(DisasContext * ctx,TCGv_i32 t,int reg)1375 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1376 {
1377     if (ctx->hflags & MIPS_HFLAG_F64) {
1378         TCGv_i64 t64 = tcg_temp_new_i64();
1379         tcg_gen_extu_i32_i64(t64, t);
1380         tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1381     } else {
1382         gen_store_fpr32(ctx, t, reg | 1);
1383     }
1384 }
1385 
gen_load_fpr64(DisasContext * ctx,TCGv_i64 t,int reg)1386 void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1387 {
1388     if (ctx->hflags & MIPS_HFLAG_F64) {
1389         tcg_gen_mov_i64(t, fpu_f64[reg]);
1390     } else {
1391         tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1392     }
1393 }
1394 
gen_store_fpr64(DisasContext * ctx,TCGv_i64 t,int reg)1395 void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1396 {
1397     if (ctx->hflags & MIPS_HFLAG_F64) {
1398         tcg_gen_mov_i64(fpu_f64[reg], t);
1399     } else {
1400         TCGv_i64 t0;
1401         tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1402         t0 = tcg_temp_new_i64();
1403         tcg_gen_shri_i64(t0, t, 32);
1404         tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1405     }
1406 }
1407 
get_fp_bit(int cc)1408 int get_fp_bit(int cc)
1409 {
1410     if (cc) {
1411         return 24 + cc;
1412     } else {
1413         return 23;
1414     }
1415 }
1416 
1417 /* Addresses computation */
gen_op_addr_add(DisasContext * ctx,TCGv ret,TCGv arg0,TCGv arg1)1418 void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1419 {
1420     tcg_gen_add_tl(ret, arg0, arg1);
1421 
1422 #if defined(TARGET_MIPS64)
1423     if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1424         tcg_gen_ext32s_i64(ret, ret);
1425     }
1426 #endif
1427 }
1428 
gen_op_addr_addi(DisasContext * ctx,TCGv ret,TCGv base,target_long ofs)1429 void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base, target_long ofs)
1430 {
1431     tcg_gen_addi_tl(ret, base, ofs);
1432 
1433 #if defined(TARGET_MIPS64)
1434     if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1435         tcg_gen_ext32s_i64(ret, ret);
1436     }
1437 #endif
1438 }
1439 
1440 /* Addresses computation (translation time) */
addr_add(DisasContext * ctx,target_long base,target_long offset)1441 static target_long addr_add(DisasContext *ctx, target_long base,
1442                             target_long offset)
1443 {
1444     target_long sum = base + offset;
1445 
1446 #if defined(TARGET_MIPS64)
1447     if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1448         sum = (int32_t)sum;
1449     }
1450 #endif
1451     return sum;
1452 }
1453 
1454 /* Sign-extract the low 32-bits to a target_long.  */
gen_move_low32(TCGv ret,TCGv_i64 arg)1455 void gen_move_low32(TCGv ret, TCGv_i64 arg)
1456 {
1457 #if defined(TARGET_MIPS64)
1458     tcg_gen_ext32s_i64(ret, arg);
1459 #else
1460     tcg_gen_extrl_i64_i32(ret, arg);
1461 #endif
1462 }
1463 
1464 /* Sign-extract the high 32-bits to a target_long.  */
gen_move_high32(TCGv ret,TCGv_i64 arg)1465 void gen_move_high32(TCGv ret, TCGv_i64 arg)
1466 {
1467 #if defined(TARGET_MIPS64)
1468     tcg_gen_sari_i64(ret, arg, 32);
1469 #else
1470     tcg_gen_extrh_i64_i32(ret, arg);
1471 #endif
1472 }
1473 
check_cp0_enabled(DisasContext * ctx)1474 bool check_cp0_enabled(DisasContext *ctx)
1475 {
1476     if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
1477         generate_exception_end(ctx, EXCP_CpU);
1478         return false;
1479     }
1480     return true;
1481 }
1482 
check_cp1_enabled(DisasContext * ctx)1483 void check_cp1_enabled(DisasContext *ctx)
1484 {
1485     if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) {
1486         generate_exception_err(ctx, EXCP_CpU, 1);
1487     }
1488 }
1489 
1490 /*
1491  * Verify that the processor is running with COP1X instructions enabled.
1492  * This is associated with the nabla symbol in the MIPS32 and MIPS64
1493  * opcode tables.
1494  */
check_cop1x(DisasContext * ctx)1495 void check_cop1x(DisasContext *ctx)
1496 {
1497     if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) {
1498         gen_reserved_instruction(ctx);
1499     }
1500 }
1501 
1502 /*
1503  * Verify that the processor is running with 64-bit floating-point
1504  * operations enabled.
1505  */
check_cp1_64bitmode(DisasContext * ctx)1506 void check_cp1_64bitmode(DisasContext *ctx)
1507 {
1508     if (unlikely(~ctx->hflags & MIPS_HFLAG_F64)) {
1509         gen_reserved_instruction(ctx);
1510     }
1511 }
1512 
1513 /*
1514  * Verify if floating point register is valid; an operation is not defined
1515  * if bit 0 of any register specification is set and the FR bit in the
1516  * Status register equals zero, since the register numbers specify an
1517  * even-odd pair of adjacent coprocessor general registers. When the FR bit
1518  * in the Status register equals one, both even and odd register numbers
1519  * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1520  *
1521  * Multiple 64 bit wide registers can be checked by calling
1522  * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1523  */
check_cp1_registers(DisasContext * ctx,int regs)1524 void check_cp1_registers(DisasContext *ctx, int regs)
1525 {
1526     if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) {
1527         gen_reserved_instruction(ctx);
1528     }
1529 }
1530 
1531 /*
1532  * Verify that the processor is running with DSP instructions enabled.
1533  * This is enabled by CP0 Status register MX(24) bit.
1534  */
check_dsp(DisasContext * ctx)1535 static inline void check_dsp(DisasContext *ctx)
1536 {
1537     if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1538         if (ctx->insn_flags & ASE_DSP) {
1539             generate_exception_end(ctx, EXCP_DSPDIS);
1540         } else {
1541             gen_reserved_instruction(ctx);
1542         }
1543     }
1544 }
1545 
check_dsp_r2(DisasContext * ctx)1546 static inline void check_dsp_r2(DisasContext *ctx)
1547 {
1548     if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
1549         if (ctx->insn_flags & ASE_DSP) {
1550             generate_exception_end(ctx, EXCP_DSPDIS);
1551         } else {
1552             gen_reserved_instruction(ctx);
1553         }
1554     }
1555 }
1556 
check_dsp_r3(DisasContext * ctx)1557 static inline void check_dsp_r3(DisasContext *ctx)
1558 {
1559     if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
1560         if (ctx->insn_flags & ASE_DSP) {
1561             generate_exception_end(ctx, EXCP_DSPDIS);
1562         } else {
1563             gen_reserved_instruction(ctx);
1564         }
1565     }
1566 }
1567 
1568 /*
1569  * This code generates a "reserved instruction" exception if the
1570  * CPU does not support the instruction set corresponding to flags.
1571  */
check_insn(DisasContext * ctx,uint64_t flags)1572 void check_insn(DisasContext *ctx, uint64_t flags)
1573 {
1574     if (unlikely(!(ctx->insn_flags & flags))) {
1575         gen_reserved_instruction(ctx);
1576     }
1577 }
1578 
1579 /*
1580  * This code generates a "reserved instruction" exception if the
1581  * CPU has corresponding flag set which indicates that the instruction
1582  * has been removed.
1583  */
check_insn_opc_removed(DisasContext * ctx,uint64_t flags)1584 static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
1585 {
1586     if (unlikely(ctx->insn_flags & flags)) {
1587         gen_reserved_instruction(ctx);
1588     }
1589 }
1590 
1591 /*
1592  * The Linux kernel traps certain reserved instruction exceptions to
1593  * emulate the corresponding instructions. QEMU is the kernel in user
1594  * mode, so those traps are emulated by accepting the instructions.
1595  *
1596  * A reserved instruction exception is generated for flagged CPUs if
1597  * QEMU runs in system mode.
1598  */
check_insn_opc_user_only(DisasContext * ctx,uint64_t flags)1599 static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
1600 {
1601 #ifndef CONFIG_USER_ONLY
1602     check_insn_opc_removed(ctx, flags);
1603 #endif
1604 }
1605 
1606 /*
1607  * This code generates a "reserved instruction" exception if the
1608  * CPU does not support 64-bit paired-single (PS) floating point data type.
1609  */
check_ps(DisasContext * ctx)1610 static inline void check_ps(DisasContext *ctx)
1611 {
1612     if (unlikely(!ctx->ps)) {
1613         generate_exception(ctx, EXCP_RI);
1614     }
1615     check_cp1_64bitmode(ctx);
1616 }
1617 
decode_64bit_enabled(DisasContext * ctx)1618 bool decode_64bit_enabled(DisasContext *ctx)
1619 {
1620     return ctx->hflags & MIPS_HFLAG_64;
1621 }
1622 
1623 /*
1624  * This code generates a "reserved instruction" exception if cpu is not
1625  * 64-bit or 64-bit instructions are not enabled.
1626  */
check_mips_64(DisasContext * ctx)1627 void check_mips_64(DisasContext *ctx)
1628 {
1629     if (unlikely((TARGET_LONG_BITS != 64) || !decode_64bit_enabled(ctx))) {
1630         gen_reserved_instruction(ctx);
1631     }
1632 }
1633 
1634 #ifndef CONFIG_USER_ONLY
check_mvh(DisasContext * ctx)1635 static inline void check_mvh(DisasContext *ctx)
1636 {
1637     if (unlikely(!ctx->mvh)) {
1638         generate_exception(ctx, EXCP_RI);
1639     }
1640 }
1641 #endif
1642 
1643 /*
1644  * This code generates a "reserved instruction" exception if the
1645  * Config5 XNP bit is set.
1646  */
check_xnp(DisasContext * ctx)1647 static inline void check_xnp(DisasContext *ctx)
1648 {
1649     if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
1650         gen_reserved_instruction(ctx);
1651     }
1652 }
1653 
1654 #ifndef CONFIG_USER_ONLY
1655 /*
1656  * This code generates a "reserved instruction" exception if the
1657  * Config3 PW bit is NOT set.
1658  */
check_pw(DisasContext * ctx)1659 static inline void check_pw(DisasContext *ctx)
1660 {
1661     if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
1662         gen_reserved_instruction(ctx);
1663     }
1664 }
1665 #endif
1666 
1667 /*
1668  * This code generates a "reserved instruction" exception if the
1669  * Config3 MT bit is NOT set.
1670  */
check_mt(DisasContext * ctx)1671 static inline void check_mt(DisasContext *ctx)
1672 {
1673     if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
1674         gen_reserved_instruction(ctx);
1675     }
1676 }
1677 
1678 #ifndef CONFIG_USER_ONLY
1679 /*
1680  * This code generates a "coprocessor unusable" exception if CP0 is not
1681  * available, and, if that is not the case, generates a "reserved instruction"
1682  * exception if the Config5 MT bit is NOT set. This is needed for availability
1683  * control of some of MT ASE instructions.
1684  */
check_cp0_mt(DisasContext * ctx)1685 static inline void check_cp0_mt(DisasContext *ctx)
1686 {
1687     if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
1688         generate_exception_end(ctx, EXCP_CpU);
1689     } else {
1690         if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
1691             gen_reserved_instruction(ctx);
1692         }
1693     }
1694 }
1695 #endif
1696 
1697 /*
1698  * This code generates a "reserved instruction" exception if the
1699  * Config5 NMS bit is set.
1700  */
check_nms(DisasContext * ctx)1701 static inline void check_nms(DisasContext *ctx)
1702 {
1703     if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
1704         gen_reserved_instruction(ctx);
1705     }
1706 }
1707 
1708 /*
1709  * This code generates a "reserved instruction" exception if the
1710  * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
1711  * Config2 TL, and Config5 L2C are unset.
1712  */
check_nms_dl_il_sl_tl_l2c(DisasContext * ctx)1713 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
1714 {
1715     if (unlikely((ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
1716                  !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
1717                  !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
1718                  !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
1719                  !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
1720                  !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))) {
1721         gen_reserved_instruction(ctx);
1722     }
1723 }
1724 
1725 /*
1726  * This code generates a "reserved instruction" exception if the
1727  * Config5 EVA bit is NOT set.
1728  */
check_eva(DisasContext * ctx)1729 static inline void check_eva(DisasContext *ctx)
1730 {
1731     if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
1732         gen_reserved_instruction(ctx);
1733     }
1734 }
1735 
1736 
1737 /*
1738  * Define small wrappers for gen_load_fpr* so that we have a uniform
1739  * calling interface for 32 and 64-bit FPRs.  No sense in changing
1740  * all callers for gen_load_fpr32 when we need the CTX parameter for
1741  * this one use.
1742  */
1743 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
1744 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1745 #define FOP_CONDS(type, abs, fmt, ifmt, bits)                                 \
1746 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
1747                                                int ft, int fs, int cc)        \
1748 {                                                                             \
1749     TCGv_i##bits fp0 = tcg_temp_new_i##bits();                                \
1750     TCGv_i##bits fp1 = tcg_temp_new_i##bits();                                \
1751     switch (ifmt) {                                                           \
1752     case FMT_PS:                                                              \
1753         check_ps(ctx);                                                        \
1754         break;                                                                \
1755     case FMT_D:                                                               \
1756         if (abs) {                                                            \
1757             check_cop1x(ctx);                                                 \
1758         }                                                                     \
1759         check_cp1_registers(ctx, fs | ft);                                    \
1760         break;                                                                \
1761     case FMT_S:                                                               \
1762         if (abs) {                                                            \
1763             check_cop1x(ctx);                                                 \
1764         }                                                                     \
1765         break;                                                                \
1766     }                                                                         \
1767     gen_ldcmp_fpr##bits(ctx, fp0, fs);                                        \
1768     gen_ldcmp_fpr##bits(ctx, fp1, ft);                                        \
1769     switch (n) {                                                              \
1770     case  0:                                                                  \
1771         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc);         \
1772     break;                                                                    \
1773     case  1:                                                                  \
1774         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc);        \
1775     break;                                                                    \
1776     case  2:                                                                  \
1777         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc);        \
1778     break;                                                                    \
1779     case  3:                                                                  \
1780         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc);       \
1781     break;                                                                    \
1782     case  4:                                                                  \
1783         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc);       \
1784     break;                                                                    \
1785     case  5:                                                                  \
1786         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc);       \
1787     break;                                                                    \
1788     case  6:                                                                  \
1789         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc);       \
1790     break;                                                                    \
1791     case  7:                                                                  \
1792         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc);       \
1793     break;                                                                    \
1794     case  8:                                                                  \
1795         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc);        \
1796     break;                                                                    \
1797     case  9:                                                                  \
1798         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc);      \
1799     break;                                                                    \
1800     case 10:                                                                  \
1801         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc);       \
1802     break;                                                                    \
1803     case 11:                                                                  \
1804         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc);       \
1805     break;                                                                    \
1806     case 12:                                                                  \
1807         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc);        \
1808     break;                                                                    \
1809     case 13:                                                                  \
1810         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc);       \
1811     break;                                                                    \
1812     case 14:                                                                  \
1813         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc);        \
1814     break;                                                                    \
1815     case 15:                                                                  \
1816         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc);       \
1817     break;                                                                    \
1818     default:                                                                  \
1819         abort();                                                              \
1820     }                                                                         \
1821 }
1822 
1823 FOP_CONDS(, 0, d, FMT_D, 64)
1824 FOP_CONDS(abs, 1, d, FMT_D, 64)
1825 FOP_CONDS(, 0, s, FMT_S, 32)
1826 FOP_CONDS(abs, 1, s, FMT_S, 32)
1827 FOP_CONDS(, 0, ps, FMT_PS, 64)
1828 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1829 #undef FOP_CONDS
1830 
1831 #define FOP_CONDNS(fmt, ifmt, bits, STORE)                              \
1832 static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n,         \
1833                                       int ft, int fs, int fd)           \
1834 {                                                                       \
1835     TCGv_i ## bits fp0 = tcg_temp_new_i ## bits();                      \
1836     TCGv_i ## bits fp1 = tcg_temp_new_i ## bits();                      \
1837     if (ifmt == FMT_D) {                                                \
1838         check_cp1_registers(ctx, fs | ft | fd);                         \
1839     }                                                                   \
1840     gen_ldcmp_fpr ## bits(ctx, fp0, fs);                                \
1841     gen_ldcmp_fpr ## bits(ctx, fp1, ft);                                \
1842     switch (n) {                                                        \
1843     case  0:                                                            \
1844         gen_helper_r6_cmp_ ## fmt ## _af(fp0, tcg_env, fp0, fp1);       \
1845         break;                                                          \
1846     case  1:                                                            \
1847         gen_helper_r6_cmp_ ## fmt ## _un(fp0, tcg_env, fp0, fp1);       \
1848         break;                                                          \
1849     case  2:                                                            \
1850         gen_helper_r6_cmp_ ## fmt ## _eq(fp0, tcg_env, fp0, fp1);       \
1851         break;                                                          \
1852     case  3:                                                            \
1853         gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, tcg_env, fp0, fp1);      \
1854         break;                                                          \
1855     case  4:                                                            \
1856         gen_helper_r6_cmp_ ## fmt ## _lt(fp0, tcg_env, fp0, fp1);       \
1857         break;                                                          \
1858     case  5:                                                            \
1859         gen_helper_r6_cmp_ ## fmt ## _ult(fp0, tcg_env, fp0, fp1);      \
1860         break;                                                          \
1861     case  6:                                                            \
1862         gen_helper_r6_cmp_ ## fmt ## _le(fp0, tcg_env, fp0, fp1);       \
1863         break;                                                          \
1864     case  7:                                                            \
1865         gen_helper_r6_cmp_ ## fmt ## _ule(fp0, tcg_env, fp0, fp1);      \
1866         break;                                                          \
1867     case  8:                                                            \
1868         gen_helper_r6_cmp_ ## fmt ## _saf(fp0, tcg_env, fp0, fp1);      \
1869         break;                                                          \
1870     case  9:                                                            \
1871         gen_helper_r6_cmp_ ## fmt ## _sun(fp0, tcg_env, fp0, fp1);      \
1872         break;                                                          \
1873     case 10:                                                            \
1874         gen_helper_r6_cmp_ ## fmt ## _seq(fp0, tcg_env, fp0, fp1);      \
1875         break;                                                          \
1876     case 11:                                                            \
1877         gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, tcg_env, fp0, fp1);     \
1878         break;                                                          \
1879     case 12:                                                            \
1880         gen_helper_r6_cmp_ ## fmt ## _slt(fp0, tcg_env, fp0, fp1);      \
1881         break;                                                          \
1882     case 13:                                                            \
1883         gen_helper_r6_cmp_ ## fmt ## _sult(fp0, tcg_env, fp0, fp1);     \
1884         break;                                                          \
1885     case 14:                                                            \
1886         gen_helper_r6_cmp_ ## fmt ## _sle(fp0, tcg_env, fp0, fp1);      \
1887         break;                                                          \
1888     case 15:                                                            \
1889         gen_helper_r6_cmp_ ## fmt ## _sule(fp0, tcg_env, fp0, fp1);     \
1890         break;                                                          \
1891     case 17:                                                            \
1892         gen_helper_r6_cmp_ ## fmt ## _or(fp0, tcg_env, fp0, fp1);       \
1893         break;                                                          \
1894     case 18:                                                            \
1895         gen_helper_r6_cmp_ ## fmt ## _une(fp0, tcg_env, fp0, fp1);      \
1896         break;                                                          \
1897     case 19:                                                            \
1898         gen_helper_r6_cmp_ ## fmt ## _ne(fp0, tcg_env, fp0, fp1);       \
1899         break;                                                          \
1900     case 25:                                                            \
1901         gen_helper_r6_cmp_ ## fmt ## _sor(fp0, tcg_env, fp0, fp1);      \
1902         break;                                                          \
1903     case 26:                                                            \
1904         gen_helper_r6_cmp_ ## fmt ## _sune(fp0, tcg_env, fp0, fp1);     \
1905         break;                                                          \
1906     case 27:                                                            \
1907         gen_helper_r6_cmp_ ## fmt ## _sne(fp0, tcg_env, fp0, fp1);      \
1908         break;                                                          \
1909     default:                                                            \
1910         abort();                                                        \
1911     }                                                                   \
1912     STORE;                                                              \
1913 }
1914 
1915 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
1916 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
1917 #undef FOP_CONDNS
1918 #undef gen_ldcmp_fpr32
1919 #undef gen_ldcmp_fpr64
1920 
1921 /* load/store instructions. */
1922 #ifdef CONFIG_USER_ONLY
1923 #define OP_LD_ATOMIC(insn, memop)                                          \
1924 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
1925                                 DisasContext *ctx)                         \
1926 {                                                                          \
1927     TCGv t0 = tcg_temp_new();                                              \
1928     tcg_gen_mov_tl(t0, arg1);                                              \
1929     tcg_gen_qemu_ld_tl(ret, arg1, ctx->mem_idx, memop);                    \
1930     tcg_gen_st_tl(t0, tcg_env, offsetof(CPUMIPSState, lladdr));            \
1931     tcg_gen_st_tl(ret, tcg_env, offsetof(CPUMIPSState, llval));            \
1932 }
1933 #else
1934 #define OP_LD_ATOMIC(insn, ignored_memop)                                  \
1935 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
1936                                 DisasContext *ctx)                         \
1937 {                                                                          \
1938     gen_helper_##insn(ret, tcg_env, arg1, tcg_constant_i32(mem_idx));      \
1939 }
1940 #endif
1941 OP_LD_ATOMIC(ll, mo_endian(ctx) | MO_SL);
1942 #if defined(TARGET_MIPS64)
1943 OP_LD_ATOMIC(lld, mo_endian(ctx) | MO_UQ);
1944 #endif
1945 #undef OP_LD_ATOMIC
1946 
gen_base_offset_addr(DisasContext * ctx,TCGv addr,int base,int offset)1947 void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset)
1948 {
1949     if (base == 0) {
1950         tcg_gen_movi_tl(addr, offset);
1951     } else if (offset == 0) {
1952         gen_load_gpr(addr, base);
1953     } else {
1954         tcg_gen_movi_tl(addr, offset);
1955         gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1956     }
1957 }
1958 
pc_relative_pc(DisasContext * ctx)1959 static target_ulong pc_relative_pc(DisasContext *ctx)
1960 {
1961     target_ulong pc = ctx->base.pc_next;
1962 
1963     if (ctx->hflags & MIPS_HFLAG_BMASK) {
1964         int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1965 
1966         pc -= branch_bytes;
1967     }
1968 
1969     pc &= ~(target_ulong)3;
1970     return pc;
1971 }
1972 
1973 /* LWL or LDL, depending on MemOp. */
gen_lxl(DisasContext * ctx,TCGv reg,TCGv addr,int mem_idx,MemOp mop)1974 static void gen_lxl(DisasContext *ctx, TCGv reg, TCGv addr,
1975                      int mem_idx, MemOp mop)
1976 {
1977     int sizem1 = memop_size(mop) - 1;
1978     TCGv t0 = tcg_temp_new();
1979     TCGv t1 = tcg_temp_new();
1980 
1981     /*
1982      * Do a byte access to possibly trigger a page
1983      * fault with the unaligned address.
1984      */
1985     tcg_gen_qemu_ld_tl(t1, addr, mem_idx, MO_UB);
1986     tcg_gen_andi_tl(t1, addr, sizem1);
1987     if (!disas_is_bigendian(ctx)) {
1988         tcg_gen_xori_tl(t1, t1, sizem1);
1989     }
1990     tcg_gen_shli_tl(t1, t1, 3);
1991     tcg_gen_andi_tl(t0, addr, ~sizem1);
1992     tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mop);
1993     tcg_gen_shl_tl(t0, t0, t1);
1994     tcg_gen_shl_tl(t1, tcg_constant_tl(-1), t1);
1995     tcg_gen_andc_tl(t1, reg, t1);
1996     tcg_gen_or_tl(reg, t0, t1);
1997 }
1998 
1999 /* LWR or LDR, depending on MemOp. */
gen_lxr(DisasContext * ctx,TCGv reg,TCGv addr,int mem_idx,MemOp mop)2000 static void gen_lxr(DisasContext *ctx, TCGv reg, TCGv addr,
2001                      int mem_idx, MemOp mop)
2002 {
2003     int size = memop_size(mop);
2004     int sizem1 = size - 1;
2005     TCGv t0 = tcg_temp_new();
2006     TCGv t1 = tcg_temp_new();
2007 
2008     /*
2009      * Do a byte access to possibly trigger a page
2010      * fault with the unaligned address.
2011      */
2012     tcg_gen_qemu_ld_tl(t1, addr, mem_idx, MO_UB);
2013     tcg_gen_andi_tl(t1, addr, sizem1);
2014     if (disas_is_bigendian(ctx)) {
2015         tcg_gen_xori_tl(t1, t1, sizem1);
2016     }
2017     tcg_gen_shli_tl(t1, t1, 3);
2018     tcg_gen_andi_tl(t0, addr, ~sizem1);
2019     tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mop);
2020     tcg_gen_shr_tl(t0, t0, t1);
2021     tcg_gen_xori_tl(t1, t1, size * 8 - 1);
2022     tcg_gen_shl_tl(t1, tcg_constant_tl(~1), t1);
2023     tcg_gen_and_tl(t1, reg, t1);
2024     tcg_gen_or_tl(reg, t0, t1);
2025 }
2026 
2027 /* Load */
gen_ld(DisasContext * ctx,uint32_t opc,int rt,int base,int offset)2028 static void gen_ld(DisasContext *ctx, uint32_t opc,
2029                    int rt, int base, int offset)
2030 {
2031     TCGv t0, t1;
2032     int mem_idx = ctx->mem_idx;
2033 
2034     if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F |
2035                                       INSN_LOONGSON3A)) {
2036         /*
2037          * Loongson CPU uses a load to zero register for prefetch.
2038          * We emulate it as a NOP. On other CPU we must perform the
2039          * actual memory access.
2040          */
2041         return;
2042     }
2043 
2044     t0 = tcg_temp_new();
2045     gen_base_offset_addr(ctx, t0, base, offset);
2046 
2047     switch (opc) {
2048 #if defined(TARGET_MIPS64)
2049     case OPC_LWU:
2050         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UL |
2051                            ctx->default_tcg_memop_mask);
2052         gen_store_gpr(t0, rt);
2053         break;
2054     case OPC_LD:
2055         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UQ |
2056                            ctx->default_tcg_memop_mask);
2057         gen_store_gpr(t0, rt);
2058         break;
2059     case OPC_LLD:
2060     case R6_OPC_LLD:
2061         op_ld_lld(t0, t0, mem_idx, ctx);
2062         gen_store_gpr(t0, rt);
2063         break;
2064     case OPC_LDL:
2065         t1 = tcg_temp_new();
2066         gen_load_gpr(t1, rt);
2067         gen_lxl(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UQ);
2068         gen_store_gpr(t1, rt);
2069         break;
2070     case OPC_LDR:
2071         t1 = tcg_temp_new();
2072         gen_load_gpr(t1, rt);
2073         gen_lxr(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UQ);
2074         gen_store_gpr(t1, rt);
2075         break;
2076     case OPC_LDPC:
2077         t1 = tcg_constant_tl(pc_relative_pc(ctx));
2078         gen_op_addr_add(ctx, t0, t0, t1);
2079         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UQ);
2080         gen_store_gpr(t0, rt);
2081         break;
2082 #endif
2083     case OPC_LWPC:
2084         t1 = tcg_constant_tl(pc_relative_pc(ctx));
2085         gen_op_addr_add(ctx, t0, t0, t1);
2086         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_SL);
2087         gen_store_gpr(t0, rt);
2088         break;
2089     case OPC_LWE:
2090         mem_idx = MIPS_HFLAG_UM;
2091         /* fall through */
2092     case OPC_LW:
2093         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_SL |
2094                            ctx->default_tcg_memop_mask);
2095         gen_store_gpr(t0, rt);
2096         break;
2097     case OPC_LHE:
2098         mem_idx = MIPS_HFLAG_UM;
2099         /* fall through */
2100     case OPC_LH:
2101         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_SW |
2102                            ctx->default_tcg_memop_mask);
2103         gen_store_gpr(t0, rt);
2104         break;
2105     case OPC_LHUE:
2106         mem_idx = MIPS_HFLAG_UM;
2107         /* fall through */
2108     case OPC_LHU:
2109         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UW |
2110                            ctx->default_tcg_memop_mask);
2111         gen_store_gpr(t0, rt);
2112         break;
2113     case OPC_LBE:
2114         mem_idx = MIPS_HFLAG_UM;
2115         /* fall through */
2116     case OPC_LB:
2117         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
2118         gen_store_gpr(t0, rt);
2119         break;
2120     case OPC_LBUE:
2121         mem_idx = MIPS_HFLAG_UM;
2122         /* fall through */
2123     case OPC_LBU:
2124         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
2125         gen_store_gpr(t0, rt);
2126         break;
2127     case OPC_LWLE:
2128         mem_idx = MIPS_HFLAG_UM;
2129         /* fall through */
2130     case OPC_LWL:
2131         t1 = tcg_temp_new();
2132         gen_load_gpr(t1, rt);
2133         gen_lxl(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UL);
2134         tcg_gen_ext32s_tl(t1, t1);
2135         gen_store_gpr(t1, rt);
2136         break;
2137     case OPC_LWRE:
2138         mem_idx = MIPS_HFLAG_UM;
2139         /* fall through */
2140     case OPC_LWR:
2141         t1 = tcg_temp_new();
2142         gen_load_gpr(t1, rt);
2143         gen_lxr(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UL);
2144         tcg_gen_ext32s_tl(t1, t1);
2145         gen_store_gpr(t1, rt);
2146         break;
2147     case OPC_LLE:
2148         mem_idx = MIPS_HFLAG_UM;
2149         /* fall through */
2150     case OPC_LL:
2151     case R6_OPC_LL:
2152         op_ld_ll(t0, t0, mem_idx, ctx);
2153         gen_store_gpr(t0, rt);
2154         break;
2155     }
2156 }
2157 
2158 /* Store */
gen_st(DisasContext * ctx,uint32_t opc,int rt,int base,int offset)2159 static void gen_st(DisasContext *ctx, uint32_t opc, int rt,
2160                    int base, int offset)
2161 {
2162     TCGv t0 = tcg_temp_new();
2163     TCGv t1 = tcg_temp_new();
2164     int mem_idx = ctx->mem_idx;
2165 
2166     gen_base_offset_addr(ctx, t0, base, offset);
2167     gen_load_gpr(t1, rt);
2168     switch (opc) {
2169 #if defined(TARGET_MIPS64)
2170     case OPC_SD:
2171         tcg_gen_qemu_st_tl(t1, t0, mem_idx, mo_endian(ctx) | MO_UQ |
2172                            ctx->default_tcg_memop_mask);
2173         break;
2174     case OPC_SDL:
2175         gen_helper_0e2i(sdl, t1, t0, mem_idx);
2176         break;
2177     case OPC_SDR:
2178         gen_helper_0e2i(sdr, t1, t0, mem_idx);
2179         break;
2180 #endif
2181     case OPC_SWE:
2182         mem_idx = MIPS_HFLAG_UM;
2183         /* fall through */
2184     case OPC_SW:
2185         tcg_gen_qemu_st_tl(t1, t0, mem_idx, mo_endian(ctx) | MO_UL |
2186                            ctx->default_tcg_memop_mask);
2187         break;
2188     case OPC_SHE:
2189         mem_idx = MIPS_HFLAG_UM;
2190         /* fall through */
2191     case OPC_SH:
2192         tcg_gen_qemu_st_tl(t1, t0, mem_idx, mo_endian(ctx) | MO_UW |
2193                            ctx->default_tcg_memop_mask);
2194         break;
2195     case OPC_SBE:
2196         mem_idx = MIPS_HFLAG_UM;
2197         /* fall through */
2198     case OPC_SB:
2199         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
2200         break;
2201     case OPC_SWLE:
2202         mem_idx = MIPS_HFLAG_UM;
2203         /* fall through */
2204     case OPC_SWL:
2205         gen_helper_0e2i(swl, t1, t0, mem_idx);
2206         break;
2207     case OPC_SWRE:
2208         mem_idx = MIPS_HFLAG_UM;
2209         /* fall through */
2210     case OPC_SWR:
2211         gen_helper_0e2i(swr, t1, t0, mem_idx);
2212         break;
2213     }
2214 }
2215 
2216 
2217 /* Store conditional */
gen_st_cond(DisasContext * ctx,int rt,int base,int offset,MemOp tcg_mo,bool eva)2218 static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset,
2219                         MemOp tcg_mo, bool eva)
2220 {
2221     TCGv addr, t0, val;
2222     TCGLabel *l1 = gen_new_label();
2223     TCGLabel *done = gen_new_label();
2224 
2225     t0 = tcg_temp_new();
2226     addr = tcg_temp_new();
2227     /* compare the address against that of the preceding LL */
2228     gen_base_offset_addr(ctx, addr, base, offset);
2229     tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1);
2230     gen_store_gpr(tcg_constant_tl(0), rt);
2231     tcg_gen_br(done);
2232 
2233     gen_set_label(l1);
2234     /* generate cmpxchg */
2235     val = tcg_temp_new();
2236     gen_load_gpr(val, rt);
2237     tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val,
2238                               eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo);
2239     tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval);
2240     gen_store_gpr(t0, rt);
2241 
2242     gen_set_label(done);
2243 }
2244 
2245 /* Load and store */
gen_flt_ldst(DisasContext * ctx,uint32_t opc,int ft,TCGv t0)2246 static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft,
2247                          TCGv t0)
2248 {
2249     /*
2250      * Don't do NOP if destination is zero: we must perform the actual
2251      * memory access.
2252      */
2253     switch (opc) {
2254     case OPC_LWC1:
2255         {
2256             TCGv_i32 fp0 = tcg_temp_new_i32();
2257             tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL |
2258                                 ctx->default_tcg_memop_mask);
2259             gen_store_fpr32(ctx, fp0, ft);
2260         }
2261         break;
2262     case OPC_SWC1:
2263         {
2264             TCGv_i32 fp0 = tcg_temp_new_i32();
2265             gen_load_fpr32(ctx, fp0, ft);
2266             tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL |
2267                                 ctx->default_tcg_memop_mask);
2268         }
2269         break;
2270     case OPC_LDC1:
2271         {
2272             TCGv_i64 fp0 = tcg_temp_new_i64();
2273             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
2274                                 ctx->default_tcg_memop_mask);
2275             gen_store_fpr64(ctx, fp0, ft);
2276         }
2277         break;
2278     case OPC_SDC1:
2279         {
2280             TCGv_i64 fp0 = tcg_temp_new_i64();
2281             gen_load_fpr64(ctx, fp0, ft);
2282             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
2283                                 ctx->default_tcg_memop_mask);
2284         }
2285         break;
2286     default:
2287         MIPS_INVAL("flt_ldst");
2288         gen_reserved_instruction(ctx);
2289         break;
2290     }
2291 }
2292 
gen_cop1_ldst(DisasContext * ctx,uint32_t op,int rt,int rs,int16_t imm)2293 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2294                           int rs, int16_t imm)
2295 {
2296     TCGv t0 = tcg_temp_new();
2297 
2298     if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
2299         check_cp1_enabled(ctx);
2300         switch (op) {
2301         case OPC_LDC1:
2302         case OPC_SDC1:
2303             check_insn(ctx, ISA_MIPS2);
2304             /* Fallthrough */
2305         default:
2306             gen_base_offset_addr(ctx, t0, rs, imm);
2307             gen_flt_ldst(ctx, op, rt, t0);
2308         }
2309     } else {
2310         generate_exception_err(ctx, EXCP_CpU, 1);
2311     }
2312 }
2313 
2314 /* Arithmetic with immediate operand */
gen_arith_imm(DisasContext * ctx,uint32_t opc,int rt,int rs,int imm)2315 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2316                           int rt, int rs, int imm)
2317 {
2318     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2319 
2320     if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
2321         /*
2322          * If no destination, treat it as a NOP.
2323          * For addi, we must generate the overflow exception when needed.
2324          */
2325         return;
2326     }
2327     switch (opc) {
2328     case OPC_ADDI:
2329         {
2330             TCGv t0 = tcg_temp_new();
2331             TCGv t1 = tcg_temp_new();
2332             TCGv t2 = tcg_temp_new();
2333             TCGLabel *l1 = gen_new_label();
2334 
2335             gen_load_gpr(t1, rs);
2336             tcg_gen_addi_tl(t0, t1, uimm);
2337             tcg_gen_ext32s_tl(t0, t0);
2338 
2339             tcg_gen_xori_tl(t1, t1, ~uimm);
2340             tcg_gen_xori_tl(t2, t0, uimm);
2341             tcg_gen_and_tl(t1, t1, t2);
2342             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2343             /* operands of same sign, result different sign */
2344             generate_exception(ctx, EXCP_OVERFLOW);
2345             gen_set_label(l1);
2346             tcg_gen_ext32s_tl(t0, t0);
2347             gen_store_gpr(t0, rt);
2348         }
2349         break;
2350     case OPC_ADDIU:
2351         if (rs != 0) {
2352             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2353             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2354         } else {
2355             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2356         }
2357         break;
2358 #if defined(TARGET_MIPS64)
2359     case OPC_DADDI:
2360         {
2361             TCGv t0 = tcg_temp_new();
2362             TCGv t1 = tcg_temp_new();
2363             TCGv t2 = tcg_temp_new();
2364             TCGLabel *l1 = gen_new_label();
2365 
2366             gen_load_gpr(t1, rs);
2367             tcg_gen_addi_tl(t0, t1, uimm);
2368 
2369             tcg_gen_xori_tl(t1, t1, ~uimm);
2370             tcg_gen_xori_tl(t2, t0, uimm);
2371             tcg_gen_and_tl(t1, t1, t2);
2372             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2373             /* operands of same sign, result different sign */
2374             generate_exception(ctx, EXCP_OVERFLOW);
2375             gen_set_label(l1);
2376             gen_store_gpr(t0, rt);
2377         }
2378         break;
2379     case OPC_DADDIU:
2380         if (rs != 0) {
2381             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2382         } else {
2383             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2384         }
2385         break;
2386 #endif
2387     }
2388 }
2389 
2390 /* Logic with immediate operand */
gen_logic_imm(DisasContext * ctx,uint32_t opc,int rt,int rs,int16_t imm)2391 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2392                           int rt, int rs, int16_t imm)
2393 {
2394     target_ulong uimm;
2395 
2396     if (rt == 0) {
2397         /* If no destination, treat it as a NOP. */
2398         return;
2399     }
2400     uimm = (uint16_t)imm;
2401     switch (opc) {
2402     case OPC_ANDI:
2403         if (likely(rs != 0)) {
2404             tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2405         } else {
2406             tcg_gen_movi_tl(cpu_gpr[rt], 0);
2407         }
2408         break;
2409     case OPC_ORI:
2410         if (rs != 0) {
2411             tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2412         } else {
2413             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2414         }
2415         break;
2416     case OPC_XORI:
2417         if (likely(rs != 0)) {
2418             tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2419         } else {
2420             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2421         }
2422         break;
2423     case OPC_LUI:
2424         if (rs != 0 && (ctx->insn_flags & ISA_MIPS_R6)) {
2425             /* OPC_AUI */
2426             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2427             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2428         } else {
2429             tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2430         }
2431         break;
2432 
2433     default:
2434         break;
2435     }
2436 }
2437 
2438 /* Set on less than with immediate operand */
gen_slt_imm(DisasContext * ctx,uint32_t opc,int rt,int rs,int16_t imm)2439 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2440                         int rt, int rs, int16_t imm)
2441 {
2442     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2443     TCGv t0;
2444 
2445     if (rt == 0) {
2446         /* If no destination, treat it as a NOP. */
2447         return;
2448     }
2449     t0 = tcg_temp_new();
2450     gen_load_gpr(t0, rs);
2451     switch (opc) {
2452     case OPC_SLTI:
2453         tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2454         break;
2455     case OPC_SLTIU:
2456         tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2457         break;
2458     }
2459 }
2460 
2461 /* Shifts with immediate operand */
gen_shift_imm(DisasContext * ctx,uint32_t opc,int rt,int rs,int16_t imm)2462 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2463                           int rt, int rs, int16_t imm)
2464 {
2465     target_ulong uimm = ((uint16_t)imm) & 0x1f;
2466     TCGv t0;
2467 
2468     if (rt == 0) {
2469         /* If no destination, treat it as a NOP. */
2470         return;
2471     }
2472 
2473     t0 = tcg_temp_new();
2474     gen_load_gpr(t0, rs);
2475     switch (opc) {
2476     case OPC_SLL:
2477         tcg_gen_shli_tl(t0, t0, uimm);
2478         tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2479         break;
2480     case OPC_SRA:
2481         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2482         break;
2483     case OPC_SRL:
2484         if (uimm != 0) {
2485             tcg_gen_ext32u_tl(t0, t0);
2486             tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2487         } else {
2488             tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2489         }
2490         break;
2491     case OPC_ROTR:
2492         if (uimm != 0) {
2493             TCGv_i32 t1 = tcg_temp_new_i32();
2494 
2495             tcg_gen_trunc_tl_i32(t1, t0);
2496             tcg_gen_rotri_i32(t1, t1, uimm);
2497             tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2498         } else {
2499             tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2500         }
2501         break;
2502 #if defined(TARGET_MIPS64)
2503     case OPC_DSLL:
2504         tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2505         break;
2506     case OPC_DSRA:
2507         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2508         break;
2509     case OPC_DSRL:
2510         tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2511         break;
2512     case OPC_DROTR:
2513         if (uimm != 0) {
2514             tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2515         } else {
2516             tcg_gen_mov_tl(cpu_gpr[rt], t0);
2517         }
2518         break;
2519     case OPC_DSLL32:
2520         tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2521         break;
2522     case OPC_DSRA32:
2523         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2524         break;
2525     case OPC_DSRL32:
2526         tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2527         break;
2528     case OPC_DROTR32:
2529         tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2530         break;
2531 #endif
2532     }
2533 }
2534 
2535 /* Arithmetic */
gen_arith(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)2536 static void gen_arith(DisasContext *ctx, uint32_t opc,
2537                       int rd, int rs, int rt)
2538 {
2539     if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2540        && opc != OPC_DADD && opc != OPC_DSUB) {
2541         /*
2542          * If no destination, treat it as a NOP.
2543          * For add & sub, we must generate the overflow exception when needed.
2544          */
2545         return;
2546     }
2547 
2548     switch (opc) {
2549     case OPC_ADD:
2550         {
2551             TCGv t0 = tcg_temp_new();
2552             TCGv t1 = tcg_temp_new();
2553             TCGv t2 = tcg_temp_new();
2554             TCGLabel *l1 = gen_new_label();
2555 
2556             gen_load_gpr(t1, rs);
2557             gen_load_gpr(t2, rt);
2558             tcg_gen_add_tl(t0, t1, t2);
2559             tcg_gen_ext32s_tl(t0, t0);
2560             tcg_gen_xor_tl(t1, t1, t2);
2561             tcg_gen_xor_tl(t2, t0, t2);
2562             tcg_gen_andc_tl(t1, t2, t1);
2563             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2564             /* operands of same sign, result different sign */
2565             generate_exception(ctx, EXCP_OVERFLOW);
2566             gen_set_label(l1);
2567             gen_store_gpr(t0, rd);
2568         }
2569         break;
2570     case OPC_ADDU:
2571         if (rs != 0 && rt != 0) {
2572             tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2573             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2574         } else if (rs == 0 && rt != 0) {
2575             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2576         } else if (rs != 0 && rt == 0) {
2577             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2578         } else {
2579             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2580         }
2581         break;
2582     case OPC_SUB:
2583         {
2584             TCGv t0 = tcg_temp_new();
2585             TCGv t1 = tcg_temp_new();
2586             TCGv t2 = tcg_temp_new();
2587             TCGLabel *l1 = gen_new_label();
2588 
2589             gen_load_gpr(t1, rs);
2590             gen_load_gpr(t2, rt);
2591             tcg_gen_sub_tl(t0, t1, t2);
2592             tcg_gen_ext32s_tl(t0, t0);
2593             tcg_gen_xor_tl(t2, t1, t2);
2594             tcg_gen_xor_tl(t1, t0, t1);
2595             tcg_gen_and_tl(t1, t1, t2);
2596             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2597             /*
2598              * operands of different sign, first operand and the result
2599              * of different sign
2600              */
2601             generate_exception(ctx, EXCP_OVERFLOW);
2602             gen_set_label(l1);
2603             gen_store_gpr(t0, rd);
2604         }
2605         break;
2606     case OPC_SUBU:
2607         if (rs != 0 && rt != 0) {
2608             tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2609             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2610         } else if (rs == 0 && rt != 0) {
2611             tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2612             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2613         } else if (rs != 0 && rt == 0) {
2614             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2615         } else {
2616             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2617         }
2618         break;
2619 #if defined(TARGET_MIPS64)
2620     case OPC_DADD:
2621         {
2622             TCGv t0 = tcg_temp_new();
2623             TCGv t1 = tcg_temp_new();
2624             TCGv t2 = tcg_temp_new();
2625             TCGLabel *l1 = gen_new_label();
2626 
2627             gen_load_gpr(t1, rs);
2628             gen_load_gpr(t2, rt);
2629             tcg_gen_add_tl(t0, t1, t2);
2630             tcg_gen_xor_tl(t1, t1, t2);
2631             tcg_gen_xor_tl(t2, t0, t2);
2632             tcg_gen_andc_tl(t1, t2, t1);
2633             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2634             /* operands of same sign, result different sign */
2635             generate_exception(ctx, EXCP_OVERFLOW);
2636             gen_set_label(l1);
2637             gen_store_gpr(t0, rd);
2638         }
2639         break;
2640     case OPC_DADDU:
2641         if (rs != 0 && rt != 0) {
2642             tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2643         } else if (rs == 0 && rt != 0) {
2644             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2645         } else if (rs != 0 && rt == 0) {
2646             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2647         } else {
2648             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2649         }
2650         break;
2651     case OPC_DSUB:
2652         {
2653             TCGv t0 = tcg_temp_new();
2654             TCGv t1 = tcg_temp_new();
2655             TCGv t2 = tcg_temp_new();
2656             TCGLabel *l1 = gen_new_label();
2657 
2658             gen_load_gpr(t1, rs);
2659             gen_load_gpr(t2, rt);
2660             tcg_gen_sub_tl(t0, t1, t2);
2661             tcg_gen_xor_tl(t2, t1, t2);
2662             tcg_gen_xor_tl(t1, t0, t1);
2663             tcg_gen_and_tl(t1, t1, t2);
2664             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2665             /*
2666              * Operands of different sign, first operand and result different
2667              * sign.
2668              */
2669             generate_exception(ctx, EXCP_OVERFLOW);
2670             gen_set_label(l1);
2671             gen_store_gpr(t0, rd);
2672         }
2673         break;
2674     case OPC_DSUBU:
2675         if (rs != 0 && rt != 0) {
2676             tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2677         } else if (rs == 0 && rt != 0) {
2678             tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2679         } else if (rs != 0 && rt == 0) {
2680             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2681         } else {
2682             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2683         }
2684         break;
2685 #endif
2686     case OPC_MUL:
2687         if (likely(rs != 0 && rt != 0)) {
2688             tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2689             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2690         } else {
2691             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2692         }
2693         break;
2694     }
2695 }
2696 
2697 /* Conditional move */
gen_cond_move(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)2698 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2699                           int rd, int rs, int rt)
2700 {
2701     TCGv t0, t1, t2;
2702 
2703     if (rd == 0) {
2704         /* If no destination, treat it as a NOP. */
2705         return;
2706     }
2707 
2708     t0 = tcg_temp_new();
2709     gen_load_gpr(t0, rt);
2710     t1 = tcg_constant_tl(0);
2711     t2 = tcg_temp_new();
2712     gen_load_gpr(t2, rs);
2713     switch (opc) {
2714     case OPC_MOVN:
2715         tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2716         break;
2717     case OPC_MOVZ:
2718         tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2719         break;
2720     case OPC_SELNEZ:
2721         tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2722         break;
2723     case OPC_SELEQZ:
2724         tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2725         break;
2726     }
2727 }
2728 
2729 /* Logic */
gen_logic(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)2730 static void gen_logic(DisasContext *ctx, uint32_t opc,
2731                       int rd, int rs, int rt)
2732 {
2733     if (rd == 0) {
2734         /* If no destination, treat it as a NOP. */
2735         return;
2736     }
2737 
2738     switch (opc) {
2739     case OPC_AND:
2740         if (likely(rs != 0 && rt != 0)) {
2741             tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2742         } else {
2743             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2744         }
2745         break;
2746     case OPC_NOR:
2747         if (rs != 0 && rt != 0) {
2748             tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2749         } else if (rs == 0 && rt != 0) {
2750             tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2751         } else if (rs != 0 && rt == 0) {
2752             tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2753         } else {
2754             tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2755         }
2756         break;
2757     case OPC_OR:
2758         if (likely(rs != 0 && rt != 0)) {
2759             tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2760         } else if (rs == 0 && rt != 0) {
2761             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2762         } else if (rs != 0 && rt == 0) {
2763             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2764         } else {
2765             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2766         }
2767         break;
2768     case OPC_XOR:
2769         if (likely(rs != 0 && rt != 0)) {
2770             tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2771         } else if (rs == 0 && rt != 0) {
2772             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2773         } else if (rs != 0 && rt == 0) {
2774             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2775         } else {
2776             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2777         }
2778         break;
2779     }
2780 }
2781 
2782 /* Set on lower than */
gen_slt(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)2783 static void gen_slt(DisasContext *ctx, uint32_t opc,
2784                     int rd, int rs, int rt)
2785 {
2786     TCGv t0, t1;
2787 
2788     if (rd == 0) {
2789         /* If no destination, treat it as a NOP. */
2790         return;
2791     }
2792 
2793     t0 = tcg_temp_new();
2794     t1 = tcg_temp_new();
2795     gen_load_gpr(t0, rs);
2796     gen_load_gpr(t1, rt);
2797     switch (opc) {
2798     case OPC_SLT:
2799         tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2800         break;
2801     case OPC_SLTU:
2802         tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2803         break;
2804     }
2805 }
2806 
2807 /* Shifts */
gen_shift(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)2808 static void gen_shift(DisasContext *ctx, uint32_t opc,
2809                       int rd, int rs, int rt)
2810 {
2811     TCGv t0, t1;
2812 
2813     if (rd == 0) {
2814         /*
2815          * If no destination, treat it as a NOP.
2816          * For add & sub, we must generate the overflow exception when needed.
2817          */
2818         return;
2819     }
2820 
2821     t0 = tcg_temp_new();
2822     t1 = tcg_temp_new();
2823     gen_load_gpr(t0, rs);
2824     gen_load_gpr(t1, rt);
2825     switch (opc) {
2826     case OPC_SLLV:
2827         tcg_gen_andi_tl(t0, t0, 0x1f);
2828         tcg_gen_shl_tl(t0, t1, t0);
2829         tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2830         break;
2831     case OPC_SRAV:
2832         tcg_gen_andi_tl(t0, t0, 0x1f);
2833         tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2834         break;
2835     case OPC_SRLV:
2836         tcg_gen_ext32u_tl(t1, t1);
2837         tcg_gen_andi_tl(t0, t0, 0x1f);
2838         tcg_gen_shr_tl(t0, t1, t0);
2839         tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2840         break;
2841     case OPC_ROTRV:
2842         {
2843             TCGv_i32 t2 = tcg_temp_new_i32();
2844             TCGv_i32 t3 = tcg_temp_new_i32();
2845 
2846             tcg_gen_trunc_tl_i32(t2, t0);
2847             tcg_gen_trunc_tl_i32(t3, t1);
2848             tcg_gen_andi_i32(t2, t2, 0x1f);
2849             tcg_gen_rotr_i32(t2, t3, t2);
2850             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2851         }
2852         break;
2853 #if defined(TARGET_MIPS64)
2854     case OPC_DSLLV:
2855         tcg_gen_andi_tl(t0, t0, 0x3f);
2856         tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2857         break;
2858     case OPC_DSRAV:
2859         tcg_gen_andi_tl(t0, t0, 0x3f);
2860         tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2861         break;
2862     case OPC_DSRLV:
2863         tcg_gen_andi_tl(t0, t0, 0x3f);
2864         tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2865         break;
2866     case OPC_DROTRV:
2867         tcg_gen_andi_tl(t0, t0, 0x3f);
2868         tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2869         break;
2870 #endif
2871     }
2872 }
2873 
2874 /* Arithmetic on HI/LO registers */
gen_HILO(DisasContext * ctx,uint32_t opc,int acc,int reg)2875 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
2876 {
2877     if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2878         /* Treat as NOP. */
2879         return;
2880     }
2881 
2882     if (acc != 0) {
2883         check_dsp(ctx);
2884     }
2885 
2886     switch (opc) {
2887     case OPC_MFHI:
2888 #if defined(TARGET_MIPS64)
2889         if (acc != 0) {
2890             tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2891         } else
2892 #endif
2893         {
2894             tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2895         }
2896         break;
2897     case OPC_MFLO:
2898 #if defined(TARGET_MIPS64)
2899         if (acc != 0) {
2900             tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2901         } else
2902 #endif
2903         {
2904             tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2905         }
2906         break;
2907     case OPC_MTHI:
2908         if (reg != 0) {
2909 #if defined(TARGET_MIPS64)
2910             if (acc != 0) {
2911                 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2912             } else
2913 #endif
2914             {
2915                 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2916             }
2917         } else {
2918             tcg_gen_movi_tl(cpu_HI[acc], 0);
2919         }
2920         break;
2921     case OPC_MTLO:
2922         if (reg != 0) {
2923 #if defined(TARGET_MIPS64)
2924             if (acc != 0) {
2925                 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2926             } else
2927 #endif
2928             {
2929                 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2930             }
2931         } else {
2932             tcg_gen_movi_tl(cpu_LO[acc], 0);
2933         }
2934         break;
2935     }
2936 }
2937 
gen_r6_ld(target_long addr,int reg,int memidx,MemOp memop)2938 static inline void gen_r6_ld(target_long addr, int reg, int memidx,
2939                              MemOp memop)
2940 {
2941     TCGv t0 = tcg_temp_new();
2942     tcg_gen_qemu_ld_tl(t0, tcg_constant_tl(addr), memidx, memop);
2943     gen_store_gpr(t0, reg);
2944 }
2945 
gen_pcrel(DisasContext * ctx,int opc,target_ulong pc,int rs)2946 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
2947                              int rs)
2948 {
2949     target_long offset;
2950     target_long addr;
2951 
2952     switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
2953     case OPC_ADDIUPC:
2954         if (rs != 0) {
2955             offset = sextract32(ctx->opcode << 2, 0, 21);
2956             addr = addr_add(ctx, pc, offset);
2957             tcg_gen_movi_tl(cpu_gpr[rs], addr);
2958         }
2959         break;
2960     case R6_OPC_LWPC:
2961         offset = sextract32(ctx->opcode << 2, 0, 21);
2962         addr = addr_add(ctx, pc, offset);
2963         gen_r6_ld(addr, rs, ctx->mem_idx, mo_endian(ctx) | MO_SL);
2964         break;
2965 #if defined(TARGET_MIPS64)
2966     case OPC_LWUPC:
2967         check_mips_64(ctx);
2968         offset = sextract32(ctx->opcode << 2, 0, 21);
2969         addr = addr_add(ctx, pc, offset);
2970         gen_r6_ld(addr, rs, ctx->mem_idx, mo_endian(ctx) | MO_UL);
2971         break;
2972 #endif
2973     default:
2974         switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
2975         case OPC_AUIPC:
2976             if (rs != 0) {
2977                 offset = sextract32(ctx->opcode, 0, 16) << 16;
2978                 addr = addr_add(ctx, pc, offset);
2979                 tcg_gen_movi_tl(cpu_gpr[rs], addr);
2980             }
2981             break;
2982         case OPC_ALUIPC:
2983             if (rs != 0) {
2984                 offset = sextract32(ctx->opcode, 0, 16) << 16;
2985                 addr = ~0xFFFF & addr_add(ctx, pc, offset);
2986                 tcg_gen_movi_tl(cpu_gpr[rs], addr);
2987             }
2988             break;
2989 #if defined(TARGET_MIPS64)
2990         case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
2991         case R6_OPC_LDPC + (1 << 16):
2992         case R6_OPC_LDPC + (2 << 16):
2993         case R6_OPC_LDPC + (3 << 16):
2994             check_mips_64(ctx);
2995             offset = sextract32(ctx->opcode << 3, 0, 21);
2996             addr = addr_add(ctx, (pc & ~0x7), offset);
2997             gen_r6_ld(addr, rs, ctx->mem_idx, mo_endian(ctx) | MO_UQ);
2998             break;
2999 #endif
3000         default:
3001             MIPS_INVAL("OPC_PCREL");
3002             gen_reserved_instruction(ctx);
3003             break;
3004         }
3005         break;
3006     }
3007 }
3008 
gen_r6_muldiv(DisasContext * ctx,int opc,int rd,int rs,int rt)3009 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3010 {
3011     TCGv t0, t1;
3012 
3013     if (rd == 0) {
3014         /* Treat as NOP. */
3015         return;
3016     }
3017 
3018     t0 = tcg_temp_new();
3019     t1 = tcg_temp_new();
3020 
3021     gen_load_gpr(t0, rs);
3022     gen_load_gpr(t1, rt);
3023 
3024     switch (opc) {
3025     case R6_OPC_DIV:
3026         {
3027             TCGv t2 = tcg_temp_new();
3028             TCGv t3 = tcg_temp_new();
3029             tcg_gen_ext32s_tl(t0, t0);
3030             tcg_gen_ext32s_tl(t1, t1);
3031             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3032             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3033             tcg_gen_and_tl(t2, t2, t3);
3034             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3035             tcg_gen_or_tl(t2, t2, t3);
3036             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1);
3037             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3038             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3039         }
3040         break;
3041     case R6_OPC_MOD:
3042         {
3043             TCGv t2 = tcg_temp_new();
3044             TCGv t3 = tcg_temp_new();
3045             tcg_gen_ext32s_tl(t0, t0);
3046             tcg_gen_ext32s_tl(t1, t1);
3047             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3048             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3049             tcg_gen_and_tl(t2, t2, t3);
3050             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3051             tcg_gen_or_tl(t2, t2, t3);
3052             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1);
3053             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3054             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3055         }
3056         break;
3057     case R6_OPC_DIVU:
3058         {
3059             tcg_gen_ext32u_tl(t0, t0);
3060             tcg_gen_ext32u_tl(t1, t1);
3061             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1,
3062                                tcg_constant_tl(0), tcg_constant_tl(1), t1);
3063             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3064             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3065         }
3066         break;
3067     case R6_OPC_MODU:
3068         {
3069             tcg_gen_ext32u_tl(t0, t0);
3070             tcg_gen_ext32u_tl(t1, t1);
3071             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1,
3072                                tcg_constant_tl(0), tcg_constant_tl(1), t1);
3073             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3074             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3075         }
3076         break;
3077     case R6_OPC_MUL:
3078         {
3079             TCGv_i32 t2 = tcg_temp_new_i32();
3080             TCGv_i32 t3 = tcg_temp_new_i32();
3081             tcg_gen_trunc_tl_i32(t2, t0);
3082             tcg_gen_trunc_tl_i32(t3, t1);
3083             tcg_gen_mul_i32(t2, t2, t3);
3084             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3085         }
3086         break;
3087     case R6_OPC_MUH:
3088         {
3089             TCGv_i32 t2 = tcg_temp_new_i32();
3090             TCGv_i32 t3 = tcg_temp_new_i32();
3091             tcg_gen_trunc_tl_i32(t2, t0);
3092             tcg_gen_trunc_tl_i32(t3, t1);
3093             tcg_gen_muls2_i32(t2, t3, t2, t3);
3094             tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3095         }
3096         break;
3097     case R6_OPC_MULU:
3098         {
3099             TCGv_i32 t2 = tcg_temp_new_i32();
3100             TCGv_i32 t3 = tcg_temp_new_i32();
3101             tcg_gen_trunc_tl_i32(t2, t0);
3102             tcg_gen_trunc_tl_i32(t3, t1);
3103             tcg_gen_mul_i32(t2, t2, t3);
3104             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3105         }
3106         break;
3107     case R6_OPC_MUHU:
3108         {
3109             TCGv_i32 t2 = tcg_temp_new_i32();
3110             TCGv_i32 t3 = tcg_temp_new_i32();
3111             tcg_gen_trunc_tl_i32(t2, t0);
3112             tcg_gen_trunc_tl_i32(t3, t1);
3113             tcg_gen_mulu2_i32(t2, t3, t2, t3);
3114             tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3115         }
3116         break;
3117 #if defined(TARGET_MIPS64)
3118     case R6_OPC_DDIV:
3119         {
3120             TCGv t2 = tcg_temp_new();
3121             TCGv t3 = tcg_temp_new();
3122             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3123             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3124             tcg_gen_and_tl(t2, t2, t3);
3125             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3126             tcg_gen_or_tl(t2, t2, t3);
3127             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1);
3128             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3129         }
3130         break;
3131     case R6_OPC_DMOD:
3132         {
3133             TCGv t2 = tcg_temp_new();
3134             TCGv t3 = tcg_temp_new();
3135             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3136             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3137             tcg_gen_and_tl(t2, t2, t3);
3138             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3139             tcg_gen_or_tl(t2, t2, t3);
3140             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1);
3141             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3142         }
3143         break;
3144     case R6_OPC_DDIVU:
3145         {
3146             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1,
3147                                tcg_constant_tl(0), tcg_constant_tl(1), t1);
3148             tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3149         }
3150         break;
3151     case R6_OPC_DMODU:
3152         {
3153             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1,
3154                                tcg_constant_tl(0), tcg_constant_tl(1), t1);
3155             tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3156         }
3157         break;
3158     case R6_OPC_DMUL:
3159         tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3160         break;
3161     case R6_OPC_DMUH:
3162         {
3163             TCGv t2 = tcg_temp_new();
3164             tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3165         }
3166         break;
3167     case R6_OPC_DMULU:
3168         tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3169         break;
3170     case R6_OPC_DMUHU:
3171         {
3172             TCGv t2 = tcg_temp_new();
3173             tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3174         }
3175         break;
3176 #endif
3177     default:
3178         MIPS_INVAL("r6 mul/div");
3179         gen_reserved_instruction(ctx);
3180         break;
3181     }
3182 }
3183 
3184 #if defined(TARGET_MIPS64)
gen_div1_tx79(DisasContext * ctx,uint32_t opc,int rs,int rt)3185 static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
3186 {
3187     TCGv t0, t1;
3188 
3189     t0 = tcg_temp_new();
3190     t1 = tcg_temp_new();
3191 
3192     gen_load_gpr(t0, rs);
3193     gen_load_gpr(t1, rt);
3194 
3195     switch (opc) {
3196     case MMI_OPC_DIV1:
3197         {
3198             TCGv t2 = tcg_temp_new();
3199             TCGv t3 = tcg_temp_new();
3200             tcg_gen_ext32s_tl(t0, t0);
3201             tcg_gen_ext32s_tl(t1, t1);
3202             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3203             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3204             tcg_gen_and_tl(t2, t2, t3);
3205             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3206             tcg_gen_or_tl(t2, t2, t3);
3207             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1);
3208             tcg_gen_div_tl(cpu_LO[1], t0, t1);
3209             tcg_gen_rem_tl(cpu_HI[1], t0, t1);
3210             tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
3211             tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
3212         }
3213         break;
3214     case MMI_OPC_DIVU1:
3215         {
3216             TCGv t2 = tcg_constant_tl(0);
3217             TCGv t3 = tcg_constant_tl(1);
3218             tcg_gen_ext32u_tl(t0, t0);
3219             tcg_gen_ext32u_tl(t1, t1);
3220             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3221             tcg_gen_divu_tl(cpu_LO[1], t0, t1);
3222             tcg_gen_remu_tl(cpu_HI[1], t0, t1);
3223             tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
3224             tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
3225         }
3226         break;
3227     default:
3228         MIPS_INVAL("div1 TX79");
3229         gen_reserved_instruction(ctx);
3230         break;
3231     }
3232 }
3233 #endif
3234 
gen_muldiv(DisasContext * ctx,uint32_t opc,int acc,int rs,int rt)3235 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3236                        int acc, int rs, int rt)
3237 {
3238     TCGv t0, t1;
3239 
3240     t0 = tcg_temp_new();
3241     t1 = tcg_temp_new();
3242 
3243     gen_load_gpr(t0, rs);
3244     gen_load_gpr(t1, rt);
3245 
3246     if (acc != 0) {
3247         check_dsp(ctx);
3248     }
3249 
3250     switch (opc) {
3251     case OPC_DIV:
3252         {
3253             TCGv t2 = tcg_temp_new();
3254             TCGv t3 = tcg_temp_new();
3255             tcg_gen_ext32s_tl(t0, t0);
3256             tcg_gen_ext32s_tl(t1, t1);
3257             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3258             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3259             tcg_gen_and_tl(t2, t2, t3);
3260             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3261             tcg_gen_or_tl(t2, t2, t3);
3262             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1);
3263             tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3264             tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3265             tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3266             tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3267         }
3268         break;
3269     case OPC_DIVU:
3270         {
3271             TCGv t2 = tcg_constant_tl(0);
3272             TCGv t3 = tcg_constant_tl(1);
3273             tcg_gen_ext32u_tl(t0, t0);
3274             tcg_gen_ext32u_tl(t1, t1);
3275             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3276             tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3277             tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3278             tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3279             tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3280         }
3281         break;
3282     case OPC_MULT:
3283         {
3284             TCGv_i32 t2 = tcg_temp_new_i32();
3285             TCGv_i32 t3 = tcg_temp_new_i32();
3286             tcg_gen_trunc_tl_i32(t2, t0);
3287             tcg_gen_trunc_tl_i32(t3, t1);
3288             tcg_gen_muls2_i32(t2, t3, t2, t3);
3289             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3290             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3291         }
3292         break;
3293     case OPC_MULTU:
3294         {
3295             TCGv_i32 t2 = tcg_temp_new_i32();
3296             TCGv_i32 t3 = tcg_temp_new_i32();
3297             tcg_gen_trunc_tl_i32(t2, t0);
3298             tcg_gen_trunc_tl_i32(t3, t1);
3299             tcg_gen_mulu2_i32(t2, t3, t2, t3);
3300             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3301             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3302         }
3303         break;
3304 #if defined(TARGET_MIPS64)
3305     case OPC_DDIV:
3306         {
3307             TCGv t2 = tcg_temp_new();
3308             TCGv t3 = tcg_temp_new();
3309             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3310             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3311             tcg_gen_and_tl(t2, t2, t3);
3312             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3313             tcg_gen_or_tl(t2, t2, t3);
3314             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1);
3315             tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3316             tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3317         }
3318         break;
3319     case OPC_DDIVU:
3320         {
3321             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1,
3322                                tcg_constant_tl(0), tcg_constant_tl(1), t1);
3323             tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3324             tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
3325         }
3326         break;
3327     case OPC_DMULT:
3328         tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3329         break;
3330     case OPC_DMULTU:
3331         tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3332         break;
3333 #endif
3334     case OPC_MADD:
3335         {
3336             TCGv_i64 t2 = tcg_temp_new_i64();
3337             TCGv_i64 t3 = tcg_temp_new_i64();
3338 
3339             tcg_gen_ext_tl_i64(t2, t0);
3340             tcg_gen_ext_tl_i64(t3, t1);
3341             tcg_gen_mul_i64(t2, t2, t3);
3342             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3343             tcg_gen_add_i64(t2, t2, t3);
3344             gen_move_low32(cpu_LO[acc], t2);
3345             gen_move_high32(cpu_HI[acc], t2);
3346         }
3347         break;
3348     case OPC_MADDU:
3349         {
3350             TCGv_i64 t2 = tcg_temp_new_i64();
3351             TCGv_i64 t3 = tcg_temp_new_i64();
3352 
3353             tcg_gen_ext32u_tl(t0, t0);
3354             tcg_gen_ext32u_tl(t1, t1);
3355             tcg_gen_extu_tl_i64(t2, t0);
3356             tcg_gen_extu_tl_i64(t3, t1);
3357             tcg_gen_mul_i64(t2, t2, t3);
3358             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3359             tcg_gen_add_i64(t2, t2, t3);
3360             gen_move_low32(cpu_LO[acc], t2);
3361             gen_move_high32(cpu_HI[acc], t2);
3362         }
3363         break;
3364     case OPC_MSUB:
3365         {
3366             TCGv_i64 t2 = tcg_temp_new_i64();
3367             TCGv_i64 t3 = tcg_temp_new_i64();
3368 
3369             tcg_gen_ext_tl_i64(t2, t0);
3370             tcg_gen_ext_tl_i64(t3, t1);
3371             tcg_gen_mul_i64(t2, t2, t3);
3372             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3373             tcg_gen_sub_i64(t2, t3, t2);
3374             gen_move_low32(cpu_LO[acc], t2);
3375             gen_move_high32(cpu_HI[acc], t2);
3376         }
3377         break;
3378     case OPC_MSUBU:
3379         {
3380             TCGv_i64 t2 = tcg_temp_new_i64();
3381             TCGv_i64 t3 = tcg_temp_new_i64();
3382 
3383             tcg_gen_ext32u_tl(t0, t0);
3384             tcg_gen_ext32u_tl(t1, t1);
3385             tcg_gen_extu_tl_i64(t2, t0);
3386             tcg_gen_extu_tl_i64(t3, t1);
3387             tcg_gen_mul_i64(t2, t2, t3);
3388             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3389             tcg_gen_sub_i64(t2, t3, t2);
3390             gen_move_low32(cpu_LO[acc], t2);
3391             gen_move_high32(cpu_HI[acc], t2);
3392         }
3393         break;
3394     default:
3395         MIPS_INVAL("mul/div");
3396         gen_reserved_instruction(ctx);
3397         break;
3398     }
3399 }
3400 
3401 /*
3402  * These MULT[U] and MADD[U] instructions implemented in for example
3403  * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
3404  * architectures are special three-operand variants with the syntax
3405  *
3406  *     MULT[U][1] rd, rs, rt
3407  *
3408  * such that
3409  *
3410  *     (rd, LO, HI) <- rs * rt
3411  *
3412  * and
3413  *
3414  *     MADD[U][1] rd, rs, rt
3415  *
3416  * such that
3417  *
3418  *     (rd, LO, HI) <- (LO, HI) + rs * rt
3419  *
3420  * where the low-order 32-bits of the result is placed into both the
3421  * GPR rd and the special register LO. The high-order 32-bits of the
3422  * result is placed into the special register HI.
3423  *
3424  * If the GPR rd is omitted in assembly language, it is taken to be 0,
3425  * which is the zero register that always reads as 0.
3426  */
gen_mul_txx9(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)3427 static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
3428                          int rd, int rs, int rt)
3429 {
3430     TCGv t0 = tcg_temp_new();
3431     TCGv t1 = tcg_temp_new();
3432     int acc = 0;
3433 
3434     gen_load_gpr(t0, rs);
3435     gen_load_gpr(t1, rt);
3436 
3437     switch (opc) {
3438     case MMI_OPC_MULT1:
3439         acc = 1;
3440         /* Fall through */
3441     case OPC_MULT:
3442         {
3443             TCGv_i32 t2 = tcg_temp_new_i32();
3444             TCGv_i32 t3 = tcg_temp_new_i32();
3445             tcg_gen_trunc_tl_i32(t2, t0);
3446             tcg_gen_trunc_tl_i32(t3, t1);
3447             tcg_gen_muls2_i32(t2, t3, t2, t3);
3448             if (rd) {
3449                 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3450             }
3451             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3452             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3453         }
3454         break;
3455     case MMI_OPC_MULTU1:
3456         acc = 1;
3457         /* Fall through */
3458     case OPC_MULTU:
3459         {
3460             TCGv_i32 t2 = tcg_temp_new_i32();
3461             TCGv_i32 t3 = tcg_temp_new_i32();
3462             tcg_gen_trunc_tl_i32(t2, t0);
3463             tcg_gen_trunc_tl_i32(t3, t1);
3464             tcg_gen_mulu2_i32(t2, t3, t2, t3);
3465             if (rd) {
3466                 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3467             }
3468             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3469             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3470         }
3471         break;
3472     case MMI_OPC_MADD1:
3473         acc = 1;
3474         /* Fall through */
3475     case MMI_OPC_MADD:
3476         {
3477             TCGv_i64 t2 = tcg_temp_new_i64();
3478             TCGv_i64 t3 = tcg_temp_new_i64();
3479 
3480             tcg_gen_ext_tl_i64(t2, t0);
3481             tcg_gen_ext_tl_i64(t3, t1);
3482             tcg_gen_mul_i64(t2, t2, t3);
3483             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3484             tcg_gen_add_i64(t2, t2, t3);
3485             gen_move_low32(cpu_LO[acc], t2);
3486             gen_move_high32(cpu_HI[acc], t2);
3487             if (rd) {
3488                 gen_move_low32(cpu_gpr[rd], t2);
3489             }
3490         }
3491         break;
3492     case MMI_OPC_MADDU1:
3493         acc = 1;
3494         /* Fall through */
3495     case MMI_OPC_MADDU:
3496         {
3497             TCGv_i64 t2 = tcg_temp_new_i64();
3498             TCGv_i64 t3 = tcg_temp_new_i64();
3499 
3500             tcg_gen_ext32u_tl(t0, t0);
3501             tcg_gen_ext32u_tl(t1, t1);
3502             tcg_gen_extu_tl_i64(t2, t0);
3503             tcg_gen_extu_tl_i64(t3, t1);
3504             tcg_gen_mul_i64(t2, t2, t3);
3505             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3506             tcg_gen_add_i64(t2, t2, t3);
3507             gen_move_low32(cpu_LO[acc], t2);
3508             gen_move_high32(cpu_HI[acc], t2);
3509             if (rd) {
3510                 gen_move_low32(cpu_gpr[rd], t2);
3511             }
3512         }
3513         break;
3514     default:
3515         MIPS_INVAL("mul/madd TXx9");
3516         gen_reserved_instruction(ctx);
3517         break;
3518     }
3519 }
3520 
gen_cl(DisasContext * ctx,uint32_t opc,int rd,int rs)3521 static void gen_cl(DisasContext *ctx, uint32_t opc,
3522                    int rd, int rs)
3523 {
3524     TCGv t0;
3525 
3526     if (rd == 0) {
3527         /* Treat as NOP. */
3528         return;
3529     }
3530     t0 = cpu_gpr[rd];
3531     gen_load_gpr(t0, rs);
3532 
3533     switch (opc) {
3534     case OPC_CLO:
3535     case R6_OPC_CLO:
3536 #if defined(TARGET_MIPS64)
3537     case OPC_DCLO:
3538     case R6_OPC_DCLO:
3539 #endif
3540         tcg_gen_not_tl(t0, t0);
3541         break;
3542     }
3543 
3544     switch (opc) {
3545     case OPC_CLO:
3546     case R6_OPC_CLO:
3547     case OPC_CLZ:
3548     case R6_OPC_CLZ:
3549         tcg_gen_ext32u_tl(t0, t0);
3550         tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
3551         tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
3552         break;
3553 #if defined(TARGET_MIPS64)
3554     case OPC_DCLO:
3555     case R6_OPC_DCLO:
3556     case OPC_DCLZ:
3557     case R6_OPC_DCLZ:
3558         tcg_gen_clzi_i64(t0, t0, 64);
3559         break;
3560 #endif
3561     }
3562 }
3563 
3564 /* Loongson multimedia instructions */
gen_loongson_multimedia(DisasContext * ctx,int rd,int rs,int rt)3565 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3566 {
3567     uint32_t opc, shift_max;
3568     TCGv_i64 t0, t1;
3569     TCGCond cond;
3570 
3571     opc = MASK_LMMI(ctx->opcode);
3572     check_cp1_enabled(ctx);
3573 
3574     t0 = tcg_temp_new_i64();
3575     t1 = tcg_temp_new_i64();
3576     gen_load_fpr64(ctx, t0, rs);
3577     gen_load_fpr64(ctx, t1, rt);
3578 
3579     switch (opc) {
3580     case OPC_PADDSH:
3581         gen_helper_paddsh(t0, t0, t1);
3582         break;
3583     case OPC_PADDUSH:
3584         gen_helper_paddush(t0, t0, t1);
3585         break;
3586     case OPC_PADDH:
3587         gen_helper_paddh(t0, t0, t1);
3588         break;
3589     case OPC_PADDW:
3590         gen_helper_paddw(t0, t0, t1);
3591         break;
3592     case OPC_PADDSB:
3593         gen_helper_paddsb(t0, t0, t1);
3594         break;
3595     case OPC_PADDUSB:
3596         gen_helper_paddusb(t0, t0, t1);
3597         break;
3598     case OPC_PADDB:
3599         gen_helper_paddb(t0, t0, t1);
3600         break;
3601 
3602     case OPC_PSUBSH:
3603         gen_helper_psubsh(t0, t0, t1);
3604         break;
3605     case OPC_PSUBUSH:
3606         gen_helper_psubush(t0, t0, t1);
3607         break;
3608     case OPC_PSUBH:
3609         gen_helper_psubh(t0, t0, t1);
3610         break;
3611     case OPC_PSUBW:
3612         gen_helper_psubw(t0, t0, t1);
3613         break;
3614     case OPC_PSUBSB:
3615         gen_helper_psubsb(t0, t0, t1);
3616         break;
3617     case OPC_PSUBUSB:
3618         gen_helper_psubusb(t0, t0, t1);
3619         break;
3620     case OPC_PSUBB:
3621         gen_helper_psubb(t0, t0, t1);
3622         break;
3623 
3624     case OPC_PSHUFH:
3625         gen_helper_pshufh(t0, t0, t1);
3626         break;
3627     case OPC_PACKSSWH:
3628         gen_helper_packsswh(t0, t0, t1);
3629         break;
3630     case OPC_PACKSSHB:
3631         gen_helper_packsshb(t0, t0, t1);
3632         break;
3633     case OPC_PACKUSHB:
3634         gen_helper_packushb(t0, t0, t1);
3635         break;
3636 
3637     case OPC_PUNPCKLHW:
3638         gen_helper_punpcklhw(t0, t0, t1);
3639         break;
3640     case OPC_PUNPCKHHW:
3641         gen_helper_punpckhhw(t0, t0, t1);
3642         break;
3643     case OPC_PUNPCKLBH:
3644         gen_helper_punpcklbh(t0, t0, t1);
3645         break;
3646     case OPC_PUNPCKHBH:
3647         gen_helper_punpckhbh(t0, t0, t1);
3648         break;
3649     case OPC_PUNPCKLWD:
3650         gen_helper_punpcklwd(t0, t0, t1);
3651         break;
3652     case OPC_PUNPCKHWD:
3653         gen_helper_punpckhwd(t0, t0, t1);
3654         break;
3655 
3656     case OPC_PAVGH:
3657         gen_helper_pavgh(t0, t0, t1);
3658         break;
3659     case OPC_PAVGB:
3660         gen_helper_pavgb(t0, t0, t1);
3661         break;
3662     case OPC_PMAXSH:
3663         gen_helper_pmaxsh(t0, t0, t1);
3664         break;
3665     case OPC_PMINSH:
3666         gen_helper_pminsh(t0, t0, t1);
3667         break;
3668     case OPC_PMAXUB:
3669         gen_helper_pmaxub(t0, t0, t1);
3670         break;
3671     case OPC_PMINUB:
3672         gen_helper_pminub(t0, t0, t1);
3673         break;
3674 
3675     case OPC_PCMPEQW:
3676         gen_helper_pcmpeqw(t0, t0, t1);
3677         break;
3678     case OPC_PCMPGTW:
3679         gen_helper_pcmpgtw(t0, t0, t1);
3680         break;
3681     case OPC_PCMPEQH:
3682         gen_helper_pcmpeqh(t0, t0, t1);
3683         break;
3684     case OPC_PCMPGTH:
3685         gen_helper_pcmpgth(t0, t0, t1);
3686         break;
3687     case OPC_PCMPEQB:
3688         gen_helper_pcmpeqb(t0, t0, t1);
3689         break;
3690     case OPC_PCMPGTB:
3691         gen_helper_pcmpgtb(t0, t0, t1);
3692         break;
3693 
3694     case OPC_PSLLW:
3695         gen_helper_psllw(t0, t0, t1);
3696         break;
3697     case OPC_PSLLH:
3698         gen_helper_psllh(t0, t0, t1);
3699         break;
3700     case OPC_PSRLW:
3701         gen_helper_psrlw(t0, t0, t1);
3702         break;
3703     case OPC_PSRLH:
3704         gen_helper_psrlh(t0, t0, t1);
3705         break;
3706     case OPC_PSRAW:
3707         gen_helper_psraw(t0, t0, t1);
3708         break;
3709     case OPC_PSRAH:
3710         gen_helper_psrah(t0, t0, t1);
3711         break;
3712 
3713     case OPC_PMULLH:
3714         gen_helper_pmullh(t0, t0, t1);
3715         break;
3716     case OPC_PMULHH:
3717         gen_helper_pmulhh(t0, t0, t1);
3718         break;
3719     case OPC_PMULHUH:
3720         gen_helper_pmulhuh(t0, t0, t1);
3721         break;
3722     case OPC_PMADDHW:
3723         gen_helper_pmaddhw(t0, t0, t1);
3724         break;
3725 
3726     case OPC_PASUBUB:
3727         gen_helper_pasubub(t0, t0, t1);
3728         break;
3729     case OPC_BIADD:
3730         gen_helper_biadd(t0, t0);
3731         break;
3732     case OPC_PMOVMSKB:
3733         gen_helper_pmovmskb(t0, t0);
3734         break;
3735 
3736     case OPC_PADDD:
3737         tcg_gen_add_i64(t0, t0, t1);
3738         break;
3739     case OPC_PSUBD:
3740         tcg_gen_sub_i64(t0, t0, t1);
3741         break;
3742     case OPC_XOR_CP2:
3743         tcg_gen_xor_i64(t0, t0, t1);
3744         break;
3745     case OPC_NOR_CP2:
3746         tcg_gen_nor_i64(t0, t0, t1);
3747         break;
3748     case OPC_AND_CP2:
3749         tcg_gen_and_i64(t0, t0, t1);
3750         break;
3751     case OPC_OR_CP2:
3752         tcg_gen_or_i64(t0, t0, t1);
3753         break;
3754 
3755     case OPC_PANDN:
3756         tcg_gen_andc_i64(t0, t1, t0);
3757         break;
3758 
3759     case OPC_PINSRH_0:
3760         tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3761         break;
3762     case OPC_PINSRH_1:
3763         tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3764         break;
3765     case OPC_PINSRH_2:
3766         tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3767         break;
3768     case OPC_PINSRH_3:
3769         tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3770         break;
3771 
3772     case OPC_PEXTRH:
3773         tcg_gen_andi_i64(t1, t1, 3);
3774         tcg_gen_shli_i64(t1, t1, 4);
3775         tcg_gen_shr_i64(t0, t0, t1);
3776         tcg_gen_ext16u_i64(t0, t0);
3777         break;
3778 
3779     case OPC_ADDU_CP2:
3780         tcg_gen_add_i64(t0, t0, t1);
3781         tcg_gen_ext32s_i64(t0, t0);
3782         break;
3783     case OPC_SUBU_CP2:
3784         tcg_gen_sub_i64(t0, t0, t1);
3785         tcg_gen_ext32s_i64(t0, t0);
3786         break;
3787 
3788     case OPC_SLL_CP2:
3789         shift_max = 32;
3790         goto do_shift;
3791     case OPC_SRL_CP2:
3792         shift_max = 32;
3793         goto do_shift;
3794     case OPC_SRA_CP2:
3795         shift_max = 32;
3796         goto do_shift;
3797     case OPC_DSLL_CP2:
3798         shift_max = 64;
3799         goto do_shift;
3800     case OPC_DSRL_CP2:
3801         shift_max = 64;
3802         goto do_shift;
3803     case OPC_DSRA_CP2:
3804         shift_max = 64;
3805         goto do_shift;
3806     do_shift:
3807         /* Make sure shift count isn't TCG undefined behaviour.  */
3808         tcg_gen_andi_i64(t1, t1, shift_max - 1);
3809 
3810         switch (opc) {
3811         case OPC_SLL_CP2:
3812         case OPC_DSLL_CP2:
3813             tcg_gen_shl_i64(t0, t0, t1);
3814             break;
3815         case OPC_SRA_CP2:
3816         case OPC_DSRA_CP2:
3817             /*
3818              * Since SRA is UndefinedResult without sign-extended inputs,
3819              * we can treat SRA and DSRA the same.
3820              */
3821             tcg_gen_sar_i64(t0, t0, t1);
3822             break;
3823         case OPC_SRL_CP2:
3824             /* We want to shift in zeros for SRL; zero-extend first.  */
3825             tcg_gen_ext32u_i64(t0, t0);
3826             /* FALLTHRU */
3827         case OPC_DSRL_CP2:
3828             tcg_gen_shr_i64(t0, t0, t1);
3829             break;
3830         }
3831 
3832         if (shift_max == 32) {
3833             tcg_gen_ext32s_i64(t0, t0);
3834         }
3835 
3836         /* Shifts larger than MAX produce zero.  */
3837         tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3838         tcg_gen_neg_i64(t1, t1);
3839         tcg_gen_and_i64(t0, t0, t1);
3840         break;
3841 
3842     case OPC_ADD_CP2:
3843     case OPC_DADD_CP2:
3844         {
3845             TCGv_i64 t2 = tcg_temp_new_i64();
3846             TCGLabel *lab = gen_new_label();
3847 
3848             tcg_gen_mov_i64(t2, t0);
3849             tcg_gen_add_i64(t0, t1, t2);
3850             if (opc == OPC_ADD_CP2) {
3851                 tcg_gen_ext32s_i64(t0, t0);
3852             }
3853             tcg_gen_xor_i64(t1, t1, t2);
3854             tcg_gen_xor_i64(t2, t2, t0);
3855             tcg_gen_andc_i64(t1, t2, t1);
3856             tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3857             generate_exception(ctx, EXCP_OVERFLOW);
3858             gen_set_label(lab);
3859             break;
3860         }
3861 
3862     case OPC_SUB_CP2:
3863     case OPC_DSUB_CP2:
3864         {
3865             TCGv_i64 t2 = tcg_temp_new_i64();
3866             TCGLabel *lab = gen_new_label();
3867 
3868             tcg_gen_mov_i64(t2, t0);
3869             tcg_gen_sub_i64(t0, t1, t2);
3870             if (opc == OPC_SUB_CP2) {
3871                 tcg_gen_ext32s_i64(t0, t0);
3872             }
3873             tcg_gen_xor_i64(t1, t1, t2);
3874             tcg_gen_xor_i64(t2, t2, t0);
3875             tcg_gen_and_i64(t1, t1, t2);
3876             tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3877             generate_exception(ctx, EXCP_OVERFLOW);
3878             gen_set_label(lab);
3879             break;
3880         }
3881 
3882     case OPC_PMULUW:
3883         tcg_gen_ext32u_i64(t0, t0);
3884         tcg_gen_ext32u_i64(t1, t1);
3885         tcg_gen_mul_i64(t0, t0, t1);
3886         break;
3887 
3888     case OPC_SEQU_CP2:
3889     case OPC_SEQ_CP2:
3890         cond = TCG_COND_EQ;
3891         goto do_cc_cond;
3892         break;
3893     case OPC_SLTU_CP2:
3894         cond = TCG_COND_LTU;
3895         goto do_cc_cond;
3896         break;
3897     case OPC_SLT_CP2:
3898         cond = TCG_COND_LT;
3899         goto do_cc_cond;
3900         break;
3901     case OPC_SLEU_CP2:
3902         cond = TCG_COND_LEU;
3903         goto do_cc_cond;
3904         break;
3905     case OPC_SLE_CP2:
3906         cond = TCG_COND_LE;
3907     do_cc_cond:
3908         {
3909             int cc = (ctx->opcode >> 8) & 0x7;
3910             TCGv_i64 t64 = tcg_temp_new_i64();
3911             TCGv_i32 t32 = tcg_temp_new_i32();
3912 
3913             tcg_gen_setcond_i64(cond, t64, t0, t1);
3914             tcg_gen_extrl_i64_i32(t32, t64);
3915             tcg_gen_deposit_i32(fpu_fcr31, fpu_fcr31, t32,
3916                                 get_fp_bit(cc), 1);
3917         }
3918         return;
3919     default:
3920         MIPS_INVAL("loongson_cp2");
3921         gen_reserved_instruction(ctx);
3922         return;
3923     }
3924 
3925     gen_store_fpr64(ctx, t0, rd);
3926 }
3927 
gen_loongson_lswc2(DisasContext * ctx,int rt,int rs,int rd)3928 static void gen_loongson_lswc2(DisasContext *ctx, int rt,
3929                                int rs, int rd)
3930 {
3931     TCGv t0, t1;
3932     TCGv_i32 fp0;
3933 #if defined(TARGET_MIPS64)
3934     int lsq_rt1 = ctx->opcode & 0x1f;
3935     int lsq_offset = sextract32(ctx->opcode, 6, 9) << 4;
3936 #endif
3937     int shf_offset = sextract32(ctx->opcode, 6, 8);
3938 
3939     t0 = tcg_temp_new();
3940 
3941     switch (MASK_LOONGSON_GSLSQ(ctx->opcode)) {
3942 #if defined(TARGET_MIPS64)
3943     case OPC_GSLQ:
3944         t1 = tcg_temp_new();
3945         gen_base_offset_addr(ctx, t0, rs, lsq_offset);
3946         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
3947                            ctx->default_tcg_memop_mask);
3948         gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
3949         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
3950                            ctx->default_tcg_memop_mask);
3951         gen_store_gpr(t1, rt);
3952         gen_store_gpr(t0, lsq_rt1);
3953         break;
3954     case OPC_GSLQC1:
3955         check_cp1_enabled(ctx);
3956         t1 = tcg_temp_new();
3957         gen_base_offset_addr(ctx, t0, rs, lsq_offset);
3958         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
3959                            ctx->default_tcg_memop_mask);
3960         gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
3961         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
3962                            ctx->default_tcg_memop_mask);
3963         gen_store_fpr64(ctx, t1, rt);
3964         gen_store_fpr64(ctx, t0, lsq_rt1);
3965         break;
3966     case OPC_GSSQ:
3967         t1 = tcg_temp_new();
3968         gen_base_offset_addr(ctx, t0, rs, lsq_offset);
3969         gen_load_gpr(t1, rt);
3970         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
3971                            ctx->default_tcg_memop_mask);
3972         gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
3973         gen_load_gpr(t1, lsq_rt1);
3974         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
3975                            ctx->default_tcg_memop_mask);
3976         break;
3977     case OPC_GSSQC1:
3978         check_cp1_enabled(ctx);
3979         t1 = tcg_temp_new();
3980         gen_base_offset_addr(ctx, t0, rs, lsq_offset);
3981         gen_load_fpr64(ctx, t1, rt);
3982         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
3983                            ctx->default_tcg_memop_mask);
3984         gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
3985         gen_load_fpr64(ctx, t1, lsq_rt1);
3986         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
3987                            ctx->default_tcg_memop_mask);
3988         break;
3989 #endif
3990     case OPC_GSSHFL:
3991         switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
3992         case OPC_GSLWLC1:
3993             check_cp1_enabled(ctx);
3994             gen_base_offset_addr(ctx, t0, rs, shf_offset);
3995             fp0 = tcg_temp_new_i32();
3996             gen_load_fpr32(ctx, fp0, rt);
3997             t1 = tcg_temp_new();
3998             tcg_gen_ext_i32_tl(t1, fp0);
3999             gen_lxl(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL);
4000             tcg_gen_trunc_tl_i32(fp0, t1);
4001             gen_store_fpr32(ctx, fp0, rt);
4002             break;
4003         case OPC_GSLWRC1:
4004             check_cp1_enabled(ctx);
4005             gen_base_offset_addr(ctx, t0, rs, shf_offset);
4006             fp0 = tcg_temp_new_i32();
4007             gen_load_fpr32(ctx, fp0, rt);
4008             t1 = tcg_temp_new();
4009             tcg_gen_ext_i32_tl(t1, fp0);
4010             gen_lxr(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL);
4011             tcg_gen_trunc_tl_i32(fp0, t1);
4012             gen_store_fpr32(ctx, fp0, rt);
4013             break;
4014 #if defined(TARGET_MIPS64)
4015         case OPC_GSLDLC1:
4016             check_cp1_enabled(ctx);
4017             gen_base_offset_addr(ctx, t0, rs, shf_offset);
4018             t1 = tcg_temp_new();
4019             gen_load_fpr64(ctx, t1, rt);
4020             gen_lxl(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ);
4021             gen_store_fpr64(ctx, t1, rt);
4022             break;
4023         case OPC_GSLDRC1:
4024             check_cp1_enabled(ctx);
4025             gen_base_offset_addr(ctx, t0, rs, shf_offset);
4026             t1 = tcg_temp_new();
4027             gen_load_fpr64(ctx, t1, rt);
4028             gen_lxr(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ);
4029             gen_store_fpr64(ctx, t1, rt);
4030             break;
4031 #endif
4032         default:
4033             MIPS_INVAL("loongson_gsshfl");
4034             gen_reserved_instruction(ctx);
4035             break;
4036         }
4037         break;
4038     case OPC_GSSHFS:
4039         switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
4040         case OPC_GSSWLC1:
4041             check_cp1_enabled(ctx);
4042             t1 = tcg_temp_new();
4043             gen_base_offset_addr(ctx, t0, rs, shf_offset);
4044             fp0 = tcg_temp_new_i32();
4045             gen_load_fpr32(ctx, fp0, rt);
4046             tcg_gen_ext_i32_tl(t1, fp0);
4047             gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
4048             break;
4049         case OPC_GSSWRC1:
4050             check_cp1_enabled(ctx);
4051             t1 = tcg_temp_new();
4052             gen_base_offset_addr(ctx, t0, rs, shf_offset);
4053             fp0 = tcg_temp_new_i32();
4054             gen_load_fpr32(ctx, fp0, rt);
4055             tcg_gen_ext_i32_tl(t1, fp0);
4056             gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
4057             break;
4058 #if defined(TARGET_MIPS64)
4059         case OPC_GSSDLC1:
4060             check_cp1_enabled(ctx);
4061             t1 = tcg_temp_new();
4062             gen_base_offset_addr(ctx, t0, rs, shf_offset);
4063             gen_load_fpr64(ctx, t1, rt);
4064             gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
4065             break;
4066         case OPC_GSSDRC1:
4067             check_cp1_enabled(ctx);
4068             t1 = tcg_temp_new();
4069             gen_base_offset_addr(ctx, t0, rs, shf_offset);
4070             gen_load_fpr64(ctx, t1, rt);
4071             gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
4072             break;
4073 #endif
4074         default:
4075             MIPS_INVAL("loongson_gsshfs");
4076             gen_reserved_instruction(ctx);
4077             break;
4078         }
4079         break;
4080     default:
4081         MIPS_INVAL("loongson_gslsq");
4082         gen_reserved_instruction(ctx);
4083         break;
4084     }
4085 }
4086 
4087 /* Loongson EXT LDC2/SDC2 */
gen_loongson_lsdc2(DisasContext * ctx,int rt,int rs,int rd)4088 static void gen_loongson_lsdc2(DisasContext *ctx, int rt,
4089                                int rs, int rd)
4090 {
4091     int offset = sextract32(ctx->opcode, 3, 8);
4092     uint32_t opc = MASK_LOONGSON_LSDC2(ctx->opcode);
4093     TCGv t0, t1;
4094     TCGv_i32 fp0;
4095 
4096     /* Pre-conditions */
4097     switch (opc) {
4098     case OPC_GSLBX:
4099     case OPC_GSLHX:
4100     case OPC_GSLWX:
4101     case OPC_GSLDX:
4102         /* prefetch, implement as NOP */
4103         if (rt == 0) {
4104             return;
4105         }
4106         break;
4107     case OPC_GSSBX:
4108     case OPC_GSSHX:
4109     case OPC_GSSWX:
4110     case OPC_GSSDX:
4111         break;
4112     case OPC_GSLWXC1:
4113 #if defined(TARGET_MIPS64)
4114     case OPC_GSLDXC1:
4115 #endif
4116         check_cp1_enabled(ctx);
4117         /* prefetch, implement as NOP */
4118         if (rt == 0) {
4119             return;
4120         }
4121         break;
4122     case OPC_GSSWXC1:
4123 #if defined(TARGET_MIPS64)
4124     case OPC_GSSDXC1:
4125 #endif
4126         check_cp1_enabled(ctx);
4127         break;
4128     default:
4129         MIPS_INVAL("loongson_lsdc2");
4130         gen_reserved_instruction(ctx);
4131         return;
4132         break;
4133     }
4134 
4135     t0 = tcg_temp_new();
4136 
4137     gen_base_offset_addr(ctx, t0, rs, offset);
4138     gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4139 
4140     switch (opc) {
4141     case OPC_GSLBX:
4142         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
4143         gen_store_gpr(t0, rt);
4144         break;
4145     case OPC_GSLHX:
4146         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SW |
4147                            ctx->default_tcg_memop_mask);
4148         gen_store_gpr(t0, rt);
4149         break;
4150     case OPC_GSLWX:
4151         gen_base_offset_addr(ctx, t0, rs, offset);
4152         if (rd) {
4153             gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4154         }
4155         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL |
4156                            ctx->default_tcg_memop_mask);
4157         gen_store_gpr(t0, rt);
4158         break;
4159 #if defined(TARGET_MIPS64)
4160     case OPC_GSLDX:
4161         gen_base_offset_addr(ctx, t0, rs, offset);
4162         if (rd) {
4163             gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4164         }
4165         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
4166                            ctx->default_tcg_memop_mask);
4167         gen_store_gpr(t0, rt);
4168         break;
4169 #endif
4170     case OPC_GSLWXC1:
4171         gen_base_offset_addr(ctx, t0, rs, offset);
4172         if (rd) {
4173             gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4174         }
4175         fp0 = tcg_temp_new_i32();
4176         tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL |
4177                             ctx->default_tcg_memop_mask);
4178         gen_store_fpr32(ctx, fp0, rt);
4179         break;
4180 #if defined(TARGET_MIPS64)
4181     case OPC_GSLDXC1:
4182         gen_base_offset_addr(ctx, t0, rs, offset);
4183         if (rd) {
4184             gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4185         }
4186         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
4187                            ctx->default_tcg_memop_mask);
4188         gen_store_fpr64(ctx, t0, rt);
4189         break;
4190 #endif
4191     case OPC_GSSBX:
4192         t1 = tcg_temp_new();
4193         gen_load_gpr(t1, rt);
4194         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_SB);
4195         break;
4196     case OPC_GSSHX:
4197         t1 = tcg_temp_new();
4198         gen_load_gpr(t1, rt);
4199         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UW |
4200                            ctx->default_tcg_memop_mask);
4201         break;
4202     case OPC_GSSWX:
4203         t1 = tcg_temp_new();
4204         gen_load_gpr(t1, rt);
4205         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL |
4206                            ctx->default_tcg_memop_mask);
4207         break;
4208 #if defined(TARGET_MIPS64)
4209     case OPC_GSSDX:
4210         t1 = tcg_temp_new();
4211         gen_load_gpr(t1, rt);
4212         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
4213                            ctx->default_tcg_memop_mask);
4214         break;
4215 #endif
4216     case OPC_GSSWXC1:
4217         fp0 = tcg_temp_new_i32();
4218         gen_load_fpr32(ctx, fp0, rt);
4219         tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL |
4220                             ctx->default_tcg_memop_mask);
4221         break;
4222 #if defined(TARGET_MIPS64)
4223     case OPC_GSSDXC1:
4224         t1 = tcg_temp_new();
4225         gen_load_fpr64(ctx, t1, rt);
4226         tcg_gen_qemu_st_i64(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
4227                             ctx->default_tcg_memop_mask);
4228         break;
4229 #endif
4230     default:
4231         break;
4232     }
4233 }
4234 
4235 /* Traps */
gen_trap(DisasContext * ctx,uint32_t opc,int rs,int rt,int16_t imm,int code)4236 static void gen_trap(DisasContext *ctx, uint32_t opc,
4237                      int rs, int rt, int16_t imm, int code)
4238 {
4239     int cond;
4240     TCGv t0 = tcg_temp_new();
4241     TCGv t1 = tcg_temp_new();
4242 
4243     cond = 0;
4244     /* Load needed operands */
4245     switch (opc) {
4246     case OPC_TEQ:
4247     case OPC_TGE:
4248     case OPC_TGEU:
4249     case OPC_TLT:
4250     case OPC_TLTU:
4251     case OPC_TNE:
4252         /* Compare two registers */
4253         if (rs != rt) {
4254             gen_load_gpr(t0, rs);
4255             gen_load_gpr(t1, rt);
4256             cond = 1;
4257         }
4258         break;
4259     case OPC_TEQI:
4260     case OPC_TGEI:
4261     case OPC_TGEIU:
4262     case OPC_TLTI:
4263     case OPC_TLTIU:
4264     case OPC_TNEI:
4265         /* Compare register to immediate */
4266         if (rs != 0 || imm != 0) {
4267             gen_load_gpr(t0, rs);
4268             tcg_gen_movi_tl(t1, (int32_t)imm);
4269             cond = 1;
4270         }
4271         break;
4272     }
4273     if (cond == 0) {
4274         switch (opc) {
4275         case OPC_TEQ:   /* rs == rs */
4276         case OPC_TEQI:  /* r0 == 0  */
4277         case OPC_TGE:   /* rs >= rs */
4278         case OPC_TGEI:  /* r0 >= 0  */
4279         case OPC_TGEU:  /* rs >= rs unsigned */
4280         case OPC_TGEIU: /* r0 >= 0  unsigned */
4281             /* Always trap */
4282 #ifdef CONFIG_USER_ONLY
4283             /* Pass the break code along to cpu_loop. */
4284             tcg_gen_st_i32(tcg_constant_i32(code), tcg_env,
4285                            offsetof(CPUMIPSState, error_code));
4286 #endif
4287             generate_exception_end(ctx, EXCP_TRAP);
4288             break;
4289         case OPC_TLT:   /* rs < rs           */
4290         case OPC_TLTI:  /* r0 < 0            */
4291         case OPC_TLTU:  /* rs < rs unsigned  */
4292         case OPC_TLTIU: /* r0 < 0  unsigned  */
4293         case OPC_TNE:   /* rs != rs          */
4294         case OPC_TNEI:  /* r0 != 0           */
4295             /* Never trap: treat as NOP. */
4296             break;
4297         }
4298     } else {
4299         TCGLabel *l1 = gen_new_label();
4300 
4301         switch (opc) {
4302         case OPC_TEQ:
4303         case OPC_TEQI:
4304             tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
4305             break;
4306         case OPC_TGE:
4307         case OPC_TGEI:
4308             tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
4309             break;
4310         case OPC_TGEU:
4311         case OPC_TGEIU:
4312             tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
4313             break;
4314         case OPC_TLT:
4315         case OPC_TLTI:
4316             tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4317             break;
4318         case OPC_TLTU:
4319         case OPC_TLTIU:
4320             tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
4321             break;
4322         case OPC_TNE:
4323         case OPC_TNEI:
4324             tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
4325             break;
4326         }
4327 #ifdef CONFIG_USER_ONLY
4328         /* Pass the break code along to cpu_loop. */
4329         tcg_gen_st_i32(tcg_constant_i32(code), tcg_env,
4330                        offsetof(CPUMIPSState, error_code));
4331 #endif
4332         /* Like save_cpu_state, only don't update saved values. */
4333         if (ctx->base.pc_next != ctx->saved_pc) {
4334             gen_save_pc(ctx->base.pc_next);
4335         }
4336         if (ctx->hflags != ctx->saved_hflags) {
4337             tcg_gen_movi_i32(hflags, ctx->hflags);
4338         }
4339         generate_exception(ctx, EXCP_TRAP);
4340         gen_set_label(l1);
4341     }
4342 }
4343 
gen_goto_tb(DisasContext * ctx,int n,target_ulong dest)4344 static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
4345 {
4346     if (translator_use_goto_tb(&ctx->base, dest)) {
4347         tcg_gen_goto_tb(n);
4348         gen_save_pc(dest);
4349         tcg_gen_exit_tb(ctx->base.tb, n);
4350     } else {
4351         gen_save_pc(dest);
4352         tcg_gen_lookup_and_goto_ptr();
4353     }
4354 }
4355 
4356 /* 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)4357 static void gen_compute_branch(DisasContext *ctx, uint32_t opc,
4358                                int insn_bytes,
4359                                int rs, int rt, int32_t offset,
4360                                int delayslot_size)
4361 {
4362     target_ulong btgt = -1;
4363     int blink = 0;
4364     int bcond_compute = 0;
4365     TCGv t0 = tcg_temp_new();
4366     TCGv t1 = tcg_temp_new();
4367 
4368     if (ctx->hflags & MIPS_HFLAG_BMASK) {
4369 #ifdef MIPS_DEBUG_DISAS
4370         LOG_DISAS("Branch in delay / forbidden slot at PC 0x%016"
4371                   VADDR_PRIx "\n", ctx->base.pc_next);
4372 #endif
4373         gen_reserved_instruction(ctx);
4374         goto out;
4375     }
4376 
4377     /* Load needed operands */
4378     switch (opc) {
4379     case OPC_BEQ:
4380     case OPC_BEQL:
4381     case OPC_BNE:
4382     case OPC_BNEL:
4383         /* Compare two registers */
4384         if (rs != rt) {
4385             gen_load_gpr(t0, rs);
4386             gen_load_gpr(t1, rt);
4387             bcond_compute = 1;
4388         }
4389         btgt = ctx->base.pc_next + insn_bytes + offset;
4390         break;
4391     case OPC_BGEZ:
4392     case OPC_BGEZAL:
4393     case OPC_BGEZALL:
4394     case OPC_BGEZL:
4395     case OPC_BGTZ:
4396     case OPC_BGTZL:
4397     case OPC_BLEZ:
4398     case OPC_BLEZL:
4399     case OPC_BLTZ:
4400     case OPC_BLTZAL:
4401     case OPC_BLTZALL:
4402     case OPC_BLTZL:
4403         /* Compare to zero */
4404         if (rs != 0) {
4405             gen_load_gpr(t0, rs);
4406             bcond_compute = 1;
4407         }
4408         btgt = ctx->base.pc_next + insn_bytes + offset;
4409         break;
4410     case OPC_BPOSGE32:
4411 #if defined(TARGET_MIPS64)
4412     case OPC_BPOSGE64:
4413         tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4414 #else
4415         tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4416 #endif
4417         bcond_compute = 1;
4418         btgt = ctx->base.pc_next + insn_bytes + offset;
4419         break;
4420     case OPC_J:
4421     case OPC_JAL:
4422         {
4423             /* Jump to immediate */
4424             int jal_mask = ctx->hflags & MIPS_HFLAG_M16 ? 0xF8000000
4425                                                         : 0xF0000000;
4426             btgt = ((ctx->base.pc_next + insn_bytes) & jal_mask)
4427                    | (uint32_t)offset;
4428             break;
4429         }
4430     case OPC_JALX:
4431         /* Jump to immediate */
4432         btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
4433             (uint32_t)offset;
4434         break;
4435     case OPC_JR:
4436     case OPC_JALR:
4437         /* Jump to register */
4438         if (offset != 0 && offset != 16) {
4439             /*
4440              * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
4441              * others are reserved.
4442              */
4443             MIPS_INVAL("jump hint");
4444             gen_reserved_instruction(ctx);
4445             goto out;
4446         }
4447         gen_load_gpr(btarget, rs);
4448         break;
4449     default:
4450         MIPS_INVAL("branch/jump");
4451         gen_reserved_instruction(ctx);
4452         goto out;
4453     }
4454     if (bcond_compute == 0) {
4455         /* No condition to be computed */
4456         switch (opc) {
4457         case OPC_BEQ:     /* rx == rx        */
4458         case OPC_BEQL:    /* rx == rx likely */
4459         case OPC_BGEZ:    /* 0 >= 0          */
4460         case OPC_BGEZL:   /* 0 >= 0 likely   */
4461         case OPC_BLEZ:    /* 0 <= 0          */
4462         case OPC_BLEZL:   /* 0 <= 0 likely   */
4463             /* Always take */
4464             ctx->hflags |= MIPS_HFLAG_B;
4465             break;
4466         case OPC_BGEZAL:  /* 0 >= 0          */
4467         case OPC_BGEZALL: /* 0 >= 0 likely   */
4468             /* Always take and link */
4469             blink = 31;
4470             ctx->hflags |= MIPS_HFLAG_B;
4471             break;
4472         case OPC_BNE:     /* rx != rx        */
4473         case OPC_BGTZ:    /* 0 > 0           */
4474         case OPC_BLTZ:    /* 0 < 0           */
4475             /* Treat as NOP. */
4476             goto out;
4477         case OPC_BLTZAL:  /* 0 < 0           */
4478             /*
4479              * Handle as an unconditional branch to get correct delay
4480              * slot checking.
4481              */
4482             blink = 31;
4483             btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
4484             ctx->hflags |= MIPS_HFLAG_B;
4485             break;
4486         case OPC_BLTZALL: /* 0 < 0 likely */
4487             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
4488             /* Skip the instruction in the delay slot */
4489             ctx->base.pc_next += 4;
4490             goto out;
4491         case OPC_BNEL:    /* rx != rx likely */
4492         case OPC_BGTZL:   /* 0 > 0 likely */
4493         case OPC_BLTZL:   /* 0 < 0 likely */
4494             /* Skip the instruction in the delay slot */
4495             ctx->base.pc_next += 4;
4496             goto out;
4497         case OPC_J:
4498             ctx->hflags |= MIPS_HFLAG_B;
4499             break;
4500         case OPC_JALX:
4501             ctx->hflags |= MIPS_HFLAG_BX;
4502             /* Fallthrough */
4503         case OPC_JAL:
4504             blink = 31;
4505             ctx->hflags |= MIPS_HFLAG_B;
4506             break;
4507         case OPC_JR:
4508             ctx->hflags |= MIPS_HFLAG_BR;
4509             break;
4510         case OPC_JALR:
4511             blink = rt;
4512             ctx->hflags |= MIPS_HFLAG_BR;
4513             break;
4514         default:
4515             MIPS_INVAL("branch/jump");
4516             gen_reserved_instruction(ctx);
4517             goto out;
4518         }
4519     } else {
4520         switch (opc) {
4521         case OPC_BEQ:
4522             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4523             goto not_likely;
4524         case OPC_BEQL:
4525             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4526             goto likely;
4527         case OPC_BNE:
4528             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4529             goto not_likely;
4530         case OPC_BNEL:
4531             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4532             goto likely;
4533         case OPC_BGEZ:
4534             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4535             goto not_likely;
4536         case OPC_BGEZL:
4537             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4538             goto likely;
4539         case OPC_BGEZAL:
4540             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4541             blink = 31;
4542             goto not_likely;
4543         case OPC_BGEZALL:
4544             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4545             blink = 31;
4546             goto likely;
4547         case OPC_BGTZ:
4548             tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4549             goto not_likely;
4550         case OPC_BGTZL:
4551             tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4552             goto likely;
4553         case OPC_BLEZ:
4554             tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4555             goto not_likely;
4556         case OPC_BLEZL:
4557             tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4558             goto likely;
4559         case OPC_BLTZ:
4560             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4561             goto not_likely;
4562         case OPC_BLTZL:
4563             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4564             goto likely;
4565         case OPC_BPOSGE32:
4566             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
4567             goto not_likely;
4568 #if defined(TARGET_MIPS64)
4569         case OPC_BPOSGE64:
4570             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
4571             goto not_likely;
4572 #endif
4573         case OPC_BLTZAL:
4574             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4575             blink = 31;
4576         not_likely:
4577             ctx->hflags |= MIPS_HFLAG_BC;
4578             break;
4579         case OPC_BLTZALL:
4580             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4581             blink = 31;
4582         likely:
4583             ctx->hflags |= MIPS_HFLAG_BL;
4584             break;
4585         default:
4586             MIPS_INVAL("conditional branch/jump");
4587             gen_reserved_instruction(ctx);
4588             goto out;
4589         }
4590     }
4591 
4592     ctx->btarget = btgt;
4593 
4594     switch (delayslot_size) {
4595     case 2:
4596         ctx->hflags |= MIPS_HFLAG_BDS16;
4597         break;
4598     case 4:
4599         ctx->hflags |= MIPS_HFLAG_BDS32;
4600         break;
4601     }
4602 
4603     if (blink > 0) {
4604         int post_delay = insn_bytes + delayslot_size;
4605         int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4606 
4607         tcg_gen_movi_tl(cpu_gpr[blink],
4608                         ctx->base.pc_next + post_delay + lowbit);
4609     }
4610 
4611  out:
4612     if (insn_bytes == 2) {
4613         ctx->hflags |= MIPS_HFLAG_B16;
4614     }
4615 }
4616 
4617 
4618 /* special3 bitfield operations */
gen_bitops(DisasContext * ctx,uint32_t opc,int rt,int rs,int lsb,int msb)4619 static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt,
4620                        int rs, int lsb, int msb)
4621 {
4622     TCGv t0 = tcg_temp_new();
4623     TCGv t1 = tcg_temp_new();
4624 
4625     gen_load_gpr(t1, rs);
4626     switch (opc) {
4627     case OPC_EXT:
4628         if (lsb + msb > 31) {
4629             goto fail;
4630         }
4631         if (msb != 31) {
4632             tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
4633         } else {
4634             /*
4635              * The two checks together imply that lsb == 0,
4636              * so this is a simple sign-extension.
4637              */
4638             tcg_gen_ext32s_tl(t0, t1);
4639         }
4640         break;
4641 #if defined(TARGET_MIPS64)
4642     case OPC_DEXTU:
4643         lsb += 32;
4644         goto do_dext;
4645     case OPC_DEXTM:
4646         msb += 32;
4647         goto do_dext;
4648     case OPC_DEXT:
4649     do_dext:
4650         if (lsb + msb > 63) {
4651             goto fail;
4652         }
4653         tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
4654         break;
4655 #endif
4656     case OPC_INS:
4657         if (lsb > msb) {
4658             goto fail;
4659         }
4660         gen_load_gpr(t0, rt);
4661         tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4662         tcg_gen_ext32s_tl(t0, t0);
4663         break;
4664 #if defined(TARGET_MIPS64)
4665     case OPC_DINSU:
4666         lsb += 32;
4667         /* FALLTHRU */
4668     case OPC_DINSM:
4669         msb += 32;
4670         /* FALLTHRU */
4671     case OPC_DINS:
4672         if (lsb > msb) {
4673             goto fail;
4674         }
4675         gen_load_gpr(t0, rt);
4676         tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4677         break;
4678 #endif
4679     default:
4680 fail:
4681         MIPS_INVAL("bitops");
4682         gen_reserved_instruction(ctx);
4683         return;
4684     }
4685     gen_store_gpr(t0, rt);
4686 }
4687 
gen_bshfl(DisasContext * ctx,uint32_t op2,int rt,int rd)4688 static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd)
4689 {
4690     TCGv t0;
4691 
4692     if (rd == 0) {
4693         /* If no destination, treat it as a NOP. */
4694         return;
4695     }
4696 
4697     t0 = tcg_temp_new();
4698     gen_load_gpr(t0, rt);
4699     switch (op2) {
4700     case OPC_WSBH:
4701         {
4702             TCGv t1 = tcg_temp_new();
4703             TCGv t2 = tcg_constant_tl(0x00FF00FF);
4704 
4705             tcg_gen_shri_tl(t1, t0, 8);
4706             tcg_gen_and_tl(t1, t1, t2);
4707             tcg_gen_and_tl(t0, t0, t2);
4708             tcg_gen_shli_tl(t0, t0, 8);
4709             tcg_gen_or_tl(t0, t0, t1);
4710             tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4711         }
4712         break;
4713     case OPC_SEB:
4714         tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4715         break;
4716     case OPC_SEH:
4717         tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4718         break;
4719 #if defined(TARGET_MIPS64)
4720     case OPC_DSBH:
4721         {
4722             TCGv t1 = tcg_temp_new();
4723             TCGv t2 = tcg_constant_tl(0x00FF00FF00FF00FFULL);
4724 
4725             tcg_gen_shri_tl(t1, t0, 8);
4726             tcg_gen_and_tl(t1, t1, t2);
4727             tcg_gen_and_tl(t0, t0, t2);
4728             tcg_gen_shli_tl(t0, t0, 8);
4729             tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4730         }
4731         break;
4732     case OPC_DSHD:
4733         {
4734             TCGv t1 = tcg_temp_new();
4735             TCGv t2 = tcg_constant_tl(0x0000FFFF0000FFFFULL);
4736 
4737             tcg_gen_shri_tl(t1, t0, 16);
4738             tcg_gen_and_tl(t1, t1, t2);
4739             tcg_gen_and_tl(t0, t0, t2);
4740             tcg_gen_shli_tl(t0, t0, 16);
4741             tcg_gen_or_tl(t0, t0, t1);
4742             tcg_gen_shri_tl(t1, t0, 32);
4743             tcg_gen_shli_tl(t0, t0, 32);
4744             tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4745         }
4746         break;
4747 #endif
4748     default:
4749         MIPS_INVAL("bsfhl");
4750         gen_reserved_instruction(ctx);
4751         return;
4752     }
4753 }
4754 
gen_align_bits(DisasContext * ctx,int wordsz,int rd,int rs,int rt,int bits)4755 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
4756                            int rt, int bits)
4757 {
4758     TCGv t0;
4759     if (rd == 0) {
4760         /* Treat as NOP. */
4761         return;
4762     }
4763     t0 = tcg_temp_new();
4764     if (bits == 0 || bits == wordsz) {
4765         if (bits == 0) {
4766             gen_load_gpr(t0, rt);
4767         } else {
4768             gen_load_gpr(t0, rs);
4769         }
4770         switch (wordsz) {
4771         case 32:
4772             tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4773             break;
4774 #if defined(TARGET_MIPS64)
4775         case 64:
4776             tcg_gen_mov_tl(cpu_gpr[rd], t0);
4777             break;
4778 #endif
4779         }
4780     } else {
4781         TCGv t1 = tcg_temp_new();
4782         gen_load_gpr(t0, rt);
4783         gen_load_gpr(t1, rs);
4784         switch (wordsz) {
4785         case 32:
4786             {
4787                 TCGv_i64 t2 = tcg_temp_new_i64();
4788                 tcg_gen_concat_tl_i64(t2, t1, t0);
4789                 tcg_gen_shri_i64(t2, t2, 32 - bits);
4790                 gen_move_low32(cpu_gpr[rd], t2);
4791             }
4792             break;
4793 #if defined(TARGET_MIPS64)
4794         case 64:
4795             tcg_gen_shli_tl(t0, t0, bits);
4796             tcg_gen_shri_tl(t1, t1, 64 - bits);
4797             tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
4798             break;
4799 #endif
4800         }
4801     }
4802 }
4803 
gen_align(DisasContext * ctx,int wordsz,int rd,int rs,int rt,int bp)4804 void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt, int bp)
4805 {
4806     gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
4807 }
4808 
gen_bitswap(DisasContext * ctx,int opc,int rd,int rt)4809 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
4810 {
4811     TCGv t0;
4812     if (rd == 0) {
4813         /* Treat as NOP. */
4814         return;
4815     }
4816     t0 = tcg_temp_new();
4817     gen_load_gpr(t0, rt);
4818     switch (opc) {
4819     case OPC_BITSWAP:
4820         gen_helper_bitswap(cpu_gpr[rd], t0);
4821         break;
4822 #if defined(TARGET_MIPS64)
4823     case OPC_DBITSWAP:
4824         gen_helper_dbitswap(cpu_gpr[rd], t0);
4825         break;
4826 #endif
4827     }
4828 }
4829 
4830 #ifndef CONFIG_USER_ONLY
4831 /* CP0 (MMU and control) */
gen_mthc0_entrylo(TCGv arg,target_ulong off)4832 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
4833 {
4834     TCGv_i64 t0 = tcg_temp_new_i64();
4835     TCGv_i64 t1 = tcg_temp_new_i64();
4836 
4837     tcg_gen_ext_tl_i64(t0, arg);
4838     tcg_gen_ld_i64(t1, tcg_env, off);
4839 #if defined(TARGET_MIPS64)
4840     tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
4841 #else
4842     tcg_gen_concat32_i64(t1, t1, t0);
4843 #endif
4844     tcg_gen_st_i64(t1, tcg_env, off);
4845 }
4846 
gen_mthc0_store64(TCGv arg,target_ulong off)4847 static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
4848 {
4849     TCGv_i64 t0 = tcg_temp_new_i64();
4850     TCGv_i64 t1 = tcg_temp_new_i64();
4851 
4852     tcg_gen_ext_tl_i64(t0, arg);
4853     tcg_gen_ld_i64(t1, tcg_env, off);
4854     tcg_gen_concat32_i64(t1, t1, t0);
4855     tcg_gen_st_i64(t1, tcg_env, off);
4856 }
4857 
gen_mfhc0_entrylo(TCGv arg,target_ulong off)4858 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
4859 {
4860     TCGv_i64 t0 = tcg_temp_new_i64();
4861 
4862     tcg_gen_ld_i64(t0, tcg_env, off);
4863 #if defined(TARGET_MIPS64)
4864     tcg_gen_shri_i64(t0, t0, 30);
4865 #else
4866     tcg_gen_shri_i64(t0, t0, 32);
4867 #endif
4868     gen_move_low32(arg, t0);
4869 }
4870 
gen_mfhc0_load64(TCGv arg,target_ulong off,int shift)4871 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
4872 {
4873     TCGv_i64 t0 = tcg_temp_new_i64();
4874 
4875     tcg_gen_ld_i64(t0, tcg_env, off);
4876     tcg_gen_shri_i64(t0, t0, 32 + shift);
4877     gen_move_low32(arg, t0);
4878 }
4879 
gen_mfc0_load32(TCGv arg,target_ulong off)4880 static inline void gen_mfc0_load32(TCGv arg, target_ulong off)
4881 {
4882     TCGv_i32 t0 = tcg_temp_new_i32();
4883 
4884     tcg_gen_ld_i32(t0, tcg_env, off);
4885     tcg_gen_ext_i32_tl(arg, t0);
4886 }
4887 
gen_mfc0_load64(TCGv arg,target_ulong off)4888 static inline void gen_mfc0_load64(TCGv arg, target_ulong off)
4889 {
4890     tcg_gen_ld_tl(arg, tcg_env, off);
4891     tcg_gen_ext32s_tl(arg, arg);
4892 }
4893 
gen_mtc0_store32(TCGv arg,target_ulong off)4894 static inline void gen_mtc0_store32(TCGv arg, target_ulong off)
4895 {
4896     TCGv_i32 t0 = tcg_temp_new_i32();
4897 
4898     tcg_gen_trunc_tl_i32(t0, arg);
4899     tcg_gen_st_i32(t0, tcg_env, off);
4900 }
4901 
4902 #define CP0_CHECK(c)                            \
4903     do {                                        \
4904         if (!(c)) {                             \
4905             goto cp0_unimplemented;             \
4906         }                                       \
4907     } while (0)
4908 
gen_mfhc0(DisasContext * ctx,TCGv arg,int reg,int sel)4909 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4910 {
4911     const char *register_name = "invalid";
4912 
4913     switch (reg) {
4914     case CP0_REGISTER_02:
4915         switch (sel) {
4916         case 0:
4917             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
4918             gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4919             register_name = "EntryLo0";
4920             break;
4921         default:
4922             goto cp0_unimplemented;
4923         }
4924         break;
4925     case CP0_REGISTER_03:
4926         switch (sel) {
4927         case CP0_REG03__ENTRYLO1:
4928             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
4929             gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4930             register_name = "EntryLo1";
4931             break;
4932         default:
4933             goto cp0_unimplemented;
4934         }
4935         break;
4936     case CP0_REGISTER_17:
4937         switch (sel) {
4938         case CP0_REG17__LLADDR:
4939             gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr),
4940                              ctx->CP0_LLAddr_shift);
4941             register_name = "LLAddr";
4942             break;
4943         case CP0_REG17__MAAR:
4944             CP0_CHECK(ctx->mrp);
4945             gen_helper_mfhc0_maar(arg, tcg_env);
4946             register_name = "MAAR";
4947             break;
4948         default:
4949             goto cp0_unimplemented;
4950         }
4951         break;
4952     case CP0_REGISTER_19:
4953         switch (sel) {
4954         case CP0_REG19__WATCHHI0:
4955         case CP0_REG19__WATCHHI1:
4956         case CP0_REG19__WATCHHI2:
4957         case CP0_REG19__WATCHHI3:
4958         case CP0_REG19__WATCHHI4:
4959         case CP0_REG19__WATCHHI5:
4960         case CP0_REG19__WATCHHI6:
4961         case CP0_REG19__WATCHHI7:
4962             /* upper 32 bits are only available when Config5MI != 0 */
4963             CP0_CHECK(ctx->mi);
4964             gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_WatchHi[sel]), 0);
4965             register_name = "WatchHi";
4966             break;
4967         default:
4968             goto cp0_unimplemented;
4969         }
4970         break;
4971     case CP0_REGISTER_28:
4972         switch (sel) {
4973         case 0:
4974         case 2:
4975         case 4:
4976         case 6:
4977             gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
4978             register_name = "TagLo";
4979             break;
4980         default:
4981             goto cp0_unimplemented;
4982         }
4983         break;
4984     default:
4985         goto cp0_unimplemented;
4986     }
4987     trace_mips_translate_c0("mfhc0", register_name, reg, sel);
4988     return;
4989 
4990 cp0_unimplemented:
4991     qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n",
4992                   register_name, reg, sel);
4993     tcg_gen_movi_tl(arg, 0);
4994 }
4995 
gen_mthc0(DisasContext * ctx,TCGv arg,int reg,int sel)4996 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4997 {
4998     const char *register_name = "invalid";
4999     uint64_t mask = ctx->PAMask >> 36;
5000 
5001     switch (reg) {
5002     case CP0_REGISTER_02:
5003         switch (sel) {
5004         case 0:
5005             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5006             tcg_gen_andi_tl(arg, arg, mask);
5007             gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5008             register_name = "EntryLo0";
5009             break;
5010         default:
5011             goto cp0_unimplemented;
5012         }
5013         break;
5014     case CP0_REGISTER_03:
5015         switch (sel) {
5016         case CP0_REG03__ENTRYLO1:
5017             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5018             tcg_gen_andi_tl(arg, arg, mask);
5019             gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5020             register_name = "EntryLo1";
5021             break;
5022         default:
5023             goto cp0_unimplemented;
5024         }
5025         break;
5026     case CP0_REGISTER_17:
5027         switch (sel) {
5028         case CP0_REG17__LLADDR:
5029             /*
5030              * LLAddr is read-only (the only exception is bit 0 if LLB is
5031              * supported); the CP0_LLAddr_rw_bitmask does not seem to be
5032              * relevant for modern MIPS cores supporting MTHC0, therefore
5033              * treating MTHC0 to LLAddr as NOP.
5034              */
5035             register_name = "LLAddr";
5036             break;
5037         case CP0_REG17__MAAR:
5038             CP0_CHECK(ctx->mrp);
5039             gen_helper_mthc0_maar(tcg_env, arg);
5040             register_name = "MAAR";
5041             break;
5042         default:
5043             goto cp0_unimplemented;
5044         }
5045         break;
5046     case CP0_REGISTER_19:
5047         switch (sel) {
5048         case CP0_REG19__WATCHHI0:
5049         case CP0_REG19__WATCHHI1:
5050         case CP0_REG19__WATCHHI2:
5051         case CP0_REG19__WATCHHI3:
5052         case CP0_REG19__WATCHHI4:
5053         case CP0_REG19__WATCHHI5:
5054         case CP0_REG19__WATCHHI6:
5055         case CP0_REG19__WATCHHI7:
5056             /* upper 32 bits are only available when Config5MI != 0 */
5057             CP0_CHECK(ctx->mi);
5058             gen_helper_0e1i(mthc0_watchhi, arg, sel);
5059             register_name = "WatchHi";
5060             break;
5061         default:
5062             goto cp0_unimplemented;
5063         }
5064         break;
5065     case CP0_REGISTER_28:
5066         switch (sel) {
5067         case 0:
5068         case 2:
5069         case 4:
5070         case 6:
5071             tcg_gen_andi_tl(arg, arg, mask);
5072             gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
5073             register_name = "TagLo";
5074             break;
5075         default:
5076             goto cp0_unimplemented;
5077         }
5078         break;
5079     default:
5080         goto cp0_unimplemented;
5081     }
5082     trace_mips_translate_c0("mthc0", register_name, reg, sel);
5083     return;
5084 
5085 cp0_unimplemented:
5086     qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n",
5087                   register_name, reg, sel);
5088 }
5089 
gen_mfc0_unimplemented(DisasContext * ctx,TCGv arg)5090 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
5091 {
5092     if (ctx->insn_flags & ISA_MIPS_R6) {
5093         tcg_gen_movi_tl(arg, 0);
5094     } else {
5095         tcg_gen_movi_tl(arg, ~0);
5096     }
5097 }
5098 
gen_mfc0(DisasContext * ctx,TCGv arg,int reg,int sel)5099 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5100 {
5101     const char *register_name = "invalid";
5102 
5103     if (sel != 0) {
5104         check_insn(ctx, ISA_MIPS_R1);
5105     }
5106 
5107     switch (reg) {
5108     case CP0_REGISTER_00:
5109         switch (sel) {
5110         case CP0_REG00__INDEX:
5111             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5112             register_name = "Index";
5113             break;
5114         case CP0_REG00__MVPCONTROL:
5115             CP0_CHECK(disas_mt_available(ctx));
5116             gen_helper_mfc0_mvpcontrol(arg, tcg_env);
5117             register_name = "MVPControl";
5118             break;
5119         case CP0_REG00__MVPCONF0:
5120             CP0_CHECK(disas_mt_available(ctx));
5121             gen_helper_mfc0_mvpconf0(arg, tcg_env);
5122             register_name = "MVPConf0";
5123             break;
5124         case CP0_REG00__MVPCONF1:
5125             CP0_CHECK(disas_mt_available(ctx));
5126             gen_helper_mfc0_mvpconf1(arg, tcg_env);
5127             register_name = "MVPConf1";
5128             break;
5129         case CP0_REG00__VPCONTROL:
5130             CP0_CHECK(ctx->vp);
5131             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
5132             register_name = "VPControl";
5133             break;
5134         default:
5135             goto cp0_unimplemented;
5136         }
5137         break;
5138     case CP0_REGISTER_01:
5139         switch (sel) {
5140         case CP0_REG01__RANDOM:
5141             CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
5142             gen_helper_mfc0_random(arg, tcg_env);
5143             register_name = "Random";
5144             break;
5145         case CP0_REG01__VPECONTROL:
5146             CP0_CHECK(disas_mt_available(ctx));
5147             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5148             register_name = "VPEControl";
5149             break;
5150         case CP0_REG01__VPECONF0:
5151             CP0_CHECK(disas_mt_available(ctx));
5152             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5153             register_name = "VPEConf0";
5154             break;
5155         case CP0_REG01__VPECONF1:
5156             CP0_CHECK(disas_mt_available(ctx));
5157             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5158             register_name = "VPEConf1";
5159             break;
5160         case CP0_REG01__YQMASK:
5161             CP0_CHECK(disas_mt_available(ctx));
5162             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
5163             register_name = "YQMask";
5164             break;
5165         case CP0_REG01__VPESCHEDULE:
5166             CP0_CHECK(disas_mt_available(ctx));
5167             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
5168             register_name = "VPESchedule";
5169             break;
5170         case CP0_REG01__VPESCHEFBACK:
5171             CP0_CHECK(disas_mt_available(ctx));
5172             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5173             register_name = "VPEScheFBack";
5174             break;
5175         case CP0_REG01__VPEOPT:
5176             CP0_CHECK(disas_mt_available(ctx));
5177             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5178             register_name = "VPEOpt";
5179             break;
5180         default:
5181             goto cp0_unimplemented;
5182         }
5183         break;
5184     case CP0_REGISTER_02:
5185         switch (sel) {
5186         case CP0_REG02__ENTRYLO0:
5187             {
5188                 TCGv_i64 tmp = tcg_temp_new_i64();
5189                 tcg_gen_ld_i64(tmp, tcg_env,
5190                                offsetof(CPUMIPSState, CP0_EntryLo0));
5191 #if defined(TARGET_MIPS64)
5192                 if (ctx->rxi) {
5193                     /* Move RI/XI fields to bits 31:30 */
5194                     tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5195                     tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5196                 }
5197 #endif
5198                 gen_move_low32(arg, tmp);
5199             }
5200             register_name = "EntryLo0";
5201             break;
5202         case CP0_REG02__TCSTATUS:
5203             CP0_CHECK(disas_mt_available(ctx));
5204             gen_helper_mfc0_tcstatus(arg, tcg_env);
5205             register_name = "TCStatus";
5206             break;
5207         case CP0_REG02__TCBIND:
5208             CP0_CHECK(disas_mt_available(ctx));
5209             gen_helper_mfc0_tcbind(arg, tcg_env);
5210             register_name = "TCBind";
5211             break;
5212         case CP0_REG02__TCRESTART:
5213             CP0_CHECK(disas_mt_available(ctx));
5214             gen_helper_mfc0_tcrestart(arg, tcg_env);
5215             register_name = "TCRestart";
5216             break;
5217         case CP0_REG02__TCHALT:
5218             CP0_CHECK(disas_mt_available(ctx));
5219             gen_helper_mfc0_tchalt(arg, tcg_env);
5220             register_name = "TCHalt";
5221             break;
5222         case CP0_REG02__TCCONTEXT:
5223             CP0_CHECK(disas_mt_available(ctx));
5224             gen_helper_mfc0_tccontext(arg, tcg_env);
5225             register_name = "TCContext";
5226             break;
5227         case CP0_REG02__TCSCHEDULE:
5228             CP0_CHECK(disas_mt_available(ctx));
5229             gen_helper_mfc0_tcschedule(arg, tcg_env);
5230             register_name = "TCSchedule";
5231             break;
5232         case CP0_REG02__TCSCHEFBACK:
5233             CP0_CHECK(disas_mt_available(ctx));
5234             gen_helper_mfc0_tcschefback(arg, tcg_env);
5235             register_name = "TCScheFBack";
5236             break;
5237         default:
5238             goto cp0_unimplemented;
5239         }
5240         break;
5241     case CP0_REGISTER_03:
5242         switch (sel) {
5243         case CP0_REG03__ENTRYLO1:
5244             {
5245                 TCGv_i64 tmp = tcg_temp_new_i64();
5246                 tcg_gen_ld_i64(tmp, tcg_env,
5247                                offsetof(CPUMIPSState, CP0_EntryLo1));
5248 #if defined(TARGET_MIPS64)
5249                 if (ctx->rxi) {
5250                     /* Move RI/XI fields to bits 31:30 */
5251                     tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5252                     tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5253                 }
5254 #endif
5255                 gen_move_low32(arg, tmp);
5256             }
5257             register_name = "EntryLo1";
5258             break;
5259         case CP0_REG03__GLOBALNUM:
5260             CP0_CHECK(ctx->vp);
5261             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
5262             register_name = "GlobalNumber";
5263             break;
5264         default:
5265             goto cp0_unimplemented;
5266         }
5267         break;
5268     case CP0_REGISTER_04:
5269         switch (sel) {
5270         case CP0_REG04__CONTEXT:
5271             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_Context));
5272             tcg_gen_ext32s_tl(arg, arg);
5273             register_name = "Context";
5274             break;
5275         case CP0_REG04__CONTEXTCONFIG:
5276             /* SmartMIPS ASE */
5277             /* gen_helper_mfc0_contextconfig(arg); */
5278             register_name = "ContextConfig";
5279             goto cp0_unimplemented;
5280         case CP0_REG04__USERLOCAL:
5281             CP0_CHECK(ctx->ulri);
5282             tcg_gen_ld_tl(arg, tcg_env,
5283                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5284             tcg_gen_ext32s_tl(arg, arg);
5285             register_name = "UserLocal";
5286             break;
5287         case CP0_REG04__MMID:
5288             CP0_CHECK(ctx->mi);
5289             gen_helper_mtc0_memorymapid(tcg_env, arg);
5290             register_name = "MMID";
5291             break;
5292         default:
5293             goto cp0_unimplemented;
5294         }
5295         break;
5296     case CP0_REGISTER_05:
5297         switch (sel) {
5298         case CP0_REG05__PAGEMASK:
5299             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5300             register_name = "PageMask";
5301             break;
5302         case CP0_REG05__PAGEGRAIN:
5303             check_insn(ctx, ISA_MIPS_R2);
5304             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5305             register_name = "PageGrain";
5306             break;
5307         case CP0_REG05__SEGCTL0:
5308             CP0_CHECK(ctx->sc);
5309             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl0));
5310             tcg_gen_ext32s_tl(arg, arg);
5311             register_name = "SegCtl0";
5312             break;
5313         case CP0_REG05__SEGCTL1:
5314             CP0_CHECK(ctx->sc);
5315             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl1));
5316             tcg_gen_ext32s_tl(arg, arg);
5317             register_name = "SegCtl1";
5318             break;
5319         case CP0_REG05__SEGCTL2:
5320             CP0_CHECK(ctx->sc);
5321             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl2));
5322             tcg_gen_ext32s_tl(arg, arg);
5323             register_name = "SegCtl2";
5324             break;
5325         case CP0_REG05__PWBASE:
5326             check_pw(ctx);
5327             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
5328             register_name = "PWBase";
5329             break;
5330         case CP0_REG05__PWFIELD:
5331             check_pw(ctx);
5332             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
5333             register_name = "PWField";
5334             break;
5335         case CP0_REG05__PWSIZE:
5336             check_pw(ctx);
5337             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
5338             register_name = "PWSize";
5339             break;
5340         default:
5341             goto cp0_unimplemented;
5342         }
5343         break;
5344     case CP0_REGISTER_06:
5345         switch (sel) {
5346         case CP0_REG06__WIRED:
5347             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5348             register_name = "Wired";
5349             break;
5350         case CP0_REG06__SRSCONF0:
5351             check_insn(ctx, ISA_MIPS_R2);
5352             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5353             register_name = "SRSConf0";
5354             break;
5355         case CP0_REG06__SRSCONF1:
5356             check_insn(ctx, ISA_MIPS_R2);
5357             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5358             register_name = "SRSConf1";
5359             break;
5360         case CP0_REG06__SRSCONF2:
5361             check_insn(ctx, ISA_MIPS_R2);
5362             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5363             register_name = "SRSConf2";
5364             break;
5365         case CP0_REG06__SRSCONF3:
5366             check_insn(ctx, ISA_MIPS_R2);
5367             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5368             register_name = "SRSConf3";
5369             break;
5370         case CP0_REG06__SRSCONF4:
5371             check_insn(ctx, ISA_MIPS_R2);
5372             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5373             register_name = "SRSConf4";
5374             break;
5375         case CP0_REG06__PWCTL:
5376             check_pw(ctx);
5377             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
5378             register_name = "PWCtl";
5379             break;
5380         default:
5381             goto cp0_unimplemented;
5382         }
5383         break;
5384     case CP0_REGISTER_07:
5385         switch (sel) {
5386         case CP0_REG07__HWRENA:
5387             check_insn(ctx, ISA_MIPS_R2);
5388             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5389             register_name = "HWREna";
5390             break;
5391         default:
5392             goto cp0_unimplemented;
5393         }
5394         break;
5395     case CP0_REGISTER_08:
5396         switch (sel) {
5397         case CP0_REG08__BADVADDR:
5398             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5399             tcg_gen_ext32s_tl(arg, arg);
5400             register_name = "BadVAddr";
5401             break;
5402         case CP0_REG08__BADINSTR:
5403             CP0_CHECK(ctx->bi);
5404             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5405             register_name = "BadInstr";
5406             break;
5407         case CP0_REG08__BADINSTRP:
5408             CP0_CHECK(ctx->bp);
5409             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5410             register_name = "BadInstrP";
5411             break;
5412         case CP0_REG08__BADINSTRX:
5413             CP0_CHECK(ctx->bi);
5414             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
5415             tcg_gen_andi_tl(arg, arg, ~0xffff);
5416             register_name = "BadInstrX";
5417             break;
5418         default:
5419             goto cp0_unimplemented;
5420         }
5421         break;
5422     case CP0_REGISTER_09:
5423         switch (sel) {
5424         case CP0_REG09__COUNT:
5425             /* Mark as an IO operation because we read the time.  */
5426             translator_io_start(&ctx->base);
5427 
5428             gen_helper_mfc0_count(arg, tcg_env);
5429             /*
5430              * Break the TB to be able to take timer interrupts immediately
5431              * after reading count. DISAS_STOP isn't sufficient, we need to
5432              * ensure we break completely out of translated code.
5433              */
5434             gen_save_pc(ctx->base.pc_next + 4);
5435             ctx->base.is_jmp = DISAS_EXIT;
5436             register_name = "Count";
5437             break;
5438         default:
5439             goto cp0_unimplemented;
5440         }
5441         break;
5442     case CP0_REGISTER_10:
5443         switch (sel) {
5444         case CP0_REG10__ENTRYHI:
5445             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EntryHi));
5446             tcg_gen_ext32s_tl(arg, arg);
5447             register_name = "EntryHi";
5448             break;
5449         default:
5450             goto cp0_unimplemented;
5451         }
5452         break;
5453     case CP0_REGISTER_11:
5454         switch (sel) {
5455         case CP0_REG11__COMPARE:
5456             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5457             register_name = "Compare";
5458             break;
5459         /* 6,7 are implementation dependent */
5460         default:
5461             goto cp0_unimplemented;
5462         }
5463         break;
5464     case CP0_REGISTER_12:
5465         switch (sel) {
5466         case CP0_REG12__STATUS:
5467             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5468             register_name = "Status";
5469             break;
5470         case CP0_REG12__INTCTL:
5471             check_insn(ctx, ISA_MIPS_R2);
5472             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5473             register_name = "IntCtl";
5474             break;
5475         case CP0_REG12__SRSCTL:
5476             check_insn(ctx, ISA_MIPS_R2);
5477             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5478             register_name = "SRSCtl";
5479             break;
5480         case CP0_REG12__SRSMAP:
5481             check_insn(ctx, ISA_MIPS_R2);
5482             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5483             register_name = "SRSMap";
5484             break;
5485         default:
5486             goto cp0_unimplemented;
5487        }
5488         break;
5489     case CP0_REGISTER_13:
5490         switch (sel) {
5491         case CP0_REG13__CAUSE:
5492             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5493             register_name = "Cause";
5494             break;
5495         default:
5496             goto cp0_unimplemented;
5497        }
5498         break;
5499     case CP0_REGISTER_14:
5500         switch (sel) {
5501         case CP0_REG14__EPC:
5502             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC));
5503             tcg_gen_ext32s_tl(arg, arg);
5504             register_name = "EPC";
5505             break;
5506         default:
5507             goto cp0_unimplemented;
5508         }
5509         break;
5510     case CP0_REGISTER_15:
5511         switch (sel) {
5512         case CP0_REG15__PRID:
5513             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5514             register_name = "PRid";
5515             break;
5516         case CP0_REG15__EBASE:
5517             check_insn(ctx, ISA_MIPS_R2);
5518             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EBase));
5519             tcg_gen_ext32s_tl(arg, arg);
5520             register_name = "EBase";
5521             break;
5522         case CP0_REG15__CMGCRBASE:
5523             check_insn(ctx, ISA_MIPS_R2);
5524             CP0_CHECK(ctx->cmgcr);
5525             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
5526             tcg_gen_ext32s_tl(arg, arg);
5527             register_name = "CMGCRBase";
5528             break;
5529         default:
5530             goto cp0_unimplemented;
5531        }
5532         break;
5533     case CP0_REGISTER_16:
5534         switch (sel) {
5535         case CP0_REG16__CONFIG:
5536             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5537             register_name = "Config";
5538             break;
5539         case CP0_REG16__CONFIG1:
5540             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5541             register_name = "Config1";
5542             break;
5543         case CP0_REG16__CONFIG2:
5544             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5545             register_name = "Config2";
5546             break;
5547         case CP0_REG16__CONFIG3:
5548             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5549             register_name = "Config3";
5550             break;
5551         case CP0_REG16__CONFIG4:
5552             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
5553             register_name = "Config4";
5554             break;
5555         case CP0_REG16__CONFIG5:
5556             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
5557             register_name = "Config5";
5558             break;
5559         /* 6,7 are implementation dependent */
5560         case CP0_REG16__CONFIG6:
5561             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5562             register_name = "Config6";
5563             break;
5564         case CP0_REG16__CONFIG7:
5565             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5566             register_name = "Config7";
5567             break;
5568         default:
5569             goto cp0_unimplemented;
5570         }
5571         break;
5572     case CP0_REGISTER_17:
5573         switch (sel) {
5574         case CP0_REG17__LLADDR:
5575             gen_helper_mfc0_lladdr(arg, tcg_env);
5576             register_name = "LLAddr";
5577             break;
5578         case CP0_REG17__MAAR:
5579             CP0_CHECK(ctx->mrp);
5580             gen_helper_mfc0_maar(arg, tcg_env);
5581             register_name = "MAAR";
5582             break;
5583         case CP0_REG17__MAARI:
5584             CP0_CHECK(ctx->mrp);
5585             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
5586             register_name = "MAARI";
5587             break;
5588         default:
5589             goto cp0_unimplemented;
5590         }
5591         break;
5592     case CP0_REGISTER_18:
5593         switch (sel) {
5594         case CP0_REG18__WATCHLO0:
5595         case CP0_REG18__WATCHLO1:
5596         case CP0_REG18__WATCHLO2:
5597         case CP0_REG18__WATCHLO3:
5598         case CP0_REG18__WATCHLO4:
5599         case CP0_REG18__WATCHLO5:
5600         case CP0_REG18__WATCHLO6:
5601         case CP0_REG18__WATCHLO7:
5602             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
5603             gen_helper_1e0i(mfc0_watchlo, arg, sel);
5604             register_name = "WatchLo";
5605             break;
5606         default:
5607             goto cp0_unimplemented;
5608         }
5609         break;
5610     case CP0_REGISTER_19:
5611         switch (sel) {
5612         case CP0_REG19__WATCHHI0:
5613         case CP0_REG19__WATCHHI1:
5614         case CP0_REG19__WATCHHI2:
5615         case CP0_REG19__WATCHHI3:
5616         case CP0_REG19__WATCHHI4:
5617         case CP0_REG19__WATCHHI5:
5618         case CP0_REG19__WATCHHI6:
5619         case CP0_REG19__WATCHHI7:
5620             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
5621             gen_helper_1e0i(mfc0_watchhi, arg, sel);
5622             register_name = "WatchHi";
5623             break;
5624         default:
5625             goto cp0_unimplemented;
5626         }
5627         break;
5628     case CP0_REGISTER_20:
5629         switch (sel) {
5630         case CP0_REG20__XCONTEXT:
5631 #if defined(TARGET_MIPS64)
5632             check_insn(ctx, ISA_MIPS3);
5633             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_XContext));
5634             tcg_gen_ext32s_tl(arg, arg);
5635             register_name = "XContext";
5636             break;
5637 #endif
5638         default:
5639             goto cp0_unimplemented;
5640         }
5641         break;
5642     case CP0_REGISTER_21:
5643        /* Officially reserved, but sel 0 is used for R1x000 framemask */
5644         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
5645         switch (sel) {
5646         case 0:
5647             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5648             register_name = "Framemask";
5649             break;
5650         default:
5651             goto cp0_unimplemented;
5652         }
5653         break;
5654     case CP0_REGISTER_22:
5655         tcg_gen_movi_tl(arg, 0); /* unimplemented */
5656         register_name = "'Diagnostic"; /* implementation dependent */
5657         break;
5658     case CP0_REGISTER_23:
5659         switch (sel) {
5660         case CP0_REG23__DEBUG:
5661             gen_helper_mfc0_debug(arg, tcg_env); /* EJTAG support */
5662             register_name = "Debug";
5663             break;
5664         case CP0_REG23__TRACECONTROL:
5665             /* PDtrace support */
5666             /* gen_helper_mfc0_tracecontrol(arg);  */
5667             register_name = "TraceControl";
5668             goto cp0_unimplemented;
5669         case CP0_REG23__TRACECONTROL2:
5670             /* PDtrace support */
5671             /* gen_helper_mfc0_tracecontrol2(arg); */
5672             register_name = "TraceControl2";
5673             goto cp0_unimplemented;
5674         case CP0_REG23__USERTRACEDATA1:
5675             /* PDtrace support */
5676             /* gen_helper_mfc0_usertracedata1(arg);*/
5677             register_name = "UserTraceData1";
5678             goto cp0_unimplemented;
5679         case CP0_REG23__TRACEIBPC:
5680             /* PDtrace support */
5681             /* gen_helper_mfc0_traceibpc(arg);     */
5682             register_name = "TraceIBPC";
5683             goto cp0_unimplemented;
5684         case CP0_REG23__TRACEDBPC:
5685             /* PDtrace support */
5686             /* gen_helper_mfc0_tracedbpc(arg);     */
5687             register_name = "TraceDBPC";
5688             goto cp0_unimplemented;
5689         default:
5690             goto cp0_unimplemented;
5691         }
5692         break;
5693     case CP0_REGISTER_24:
5694         switch (sel) {
5695         case CP0_REG24__DEPC:
5696             /* EJTAG support */
5697             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC));
5698             tcg_gen_ext32s_tl(arg, arg);
5699             register_name = "DEPC";
5700             break;
5701         default:
5702             goto cp0_unimplemented;
5703         }
5704         break;
5705     case CP0_REGISTER_25:
5706         switch (sel) {
5707         case CP0_REG25__PERFCTL0:
5708             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5709             register_name = "Performance0";
5710             break;
5711         case CP0_REG25__PERFCNT0:
5712             /* gen_helper_mfc0_performance1(arg); */
5713             register_name = "Performance1";
5714             goto cp0_unimplemented;
5715         case CP0_REG25__PERFCTL1:
5716             /* gen_helper_mfc0_performance2(arg); */
5717             register_name = "Performance2";
5718             goto cp0_unimplemented;
5719         case CP0_REG25__PERFCNT1:
5720             /* gen_helper_mfc0_performance3(arg); */
5721             register_name = "Performance3";
5722             goto cp0_unimplemented;
5723         case CP0_REG25__PERFCTL2:
5724             /* gen_helper_mfc0_performance4(arg); */
5725             register_name = "Performance4";
5726             goto cp0_unimplemented;
5727         case CP0_REG25__PERFCNT2:
5728             /* gen_helper_mfc0_performance5(arg); */
5729             register_name = "Performance5";
5730             goto cp0_unimplemented;
5731         case CP0_REG25__PERFCTL3:
5732             /* gen_helper_mfc0_performance6(arg); */
5733             register_name = "Performance6";
5734             goto cp0_unimplemented;
5735         case CP0_REG25__PERFCNT3:
5736             /* gen_helper_mfc0_performance7(arg); */
5737             register_name = "Performance7";
5738             goto cp0_unimplemented;
5739         default:
5740             goto cp0_unimplemented;
5741         }
5742         break;
5743     case CP0_REGISTER_26:
5744         switch (sel) {
5745         case CP0_REG26__ERRCTL:
5746             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
5747             register_name = "ErrCtl";
5748             break;
5749         default:
5750             goto cp0_unimplemented;
5751         }
5752         break;
5753     case CP0_REGISTER_27:
5754         switch (sel) {
5755         case CP0_REG27__CACHERR:
5756             tcg_gen_movi_tl(arg, 0); /* unimplemented */
5757             register_name = "CacheErr";
5758             break;
5759         default:
5760             goto cp0_unimplemented;
5761         }
5762         break;
5763     case CP0_REGISTER_28:
5764         switch (sel) {
5765         case CP0_REG28__TAGLO:
5766         case CP0_REG28__TAGLO1:
5767         case CP0_REG28__TAGLO2:
5768         case CP0_REG28__TAGLO3:
5769             {
5770                 TCGv_i64 tmp = tcg_temp_new_i64();
5771                 tcg_gen_ld_i64(tmp, tcg_env, offsetof(CPUMIPSState, CP0_TagLo));
5772                 gen_move_low32(arg, tmp);
5773             }
5774             register_name = "TagLo";
5775             break;
5776         case CP0_REG28__DATALO:
5777         case CP0_REG28__DATALO1:
5778         case CP0_REG28__DATALO2:
5779         case CP0_REG28__DATALO3:
5780             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5781             register_name = "DataLo";
5782             break;
5783         default:
5784             goto cp0_unimplemented;
5785         }
5786         break;
5787     case CP0_REGISTER_29:
5788         switch (sel) {
5789         case CP0_REG29__TAGHI:
5790         case CP0_REG29__TAGHI1:
5791         case CP0_REG29__TAGHI2:
5792         case CP0_REG29__TAGHI3:
5793             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5794             register_name = "TagHi";
5795             break;
5796         case CP0_REG29__DATAHI:
5797         case CP0_REG29__DATAHI1:
5798         case CP0_REG29__DATAHI2:
5799         case CP0_REG29__DATAHI3:
5800             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5801             register_name = "DataHi";
5802             break;
5803         default:
5804             goto cp0_unimplemented;
5805         }
5806         break;
5807     case CP0_REGISTER_30:
5808         switch (sel) {
5809         case CP0_REG30__ERROREPC:
5810             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5811             tcg_gen_ext32s_tl(arg, arg);
5812             register_name = "ErrorEPC";
5813             break;
5814         default:
5815             goto cp0_unimplemented;
5816         }
5817         break;
5818     case CP0_REGISTER_31:
5819         switch (sel) {
5820         case CP0_REG31__DESAVE:
5821             /* EJTAG support */
5822             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5823             register_name = "DESAVE";
5824             break;
5825         case CP0_REG31__KSCRATCH1:
5826         case CP0_REG31__KSCRATCH2:
5827         case CP0_REG31__KSCRATCH3:
5828         case CP0_REG31__KSCRATCH4:
5829         case CP0_REG31__KSCRATCH5:
5830         case CP0_REG31__KSCRATCH6:
5831             CP0_CHECK(ctx->kscrexist & (1 << sel));
5832             tcg_gen_ld_tl(arg, tcg_env,
5833                           offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
5834             tcg_gen_ext32s_tl(arg, arg);
5835             register_name = "KScratch";
5836             break;
5837         default:
5838             goto cp0_unimplemented;
5839         }
5840         break;
5841     default:
5842        goto cp0_unimplemented;
5843     }
5844     trace_mips_translate_c0("mfc0", register_name, reg, sel);
5845     return;
5846 
5847 cp0_unimplemented:
5848     qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n",
5849                   register_name, reg, sel);
5850     gen_mfc0_unimplemented(ctx, arg);
5851 }
5852 
gen_mtc0(DisasContext * ctx,TCGv arg,int reg,int sel)5853 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5854 {
5855     const char *register_name = "invalid";
5856     bool icount;
5857 
5858     if (sel != 0) {
5859         check_insn(ctx, ISA_MIPS_R1);
5860     }
5861 
5862     icount = translator_io_start(&ctx->base);
5863 
5864     switch (reg) {
5865     case CP0_REGISTER_00:
5866         switch (sel) {
5867         case CP0_REG00__INDEX:
5868             gen_helper_mtc0_index(tcg_env, arg);
5869             register_name = "Index";
5870             break;
5871         case CP0_REG00__MVPCONTROL:
5872             CP0_CHECK(disas_mt_available(ctx));
5873             gen_helper_mtc0_mvpcontrol(tcg_env, arg);
5874             register_name = "MVPControl";
5875             break;
5876         case CP0_REG00__MVPCONF0:
5877             CP0_CHECK(disas_mt_available(ctx));
5878             /* ignored */
5879             register_name = "MVPConf0";
5880             break;
5881         case CP0_REG00__MVPCONF1:
5882             CP0_CHECK(disas_mt_available(ctx));
5883             /* ignored */
5884             register_name = "MVPConf1";
5885             break;
5886         case CP0_REG00__VPCONTROL:
5887             CP0_CHECK(ctx->vp);
5888             /* ignored */
5889             register_name = "VPControl";
5890             break;
5891         default:
5892             goto cp0_unimplemented;
5893         }
5894         break;
5895     case CP0_REGISTER_01:
5896         switch (sel) {
5897         case CP0_REG01__RANDOM:
5898             /* ignored */
5899             register_name = "Random";
5900             break;
5901         case CP0_REG01__VPECONTROL:
5902             CP0_CHECK(disas_mt_available(ctx));
5903             gen_helper_mtc0_vpecontrol(tcg_env, arg);
5904             register_name = "VPEControl";
5905             break;
5906         case CP0_REG01__VPECONF0:
5907             CP0_CHECK(disas_mt_available(ctx));
5908             gen_helper_mtc0_vpeconf0(tcg_env, arg);
5909             register_name = "VPEConf0";
5910             break;
5911         case CP0_REG01__VPECONF1:
5912             CP0_CHECK(disas_mt_available(ctx));
5913             gen_helper_mtc0_vpeconf1(tcg_env, arg);
5914             register_name = "VPEConf1";
5915             break;
5916         case CP0_REG01__YQMASK:
5917             CP0_CHECK(disas_mt_available(ctx));
5918             gen_helper_mtc0_yqmask(tcg_env, arg);
5919             register_name = "YQMask";
5920             break;
5921         case CP0_REG01__VPESCHEDULE:
5922             CP0_CHECK(disas_mt_available(ctx));
5923             tcg_gen_st_tl(arg, tcg_env,
5924                           offsetof(CPUMIPSState, CP0_VPESchedule));
5925             register_name = "VPESchedule";
5926             break;
5927         case CP0_REG01__VPESCHEFBACK:
5928             CP0_CHECK(disas_mt_available(ctx));
5929             tcg_gen_st_tl(arg, tcg_env,
5930                           offsetof(CPUMIPSState, CP0_VPEScheFBack));
5931             register_name = "VPEScheFBack";
5932             break;
5933         case CP0_REG01__VPEOPT:
5934             CP0_CHECK(disas_mt_available(ctx));
5935             gen_helper_mtc0_vpeopt(tcg_env, arg);
5936             register_name = "VPEOpt";
5937             break;
5938         default:
5939             goto cp0_unimplemented;
5940         }
5941         break;
5942     case CP0_REGISTER_02:
5943         switch (sel) {
5944         case CP0_REG02__ENTRYLO0:
5945             gen_helper_mtc0_entrylo0(tcg_env, arg);
5946             register_name = "EntryLo0";
5947             break;
5948         case CP0_REG02__TCSTATUS:
5949             CP0_CHECK(disas_mt_available(ctx));
5950             gen_helper_mtc0_tcstatus(tcg_env, arg);
5951             register_name = "TCStatus";
5952             break;
5953         case CP0_REG02__TCBIND:
5954             CP0_CHECK(disas_mt_available(ctx));
5955             gen_helper_mtc0_tcbind(tcg_env, arg);
5956             register_name = "TCBind";
5957             break;
5958         case CP0_REG02__TCRESTART:
5959             CP0_CHECK(disas_mt_available(ctx));
5960             gen_helper_mtc0_tcrestart(tcg_env, arg);
5961             register_name = "TCRestart";
5962             break;
5963         case CP0_REG02__TCHALT:
5964             CP0_CHECK(disas_mt_available(ctx));
5965             gen_helper_mtc0_tchalt(tcg_env, arg);
5966             register_name = "TCHalt";
5967             break;
5968         case CP0_REG02__TCCONTEXT:
5969             CP0_CHECK(disas_mt_available(ctx));
5970             gen_helper_mtc0_tccontext(tcg_env, arg);
5971             register_name = "TCContext";
5972             break;
5973         case CP0_REG02__TCSCHEDULE:
5974             CP0_CHECK(disas_mt_available(ctx));
5975             gen_helper_mtc0_tcschedule(tcg_env, arg);
5976             register_name = "TCSchedule";
5977             break;
5978         case CP0_REG02__TCSCHEFBACK:
5979             CP0_CHECK(disas_mt_available(ctx));
5980             gen_helper_mtc0_tcschefback(tcg_env, arg);
5981             register_name = "TCScheFBack";
5982             break;
5983         default:
5984             goto cp0_unimplemented;
5985         }
5986         break;
5987     case CP0_REGISTER_03:
5988         switch (sel) {
5989         case CP0_REG03__ENTRYLO1:
5990             gen_helper_mtc0_entrylo1(tcg_env, arg);
5991             register_name = "EntryLo1";
5992             break;
5993         case CP0_REG03__GLOBALNUM:
5994             CP0_CHECK(ctx->vp);
5995             /* ignored */
5996             register_name = "GlobalNumber";
5997             break;
5998         default:
5999             goto cp0_unimplemented;
6000         }
6001         break;
6002     case CP0_REGISTER_04:
6003         switch (sel) {
6004         case CP0_REG04__CONTEXT:
6005             gen_helper_mtc0_context(tcg_env, arg);
6006             register_name = "Context";
6007             break;
6008         case CP0_REG04__CONTEXTCONFIG:
6009             /* SmartMIPS ASE */
6010             /* gen_helper_mtc0_contextconfig(arg); */
6011             register_name = "ContextConfig";
6012             goto cp0_unimplemented;
6013         case CP0_REG04__USERLOCAL:
6014             CP0_CHECK(ctx->ulri);
6015             tcg_gen_st_tl(arg, tcg_env,
6016                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6017             register_name = "UserLocal";
6018             break;
6019         case CP0_REG04__MMID:
6020             CP0_CHECK(ctx->mi);
6021             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID));
6022             register_name = "MMID";
6023             break;
6024         default:
6025             goto cp0_unimplemented;
6026         }
6027         break;
6028     case CP0_REGISTER_05:
6029         switch (sel) {
6030         case CP0_REG05__PAGEMASK:
6031             gen_helper_mtc0_pagemask(tcg_env, arg);
6032             register_name = "PageMask";
6033             break;
6034         case CP0_REG05__PAGEGRAIN:
6035             check_insn(ctx, ISA_MIPS_R2);
6036             gen_helper_mtc0_pagegrain(tcg_env, arg);
6037             register_name = "PageGrain";
6038             ctx->base.is_jmp = DISAS_STOP;
6039             break;
6040         case CP0_REG05__SEGCTL0:
6041             CP0_CHECK(ctx->sc);
6042             gen_helper_mtc0_segctl0(tcg_env, arg);
6043             register_name = "SegCtl0";
6044             break;
6045         case CP0_REG05__SEGCTL1:
6046             CP0_CHECK(ctx->sc);
6047             gen_helper_mtc0_segctl1(tcg_env, arg);
6048             register_name = "SegCtl1";
6049             break;
6050         case CP0_REG05__SEGCTL2:
6051             CP0_CHECK(ctx->sc);
6052             gen_helper_mtc0_segctl2(tcg_env, arg);
6053             register_name = "SegCtl2";
6054             break;
6055         case CP0_REG05__PWBASE:
6056             check_pw(ctx);
6057             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6058             register_name = "PWBase";
6059             break;
6060         case CP0_REG05__PWFIELD:
6061             check_pw(ctx);
6062             gen_helper_mtc0_pwfield(tcg_env, arg);
6063             register_name = "PWField";
6064             break;
6065         case CP0_REG05__PWSIZE:
6066             check_pw(ctx);
6067             gen_helper_mtc0_pwsize(tcg_env, arg);
6068             register_name = "PWSize";
6069             break;
6070         default:
6071             goto cp0_unimplemented;
6072         }
6073         break;
6074     case CP0_REGISTER_06:
6075         switch (sel) {
6076         case CP0_REG06__WIRED:
6077             gen_helper_mtc0_wired(tcg_env, arg);
6078             register_name = "Wired";
6079             break;
6080         case CP0_REG06__SRSCONF0:
6081             check_insn(ctx, ISA_MIPS_R2);
6082             gen_helper_mtc0_srsconf0(tcg_env, arg);
6083             register_name = "SRSConf0";
6084             break;
6085         case CP0_REG06__SRSCONF1:
6086             check_insn(ctx, ISA_MIPS_R2);
6087             gen_helper_mtc0_srsconf1(tcg_env, arg);
6088             register_name = "SRSConf1";
6089             break;
6090         case CP0_REG06__SRSCONF2:
6091             check_insn(ctx, ISA_MIPS_R2);
6092             gen_helper_mtc0_srsconf2(tcg_env, arg);
6093             register_name = "SRSConf2";
6094             break;
6095         case CP0_REG06__SRSCONF3:
6096             check_insn(ctx, ISA_MIPS_R2);
6097             gen_helper_mtc0_srsconf3(tcg_env, arg);
6098             register_name = "SRSConf3";
6099             break;
6100         case CP0_REG06__SRSCONF4:
6101             check_insn(ctx, ISA_MIPS_R2);
6102             gen_helper_mtc0_srsconf4(tcg_env, arg);
6103             register_name = "SRSConf4";
6104             break;
6105         case CP0_REG06__PWCTL:
6106             check_pw(ctx);
6107             gen_helper_mtc0_pwctl(tcg_env, arg);
6108             register_name = "PWCtl";
6109             break;
6110         default:
6111             goto cp0_unimplemented;
6112         }
6113         break;
6114     case CP0_REGISTER_07:
6115         switch (sel) {
6116         case CP0_REG07__HWRENA:
6117             check_insn(ctx, ISA_MIPS_R2);
6118             gen_helper_mtc0_hwrena(tcg_env, arg);
6119             ctx->base.is_jmp = DISAS_STOP;
6120             register_name = "HWREna";
6121             break;
6122         default:
6123             goto cp0_unimplemented;
6124         }
6125         break;
6126     case CP0_REGISTER_08:
6127         switch (sel) {
6128         case CP0_REG08__BADVADDR:
6129             /* ignored */
6130             register_name = "BadVAddr";
6131             break;
6132         case CP0_REG08__BADINSTR:
6133             /* ignored */
6134             register_name = "BadInstr";
6135             break;
6136         case CP0_REG08__BADINSTRP:
6137             /* ignored */
6138             register_name = "BadInstrP";
6139             break;
6140         case CP0_REG08__BADINSTRX:
6141             /* ignored */
6142             register_name = "BadInstrX";
6143             break;
6144         default:
6145             goto cp0_unimplemented;
6146         }
6147         break;
6148     case CP0_REGISTER_09:
6149         switch (sel) {
6150         case CP0_REG09__COUNT:
6151             gen_helper_mtc0_count(tcg_env, arg);
6152             register_name = "Count";
6153             break;
6154         default:
6155             goto cp0_unimplemented;
6156         }
6157         break;
6158     case CP0_REGISTER_10:
6159         switch (sel) {
6160         case CP0_REG10__ENTRYHI:
6161             gen_helper_mtc0_entryhi(tcg_env, arg);
6162             register_name = "EntryHi";
6163             break;
6164         default:
6165             goto cp0_unimplemented;
6166         }
6167         break;
6168     case CP0_REGISTER_11:
6169         switch (sel) {
6170         case CP0_REG11__COMPARE:
6171             gen_helper_mtc0_compare(tcg_env, arg);
6172             register_name = "Compare";
6173             break;
6174         /* 6,7 are implementation dependent */
6175         default:
6176             goto cp0_unimplemented;
6177         }
6178         break;
6179     case CP0_REGISTER_12:
6180         switch (sel) {
6181         case CP0_REG12__STATUS:
6182             save_cpu_state(ctx, 1);
6183             gen_helper_mtc0_status(tcg_env, arg);
6184             /* DISAS_STOP isn't good enough here, hflags may have changed. */
6185             gen_save_pc(ctx->base.pc_next + 4);
6186             ctx->base.is_jmp = DISAS_EXIT;
6187             register_name = "Status";
6188             break;
6189         case CP0_REG12__INTCTL:
6190             check_insn(ctx, ISA_MIPS_R2);
6191             gen_helper_mtc0_intctl(tcg_env, arg);
6192             /* Stop translation as we may have switched the execution mode */
6193             ctx->base.is_jmp = DISAS_STOP;
6194             register_name = "IntCtl";
6195             break;
6196         case CP0_REG12__SRSCTL:
6197             check_insn(ctx, ISA_MIPS_R2);
6198             gen_helper_mtc0_srsctl(tcg_env, arg);
6199             /* Stop translation as we may have switched the execution mode */
6200             ctx->base.is_jmp = DISAS_STOP;
6201             register_name = "SRSCtl";
6202             break;
6203         case CP0_REG12__SRSMAP:
6204             check_insn(ctx, ISA_MIPS_R2);
6205             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6206             /* Stop translation as we may have switched the execution mode */
6207             ctx->base.is_jmp = DISAS_STOP;
6208             register_name = "SRSMap";
6209             break;
6210         default:
6211             goto cp0_unimplemented;
6212         }
6213         break;
6214     case CP0_REGISTER_13:
6215         switch (sel) {
6216         case CP0_REG13__CAUSE:
6217             save_cpu_state(ctx, 1);
6218             gen_helper_mtc0_cause(tcg_env, arg);
6219             /*
6220              * Stop translation as we may have triggered an interrupt.
6221              * DISAS_STOP isn't sufficient, we need to ensure we break out of
6222              * translated code to check for pending interrupts.
6223              */
6224             gen_save_pc(ctx->base.pc_next + 4);
6225             ctx->base.is_jmp = DISAS_EXIT;
6226             register_name = "Cause";
6227             break;
6228         default:
6229             goto cp0_unimplemented;
6230         }
6231         break;
6232     case CP0_REGISTER_14:
6233         switch (sel) {
6234         case CP0_REG14__EPC:
6235             tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC));
6236             register_name = "EPC";
6237             break;
6238         default:
6239             goto cp0_unimplemented;
6240         }
6241         break;
6242     case CP0_REGISTER_15:
6243         switch (sel) {
6244         case CP0_REG15__PRID:
6245             /* ignored */
6246             register_name = "PRid";
6247             break;
6248         case CP0_REG15__EBASE:
6249             check_insn(ctx, ISA_MIPS_R2);
6250             gen_helper_mtc0_ebase(tcg_env, arg);
6251             register_name = "EBase";
6252             break;
6253         default:
6254             goto cp0_unimplemented;
6255         }
6256         break;
6257     case CP0_REGISTER_16:
6258         switch (sel) {
6259         case CP0_REG16__CONFIG:
6260             gen_helper_mtc0_config0(tcg_env, arg);
6261             register_name = "Config";
6262             /* Stop translation as we may have switched the execution mode */
6263             ctx->base.is_jmp = DISAS_STOP;
6264             break;
6265         case CP0_REG16__CONFIG1:
6266             /* ignored, read only */
6267             register_name = "Config1";
6268             break;
6269         case CP0_REG16__CONFIG2:
6270             gen_helper_mtc0_config2(tcg_env, arg);
6271             register_name = "Config2";
6272             /* Stop translation as we may have switched the execution mode */
6273             ctx->base.is_jmp = DISAS_STOP;
6274             break;
6275         case CP0_REG16__CONFIG3:
6276             gen_helper_mtc0_config3(tcg_env, arg);
6277             register_name = "Config3";
6278             /* Stop translation as we may have switched the execution mode */
6279             ctx->base.is_jmp = DISAS_STOP;
6280             break;
6281         case CP0_REG16__CONFIG4:
6282             gen_helper_mtc0_config4(tcg_env, arg);
6283             register_name = "Config4";
6284             ctx->base.is_jmp = DISAS_STOP;
6285             break;
6286         case CP0_REG16__CONFIG5:
6287             gen_helper_mtc0_config5(tcg_env, arg);
6288             register_name = "Config5";
6289             /* Stop translation as we may have switched the execution mode */
6290             ctx->base.is_jmp = DISAS_STOP;
6291             break;
6292         /* 6,7 are implementation dependent */
6293         case CP0_REG16__CONFIG6:
6294             /* ignored */
6295             register_name = "Config6";
6296             break;
6297         case CP0_REG16__CONFIG7:
6298             /* ignored */
6299             register_name = "Config7";
6300             break;
6301         default:
6302             register_name = "Invalid config selector";
6303             goto cp0_unimplemented;
6304         }
6305         break;
6306     case CP0_REGISTER_17:
6307         switch (sel) {
6308         case CP0_REG17__LLADDR:
6309             gen_helper_mtc0_lladdr(tcg_env, arg);
6310             register_name = "LLAddr";
6311             break;
6312         case CP0_REG17__MAAR:
6313             CP0_CHECK(ctx->mrp);
6314             gen_helper_mtc0_maar(tcg_env, arg);
6315             register_name = "MAAR";
6316             break;
6317         case CP0_REG17__MAARI:
6318             CP0_CHECK(ctx->mrp);
6319             gen_helper_mtc0_maari(tcg_env, arg);
6320             register_name = "MAARI";
6321             break;
6322         default:
6323             goto cp0_unimplemented;
6324         }
6325         break;
6326     case CP0_REGISTER_18:
6327         switch (sel) {
6328         case CP0_REG18__WATCHLO0:
6329         case CP0_REG18__WATCHLO1:
6330         case CP0_REG18__WATCHLO2:
6331         case CP0_REG18__WATCHLO3:
6332         case CP0_REG18__WATCHLO4:
6333         case CP0_REG18__WATCHLO5:
6334         case CP0_REG18__WATCHLO6:
6335         case CP0_REG18__WATCHLO7:
6336             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6337             gen_helper_0e1i(mtc0_watchlo, arg, sel);
6338             register_name = "WatchLo";
6339             break;
6340         default:
6341             goto cp0_unimplemented;
6342         }
6343         break;
6344     case CP0_REGISTER_19:
6345         switch (sel) {
6346         case CP0_REG19__WATCHHI0:
6347         case CP0_REG19__WATCHHI1:
6348         case CP0_REG19__WATCHHI2:
6349         case CP0_REG19__WATCHHI3:
6350         case CP0_REG19__WATCHHI4:
6351         case CP0_REG19__WATCHHI5:
6352         case CP0_REG19__WATCHHI6:
6353         case CP0_REG19__WATCHHI7:
6354             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6355             gen_helper_0e1i(mtc0_watchhi, arg, sel);
6356             register_name = "WatchHi";
6357             break;
6358         default:
6359             goto cp0_unimplemented;
6360         }
6361         break;
6362     case CP0_REGISTER_20:
6363         switch (sel) {
6364         case CP0_REG20__XCONTEXT:
6365 #if defined(TARGET_MIPS64)
6366             check_insn(ctx, ISA_MIPS3);
6367             gen_helper_mtc0_xcontext(tcg_env, arg);
6368             register_name = "XContext";
6369             break;
6370 #endif
6371         default:
6372             goto cp0_unimplemented;
6373         }
6374         break;
6375     case CP0_REGISTER_21:
6376        /* Officially reserved, but sel 0 is used for R1x000 framemask */
6377         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
6378         switch (sel) {
6379         case 0:
6380             gen_helper_mtc0_framemask(tcg_env, arg);
6381             register_name = "Framemask";
6382             break;
6383         default:
6384             goto cp0_unimplemented;
6385         }
6386         break;
6387     case CP0_REGISTER_22:
6388         /* ignored */
6389         register_name = "Diagnostic"; /* implementation dependent */
6390         break;
6391     case CP0_REGISTER_23:
6392         switch (sel) {
6393         case CP0_REG23__DEBUG:
6394             gen_helper_mtc0_debug(tcg_env, arg); /* EJTAG support */
6395             /* DISAS_STOP isn't good enough here, hflags may have changed. */
6396             gen_save_pc(ctx->base.pc_next + 4);
6397             ctx->base.is_jmp = DISAS_EXIT;
6398             register_name = "Debug";
6399             break;
6400         case CP0_REG23__TRACECONTROL:
6401             /* PDtrace support */
6402             /* gen_helper_mtc0_tracecontrol(tcg_env, arg);  */
6403             register_name = "TraceControl";
6404             /* Stop translation as we may have switched the execution mode */
6405             ctx->base.is_jmp = DISAS_STOP;
6406             goto cp0_unimplemented;
6407         case CP0_REG23__TRACECONTROL2:
6408             /* PDtrace support */
6409             /* gen_helper_mtc0_tracecontrol2(tcg_env, arg); */
6410             register_name = "TraceControl2";
6411             /* Stop translation as we may have switched the execution mode */
6412             ctx->base.is_jmp = DISAS_STOP;
6413             goto cp0_unimplemented;
6414         case CP0_REG23__USERTRACEDATA1:
6415             /* Stop translation as we may have switched the execution mode */
6416             ctx->base.is_jmp = DISAS_STOP;
6417             /* PDtrace support */
6418             /* gen_helper_mtc0_usertracedata1(tcg_env, arg);*/
6419             register_name = "UserTraceData";
6420             /* Stop translation as we may have switched the execution mode */
6421             ctx->base.is_jmp = DISAS_STOP;
6422             goto cp0_unimplemented;
6423         case CP0_REG23__TRACEIBPC:
6424             /* PDtrace support */
6425             /* gen_helper_mtc0_traceibpc(tcg_env, arg);     */
6426             /* Stop translation as we may have switched the execution mode */
6427             ctx->base.is_jmp = DISAS_STOP;
6428             register_name = "TraceIBPC";
6429             goto cp0_unimplemented;
6430         case CP0_REG23__TRACEDBPC:
6431             /* PDtrace support */
6432             /* gen_helper_mtc0_tracedbpc(tcg_env, arg);     */
6433             /* Stop translation as we may have switched the execution mode */
6434             ctx->base.is_jmp = DISAS_STOP;
6435             register_name = "TraceDBPC";
6436             goto cp0_unimplemented;
6437         default:
6438             goto cp0_unimplemented;
6439         }
6440         break;
6441     case CP0_REGISTER_24:
6442         switch (sel) {
6443         case CP0_REG24__DEPC:
6444             /* EJTAG support */
6445             tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC));
6446             register_name = "DEPC";
6447             break;
6448         default:
6449             goto cp0_unimplemented;
6450         }
6451         break;
6452     case CP0_REGISTER_25:
6453         switch (sel) {
6454         case CP0_REG25__PERFCTL0:
6455             gen_helper_mtc0_performance0(tcg_env, arg);
6456             register_name = "Performance0";
6457             break;
6458         case CP0_REG25__PERFCNT0:
6459             /* gen_helper_mtc0_performance1(arg); */
6460             register_name = "Performance1";
6461             goto cp0_unimplemented;
6462         case CP0_REG25__PERFCTL1:
6463             /* gen_helper_mtc0_performance2(arg); */
6464             register_name = "Performance2";
6465             goto cp0_unimplemented;
6466         case CP0_REG25__PERFCNT1:
6467             /* gen_helper_mtc0_performance3(arg); */
6468             register_name = "Performance3";
6469             goto cp0_unimplemented;
6470         case CP0_REG25__PERFCTL2:
6471             /* gen_helper_mtc0_performance4(arg); */
6472             register_name = "Performance4";
6473             goto cp0_unimplemented;
6474         case CP0_REG25__PERFCNT2:
6475             /* gen_helper_mtc0_performance5(arg); */
6476             register_name = "Performance5";
6477             goto cp0_unimplemented;
6478         case CP0_REG25__PERFCTL3:
6479             /* gen_helper_mtc0_performance6(arg); */
6480             register_name = "Performance6";
6481             goto cp0_unimplemented;
6482         case CP0_REG25__PERFCNT3:
6483             /* gen_helper_mtc0_performance7(arg); */
6484             register_name = "Performance7";
6485             goto cp0_unimplemented;
6486         default:
6487             goto cp0_unimplemented;
6488         }
6489        break;
6490     case CP0_REGISTER_26:
6491         switch (sel) {
6492         case CP0_REG26__ERRCTL:
6493             gen_helper_mtc0_errctl(tcg_env, arg);
6494             ctx->base.is_jmp = DISAS_STOP;
6495             register_name = "ErrCtl";
6496             break;
6497         default:
6498             goto cp0_unimplemented;
6499         }
6500         break;
6501     case CP0_REGISTER_27:
6502         switch (sel) {
6503         case CP0_REG27__CACHERR:
6504             /* ignored */
6505             register_name = "CacheErr";
6506             break;
6507         default:
6508             goto cp0_unimplemented;
6509         }
6510        break;
6511     case CP0_REGISTER_28:
6512         switch (sel) {
6513         case CP0_REG28__TAGLO:
6514         case CP0_REG28__TAGLO1:
6515         case CP0_REG28__TAGLO2:
6516         case CP0_REG28__TAGLO3:
6517             gen_helper_mtc0_taglo(tcg_env, arg);
6518             register_name = "TagLo";
6519             break;
6520         case CP0_REG28__DATALO:
6521         case CP0_REG28__DATALO1:
6522         case CP0_REG28__DATALO2:
6523         case CP0_REG28__DATALO3:
6524             gen_helper_mtc0_datalo(tcg_env, arg);
6525             register_name = "DataLo";
6526             break;
6527         default:
6528             goto cp0_unimplemented;
6529         }
6530         break;
6531     case CP0_REGISTER_29:
6532         switch (sel) {
6533         case CP0_REG29__TAGHI:
6534         case CP0_REG29__TAGHI1:
6535         case CP0_REG29__TAGHI2:
6536         case CP0_REG29__TAGHI3:
6537             gen_helper_mtc0_taghi(tcg_env, arg);
6538             register_name = "TagHi";
6539             break;
6540         case CP0_REG29__DATAHI:
6541         case CP0_REG29__DATAHI1:
6542         case CP0_REG29__DATAHI2:
6543         case CP0_REG29__DATAHI3:
6544             gen_helper_mtc0_datahi(tcg_env, arg);
6545             register_name = "DataHi";
6546             break;
6547         default:
6548             register_name = "invalid sel";
6549             goto cp0_unimplemented;
6550         }
6551        break;
6552     case CP0_REGISTER_30:
6553         switch (sel) {
6554         case CP0_REG30__ERROREPC:
6555             tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6556             register_name = "ErrorEPC";
6557             break;
6558         default:
6559             goto cp0_unimplemented;
6560         }
6561         break;
6562     case CP0_REGISTER_31:
6563         switch (sel) {
6564         case CP0_REG31__DESAVE:
6565             /* EJTAG support */
6566             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6567             register_name = "DESAVE";
6568             break;
6569         case CP0_REG31__KSCRATCH1:
6570         case CP0_REG31__KSCRATCH2:
6571         case CP0_REG31__KSCRATCH3:
6572         case CP0_REG31__KSCRATCH4:
6573         case CP0_REG31__KSCRATCH5:
6574         case CP0_REG31__KSCRATCH6:
6575             CP0_CHECK(ctx->kscrexist & (1 << sel));
6576             tcg_gen_st_tl(arg, tcg_env,
6577                           offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
6578             register_name = "KScratch";
6579             break;
6580         default:
6581             goto cp0_unimplemented;
6582         }
6583         break;
6584     default:
6585        goto cp0_unimplemented;
6586     }
6587     trace_mips_translate_c0("mtc0", register_name, reg, sel);
6588 
6589     /* For simplicity assume that all writes can cause interrupts.  */
6590     if (icount) {
6591         /*
6592          * DISAS_STOP isn't sufficient, we need to ensure we break out of
6593          * translated code to check for pending interrupts.
6594          */
6595         gen_save_pc(ctx->base.pc_next + 4);
6596         ctx->base.is_jmp = DISAS_EXIT;
6597     }
6598     return;
6599 
6600 cp0_unimplemented:
6601     qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n",
6602                   register_name, reg, sel);
6603 }
6604 
6605 #if defined(TARGET_MIPS64)
gen_dmfc0(DisasContext * ctx,TCGv arg,int reg,int sel)6606 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6607 {
6608     const char *register_name = "invalid";
6609 
6610     if (sel != 0) {
6611         check_insn(ctx, ISA_MIPS_R1);
6612     }
6613 
6614     switch (reg) {
6615     case CP0_REGISTER_00:
6616         switch (sel) {
6617         case CP0_REG00__INDEX:
6618             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
6619             register_name = "Index";
6620             break;
6621         case CP0_REG00__MVPCONTROL:
6622             CP0_CHECK(disas_mt_available(ctx));
6623             gen_helper_mfc0_mvpcontrol(arg, tcg_env);
6624             register_name = "MVPControl";
6625             break;
6626         case CP0_REG00__MVPCONF0:
6627             CP0_CHECK(disas_mt_available(ctx));
6628             gen_helper_mfc0_mvpconf0(arg, tcg_env);
6629             register_name = "MVPConf0";
6630             break;
6631         case CP0_REG00__MVPCONF1:
6632             CP0_CHECK(disas_mt_available(ctx));
6633             gen_helper_mfc0_mvpconf1(arg, tcg_env);
6634             register_name = "MVPConf1";
6635             break;
6636         case CP0_REG00__VPCONTROL:
6637             CP0_CHECK(ctx->vp);
6638             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6639             register_name = "VPControl";
6640             break;
6641         default:
6642             goto cp0_unimplemented;
6643         }
6644         break;
6645     case CP0_REGISTER_01:
6646         switch (sel) {
6647         case CP0_REG01__RANDOM:
6648             CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
6649             gen_helper_mfc0_random(arg, tcg_env);
6650             register_name = "Random";
6651             break;
6652         case CP0_REG01__VPECONTROL:
6653             CP0_CHECK(disas_mt_available(ctx));
6654             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
6655             register_name = "VPEControl";
6656             break;
6657         case CP0_REG01__VPECONF0:
6658             CP0_CHECK(disas_mt_available(ctx));
6659             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
6660             register_name = "VPEConf0";
6661             break;
6662         case CP0_REG01__VPECONF1:
6663             CP0_CHECK(disas_mt_available(ctx));
6664             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
6665             register_name = "VPEConf1";
6666             break;
6667         case CP0_REG01__YQMASK:
6668             CP0_CHECK(disas_mt_available(ctx));
6669             tcg_gen_ld_tl(arg, tcg_env,
6670                           offsetof(CPUMIPSState, CP0_YQMask));
6671             register_name = "YQMask";
6672             break;
6673         case CP0_REG01__VPESCHEDULE:
6674             CP0_CHECK(disas_mt_available(ctx));
6675             tcg_gen_ld_tl(arg, tcg_env,
6676                           offsetof(CPUMIPSState, CP0_VPESchedule));
6677             register_name = "VPESchedule";
6678             break;
6679         case CP0_REG01__VPESCHEFBACK:
6680             CP0_CHECK(disas_mt_available(ctx));
6681             tcg_gen_ld_tl(arg, tcg_env,
6682                           offsetof(CPUMIPSState, CP0_VPEScheFBack));
6683             register_name = "VPEScheFBack";
6684             break;
6685         case CP0_REG01__VPEOPT:
6686             CP0_CHECK(disas_mt_available(ctx));
6687             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
6688             register_name = "VPEOpt";
6689             break;
6690         default:
6691             goto cp0_unimplemented;
6692         }
6693         break;
6694     case CP0_REGISTER_02:
6695         switch (sel) {
6696         case CP0_REG02__ENTRYLO0:
6697             tcg_gen_ld_tl(arg, tcg_env,
6698                           offsetof(CPUMIPSState, CP0_EntryLo0));
6699             register_name = "EntryLo0";
6700             break;
6701         case CP0_REG02__TCSTATUS:
6702             CP0_CHECK(disas_mt_available(ctx));
6703             gen_helper_mfc0_tcstatus(arg, tcg_env);
6704             register_name = "TCStatus";
6705             break;
6706         case CP0_REG02__TCBIND:
6707             CP0_CHECK(disas_mt_available(ctx));
6708             gen_helper_mfc0_tcbind(arg, tcg_env);
6709             register_name = "TCBind";
6710             break;
6711         case CP0_REG02__TCRESTART:
6712             CP0_CHECK(disas_mt_available(ctx));
6713             gen_helper_dmfc0_tcrestart(arg, tcg_env);
6714             register_name = "TCRestart";
6715             break;
6716         case CP0_REG02__TCHALT:
6717             CP0_CHECK(disas_mt_available(ctx));
6718             gen_helper_dmfc0_tchalt(arg, tcg_env);
6719             register_name = "TCHalt";
6720             break;
6721         case CP0_REG02__TCCONTEXT:
6722             CP0_CHECK(disas_mt_available(ctx));
6723             gen_helper_dmfc0_tccontext(arg, tcg_env);
6724             register_name = "TCContext";
6725             break;
6726         case CP0_REG02__TCSCHEDULE:
6727             CP0_CHECK(disas_mt_available(ctx));
6728             gen_helper_dmfc0_tcschedule(arg, tcg_env);
6729             register_name = "TCSchedule";
6730             break;
6731         case CP0_REG02__TCSCHEFBACK:
6732             CP0_CHECK(disas_mt_available(ctx));
6733             gen_helper_dmfc0_tcschefback(arg, tcg_env);
6734             register_name = "TCScheFBack";
6735             break;
6736         default:
6737             goto cp0_unimplemented;
6738         }
6739         break;
6740     case CP0_REGISTER_03:
6741         switch (sel) {
6742         case CP0_REG03__ENTRYLO1:
6743             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EntryLo1));
6744             register_name = "EntryLo1";
6745             break;
6746         case CP0_REG03__GLOBALNUM:
6747             CP0_CHECK(ctx->vp);
6748             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6749             register_name = "GlobalNumber";
6750             break;
6751         default:
6752             goto cp0_unimplemented;
6753         }
6754         break;
6755     case CP0_REGISTER_04:
6756         switch (sel) {
6757         case CP0_REG04__CONTEXT:
6758             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_Context));
6759             register_name = "Context";
6760             break;
6761         case CP0_REG04__CONTEXTCONFIG:
6762             /* SmartMIPS ASE */
6763             /* gen_helper_dmfc0_contextconfig(arg); */
6764             register_name = "ContextConfig";
6765             goto cp0_unimplemented;
6766         case CP0_REG04__USERLOCAL:
6767             CP0_CHECK(ctx->ulri);
6768             tcg_gen_ld_tl(arg, tcg_env,
6769                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6770             register_name = "UserLocal";
6771             break;
6772         case CP0_REG04__MMID:
6773             CP0_CHECK(ctx->mi);
6774             gen_helper_mtc0_memorymapid(tcg_env, arg);
6775             register_name = "MMID";
6776             break;
6777         default:
6778             goto cp0_unimplemented;
6779         }
6780         break;
6781     case CP0_REGISTER_05:
6782         switch (sel) {
6783         case CP0_REG05__PAGEMASK:
6784             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
6785             register_name = "PageMask";
6786             break;
6787         case CP0_REG05__PAGEGRAIN:
6788             check_insn(ctx, ISA_MIPS_R2);
6789             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
6790             register_name = "PageGrain";
6791             break;
6792         case CP0_REG05__SEGCTL0:
6793             CP0_CHECK(ctx->sc);
6794             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl0));
6795             register_name = "SegCtl0";
6796             break;
6797         case CP0_REG05__SEGCTL1:
6798             CP0_CHECK(ctx->sc);
6799             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl1));
6800             register_name = "SegCtl1";
6801             break;
6802         case CP0_REG05__SEGCTL2:
6803             CP0_CHECK(ctx->sc);
6804             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl2));
6805             register_name = "SegCtl2";
6806             break;
6807         case CP0_REG05__PWBASE:
6808             check_pw(ctx);
6809             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWBase));
6810             register_name = "PWBase";
6811             break;
6812         case CP0_REG05__PWFIELD:
6813             check_pw(ctx);
6814             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWField));
6815             register_name = "PWField";
6816             break;
6817         case CP0_REG05__PWSIZE:
6818             check_pw(ctx);
6819             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWSize));
6820             register_name = "PWSize";
6821             break;
6822         default:
6823             goto cp0_unimplemented;
6824         }
6825         break;
6826     case CP0_REGISTER_06:
6827         switch (sel) {
6828         case CP0_REG06__WIRED:
6829             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
6830             register_name = "Wired";
6831             break;
6832         case CP0_REG06__SRSCONF0:
6833             check_insn(ctx, ISA_MIPS_R2);
6834             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
6835             register_name = "SRSConf0";
6836             break;
6837         case CP0_REG06__SRSCONF1:
6838             check_insn(ctx, ISA_MIPS_R2);
6839             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
6840             register_name = "SRSConf1";
6841             break;
6842         case CP0_REG06__SRSCONF2:
6843             check_insn(ctx, ISA_MIPS_R2);
6844             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
6845             register_name = "SRSConf2";
6846             break;
6847         case CP0_REG06__SRSCONF3:
6848             check_insn(ctx, ISA_MIPS_R2);
6849             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
6850             register_name = "SRSConf3";
6851             break;
6852         case CP0_REG06__SRSCONF4:
6853             check_insn(ctx, ISA_MIPS_R2);
6854             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
6855             register_name = "SRSConf4";
6856             break;
6857         case CP0_REG06__PWCTL:
6858             check_pw(ctx);
6859             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
6860             register_name = "PWCtl";
6861             break;
6862         default:
6863             goto cp0_unimplemented;
6864         }
6865         break;
6866     case CP0_REGISTER_07:
6867         switch (sel) {
6868         case CP0_REG07__HWRENA:
6869             check_insn(ctx, ISA_MIPS_R2);
6870             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
6871             register_name = "HWREna";
6872             break;
6873         default:
6874             goto cp0_unimplemented;
6875         }
6876         break;
6877     case CP0_REGISTER_08:
6878         switch (sel) {
6879         case CP0_REG08__BADVADDR:
6880             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_BadVAddr));
6881             register_name = "BadVAddr";
6882             break;
6883         case CP0_REG08__BADINSTR:
6884             CP0_CHECK(ctx->bi);
6885             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6886             register_name = "BadInstr";
6887             break;
6888         case CP0_REG08__BADINSTRP:
6889             CP0_CHECK(ctx->bp);
6890             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6891             register_name = "BadInstrP";
6892             break;
6893         case CP0_REG08__BADINSTRX:
6894             CP0_CHECK(ctx->bi);
6895             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
6896             tcg_gen_andi_tl(arg, arg, ~0xffff);
6897             register_name = "BadInstrX";
6898             break;
6899         default:
6900             goto cp0_unimplemented;
6901         }
6902         break;
6903     case CP0_REGISTER_09:
6904         switch (sel) {
6905         case CP0_REG09__COUNT:
6906             /* Mark as an IO operation because we read the time.  */
6907             translator_io_start(&ctx->base);
6908             gen_helper_mfc0_count(arg, tcg_env);
6909             /*
6910              * Break the TB to be able to take timer interrupts immediately
6911              * after reading count. DISAS_STOP isn't sufficient, we need to
6912              * ensure we break completely out of translated code.
6913              */
6914             gen_save_pc(ctx->base.pc_next + 4);
6915             ctx->base.is_jmp = DISAS_EXIT;
6916             register_name = "Count";
6917             break;
6918         default:
6919             goto cp0_unimplemented;
6920         }
6921         break;
6922     case CP0_REGISTER_10:
6923         switch (sel) {
6924         case CP0_REG10__ENTRYHI:
6925             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EntryHi));
6926             register_name = "EntryHi";
6927             break;
6928         default:
6929             goto cp0_unimplemented;
6930         }
6931         break;
6932     case CP0_REGISTER_11:
6933         switch (sel) {
6934         case CP0_REG11__COMPARE:
6935             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
6936             register_name = "Compare";
6937             break;
6938         /* 6,7 are implementation dependent */
6939         default:
6940             goto cp0_unimplemented;
6941         }
6942         break;
6943     case CP0_REGISTER_12:
6944         switch (sel) {
6945         case CP0_REG12__STATUS:
6946             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
6947             register_name = "Status";
6948             break;
6949         case CP0_REG12__INTCTL:
6950             check_insn(ctx, ISA_MIPS_R2);
6951             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
6952             register_name = "IntCtl";
6953             break;
6954         case CP0_REG12__SRSCTL:
6955             check_insn(ctx, ISA_MIPS_R2);
6956             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
6957             register_name = "SRSCtl";
6958             break;
6959         case CP0_REG12__SRSMAP:
6960             check_insn(ctx, ISA_MIPS_R2);
6961             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6962             register_name = "SRSMap";
6963             break;
6964         default:
6965             goto cp0_unimplemented;
6966         }
6967         break;
6968     case CP0_REGISTER_13:
6969         switch (sel) {
6970         case CP0_REG13__CAUSE:
6971             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
6972             register_name = "Cause";
6973             break;
6974         default:
6975             goto cp0_unimplemented;
6976         }
6977         break;
6978     case CP0_REGISTER_14:
6979         switch (sel) {
6980         case CP0_REG14__EPC:
6981             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC));
6982             register_name = "EPC";
6983             break;
6984         default:
6985             goto cp0_unimplemented;
6986         }
6987         break;
6988     case CP0_REGISTER_15:
6989         switch (sel) {
6990         case CP0_REG15__PRID:
6991             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
6992             register_name = "PRid";
6993             break;
6994         case CP0_REG15__EBASE:
6995             check_insn(ctx, ISA_MIPS_R2);
6996             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EBase));
6997             register_name = "EBase";
6998             break;
6999         case CP0_REG15__CMGCRBASE:
7000             check_insn(ctx, ISA_MIPS_R2);
7001             CP0_CHECK(ctx->cmgcr);
7002             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7003             register_name = "CMGCRBase";
7004             break;
7005         default:
7006             goto cp0_unimplemented;
7007         }
7008         break;
7009     case CP0_REGISTER_16:
7010         switch (sel) {
7011         case CP0_REG16__CONFIG:
7012             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
7013             register_name = "Config";
7014             break;
7015         case CP0_REG16__CONFIG1:
7016             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
7017             register_name = "Config1";
7018             break;
7019         case CP0_REG16__CONFIG2:
7020             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7021             register_name = "Config2";
7022             break;
7023         case CP0_REG16__CONFIG3:
7024             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7025             register_name = "Config3";
7026             break;
7027         case CP0_REG16__CONFIG4:
7028             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7029             register_name = "Config4";
7030             break;
7031         case CP0_REG16__CONFIG5:
7032             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7033             register_name = "Config5";
7034             break;
7035         /* 6,7 are implementation dependent */
7036         case CP0_REG16__CONFIG6:
7037             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
7038             register_name = "Config6";
7039             break;
7040         case CP0_REG16__CONFIG7:
7041             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
7042             register_name = "Config7";
7043             break;
7044         default:
7045             goto cp0_unimplemented;
7046         }
7047         break;
7048     case CP0_REGISTER_17:
7049         switch (sel) {
7050         case CP0_REG17__LLADDR:
7051             gen_helper_dmfc0_lladdr(arg, tcg_env);
7052             register_name = "LLAddr";
7053             break;
7054         case CP0_REG17__MAAR:
7055             CP0_CHECK(ctx->mrp);
7056             gen_helper_dmfc0_maar(arg, tcg_env);
7057             register_name = "MAAR";
7058             break;
7059         case CP0_REG17__MAARI:
7060             CP0_CHECK(ctx->mrp);
7061             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7062             register_name = "MAARI";
7063             break;
7064         default:
7065             goto cp0_unimplemented;
7066         }
7067         break;
7068     case CP0_REGISTER_18:
7069         switch (sel) {
7070         case CP0_REG18__WATCHLO0:
7071         case CP0_REG18__WATCHLO1:
7072         case CP0_REG18__WATCHLO2:
7073         case CP0_REG18__WATCHLO3:
7074         case CP0_REG18__WATCHLO4:
7075         case CP0_REG18__WATCHLO5:
7076         case CP0_REG18__WATCHLO6:
7077         case CP0_REG18__WATCHLO7:
7078             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7079             gen_helper_1e0i(dmfc0_watchlo, arg, sel);
7080             register_name = "WatchLo";
7081             break;
7082         default:
7083             goto cp0_unimplemented;
7084         }
7085         break;
7086     case CP0_REGISTER_19:
7087         switch (sel) {
7088         case CP0_REG19__WATCHHI0:
7089         case CP0_REG19__WATCHHI1:
7090         case CP0_REG19__WATCHHI2:
7091         case CP0_REG19__WATCHHI3:
7092         case CP0_REG19__WATCHHI4:
7093         case CP0_REG19__WATCHHI5:
7094         case CP0_REG19__WATCHHI6:
7095         case CP0_REG19__WATCHHI7:
7096             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7097             gen_helper_1e0i(dmfc0_watchhi, arg, sel);
7098             register_name = "WatchHi";
7099             break;
7100         default:
7101             goto cp0_unimplemented;
7102         }
7103         break;
7104     case CP0_REGISTER_20:
7105         switch (sel) {
7106         case CP0_REG20__XCONTEXT:
7107             check_insn(ctx, ISA_MIPS3);
7108             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_XContext));
7109             register_name = "XContext";
7110             break;
7111         default:
7112             goto cp0_unimplemented;
7113         }
7114         break;
7115     case CP0_REGISTER_21:
7116         /* Officially reserved, but sel 0 is used for R1x000 framemask */
7117         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
7118         switch (sel) {
7119         case 0:
7120             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
7121             register_name = "Framemask";
7122             break;
7123         default:
7124             goto cp0_unimplemented;
7125         }
7126         break;
7127     case CP0_REGISTER_22:
7128         tcg_gen_movi_tl(arg, 0); /* unimplemented */
7129         register_name = "'Diagnostic"; /* implementation dependent */
7130         break;
7131     case CP0_REGISTER_23:
7132         switch (sel) {
7133         case CP0_REG23__DEBUG:
7134             gen_helper_mfc0_debug(arg, tcg_env); /* EJTAG support */
7135             register_name = "Debug";
7136             break;
7137         case CP0_REG23__TRACECONTROL:
7138             /* PDtrace support */
7139             /* gen_helper_dmfc0_tracecontrol(arg, tcg_env);  */
7140             register_name = "TraceControl";
7141             goto cp0_unimplemented;
7142         case CP0_REG23__TRACECONTROL2:
7143             /* PDtrace support */
7144             /* gen_helper_dmfc0_tracecontrol2(arg, tcg_env); */
7145             register_name = "TraceControl2";
7146             goto cp0_unimplemented;
7147         case CP0_REG23__USERTRACEDATA1:
7148             /* PDtrace support */
7149             /* gen_helper_dmfc0_usertracedata1(arg, tcg_env);*/
7150             register_name = "UserTraceData1";
7151             goto cp0_unimplemented;
7152         case CP0_REG23__TRACEIBPC:
7153             /* PDtrace support */
7154             /* gen_helper_dmfc0_traceibpc(arg, tcg_env);     */
7155             register_name = "TraceIBPC";
7156             goto cp0_unimplemented;
7157         case CP0_REG23__TRACEDBPC:
7158             /* PDtrace support */
7159             /* gen_helper_dmfc0_tracedbpc(arg, tcg_env);     */
7160             register_name = "TraceDBPC";
7161             goto cp0_unimplemented;
7162         default:
7163             goto cp0_unimplemented;
7164         }
7165         break;
7166     case CP0_REGISTER_24:
7167         switch (sel) {
7168         case CP0_REG24__DEPC:
7169             /* EJTAG support */
7170             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC));
7171             register_name = "DEPC";
7172             break;
7173         default:
7174             goto cp0_unimplemented;
7175         }
7176         break;
7177     case CP0_REGISTER_25:
7178         switch (sel) {
7179         case CP0_REG25__PERFCTL0:
7180             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
7181             register_name = "Performance0";
7182             break;
7183         case CP0_REG25__PERFCNT0:
7184             /* gen_helper_dmfc0_performance1(arg); */
7185             register_name = "Performance1";
7186             goto cp0_unimplemented;
7187         case CP0_REG25__PERFCTL1:
7188             /* gen_helper_dmfc0_performance2(arg); */
7189             register_name = "Performance2";
7190             goto cp0_unimplemented;
7191         case CP0_REG25__PERFCNT1:
7192             /* gen_helper_dmfc0_performance3(arg); */
7193             register_name = "Performance3";
7194             goto cp0_unimplemented;
7195         case CP0_REG25__PERFCTL2:
7196             /* gen_helper_dmfc0_performance4(arg); */
7197             register_name = "Performance4";
7198             goto cp0_unimplemented;
7199         case CP0_REG25__PERFCNT2:
7200             /* gen_helper_dmfc0_performance5(arg); */
7201             register_name = "Performance5";
7202             goto cp0_unimplemented;
7203         case CP0_REG25__PERFCTL3:
7204             /* gen_helper_dmfc0_performance6(arg); */
7205             register_name = "Performance6";
7206             goto cp0_unimplemented;
7207         case CP0_REG25__PERFCNT3:
7208             /* gen_helper_dmfc0_performance7(arg); */
7209             register_name = "Performance7";
7210             goto cp0_unimplemented;
7211         default:
7212             goto cp0_unimplemented;
7213         }
7214         break;
7215     case CP0_REGISTER_26:
7216         switch (sel) {
7217         case CP0_REG26__ERRCTL:
7218             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7219             register_name = "ErrCtl";
7220             break;
7221         default:
7222             goto cp0_unimplemented;
7223         }
7224         break;
7225     case CP0_REGISTER_27:
7226         switch (sel) {
7227         /* ignored */
7228         case CP0_REG27__CACHERR:
7229             tcg_gen_movi_tl(arg, 0); /* unimplemented */
7230             register_name = "CacheErr";
7231             break;
7232         default:
7233             goto cp0_unimplemented;
7234         }
7235         break;
7236     case CP0_REGISTER_28:
7237         switch (sel) {
7238         case CP0_REG28__TAGLO:
7239         case CP0_REG28__TAGLO1:
7240         case CP0_REG28__TAGLO2:
7241         case CP0_REG28__TAGLO3:
7242             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
7243             register_name = "TagLo";
7244             break;
7245         case CP0_REG28__DATALO:
7246         case CP0_REG28__DATALO1:
7247         case CP0_REG28__DATALO2:
7248         case CP0_REG28__DATALO3:
7249             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
7250             register_name = "DataLo";
7251             break;
7252         default:
7253             goto cp0_unimplemented;
7254         }
7255         break;
7256     case CP0_REGISTER_29:
7257         switch (sel) {
7258         case CP0_REG29__TAGHI:
7259         case CP0_REG29__TAGHI1:
7260         case CP0_REG29__TAGHI2:
7261         case CP0_REG29__TAGHI3:
7262             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7263             register_name = "TagHi";
7264             break;
7265         case CP0_REG29__DATAHI:
7266         case CP0_REG29__DATAHI1:
7267         case CP0_REG29__DATAHI2:
7268         case CP0_REG29__DATAHI3:
7269             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7270             register_name = "DataHi";
7271             break;
7272         default:
7273             goto cp0_unimplemented;
7274         }
7275         break;
7276     case CP0_REGISTER_30:
7277         switch (sel) {
7278         case CP0_REG30__ERROREPC:
7279             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7280             register_name = "ErrorEPC";
7281             break;
7282         default:
7283             goto cp0_unimplemented;
7284         }
7285         break;
7286     case CP0_REGISTER_31:
7287         switch (sel) {
7288         case CP0_REG31__DESAVE:
7289             /* EJTAG support */
7290             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7291             register_name = "DESAVE";
7292             break;
7293         case CP0_REG31__KSCRATCH1:
7294         case CP0_REG31__KSCRATCH2:
7295         case CP0_REG31__KSCRATCH3:
7296         case CP0_REG31__KSCRATCH4:
7297         case CP0_REG31__KSCRATCH5:
7298         case CP0_REG31__KSCRATCH6:
7299             CP0_CHECK(ctx->kscrexist & (1 << sel));
7300             tcg_gen_ld_tl(arg, tcg_env,
7301                           offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
7302             register_name = "KScratch";
7303             break;
7304         default:
7305             goto cp0_unimplemented;
7306         }
7307         break;
7308     default:
7309         goto cp0_unimplemented;
7310     }
7311     trace_mips_translate_c0("dmfc0", register_name, reg, sel);
7312     return;
7313 
7314 cp0_unimplemented:
7315     qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n",
7316                   register_name, reg, sel);
7317     gen_mfc0_unimplemented(ctx, arg);
7318 }
7319 
gen_dmtc0(DisasContext * ctx,TCGv arg,int reg,int sel)7320 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7321 {
7322     const char *register_name = "invalid";
7323     bool icount;
7324 
7325     if (sel != 0) {
7326         check_insn(ctx, ISA_MIPS_R1);
7327     }
7328 
7329     icount = translator_io_start(&ctx->base);
7330 
7331     switch (reg) {
7332     case CP0_REGISTER_00:
7333         switch (sel) {
7334         case CP0_REG00__INDEX:
7335             gen_helper_mtc0_index(tcg_env, arg);
7336             register_name = "Index";
7337             break;
7338         case CP0_REG00__MVPCONTROL:
7339             CP0_CHECK(disas_mt_available(ctx));
7340             gen_helper_mtc0_mvpcontrol(tcg_env, arg);
7341             register_name = "MVPControl";
7342             break;
7343         case CP0_REG00__MVPCONF0:
7344             CP0_CHECK(disas_mt_available(ctx));
7345             /* ignored */
7346             register_name = "MVPConf0";
7347             break;
7348         case CP0_REG00__MVPCONF1:
7349             CP0_CHECK(disas_mt_available(ctx));
7350             /* ignored */
7351             register_name = "MVPConf1";
7352             break;
7353         case CP0_REG00__VPCONTROL:
7354             CP0_CHECK(ctx->vp);
7355             /* ignored */
7356             register_name = "VPControl";
7357             break;
7358         default:
7359             goto cp0_unimplemented;
7360         }
7361         break;
7362     case CP0_REGISTER_01:
7363         switch (sel) {
7364         case CP0_REG01__RANDOM:
7365             /* ignored */
7366             register_name = "Random";
7367             break;
7368         case CP0_REG01__VPECONTROL:
7369             CP0_CHECK(disas_mt_available(ctx));
7370             gen_helper_mtc0_vpecontrol(tcg_env, arg);
7371             register_name = "VPEControl";
7372             break;
7373         case CP0_REG01__VPECONF0:
7374             CP0_CHECK(disas_mt_available(ctx));
7375             gen_helper_mtc0_vpeconf0(tcg_env, arg);
7376             register_name = "VPEConf0";
7377             break;
7378         case CP0_REG01__VPECONF1:
7379             CP0_CHECK(disas_mt_available(ctx));
7380             gen_helper_mtc0_vpeconf1(tcg_env, arg);
7381             register_name = "VPEConf1";
7382             break;
7383         case CP0_REG01__YQMASK:
7384             CP0_CHECK(disas_mt_available(ctx));
7385             gen_helper_mtc0_yqmask(tcg_env, arg);
7386             register_name = "YQMask";
7387             break;
7388         case CP0_REG01__VPESCHEDULE:
7389             CP0_CHECK(disas_mt_available(ctx));
7390             tcg_gen_st_tl(arg, tcg_env,
7391                           offsetof(CPUMIPSState, CP0_VPESchedule));
7392             register_name = "VPESchedule";
7393             break;
7394         case CP0_REG01__VPESCHEFBACK:
7395             CP0_CHECK(disas_mt_available(ctx));
7396             tcg_gen_st_tl(arg, tcg_env,
7397                           offsetof(CPUMIPSState, CP0_VPEScheFBack));
7398             register_name = "VPEScheFBack";
7399             break;
7400         case CP0_REG01__VPEOPT:
7401             CP0_CHECK(disas_mt_available(ctx));
7402             gen_helper_mtc0_vpeopt(tcg_env, arg);
7403             register_name = "VPEOpt";
7404             break;
7405         default:
7406             goto cp0_unimplemented;
7407         }
7408         break;
7409     case CP0_REGISTER_02:
7410         switch (sel) {
7411         case CP0_REG02__ENTRYLO0:
7412             gen_helper_dmtc0_entrylo0(tcg_env, arg);
7413             register_name = "EntryLo0";
7414             break;
7415         case CP0_REG02__TCSTATUS:
7416             CP0_CHECK(disas_mt_available(ctx));
7417             gen_helper_mtc0_tcstatus(tcg_env, arg);
7418             register_name = "TCStatus";
7419             break;
7420         case CP0_REG02__TCBIND:
7421             CP0_CHECK(disas_mt_available(ctx));
7422             gen_helper_mtc0_tcbind(tcg_env, arg);
7423             register_name = "TCBind";
7424             break;
7425         case CP0_REG02__TCRESTART:
7426             CP0_CHECK(disas_mt_available(ctx));
7427             gen_helper_mtc0_tcrestart(tcg_env, arg);
7428             register_name = "TCRestart";
7429             break;
7430         case CP0_REG02__TCHALT:
7431             CP0_CHECK(disas_mt_available(ctx));
7432             gen_helper_mtc0_tchalt(tcg_env, arg);
7433             register_name = "TCHalt";
7434             break;
7435         case CP0_REG02__TCCONTEXT:
7436             CP0_CHECK(disas_mt_available(ctx));
7437             gen_helper_mtc0_tccontext(tcg_env, arg);
7438             register_name = "TCContext";
7439             break;
7440         case CP0_REG02__TCSCHEDULE:
7441             CP0_CHECK(disas_mt_available(ctx));
7442             gen_helper_mtc0_tcschedule(tcg_env, arg);
7443             register_name = "TCSchedule";
7444             break;
7445         case CP0_REG02__TCSCHEFBACK:
7446             CP0_CHECK(disas_mt_available(ctx));
7447             gen_helper_mtc0_tcschefback(tcg_env, arg);
7448             register_name = "TCScheFBack";
7449             break;
7450         default:
7451             goto cp0_unimplemented;
7452         }
7453         break;
7454     case CP0_REGISTER_03:
7455         switch (sel) {
7456         case CP0_REG03__ENTRYLO1:
7457             gen_helper_dmtc0_entrylo1(tcg_env, arg);
7458             register_name = "EntryLo1";
7459             break;
7460         case CP0_REG03__GLOBALNUM:
7461             CP0_CHECK(ctx->vp);
7462             /* ignored */
7463             register_name = "GlobalNumber";
7464             break;
7465         default:
7466             goto cp0_unimplemented;
7467         }
7468         break;
7469     case CP0_REGISTER_04:
7470         switch (sel) {
7471         case CP0_REG04__CONTEXT:
7472             gen_helper_mtc0_context(tcg_env, arg);
7473             register_name = "Context";
7474             break;
7475         case CP0_REG04__CONTEXTCONFIG:
7476             /* SmartMIPS ASE */
7477             /* gen_helper_dmtc0_contextconfig(arg); */
7478             register_name = "ContextConfig";
7479             goto cp0_unimplemented;
7480         case CP0_REG04__USERLOCAL:
7481             CP0_CHECK(ctx->ulri);
7482             tcg_gen_st_tl(arg, tcg_env,
7483                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7484             register_name = "UserLocal";
7485             break;
7486         case CP0_REG04__MMID:
7487             CP0_CHECK(ctx->mi);
7488             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID));
7489             register_name = "MMID";
7490             break;
7491         default:
7492             goto cp0_unimplemented;
7493         }
7494         break;
7495     case CP0_REGISTER_05:
7496         switch (sel) {
7497         case CP0_REG05__PAGEMASK:
7498             gen_helper_mtc0_pagemask(tcg_env, arg);
7499             register_name = "PageMask";
7500             break;
7501         case CP0_REG05__PAGEGRAIN:
7502             check_insn(ctx, ISA_MIPS_R2);
7503             gen_helper_mtc0_pagegrain(tcg_env, arg);
7504             register_name = "PageGrain";
7505             break;
7506         case CP0_REG05__SEGCTL0:
7507             CP0_CHECK(ctx->sc);
7508             gen_helper_mtc0_segctl0(tcg_env, arg);
7509             register_name = "SegCtl0";
7510             break;
7511         case CP0_REG05__SEGCTL1:
7512             CP0_CHECK(ctx->sc);
7513             gen_helper_mtc0_segctl1(tcg_env, arg);
7514             register_name = "SegCtl1";
7515             break;
7516         case CP0_REG05__SEGCTL2:
7517             CP0_CHECK(ctx->sc);
7518             gen_helper_mtc0_segctl2(tcg_env, arg);
7519             register_name = "SegCtl2";
7520             break;
7521         case CP0_REG05__PWBASE:
7522             check_pw(ctx);
7523             tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWBase));
7524             register_name = "PWBase";
7525             break;
7526         case CP0_REG05__PWFIELD:
7527             check_pw(ctx);
7528             gen_helper_mtc0_pwfield(tcg_env, arg);
7529             register_name = "PWField";
7530             break;
7531         case CP0_REG05__PWSIZE:
7532             check_pw(ctx);
7533             gen_helper_mtc0_pwsize(tcg_env, arg);
7534             register_name = "PWSize";
7535             break;
7536         default:
7537             goto cp0_unimplemented;
7538         }
7539         break;
7540     case CP0_REGISTER_06:
7541         switch (sel) {
7542         case CP0_REG06__WIRED:
7543             gen_helper_mtc0_wired(tcg_env, arg);
7544             register_name = "Wired";
7545             break;
7546         case CP0_REG06__SRSCONF0:
7547             check_insn(ctx, ISA_MIPS_R2);
7548             gen_helper_mtc0_srsconf0(tcg_env, arg);
7549             register_name = "SRSConf0";
7550             break;
7551         case CP0_REG06__SRSCONF1:
7552             check_insn(ctx, ISA_MIPS_R2);
7553             gen_helper_mtc0_srsconf1(tcg_env, arg);
7554             register_name = "SRSConf1";
7555             break;
7556         case CP0_REG06__SRSCONF2:
7557             check_insn(ctx, ISA_MIPS_R2);
7558             gen_helper_mtc0_srsconf2(tcg_env, arg);
7559             register_name = "SRSConf2";
7560             break;
7561         case CP0_REG06__SRSCONF3:
7562             check_insn(ctx, ISA_MIPS_R2);
7563             gen_helper_mtc0_srsconf3(tcg_env, arg);
7564             register_name = "SRSConf3";
7565             break;
7566         case CP0_REG06__SRSCONF4:
7567             check_insn(ctx, ISA_MIPS_R2);
7568             gen_helper_mtc0_srsconf4(tcg_env, arg);
7569             register_name = "SRSConf4";
7570             break;
7571         case CP0_REG06__PWCTL:
7572             check_pw(ctx);
7573             gen_helper_mtc0_pwctl(tcg_env, arg);
7574             register_name = "PWCtl";
7575             break;
7576         default:
7577             goto cp0_unimplemented;
7578         }
7579         break;
7580     case CP0_REGISTER_07:
7581         switch (sel) {
7582         case CP0_REG07__HWRENA:
7583             check_insn(ctx, ISA_MIPS_R2);
7584             gen_helper_mtc0_hwrena(tcg_env, arg);
7585             ctx->base.is_jmp = DISAS_STOP;
7586             register_name = "HWREna";
7587             break;
7588         default:
7589             goto cp0_unimplemented;
7590         }
7591         break;
7592     case CP0_REGISTER_08:
7593         switch (sel) {
7594         case CP0_REG08__BADVADDR:
7595             /* ignored */
7596             register_name = "BadVAddr";
7597             break;
7598         case CP0_REG08__BADINSTR:
7599             /* ignored */
7600             register_name = "BadInstr";
7601             break;
7602         case CP0_REG08__BADINSTRP:
7603             /* ignored */
7604             register_name = "BadInstrP";
7605             break;
7606         case CP0_REG08__BADINSTRX:
7607             /* ignored */
7608             register_name = "BadInstrX";
7609             break;
7610         default:
7611             goto cp0_unimplemented;
7612         }
7613         break;
7614     case CP0_REGISTER_09:
7615         switch (sel) {
7616         case CP0_REG09__COUNT:
7617             gen_helper_mtc0_count(tcg_env, arg);
7618             register_name = "Count";
7619             break;
7620         default:
7621             goto cp0_unimplemented;
7622         }
7623         /* Stop translation as we may have switched the execution mode */
7624         ctx->base.is_jmp = DISAS_STOP;
7625         break;
7626     case CP0_REGISTER_10:
7627         switch (sel) {
7628         case CP0_REG10__ENTRYHI:
7629             gen_helper_mtc0_entryhi(tcg_env, arg);
7630             register_name = "EntryHi";
7631             break;
7632         default:
7633             goto cp0_unimplemented;
7634         }
7635         break;
7636     case CP0_REGISTER_11:
7637         switch (sel) {
7638         case CP0_REG11__COMPARE:
7639             gen_helper_mtc0_compare(tcg_env, arg);
7640             register_name = "Compare";
7641             break;
7642         /* 6,7 are implementation dependent */
7643         default:
7644             goto cp0_unimplemented;
7645         }
7646         /* Stop translation as we may have switched the execution mode */
7647         ctx->base.is_jmp = DISAS_STOP;
7648         break;
7649     case CP0_REGISTER_12:
7650         switch (sel) {
7651         case CP0_REG12__STATUS:
7652             save_cpu_state(ctx, 1);
7653             gen_helper_mtc0_status(tcg_env, arg);
7654             /* DISAS_STOP isn't good enough here, hflags may have changed. */
7655             gen_save_pc(ctx->base.pc_next + 4);
7656             ctx->base.is_jmp = DISAS_EXIT;
7657             register_name = "Status";
7658             break;
7659         case CP0_REG12__INTCTL:
7660             check_insn(ctx, ISA_MIPS_R2);
7661             gen_helper_mtc0_intctl(tcg_env, arg);
7662             /* Stop translation as we may have switched the execution mode */
7663             ctx->base.is_jmp = DISAS_STOP;
7664             register_name = "IntCtl";
7665             break;
7666         case CP0_REG12__SRSCTL:
7667             check_insn(ctx, ISA_MIPS_R2);
7668             gen_helper_mtc0_srsctl(tcg_env, arg);
7669             /* Stop translation as we may have switched the execution mode */
7670             ctx->base.is_jmp = DISAS_STOP;
7671             register_name = "SRSCtl";
7672             break;
7673         case CP0_REG12__SRSMAP:
7674             check_insn(ctx, ISA_MIPS_R2);
7675             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7676             /* Stop translation as we may have switched the execution mode */
7677             ctx->base.is_jmp = DISAS_STOP;
7678             register_name = "SRSMap";
7679             break;
7680         default:
7681             goto cp0_unimplemented;
7682         }
7683         break;
7684     case CP0_REGISTER_13:
7685         switch (sel) {
7686         case CP0_REG13__CAUSE:
7687             save_cpu_state(ctx, 1);
7688             gen_helper_mtc0_cause(tcg_env, arg);
7689             /*
7690              * Stop translation as we may have triggered an interrupt.
7691              * DISAS_STOP isn't sufficient, we need to ensure we break out of
7692              * translated code to check for pending interrupts.
7693              */
7694             gen_save_pc(ctx->base.pc_next + 4);
7695             ctx->base.is_jmp = DISAS_EXIT;
7696             register_name = "Cause";
7697             break;
7698         default:
7699             goto cp0_unimplemented;
7700         }
7701         break;
7702     case CP0_REGISTER_14:
7703         switch (sel) {
7704         case CP0_REG14__EPC:
7705             tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC));
7706             register_name = "EPC";
7707             break;
7708         default:
7709             goto cp0_unimplemented;
7710         }
7711         break;
7712     case CP0_REGISTER_15:
7713         switch (sel) {
7714         case CP0_REG15__PRID:
7715             /* ignored */
7716             register_name = "PRid";
7717             break;
7718         case CP0_REG15__EBASE:
7719             check_insn(ctx, ISA_MIPS_R2);
7720             gen_helper_mtc0_ebase(tcg_env, arg);
7721             register_name = "EBase";
7722             break;
7723         default:
7724             goto cp0_unimplemented;
7725         }
7726         break;
7727     case CP0_REGISTER_16:
7728         switch (sel) {
7729         case CP0_REG16__CONFIG:
7730             gen_helper_mtc0_config0(tcg_env, arg);
7731             register_name = "Config";
7732             /* Stop translation as we may have switched the execution mode */
7733             ctx->base.is_jmp = DISAS_STOP;
7734             break;
7735         case CP0_REG16__CONFIG1:
7736             /* ignored, read only */
7737             register_name = "Config1";
7738             break;
7739         case CP0_REG16__CONFIG2:
7740             gen_helper_mtc0_config2(tcg_env, arg);
7741             register_name = "Config2";
7742             /* Stop translation as we may have switched the execution mode */
7743             ctx->base.is_jmp = DISAS_STOP;
7744             break;
7745         case CP0_REG16__CONFIG3:
7746             gen_helper_mtc0_config3(tcg_env, arg);
7747             register_name = "Config3";
7748             /* Stop translation as we may have switched the execution mode */
7749             ctx->base.is_jmp = DISAS_STOP;
7750             break;
7751         case CP0_REG16__CONFIG4:
7752             /* currently ignored */
7753             register_name = "Config4";
7754             break;
7755         case CP0_REG16__CONFIG5:
7756             gen_helper_mtc0_config5(tcg_env, arg);
7757             register_name = "Config5";
7758             /* Stop translation as we may have switched the execution mode */
7759             ctx->base.is_jmp = DISAS_STOP;
7760             break;
7761         /* 6,7 are implementation dependent */
7762         default:
7763             register_name = "Invalid config selector";
7764             goto cp0_unimplemented;
7765         }
7766         break;
7767     case CP0_REGISTER_17:
7768         switch (sel) {
7769         case CP0_REG17__LLADDR:
7770             gen_helper_mtc0_lladdr(tcg_env, arg);
7771             register_name = "LLAddr";
7772             break;
7773         case CP0_REG17__MAAR:
7774             CP0_CHECK(ctx->mrp);
7775             gen_helper_mtc0_maar(tcg_env, arg);
7776             register_name = "MAAR";
7777             break;
7778         case CP0_REG17__MAARI:
7779             CP0_CHECK(ctx->mrp);
7780             gen_helper_mtc0_maari(tcg_env, arg);
7781             register_name = "MAARI";
7782             break;
7783         default:
7784             goto cp0_unimplemented;
7785         }
7786         break;
7787     case CP0_REGISTER_18:
7788         switch (sel) {
7789         case CP0_REG18__WATCHLO0:
7790         case CP0_REG18__WATCHLO1:
7791         case CP0_REG18__WATCHLO2:
7792         case CP0_REG18__WATCHLO3:
7793         case CP0_REG18__WATCHLO4:
7794         case CP0_REG18__WATCHLO5:
7795         case CP0_REG18__WATCHLO6:
7796         case CP0_REG18__WATCHLO7:
7797             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7798             gen_helper_0e1i(mtc0_watchlo, arg, sel);
7799             register_name = "WatchLo";
7800             break;
7801         default:
7802             goto cp0_unimplemented;
7803         }
7804         break;
7805     case CP0_REGISTER_19:
7806         switch (sel) {
7807         case CP0_REG19__WATCHHI0:
7808         case CP0_REG19__WATCHHI1:
7809         case CP0_REG19__WATCHHI2:
7810         case CP0_REG19__WATCHHI3:
7811         case CP0_REG19__WATCHHI4:
7812         case CP0_REG19__WATCHHI5:
7813         case CP0_REG19__WATCHHI6:
7814         case CP0_REG19__WATCHHI7:
7815             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7816             gen_helper_0e1i(mtc0_watchhi, arg, sel);
7817             register_name = "WatchHi";
7818             break;
7819         default:
7820             goto cp0_unimplemented;
7821         }
7822         break;
7823     case CP0_REGISTER_20:
7824         switch (sel) {
7825         case CP0_REG20__XCONTEXT:
7826             check_insn(ctx, ISA_MIPS3);
7827             gen_helper_mtc0_xcontext(tcg_env, arg);
7828             register_name = "XContext";
7829             break;
7830         default:
7831             goto cp0_unimplemented;
7832         }
7833         break;
7834     case CP0_REGISTER_21:
7835        /* Officially reserved, but sel 0 is used for R1x000 framemask */
7836         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
7837         switch (sel) {
7838         case 0:
7839             gen_helper_mtc0_framemask(tcg_env, arg);
7840             register_name = "Framemask";
7841             break;
7842         default:
7843             goto cp0_unimplemented;
7844         }
7845         break;
7846     case CP0_REGISTER_22:
7847         /* ignored */
7848         register_name = "Diagnostic"; /* implementation dependent */
7849         break;
7850     case CP0_REGISTER_23:
7851         switch (sel) {
7852         case CP0_REG23__DEBUG:
7853             gen_helper_mtc0_debug(tcg_env, arg); /* EJTAG support */
7854             /* DISAS_STOP isn't good enough here, hflags may have changed. */
7855             gen_save_pc(ctx->base.pc_next + 4);
7856             ctx->base.is_jmp = DISAS_EXIT;
7857             register_name = "Debug";
7858             break;
7859         case CP0_REG23__TRACECONTROL:
7860             /* PDtrace support */
7861             /* gen_helper_mtc0_tracecontrol(tcg_env, arg);  */
7862             /* Stop translation as we may have switched the execution mode */
7863             ctx->base.is_jmp = DISAS_STOP;
7864             register_name = "TraceControl";
7865             goto cp0_unimplemented;
7866         case CP0_REG23__TRACECONTROL2:
7867             /* PDtrace support */
7868             /* gen_helper_mtc0_tracecontrol2(tcg_env, arg); */
7869             /* Stop translation as we may have switched the execution mode */
7870             ctx->base.is_jmp = DISAS_STOP;
7871             register_name = "TraceControl2";
7872             goto cp0_unimplemented;
7873         case CP0_REG23__USERTRACEDATA1:
7874             /* PDtrace support */
7875             /* gen_helper_mtc0_usertracedata1(tcg_env, arg);*/
7876             /* Stop translation as we may have switched the execution mode */
7877             ctx->base.is_jmp = DISAS_STOP;
7878             register_name = "UserTraceData1";
7879             goto cp0_unimplemented;
7880         case CP0_REG23__TRACEIBPC:
7881             /* PDtrace support */
7882             /* gen_helper_mtc0_traceibpc(tcg_env, arg);     */
7883             /* Stop translation as we may have switched the execution mode */
7884             ctx->base.is_jmp = DISAS_STOP;
7885             register_name = "TraceIBPC";
7886             goto cp0_unimplemented;
7887         case CP0_REG23__TRACEDBPC:
7888             /* PDtrace support */
7889             /* gen_helper_mtc0_tracedbpc(tcg_env, arg);     */
7890             /* Stop translation as we may have switched the execution mode */
7891             ctx->base.is_jmp = DISAS_STOP;
7892             register_name = "TraceDBPC";
7893             goto cp0_unimplemented;
7894         default:
7895             goto cp0_unimplemented;
7896         }
7897         break;
7898     case CP0_REGISTER_24:
7899         switch (sel) {
7900         case CP0_REG24__DEPC:
7901             /* EJTAG support */
7902             tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC));
7903             register_name = "DEPC";
7904             break;
7905         default:
7906             goto cp0_unimplemented;
7907         }
7908         break;
7909     case CP0_REGISTER_25:
7910         switch (sel) {
7911         case CP0_REG25__PERFCTL0:
7912             gen_helper_mtc0_performance0(tcg_env, arg);
7913             register_name = "Performance0";
7914             break;
7915         case CP0_REG25__PERFCNT0:
7916             /* gen_helper_mtc0_performance1(tcg_env, arg); */
7917             register_name = "Performance1";
7918             goto cp0_unimplemented;
7919         case CP0_REG25__PERFCTL1:
7920             /* gen_helper_mtc0_performance2(tcg_env, arg); */
7921             register_name = "Performance2";
7922             goto cp0_unimplemented;
7923         case CP0_REG25__PERFCNT1:
7924             /* gen_helper_mtc0_performance3(tcg_env, arg); */
7925             register_name = "Performance3";
7926             goto cp0_unimplemented;
7927         case CP0_REG25__PERFCTL2:
7928             /* gen_helper_mtc0_performance4(tcg_env, arg); */
7929             register_name = "Performance4";
7930             goto cp0_unimplemented;
7931         case CP0_REG25__PERFCNT2:
7932             /* gen_helper_mtc0_performance5(tcg_env, arg); */
7933             register_name = "Performance5";
7934             goto cp0_unimplemented;
7935         case CP0_REG25__PERFCTL3:
7936             /* gen_helper_mtc0_performance6(tcg_env, arg); */
7937             register_name = "Performance6";
7938             goto cp0_unimplemented;
7939         case CP0_REG25__PERFCNT3:
7940             /* gen_helper_mtc0_performance7(tcg_env, arg); */
7941             register_name = "Performance7";
7942             goto cp0_unimplemented;
7943         default:
7944             goto cp0_unimplemented;
7945         }
7946         break;
7947     case CP0_REGISTER_26:
7948         switch (sel) {
7949         case CP0_REG26__ERRCTL:
7950             gen_helper_mtc0_errctl(tcg_env, arg);
7951             ctx->base.is_jmp = DISAS_STOP;
7952             register_name = "ErrCtl";
7953             break;
7954         default:
7955             goto cp0_unimplemented;
7956         }
7957         break;
7958     case CP0_REGISTER_27:
7959         switch (sel) {
7960         case CP0_REG27__CACHERR:
7961             /* ignored */
7962             register_name = "CacheErr";
7963             break;
7964         default:
7965             goto cp0_unimplemented;
7966         }
7967         break;
7968     case CP0_REGISTER_28:
7969         switch (sel) {
7970         case CP0_REG28__TAGLO:
7971         case CP0_REG28__TAGLO1:
7972         case CP0_REG28__TAGLO2:
7973         case CP0_REG28__TAGLO3:
7974             gen_helper_mtc0_taglo(tcg_env, arg);
7975             register_name = "TagLo";
7976             break;
7977         case CP0_REG28__DATALO:
7978         case CP0_REG28__DATALO1:
7979         case CP0_REG28__DATALO2:
7980         case CP0_REG28__DATALO3:
7981             gen_helper_mtc0_datalo(tcg_env, arg);
7982             register_name = "DataLo";
7983             break;
7984         default:
7985             goto cp0_unimplemented;
7986         }
7987         break;
7988     case CP0_REGISTER_29:
7989         switch (sel) {
7990         case CP0_REG29__TAGHI:
7991         case CP0_REG29__TAGHI1:
7992         case CP0_REG29__TAGHI2:
7993         case CP0_REG29__TAGHI3:
7994             gen_helper_mtc0_taghi(tcg_env, arg);
7995             register_name = "TagHi";
7996             break;
7997         case CP0_REG29__DATAHI:
7998         case CP0_REG29__DATAHI1:
7999         case CP0_REG29__DATAHI2:
8000         case CP0_REG29__DATAHI3:
8001             gen_helper_mtc0_datahi(tcg_env, arg);
8002             register_name = "DataHi";
8003             break;
8004         default:
8005             register_name = "invalid sel";
8006             goto cp0_unimplemented;
8007         }
8008         break;
8009     case CP0_REGISTER_30:
8010         switch (sel) {
8011         case CP0_REG30__ERROREPC:
8012             tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8013             register_name = "ErrorEPC";
8014             break;
8015         default:
8016             goto cp0_unimplemented;
8017         }
8018         break;
8019     case CP0_REGISTER_31:
8020         switch (sel) {
8021         case CP0_REG31__DESAVE:
8022             /* EJTAG support */
8023             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8024             register_name = "DESAVE";
8025             break;
8026         case CP0_REG31__KSCRATCH1:
8027         case CP0_REG31__KSCRATCH2:
8028         case CP0_REG31__KSCRATCH3:
8029         case CP0_REG31__KSCRATCH4:
8030         case CP0_REG31__KSCRATCH5:
8031         case CP0_REG31__KSCRATCH6:
8032             CP0_CHECK(ctx->kscrexist & (1 << sel));
8033             tcg_gen_st_tl(arg, tcg_env,
8034                           offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
8035             register_name = "KScratch";
8036             break;
8037         default:
8038             goto cp0_unimplemented;
8039         }
8040         break;
8041     default:
8042         goto cp0_unimplemented;
8043     }
8044     trace_mips_translate_c0("dmtc0", register_name, reg, sel);
8045 
8046     /* For simplicity assume that all writes can cause interrupts.  */
8047     if (icount) {
8048         /*
8049          * DISAS_STOP isn't sufficient, we need to ensure we break out of
8050          * translated code to check for pending interrupts.
8051          */
8052         gen_save_pc(ctx->base.pc_next + 4);
8053         ctx->base.is_jmp = DISAS_EXIT;
8054     }
8055     return;
8056 
8057 cp0_unimplemented:
8058     qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n",
8059                   register_name, reg, sel);
8060 }
8061 #endif /* TARGET_MIPS64 */
8062 
gen_mftr(CPUMIPSState * env,DisasContext * ctx,int rt,int rd,int u,int sel,int h)8063 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
8064                      int u, int sel, int h)
8065 {
8066     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
8067     TCGv t0 = tcg_temp_new();
8068 
8069     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
8070         ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8071          (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
8072         tcg_gen_movi_tl(t0, -1);
8073     } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8074                (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
8075         tcg_gen_movi_tl(t0, -1);
8076     } else if (u == 0) {
8077         switch (rt) {
8078         case 1:
8079             switch (sel) {
8080             case 1:
8081                 gen_helper_mftc0_vpecontrol(t0, tcg_env);
8082                 break;
8083             case 2:
8084                 gen_helper_mftc0_vpeconf0(t0, tcg_env);
8085                 break;
8086             default:
8087                 goto die;
8088                 break;
8089             }
8090             break;
8091         case 2:
8092             switch (sel) {
8093             case 1:
8094                 gen_helper_mftc0_tcstatus(t0, tcg_env);
8095                 break;
8096             case 2:
8097                 gen_helper_mftc0_tcbind(t0, tcg_env);
8098                 break;
8099             case 3:
8100                 gen_helper_mftc0_tcrestart(t0, tcg_env);
8101                 break;
8102             case 4:
8103                 gen_helper_mftc0_tchalt(t0, tcg_env);
8104                 break;
8105             case 5:
8106                 gen_helper_mftc0_tccontext(t0, tcg_env);
8107                 break;
8108             case 6:
8109                 gen_helper_mftc0_tcschedule(t0, tcg_env);
8110                 break;
8111             case 7:
8112                 gen_helper_mftc0_tcschefback(t0, tcg_env);
8113                 break;
8114             default:
8115                 gen_mfc0(ctx, t0, rt, sel);
8116                 break;
8117             }
8118             break;
8119         case 10:
8120             switch (sel) {
8121             case 0:
8122                 gen_helper_mftc0_entryhi(t0, tcg_env);
8123                 break;
8124             default:
8125                 gen_mfc0(ctx, t0, rt, sel);
8126                 break;
8127             }
8128             break;
8129         case 12:
8130             switch (sel) {
8131             case 0:
8132                 gen_helper_mftc0_status(t0, tcg_env);
8133                 break;
8134             default:
8135                 gen_mfc0(ctx, t0, rt, sel);
8136                 break;
8137             }
8138             break;
8139         case 13:
8140             switch (sel) {
8141             case 0:
8142                 gen_helper_mftc0_cause(t0, tcg_env);
8143                 break;
8144             default:
8145                 goto die;
8146                 break;
8147             }
8148             break;
8149         case 14:
8150             switch (sel) {
8151             case 0:
8152                 gen_helper_mftc0_epc(t0, tcg_env);
8153                 break;
8154             default:
8155                 goto die;
8156                 break;
8157             }
8158             break;
8159         case 15:
8160             switch (sel) {
8161             case 1:
8162                 gen_helper_mftc0_ebase(t0, tcg_env);
8163                 break;
8164             default:
8165                 goto die;
8166                 break;
8167             }
8168             break;
8169         case 16:
8170             switch (sel) {
8171             case 0:
8172             case 1:
8173             case 2:
8174             case 3:
8175             case 4:
8176             case 5:
8177             case 6:
8178             case 7:
8179                 gen_helper_mftc0_configx(t0, tcg_env, tcg_constant_tl(sel));
8180                 break;
8181             default:
8182                 goto die;
8183                 break;
8184             }
8185             break;
8186         case 23:
8187             switch (sel) {
8188             case 0:
8189                 gen_helper_mftc0_debug(t0, tcg_env);
8190                 break;
8191             default:
8192                 gen_mfc0(ctx, t0, rt, sel);
8193                 break;
8194             }
8195             break;
8196         default:
8197             gen_mfc0(ctx, t0, rt, sel);
8198         }
8199     } else {
8200         switch (sel) {
8201         /* GPR registers. */
8202         case 0:
8203             gen_helper_1e0i(mftgpr, t0, rt);
8204             break;
8205         /* Auxiliary CPU registers */
8206         case 1:
8207             switch (rt) {
8208             case 0:
8209                 gen_helper_1e0i(mftlo, t0, 0);
8210                 break;
8211             case 1:
8212                 gen_helper_1e0i(mfthi, t0, 0);
8213                 break;
8214             case 2:
8215                 gen_helper_1e0i(mftacx, t0, 0);
8216                 break;
8217             case 4:
8218                 gen_helper_1e0i(mftlo, t0, 1);
8219                 break;
8220             case 5:
8221                 gen_helper_1e0i(mfthi, t0, 1);
8222                 break;
8223             case 6:
8224                 gen_helper_1e0i(mftacx, t0, 1);
8225                 break;
8226             case 8:
8227                 gen_helper_1e0i(mftlo, t0, 2);
8228                 break;
8229             case 9:
8230                 gen_helper_1e0i(mfthi, t0, 2);
8231                 break;
8232             case 10:
8233                 gen_helper_1e0i(mftacx, t0, 2);
8234                 break;
8235             case 12:
8236                 gen_helper_1e0i(mftlo, t0, 3);
8237                 break;
8238             case 13:
8239                 gen_helper_1e0i(mfthi, t0, 3);
8240                 break;
8241             case 14:
8242                 gen_helper_1e0i(mftacx, t0, 3);
8243                 break;
8244             case 16:
8245                 gen_helper_mftdsp(t0, tcg_env);
8246                 break;
8247             default:
8248                 goto die;
8249             }
8250             break;
8251         /* Floating point (COP1). */
8252         case 2:
8253             /* XXX: For now we support only a single FPU context. */
8254             if (h == 0) {
8255                 TCGv_i32 fp0 = tcg_temp_new_i32();
8256 
8257                 gen_load_fpr32(ctx, fp0, rt);
8258                 tcg_gen_ext_i32_tl(t0, fp0);
8259             } else {
8260                 TCGv_i32 fp0 = tcg_temp_new_i32();
8261 
8262                 gen_load_fpr32h(ctx, fp0, rt);
8263                 tcg_gen_ext_i32_tl(t0, fp0);
8264             }
8265             break;
8266         case 3:
8267             /* XXX: For now we support only a single FPU context. */
8268             gen_helper_1e0i(cfc1, t0, rt);
8269             break;
8270         /* COP2: Not implemented. */
8271         case 4:
8272         case 5:
8273             /* fall through */
8274         default:
8275             goto die;
8276         }
8277     }
8278     trace_mips_translate_tr("mftr", rt, u, sel, h);
8279     gen_store_gpr(t0, rd);
8280     return;
8281 
8282 die:
8283     LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
8284     gen_reserved_instruction(ctx);
8285 }
8286 
gen_mttr(CPUMIPSState * env,DisasContext * ctx,int rd,int rt,int u,int sel,int h)8287 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
8288                      int u, int sel, int h)
8289 {
8290     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
8291     TCGv t0 = tcg_temp_new();
8292 
8293     gen_load_gpr(t0, rt);
8294     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
8295         ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8296          (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
8297         /* NOP */
8298         ;
8299     } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8300              (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
8301         /* NOP */
8302         ;
8303     } else if (u == 0) {
8304         switch (rd) {
8305         case 1:
8306             switch (sel) {
8307             case 1:
8308                 gen_helper_mttc0_vpecontrol(tcg_env, t0);
8309                 break;
8310             case 2:
8311                 gen_helper_mttc0_vpeconf0(tcg_env, t0);
8312                 break;
8313             default:
8314                 goto die;
8315                 break;
8316             }
8317             break;
8318         case 2:
8319             switch (sel) {
8320             case 1:
8321                 gen_helper_mttc0_tcstatus(tcg_env, t0);
8322                 break;
8323             case 2:
8324                 gen_helper_mttc0_tcbind(tcg_env, t0);
8325                 break;
8326             case 3:
8327                 gen_helper_mttc0_tcrestart(tcg_env, t0);
8328                 break;
8329             case 4:
8330                 gen_helper_mttc0_tchalt(tcg_env, t0);
8331                 break;
8332             case 5:
8333                 gen_helper_mttc0_tccontext(tcg_env, t0);
8334                 break;
8335             case 6:
8336                 gen_helper_mttc0_tcschedule(tcg_env, t0);
8337                 break;
8338             case 7:
8339                 gen_helper_mttc0_tcschefback(tcg_env, t0);
8340                 break;
8341             default:
8342                 gen_mtc0(ctx, t0, rd, sel);
8343                 break;
8344             }
8345             break;
8346         case 10:
8347             switch (sel) {
8348             case 0:
8349                 gen_helper_mttc0_entryhi(tcg_env, t0);
8350                 break;
8351             default:
8352                 gen_mtc0(ctx, t0, rd, sel);
8353                 break;
8354             }
8355             break;
8356         case 12:
8357             switch (sel) {
8358             case 0:
8359                 gen_helper_mttc0_status(tcg_env, t0);
8360                 break;
8361             default:
8362                 gen_mtc0(ctx, t0, rd, sel);
8363                 break;
8364             }
8365             break;
8366         case 13:
8367             switch (sel) {
8368             case 0:
8369                 gen_helper_mttc0_cause(tcg_env, t0);
8370                 break;
8371             default:
8372                 goto die;
8373                 break;
8374             }
8375             break;
8376         case 15:
8377             switch (sel) {
8378             case 1:
8379                 gen_helper_mttc0_ebase(tcg_env, t0);
8380                 break;
8381             default:
8382                 goto die;
8383                 break;
8384             }
8385             break;
8386         case 23:
8387             switch (sel) {
8388             case 0:
8389                 gen_helper_mttc0_debug(tcg_env, t0);
8390                 break;
8391             default:
8392                 gen_mtc0(ctx, t0, rd, sel);
8393                 break;
8394             }
8395             break;
8396         default:
8397             gen_mtc0(ctx, t0, rd, sel);
8398         }
8399     } else {
8400         switch (sel) {
8401         /* GPR registers. */
8402         case 0:
8403             gen_helper_0e1i(mttgpr, t0, rd);
8404             break;
8405         /* Auxiliary CPU registers */
8406         case 1:
8407             switch (rd) {
8408             case 0:
8409                 gen_helper_0e1i(mttlo, t0, 0);
8410                 break;
8411             case 1:
8412                 gen_helper_0e1i(mtthi, t0, 0);
8413                 break;
8414             case 2:
8415                 gen_helper_0e1i(mttacx, t0, 0);
8416                 break;
8417             case 4:
8418                 gen_helper_0e1i(mttlo, t0, 1);
8419                 break;
8420             case 5:
8421                 gen_helper_0e1i(mtthi, t0, 1);
8422                 break;
8423             case 6:
8424                 gen_helper_0e1i(mttacx, t0, 1);
8425                 break;
8426             case 8:
8427                 gen_helper_0e1i(mttlo, t0, 2);
8428                 break;
8429             case 9:
8430                 gen_helper_0e1i(mtthi, t0, 2);
8431                 break;
8432             case 10:
8433                 gen_helper_0e1i(mttacx, t0, 2);
8434                 break;
8435             case 12:
8436                 gen_helper_0e1i(mttlo, t0, 3);
8437                 break;
8438             case 13:
8439                 gen_helper_0e1i(mtthi, t0, 3);
8440                 break;
8441             case 14:
8442                 gen_helper_0e1i(mttacx, t0, 3);
8443                 break;
8444             case 16:
8445                 gen_helper_mttdsp(tcg_env, t0);
8446                 break;
8447             default:
8448                 goto die;
8449             }
8450             break;
8451         /* Floating point (COP1). */
8452         case 2:
8453             /* XXX: For now we support only a single FPU context. */
8454             if (h == 0) {
8455                 TCGv_i32 fp0 = tcg_temp_new_i32();
8456 
8457                 tcg_gen_trunc_tl_i32(fp0, t0);
8458                 gen_store_fpr32(ctx, fp0, rd);
8459             } else {
8460                 TCGv_i32 fp0 = tcg_temp_new_i32();
8461 
8462                 tcg_gen_trunc_tl_i32(fp0, t0);
8463                 gen_store_fpr32h(ctx, fp0, rd);
8464             }
8465             break;
8466         case 3:
8467             /* XXX: For now we support only a single FPU context. */
8468             gen_helper_0e2i(ctc1, t0, tcg_constant_i32(rd), rt);
8469             /* Stop translation as we may have changed hflags */
8470             ctx->base.is_jmp = DISAS_STOP;
8471             break;
8472         /* COP2: Not implemented. */
8473         case 4:
8474         case 5:
8475             /* fall through */
8476         default:
8477             goto die;
8478         }
8479     }
8480     trace_mips_translate_tr("mttr", rd, u, sel, h);
8481     return;
8482 
8483 die:
8484     LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
8485     gen_reserved_instruction(ctx);
8486 }
8487 
gen_cp0(CPUMIPSState * env,DisasContext * ctx,uint32_t opc,int rt,int rd)8488 static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
8489                     int rt, int rd)
8490 {
8491     const char *opn = "ldst";
8492 
8493     check_cp0_enabled(ctx);
8494     switch (opc) {
8495     case OPC_MFC0:
8496         if (rt == 0) {
8497             /* Treat as NOP. */
8498             return;
8499         }
8500         gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8501         opn = "mfc0";
8502         break;
8503     case OPC_MTC0:
8504         {
8505             TCGv t0 = tcg_temp_new();
8506 
8507             gen_load_gpr(t0, rt);
8508             gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
8509         }
8510         opn = "mtc0";
8511         break;
8512 #if defined(TARGET_MIPS64)
8513     case OPC_DMFC0:
8514         check_insn(ctx, ISA_MIPS3);
8515         if (rt == 0) {
8516             /* Treat as NOP. */
8517             return;
8518         }
8519         gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8520         opn = "dmfc0";
8521         break;
8522     case OPC_DMTC0:
8523         check_insn(ctx, ISA_MIPS3);
8524         {
8525             TCGv t0 = tcg_temp_new();
8526 
8527             gen_load_gpr(t0, rt);
8528             gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
8529         }
8530         opn = "dmtc0";
8531         break;
8532 #endif
8533     case OPC_MFHC0:
8534         check_mvh(ctx);
8535         if (rt == 0) {
8536             /* Treat as NOP. */
8537             return;
8538         }
8539         gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8540         opn = "mfhc0";
8541         break;
8542     case OPC_MTHC0:
8543         check_mvh(ctx);
8544         {
8545             TCGv t0 = tcg_temp_new();
8546             gen_load_gpr(t0, rt);
8547             gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
8548         }
8549         opn = "mthc0";
8550         break;
8551     case OPC_MFTR:
8552         check_cp0_enabled(ctx);
8553         if (rd == 0) {
8554             /* Treat as NOP. */
8555             return;
8556         }
8557         gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
8558                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8559         opn = "mftr";
8560         break;
8561     case OPC_MTTR:
8562         check_cp0_enabled(ctx);
8563         gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
8564                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8565         opn = "mttr";
8566         break;
8567     case OPC_TLBWI:
8568         opn = "tlbwi";
8569         if (!env->tlb->helper_tlbwi) {
8570             goto die;
8571         }
8572         gen_helper_tlbwi(tcg_env);
8573         break;
8574     case OPC_TLBINV:
8575         opn = "tlbinv";
8576         if (ctx->ie >= 2) {
8577             if (!env->tlb->helper_tlbinv) {
8578                 goto die;
8579             }
8580             gen_helper_tlbinv(tcg_env);
8581         } /* treat as nop if TLBINV not supported */
8582         break;
8583     case OPC_TLBINVF:
8584         opn = "tlbinvf";
8585         if (ctx->ie >= 2) {
8586             if (!env->tlb->helper_tlbinvf) {
8587                 goto die;
8588             }
8589             gen_helper_tlbinvf(tcg_env);
8590         } /* treat as nop if TLBINV not supported */
8591         break;
8592     case OPC_TLBWR:
8593         opn = "tlbwr";
8594         if (!env->tlb->helper_tlbwr) {
8595             goto die;
8596         }
8597         gen_helper_tlbwr(tcg_env);
8598         break;
8599     case OPC_TLBP:
8600         opn = "tlbp";
8601         if (!env->tlb->helper_tlbp) {
8602             goto die;
8603         }
8604         gen_helper_tlbp(tcg_env);
8605         break;
8606     case OPC_TLBR:
8607         opn = "tlbr";
8608         if (!env->tlb->helper_tlbr) {
8609             goto die;
8610         }
8611         gen_helper_tlbr(tcg_env);
8612         break;
8613     case OPC_ERET: /* OPC_ERETNC */
8614         if ((ctx->insn_flags & ISA_MIPS_R6) &&
8615             (ctx->hflags & MIPS_HFLAG_BMASK)) {
8616             goto die;
8617         } else {
8618             int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
8619             if (ctx->opcode & (1 << bit_shift)) {
8620                 /* OPC_ERETNC */
8621                 opn = "eretnc";
8622                 check_insn(ctx, ISA_MIPS_R5);
8623                 gen_helper_eretnc(tcg_env);
8624             } else {
8625                 /* OPC_ERET */
8626                 opn = "eret";
8627                 check_insn(ctx, ISA_MIPS2);
8628                 gen_helper_eret(tcg_env);
8629             }
8630             ctx->base.is_jmp = DISAS_EXIT;
8631         }
8632         break;
8633     case OPC_DERET:
8634         opn = "deret";
8635         check_insn(ctx, ISA_MIPS_R1);
8636         if ((ctx->insn_flags & ISA_MIPS_R6) &&
8637             (ctx->hflags & MIPS_HFLAG_BMASK)) {
8638             goto die;
8639         }
8640         if (!(ctx->hflags & MIPS_HFLAG_DM)) {
8641             MIPS_INVAL(opn);
8642             gen_reserved_instruction(ctx);
8643         } else {
8644             gen_helper_deret(tcg_env);
8645             ctx->base.is_jmp = DISAS_EXIT;
8646         }
8647         break;
8648     case OPC_WAIT:
8649         opn = "wait";
8650         check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1);
8651         if ((ctx->insn_flags & ISA_MIPS_R6) &&
8652             (ctx->hflags & MIPS_HFLAG_BMASK)) {
8653             goto die;
8654         }
8655         /* If we get an exception, we want to restart at next instruction */
8656         ctx->base.pc_next += 4;
8657         save_cpu_state(ctx, 1);
8658         ctx->base.pc_next -= 4;
8659         gen_helper_wait(tcg_env);
8660         ctx->base.is_jmp = DISAS_NORETURN;
8661         break;
8662     default:
8663  die:
8664         MIPS_INVAL(opn);
8665         gen_reserved_instruction(ctx);
8666         return;
8667     }
8668     (void)opn; /* avoid a compiler warning */
8669 }
8670 #endif /* !CONFIG_USER_ONLY */
8671 
8672 /* CP1 Branches (before delay slot) */
gen_compute_branch1(DisasContext * ctx,uint32_t op,int32_t cc,int32_t offset)8673 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
8674                                 int32_t cc, int32_t offset)
8675 {
8676     target_ulong btarget;
8677     TCGv_i32 t0 = tcg_temp_new_i32();
8678 
8679     if ((ctx->insn_flags & ISA_MIPS_R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8680         gen_reserved_instruction(ctx);
8681         return;
8682     }
8683 
8684     if (cc != 0) {
8685         check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1);
8686     }
8687 
8688     btarget = ctx->base.pc_next + 4 + offset;
8689 
8690     switch (op) {
8691     case OPC_BC1F:
8692         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8693         tcg_gen_not_i32(t0, t0);
8694         tcg_gen_andi_i32(t0, t0, 1);
8695         tcg_gen_extu_i32_tl(bcond, t0);
8696         goto not_likely;
8697     case OPC_BC1FL:
8698         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8699         tcg_gen_not_i32(t0, t0);
8700         tcg_gen_andi_i32(t0, t0, 1);
8701         tcg_gen_extu_i32_tl(bcond, t0);
8702         goto likely;
8703     case OPC_BC1T:
8704         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8705         tcg_gen_andi_i32(t0, t0, 1);
8706         tcg_gen_extu_i32_tl(bcond, t0);
8707         goto not_likely;
8708     case OPC_BC1TL:
8709         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8710         tcg_gen_andi_i32(t0, t0, 1);
8711         tcg_gen_extu_i32_tl(bcond, t0);
8712     likely:
8713         ctx->hflags |= MIPS_HFLAG_BL;
8714         break;
8715     case OPC_BC1FANY2:
8716         {
8717             TCGv_i32 t1 = tcg_temp_new_i32();
8718             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8719             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
8720             tcg_gen_nand_i32(t0, t0, t1);
8721             tcg_gen_andi_i32(t0, t0, 1);
8722             tcg_gen_extu_i32_tl(bcond, t0);
8723         }
8724         goto not_likely;
8725     case OPC_BC1TANY2:
8726         {
8727             TCGv_i32 t1 = tcg_temp_new_i32();
8728             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8729             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
8730             tcg_gen_or_i32(t0, t0, t1);
8731             tcg_gen_andi_i32(t0, t0, 1);
8732             tcg_gen_extu_i32_tl(bcond, t0);
8733         }
8734         goto not_likely;
8735     case OPC_BC1FANY4:
8736         {
8737             TCGv_i32 t1 = tcg_temp_new_i32();
8738             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8739             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
8740             tcg_gen_and_i32(t0, t0, t1);
8741             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
8742             tcg_gen_and_i32(t0, t0, t1);
8743             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
8744             tcg_gen_nand_i32(t0, t0, t1);
8745             tcg_gen_andi_i32(t0, t0, 1);
8746             tcg_gen_extu_i32_tl(bcond, t0);
8747         }
8748         goto not_likely;
8749     case OPC_BC1TANY4:
8750         {
8751             TCGv_i32 t1 = tcg_temp_new_i32();
8752             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8753             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
8754             tcg_gen_or_i32(t0, t0, t1);
8755             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
8756             tcg_gen_or_i32(t0, t0, t1);
8757             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
8758             tcg_gen_or_i32(t0, t0, t1);
8759             tcg_gen_andi_i32(t0, t0, 1);
8760             tcg_gen_extu_i32_tl(bcond, t0);
8761         }
8762     not_likely:
8763         ctx->hflags |= MIPS_HFLAG_BC;
8764         break;
8765     default:
8766         MIPS_INVAL("cp1 cond branch");
8767         gen_reserved_instruction(ctx);
8768         return;
8769     }
8770     ctx->btarget = btarget;
8771     ctx->hflags |= MIPS_HFLAG_BDS32;
8772 }
8773 
8774 /* R6 CP1 Branches */
gen_compute_branch1_r6(DisasContext * ctx,uint32_t op,int32_t ft,int32_t offset,int delayslot_size)8775 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
8776                                    int32_t ft, int32_t offset,
8777                                    int delayslot_size)
8778 {
8779     target_ulong btarget;
8780     TCGv_i64 t0 = tcg_temp_new_i64();
8781 
8782     if (ctx->hflags & MIPS_HFLAG_BMASK) {
8783 #ifdef MIPS_DEBUG_DISAS
8784         LOG_DISAS("Branch in delay / forbidden slot at PC 0x%016"
8785                   VADDR_PRIx "\n", ctx->base.pc_next);
8786 #endif
8787         gen_reserved_instruction(ctx);
8788         return;
8789     }
8790 
8791     gen_load_fpr64(ctx, t0, ft);
8792     tcg_gen_andi_i64(t0, t0, 1);
8793 
8794     btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
8795 
8796     switch (op) {
8797     case OPC_BC1EQZ:
8798         tcg_gen_xori_i64(t0, t0, 1);
8799         ctx->hflags |= MIPS_HFLAG_BC;
8800         break;
8801     case OPC_BC1NEZ:
8802         /* t0 already set */
8803         ctx->hflags |= MIPS_HFLAG_BC;
8804         break;
8805     default:
8806         MIPS_INVAL("cp1 cond branch");
8807         gen_reserved_instruction(ctx);
8808         return;
8809     }
8810 
8811     tcg_gen_trunc_i64_tl(bcond, t0);
8812 
8813     ctx->btarget = btarget;
8814 
8815     switch (delayslot_size) {
8816     case 2:
8817         ctx->hflags |= MIPS_HFLAG_BDS16;
8818         break;
8819     case 4:
8820         ctx->hflags |= MIPS_HFLAG_BDS32;
8821         break;
8822     }
8823 }
8824 
8825 /* Coprocessor 1 (FPU) */
8826 
8827 #define FOP(func, fmt) (((fmt) << 21) | (func))
8828 
8829 enum fopcode {
8830     OPC_ADD_S = FOP(0, FMT_S),
8831     OPC_SUB_S = FOP(1, FMT_S),
8832     OPC_MUL_S = FOP(2, FMT_S),
8833     OPC_DIV_S = FOP(3, FMT_S),
8834     OPC_SQRT_S = FOP(4, FMT_S),
8835     OPC_ABS_S = FOP(5, FMT_S),
8836     OPC_MOV_S = FOP(6, FMT_S),
8837     OPC_NEG_S = FOP(7, FMT_S),
8838     OPC_ROUND_L_S = FOP(8, FMT_S),
8839     OPC_TRUNC_L_S = FOP(9, FMT_S),
8840     OPC_CEIL_L_S = FOP(10, FMT_S),
8841     OPC_FLOOR_L_S = FOP(11, FMT_S),
8842     OPC_ROUND_W_S = FOP(12, FMT_S),
8843     OPC_TRUNC_W_S = FOP(13, FMT_S),
8844     OPC_CEIL_W_S = FOP(14, FMT_S),
8845     OPC_FLOOR_W_S = FOP(15, FMT_S),
8846     OPC_SEL_S = FOP(16, FMT_S),
8847     OPC_MOVCF_S = FOP(17, FMT_S),
8848     OPC_MOVZ_S = FOP(18, FMT_S),
8849     OPC_MOVN_S = FOP(19, FMT_S),
8850     OPC_SELEQZ_S = FOP(20, FMT_S),
8851     OPC_RECIP_S = FOP(21, FMT_S),
8852     OPC_RSQRT_S = FOP(22, FMT_S),
8853     OPC_SELNEZ_S = FOP(23, FMT_S),
8854     OPC_MADDF_S = FOP(24, FMT_S),
8855     OPC_MSUBF_S = FOP(25, FMT_S),
8856     OPC_RINT_S = FOP(26, FMT_S),
8857     OPC_CLASS_S = FOP(27, FMT_S),
8858     OPC_MIN_S = FOP(28, FMT_S),
8859     OPC_RECIP2_S = FOP(28, FMT_S),
8860     OPC_MINA_S = FOP(29, FMT_S),
8861     OPC_RECIP1_S = FOP(29, FMT_S),
8862     OPC_MAX_S = FOP(30, FMT_S),
8863     OPC_RSQRT1_S = FOP(30, FMT_S),
8864     OPC_MAXA_S = FOP(31, FMT_S),
8865     OPC_RSQRT2_S = FOP(31, FMT_S),
8866     OPC_CVT_D_S = FOP(33, FMT_S),
8867     OPC_CVT_W_S = FOP(36, FMT_S),
8868     OPC_CVT_L_S = FOP(37, FMT_S),
8869     OPC_CVT_PS_S = FOP(38, FMT_S),
8870     OPC_CMP_F_S = FOP(48, FMT_S),
8871     OPC_CMP_UN_S = FOP(49, FMT_S),
8872     OPC_CMP_EQ_S = FOP(50, FMT_S),
8873     OPC_CMP_UEQ_S = FOP(51, FMT_S),
8874     OPC_CMP_OLT_S = FOP(52, FMT_S),
8875     OPC_CMP_ULT_S = FOP(53, FMT_S),
8876     OPC_CMP_OLE_S = FOP(54, FMT_S),
8877     OPC_CMP_ULE_S = FOP(55, FMT_S),
8878     OPC_CMP_SF_S = FOP(56, FMT_S),
8879     OPC_CMP_NGLE_S = FOP(57, FMT_S),
8880     OPC_CMP_SEQ_S = FOP(58, FMT_S),
8881     OPC_CMP_NGL_S = FOP(59, FMT_S),
8882     OPC_CMP_LT_S = FOP(60, FMT_S),
8883     OPC_CMP_NGE_S = FOP(61, FMT_S),
8884     OPC_CMP_LE_S = FOP(62, FMT_S),
8885     OPC_CMP_NGT_S = FOP(63, FMT_S),
8886 
8887     OPC_ADD_D = FOP(0, FMT_D),
8888     OPC_SUB_D = FOP(1, FMT_D),
8889     OPC_MUL_D = FOP(2, FMT_D),
8890     OPC_DIV_D = FOP(3, FMT_D),
8891     OPC_SQRT_D = FOP(4, FMT_D),
8892     OPC_ABS_D = FOP(5, FMT_D),
8893     OPC_MOV_D = FOP(6, FMT_D),
8894     OPC_NEG_D = FOP(7, FMT_D),
8895     OPC_ROUND_L_D = FOP(8, FMT_D),
8896     OPC_TRUNC_L_D = FOP(9, FMT_D),
8897     OPC_CEIL_L_D = FOP(10, FMT_D),
8898     OPC_FLOOR_L_D = FOP(11, FMT_D),
8899     OPC_ROUND_W_D = FOP(12, FMT_D),
8900     OPC_TRUNC_W_D = FOP(13, FMT_D),
8901     OPC_CEIL_W_D = FOP(14, FMT_D),
8902     OPC_FLOOR_W_D = FOP(15, FMT_D),
8903     OPC_SEL_D = FOP(16, FMT_D),
8904     OPC_MOVCF_D = FOP(17, FMT_D),
8905     OPC_MOVZ_D = FOP(18, FMT_D),
8906     OPC_MOVN_D = FOP(19, FMT_D),
8907     OPC_SELEQZ_D = FOP(20, FMT_D),
8908     OPC_RECIP_D = FOP(21, FMT_D),
8909     OPC_RSQRT_D = FOP(22, FMT_D),
8910     OPC_SELNEZ_D = FOP(23, FMT_D),
8911     OPC_MADDF_D = FOP(24, FMT_D),
8912     OPC_MSUBF_D = FOP(25, FMT_D),
8913     OPC_RINT_D = FOP(26, FMT_D),
8914     OPC_CLASS_D = FOP(27, FMT_D),
8915     OPC_MIN_D = FOP(28, FMT_D),
8916     OPC_RECIP2_D = FOP(28, FMT_D),
8917     OPC_MINA_D = FOP(29, FMT_D),
8918     OPC_RECIP1_D = FOP(29, FMT_D),
8919     OPC_MAX_D = FOP(30, FMT_D),
8920     OPC_RSQRT1_D = FOP(30, FMT_D),
8921     OPC_MAXA_D = FOP(31, FMT_D),
8922     OPC_RSQRT2_D = FOP(31, FMT_D),
8923     OPC_CVT_S_D = FOP(32, FMT_D),
8924     OPC_CVT_W_D = FOP(36, FMT_D),
8925     OPC_CVT_L_D = FOP(37, FMT_D),
8926     OPC_CMP_F_D = FOP(48, FMT_D),
8927     OPC_CMP_UN_D = FOP(49, FMT_D),
8928     OPC_CMP_EQ_D = FOP(50, FMT_D),
8929     OPC_CMP_UEQ_D = FOP(51, FMT_D),
8930     OPC_CMP_OLT_D = FOP(52, FMT_D),
8931     OPC_CMP_ULT_D = FOP(53, FMT_D),
8932     OPC_CMP_OLE_D = FOP(54, FMT_D),
8933     OPC_CMP_ULE_D = FOP(55, FMT_D),
8934     OPC_CMP_SF_D = FOP(56, FMT_D),
8935     OPC_CMP_NGLE_D = FOP(57, FMT_D),
8936     OPC_CMP_SEQ_D = FOP(58, FMT_D),
8937     OPC_CMP_NGL_D = FOP(59, FMT_D),
8938     OPC_CMP_LT_D = FOP(60, FMT_D),
8939     OPC_CMP_NGE_D = FOP(61, FMT_D),
8940     OPC_CMP_LE_D = FOP(62, FMT_D),
8941     OPC_CMP_NGT_D = FOP(63, FMT_D),
8942 
8943     OPC_CVT_S_W = FOP(32, FMT_W),
8944     OPC_CVT_D_W = FOP(33, FMT_W),
8945     OPC_CVT_S_L = FOP(32, FMT_L),
8946     OPC_CVT_D_L = FOP(33, FMT_L),
8947     OPC_CVT_PS_PW = FOP(38, FMT_W),
8948 
8949     OPC_ADD_PS = FOP(0, FMT_PS),
8950     OPC_SUB_PS = FOP(1, FMT_PS),
8951     OPC_MUL_PS = FOP(2, FMT_PS),
8952     OPC_DIV_PS = FOP(3, FMT_PS),
8953     OPC_ABS_PS = FOP(5, FMT_PS),
8954     OPC_MOV_PS = FOP(6, FMT_PS),
8955     OPC_NEG_PS = FOP(7, FMT_PS),
8956     OPC_MOVCF_PS = FOP(17, FMT_PS),
8957     OPC_MOVZ_PS = FOP(18, FMT_PS),
8958     OPC_MOVN_PS = FOP(19, FMT_PS),
8959     OPC_ADDR_PS = FOP(24, FMT_PS),
8960     OPC_MULR_PS = FOP(26, FMT_PS),
8961     OPC_RECIP2_PS = FOP(28, FMT_PS),
8962     OPC_RECIP1_PS = FOP(29, FMT_PS),
8963     OPC_RSQRT1_PS = FOP(30, FMT_PS),
8964     OPC_RSQRT2_PS = FOP(31, FMT_PS),
8965 
8966     OPC_CVT_S_PU = FOP(32, FMT_PS),
8967     OPC_CVT_PW_PS = FOP(36, FMT_PS),
8968     OPC_CVT_S_PL = FOP(40, FMT_PS),
8969     OPC_PLL_PS = FOP(44, FMT_PS),
8970     OPC_PLU_PS = FOP(45, FMT_PS),
8971     OPC_PUL_PS = FOP(46, FMT_PS),
8972     OPC_PUU_PS = FOP(47, FMT_PS),
8973     OPC_CMP_F_PS = FOP(48, FMT_PS),
8974     OPC_CMP_UN_PS = FOP(49, FMT_PS),
8975     OPC_CMP_EQ_PS = FOP(50, FMT_PS),
8976     OPC_CMP_UEQ_PS = FOP(51, FMT_PS),
8977     OPC_CMP_OLT_PS = FOP(52, FMT_PS),
8978     OPC_CMP_ULT_PS = FOP(53, FMT_PS),
8979     OPC_CMP_OLE_PS = FOP(54, FMT_PS),
8980     OPC_CMP_ULE_PS = FOP(55, FMT_PS),
8981     OPC_CMP_SF_PS = FOP(56, FMT_PS),
8982     OPC_CMP_NGLE_PS = FOP(57, FMT_PS),
8983     OPC_CMP_SEQ_PS = FOP(58, FMT_PS),
8984     OPC_CMP_NGL_PS = FOP(59, FMT_PS),
8985     OPC_CMP_LT_PS = FOP(60, FMT_PS),
8986     OPC_CMP_NGE_PS = FOP(61, FMT_PS),
8987     OPC_CMP_LE_PS = FOP(62, FMT_PS),
8988     OPC_CMP_NGT_PS = FOP(63, FMT_PS),
8989 };
8990 
8991 enum r6_f_cmp_op {
8992     R6_OPC_CMP_AF_S   = FOP(0, FMT_W),
8993     R6_OPC_CMP_UN_S   = FOP(1, FMT_W),
8994     R6_OPC_CMP_EQ_S   = FOP(2, FMT_W),
8995     R6_OPC_CMP_UEQ_S  = FOP(3, FMT_W),
8996     R6_OPC_CMP_LT_S   = FOP(4, FMT_W),
8997     R6_OPC_CMP_ULT_S  = FOP(5, FMT_W),
8998     R6_OPC_CMP_LE_S   = FOP(6, FMT_W),
8999     R6_OPC_CMP_ULE_S  = FOP(7, FMT_W),
9000     R6_OPC_CMP_SAF_S  = FOP(8, FMT_W),
9001     R6_OPC_CMP_SUN_S  = FOP(9, FMT_W),
9002     R6_OPC_CMP_SEQ_S  = FOP(10, FMT_W),
9003     R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
9004     R6_OPC_CMP_SLT_S  = FOP(12, FMT_W),
9005     R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
9006     R6_OPC_CMP_SLE_S  = FOP(14, FMT_W),
9007     R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
9008     R6_OPC_CMP_OR_S   = FOP(17, FMT_W),
9009     R6_OPC_CMP_UNE_S  = FOP(18, FMT_W),
9010     R6_OPC_CMP_NE_S   = FOP(19, FMT_W),
9011     R6_OPC_CMP_SOR_S  = FOP(25, FMT_W),
9012     R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
9013     R6_OPC_CMP_SNE_S  = FOP(27, FMT_W),
9014 
9015     R6_OPC_CMP_AF_D   = FOP(0, FMT_L),
9016     R6_OPC_CMP_UN_D   = FOP(1, FMT_L),
9017     R6_OPC_CMP_EQ_D   = FOP(2, FMT_L),
9018     R6_OPC_CMP_UEQ_D  = FOP(3, FMT_L),
9019     R6_OPC_CMP_LT_D   = FOP(4, FMT_L),
9020     R6_OPC_CMP_ULT_D  = FOP(5, FMT_L),
9021     R6_OPC_CMP_LE_D   = FOP(6, FMT_L),
9022     R6_OPC_CMP_ULE_D  = FOP(7, FMT_L),
9023     R6_OPC_CMP_SAF_D  = FOP(8, FMT_L),
9024     R6_OPC_CMP_SUN_D  = FOP(9, FMT_L),
9025     R6_OPC_CMP_SEQ_D  = FOP(10, FMT_L),
9026     R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
9027     R6_OPC_CMP_SLT_D  = FOP(12, FMT_L),
9028     R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
9029     R6_OPC_CMP_SLE_D  = FOP(14, FMT_L),
9030     R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
9031     R6_OPC_CMP_OR_D   = FOP(17, FMT_L),
9032     R6_OPC_CMP_UNE_D  = FOP(18, FMT_L),
9033     R6_OPC_CMP_NE_D   = FOP(19, FMT_L),
9034     R6_OPC_CMP_SOR_D  = FOP(25, FMT_L),
9035     R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
9036     R6_OPC_CMP_SNE_D  = FOP(27, FMT_L),
9037 };
9038 
gen_cp1(DisasContext * ctx,uint32_t opc,int rt,int fs)9039 static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs)
9040 {
9041     TCGv t0 = tcg_temp_new();
9042 
9043     switch (opc) {
9044     case OPC_MFC1:
9045         {
9046             TCGv_i32 fp0 = tcg_temp_new_i32();
9047 
9048             gen_load_fpr32(ctx, fp0, fs);
9049             tcg_gen_ext_i32_tl(t0, fp0);
9050         }
9051         gen_store_gpr(t0, rt);
9052         break;
9053     case OPC_MTC1:
9054         gen_load_gpr(t0, rt);
9055         {
9056             TCGv_i32 fp0 = tcg_temp_new_i32();
9057 
9058             tcg_gen_trunc_tl_i32(fp0, t0);
9059             gen_store_fpr32(ctx, fp0, fs);
9060         }
9061         break;
9062     case OPC_CFC1:
9063         gen_helper_1e0i(cfc1, t0, fs);
9064         gen_store_gpr(t0, rt);
9065         break;
9066     case OPC_CTC1:
9067         gen_load_gpr(t0, rt);
9068         save_cpu_state(ctx, 0);
9069         gen_helper_0e2i(ctc1, t0, tcg_constant_i32(fs), rt);
9070         /* Stop translation as we may have changed hflags */
9071         ctx->base.is_jmp = DISAS_STOP;
9072         break;
9073 #if defined(TARGET_MIPS64)
9074     case OPC_DMFC1:
9075         gen_load_fpr64(ctx, t0, fs);
9076         gen_store_gpr(t0, rt);
9077         break;
9078     case OPC_DMTC1:
9079         gen_load_gpr(t0, rt);
9080         gen_store_fpr64(ctx, t0, fs);
9081         break;
9082 #endif
9083     case OPC_MFHC1:
9084         {
9085             TCGv_i32 fp0 = tcg_temp_new_i32();
9086 
9087             gen_load_fpr32h(ctx, fp0, fs);
9088             tcg_gen_ext_i32_tl(t0, fp0);
9089         }
9090         gen_store_gpr(t0, rt);
9091         break;
9092     case OPC_MTHC1:
9093         gen_load_gpr(t0, rt);
9094         {
9095             TCGv_i32 fp0 = tcg_temp_new_i32();
9096 
9097             tcg_gen_trunc_tl_i32(fp0, t0);
9098             gen_store_fpr32h(ctx, fp0, fs);
9099         }
9100         break;
9101     default:
9102         MIPS_INVAL("cp1 move");
9103         gen_reserved_instruction(ctx);
9104         return;
9105     }
9106 }
9107 
gen_movci(DisasContext * ctx,int rd,int rs,int cc,int tf)9108 static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf)
9109 {
9110     TCGLabel *l1;
9111     TCGCond cond;
9112     TCGv_i32 t0;
9113 
9114     if (rd == 0) {
9115         /* Treat as NOP. */
9116         return;
9117     }
9118 
9119     if (tf) {
9120         cond = TCG_COND_EQ;
9121     } else {
9122         cond = TCG_COND_NE;
9123     }
9124 
9125     l1 = gen_new_label();
9126     t0 = tcg_temp_new_i32();
9127     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9128     tcg_gen_brcondi_i32(cond, t0, 0, l1);
9129     gen_load_gpr(cpu_gpr[rd], rs);
9130     gen_set_label(l1);
9131 }
9132 
gen_movcf_s(DisasContext * ctx,int fs,int fd,int cc,int tf)9133 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
9134                                int tf)
9135 {
9136     int cond;
9137     TCGv_i32 t0 = tcg_temp_new_i32();
9138     TCGLabel *l1 = gen_new_label();
9139 
9140     if (tf) {
9141         cond = TCG_COND_EQ;
9142     } else {
9143         cond = TCG_COND_NE;
9144     }
9145 
9146     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9147     tcg_gen_brcondi_i32(cond, t0, 0, l1);
9148     gen_load_fpr32(ctx, t0, fs);
9149     gen_store_fpr32(ctx, t0, fd);
9150     gen_set_label(l1);
9151 }
9152 
gen_movcf_d(DisasContext * ctx,int fs,int fd,int cc,int tf)9153 static inline void gen_movcf_d(DisasContext *ctx, int fs, int fd, int cc,
9154                                int tf)
9155 {
9156     int cond;
9157     TCGv_i32 t0 = tcg_temp_new_i32();
9158     TCGv_i64 fp0;
9159     TCGLabel *l1 = gen_new_label();
9160 
9161     if (tf) {
9162         cond = TCG_COND_EQ;
9163     } else {
9164         cond = TCG_COND_NE;
9165     }
9166 
9167     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9168     tcg_gen_brcondi_i32(cond, t0, 0, l1);
9169     fp0 = tcg_temp_new_i64();
9170     gen_load_fpr64(ctx, fp0, fs);
9171     gen_store_fpr64(ctx, fp0, fd);
9172     gen_set_label(l1);
9173 }
9174 
gen_movcf_ps(DisasContext * ctx,int fs,int fd,int cc,int tf)9175 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
9176                                 int cc, int tf)
9177 {
9178     int cond;
9179     TCGv_i32 t0 = tcg_temp_new_i32();
9180     TCGLabel *l1 = gen_new_label();
9181     TCGLabel *l2 = gen_new_label();
9182 
9183     if (tf) {
9184         cond = TCG_COND_EQ;
9185     } else {
9186         cond = TCG_COND_NE;
9187     }
9188 
9189     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9190     tcg_gen_brcondi_i32(cond, t0, 0, l1);
9191     gen_load_fpr32(ctx, t0, fs);
9192     gen_store_fpr32(ctx, t0, fd);
9193     gen_set_label(l1);
9194 
9195     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc + 1));
9196     tcg_gen_brcondi_i32(cond, t0, 0, l2);
9197     gen_load_fpr32h(ctx, t0, fs);
9198     gen_store_fpr32h(ctx, t0, fd);
9199     gen_set_label(l2);
9200 }
9201 
gen_sel_s(DisasContext * ctx,enum fopcode op1,int fd,int ft,int fs)9202 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9203                       int fs)
9204 {
9205     TCGv_i32 t1 = tcg_constant_i32(0);
9206     TCGv_i32 fp0 = tcg_temp_new_i32();
9207     TCGv_i32 fp1 = tcg_temp_new_i32();
9208     TCGv_i32 fp2 = tcg_temp_new_i32();
9209     gen_load_fpr32(ctx, fp0, fd);
9210     gen_load_fpr32(ctx, fp1, ft);
9211     gen_load_fpr32(ctx, fp2, fs);
9212 
9213     switch (op1) {
9214     case OPC_SEL_S:
9215         tcg_gen_andi_i32(fp0, fp0, 1);
9216         tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9217         break;
9218     case OPC_SELEQZ_S:
9219         tcg_gen_andi_i32(fp1, fp1, 1);
9220         tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9221         break;
9222     case OPC_SELNEZ_S:
9223         tcg_gen_andi_i32(fp1, fp1, 1);
9224         tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9225         break;
9226     default:
9227         MIPS_INVAL("gen_sel_s");
9228         gen_reserved_instruction(ctx);
9229         break;
9230     }
9231 
9232     gen_store_fpr32(ctx, fp0, fd);
9233 }
9234 
gen_sel_d(DisasContext * ctx,enum fopcode op1,int fd,int ft,int fs)9235 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9236                       int fs)
9237 {
9238     TCGv_i64 t1 = tcg_constant_i64(0);
9239     TCGv_i64 fp0 = tcg_temp_new_i64();
9240     TCGv_i64 fp1 = tcg_temp_new_i64();
9241     TCGv_i64 fp2 = tcg_temp_new_i64();
9242     gen_load_fpr64(ctx, fp0, fd);
9243     gen_load_fpr64(ctx, fp1, ft);
9244     gen_load_fpr64(ctx, fp2, fs);
9245 
9246     switch (op1) {
9247     case OPC_SEL_D:
9248         tcg_gen_andi_i64(fp0, fp0, 1);
9249         tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9250         break;
9251     case OPC_SELEQZ_D:
9252         tcg_gen_andi_i64(fp1, fp1, 1);
9253         tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9254         break;
9255     case OPC_SELNEZ_D:
9256         tcg_gen_andi_i64(fp1, fp1, 1);
9257         tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9258         break;
9259     default:
9260         MIPS_INVAL("gen_sel_d");
9261         gen_reserved_instruction(ctx);
9262         break;
9263     }
9264 
9265     gen_store_fpr64(ctx, fp0, fd);
9266 }
9267 
gen_farith(DisasContext * ctx,enum fopcode op1,int ft,int fs,int fd,int cc)9268 static void gen_farith(DisasContext *ctx, enum fopcode op1,
9269                        int ft, int fs, int fd, int cc)
9270 {
9271     uint32_t func = ctx->opcode & 0x3f;
9272     switch (op1) {
9273     case OPC_ADD_S:
9274         {
9275             TCGv_i32 fp0 = tcg_temp_new_i32();
9276             TCGv_i32 fp1 = tcg_temp_new_i32();
9277 
9278             gen_load_fpr32(ctx, fp0, fs);
9279             gen_load_fpr32(ctx, fp1, ft);
9280             gen_helper_float_add_s(fp0, tcg_env, fp0, fp1);
9281             gen_store_fpr32(ctx, fp0, fd);
9282         }
9283         break;
9284     case OPC_SUB_S:
9285         {
9286             TCGv_i32 fp0 = tcg_temp_new_i32();
9287             TCGv_i32 fp1 = tcg_temp_new_i32();
9288 
9289             gen_load_fpr32(ctx, fp0, fs);
9290             gen_load_fpr32(ctx, fp1, ft);
9291             gen_helper_float_sub_s(fp0, tcg_env, fp0, fp1);
9292             gen_store_fpr32(ctx, fp0, fd);
9293         }
9294         break;
9295     case OPC_MUL_S:
9296         {
9297             TCGv_i32 fp0 = tcg_temp_new_i32();
9298             TCGv_i32 fp1 = tcg_temp_new_i32();
9299 
9300             gen_load_fpr32(ctx, fp0, fs);
9301             gen_load_fpr32(ctx, fp1, ft);
9302             gen_helper_float_mul_s(fp0, tcg_env, fp0, fp1);
9303             gen_store_fpr32(ctx, fp0, fd);
9304         }
9305         break;
9306     case OPC_DIV_S:
9307         {
9308             TCGv_i32 fp0 = tcg_temp_new_i32();
9309             TCGv_i32 fp1 = tcg_temp_new_i32();
9310 
9311             gen_load_fpr32(ctx, fp0, fs);
9312             gen_load_fpr32(ctx, fp1, ft);
9313             gen_helper_float_div_s(fp0, tcg_env, fp0, fp1);
9314             gen_store_fpr32(ctx, fp0, fd);
9315         }
9316         break;
9317     case OPC_SQRT_S:
9318         {
9319             TCGv_i32 fp0 = tcg_temp_new_i32();
9320 
9321             gen_load_fpr32(ctx, fp0, fs);
9322             gen_helper_float_sqrt_s(fp0, tcg_env, fp0);
9323             gen_store_fpr32(ctx, fp0, fd);
9324         }
9325         break;
9326     case OPC_ABS_S:
9327         {
9328             TCGv_i32 fp0 = tcg_temp_new_i32();
9329 
9330             gen_load_fpr32(ctx, fp0, fs);
9331             if (ctx->abs2008) {
9332                 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
9333             } else {
9334                 gen_helper_float_abs_s(fp0, fp0);
9335             }
9336             gen_store_fpr32(ctx, fp0, fd);
9337         }
9338         break;
9339     case OPC_MOV_S:
9340         {
9341             TCGv_i32 fp0 = tcg_temp_new_i32();
9342 
9343             gen_load_fpr32(ctx, fp0, fs);
9344             gen_store_fpr32(ctx, fp0, fd);
9345         }
9346         break;
9347     case OPC_NEG_S:
9348         {
9349             TCGv_i32 fp0 = tcg_temp_new_i32();
9350 
9351             gen_load_fpr32(ctx, fp0, fs);
9352             if (ctx->abs2008) {
9353                 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
9354             } else {
9355                 gen_helper_float_chs_s(fp0, fp0);
9356             }
9357             gen_store_fpr32(ctx, fp0, fd);
9358         }
9359         break;
9360     case OPC_ROUND_L_S:
9361         check_cp1_64bitmode(ctx);
9362         {
9363             TCGv_i32 fp32 = tcg_temp_new_i32();
9364             TCGv_i64 fp64 = tcg_temp_new_i64();
9365 
9366             gen_load_fpr32(ctx, fp32, fs);
9367             if (ctx->nan2008) {
9368                 gen_helper_float_round_2008_l_s(fp64, tcg_env, fp32);
9369             } else {
9370                 gen_helper_float_round_l_s(fp64, tcg_env, fp32);
9371             }
9372             gen_store_fpr64(ctx, fp64, fd);
9373         }
9374         break;
9375     case OPC_TRUNC_L_S:
9376         check_cp1_64bitmode(ctx);
9377         {
9378             TCGv_i32 fp32 = tcg_temp_new_i32();
9379             TCGv_i64 fp64 = tcg_temp_new_i64();
9380 
9381             gen_load_fpr32(ctx, fp32, fs);
9382             if (ctx->nan2008) {
9383                 gen_helper_float_trunc_2008_l_s(fp64, tcg_env, fp32);
9384             } else {
9385                 gen_helper_float_trunc_l_s(fp64, tcg_env, fp32);
9386             }
9387             gen_store_fpr64(ctx, fp64, fd);
9388         }
9389         break;
9390     case OPC_CEIL_L_S:
9391         check_cp1_64bitmode(ctx);
9392         {
9393             TCGv_i32 fp32 = tcg_temp_new_i32();
9394             TCGv_i64 fp64 = tcg_temp_new_i64();
9395 
9396             gen_load_fpr32(ctx, fp32, fs);
9397             if (ctx->nan2008) {
9398                 gen_helper_float_ceil_2008_l_s(fp64, tcg_env, fp32);
9399             } else {
9400                 gen_helper_float_ceil_l_s(fp64, tcg_env, fp32);
9401             }
9402             gen_store_fpr64(ctx, fp64, fd);
9403         }
9404         break;
9405     case OPC_FLOOR_L_S:
9406         check_cp1_64bitmode(ctx);
9407         {
9408             TCGv_i32 fp32 = tcg_temp_new_i32();
9409             TCGv_i64 fp64 = tcg_temp_new_i64();
9410 
9411             gen_load_fpr32(ctx, fp32, fs);
9412             if (ctx->nan2008) {
9413                 gen_helper_float_floor_2008_l_s(fp64, tcg_env, fp32);
9414             } else {
9415                 gen_helper_float_floor_l_s(fp64, tcg_env, fp32);
9416             }
9417             gen_store_fpr64(ctx, fp64, fd);
9418         }
9419         break;
9420     case OPC_ROUND_W_S:
9421         {
9422             TCGv_i32 fp0 = tcg_temp_new_i32();
9423 
9424             gen_load_fpr32(ctx, fp0, fs);
9425             if (ctx->nan2008) {
9426                 gen_helper_float_round_2008_w_s(fp0, tcg_env, fp0);
9427             } else {
9428                 gen_helper_float_round_w_s(fp0, tcg_env, fp0);
9429             }
9430             gen_store_fpr32(ctx, fp0, fd);
9431         }
9432         break;
9433     case OPC_TRUNC_W_S:
9434         {
9435             TCGv_i32 fp0 = tcg_temp_new_i32();
9436 
9437             gen_load_fpr32(ctx, fp0, fs);
9438             if (ctx->nan2008) {
9439                 gen_helper_float_trunc_2008_w_s(fp0, tcg_env, fp0);
9440             } else {
9441                 gen_helper_float_trunc_w_s(fp0, tcg_env, fp0);
9442             }
9443             gen_store_fpr32(ctx, fp0, fd);
9444         }
9445         break;
9446     case OPC_CEIL_W_S:
9447         {
9448             TCGv_i32 fp0 = tcg_temp_new_i32();
9449 
9450             gen_load_fpr32(ctx, fp0, fs);
9451             if (ctx->nan2008) {
9452                 gen_helper_float_ceil_2008_w_s(fp0, tcg_env, fp0);
9453             } else {
9454                 gen_helper_float_ceil_w_s(fp0, tcg_env, fp0);
9455             }
9456             gen_store_fpr32(ctx, fp0, fd);
9457         }
9458         break;
9459     case OPC_FLOOR_W_S:
9460         {
9461             TCGv_i32 fp0 = tcg_temp_new_i32();
9462 
9463             gen_load_fpr32(ctx, fp0, fs);
9464             if (ctx->nan2008) {
9465                 gen_helper_float_floor_2008_w_s(fp0, tcg_env, fp0);
9466             } else {
9467                 gen_helper_float_floor_w_s(fp0, tcg_env, fp0);
9468             }
9469             gen_store_fpr32(ctx, fp0, fd);
9470         }
9471         break;
9472     case OPC_SEL_S:
9473         check_insn(ctx, ISA_MIPS_R6);
9474         gen_sel_s(ctx, op1, fd, ft, fs);
9475         break;
9476     case OPC_SELEQZ_S:
9477         check_insn(ctx, ISA_MIPS_R6);
9478         gen_sel_s(ctx, op1, fd, ft, fs);
9479         break;
9480     case OPC_SELNEZ_S:
9481         check_insn(ctx, ISA_MIPS_R6);
9482         gen_sel_s(ctx, op1, fd, ft, fs);
9483         break;
9484     case OPC_MOVCF_S:
9485         check_insn_opc_removed(ctx, ISA_MIPS_R6);
9486         gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9487         break;
9488     case OPC_MOVZ_S:
9489         check_insn_opc_removed(ctx, ISA_MIPS_R6);
9490         {
9491             TCGLabel *l1 = gen_new_label();
9492             TCGv_i32 fp0;
9493 
9494             if (ft != 0) {
9495                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9496             }
9497             fp0 = tcg_temp_new_i32();
9498             gen_load_fpr32(ctx, fp0, fs);
9499             gen_store_fpr32(ctx, fp0, fd);
9500             gen_set_label(l1);
9501         }
9502         break;
9503     case OPC_MOVN_S:
9504         check_insn_opc_removed(ctx, ISA_MIPS_R6);
9505         {
9506             TCGLabel *l1 = gen_new_label();
9507             TCGv_i32 fp0;
9508 
9509             if (ft != 0) {
9510                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9511                 fp0 = tcg_temp_new_i32();
9512                 gen_load_fpr32(ctx, fp0, fs);
9513                 gen_store_fpr32(ctx, fp0, fd);
9514                 gen_set_label(l1);
9515             }
9516         }
9517         break;
9518     case OPC_RECIP_S:
9519         {
9520             TCGv_i32 fp0 = tcg_temp_new_i32();
9521 
9522             gen_load_fpr32(ctx, fp0, fs);
9523             gen_helper_float_recip_s(fp0, tcg_env, fp0);
9524             gen_store_fpr32(ctx, fp0, fd);
9525         }
9526         break;
9527     case OPC_RSQRT_S:
9528         {
9529             TCGv_i32 fp0 = tcg_temp_new_i32();
9530 
9531             gen_load_fpr32(ctx, fp0, fs);
9532             gen_helper_float_rsqrt_s(fp0, tcg_env, fp0);
9533             gen_store_fpr32(ctx, fp0, fd);
9534         }
9535         break;
9536     case OPC_MADDF_S:
9537         check_insn(ctx, ISA_MIPS_R6);
9538         {
9539             TCGv_i32 fp0 = tcg_temp_new_i32();
9540             TCGv_i32 fp1 = tcg_temp_new_i32();
9541             TCGv_i32 fp2 = tcg_temp_new_i32();
9542             gen_load_fpr32(ctx, fp0, fs);
9543             gen_load_fpr32(ctx, fp1, ft);
9544             gen_load_fpr32(ctx, fp2, fd);
9545             gen_helper_float_maddf_s(fp2, tcg_env, fp0, fp1, fp2);
9546             gen_store_fpr32(ctx, fp2, fd);
9547         }
9548         break;
9549     case OPC_MSUBF_S:
9550         check_insn(ctx, ISA_MIPS_R6);
9551         {
9552             TCGv_i32 fp0 = tcg_temp_new_i32();
9553             TCGv_i32 fp1 = tcg_temp_new_i32();
9554             TCGv_i32 fp2 = tcg_temp_new_i32();
9555             gen_load_fpr32(ctx, fp0, fs);
9556             gen_load_fpr32(ctx, fp1, ft);
9557             gen_load_fpr32(ctx, fp2, fd);
9558             gen_helper_float_msubf_s(fp2, tcg_env, fp0, fp1, fp2);
9559             gen_store_fpr32(ctx, fp2, fd);
9560         }
9561         break;
9562     case OPC_RINT_S:
9563         check_insn(ctx, ISA_MIPS_R6);
9564         {
9565             TCGv_i32 fp0 = tcg_temp_new_i32();
9566             gen_load_fpr32(ctx, fp0, fs);
9567             gen_helper_float_rint_s(fp0, tcg_env, fp0);
9568             gen_store_fpr32(ctx, fp0, fd);
9569         }
9570         break;
9571     case OPC_CLASS_S:
9572         check_insn(ctx, ISA_MIPS_R6);
9573         {
9574             TCGv_i32 fp0 = tcg_temp_new_i32();
9575             gen_load_fpr32(ctx, fp0, fs);
9576             gen_helper_float_class_s(fp0, tcg_env, fp0);
9577             gen_store_fpr32(ctx, fp0, fd);
9578         }
9579         break;
9580     case OPC_MIN_S: /* OPC_RECIP2_S */
9581         if (ctx->insn_flags & ISA_MIPS_R6) {
9582             /* OPC_MIN_S */
9583             TCGv_i32 fp0 = tcg_temp_new_i32();
9584             TCGv_i32 fp1 = tcg_temp_new_i32();
9585             TCGv_i32 fp2 = tcg_temp_new_i32();
9586             gen_load_fpr32(ctx, fp0, fs);
9587             gen_load_fpr32(ctx, fp1, ft);
9588             gen_helper_float_min_s(fp2, tcg_env, fp0, fp1);
9589             gen_store_fpr32(ctx, fp2, fd);
9590         } else {
9591             /* OPC_RECIP2_S */
9592             check_cp1_64bitmode(ctx);
9593             {
9594                 TCGv_i32 fp0 = tcg_temp_new_i32();
9595                 TCGv_i32 fp1 = tcg_temp_new_i32();
9596 
9597                 gen_load_fpr32(ctx, fp0, fs);
9598                 gen_load_fpr32(ctx, fp1, ft);
9599                 gen_helper_float_recip2_s(fp0, tcg_env, fp0, fp1);
9600                 gen_store_fpr32(ctx, fp0, fd);
9601             }
9602         }
9603         break;
9604     case OPC_MINA_S: /* OPC_RECIP1_S */
9605         if (ctx->insn_flags & ISA_MIPS_R6) {
9606             /* OPC_MINA_S */
9607             TCGv_i32 fp0 = tcg_temp_new_i32();
9608             TCGv_i32 fp1 = tcg_temp_new_i32();
9609             TCGv_i32 fp2 = tcg_temp_new_i32();
9610             gen_load_fpr32(ctx, fp0, fs);
9611             gen_load_fpr32(ctx, fp1, ft);
9612             gen_helper_float_mina_s(fp2, tcg_env, fp0, fp1);
9613             gen_store_fpr32(ctx, fp2, fd);
9614         } else {
9615             /* OPC_RECIP1_S */
9616             check_cp1_64bitmode(ctx);
9617             {
9618                 TCGv_i32 fp0 = tcg_temp_new_i32();
9619 
9620                 gen_load_fpr32(ctx, fp0, fs);
9621                 gen_helper_float_recip1_s(fp0, tcg_env, fp0);
9622                 gen_store_fpr32(ctx, fp0, fd);
9623             }
9624         }
9625         break;
9626     case OPC_MAX_S: /* OPC_RSQRT1_S */
9627         if (ctx->insn_flags & ISA_MIPS_R6) {
9628             /* OPC_MAX_S */
9629             TCGv_i32 fp0 = tcg_temp_new_i32();
9630             TCGv_i32 fp1 = tcg_temp_new_i32();
9631             gen_load_fpr32(ctx, fp0, fs);
9632             gen_load_fpr32(ctx, fp1, ft);
9633             gen_helper_float_max_s(fp1, tcg_env, fp0, fp1);
9634             gen_store_fpr32(ctx, fp1, fd);
9635         } else {
9636             /* OPC_RSQRT1_S */
9637             check_cp1_64bitmode(ctx);
9638             {
9639                 TCGv_i32 fp0 = tcg_temp_new_i32();
9640 
9641                 gen_load_fpr32(ctx, fp0, fs);
9642                 gen_helper_float_rsqrt1_s(fp0, tcg_env, fp0);
9643                 gen_store_fpr32(ctx, fp0, fd);
9644             }
9645         }
9646         break;
9647     case OPC_MAXA_S: /* OPC_RSQRT2_S */
9648         if (ctx->insn_flags & ISA_MIPS_R6) {
9649             /* OPC_MAXA_S */
9650             TCGv_i32 fp0 = tcg_temp_new_i32();
9651             TCGv_i32 fp1 = tcg_temp_new_i32();
9652             gen_load_fpr32(ctx, fp0, fs);
9653             gen_load_fpr32(ctx, fp1, ft);
9654             gen_helper_float_maxa_s(fp1, tcg_env, fp0, fp1);
9655             gen_store_fpr32(ctx, fp1, fd);
9656         } else {
9657             /* OPC_RSQRT2_S */
9658             check_cp1_64bitmode(ctx);
9659             {
9660                 TCGv_i32 fp0 = tcg_temp_new_i32();
9661                 TCGv_i32 fp1 = tcg_temp_new_i32();
9662 
9663                 gen_load_fpr32(ctx, fp0, fs);
9664                 gen_load_fpr32(ctx, fp1, ft);
9665                 gen_helper_float_rsqrt2_s(fp0, tcg_env, fp0, fp1);
9666                 gen_store_fpr32(ctx, fp0, fd);
9667             }
9668         }
9669         break;
9670     case OPC_CVT_D_S:
9671         check_cp1_registers(ctx, fd);
9672         {
9673             TCGv_i32 fp32 = tcg_temp_new_i32();
9674             TCGv_i64 fp64 = tcg_temp_new_i64();
9675 
9676             gen_load_fpr32(ctx, fp32, fs);
9677             gen_helper_float_cvtd_s(fp64, tcg_env, fp32);
9678             gen_store_fpr64(ctx, fp64, fd);
9679         }
9680         break;
9681     case OPC_CVT_W_S:
9682         {
9683             TCGv_i32 fp0 = tcg_temp_new_i32();
9684 
9685             gen_load_fpr32(ctx, fp0, fs);
9686             if (ctx->nan2008) {
9687                 gen_helper_float_cvt_2008_w_s(fp0, tcg_env, fp0);
9688             } else {
9689                 gen_helper_float_cvt_w_s(fp0, tcg_env, fp0);
9690             }
9691             gen_store_fpr32(ctx, fp0, fd);
9692         }
9693         break;
9694     case OPC_CVT_L_S:
9695         check_cp1_64bitmode(ctx);
9696         {
9697             TCGv_i32 fp32 = tcg_temp_new_i32();
9698             TCGv_i64 fp64 = tcg_temp_new_i64();
9699 
9700             gen_load_fpr32(ctx, fp32, fs);
9701             if (ctx->nan2008) {
9702                 gen_helper_float_cvt_2008_l_s(fp64, tcg_env, fp32);
9703             } else {
9704                 gen_helper_float_cvt_l_s(fp64, tcg_env, fp32);
9705             }
9706             gen_store_fpr64(ctx, fp64, fd);
9707         }
9708         break;
9709     case OPC_CVT_PS_S:
9710         check_ps(ctx);
9711         {
9712             TCGv_i64 fp64 = tcg_temp_new_i64();
9713             TCGv_i32 fp32_0 = tcg_temp_new_i32();
9714             TCGv_i32 fp32_1 = tcg_temp_new_i32();
9715 
9716             gen_load_fpr32(ctx, fp32_0, fs);
9717             gen_load_fpr32(ctx, fp32_1, ft);
9718             tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
9719             gen_store_fpr64(ctx, fp64, fd);
9720         }
9721         break;
9722     case OPC_CMP_F_S:
9723     case OPC_CMP_UN_S:
9724     case OPC_CMP_EQ_S:
9725     case OPC_CMP_UEQ_S:
9726     case OPC_CMP_OLT_S:
9727     case OPC_CMP_ULT_S:
9728     case OPC_CMP_OLE_S:
9729     case OPC_CMP_ULE_S:
9730     case OPC_CMP_SF_S:
9731     case OPC_CMP_NGLE_S:
9732     case OPC_CMP_SEQ_S:
9733     case OPC_CMP_NGL_S:
9734     case OPC_CMP_LT_S:
9735     case OPC_CMP_NGE_S:
9736     case OPC_CMP_LE_S:
9737     case OPC_CMP_NGT_S:
9738         check_insn_opc_removed(ctx, ISA_MIPS_R6);
9739         if (ctx->opcode & (1 << 6)) {
9740             gen_cmpabs_s(ctx, func - 48, ft, fs, cc);
9741         } else {
9742             gen_cmp_s(ctx, func - 48, ft, fs, cc);
9743         }
9744         break;
9745     case OPC_ADD_D:
9746         check_cp1_registers(ctx, fs | ft | fd);
9747         {
9748             TCGv_i64 fp0 = tcg_temp_new_i64();
9749             TCGv_i64 fp1 = tcg_temp_new_i64();
9750 
9751             gen_load_fpr64(ctx, fp0, fs);
9752             gen_load_fpr64(ctx, fp1, ft);
9753             gen_helper_float_add_d(fp0, tcg_env, fp0, fp1);
9754             gen_store_fpr64(ctx, fp0, fd);
9755         }
9756         break;
9757     case OPC_SUB_D:
9758         check_cp1_registers(ctx, fs | ft | fd);
9759         {
9760             TCGv_i64 fp0 = tcg_temp_new_i64();
9761             TCGv_i64 fp1 = tcg_temp_new_i64();
9762 
9763             gen_load_fpr64(ctx, fp0, fs);
9764             gen_load_fpr64(ctx, fp1, ft);
9765             gen_helper_float_sub_d(fp0, tcg_env, fp0, fp1);
9766             gen_store_fpr64(ctx, fp0, fd);
9767         }
9768         break;
9769     case OPC_MUL_D:
9770         check_cp1_registers(ctx, fs | ft | fd);
9771         {
9772             TCGv_i64 fp0 = tcg_temp_new_i64();
9773             TCGv_i64 fp1 = tcg_temp_new_i64();
9774 
9775             gen_load_fpr64(ctx, fp0, fs);
9776             gen_load_fpr64(ctx, fp1, ft);
9777             gen_helper_float_mul_d(fp0, tcg_env, fp0, fp1);
9778             gen_store_fpr64(ctx, fp0, fd);
9779         }
9780         break;
9781     case OPC_DIV_D:
9782         check_cp1_registers(ctx, fs | ft | fd);
9783         {
9784             TCGv_i64 fp0 = tcg_temp_new_i64();
9785             TCGv_i64 fp1 = tcg_temp_new_i64();
9786 
9787             gen_load_fpr64(ctx, fp0, fs);
9788             gen_load_fpr64(ctx, fp1, ft);
9789             gen_helper_float_div_d(fp0, tcg_env, fp0, fp1);
9790             gen_store_fpr64(ctx, fp0, fd);
9791         }
9792         break;
9793     case OPC_SQRT_D:
9794         check_cp1_registers(ctx, fs | fd);
9795         {
9796             TCGv_i64 fp0 = tcg_temp_new_i64();
9797 
9798             gen_load_fpr64(ctx, fp0, fs);
9799             gen_helper_float_sqrt_d(fp0, tcg_env, fp0);
9800             gen_store_fpr64(ctx, fp0, fd);
9801         }
9802         break;
9803     case OPC_ABS_D:
9804         check_cp1_registers(ctx, fs | fd);
9805         {
9806             TCGv_i64 fp0 = tcg_temp_new_i64();
9807 
9808             gen_load_fpr64(ctx, fp0, fs);
9809             if (ctx->abs2008) {
9810                 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
9811             } else {
9812                 gen_helper_float_abs_d(fp0, fp0);
9813             }
9814             gen_store_fpr64(ctx, fp0, fd);
9815         }
9816         break;
9817     case OPC_MOV_D:
9818         check_cp1_registers(ctx, fs | fd);
9819         {
9820             TCGv_i64 fp0 = tcg_temp_new_i64();
9821 
9822             gen_load_fpr64(ctx, fp0, fs);
9823             gen_store_fpr64(ctx, fp0, fd);
9824         }
9825         break;
9826     case OPC_NEG_D:
9827         check_cp1_registers(ctx, fs | fd);
9828         {
9829             TCGv_i64 fp0 = tcg_temp_new_i64();
9830 
9831             gen_load_fpr64(ctx, fp0, fs);
9832             if (ctx->abs2008) {
9833                 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
9834             } else {
9835                 gen_helper_float_chs_d(fp0, fp0);
9836             }
9837             gen_store_fpr64(ctx, fp0, fd);
9838         }
9839         break;
9840     case OPC_ROUND_L_D:
9841         check_cp1_64bitmode(ctx);
9842         {
9843             TCGv_i64 fp0 = tcg_temp_new_i64();
9844 
9845             gen_load_fpr64(ctx, fp0, fs);
9846             if (ctx->nan2008) {
9847                 gen_helper_float_round_2008_l_d(fp0, tcg_env, fp0);
9848             } else {
9849                 gen_helper_float_round_l_d(fp0, tcg_env, fp0);
9850             }
9851             gen_store_fpr64(ctx, fp0, fd);
9852         }
9853         break;
9854     case OPC_TRUNC_L_D:
9855         check_cp1_64bitmode(ctx);
9856         {
9857             TCGv_i64 fp0 = tcg_temp_new_i64();
9858 
9859             gen_load_fpr64(ctx, fp0, fs);
9860             if (ctx->nan2008) {
9861                 gen_helper_float_trunc_2008_l_d(fp0, tcg_env, fp0);
9862             } else {
9863                 gen_helper_float_trunc_l_d(fp0, tcg_env, fp0);
9864             }
9865             gen_store_fpr64(ctx, fp0, fd);
9866         }
9867         break;
9868     case OPC_CEIL_L_D:
9869         check_cp1_64bitmode(ctx);
9870         {
9871             TCGv_i64 fp0 = tcg_temp_new_i64();
9872 
9873             gen_load_fpr64(ctx, fp0, fs);
9874             if (ctx->nan2008) {
9875                 gen_helper_float_ceil_2008_l_d(fp0, tcg_env, fp0);
9876             } else {
9877                 gen_helper_float_ceil_l_d(fp0, tcg_env, fp0);
9878             }
9879             gen_store_fpr64(ctx, fp0, fd);
9880         }
9881         break;
9882     case OPC_FLOOR_L_D:
9883         check_cp1_64bitmode(ctx);
9884         {
9885             TCGv_i64 fp0 = tcg_temp_new_i64();
9886 
9887             gen_load_fpr64(ctx, fp0, fs);
9888             if (ctx->nan2008) {
9889                 gen_helper_float_floor_2008_l_d(fp0, tcg_env, fp0);
9890             } else {
9891                 gen_helper_float_floor_l_d(fp0, tcg_env, fp0);
9892             }
9893             gen_store_fpr64(ctx, fp0, fd);
9894         }
9895         break;
9896     case OPC_ROUND_W_D:
9897         check_cp1_registers(ctx, fs);
9898         {
9899             TCGv_i32 fp32 = tcg_temp_new_i32();
9900             TCGv_i64 fp64 = tcg_temp_new_i64();
9901 
9902             gen_load_fpr64(ctx, fp64, fs);
9903             if (ctx->nan2008) {
9904                 gen_helper_float_round_2008_w_d(fp32, tcg_env, fp64);
9905             } else {
9906                 gen_helper_float_round_w_d(fp32, tcg_env, fp64);
9907             }
9908             gen_store_fpr32(ctx, fp32, fd);
9909         }
9910         break;
9911     case OPC_TRUNC_W_D:
9912         check_cp1_registers(ctx, fs);
9913         {
9914             TCGv_i32 fp32 = tcg_temp_new_i32();
9915             TCGv_i64 fp64 = tcg_temp_new_i64();
9916 
9917             gen_load_fpr64(ctx, fp64, fs);
9918             if (ctx->nan2008) {
9919                 gen_helper_float_trunc_2008_w_d(fp32, tcg_env, fp64);
9920             } else {
9921                 gen_helper_float_trunc_w_d(fp32, tcg_env, fp64);
9922             }
9923             gen_store_fpr32(ctx, fp32, fd);
9924         }
9925         break;
9926     case OPC_CEIL_W_D:
9927         check_cp1_registers(ctx, fs);
9928         {
9929             TCGv_i32 fp32 = tcg_temp_new_i32();
9930             TCGv_i64 fp64 = tcg_temp_new_i64();
9931 
9932             gen_load_fpr64(ctx, fp64, fs);
9933             if (ctx->nan2008) {
9934                 gen_helper_float_ceil_2008_w_d(fp32, tcg_env, fp64);
9935             } else {
9936                 gen_helper_float_ceil_w_d(fp32, tcg_env, fp64);
9937             }
9938             gen_store_fpr32(ctx, fp32, fd);
9939         }
9940         break;
9941     case OPC_FLOOR_W_D:
9942         check_cp1_registers(ctx, fs);
9943         {
9944             TCGv_i32 fp32 = tcg_temp_new_i32();
9945             TCGv_i64 fp64 = tcg_temp_new_i64();
9946 
9947             gen_load_fpr64(ctx, fp64, fs);
9948             if (ctx->nan2008) {
9949                 gen_helper_float_floor_2008_w_d(fp32, tcg_env, fp64);
9950             } else {
9951                 gen_helper_float_floor_w_d(fp32, tcg_env, fp64);
9952             }
9953             gen_store_fpr32(ctx, fp32, fd);
9954         }
9955         break;
9956     case OPC_SEL_D:
9957         check_insn(ctx, ISA_MIPS_R6);
9958         gen_sel_d(ctx, op1, fd, ft, fs);
9959         break;
9960     case OPC_SELEQZ_D:
9961         check_insn(ctx, ISA_MIPS_R6);
9962         gen_sel_d(ctx, op1, fd, ft, fs);
9963         break;
9964     case OPC_SELNEZ_D:
9965         check_insn(ctx, ISA_MIPS_R6);
9966         gen_sel_d(ctx, op1, fd, ft, fs);
9967         break;
9968     case OPC_MOVCF_D:
9969         check_insn_opc_removed(ctx, ISA_MIPS_R6);
9970         gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9971         break;
9972     case OPC_MOVZ_D:
9973         check_insn_opc_removed(ctx, ISA_MIPS_R6);
9974         {
9975             TCGLabel *l1 = gen_new_label();
9976             TCGv_i64 fp0;
9977 
9978             if (ft != 0) {
9979                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9980             }
9981             fp0 = tcg_temp_new_i64();
9982             gen_load_fpr64(ctx, fp0, fs);
9983             gen_store_fpr64(ctx, fp0, fd);
9984             gen_set_label(l1);
9985         }
9986         break;
9987     case OPC_MOVN_D:
9988         check_insn_opc_removed(ctx, ISA_MIPS_R6);
9989         {
9990             TCGLabel *l1 = gen_new_label();
9991             TCGv_i64 fp0;
9992 
9993             if (ft != 0) {
9994                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9995                 fp0 = tcg_temp_new_i64();
9996                 gen_load_fpr64(ctx, fp0, fs);
9997                 gen_store_fpr64(ctx, fp0, fd);
9998                 gen_set_label(l1);
9999             }
10000         }
10001         break;
10002     case OPC_RECIP_D:
10003         check_cp1_registers(ctx, fs | fd);
10004         {
10005             TCGv_i64 fp0 = tcg_temp_new_i64();
10006 
10007             gen_load_fpr64(ctx, fp0, fs);
10008             gen_helper_float_recip_d(fp0, tcg_env, fp0);
10009             gen_store_fpr64(ctx, fp0, fd);
10010         }
10011         break;
10012     case OPC_RSQRT_D:
10013         check_cp1_registers(ctx, fs | fd);
10014         {
10015             TCGv_i64 fp0 = tcg_temp_new_i64();
10016 
10017             gen_load_fpr64(ctx, fp0, fs);
10018             gen_helper_float_rsqrt_d(fp0, tcg_env, fp0);
10019             gen_store_fpr64(ctx, fp0, fd);
10020         }
10021         break;
10022     case OPC_MADDF_D:
10023         check_insn(ctx, ISA_MIPS_R6);
10024         {
10025             TCGv_i64 fp0 = tcg_temp_new_i64();
10026             TCGv_i64 fp1 = tcg_temp_new_i64();
10027             TCGv_i64 fp2 = tcg_temp_new_i64();
10028             gen_load_fpr64(ctx, fp0, fs);
10029             gen_load_fpr64(ctx, fp1, ft);
10030             gen_load_fpr64(ctx, fp2, fd);
10031             gen_helper_float_maddf_d(fp2, tcg_env, fp0, fp1, fp2);
10032             gen_store_fpr64(ctx, fp2, fd);
10033         }
10034         break;
10035     case OPC_MSUBF_D:
10036         check_insn(ctx, ISA_MIPS_R6);
10037         {
10038             TCGv_i64 fp0 = tcg_temp_new_i64();
10039             TCGv_i64 fp1 = tcg_temp_new_i64();
10040             TCGv_i64 fp2 = tcg_temp_new_i64();
10041             gen_load_fpr64(ctx, fp0, fs);
10042             gen_load_fpr64(ctx, fp1, ft);
10043             gen_load_fpr64(ctx, fp2, fd);
10044             gen_helper_float_msubf_d(fp2, tcg_env, fp0, fp1, fp2);
10045             gen_store_fpr64(ctx, fp2, fd);
10046         }
10047         break;
10048     case OPC_RINT_D:
10049         check_insn(ctx, ISA_MIPS_R6);
10050         {
10051             TCGv_i64 fp0 = tcg_temp_new_i64();
10052             gen_load_fpr64(ctx, fp0, fs);
10053             gen_helper_float_rint_d(fp0, tcg_env, fp0);
10054             gen_store_fpr64(ctx, fp0, fd);
10055         }
10056         break;
10057     case OPC_CLASS_D:
10058         check_insn(ctx, ISA_MIPS_R6);
10059         {
10060             TCGv_i64 fp0 = tcg_temp_new_i64();
10061             gen_load_fpr64(ctx, fp0, fs);
10062             gen_helper_float_class_d(fp0, tcg_env, fp0);
10063             gen_store_fpr64(ctx, fp0, fd);
10064         }
10065         break;
10066     case OPC_MIN_D: /* OPC_RECIP2_D */
10067         if (ctx->insn_flags & ISA_MIPS_R6) {
10068             /* OPC_MIN_D */
10069             TCGv_i64 fp0 = tcg_temp_new_i64();
10070             TCGv_i64 fp1 = tcg_temp_new_i64();
10071             gen_load_fpr64(ctx, fp0, fs);
10072             gen_load_fpr64(ctx, fp1, ft);
10073             gen_helper_float_min_d(fp1, tcg_env, fp0, fp1);
10074             gen_store_fpr64(ctx, fp1, fd);
10075         } else {
10076             /* OPC_RECIP2_D */
10077             check_cp1_64bitmode(ctx);
10078             {
10079                 TCGv_i64 fp0 = tcg_temp_new_i64();
10080                 TCGv_i64 fp1 = tcg_temp_new_i64();
10081 
10082                 gen_load_fpr64(ctx, fp0, fs);
10083                 gen_load_fpr64(ctx, fp1, ft);
10084                 gen_helper_float_recip2_d(fp0, tcg_env, fp0, fp1);
10085                 gen_store_fpr64(ctx, fp0, fd);
10086             }
10087         }
10088         break;
10089     case OPC_MINA_D: /* OPC_RECIP1_D */
10090         if (ctx->insn_flags & ISA_MIPS_R6) {
10091             /* OPC_MINA_D */
10092             TCGv_i64 fp0 = tcg_temp_new_i64();
10093             TCGv_i64 fp1 = tcg_temp_new_i64();
10094             gen_load_fpr64(ctx, fp0, fs);
10095             gen_load_fpr64(ctx, fp1, ft);
10096             gen_helper_float_mina_d(fp1, tcg_env, fp0, fp1);
10097             gen_store_fpr64(ctx, fp1, fd);
10098         } else {
10099             /* OPC_RECIP1_D */
10100             check_cp1_64bitmode(ctx);
10101             {
10102                 TCGv_i64 fp0 = tcg_temp_new_i64();
10103 
10104                 gen_load_fpr64(ctx, fp0, fs);
10105                 gen_helper_float_recip1_d(fp0, tcg_env, fp0);
10106                 gen_store_fpr64(ctx, fp0, fd);
10107             }
10108         }
10109         break;
10110     case OPC_MAX_D: /*  OPC_RSQRT1_D */
10111         if (ctx->insn_flags & ISA_MIPS_R6) {
10112             /* OPC_MAX_D */
10113             TCGv_i64 fp0 = tcg_temp_new_i64();
10114             TCGv_i64 fp1 = tcg_temp_new_i64();
10115             gen_load_fpr64(ctx, fp0, fs);
10116             gen_load_fpr64(ctx, fp1, ft);
10117             gen_helper_float_max_d(fp1, tcg_env, fp0, fp1);
10118             gen_store_fpr64(ctx, fp1, fd);
10119         } else {
10120             /* OPC_RSQRT1_D */
10121             check_cp1_64bitmode(ctx);
10122             {
10123                 TCGv_i64 fp0 = tcg_temp_new_i64();
10124 
10125                 gen_load_fpr64(ctx, fp0, fs);
10126                 gen_helper_float_rsqrt1_d(fp0, tcg_env, fp0);
10127                 gen_store_fpr64(ctx, fp0, fd);
10128             }
10129         }
10130         break;
10131     case OPC_MAXA_D: /* OPC_RSQRT2_D */
10132         if (ctx->insn_flags & ISA_MIPS_R6) {
10133             /* OPC_MAXA_D */
10134             TCGv_i64 fp0 = tcg_temp_new_i64();
10135             TCGv_i64 fp1 = tcg_temp_new_i64();
10136             gen_load_fpr64(ctx, fp0, fs);
10137             gen_load_fpr64(ctx, fp1, ft);
10138             gen_helper_float_maxa_d(fp1, tcg_env, fp0, fp1);
10139             gen_store_fpr64(ctx, fp1, fd);
10140         } else {
10141             /* OPC_RSQRT2_D */
10142             check_cp1_64bitmode(ctx);
10143             {
10144                 TCGv_i64 fp0 = tcg_temp_new_i64();
10145                 TCGv_i64 fp1 = tcg_temp_new_i64();
10146 
10147                 gen_load_fpr64(ctx, fp0, fs);
10148                 gen_load_fpr64(ctx, fp1, ft);
10149                 gen_helper_float_rsqrt2_d(fp0, tcg_env, fp0, fp1);
10150                 gen_store_fpr64(ctx, fp0, fd);
10151             }
10152         }
10153         break;
10154     case OPC_CMP_F_D:
10155     case OPC_CMP_UN_D:
10156     case OPC_CMP_EQ_D:
10157     case OPC_CMP_UEQ_D:
10158     case OPC_CMP_OLT_D:
10159     case OPC_CMP_ULT_D:
10160     case OPC_CMP_OLE_D:
10161     case OPC_CMP_ULE_D:
10162     case OPC_CMP_SF_D:
10163     case OPC_CMP_NGLE_D:
10164     case OPC_CMP_SEQ_D:
10165     case OPC_CMP_NGL_D:
10166     case OPC_CMP_LT_D:
10167     case OPC_CMP_NGE_D:
10168     case OPC_CMP_LE_D:
10169     case OPC_CMP_NGT_D:
10170         check_insn_opc_removed(ctx, ISA_MIPS_R6);
10171         if (ctx->opcode & (1 << 6)) {
10172             gen_cmpabs_d(ctx, func - 48, ft, fs, cc);
10173         } else {
10174             gen_cmp_d(ctx, func - 48, ft, fs, cc);
10175         }
10176         break;
10177     case OPC_CVT_S_D:
10178         check_cp1_registers(ctx, fs);
10179         {
10180             TCGv_i32 fp32 = tcg_temp_new_i32();
10181             TCGv_i64 fp64 = tcg_temp_new_i64();
10182 
10183             gen_load_fpr64(ctx, fp64, fs);
10184             gen_helper_float_cvts_d(fp32, tcg_env, fp64);
10185             gen_store_fpr32(ctx, fp32, fd);
10186         }
10187         break;
10188     case OPC_CVT_W_D:
10189         check_cp1_registers(ctx, fs);
10190         {
10191             TCGv_i32 fp32 = tcg_temp_new_i32();
10192             TCGv_i64 fp64 = tcg_temp_new_i64();
10193 
10194             gen_load_fpr64(ctx, fp64, fs);
10195             if (ctx->nan2008) {
10196                 gen_helper_float_cvt_2008_w_d(fp32, tcg_env, fp64);
10197             } else {
10198                 gen_helper_float_cvt_w_d(fp32, tcg_env, fp64);
10199             }
10200             gen_store_fpr32(ctx, fp32, fd);
10201         }
10202         break;
10203     case OPC_CVT_L_D:
10204         check_cp1_64bitmode(ctx);
10205         {
10206             TCGv_i64 fp0 = tcg_temp_new_i64();
10207 
10208             gen_load_fpr64(ctx, fp0, fs);
10209             if (ctx->nan2008) {
10210                 gen_helper_float_cvt_2008_l_d(fp0, tcg_env, fp0);
10211             } else {
10212                 gen_helper_float_cvt_l_d(fp0, tcg_env, fp0);
10213             }
10214             gen_store_fpr64(ctx, fp0, fd);
10215         }
10216         break;
10217     case OPC_CVT_S_W:
10218         {
10219             TCGv_i32 fp0 = tcg_temp_new_i32();
10220 
10221             gen_load_fpr32(ctx, fp0, fs);
10222             gen_helper_float_cvts_w(fp0, tcg_env, fp0);
10223             gen_store_fpr32(ctx, fp0, fd);
10224         }
10225         break;
10226     case OPC_CVT_D_W:
10227         check_cp1_registers(ctx, fd);
10228         {
10229             TCGv_i32 fp32 = tcg_temp_new_i32();
10230             TCGv_i64 fp64 = tcg_temp_new_i64();
10231 
10232             gen_load_fpr32(ctx, fp32, fs);
10233             gen_helper_float_cvtd_w(fp64, tcg_env, fp32);
10234             gen_store_fpr64(ctx, fp64, fd);
10235         }
10236         break;
10237     case OPC_CVT_S_L:
10238         check_cp1_64bitmode(ctx);
10239         {
10240             TCGv_i32 fp32 = tcg_temp_new_i32();
10241             TCGv_i64 fp64 = tcg_temp_new_i64();
10242 
10243             gen_load_fpr64(ctx, fp64, fs);
10244             gen_helper_float_cvts_l(fp32, tcg_env, fp64);
10245             gen_store_fpr32(ctx, fp32, fd);
10246         }
10247         break;
10248     case OPC_CVT_D_L:
10249         check_cp1_64bitmode(ctx);
10250         {
10251             TCGv_i64 fp0 = tcg_temp_new_i64();
10252 
10253             gen_load_fpr64(ctx, fp0, fs);
10254             gen_helper_float_cvtd_l(fp0, tcg_env, fp0);
10255             gen_store_fpr64(ctx, fp0, fd);
10256         }
10257         break;
10258     case OPC_CVT_PS_PW:
10259         check_ps(ctx);
10260         {
10261             TCGv_i64 fp0 = tcg_temp_new_i64();
10262 
10263             gen_load_fpr64(ctx, fp0, fs);
10264             gen_helper_float_cvtps_pw(fp0, tcg_env, fp0);
10265             gen_store_fpr64(ctx, fp0, fd);
10266         }
10267         break;
10268     case OPC_ADD_PS:
10269         check_ps(ctx);
10270         {
10271             TCGv_i64 fp0 = tcg_temp_new_i64();
10272             TCGv_i64 fp1 = tcg_temp_new_i64();
10273 
10274             gen_load_fpr64(ctx, fp0, fs);
10275             gen_load_fpr64(ctx, fp1, ft);
10276             gen_helper_float_add_ps(fp0, tcg_env, fp0, fp1);
10277             gen_store_fpr64(ctx, fp0, fd);
10278         }
10279         break;
10280     case OPC_SUB_PS:
10281         check_ps(ctx);
10282         {
10283             TCGv_i64 fp0 = tcg_temp_new_i64();
10284             TCGv_i64 fp1 = tcg_temp_new_i64();
10285 
10286             gen_load_fpr64(ctx, fp0, fs);
10287             gen_load_fpr64(ctx, fp1, ft);
10288             gen_helper_float_sub_ps(fp0, tcg_env, fp0, fp1);
10289             gen_store_fpr64(ctx, fp0, fd);
10290         }
10291         break;
10292     case OPC_MUL_PS:
10293         check_ps(ctx);
10294         {
10295             TCGv_i64 fp0 = tcg_temp_new_i64();
10296             TCGv_i64 fp1 = tcg_temp_new_i64();
10297 
10298             gen_load_fpr64(ctx, fp0, fs);
10299             gen_load_fpr64(ctx, fp1, ft);
10300             gen_helper_float_mul_ps(fp0, tcg_env, fp0, fp1);
10301             gen_store_fpr64(ctx, fp0, fd);
10302         }
10303         break;
10304     case OPC_ABS_PS:
10305         check_ps(ctx);
10306         {
10307             TCGv_i64 fp0 = tcg_temp_new_i64();
10308 
10309             gen_load_fpr64(ctx, fp0, fs);
10310             gen_helper_float_abs_ps(fp0, fp0);
10311             gen_store_fpr64(ctx, fp0, fd);
10312         }
10313         break;
10314     case OPC_MOV_PS:
10315         check_ps(ctx);
10316         {
10317             TCGv_i64 fp0 = tcg_temp_new_i64();
10318 
10319             gen_load_fpr64(ctx, fp0, fs);
10320             gen_store_fpr64(ctx, fp0, fd);
10321         }
10322         break;
10323     case OPC_NEG_PS:
10324         check_ps(ctx);
10325         {
10326             TCGv_i64 fp0 = tcg_temp_new_i64();
10327 
10328             gen_load_fpr64(ctx, fp0, fs);
10329             gen_helper_float_chs_ps(fp0, fp0);
10330             gen_store_fpr64(ctx, fp0, fd);
10331         }
10332         break;
10333     case OPC_MOVCF_PS:
10334         check_ps(ctx);
10335         gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10336         break;
10337     case OPC_MOVZ_PS:
10338         check_ps(ctx);
10339         {
10340             TCGLabel *l1 = gen_new_label();
10341             TCGv_i64 fp0;
10342 
10343             if (ft != 0) {
10344                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10345             }
10346             fp0 = tcg_temp_new_i64();
10347             gen_load_fpr64(ctx, fp0, fs);
10348             gen_store_fpr64(ctx, fp0, fd);
10349             gen_set_label(l1);
10350         }
10351         break;
10352     case OPC_MOVN_PS:
10353         check_ps(ctx);
10354         {
10355             TCGLabel *l1 = gen_new_label();
10356             TCGv_i64 fp0;
10357 
10358             if (ft != 0) {
10359                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10360                 fp0 = tcg_temp_new_i64();
10361                 gen_load_fpr64(ctx, fp0, fs);
10362                 gen_store_fpr64(ctx, fp0, fd);
10363                 gen_set_label(l1);
10364             }
10365         }
10366         break;
10367     case OPC_ADDR_PS:
10368         check_ps(ctx);
10369         {
10370             TCGv_i64 fp0 = tcg_temp_new_i64();
10371             TCGv_i64 fp1 = tcg_temp_new_i64();
10372 
10373             gen_load_fpr64(ctx, fp0, ft);
10374             gen_load_fpr64(ctx, fp1, fs);
10375             gen_helper_float_addr_ps(fp0, tcg_env, fp0, fp1);
10376             gen_store_fpr64(ctx, fp0, fd);
10377         }
10378         break;
10379     case OPC_MULR_PS:
10380         check_ps(ctx);
10381         {
10382             TCGv_i64 fp0 = tcg_temp_new_i64();
10383             TCGv_i64 fp1 = tcg_temp_new_i64();
10384 
10385             gen_load_fpr64(ctx, fp0, ft);
10386             gen_load_fpr64(ctx, fp1, fs);
10387             gen_helper_float_mulr_ps(fp0, tcg_env, fp0, fp1);
10388             gen_store_fpr64(ctx, fp0, fd);
10389         }
10390         break;
10391     case OPC_RECIP2_PS:
10392         check_ps(ctx);
10393         {
10394             TCGv_i64 fp0 = tcg_temp_new_i64();
10395             TCGv_i64 fp1 = tcg_temp_new_i64();
10396 
10397             gen_load_fpr64(ctx, fp0, fs);
10398             gen_load_fpr64(ctx, fp1, ft);
10399             gen_helper_float_recip2_ps(fp0, tcg_env, fp0, fp1);
10400             gen_store_fpr64(ctx, fp0, fd);
10401         }
10402         break;
10403     case OPC_RECIP1_PS:
10404         check_ps(ctx);
10405         {
10406             TCGv_i64 fp0 = tcg_temp_new_i64();
10407 
10408             gen_load_fpr64(ctx, fp0, fs);
10409             gen_helper_float_recip1_ps(fp0, tcg_env, fp0);
10410             gen_store_fpr64(ctx, fp0, fd);
10411         }
10412         break;
10413     case OPC_RSQRT1_PS:
10414         check_ps(ctx);
10415         {
10416             TCGv_i64 fp0 = tcg_temp_new_i64();
10417 
10418             gen_load_fpr64(ctx, fp0, fs);
10419             gen_helper_float_rsqrt1_ps(fp0, tcg_env, fp0);
10420             gen_store_fpr64(ctx, fp0, fd);
10421         }
10422         break;
10423     case OPC_RSQRT2_PS:
10424         check_ps(ctx);
10425         {
10426             TCGv_i64 fp0 = tcg_temp_new_i64();
10427             TCGv_i64 fp1 = tcg_temp_new_i64();
10428 
10429             gen_load_fpr64(ctx, fp0, fs);
10430             gen_load_fpr64(ctx, fp1, ft);
10431             gen_helper_float_rsqrt2_ps(fp0, tcg_env, fp0, fp1);
10432             gen_store_fpr64(ctx, fp0, fd);
10433         }
10434         break;
10435     case OPC_CVT_S_PU:
10436         check_cp1_64bitmode(ctx);
10437         {
10438             TCGv_i32 fp0 = tcg_temp_new_i32();
10439 
10440             gen_load_fpr32h(ctx, fp0, fs);
10441             gen_helper_float_cvts_pu(fp0, tcg_env, fp0);
10442             gen_store_fpr32(ctx, fp0, fd);
10443         }
10444         break;
10445     case OPC_CVT_PW_PS:
10446         check_ps(ctx);
10447         {
10448             TCGv_i64 fp0 = tcg_temp_new_i64();
10449 
10450             gen_load_fpr64(ctx, fp0, fs);
10451             gen_helper_float_cvtpw_ps(fp0, tcg_env, fp0);
10452             gen_store_fpr64(ctx, fp0, fd);
10453         }
10454         break;
10455     case OPC_CVT_S_PL:
10456         check_cp1_64bitmode(ctx);
10457         {
10458             TCGv_i32 fp0 = tcg_temp_new_i32();
10459 
10460             gen_load_fpr32(ctx, fp0, fs);
10461             gen_helper_float_cvts_pl(fp0, tcg_env, fp0);
10462             gen_store_fpr32(ctx, fp0, fd);
10463         }
10464         break;
10465     case OPC_PLL_PS:
10466         check_ps(ctx);
10467         {
10468             TCGv_i32 fp0 = tcg_temp_new_i32();
10469             TCGv_i32 fp1 = tcg_temp_new_i32();
10470 
10471             gen_load_fpr32(ctx, fp0, fs);
10472             gen_load_fpr32(ctx, fp1, ft);
10473             gen_store_fpr32h(ctx, fp0, fd);
10474             gen_store_fpr32(ctx, fp1, fd);
10475         }
10476         break;
10477     case OPC_PLU_PS:
10478         check_ps(ctx);
10479         {
10480             TCGv_i32 fp0 = tcg_temp_new_i32();
10481             TCGv_i32 fp1 = tcg_temp_new_i32();
10482 
10483             gen_load_fpr32(ctx, fp0, fs);
10484             gen_load_fpr32h(ctx, fp1, ft);
10485             gen_store_fpr32(ctx, fp1, fd);
10486             gen_store_fpr32h(ctx, fp0, fd);
10487         }
10488         break;
10489     case OPC_PUL_PS:
10490         check_ps(ctx);
10491         {
10492             TCGv_i32 fp0 = tcg_temp_new_i32();
10493             TCGv_i32 fp1 = tcg_temp_new_i32();
10494 
10495             gen_load_fpr32h(ctx, fp0, fs);
10496             gen_load_fpr32(ctx, fp1, ft);
10497             gen_store_fpr32(ctx, fp1, fd);
10498             gen_store_fpr32h(ctx, fp0, fd);
10499         }
10500         break;
10501     case OPC_PUU_PS:
10502         check_ps(ctx);
10503         {
10504             TCGv_i32 fp0 = tcg_temp_new_i32();
10505             TCGv_i32 fp1 = tcg_temp_new_i32();
10506 
10507             gen_load_fpr32h(ctx, fp0, fs);
10508             gen_load_fpr32h(ctx, fp1, ft);
10509             gen_store_fpr32(ctx, fp1, fd);
10510             gen_store_fpr32h(ctx, fp0, fd);
10511         }
10512         break;
10513     case OPC_CMP_F_PS:
10514     case OPC_CMP_UN_PS:
10515     case OPC_CMP_EQ_PS:
10516     case OPC_CMP_UEQ_PS:
10517     case OPC_CMP_OLT_PS:
10518     case OPC_CMP_ULT_PS:
10519     case OPC_CMP_OLE_PS:
10520     case OPC_CMP_ULE_PS:
10521     case OPC_CMP_SF_PS:
10522     case OPC_CMP_NGLE_PS:
10523     case OPC_CMP_SEQ_PS:
10524     case OPC_CMP_NGL_PS:
10525     case OPC_CMP_LT_PS:
10526     case OPC_CMP_NGE_PS:
10527     case OPC_CMP_LE_PS:
10528     case OPC_CMP_NGT_PS:
10529         if (ctx->opcode & (1 << 6)) {
10530             gen_cmpabs_ps(ctx, func - 48, ft, fs, cc);
10531         } else {
10532             gen_cmp_ps(ctx, func - 48, ft, fs, cc);
10533         }
10534         break;
10535     default:
10536         MIPS_INVAL("farith");
10537         gen_reserved_instruction(ctx);
10538         return;
10539     }
10540 }
10541 
10542 /* Coprocessor 3 (FPU) */
gen_flt3_ldst(DisasContext * ctx,uint32_t opc,int fd,int fs,int base,int index)10543 static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc,
10544                           int fd, int fs, int base, int index)
10545 {
10546     TCGv t0 = tcg_temp_new();
10547 
10548     if (base == 0) {
10549         gen_load_gpr(t0, index);
10550     } else if (index == 0) {
10551         gen_load_gpr(t0, base);
10552     } else {
10553         gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
10554     }
10555     /*
10556      * Don't do NOP if destination is zero: we must perform the actual
10557      * memory access.
10558      */
10559     switch (opc) {
10560     case OPC_LWXC1:
10561         check_cop1x(ctx);
10562         {
10563             TCGv_i32 fp0 = tcg_temp_new_i32();
10564 
10565             tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL);
10566             tcg_gen_trunc_tl_i32(fp0, t0);
10567             gen_store_fpr32(ctx, fp0, fd);
10568         }
10569         break;
10570     case OPC_LDXC1:
10571         check_cop1x(ctx);
10572         check_cp1_registers(ctx, fd);
10573         {
10574             TCGv_i64 fp0 = tcg_temp_new_i64();
10575             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ);
10576             gen_store_fpr64(ctx, fp0, fd);
10577         }
10578         break;
10579     case OPC_LUXC1:
10580         check_cp1_64bitmode(ctx);
10581         tcg_gen_andi_tl(t0, t0, ~0x7);
10582         {
10583             TCGv_i64 fp0 = tcg_temp_new_i64();
10584 
10585             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ);
10586             gen_store_fpr64(ctx, fp0, fd);
10587         }
10588         break;
10589     case OPC_SWXC1:
10590         check_cop1x(ctx);
10591         {
10592             TCGv_i32 fp0 = tcg_temp_new_i32();
10593             gen_load_fpr32(ctx, fp0, fs);
10594             tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL);
10595         }
10596         break;
10597     case OPC_SDXC1:
10598         check_cop1x(ctx);
10599         check_cp1_registers(ctx, fs);
10600         {
10601             TCGv_i64 fp0 = tcg_temp_new_i64();
10602             gen_load_fpr64(ctx, fp0, fs);
10603             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ);
10604         }
10605         break;
10606     case OPC_SUXC1:
10607         check_cp1_64bitmode(ctx);
10608         tcg_gen_andi_tl(t0, t0, ~0x7);
10609         {
10610             TCGv_i64 fp0 = tcg_temp_new_i64();
10611             gen_load_fpr64(ctx, fp0, fs);
10612             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ);
10613         }
10614         break;
10615     }
10616 }
10617 
gen_flt3_arith(DisasContext * ctx,uint32_t opc,int fd,int fr,int fs,int ft)10618 static void gen_flt3_arith(DisasContext *ctx, uint32_t opc,
10619                            int fd, int fr, int fs, int ft)
10620 {
10621     switch (opc) {
10622     case OPC_ALNV_PS:
10623         check_ps(ctx);
10624         {
10625             TCGv t0 = tcg_temp_new();
10626             TCGv_i32 fp = tcg_temp_new_i32();
10627             TCGv_i32 fph = tcg_temp_new_i32();
10628             TCGLabel *l1 = gen_new_label();
10629             TCGLabel *l2 = gen_new_label();
10630 
10631             gen_load_gpr(t0, fr);
10632             tcg_gen_andi_tl(t0, t0, 0x7);
10633 
10634             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
10635             gen_load_fpr32(ctx, fp, fs);
10636             gen_load_fpr32h(ctx, fph, fs);
10637             gen_store_fpr32(ctx, fp, fd);
10638             gen_store_fpr32h(ctx, fph, fd);
10639             tcg_gen_br(l2);
10640             gen_set_label(l1);
10641             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
10642             if (disas_is_bigendian(ctx)) {
10643                 gen_load_fpr32(ctx, fp, fs);
10644                 gen_load_fpr32h(ctx, fph, ft);
10645                 gen_store_fpr32h(ctx, fp, fd);
10646                 gen_store_fpr32(ctx, fph, fd);
10647             } else {
10648                 gen_load_fpr32h(ctx, fph, fs);
10649                 gen_load_fpr32(ctx, fp, ft);
10650                 gen_store_fpr32(ctx, fph, fd);
10651                 gen_store_fpr32h(ctx, fp, fd);
10652             }
10653             gen_set_label(l2);
10654         }
10655         break;
10656     case OPC_MADD_S:
10657         check_cop1x(ctx);
10658         {
10659             TCGv_i32 fp0 = tcg_temp_new_i32();
10660             TCGv_i32 fp1 = tcg_temp_new_i32();
10661             TCGv_i32 fp2 = tcg_temp_new_i32();
10662 
10663             gen_load_fpr32(ctx, fp0, fs);
10664             gen_load_fpr32(ctx, fp1, ft);
10665             gen_load_fpr32(ctx, fp2, fr);
10666             gen_helper_float_madd_s(fp2, tcg_env, fp0, fp1, fp2);
10667             gen_store_fpr32(ctx, fp2, fd);
10668         }
10669         break;
10670     case OPC_MADD_D:
10671         check_cop1x(ctx);
10672         check_cp1_registers(ctx, fd | fs | ft | fr);
10673         {
10674             TCGv_i64 fp0 = tcg_temp_new_i64();
10675             TCGv_i64 fp1 = tcg_temp_new_i64();
10676             TCGv_i64 fp2 = tcg_temp_new_i64();
10677 
10678             gen_load_fpr64(ctx, fp0, fs);
10679             gen_load_fpr64(ctx, fp1, ft);
10680             gen_load_fpr64(ctx, fp2, fr);
10681             gen_helper_float_madd_d(fp2, tcg_env, fp0, fp1, fp2);
10682             gen_store_fpr64(ctx, fp2, fd);
10683         }
10684         break;
10685     case OPC_MADD_PS:
10686         check_ps(ctx);
10687         {
10688             TCGv_i64 fp0 = tcg_temp_new_i64();
10689             TCGv_i64 fp1 = tcg_temp_new_i64();
10690             TCGv_i64 fp2 = tcg_temp_new_i64();
10691 
10692             gen_load_fpr64(ctx, fp0, fs);
10693             gen_load_fpr64(ctx, fp1, ft);
10694             gen_load_fpr64(ctx, fp2, fr);
10695             gen_helper_float_madd_ps(fp2, tcg_env, fp0, fp1, fp2);
10696             gen_store_fpr64(ctx, fp2, fd);
10697         }
10698         break;
10699     case OPC_MSUB_S:
10700         check_cop1x(ctx);
10701         {
10702             TCGv_i32 fp0 = tcg_temp_new_i32();
10703             TCGv_i32 fp1 = tcg_temp_new_i32();
10704             TCGv_i32 fp2 = tcg_temp_new_i32();
10705 
10706             gen_load_fpr32(ctx, fp0, fs);
10707             gen_load_fpr32(ctx, fp1, ft);
10708             gen_load_fpr32(ctx, fp2, fr);
10709             gen_helper_float_msub_s(fp2, tcg_env, fp0, fp1, fp2);
10710             gen_store_fpr32(ctx, fp2, fd);
10711         }
10712         break;
10713     case OPC_MSUB_D:
10714         check_cop1x(ctx);
10715         check_cp1_registers(ctx, fd | fs | ft | fr);
10716         {
10717             TCGv_i64 fp0 = tcg_temp_new_i64();
10718             TCGv_i64 fp1 = tcg_temp_new_i64();
10719             TCGv_i64 fp2 = tcg_temp_new_i64();
10720 
10721             gen_load_fpr64(ctx, fp0, fs);
10722             gen_load_fpr64(ctx, fp1, ft);
10723             gen_load_fpr64(ctx, fp2, fr);
10724             gen_helper_float_msub_d(fp2, tcg_env, fp0, fp1, fp2);
10725             gen_store_fpr64(ctx, fp2, fd);
10726         }
10727         break;
10728     case OPC_MSUB_PS:
10729         check_ps(ctx);
10730         {
10731             TCGv_i64 fp0 = tcg_temp_new_i64();
10732             TCGv_i64 fp1 = tcg_temp_new_i64();
10733             TCGv_i64 fp2 = tcg_temp_new_i64();
10734 
10735             gen_load_fpr64(ctx, fp0, fs);
10736             gen_load_fpr64(ctx, fp1, ft);
10737             gen_load_fpr64(ctx, fp2, fr);
10738             gen_helper_float_msub_ps(fp2, tcg_env, fp0, fp1, fp2);
10739             gen_store_fpr64(ctx, fp2, fd);
10740         }
10741         break;
10742     case OPC_NMADD_S:
10743         check_cop1x(ctx);
10744         {
10745             TCGv_i32 fp0 = tcg_temp_new_i32();
10746             TCGv_i32 fp1 = tcg_temp_new_i32();
10747             TCGv_i32 fp2 = tcg_temp_new_i32();
10748 
10749             gen_load_fpr32(ctx, fp0, fs);
10750             gen_load_fpr32(ctx, fp1, ft);
10751             gen_load_fpr32(ctx, fp2, fr);
10752             gen_helper_float_nmadd_s(fp2, tcg_env, fp0, fp1, fp2);
10753             gen_store_fpr32(ctx, fp2, fd);
10754         }
10755         break;
10756     case OPC_NMADD_D:
10757         check_cop1x(ctx);
10758         check_cp1_registers(ctx, fd | fs | ft | fr);
10759         {
10760             TCGv_i64 fp0 = tcg_temp_new_i64();
10761             TCGv_i64 fp1 = tcg_temp_new_i64();
10762             TCGv_i64 fp2 = tcg_temp_new_i64();
10763 
10764             gen_load_fpr64(ctx, fp0, fs);
10765             gen_load_fpr64(ctx, fp1, ft);
10766             gen_load_fpr64(ctx, fp2, fr);
10767             gen_helper_float_nmadd_d(fp2, tcg_env, fp0, fp1, fp2);
10768             gen_store_fpr64(ctx, fp2, fd);
10769         }
10770         break;
10771     case OPC_NMADD_PS:
10772         check_ps(ctx);
10773         {
10774             TCGv_i64 fp0 = tcg_temp_new_i64();
10775             TCGv_i64 fp1 = tcg_temp_new_i64();
10776             TCGv_i64 fp2 = tcg_temp_new_i64();
10777 
10778             gen_load_fpr64(ctx, fp0, fs);
10779             gen_load_fpr64(ctx, fp1, ft);
10780             gen_load_fpr64(ctx, fp2, fr);
10781             gen_helper_float_nmadd_ps(fp2, tcg_env, fp0, fp1, fp2);
10782             gen_store_fpr64(ctx, fp2, fd);
10783         }
10784         break;
10785     case OPC_NMSUB_S:
10786         check_cop1x(ctx);
10787         {
10788             TCGv_i32 fp0 = tcg_temp_new_i32();
10789             TCGv_i32 fp1 = tcg_temp_new_i32();
10790             TCGv_i32 fp2 = tcg_temp_new_i32();
10791 
10792             gen_load_fpr32(ctx, fp0, fs);
10793             gen_load_fpr32(ctx, fp1, ft);
10794             gen_load_fpr32(ctx, fp2, fr);
10795             gen_helper_float_nmsub_s(fp2, tcg_env, fp0, fp1, fp2);
10796             gen_store_fpr32(ctx, fp2, fd);
10797         }
10798         break;
10799     case OPC_NMSUB_D:
10800         check_cop1x(ctx);
10801         check_cp1_registers(ctx, fd | fs | ft | fr);
10802         {
10803             TCGv_i64 fp0 = tcg_temp_new_i64();
10804             TCGv_i64 fp1 = tcg_temp_new_i64();
10805             TCGv_i64 fp2 = tcg_temp_new_i64();
10806 
10807             gen_load_fpr64(ctx, fp0, fs);
10808             gen_load_fpr64(ctx, fp1, ft);
10809             gen_load_fpr64(ctx, fp2, fr);
10810             gen_helper_float_nmsub_d(fp2, tcg_env, fp0, fp1, fp2);
10811             gen_store_fpr64(ctx, fp2, fd);
10812         }
10813         break;
10814     case OPC_NMSUB_PS:
10815         check_ps(ctx);
10816         {
10817             TCGv_i64 fp0 = tcg_temp_new_i64();
10818             TCGv_i64 fp1 = tcg_temp_new_i64();
10819             TCGv_i64 fp2 = tcg_temp_new_i64();
10820 
10821             gen_load_fpr64(ctx, fp0, fs);
10822             gen_load_fpr64(ctx, fp1, ft);
10823             gen_load_fpr64(ctx, fp2, fr);
10824             gen_helper_float_nmsub_ps(fp2, tcg_env, fp0, fp1, fp2);
10825             gen_store_fpr64(ctx, fp2, fd);
10826         }
10827         break;
10828     default:
10829         MIPS_INVAL("flt3_arith");
10830         gen_reserved_instruction(ctx);
10831         return;
10832     }
10833 }
10834 
gen_rdhwr(DisasContext * ctx,int rt,int rd,int sel)10835 void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
10836 {
10837     TCGv t0;
10838 
10839 #if !defined(CONFIG_USER_ONLY)
10840     /*
10841      * The Linux kernel will emulate rdhwr if it's not supported natively.
10842      * Therefore only check the ISA in system mode.
10843      */
10844     check_insn(ctx, ISA_MIPS_R2);
10845 #endif
10846     t0 = tcg_temp_new();
10847 
10848     switch (rd) {
10849     case 0:
10850         gen_helper_rdhwr_cpunum(t0, tcg_env);
10851         gen_store_gpr(t0, rt);
10852         break;
10853     case 1:
10854         gen_helper_rdhwr_synci_step(t0, tcg_env);
10855         gen_store_gpr(t0, rt);
10856         break;
10857     case 2:
10858         translator_io_start(&ctx->base);
10859         gen_helper_rdhwr_cc(t0, tcg_env);
10860         gen_store_gpr(t0, rt);
10861         /*
10862          * Break the TB to be able to take timer interrupts immediately
10863          * after reading count. DISAS_STOP isn't sufficient, we need to ensure
10864          * we break completely out of translated code.
10865          */
10866         gen_save_pc(ctx->base.pc_next + 4);
10867         ctx->base.is_jmp = DISAS_EXIT;
10868         break;
10869     case 3:
10870         gen_helper_rdhwr_ccres(t0, tcg_env);
10871         gen_store_gpr(t0, rt);
10872         break;
10873     case 4:
10874         check_insn(ctx, ISA_MIPS_R6);
10875         if (sel != 0) {
10876             /*
10877              * Performance counter registers are not implemented other than
10878              * control register 0.
10879              */
10880             generate_exception(ctx, EXCP_RI);
10881         }
10882         gen_helper_rdhwr_performance(t0, tcg_env);
10883         gen_store_gpr(t0, rt);
10884         break;
10885     case 5:
10886         check_insn(ctx, ISA_MIPS_R6);
10887         gen_helper_rdhwr_xnp(t0, tcg_env);
10888         gen_store_gpr(t0, rt);
10889         break;
10890     case 29:
10891 #if defined(CONFIG_USER_ONLY)
10892         tcg_gen_ld_tl(t0, tcg_env,
10893                       offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10894         gen_store_gpr(t0, rt);
10895         break;
10896 #else
10897         if ((ctx->hflags & MIPS_HFLAG_CP0) ||
10898             (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
10899             tcg_gen_ld_tl(t0, tcg_env,
10900                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10901             gen_store_gpr(t0, rt);
10902         } else {
10903             gen_reserved_instruction(ctx);
10904         }
10905         break;
10906 #endif
10907     default:            /* Invalid */
10908         MIPS_INVAL("rdhwr");
10909         gen_reserved_instruction(ctx);
10910         break;
10911     }
10912 }
10913 
clear_branch_hflags(DisasContext * ctx)10914 static inline void clear_branch_hflags(DisasContext *ctx)
10915 {
10916     ctx->hflags &= ~MIPS_HFLAG_BMASK;
10917     if (ctx->base.is_jmp == DISAS_NEXT) {
10918         save_cpu_state(ctx, 0);
10919     } else {
10920         /*
10921          * It is not safe to save ctx->hflags as hflags may be changed
10922          * in execution time by the instruction in delay / forbidden slot.
10923          */
10924         tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
10925     }
10926 }
10927 
gen_branch(DisasContext * ctx,int insn_bytes)10928 static void gen_branch(DisasContext *ctx, int insn_bytes)
10929 {
10930     if (ctx->hflags & MIPS_HFLAG_BMASK) {
10931         int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
10932         /* Branches completion */
10933         clear_branch_hflags(ctx);
10934         ctx->base.is_jmp = DISAS_NORETURN;
10935         switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
10936         case MIPS_HFLAG_FBNSLOT:
10937             gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
10938             break;
10939         case MIPS_HFLAG_B:
10940             /* unconditional branch */
10941             if (proc_hflags & MIPS_HFLAG_BX) {
10942                 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
10943             }
10944             gen_goto_tb(ctx, 0, ctx->btarget);
10945             break;
10946         case MIPS_HFLAG_BL:
10947             /* blikely taken case */
10948             gen_goto_tb(ctx, 0, ctx->btarget);
10949             break;
10950         case MIPS_HFLAG_BC:
10951             /* Conditional branch */
10952             {
10953                 TCGLabel *l1 = gen_new_label();
10954 
10955                 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
10956                 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
10957                 gen_set_label(l1);
10958                 gen_goto_tb(ctx, 0, ctx->btarget);
10959             }
10960             break;
10961         case MIPS_HFLAG_BR:
10962             /* unconditional branch to register */
10963             if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
10964                 TCGv t0 = tcg_temp_new();
10965                 TCGv_i32 t1 = tcg_temp_new_i32();
10966 
10967                 tcg_gen_andi_tl(t0, btarget, 0x1);
10968                 tcg_gen_trunc_tl_i32(t1, t0);
10969                 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
10970                 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
10971                 tcg_gen_or_i32(hflags, hflags, t1);
10972 
10973                 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
10974             } else {
10975                 tcg_gen_mov_tl(cpu_PC, btarget);
10976             }
10977             tcg_gen_lookup_and_goto_ptr();
10978             break;
10979         default:
10980             LOG_DISAS("unknown branch 0x%x\n", proc_hflags);
10981             gen_reserved_instruction(ctx);
10982         }
10983     }
10984 }
10985 
10986 /* Compact Branches */
gen_compute_compact_branch(DisasContext * ctx,uint32_t opc,int rs,int rt,int32_t offset)10987 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
10988                                        int rs, int rt, int32_t offset)
10989 {
10990     int bcond_compute = 0;
10991     TCGv t0 = tcg_temp_new();
10992     TCGv t1 = tcg_temp_new();
10993     int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
10994 
10995     if (ctx->hflags & MIPS_HFLAG_BMASK) {
10996 #ifdef MIPS_DEBUG_DISAS
10997         LOG_DISAS("Branch in delay / forbidden slot at PC 0x%016"
10998                   VADDR_PRIx "\n", ctx->base.pc_next);
10999 #endif
11000         gen_reserved_instruction(ctx);
11001         return;
11002     }
11003 
11004     /* Load needed operands and calculate btarget */
11005     switch (opc) {
11006     /* compact branch */
11007     case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11008     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11009         gen_load_gpr(t0, rs);
11010         gen_load_gpr(t1, rt);
11011         bcond_compute = 1;
11012         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11013         if (rs <= rt && rs == 0) {
11014             /* OPC_BEQZALC, OPC_BNEZALC */
11015             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11016         }
11017         break;
11018     case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11019     case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11020         gen_load_gpr(t0, rs);
11021         gen_load_gpr(t1, rt);
11022         bcond_compute = 1;
11023         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11024         break;
11025     case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11026     case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11027         if (rs == 0 || rs == rt) {
11028             /* OPC_BLEZALC, OPC_BGEZALC */
11029             /* OPC_BGTZALC, OPC_BLTZALC */
11030             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11031         }
11032         gen_load_gpr(t0, rs);
11033         gen_load_gpr(t1, rt);
11034         bcond_compute = 1;
11035         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11036         break;
11037     case OPC_BC:
11038     case OPC_BALC:
11039         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11040         break;
11041     case OPC_BEQZC:
11042     case OPC_BNEZC:
11043         if (rs != 0) {
11044             /* OPC_BEQZC, OPC_BNEZC */
11045             gen_load_gpr(t0, rs);
11046             bcond_compute = 1;
11047             ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11048         } else {
11049             /* OPC_JIC, OPC_JIALC */
11050             TCGv tbase = tcg_temp_new();
11051 
11052             gen_load_gpr(tbase, rt);
11053             gen_op_addr_addi(ctx, btarget, tbase, offset);
11054         }
11055         break;
11056     default:
11057         MIPS_INVAL("Compact branch/jump");
11058         gen_reserved_instruction(ctx);
11059         return;
11060     }
11061 
11062     if (bcond_compute == 0) {
11063         /* Unconditional compact branch */
11064         switch (opc) {
11065         case OPC_JIALC:
11066             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11067             /* Fallthrough */
11068         case OPC_JIC:
11069             ctx->hflags |= MIPS_HFLAG_BR;
11070             break;
11071         case OPC_BALC:
11072             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11073             /* Fallthrough */
11074         case OPC_BC:
11075             ctx->hflags |= MIPS_HFLAG_B;
11076             break;
11077         default:
11078             MIPS_INVAL("Compact branch/jump");
11079             gen_reserved_instruction(ctx);
11080             return;
11081         }
11082 
11083         /* Generating branch here as compact branches don't have delay slot */
11084         gen_branch(ctx, 4);
11085     } else {
11086         /* Conditional compact branch */
11087         TCGLabel *fs = gen_new_label();
11088         save_cpu_state(ctx, 0);
11089 
11090         switch (opc) {
11091         case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11092             if (rs == 0 && rt != 0) {
11093                 /* OPC_BLEZALC */
11094                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11095             } else if (rs != 0 && rt != 0 && rs == rt) {
11096                 /* OPC_BGEZALC */
11097                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11098             } else {
11099                 /* OPC_BGEUC */
11100                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
11101             }
11102             break;
11103         case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11104             if (rs == 0 && rt != 0) {
11105                 /* OPC_BGTZALC */
11106                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11107             } else if (rs != 0 && rt != 0 && rs == rt) {
11108                 /* OPC_BLTZALC */
11109                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11110             } else {
11111                 /* OPC_BLTUC */
11112                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
11113             }
11114             break;
11115         case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11116             if (rs == 0 && rt != 0) {
11117                 /* OPC_BLEZC */
11118                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11119             } else if (rs != 0 && rt != 0 && rs == rt) {
11120                 /* OPC_BGEZC */
11121                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11122             } else {
11123                 /* OPC_BGEC */
11124                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
11125             }
11126             break;
11127         case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11128             if (rs == 0 && rt != 0) {
11129                 /* OPC_BGTZC */
11130                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11131             } else if (rs != 0 && rt != 0 && rs == rt) {
11132                 /* OPC_BLTZC */
11133                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11134             } else {
11135                 /* OPC_BLTC */
11136                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
11137             }
11138             break;
11139         case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11140         case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11141             if (rs >= rt) {
11142                 /* OPC_BOVC, OPC_BNVC */
11143                 TCGv t2 = tcg_temp_new();
11144                 TCGv t3 = tcg_temp_new();
11145                 TCGv t4 = tcg_temp_new();
11146                 TCGv input_overflow = tcg_temp_new();
11147 
11148                 gen_load_gpr(t0, rs);
11149                 gen_load_gpr(t1, rt);
11150                 tcg_gen_ext32s_tl(t2, t0);
11151                 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
11152                 tcg_gen_ext32s_tl(t3, t1);
11153                 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
11154                 tcg_gen_or_tl(input_overflow, input_overflow, t4);
11155 
11156                 tcg_gen_add_tl(t4, t2, t3);
11157                 tcg_gen_ext32s_tl(t4, t4);
11158                 tcg_gen_xor_tl(t2, t2, t3);
11159                 tcg_gen_xor_tl(t3, t4, t3);
11160                 tcg_gen_andc_tl(t2, t3, t2);
11161                 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
11162                 tcg_gen_or_tl(t4, t4, input_overflow);
11163                 if (opc == OPC_BOVC) {
11164                     /* OPC_BOVC */
11165                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
11166                 } else {
11167                     /* OPC_BNVC */
11168                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
11169                 }
11170             } else if (rs < rt && rs == 0) {
11171                 /* OPC_BEQZALC, OPC_BNEZALC */
11172                 if (opc == OPC_BEQZALC) {
11173                     /* OPC_BEQZALC */
11174                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
11175                 } else {
11176                     /* OPC_BNEZALC */
11177                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
11178                 }
11179             } else {
11180                 /* OPC_BEQC, OPC_BNEC */
11181                 if (opc == OPC_BEQC) {
11182                     /* OPC_BEQC */
11183                     tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
11184                 } else {
11185                     /* OPC_BNEC */
11186                     tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
11187                 }
11188             }
11189             break;
11190         case OPC_BEQZC:
11191             tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
11192             break;
11193         case OPC_BNEZC:
11194             tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
11195             break;
11196         default:
11197             MIPS_INVAL("Compact conditional branch/jump");
11198             gen_reserved_instruction(ctx);
11199             return;
11200         }
11201 
11202         /* Generating branch here as compact branches don't have delay slot */
11203         gen_goto_tb(ctx, 1, ctx->btarget);
11204         gen_set_label(fs);
11205 
11206         ctx->hflags |= MIPS_HFLAG_FBNSLOT;
11207     }
11208 }
11209 
gen_addiupc(DisasContext * ctx,int rx,int imm,int is_64_bit,int extended)11210 void gen_addiupc(DisasContext *ctx, int rx, int imm,
11211                  int is_64_bit, int extended)
11212 {
11213     target_ulong npc;
11214 
11215     if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11216         gen_reserved_instruction(ctx);
11217         return;
11218     }
11219 
11220     npc = pc_relative_pc(ctx) + imm;
11221     if (!is_64_bit) {
11222         npc = (int32_t)npc;
11223     }
11224     tcg_gen_movi_tl(cpu_gpr[rx], npc);
11225 }
11226 
gen_cache_operation(DisasContext * ctx,uint32_t op,int base,int16_t offset)11227 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
11228                                 int16_t offset)
11229 {
11230     TCGv_i32 t0 = tcg_constant_i32(op);
11231     TCGv t1 = tcg_temp_new();
11232     gen_base_offset_addr(ctx, t1, base, offset);
11233     gen_helper_cache(tcg_env, t1, t0);
11234 }
11235 
is_uhi(DisasContext * ctx,int sdbbp_code)11236 static inline bool is_uhi(DisasContext *ctx, int sdbbp_code)
11237 {
11238 #ifdef CONFIG_USER_ONLY
11239     return false;
11240 #else
11241     bool is_user = (ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM;
11242     return semihosting_enabled(is_user) && sdbbp_code == 1;
11243 #endif
11244 }
11245 
gen_ldxs(DisasContext * ctx,int base,int index,int rd)11246 void gen_ldxs(DisasContext *ctx, int base, int index, int rd)
11247 {
11248     TCGv t0 = tcg_temp_new();
11249     TCGv t1 = tcg_temp_new();
11250 
11251     gen_load_gpr(t0, base);
11252 
11253     if (index != 0) {
11254         gen_load_gpr(t1, index);
11255         tcg_gen_shli_tl(t1, t1, 2);
11256         gen_op_addr_add(ctx, t0, t1, t0);
11257     }
11258 
11259     tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL);
11260     gen_store_gpr(t1, rd);
11261 }
11262 
gen_sync(int stype)11263 static void gen_sync(int stype)
11264 {
11265     TCGBar tcg_mo = TCG_BAR_SC;
11266 
11267     switch (stype) {
11268     case 0x4: /* SYNC_WMB */
11269         tcg_mo |= TCG_MO_ST_ST;
11270         break;
11271     case 0x10: /* SYNC_MB */
11272         tcg_mo |= TCG_MO_ALL;
11273         break;
11274     case 0x11: /* SYNC_ACQUIRE */
11275         tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
11276         break;
11277     case 0x12: /* SYNC_RELEASE */
11278         tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
11279         break;
11280     case 0x13: /* SYNC_RMB */
11281         tcg_mo |= TCG_MO_LD_LD;
11282         break;
11283     default:
11284         tcg_mo |= TCG_MO_ALL;
11285         break;
11286     }
11287 
11288     tcg_gen_mb(tcg_mo);
11289 }
11290 
11291 /* ISA extensions (ASEs) */
11292 
11293 /* MIPS16 extension to MIPS32 */
11294 #include "mips16e_translate.c.inc"
11295 
11296 /* microMIPS extension to MIPS32/MIPS64 */
11297 
11298 /*
11299  * Values for microMIPS fmt field.  Variable-width, depending on which
11300  * formats the instruction supports.
11301  */
11302 enum {
11303     FMT_SD_S = 0,
11304     FMT_SD_D = 1,
11305 
11306     FMT_SDPS_S = 0,
11307     FMT_SDPS_D = 1,
11308     FMT_SDPS_PS = 2,
11309 
11310     FMT_SWL_S = 0,
11311     FMT_SWL_W = 1,
11312     FMT_SWL_L = 2,
11313 
11314     FMT_DWL_D = 0,
11315     FMT_DWL_W = 1,
11316     FMT_DWL_L = 2
11317 };
11318 
11319 #include "micromips_translate.c.inc"
11320 
11321 #include "nanomips_translate.c.inc"
11322 
11323 /* MIPSDSP functions. */
11324 
11325 /* Indexed load is not for DSP only */
gen_mips_lx(DisasContext * ctx,uint32_t opc,int rd,int base,int offset)11326 static void gen_mips_lx(DisasContext *ctx, uint32_t opc,
11327                         int rd, int base, int offset)
11328 {
11329     TCGv t0;
11330 
11331     if (!(ctx->insn_flags & INSN_OCTEON)) {
11332         check_dsp(ctx);
11333     }
11334     t0 = tcg_temp_new();
11335 
11336     if (base == 0) {
11337         gen_load_gpr(t0, offset);
11338     } else if (offset == 0) {
11339         gen_load_gpr(t0, base);
11340     } else {
11341         gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
11342     }
11343 
11344     switch (opc) {
11345     case OPC_LBUX:
11346         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
11347         gen_store_gpr(t0, rd);
11348         break;
11349     case OPC_LHX:
11350         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SW);
11351         gen_store_gpr(t0, rd);
11352         break;
11353     case OPC_LWX:
11354         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL);
11355         gen_store_gpr(t0, rd);
11356         break;
11357 #if defined(TARGET_MIPS64)
11358     case OPC_LDX:
11359         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ);
11360         gen_store_gpr(t0, rd);
11361         break;
11362 #endif
11363     }
11364 }
11365 
gen_mipsdsp_arith(DisasContext * ctx,uint32_t op1,uint32_t op2,int ret,int v1,int v2)11366 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
11367                               int ret, int v1, int v2)
11368 {
11369     TCGv v1_t;
11370     TCGv v2_t;
11371 
11372     if (ret == 0) {
11373         /* Treat as NOP. */
11374         return;
11375     }
11376 
11377     v1_t = tcg_temp_new();
11378     v2_t = tcg_temp_new();
11379 
11380     gen_load_gpr(v1_t, v1);
11381     gen_load_gpr(v2_t, v2);
11382 
11383     switch (op1) {
11384     case OPC_ADDUH_QB_DSP:
11385         check_dsp_r2(ctx);
11386         switch (op2) {
11387         case OPC_ADDUH_QB:
11388             gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
11389             break;
11390         case OPC_ADDUH_R_QB:
11391             gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
11392             break;
11393         case OPC_ADDQH_PH:
11394             gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
11395             break;
11396         case OPC_ADDQH_R_PH:
11397             gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
11398             break;
11399         case OPC_ADDQH_W:
11400             gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
11401             break;
11402         case OPC_ADDQH_R_W:
11403             gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
11404             break;
11405         case OPC_SUBUH_QB:
11406             gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
11407             break;
11408         case OPC_SUBUH_R_QB:
11409             gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
11410             break;
11411         case OPC_SUBQH_PH:
11412             gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
11413             break;
11414         case OPC_SUBQH_R_PH:
11415             gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
11416             break;
11417         case OPC_SUBQH_W:
11418             gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
11419             break;
11420         case OPC_SUBQH_R_W:
11421             gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
11422             break;
11423         }
11424         break;
11425     case OPC_ABSQ_S_PH_DSP:
11426         switch (op2) {
11427         case OPC_ABSQ_S_QB:
11428             check_dsp_r2(ctx);
11429             gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, tcg_env);
11430             break;
11431         case OPC_ABSQ_S_PH:
11432             check_dsp(ctx);
11433             gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, tcg_env);
11434             break;
11435         case OPC_ABSQ_S_W:
11436             check_dsp(ctx);
11437             gen_helper_absq_s_w(cpu_gpr[ret], v2_t, tcg_env);
11438             break;
11439         case OPC_PRECEQ_W_PHL:
11440             check_dsp(ctx);
11441             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
11442             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
11443             break;
11444         case OPC_PRECEQ_W_PHR:
11445             check_dsp(ctx);
11446             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
11447             tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
11448             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
11449             break;
11450         case OPC_PRECEQU_PH_QBL:
11451             check_dsp(ctx);
11452             gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
11453             break;
11454         case OPC_PRECEQU_PH_QBR:
11455             check_dsp(ctx);
11456             gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
11457             break;
11458         case OPC_PRECEQU_PH_QBLA:
11459             check_dsp(ctx);
11460             gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
11461             break;
11462         case OPC_PRECEQU_PH_QBRA:
11463             check_dsp(ctx);
11464             gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
11465             break;
11466         case OPC_PRECEU_PH_QBL:
11467             check_dsp(ctx);
11468             gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
11469             break;
11470         case OPC_PRECEU_PH_QBR:
11471             check_dsp(ctx);
11472             gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
11473             break;
11474         case OPC_PRECEU_PH_QBLA:
11475             check_dsp(ctx);
11476             gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
11477             break;
11478         case OPC_PRECEU_PH_QBRA:
11479             check_dsp(ctx);
11480             gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
11481             break;
11482         }
11483         break;
11484     case OPC_ADDU_QB_DSP:
11485         switch (op2) {
11486         case OPC_ADDQ_PH:
11487             check_dsp(ctx);
11488             gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11489             break;
11490         case OPC_ADDQ_S_PH:
11491             check_dsp(ctx);
11492             gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11493             break;
11494         case OPC_ADDQ_S_W:
11495             check_dsp(ctx);
11496             gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11497             break;
11498         case OPC_ADDU_QB:
11499             check_dsp(ctx);
11500             gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11501             break;
11502         case OPC_ADDU_S_QB:
11503             check_dsp(ctx);
11504             gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11505             break;
11506         case OPC_ADDU_PH:
11507             check_dsp_r2(ctx);
11508             gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11509             break;
11510         case OPC_ADDU_S_PH:
11511             check_dsp_r2(ctx);
11512             gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11513             break;
11514         case OPC_SUBQ_PH:
11515             check_dsp(ctx);
11516             gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11517             break;
11518         case OPC_SUBQ_S_PH:
11519             check_dsp(ctx);
11520             gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11521             break;
11522         case OPC_SUBQ_S_W:
11523             check_dsp(ctx);
11524             gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11525             break;
11526         case OPC_SUBU_QB:
11527             check_dsp(ctx);
11528             gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11529             break;
11530         case OPC_SUBU_S_QB:
11531             check_dsp(ctx);
11532             gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11533             break;
11534         case OPC_SUBU_PH:
11535             check_dsp_r2(ctx);
11536             gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11537             break;
11538         case OPC_SUBU_S_PH:
11539             check_dsp_r2(ctx);
11540             gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11541             break;
11542         case OPC_ADDSC:
11543             check_dsp(ctx);
11544             gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11545             break;
11546         case OPC_ADDWC:
11547             check_dsp(ctx);
11548             gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11549             break;
11550         case OPC_MODSUB:
11551             check_dsp(ctx);
11552             gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
11553             break;
11554         case OPC_RADDU_W_QB:
11555             check_dsp(ctx);
11556             gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
11557             break;
11558         }
11559         break;
11560     case OPC_CMPU_EQ_QB_DSP:
11561         switch (op2) {
11562         case OPC_PRECR_QB_PH:
11563             check_dsp_r2(ctx);
11564             gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
11565             break;
11566         case OPC_PRECRQ_QB_PH:
11567             check_dsp(ctx);
11568             gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
11569             break;
11570         case OPC_PRECR_SRA_PH_W:
11571             check_dsp_r2(ctx);
11572             {
11573                 TCGv_i32 sa_t = tcg_constant_i32(v2);
11574                 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
11575                                           cpu_gpr[ret]);
11576                 break;
11577             }
11578         case OPC_PRECR_SRA_R_PH_W:
11579             check_dsp_r2(ctx);
11580             {
11581                 TCGv_i32 sa_t = tcg_constant_i32(v2);
11582                 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
11583                                             cpu_gpr[ret]);
11584                 break;
11585             }
11586         case OPC_PRECRQ_PH_W:
11587             check_dsp(ctx);
11588             gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
11589             break;
11590         case OPC_PRECRQ_RS_PH_W:
11591             check_dsp(ctx);
11592             gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11593             break;
11594         case OPC_PRECRQU_S_QB_PH:
11595             check_dsp(ctx);
11596             gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11597             break;
11598         }
11599         break;
11600 #ifdef TARGET_MIPS64
11601     case OPC_ABSQ_S_QH_DSP:
11602         switch (op2) {
11603         case OPC_PRECEQ_L_PWL:
11604             check_dsp(ctx);
11605             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
11606             break;
11607         case OPC_PRECEQ_L_PWR:
11608             check_dsp(ctx);
11609             tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
11610             break;
11611         case OPC_PRECEQ_PW_QHL:
11612             check_dsp(ctx);
11613             gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
11614             break;
11615         case OPC_PRECEQ_PW_QHR:
11616             check_dsp(ctx);
11617             gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
11618             break;
11619         case OPC_PRECEQ_PW_QHLA:
11620             check_dsp(ctx);
11621             gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
11622             break;
11623         case OPC_PRECEQ_PW_QHRA:
11624             check_dsp(ctx);
11625             gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
11626             break;
11627         case OPC_PRECEQU_QH_OBL:
11628             check_dsp(ctx);
11629             gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
11630             break;
11631         case OPC_PRECEQU_QH_OBR:
11632             check_dsp(ctx);
11633             gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
11634             break;
11635         case OPC_PRECEQU_QH_OBLA:
11636             check_dsp(ctx);
11637             gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
11638             break;
11639         case OPC_PRECEQU_QH_OBRA:
11640             check_dsp(ctx);
11641             gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
11642             break;
11643         case OPC_PRECEU_QH_OBL:
11644             check_dsp(ctx);
11645             gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
11646             break;
11647         case OPC_PRECEU_QH_OBR:
11648             check_dsp(ctx);
11649             gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
11650             break;
11651         case OPC_PRECEU_QH_OBLA:
11652             check_dsp(ctx);
11653             gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
11654             break;
11655         case OPC_PRECEU_QH_OBRA:
11656             check_dsp(ctx);
11657             gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
11658             break;
11659         case OPC_ABSQ_S_OB:
11660             check_dsp_r2(ctx);
11661             gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, tcg_env);
11662             break;
11663         case OPC_ABSQ_S_PW:
11664             check_dsp(ctx);
11665             gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, tcg_env);
11666             break;
11667         case OPC_ABSQ_S_QH:
11668             check_dsp(ctx);
11669             gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, tcg_env);
11670             break;
11671         }
11672         break;
11673     case OPC_ADDU_OB_DSP:
11674         switch (op2) {
11675         case OPC_RADDU_L_OB:
11676             check_dsp(ctx);
11677             gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
11678             break;
11679         case OPC_SUBQ_PW:
11680             check_dsp(ctx);
11681             gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11682             break;
11683         case OPC_SUBQ_S_PW:
11684             check_dsp(ctx);
11685             gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11686             break;
11687         case OPC_SUBQ_QH:
11688             check_dsp(ctx);
11689             gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11690             break;
11691         case OPC_SUBQ_S_QH:
11692             check_dsp(ctx);
11693             gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11694             break;
11695         case OPC_SUBU_OB:
11696             check_dsp(ctx);
11697             gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11698             break;
11699         case OPC_SUBU_S_OB:
11700             check_dsp(ctx);
11701             gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11702             break;
11703         case OPC_SUBU_QH:
11704             check_dsp_r2(ctx);
11705             gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11706             break;
11707         case OPC_SUBU_S_QH:
11708             check_dsp_r2(ctx);
11709             gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11710             break;
11711         case OPC_SUBUH_OB:
11712             check_dsp_r2(ctx);
11713             gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
11714             break;
11715         case OPC_SUBUH_R_OB:
11716             check_dsp_r2(ctx);
11717             gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
11718             break;
11719         case OPC_ADDQ_PW:
11720             check_dsp(ctx);
11721             gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11722             break;
11723         case OPC_ADDQ_S_PW:
11724             check_dsp(ctx);
11725             gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11726             break;
11727         case OPC_ADDQ_QH:
11728             check_dsp(ctx);
11729             gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11730             break;
11731         case OPC_ADDQ_S_QH:
11732             check_dsp(ctx);
11733             gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11734             break;
11735         case OPC_ADDU_OB:
11736             check_dsp(ctx);
11737             gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11738             break;
11739         case OPC_ADDU_S_OB:
11740             check_dsp(ctx);
11741             gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11742             break;
11743         case OPC_ADDU_QH:
11744             check_dsp_r2(ctx);
11745             gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11746             break;
11747         case OPC_ADDU_S_QH:
11748             check_dsp_r2(ctx);
11749             gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11750             break;
11751         case OPC_ADDUH_OB:
11752             check_dsp_r2(ctx);
11753             gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
11754             break;
11755         case OPC_ADDUH_R_OB:
11756             check_dsp_r2(ctx);
11757             gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
11758             break;
11759         }
11760         break;
11761     case OPC_CMPU_EQ_OB_DSP:
11762         switch (op2) {
11763         case OPC_PRECR_OB_QH:
11764             check_dsp_r2(ctx);
11765             gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
11766             break;
11767         case OPC_PRECR_SRA_QH_PW:
11768             check_dsp_r2(ctx);
11769             {
11770                 TCGv_i32 ret_t = tcg_constant_i32(ret);
11771                 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
11772                 break;
11773             }
11774         case OPC_PRECR_SRA_R_QH_PW:
11775             check_dsp_r2(ctx);
11776             {
11777                 TCGv_i32 sa_v = tcg_constant_i32(ret);
11778                 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
11779                 break;
11780             }
11781         case OPC_PRECRQ_OB_QH:
11782             check_dsp(ctx);
11783             gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
11784             break;
11785         case OPC_PRECRQ_PW_L:
11786             check_dsp(ctx);
11787             gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
11788             break;
11789         case OPC_PRECRQ_QH_PW:
11790             check_dsp(ctx);
11791             gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
11792             break;
11793         case OPC_PRECRQ_RS_QH_PW:
11794             check_dsp(ctx);
11795             gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11796             break;
11797         case OPC_PRECRQU_S_OB_QH:
11798             check_dsp(ctx);
11799             gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11800             break;
11801         }
11802         break;
11803 #endif
11804     }
11805 }
11806 
gen_mipsdsp_shift(DisasContext * ctx,uint32_t opc,int ret,int v1,int v2)11807 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
11808                               int ret, int v1, int v2)
11809 {
11810     uint32_t op2;
11811     TCGv t0;
11812     TCGv v1_t;
11813     TCGv v2_t;
11814 
11815     if (ret == 0) {
11816         /* Treat as NOP. */
11817         return;
11818     }
11819 
11820     t0 = tcg_temp_new();
11821     v1_t = tcg_temp_new();
11822     v2_t = tcg_temp_new();
11823 
11824     tcg_gen_movi_tl(t0, v1);
11825     gen_load_gpr(v1_t, v1);
11826     gen_load_gpr(v2_t, v2);
11827 
11828     switch (opc) {
11829     case OPC_SHLL_QB_DSP:
11830         {
11831             op2 = MASK_SHLL_QB(ctx->opcode);
11832             switch (op2) {
11833             case OPC_SHLL_QB:
11834                 check_dsp(ctx);
11835                 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, tcg_env);
11836                 break;
11837             case OPC_SHLLV_QB:
11838                 check_dsp(ctx);
11839                 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11840                 break;
11841             case OPC_SHLL_PH:
11842                 check_dsp(ctx);
11843                 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, tcg_env);
11844                 break;
11845             case OPC_SHLLV_PH:
11846                 check_dsp(ctx);
11847                 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11848                 break;
11849             case OPC_SHLL_S_PH:
11850                 check_dsp(ctx);
11851                 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, tcg_env);
11852                 break;
11853             case OPC_SHLLV_S_PH:
11854                 check_dsp(ctx);
11855                 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11856                 break;
11857             case OPC_SHLL_S_W:
11858                 check_dsp(ctx);
11859                 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, tcg_env);
11860                 break;
11861             case OPC_SHLLV_S_W:
11862                 check_dsp(ctx);
11863                 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11864                 break;
11865             case OPC_SHRL_QB:
11866                 check_dsp(ctx);
11867                 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
11868                 break;
11869             case OPC_SHRLV_QB:
11870                 check_dsp(ctx);
11871                 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
11872                 break;
11873             case OPC_SHRL_PH:
11874                 check_dsp_r2(ctx);
11875                 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
11876                 break;
11877             case OPC_SHRLV_PH:
11878                 check_dsp_r2(ctx);
11879                 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
11880                 break;
11881             case OPC_SHRA_QB:
11882                 check_dsp_r2(ctx);
11883                 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
11884                 break;
11885             case OPC_SHRA_R_QB:
11886                 check_dsp_r2(ctx);
11887                 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
11888                 break;
11889             case OPC_SHRAV_QB:
11890                 check_dsp_r2(ctx);
11891                 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
11892                 break;
11893             case OPC_SHRAV_R_QB:
11894                 check_dsp_r2(ctx);
11895                 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
11896                 break;
11897             case OPC_SHRA_PH:
11898                 check_dsp(ctx);
11899                 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
11900                 break;
11901             case OPC_SHRA_R_PH:
11902                 check_dsp(ctx);
11903                 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
11904                 break;
11905             case OPC_SHRAV_PH:
11906                 check_dsp(ctx);
11907                 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
11908                 break;
11909             case OPC_SHRAV_R_PH:
11910                 check_dsp(ctx);
11911                 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
11912                 break;
11913             case OPC_SHRA_R_W:
11914                 check_dsp(ctx);
11915                 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
11916                 break;
11917             case OPC_SHRAV_R_W:
11918                 check_dsp(ctx);
11919                 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
11920                 break;
11921             default:            /* Invalid */
11922                 MIPS_INVAL("MASK SHLL.QB");
11923                 gen_reserved_instruction(ctx);
11924                 break;
11925             }
11926             break;
11927         }
11928 #ifdef TARGET_MIPS64
11929     case OPC_SHLL_OB_DSP:
11930         op2 = MASK_SHLL_OB(ctx->opcode);
11931         switch (op2) {
11932         case OPC_SHLL_PW:
11933             check_dsp(ctx);
11934             gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, tcg_env);
11935             break;
11936         case OPC_SHLLV_PW:
11937             check_dsp(ctx);
11938             gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, tcg_env);
11939             break;
11940         case OPC_SHLL_S_PW:
11941             check_dsp(ctx);
11942             gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, tcg_env);
11943             break;
11944         case OPC_SHLLV_S_PW:
11945             check_dsp(ctx);
11946             gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, tcg_env);
11947             break;
11948         case OPC_SHLL_OB:
11949             check_dsp(ctx);
11950             gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, tcg_env);
11951             break;
11952         case OPC_SHLLV_OB:
11953             check_dsp(ctx);
11954             gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, tcg_env);
11955             break;
11956         case OPC_SHLL_QH:
11957             check_dsp(ctx);
11958             gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, tcg_env);
11959             break;
11960         case OPC_SHLLV_QH:
11961             check_dsp(ctx);
11962             gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, tcg_env);
11963             break;
11964         case OPC_SHLL_S_QH:
11965             check_dsp(ctx);
11966             gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, tcg_env);
11967             break;
11968         case OPC_SHLLV_S_QH:
11969             check_dsp(ctx);
11970             gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, tcg_env);
11971             break;
11972         case OPC_SHRA_OB:
11973             check_dsp_r2(ctx);
11974             gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
11975             break;
11976         case OPC_SHRAV_OB:
11977             check_dsp_r2(ctx);
11978             gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
11979             break;
11980         case OPC_SHRA_R_OB:
11981             check_dsp_r2(ctx);
11982             gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
11983             break;
11984         case OPC_SHRAV_R_OB:
11985             check_dsp_r2(ctx);
11986             gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
11987             break;
11988         case OPC_SHRA_PW:
11989             check_dsp(ctx);
11990             gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
11991             break;
11992         case OPC_SHRAV_PW:
11993             check_dsp(ctx);
11994             gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
11995             break;
11996         case OPC_SHRA_R_PW:
11997             check_dsp(ctx);
11998             gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
11999             break;
12000         case OPC_SHRAV_R_PW:
12001             check_dsp(ctx);
12002             gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
12003             break;
12004         case OPC_SHRA_QH:
12005             check_dsp(ctx);
12006             gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
12007             break;
12008         case OPC_SHRAV_QH:
12009             check_dsp(ctx);
12010             gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
12011             break;
12012         case OPC_SHRA_R_QH:
12013             check_dsp(ctx);
12014             gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
12015             break;
12016         case OPC_SHRAV_R_QH:
12017             check_dsp(ctx);
12018             gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
12019             break;
12020         case OPC_SHRL_OB:
12021             check_dsp(ctx);
12022             gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
12023             break;
12024         case OPC_SHRLV_OB:
12025             check_dsp(ctx);
12026             gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
12027             break;
12028         case OPC_SHRL_QH:
12029             check_dsp_r2(ctx);
12030             gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
12031             break;
12032         case OPC_SHRLV_QH:
12033             check_dsp_r2(ctx);
12034             gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
12035             break;
12036         default:            /* Invalid */
12037             MIPS_INVAL("MASK SHLL.OB");
12038             gen_reserved_instruction(ctx);
12039             break;
12040         }
12041         break;
12042 #endif
12043     }
12044 }
12045 
gen_mipsdsp_multiply(DisasContext * ctx,uint32_t op1,uint32_t op2,int ret,int v1,int v2,int check_ret)12046 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
12047                                  int ret, int v1, int v2, int check_ret)
12048 {
12049     TCGv_i32 t0;
12050     TCGv v1_t;
12051     TCGv v2_t;
12052 
12053     if ((ret == 0) && (check_ret == 1)) {
12054         /* Treat as NOP. */
12055         return;
12056     }
12057 
12058     t0 = tcg_temp_new_i32();
12059     v1_t = tcg_temp_new();
12060     v2_t = tcg_temp_new();
12061 
12062     tcg_gen_movi_i32(t0, ret);
12063     gen_load_gpr(v1_t, v1);
12064     gen_load_gpr(v2_t, v2);
12065 
12066     switch (op1) {
12067     case OPC_MUL_PH_DSP:
12068         check_dsp_r2(ctx);
12069         switch (op2) {
12070         case  OPC_MUL_PH:
12071             gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12072             break;
12073         case  OPC_MUL_S_PH:
12074             gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12075             break;
12076         case OPC_MULQ_S_W:
12077             gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12078             break;
12079         case OPC_MULQ_RS_W:
12080             gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12081             break;
12082         }
12083         break;
12084     case OPC_DPA_W_PH_DSP:
12085         switch (op2) {
12086         case OPC_DPAU_H_QBL:
12087             check_dsp(ctx);
12088             gen_helper_dpau_h_qbl(t0, v1_t, v2_t, tcg_env);
12089             break;
12090         case OPC_DPAU_H_QBR:
12091             check_dsp(ctx);
12092             gen_helper_dpau_h_qbr(t0, v1_t, v2_t, tcg_env);
12093             break;
12094         case OPC_DPSU_H_QBL:
12095             check_dsp(ctx);
12096             gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, tcg_env);
12097             break;
12098         case OPC_DPSU_H_QBR:
12099             check_dsp(ctx);
12100             gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, tcg_env);
12101             break;
12102         case OPC_DPA_W_PH:
12103             check_dsp_r2(ctx);
12104             gen_helper_dpa_w_ph(t0, v1_t, v2_t, tcg_env);
12105             break;
12106         case OPC_DPAX_W_PH:
12107             check_dsp_r2(ctx);
12108             gen_helper_dpax_w_ph(t0, v1_t, v2_t, tcg_env);
12109             break;
12110         case OPC_DPAQ_S_W_PH:
12111             check_dsp(ctx);
12112             gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, tcg_env);
12113             break;
12114         case OPC_DPAQX_S_W_PH:
12115             check_dsp_r2(ctx);
12116             gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, tcg_env);
12117             break;
12118         case OPC_DPAQX_SA_W_PH:
12119             check_dsp_r2(ctx);
12120             gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, tcg_env);
12121             break;
12122         case OPC_DPS_W_PH:
12123             check_dsp_r2(ctx);
12124             gen_helper_dps_w_ph(t0, v1_t, v2_t, tcg_env);
12125             break;
12126         case OPC_DPSX_W_PH:
12127             check_dsp_r2(ctx);
12128             gen_helper_dpsx_w_ph(t0, v1_t, v2_t, tcg_env);
12129             break;
12130         case OPC_DPSQ_S_W_PH:
12131             check_dsp(ctx);
12132             gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, tcg_env);
12133             break;
12134         case OPC_DPSQX_S_W_PH:
12135             check_dsp_r2(ctx);
12136             gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, tcg_env);
12137             break;
12138         case OPC_DPSQX_SA_W_PH:
12139             check_dsp_r2(ctx);
12140             gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, tcg_env);
12141             break;
12142         case OPC_MULSAQ_S_W_PH:
12143             check_dsp(ctx);
12144             gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, tcg_env);
12145             break;
12146         case OPC_DPAQ_SA_L_W:
12147             check_dsp(ctx);
12148             gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, tcg_env);
12149             break;
12150         case OPC_DPSQ_SA_L_W:
12151             check_dsp(ctx);
12152             gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, tcg_env);
12153             break;
12154         case OPC_MAQ_S_W_PHL:
12155             check_dsp(ctx);
12156             gen_helper_maq_s_w_phl(t0, v1_t, v2_t, tcg_env);
12157             break;
12158         case OPC_MAQ_S_W_PHR:
12159             check_dsp(ctx);
12160             gen_helper_maq_s_w_phr(t0, v1_t, v2_t, tcg_env);
12161             break;
12162         case OPC_MAQ_SA_W_PHL:
12163             check_dsp(ctx);
12164             gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, tcg_env);
12165             break;
12166         case OPC_MAQ_SA_W_PHR:
12167             check_dsp(ctx);
12168             gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, tcg_env);
12169             break;
12170         case OPC_MULSA_W_PH:
12171             check_dsp_r2(ctx);
12172             gen_helper_mulsa_w_ph(t0, v1_t, v2_t, tcg_env);
12173             break;
12174         }
12175         break;
12176 #ifdef TARGET_MIPS64
12177     case OPC_DPAQ_W_QH_DSP:
12178         {
12179             int ac = ret & 0x03;
12180             tcg_gen_movi_i32(t0, ac);
12181 
12182             switch (op2) {
12183             case OPC_DMADD:
12184                 check_dsp(ctx);
12185                 gen_helper_dmadd(v1_t, v2_t, t0, tcg_env);
12186                 break;
12187             case OPC_DMADDU:
12188                 check_dsp(ctx);
12189                 gen_helper_dmaddu(v1_t, v2_t, t0, tcg_env);
12190                 break;
12191             case OPC_DMSUB:
12192                 check_dsp(ctx);
12193                 gen_helper_dmsub(v1_t, v2_t, t0, tcg_env);
12194                 break;
12195             case OPC_DMSUBU:
12196                 check_dsp(ctx);
12197                 gen_helper_dmsubu(v1_t, v2_t, t0, tcg_env);
12198                 break;
12199             case OPC_DPA_W_QH:
12200                 check_dsp_r2(ctx);
12201                 gen_helper_dpa_w_qh(v1_t, v2_t, t0, tcg_env);
12202                 break;
12203             case OPC_DPAQ_S_W_QH:
12204                 check_dsp(ctx);
12205                 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, tcg_env);
12206                 break;
12207             case OPC_DPAQ_SA_L_PW:
12208                 check_dsp(ctx);
12209                 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, tcg_env);
12210                 break;
12211             case OPC_DPAU_H_OBL:
12212                 check_dsp(ctx);
12213                 gen_helper_dpau_h_obl(v1_t, v2_t, t0, tcg_env);
12214                 break;
12215             case OPC_DPAU_H_OBR:
12216                 check_dsp(ctx);
12217                 gen_helper_dpau_h_obr(v1_t, v2_t, t0, tcg_env);
12218                 break;
12219             case OPC_DPS_W_QH:
12220                 check_dsp_r2(ctx);
12221                 gen_helper_dps_w_qh(v1_t, v2_t, t0, tcg_env);
12222                 break;
12223             case OPC_DPSQ_S_W_QH:
12224                 check_dsp(ctx);
12225                 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, tcg_env);
12226                 break;
12227             case OPC_DPSQ_SA_L_PW:
12228                 check_dsp(ctx);
12229                 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, tcg_env);
12230                 break;
12231             case OPC_DPSU_H_OBL:
12232                 check_dsp(ctx);
12233                 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, tcg_env);
12234                 break;
12235             case OPC_DPSU_H_OBR:
12236                 check_dsp(ctx);
12237                 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, tcg_env);
12238                 break;
12239             case OPC_MAQ_S_L_PWL:
12240                 check_dsp(ctx);
12241                 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, tcg_env);
12242                 break;
12243             case OPC_MAQ_S_L_PWR:
12244                 check_dsp(ctx);
12245                 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, tcg_env);
12246                 break;
12247             case OPC_MAQ_S_W_QHLL:
12248                 check_dsp(ctx);
12249                 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, tcg_env);
12250                 break;
12251             case OPC_MAQ_SA_W_QHLL:
12252                 check_dsp(ctx);
12253                 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, tcg_env);
12254                 break;
12255             case OPC_MAQ_S_W_QHLR:
12256                 check_dsp(ctx);
12257                 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, tcg_env);
12258                 break;
12259             case OPC_MAQ_SA_W_QHLR:
12260                 check_dsp(ctx);
12261                 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, tcg_env);
12262                 break;
12263             case OPC_MAQ_S_W_QHRL:
12264                 check_dsp(ctx);
12265                 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, tcg_env);
12266                 break;
12267             case OPC_MAQ_SA_W_QHRL:
12268                 check_dsp(ctx);
12269                 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, tcg_env);
12270                 break;
12271             case OPC_MAQ_S_W_QHRR:
12272                 check_dsp(ctx);
12273                 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, tcg_env);
12274                 break;
12275             case OPC_MAQ_SA_W_QHRR:
12276                 check_dsp(ctx);
12277                 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, tcg_env);
12278                 break;
12279             case OPC_MULSAQ_S_L_PW:
12280                 check_dsp(ctx);
12281                 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, tcg_env);
12282                 break;
12283             case OPC_MULSAQ_S_W_QH:
12284                 check_dsp(ctx);
12285                 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, tcg_env);
12286                 break;
12287             }
12288         }
12289         break;
12290 #endif
12291     case OPC_ADDU_QB_DSP:
12292         switch (op2) {
12293         case OPC_MULEU_S_PH_QBL:
12294             check_dsp(ctx);
12295             gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12296             break;
12297         case OPC_MULEU_S_PH_QBR:
12298             check_dsp(ctx);
12299             gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12300             break;
12301         case OPC_MULQ_RS_PH:
12302             check_dsp(ctx);
12303             gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12304             break;
12305         case OPC_MULEQ_S_W_PHL:
12306             check_dsp(ctx);
12307             gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12308             break;
12309         case OPC_MULEQ_S_W_PHR:
12310             check_dsp(ctx);
12311             gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12312             break;
12313         case OPC_MULQ_S_PH:
12314             check_dsp_r2(ctx);
12315             gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12316             break;
12317         }
12318         break;
12319 #ifdef TARGET_MIPS64
12320     case OPC_ADDU_OB_DSP:
12321         switch (op2) {
12322         case OPC_MULEQ_S_PW_QHL:
12323             check_dsp(ctx);
12324             gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12325             break;
12326         case OPC_MULEQ_S_PW_QHR:
12327             check_dsp(ctx);
12328             gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12329             break;
12330         case OPC_MULEU_S_QH_OBL:
12331             check_dsp(ctx);
12332             gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12333             break;
12334         case OPC_MULEU_S_QH_OBR:
12335             check_dsp(ctx);
12336             gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12337             break;
12338         case OPC_MULQ_RS_QH:
12339             check_dsp(ctx);
12340             gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12341             break;
12342         }
12343         break;
12344 #endif
12345     }
12346 }
12347 
gen_mipsdsp_bitinsn(DisasContext * ctx,uint32_t op1,uint32_t op2,int ret,int val)12348 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
12349                                 int ret, int val)
12350 {
12351     int16_t imm;
12352     TCGv t0;
12353     TCGv val_t;
12354 
12355     if (ret == 0) {
12356         /* Treat as NOP. */
12357         return;
12358     }
12359 
12360     t0 = tcg_temp_new();
12361     val_t = tcg_temp_new();
12362     gen_load_gpr(val_t, val);
12363 
12364     switch (op1) {
12365     case OPC_ABSQ_S_PH_DSP:
12366         switch (op2) {
12367         case OPC_BITREV:
12368             check_dsp(ctx);
12369             gen_helper_bitrev(cpu_gpr[ret], val_t);
12370             break;
12371         case OPC_REPL_QB:
12372             check_dsp(ctx);
12373             {
12374                 target_long result;
12375                 imm = (ctx->opcode >> 16) & 0xFF;
12376                 result = (uint32_t)imm << 24 |
12377                          (uint32_t)imm << 16 |
12378                          (uint32_t)imm << 8  |
12379                          (uint32_t)imm;
12380                 result = (int32_t)result;
12381                 tcg_gen_movi_tl(cpu_gpr[ret], result);
12382             }
12383             break;
12384         case OPC_REPLV_QB:
12385             check_dsp(ctx);
12386             tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
12387             tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
12388             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12389             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
12390             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12391             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12392             break;
12393         case OPC_REPL_PH:
12394             check_dsp(ctx);
12395             {
12396                 imm = (ctx->opcode >> 16) & 0x03FF;
12397                 imm = (int16_t)(imm << 6) >> 6;
12398                 tcg_gen_movi_tl(cpu_gpr[ret], \
12399                                 (target_long)((int32_t)imm << 16 | \
12400                                 (uint16_t)imm));
12401             }
12402             break;
12403         case OPC_REPLV_PH:
12404             check_dsp(ctx);
12405             tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
12406             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
12407             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12408             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12409             break;
12410         }
12411         break;
12412 #ifdef TARGET_MIPS64
12413     case OPC_ABSQ_S_QH_DSP:
12414         switch (op2) {
12415         case OPC_REPL_OB:
12416             check_dsp(ctx);
12417             {
12418                 target_long temp;
12419 
12420                 imm = (ctx->opcode >> 16) & 0xFF;
12421                 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
12422                 temp = (temp << 16) | temp;
12423                 temp = (temp << 32) | temp;
12424                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
12425                 break;
12426             }
12427         case OPC_REPL_PW:
12428             check_dsp(ctx);
12429             {
12430                 target_long temp;
12431 
12432                 imm = (ctx->opcode >> 16) & 0x03FF;
12433                 imm = (int16_t)(imm << 6) >> 6;
12434                 temp = ((target_long)imm << 32) \
12435                        | ((target_long)imm & 0xFFFFFFFF);
12436                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
12437                 break;
12438             }
12439         case OPC_REPL_QH:
12440             check_dsp(ctx);
12441             {
12442                 target_long temp;
12443 
12444                 imm = (ctx->opcode >> 16) & 0x03FF;
12445                 imm = (int16_t)(imm << 6) >> 6;
12446 
12447                 temp = ((uint64_t)(uint16_t)imm << 48) |
12448                        ((uint64_t)(uint16_t)imm << 32) |
12449                        ((uint64_t)(uint16_t)imm << 16) |
12450                        (uint64_t)(uint16_t)imm;
12451                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
12452                 break;
12453             }
12454         case OPC_REPLV_OB:
12455             check_dsp(ctx);
12456             tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
12457             tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
12458             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12459             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
12460             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12461             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
12462             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12463             break;
12464         case OPC_REPLV_PW:
12465             check_dsp(ctx);
12466             tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
12467             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
12468             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12469             break;
12470         case OPC_REPLV_QH:
12471             check_dsp(ctx);
12472             tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
12473             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
12474             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12475             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
12476             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12477             break;
12478         }
12479         break;
12480 #endif
12481     }
12482 }
12483 
gen_mipsdsp_add_cmp_pick(DisasContext * ctx,uint32_t op1,uint32_t op2,int ret,int v1,int v2,int check_ret)12484 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
12485                                      uint32_t op1, uint32_t op2,
12486                                      int ret, int v1, int v2, int check_ret)
12487 {
12488     TCGv t1;
12489     TCGv v1_t;
12490     TCGv v2_t;
12491 
12492     if ((ret == 0) && (check_ret == 1)) {
12493         /* Treat as NOP. */
12494         return;
12495     }
12496 
12497     t1 = tcg_temp_new();
12498     v1_t = tcg_temp_new();
12499     v2_t = tcg_temp_new();
12500 
12501     gen_load_gpr(v1_t, v1);
12502     gen_load_gpr(v2_t, v2);
12503 
12504     switch (op1) {
12505     case OPC_CMPU_EQ_QB_DSP:
12506         switch (op2) {
12507         case OPC_CMPU_EQ_QB:
12508             check_dsp(ctx);
12509             gen_helper_cmpu_eq_qb(v1_t, v2_t, tcg_env);
12510             break;
12511         case OPC_CMPU_LT_QB:
12512             check_dsp(ctx);
12513             gen_helper_cmpu_lt_qb(v1_t, v2_t, tcg_env);
12514             break;
12515         case OPC_CMPU_LE_QB:
12516             check_dsp(ctx);
12517             gen_helper_cmpu_le_qb(v1_t, v2_t, tcg_env);
12518             break;
12519         case OPC_CMPGU_EQ_QB:
12520             check_dsp(ctx);
12521             gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
12522             break;
12523         case OPC_CMPGU_LT_QB:
12524             check_dsp(ctx);
12525             gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
12526             break;
12527         case OPC_CMPGU_LE_QB:
12528             check_dsp(ctx);
12529             gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
12530             break;
12531         case OPC_CMPGDU_EQ_QB:
12532             check_dsp_r2(ctx);
12533             gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
12534             tcg_gen_mov_tl(cpu_gpr[ret], t1);
12535             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
12536             tcg_gen_shli_tl(t1, t1, 24);
12537             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
12538             break;
12539         case OPC_CMPGDU_LT_QB:
12540             check_dsp_r2(ctx);
12541             gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
12542             tcg_gen_mov_tl(cpu_gpr[ret], t1);
12543             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
12544             tcg_gen_shli_tl(t1, t1, 24);
12545             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
12546             break;
12547         case OPC_CMPGDU_LE_QB:
12548             check_dsp_r2(ctx);
12549             gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
12550             tcg_gen_mov_tl(cpu_gpr[ret], t1);
12551             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
12552             tcg_gen_shli_tl(t1, t1, 24);
12553             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
12554             break;
12555         case OPC_CMP_EQ_PH:
12556             check_dsp(ctx);
12557             gen_helper_cmp_eq_ph(v1_t, v2_t, tcg_env);
12558             break;
12559         case OPC_CMP_LT_PH:
12560             check_dsp(ctx);
12561             gen_helper_cmp_lt_ph(v1_t, v2_t, tcg_env);
12562             break;
12563         case OPC_CMP_LE_PH:
12564             check_dsp(ctx);
12565             gen_helper_cmp_le_ph(v1_t, v2_t, tcg_env);
12566             break;
12567         case OPC_PICK_QB:
12568             check_dsp(ctx);
12569             gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12570             break;
12571         case OPC_PICK_PH:
12572             check_dsp(ctx);
12573             gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12574             break;
12575         case OPC_PACKRL_PH:
12576             check_dsp(ctx);
12577             gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
12578             break;
12579         }
12580         break;
12581 #ifdef TARGET_MIPS64
12582     case OPC_CMPU_EQ_OB_DSP:
12583         switch (op2) {
12584         case OPC_CMP_EQ_PW:
12585             check_dsp(ctx);
12586             gen_helper_cmp_eq_pw(v1_t, v2_t, tcg_env);
12587             break;
12588         case OPC_CMP_LT_PW:
12589             check_dsp(ctx);
12590             gen_helper_cmp_lt_pw(v1_t, v2_t, tcg_env);
12591             break;
12592         case OPC_CMP_LE_PW:
12593             check_dsp(ctx);
12594             gen_helper_cmp_le_pw(v1_t, v2_t, tcg_env);
12595             break;
12596         case OPC_CMP_EQ_QH:
12597             check_dsp(ctx);
12598             gen_helper_cmp_eq_qh(v1_t, v2_t, tcg_env);
12599             break;
12600         case OPC_CMP_LT_QH:
12601             check_dsp(ctx);
12602             gen_helper_cmp_lt_qh(v1_t, v2_t, tcg_env);
12603             break;
12604         case OPC_CMP_LE_QH:
12605             check_dsp(ctx);
12606             gen_helper_cmp_le_qh(v1_t, v2_t, tcg_env);
12607             break;
12608         case OPC_CMPGDU_EQ_OB:
12609             check_dsp_r2(ctx);
12610             gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12611             break;
12612         case OPC_CMPGDU_LT_OB:
12613             check_dsp_r2(ctx);
12614             gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12615             break;
12616         case OPC_CMPGDU_LE_OB:
12617             check_dsp_r2(ctx);
12618             gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12619             break;
12620         case OPC_CMPGU_EQ_OB:
12621             check_dsp(ctx);
12622             gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
12623             break;
12624         case OPC_CMPGU_LT_OB:
12625             check_dsp(ctx);
12626             gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
12627             break;
12628         case OPC_CMPGU_LE_OB:
12629             check_dsp(ctx);
12630             gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
12631             break;
12632         case OPC_CMPU_EQ_OB:
12633             check_dsp(ctx);
12634             gen_helper_cmpu_eq_ob(v1_t, v2_t, tcg_env);
12635             break;
12636         case OPC_CMPU_LT_OB:
12637             check_dsp(ctx);
12638             gen_helper_cmpu_lt_ob(v1_t, v2_t, tcg_env);
12639             break;
12640         case OPC_CMPU_LE_OB:
12641             check_dsp(ctx);
12642             gen_helper_cmpu_le_ob(v1_t, v2_t, tcg_env);
12643             break;
12644         case OPC_PACKRL_PW:
12645             check_dsp(ctx);
12646             gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
12647             break;
12648         case OPC_PICK_OB:
12649             check_dsp(ctx);
12650             gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12651             break;
12652         case OPC_PICK_PW:
12653             check_dsp(ctx);
12654             gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12655             break;
12656         case OPC_PICK_QH:
12657             check_dsp(ctx);
12658             gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12659             break;
12660         }
12661         break;
12662 #endif
12663     }
12664 }
12665 
gen_mipsdsp_append(CPUMIPSState * env,DisasContext * ctx,uint32_t op1,int rt,int rs,int sa)12666 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
12667                                uint32_t op1, int rt, int rs, int sa)
12668 {
12669     TCGv t0;
12670 
12671     check_dsp_r2(ctx);
12672 
12673     if (rt == 0) {
12674         /* Treat as NOP. */
12675         return;
12676     }
12677 
12678     t0 = tcg_temp_new();
12679     gen_load_gpr(t0, rs);
12680 
12681     switch (op1) {
12682     case OPC_APPEND_DSP:
12683         switch (MASK_APPEND(ctx->opcode)) {
12684         case OPC_APPEND:
12685             if (sa != 0) {
12686                 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
12687             }
12688             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
12689             break;
12690         case OPC_PREPEND:
12691             if (sa != 0) {
12692                 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
12693                 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
12694                 tcg_gen_shli_tl(t0, t0, 32 - sa);
12695                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
12696             }
12697             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
12698             break;
12699         case OPC_BALIGN:
12700             sa &= 3;
12701             if (sa != 0 && sa != 2) {
12702                 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
12703                 tcg_gen_ext32u_tl(t0, t0);
12704                 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
12705                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
12706             }
12707             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
12708             break;
12709         default:            /* Invalid */
12710             MIPS_INVAL("MASK APPEND");
12711             gen_reserved_instruction(ctx);
12712             break;
12713         }
12714         break;
12715 #ifdef TARGET_MIPS64
12716     case OPC_DAPPEND_DSP:
12717         switch (MASK_DAPPEND(ctx->opcode)) {
12718         case OPC_DAPPEND:
12719             if (sa != 0) {
12720                 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
12721             }
12722             break;
12723         case OPC_PREPENDD:
12724             tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
12725             tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
12726             tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
12727             break;
12728         case OPC_PREPENDW:
12729             if (sa != 0) {
12730                 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
12731                 tcg_gen_shli_tl(t0, t0, 64 - sa);
12732                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
12733             }
12734             break;
12735         case OPC_DBALIGN:
12736             sa &= 7;
12737             if (sa != 0 && sa != 2 && sa != 4) {
12738                 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
12739                 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
12740                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
12741             }
12742             break;
12743         default:            /* Invalid */
12744             MIPS_INVAL("MASK DAPPEND");
12745             gen_reserved_instruction(ctx);
12746             break;
12747         }
12748         break;
12749 #endif
12750     }
12751 }
12752 
gen_mipsdsp_accinsn(DisasContext * ctx,uint32_t op1,uint32_t op2,int ret,int v1,int v2,int check_ret)12753 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
12754                                 int ret, int v1, int v2, int check_ret)
12755 
12756 {
12757     TCGv t0;
12758     TCGv t1;
12759     TCGv v1_t;
12760     int16_t imm;
12761 
12762     if ((ret == 0) && (check_ret == 1)) {
12763         /* Treat as NOP. */
12764         return;
12765     }
12766 
12767     t0 = tcg_temp_new();
12768     t1 = tcg_temp_new();
12769     v1_t = tcg_temp_new();
12770 
12771     gen_load_gpr(v1_t, v1);
12772 
12773     switch (op1) {
12774     case OPC_EXTR_W_DSP:
12775         check_dsp(ctx);
12776         switch (op2) {
12777         case OPC_EXTR_W:
12778             tcg_gen_movi_tl(t0, v2);
12779             tcg_gen_movi_tl(t1, v1);
12780             gen_helper_extr_w(cpu_gpr[ret], t0, t1, tcg_env);
12781             break;
12782         case OPC_EXTR_R_W:
12783             tcg_gen_movi_tl(t0, v2);
12784             tcg_gen_movi_tl(t1, v1);
12785             gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, tcg_env);
12786             break;
12787         case OPC_EXTR_RS_W:
12788             tcg_gen_movi_tl(t0, v2);
12789             tcg_gen_movi_tl(t1, v1);
12790             gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, tcg_env);
12791             break;
12792         case OPC_EXTR_S_H:
12793             tcg_gen_movi_tl(t0, v2);
12794             tcg_gen_movi_tl(t1, v1);
12795             gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, tcg_env);
12796             break;
12797         case OPC_EXTRV_S_H:
12798             tcg_gen_movi_tl(t0, v2);
12799             gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, tcg_env);
12800             break;
12801         case OPC_EXTRV_W:
12802             tcg_gen_movi_tl(t0, v2);
12803             gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, tcg_env);
12804             break;
12805         case OPC_EXTRV_R_W:
12806             tcg_gen_movi_tl(t0, v2);
12807             gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, tcg_env);
12808             break;
12809         case OPC_EXTRV_RS_W:
12810             tcg_gen_movi_tl(t0, v2);
12811             gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, tcg_env);
12812             break;
12813         case OPC_EXTP:
12814             tcg_gen_movi_tl(t0, v2);
12815             tcg_gen_movi_tl(t1, v1);
12816             gen_helper_extp(cpu_gpr[ret], t0, t1, tcg_env);
12817             break;
12818         case OPC_EXTPV:
12819             tcg_gen_movi_tl(t0, v2);
12820             gen_helper_extp(cpu_gpr[ret], t0, v1_t, tcg_env);
12821             break;
12822         case OPC_EXTPDP:
12823             tcg_gen_movi_tl(t0, v2);
12824             tcg_gen_movi_tl(t1, v1);
12825             gen_helper_extpdp(cpu_gpr[ret], t0, t1, tcg_env);
12826             break;
12827         case OPC_EXTPDPV:
12828             tcg_gen_movi_tl(t0, v2);
12829             gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, tcg_env);
12830             break;
12831         case OPC_SHILO:
12832             imm = (ctx->opcode >> 20) & 0x3F;
12833             tcg_gen_movi_tl(t0, ret);
12834             tcg_gen_movi_tl(t1, imm);
12835             gen_helper_shilo(t0, t1, tcg_env);
12836             break;
12837         case OPC_SHILOV:
12838             tcg_gen_movi_tl(t0, ret);
12839             gen_helper_shilo(t0, v1_t, tcg_env);
12840             break;
12841         case OPC_MTHLIP:
12842             tcg_gen_movi_tl(t0, ret);
12843             gen_helper_mthlip(t0, v1_t, tcg_env);
12844             break;
12845         case OPC_WRDSP:
12846             imm = (ctx->opcode >> 11) & 0x3FF;
12847             tcg_gen_movi_tl(t0, imm);
12848             gen_helper_wrdsp(v1_t, t0, tcg_env);
12849             break;
12850         case OPC_RDDSP:
12851             imm = (ctx->opcode >> 16) & 0x03FF;
12852             tcg_gen_movi_tl(t0, imm);
12853             gen_helper_rddsp(cpu_gpr[ret], t0, tcg_env);
12854             break;
12855         }
12856         break;
12857 #ifdef TARGET_MIPS64
12858     case OPC_DEXTR_W_DSP:
12859         check_dsp(ctx);
12860         switch (op2) {
12861         case OPC_DMTHLIP:
12862             tcg_gen_movi_tl(t0, ret);
12863             gen_helper_dmthlip(v1_t, t0, tcg_env);
12864             break;
12865         case OPC_DSHILO:
12866             {
12867                 int shift = (ctx->opcode >> 19) & 0x7F;
12868                 int ac = (ctx->opcode >> 11) & 0x03;
12869                 tcg_gen_movi_tl(t0, shift);
12870                 tcg_gen_movi_tl(t1, ac);
12871                 gen_helper_dshilo(t0, t1, tcg_env);
12872                 break;
12873             }
12874         case OPC_DSHILOV:
12875             {
12876                 int ac = (ctx->opcode >> 11) & 0x03;
12877                 tcg_gen_movi_tl(t0, ac);
12878                 gen_helper_dshilo(v1_t, t0, tcg_env);
12879                 break;
12880             }
12881         case OPC_DEXTP:
12882             tcg_gen_movi_tl(t0, v2);
12883             tcg_gen_movi_tl(t1, v1);
12884 
12885             gen_helper_dextp(cpu_gpr[ret], t0, t1, tcg_env);
12886             break;
12887         case OPC_DEXTPV:
12888             tcg_gen_movi_tl(t0, v2);
12889             gen_helper_dextp(cpu_gpr[ret], t0, v1_t, tcg_env);
12890             break;
12891         case OPC_DEXTPDP:
12892             tcg_gen_movi_tl(t0, v2);
12893             tcg_gen_movi_tl(t1, v1);
12894             gen_helper_dextpdp(cpu_gpr[ret], t0, t1, tcg_env);
12895             break;
12896         case OPC_DEXTPDPV:
12897             tcg_gen_movi_tl(t0, v2);
12898             gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, tcg_env);
12899             break;
12900         case OPC_DEXTR_L:
12901             tcg_gen_movi_tl(t0, v2);
12902             tcg_gen_movi_tl(t1, v1);
12903             gen_helper_dextr_l(cpu_gpr[ret], t0, t1, tcg_env);
12904             break;
12905         case OPC_DEXTR_R_L:
12906             tcg_gen_movi_tl(t0, v2);
12907             tcg_gen_movi_tl(t1, v1);
12908             gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, tcg_env);
12909             break;
12910         case OPC_DEXTR_RS_L:
12911             tcg_gen_movi_tl(t0, v2);
12912             tcg_gen_movi_tl(t1, v1);
12913             gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, tcg_env);
12914             break;
12915         case OPC_DEXTR_W:
12916             tcg_gen_movi_tl(t0, v2);
12917             tcg_gen_movi_tl(t1, v1);
12918             gen_helper_dextr_w(cpu_gpr[ret], t0, t1, tcg_env);
12919             break;
12920         case OPC_DEXTR_R_W:
12921             tcg_gen_movi_tl(t0, v2);
12922             tcg_gen_movi_tl(t1, v1);
12923             gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, tcg_env);
12924             break;
12925         case OPC_DEXTR_RS_W:
12926             tcg_gen_movi_tl(t0, v2);
12927             tcg_gen_movi_tl(t1, v1);
12928             gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, tcg_env);
12929             break;
12930         case OPC_DEXTR_S_H:
12931             tcg_gen_movi_tl(t0, v2);
12932             tcg_gen_movi_tl(t1, v1);
12933             gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, tcg_env);
12934             break;
12935         case OPC_DEXTRV_S_H:
12936             tcg_gen_movi_tl(t0, v2);
12937             gen_helper_dextr_s_h(cpu_gpr[ret], t0, v1_t, tcg_env);
12938             break;
12939         case OPC_DEXTRV_L:
12940             tcg_gen_movi_tl(t0, v2);
12941             gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, tcg_env);
12942             break;
12943         case OPC_DEXTRV_R_L:
12944             tcg_gen_movi_tl(t0, v2);
12945             gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, tcg_env);
12946             break;
12947         case OPC_DEXTRV_RS_L:
12948             tcg_gen_movi_tl(t0, v2);
12949             gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, tcg_env);
12950             break;
12951         case OPC_DEXTRV_W:
12952             tcg_gen_movi_tl(t0, v2);
12953             gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, tcg_env);
12954             break;
12955         case OPC_DEXTRV_R_W:
12956             tcg_gen_movi_tl(t0, v2);
12957             gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, tcg_env);
12958             break;
12959         case OPC_DEXTRV_RS_W:
12960             tcg_gen_movi_tl(t0, v2);
12961             gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, tcg_env);
12962             break;
12963         }
12964         break;
12965 #endif
12966     }
12967 }
12968 
12969 /* End MIPSDSP functions. */
12970 
decode_opc_special_r6(CPUMIPSState * env,DisasContext * ctx)12971 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
12972 {
12973     int rs, rt, rd, sa;
12974     uint32_t op1, op2;
12975 
12976     rs = (ctx->opcode >> 21) & 0x1f;
12977     rt = (ctx->opcode >> 16) & 0x1f;
12978     rd = (ctx->opcode >> 11) & 0x1f;
12979     sa = (ctx->opcode >> 6) & 0x1f;
12980 
12981     op1 = MASK_SPECIAL(ctx->opcode);
12982     switch (op1) {
12983     case OPC_MULT:
12984     case OPC_MULTU:
12985     case OPC_DIV:
12986     case OPC_DIVU:
12987         op2 = MASK_R6_MULDIV(ctx->opcode);
12988         switch (op2) {
12989         case R6_OPC_MUL:
12990         case R6_OPC_MUH:
12991         case R6_OPC_MULU:
12992         case R6_OPC_MUHU:
12993         case R6_OPC_DIV:
12994         case R6_OPC_MOD:
12995         case R6_OPC_DIVU:
12996         case R6_OPC_MODU:
12997             gen_r6_muldiv(ctx, op2, rd, rs, rt);
12998             break;
12999         default:
13000             MIPS_INVAL("special_r6 muldiv");
13001             gen_reserved_instruction(ctx);
13002             break;
13003         }
13004         break;
13005     case OPC_SELEQZ:
13006     case OPC_SELNEZ:
13007         gen_cond_move(ctx, op1, rd, rs, rt);
13008         break;
13009     case R6_OPC_CLO:
13010     case R6_OPC_CLZ:
13011         if (rt == 0 && sa == 1) {
13012             /*
13013              * Major opcode and function field is shared with preR6 MFHI/MTHI.
13014              * We need additionally to check other fields.
13015              */
13016             gen_cl(ctx, op1, rd, rs);
13017         } else {
13018             gen_reserved_instruction(ctx);
13019         }
13020         break;
13021     case R6_OPC_SDBBP:
13022         if (is_uhi(ctx, extract32(ctx->opcode, 6, 20))) {
13023             ctx->base.is_jmp = DISAS_SEMIHOST;
13024         } else {
13025             if (ctx->hflags & MIPS_HFLAG_SBRI) {
13026                 gen_reserved_instruction(ctx);
13027             } else {
13028                 generate_exception_end(ctx, EXCP_DBp);
13029             }
13030         }
13031         break;
13032 #if defined(TARGET_MIPS64)
13033     case R6_OPC_DCLO:
13034     case R6_OPC_DCLZ:
13035         if (rt == 0 && sa == 1) {
13036             /*
13037              * Major opcode and function field is shared with preR6 MFHI/MTHI.
13038              * We need additionally to check other fields.
13039              */
13040             check_mips_64(ctx);
13041             gen_cl(ctx, op1, rd, rs);
13042         } else {
13043             gen_reserved_instruction(ctx);
13044         }
13045         break;
13046     case OPC_DMULT:
13047     case OPC_DMULTU:
13048     case OPC_DDIV:
13049     case OPC_DDIVU:
13050 
13051         op2 = MASK_R6_MULDIV(ctx->opcode);
13052         switch (op2) {
13053         case R6_OPC_DMUL:
13054         case R6_OPC_DMUH:
13055         case R6_OPC_DMULU:
13056         case R6_OPC_DMUHU:
13057         case R6_OPC_DDIV:
13058         case R6_OPC_DMOD:
13059         case R6_OPC_DDIVU:
13060         case R6_OPC_DMODU:
13061             check_mips_64(ctx);
13062             gen_r6_muldiv(ctx, op2, rd, rs, rt);
13063             break;
13064         default:
13065             MIPS_INVAL("special_r6 muldiv");
13066             gen_reserved_instruction(ctx);
13067             break;
13068         }
13069         break;
13070 #endif
13071     default:            /* Invalid */
13072         MIPS_INVAL("special_r6");
13073         gen_reserved_instruction(ctx);
13074         break;
13075     }
13076 }
13077 
decode_opc_special_tx79(CPUMIPSState * env,DisasContext * ctx)13078 static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx)
13079 {
13080     int rs = extract32(ctx->opcode, 21, 5);
13081     int rt = extract32(ctx->opcode, 16, 5);
13082     int rd = extract32(ctx->opcode, 11, 5);
13083     uint32_t op1 = MASK_SPECIAL(ctx->opcode);
13084 
13085     switch (op1) {
13086     case OPC_MOVN:         /* Conditional move */
13087     case OPC_MOVZ:
13088         gen_cond_move(ctx, op1, rd, rs, rt);
13089         break;
13090     case OPC_MFHI:          /* Move from HI/LO */
13091     case OPC_MFLO:
13092         gen_HILO(ctx, op1, 0, rd);
13093         break;
13094     case OPC_MTHI:
13095     case OPC_MTLO:          /* Move to HI/LO */
13096         gen_HILO(ctx, op1, 0, rs);
13097         break;
13098     case OPC_MULT:
13099     case OPC_MULTU:
13100         gen_mul_txx9(ctx, op1, rd, rs, rt);
13101         break;
13102     case OPC_DIV:
13103     case OPC_DIVU:
13104         gen_muldiv(ctx, op1, 0, rs, rt);
13105         break;
13106 #if defined(TARGET_MIPS64)
13107     case OPC_DMULT:
13108     case OPC_DMULTU:
13109     case OPC_DDIV:
13110     case OPC_DDIVU:
13111         check_insn_opc_user_only(ctx, INSN_R5900);
13112         gen_muldiv(ctx, op1, 0, rs, rt);
13113         break;
13114 #endif
13115     case OPC_JR:
13116         gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
13117         break;
13118     default:            /* Invalid */
13119         MIPS_INVAL("special_tx79");
13120         gen_reserved_instruction(ctx);
13121         break;
13122     }
13123 }
13124 
decode_opc_special_legacy(CPUMIPSState * env,DisasContext * ctx)13125 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
13126 {
13127     int rs, rt, rd;
13128     uint32_t op1;
13129 
13130     rs = (ctx->opcode >> 21) & 0x1f;
13131     rt = (ctx->opcode >> 16) & 0x1f;
13132     rd = (ctx->opcode >> 11) & 0x1f;
13133 
13134     op1 = MASK_SPECIAL(ctx->opcode);
13135     switch (op1) {
13136     case OPC_MOVN:         /* Conditional move */
13137     case OPC_MOVZ:
13138         check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 |
13139                    INSN_LOONGSON2E | INSN_LOONGSON2F);
13140         gen_cond_move(ctx, op1, rd, rs, rt);
13141         break;
13142     case OPC_MFHI:          /* Move from HI/LO */
13143     case OPC_MFLO:
13144         gen_HILO(ctx, op1, rs & 3, rd);
13145         break;
13146     case OPC_MTHI:
13147     case OPC_MTLO:          /* Move to HI/LO */
13148         gen_HILO(ctx, op1, rd & 3, rs);
13149         break;
13150     case OPC_MOVCI:
13151         check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1);
13152         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
13153             check_cp1_enabled(ctx);
13154             gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
13155                       (ctx->opcode >> 16) & 1);
13156         } else {
13157             generate_exception_err(ctx, EXCP_CpU, 1);
13158         }
13159         break;
13160     case OPC_MULT:
13161     case OPC_MULTU:
13162         gen_muldiv(ctx, op1, rd & 3, rs, rt);
13163         break;
13164     case OPC_DIV:
13165     case OPC_DIVU:
13166         gen_muldiv(ctx, op1, 0, rs, rt);
13167         break;
13168 #if defined(TARGET_MIPS64)
13169     case OPC_DMULT:
13170     case OPC_DMULTU:
13171     case OPC_DDIV:
13172     case OPC_DDIVU:
13173         check_insn(ctx, ISA_MIPS3);
13174         check_mips_64(ctx);
13175         gen_muldiv(ctx, op1, 0, rs, rt);
13176         break;
13177 #endif
13178     case OPC_JR:
13179         gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
13180         break;
13181     case OPC_SPIM:
13182 #ifdef MIPS_STRICT_STANDARD
13183         MIPS_INVAL("SPIM");
13184         gen_reserved_instruction(ctx);
13185 #else
13186         /* Implemented as RI exception for now. */
13187         MIPS_INVAL("spim (unofficial)");
13188         gen_reserved_instruction(ctx);
13189 #endif
13190         break;
13191     default:            /* Invalid */
13192         MIPS_INVAL("special_legacy");
13193         gen_reserved_instruction(ctx);
13194         break;
13195     }
13196 }
13197 
decode_opc_special(CPUMIPSState * env,DisasContext * ctx)13198 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
13199 {
13200     int rs, rt, rd, sa;
13201     uint32_t op1;
13202 
13203     rs = (ctx->opcode >> 21) & 0x1f;
13204     rt = (ctx->opcode >> 16) & 0x1f;
13205     rd = (ctx->opcode >> 11) & 0x1f;
13206     sa = (ctx->opcode >> 6) & 0x1f;
13207 
13208     op1 = MASK_SPECIAL(ctx->opcode);
13209     switch (op1) {
13210     case OPC_SLL:          /* Shift with immediate */
13211         if (sa == 5 && rd == 0 &&
13212             rs == 0 && rt == 0) { /* PAUSE */
13213             if ((ctx->insn_flags & ISA_MIPS_R6) &&
13214                 (ctx->hflags & MIPS_HFLAG_BMASK)) {
13215                 gen_reserved_instruction(ctx);
13216                 break;
13217             }
13218         }
13219         /* Fallthrough */
13220     case OPC_SRA:
13221         gen_shift_imm(ctx, op1, rd, rt, sa);
13222         break;
13223     case OPC_SRL:
13224         switch ((ctx->opcode >> 21) & 0x1f) {
13225         case 1:
13226             /* rotr is decoded as srl on non-R2 CPUs */
13227             if (ctx->insn_flags & ISA_MIPS_R2) {
13228                 op1 = OPC_ROTR;
13229             }
13230             /* Fallthrough */
13231         case 0:
13232             gen_shift_imm(ctx, op1, rd, rt, sa);
13233             break;
13234         default:
13235             gen_reserved_instruction(ctx);
13236             break;
13237         }
13238         break;
13239     case OPC_ADD:
13240     case OPC_ADDU:
13241     case OPC_SUB:
13242     case OPC_SUBU:
13243         gen_arith(ctx, op1, rd, rs, rt);
13244         break;
13245     case OPC_SLLV:         /* Shifts */
13246     case OPC_SRAV:
13247         gen_shift(ctx, op1, rd, rs, rt);
13248         break;
13249     case OPC_SRLV:
13250         switch ((ctx->opcode >> 6) & 0x1f) {
13251         case 1:
13252             /* rotrv is decoded as srlv on non-R2 CPUs */
13253             if (ctx->insn_flags & ISA_MIPS_R2) {
13254                 op1 = OPC_ROTRV;
13255             }
13256             /* Fallthrough */
13257         case 0:
13258             gen_shift(ctx, op1, rd, rs, rt);
13259             break;
13260         default:
13261             gen_reserved_instruction(ctx);
13262             break;
13263         }
13264         break;
13265     case OPC_SLT:          /* Set on less than */
13266     case OPC_SLTU:
13267         gen_slt(ctx, op1, rd, rs, rt);
13268         break;
13269     case OPC_AND:          /* Logic*/
13270     case OPC_OR:
13271     case OPC_NOR:
13272     case OPC_XOR:
13273         gen_logic(ctx, op1, rd, rs, rt);
13274         break;
13275     case OPC_JALR:
13276         gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
13277         break;
13278     case OPC_TGE: /* Traps */
13279     case OPC_TGEU:
13280     case OPC_TLT:
13281     case OPC_TLTU:
13282     case OPC_TEQ:
13283     case OPC_TNE:
13284         check_insn(ctx, ISA_MIPS2);
13285         gen_trap(ctx, op1, rs, rt, -1, extract32(ctx->opcode, 6, 10));
13286         break;
13287     case OPC_PMON:
13288         /* Pmon entry point, also R4010 selsl */
13289 #ifdef MIPS_STRICT_STANDARD
13290         MIPS_INVAL("PMON / selsl");
13291         gen_reserved_instruction(ctx);
13292 #else
13293         gen_helper_pmon(tcg_env, tcg_constant_i32(sa));
13294 #endif
13295         break;
13296     case OPC_SYSCALL:
13297         generate_exception_end(ctx, EXCP_SYSCALL);
13298         break;
13299     case OPC_BREAK:
13300         generate_exception_break(ctx, extract32(ctx->opcode, 6, 20));
13301         break;
13302     case OPC_SYNC:
13303         check_insn(ctx, ISA_MIPS2);
13304         gen_sync(extract32(ctx->opcode, 6, 5));
13305         break;
13306 
13307 #if defined(TARGET_MIPS64)
13308         /* MIPS64 specific opcodes */
13309     case OPC_DSLL:
13310     case OPC_DSRA:
13311     case OPC_DSLL32:
13312     case OPC_DSRA32:
13313         check_insn(ctx, ISA_MIPS3);
13314         check_mips_64(ctx);
13315         gen_shift_imm(ctx, op1, rd, rt, sa);
13316         break;
13317     case OPC_DSRL:
13318         switch ((ctx->opcode >> 21) & 0x1f) {
13319         case 1:
13320             /* drotr is decoded as dsrl on non-R2 CPUs */
13321             if (ctx->insn_flags & ISA_MIPS_R2) {
13322                 op1 = OPC_DROTR;
13323             }
13324             /* Fallthrough */
13325         case 0:
13326             check_insn(ctx, ISA_MIPS3);
13327             check_mips_64(ctx);
13328             gen_shift_imm(ctx, op1, rd, rt, sa);
13329             break;
13330         default:
13331             gen_reserved_instruction(ctx);
13332             break;
13333         }
13334         break;
13335     case OPC_DSRL32:
13336         switch ((ctx->opcode >> 21) & 0x1f) {
13337         case 1:
13338             /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
13339             if (ctx->insn_flags & ISA_MIPS_R2) {
13340                 op1 = OPC_DROTR32;
13341             }
13342             /* Fallthrough */
13343         case 0:
13344             check_insn(ctx, ISA_MIPS3);
13345             check_mips_64(ctx);
13346             gen_shift_imm(ctx, op1, rd, rt, sa);
13347             break;
13348         default:
13349             gen_reserved_instruction(ctx);
13350             break;
13351         }
13352         break;
13353     case OPC_DADD:
13354     case OPC_DADDU:
13355     case OPC_DSUB:
13356     case OPC_DSUBU:
13357         check_insn(ctx, ISA_MIPS3);
13358         check_mips_64(ctx);
13359         gen_arith(ctx, op1, rd, rs, rt);
13360         break;
13361     case OPC_DSLLV:
13362     case OPC_DSRAV:
13363         check_insn(ctx, ISA_MIPS3);
13364         check_mips_64(ctx);
13365         gen_shift(ctx, op1, rd, rs, rt);
13366         break;
13367     case OPC_DSRLV:
13368         switch ((ctx->opcode >> 6) & 0x1f) {
13369         case 1:
13370             /* drotrv is decoded as dsrlv on non-R2 CPUs */
13371             if (ctx->insn_flags & ISA_MIPS_R2) {
13372                 op1 = OPC_DROTRV;
13373             }
13374             /* Fallthrough */
13375         case 0:
13376             check_insn(ctx, ISA_MIPS3);
13377             check_mips_64(ctx);
13378             gen_shift(ctx, op1, rd, rs, rt);
13379             break;
13380         default:
13381             gen_reserved_instruction(ctx);
13382             break;
13383         }
13384         break;
13385 #endif
13386     default:
13387         if (ctx->insn_flags & ISA_MIPS_R6) {
13388             decode_opc_special_r6(env, ctx);
13389         } else if (ctx->insn_flags & INSN_R5900) {
13390             decode_opc_special_tx79(env, ctx);
13391         } else {
13392             decode_opc_special_legacy(env, ctx);
13393         }
13394     }
13395 }
13396 
13397 
decode_opc_special2_legacy(CPUMIPSState * env,DisasContext * ctx)13398 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
13399 {
13400     int rs, rt, rd;
13401     uint32_t op1;
13402 
13403     rs = (ctx->opcode >> 21) & 0x1f;
13404     rt = (ctx->opcode >> 16) & 0x1f;
13405     rd = (ctx->opcode >> 11) & 0x1f;
13406 
13407     op1 = MASK_SPECIAL2(ctx->opcode);
13408     switch (op1) {
13409     case OPC_MADD: /* Multiply and add/sub */
13410     case OPC_MADDU:
13411     case OPC_MSUB:
13412     case OPC_MSUBU:
13413         check_insn(ctx, ISA_MIPS_R1);
13414         gen_muldiv(ctx, op1, rd & 3, rs, rt);
13415         break;
13416     case OPC_MUL:
13417         gen_arith(ctx, op1, rd, rs, rt);
13418         break;
13419     case OPC_CLO:
13420     case OPC_CLZ:
13421         check_insn(ctx, ISA_MIPS_R1);
13422         gen_cl(ctx, op1, rd, rs);
13423         break;
13424     case OPC_SDBBP:
13425         if (is_uhi(ctx, extract32(ctx->opcode, 6, 20))) {
13426             ctx->base.is_jmp = DISAS_SEMIHOST;
13427         } else {
13428             /*
13429              * XXX: not clear which exception should be raised
13430              *      when in debug mode...
13431              */
13432             check_insn(ctx, ISA_MIPS_R1);
13433             generate_exception_end(ctx, EXCP_DBp);
13434         }
13435         break;
13436 #if defined(TARGET_MIPS64)
13437     case OPC_DCLO:
13438     case OPC_DCLZ:
13439         check_insn(ctx, ISA_MIPS_R1);
13440         check_mips_64(ctx);
13441         gen_cl(ctx, op1, rd, rs);
13442         break;
13443 #endif
13444     default:            /* Invalid */
13445         MIPS_INVAL("special2_legacy");
13446         gen_reserved_instruction(ctx);
13447         break;
13448     }
13449 }
13450 
decode_opc_special3_r6(CPUMIPSState * env,DisasContext * ctx)13451 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
13452 {
13453     int rs, rt, rd, sa;
13454     uint32_t op1, op2;
13455     int16_t imm;
13456 
13457     rs = (ctx->opcode >> 21) & 0x1f;
13458     rt = (ctx->opcode >> 16) & 0x1f;
13459     rd = (ctx->opcode >> 11) & 0x1f;
13460     sa = (ctx->opcode >> 6) & 0x1f;
13461     imm = (int16_t)ctx->opcode >> 7;
13462 
13463     op1 = MASK_SPECIAL3(ctx->opcode);
13464     switch (op1) {
13465     case R6_OPC_PREF:
13466         if (rt >= 24) {
13467             /* hint codes 24-31 are reserved and signal RI */
13468             gen_reserved_instruction(ctx);
13469         }
13470         /* Treat as NOP. */
13471         break;
13472     case R6_OPC_CACHE:
13473         check_cp0_enabled(ctx);
13474         if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
13475             gen_cache_operation(ctx, rt, rs, imm);
13476         }
13477         break;
13478     case R6_OPC_SC:
13479         gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_SL, false);
13480         break;
13481     case R6_OPC_LL:
13482         gen_ld(ctx, op1, rt, rs, imm);
13483         break;
13484     case OPC_BSHFL:
13485         {
13486             if (rd == 0) {
13487                 /* Treat as NOP. */
13488                 break;
13489             }
13490             op2 = MASK_BSHFL(ctx->opcode);
13491             switch (op2) {
13492             case OPC_ALIGN:
13493             case OPC_ALIGN_1:
13494             case OPC_ALIGN_2:
13495             case OPC_ALIGN_3:
13496                 gen_align(ctx, 32, rd, rs, rt, sa & 3);
13497                 break;
13498             case OPC_BITSWAP:
13499                 gen_bitswap(ctx, op2, rd, rt);
13500                 break;
13501             }
13502         }
13503         break;
13504 #ifndef CONFIG_USER_ONLY
13505     case OPC_GINV:
13506         if (unlikely(ctx->gi <= 1)) {
13507             gen_reserved_instruction(ctx);
13508         }
13509         check_cp0_enabled(ctx);
13510         switch ((ctx->opcode >> 6) & 3) {
13511         case 0:    /* GINVI */
13512             /* Treat as NOP. */
13513             break;
13514         case 2:    /* GINVT */
13515             gen_helper_0e1i(ginvt, cpu_gpr[rs], extract32(ctx->opcode, 8, 2));
13516             break;
13517         default:
13518             gen_reserved_instruction(ctx);
13519             break;
13520         }
13521         break;
13522 #endif
13523 #if defined(TARGET_MIPS64)
13524     case R6_OPC_SCD:
13525         gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_UQ, false);
13526         break;
13527     case R6_OPC_LLD:
13528         gen_ld(ctx, op1, rt, rs, imm);
13529         break;
13530     case OPC_DBSHFL:
13531         check_mips_64(ctx);
13532         {
13533             if (rd == 0) {
13534                 /* Treat as NOP. */
13535                 break;
13536             }
13537             op2 = MASK_DBSHFL(ctx->opcode);
13538             switch (op2) {
13539             case OPC_DALIGN:
13540             case OPC_DALIGN_1:
13541             case OPC_DALIGN_2:
13542             case OPC_DALIGN_3:
13543             case OPC_DALIGN_4:
13544             case OPC_DALIGN_5:
13545             case OPC_DALIGN_6:
13546             case OPC_DALIGN_7:
13547                 gen_align(ctx, 64, rd, rs, rt, sa & 7);
13548                 break;
13549             case OPC_DBITSWAP:
13550                 gen_bitswap(ctx, op2, rd, rt);
13551                 break;
13552             }
13553 
13554         }
13555         break;
13556 #endif
13557     default:            /* Invalid */
13558         MIPS_INVAL("special3_r6");
13559         gen_reserved_instruction(ctx);
13560         break;
13561     }
13562 }
13563 
decode_opc_special3_legacy(CPUMIPSState * env,DisasContext * ctx)13564 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
13565 {
13566     int rs, rt, rd;
13567     uint32_t op1, op2;
13568 
13569     rs = (ctx->opcode >> 21) & 0x1f;
13570     rt = (ctx->opcode >> 16) & 0x1f;
13571     rd = (ctx->opcode >> 11) & 0x1f;
13572 
13573     op1 = MASK_SPECIAL3(ctx->opcode);
13574     switch (op1) {
13575     case OPC_MUL_PH_DSP:
13576         /*
13577          * OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13578          * the same mask and op1.
13579          */
13580         if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MUL_PH_DSP)) {
13581             op2 = MASK_ADDUH_QB(ctx->opcode);
13582             switch (op2) {
13583             case OPC_ADDUH_QB:
13584             case OPC_ADDUH_R_QB:
13585             case OPC_ADDQH_PH:
13586             case OPC_ADDQH_R_PH:
13587             case OPC_ADDQH_W:
13588             case OPC_ADDQH_R_W:
13589             case OPC_SUBUH_QB:
13590             case OPC_SUBUH_R_QB:
13591             case OPC_SUBQH_PH:
13592             case OPC_SUBQH_R_PH:
13593             case OPC_SUBQH_W:
13594             case OPC_SUBQH_R_W:
13595                 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
13596                 break;
13597             case OPC_MUL_PH:
13598             case OPC_MUL_S_PH:
13599             case OPC_MULQ_S_W:
13600             case OPC_MULQ_RS_W:
13601                 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
13602                 break;
13603             default:
13604                 MIPS_INVAL("MASK ADDUH.QB");
13605                 gen_reserved_instruction(ctx);
13606                 break;
13607             }
13608         } else {
13609             gen_reserved_instruction(ctx);
13610         }
13611         break;
13612     case OPC_LX_DSP:
13613         op2 = MASK_LX(ctx->opcode);
13614         switch (op2) {
13615 #if defined(TARGET_MIPS64)
13616         case OPC_LDX:
13617 #endif
13618         case OPC_LBUX:
13619         case OPC_LHX:
13620         case OPC_LWX:
13621             gen_mips_lx(ctx, op2, rd, rs, rt);
13622             break;
13623         default:            /* Invalid */
13624             MIPS_INVAL("MASK LX");
13625             gen_reserved_instruction(ctx);
13626             break;
13627         }
13628         break;
13629     case OPC_ABSQ_S_PH_DSP:
13630         op2 = MASK_ABSQ_S_PH(ctx->opcode);
13631         switch (op2) {
13632         case OPC_ABSQ_S_QB:
13633         case OPC_ABSQ_S_PH:
13634         case OPC_ABSQ_S_W:
13635         case OPC_PRECEQ_W_PHL:
13636         case OPC_PRECEQ_W_PHR:
13637         case OPC_PRECEQU_PH_QBL:
13638         case OPC_PRECEQU_PH_QBR:
13639         case OPC_PRECEQU_PH_QBLA:
13640         case OPC_PRECEQU_PH_QBRA:
13641         case OPC_PRECEU_PH_QBL:
13642         case OPC_PRECEU_PH_QBR:
13643         case OPC_PRECEU_PH_QBLA:
13644         case OPC_PRECEU_PH_QBRA:
13645             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
13646             break;
13647         case OPC_BITREV:
13648         case OPC_REPL_QB:
13649         case OPC_REPLV_QB:
13650         case OPC_REPL_PH:
13651         case OPC_REPLV_PH:
13652             gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
13653             break;
13654         default:
13655             MIPS_INVAL("MASK ABSQ_S.PH");
13656             gen_reserved_instruction(ctx);
13657             break;
13658         }
13659         break;
13660     case OPC_ADDU_QB_DSP:
13661         op2 = MASK_ADDU_QB(ctx->opcode);
13662         switch (op2) {
13663         case OPC_ADDQ_PH:
13664         case OPC_ADDQ_S_PH:
13665         case OPC_ADDQ_S_W:
13666         case OPC_ADDU_QB:
13667         case OPC_ADDU_S_QB:
13668         case OPC_ADDU_PH:
13669         case OPC_ADDU_S_PH:
13670         case OPC_SUBQ_PH:
13671         case OPC_SUBQ_S_PH:
13672         case OPC_SUBQ_S_W:
13673         case OPC_SUBU_QB:
13674         case OPC_SUBU_S_QB:
13675         case OPC_SUBU_PH:
13676         case OPC_SUBU_S_PH:
13677         case OPC_ADDSC:
13678         case OPC_ADDWC:
13679         case OPC_MODSUB:
13680         case OPC_RADDU_W_QB:
13681             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
13682             break;
13683         case OPC_MULEU_S_PH_QBL:
13684         case OPC_MULEU_S_PH_QBR:
13685         case OPC_MULQ_RS_PH:
13686         case OPC_MULEQ_S_W_PHL:
13687         case OPC_MULEQ_S_W_PHR:
13688         case OPC_MULQ_S_PH:
13689             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
13690             break;
13691         default:            /* Invalid */
13692             MIPS_INVAL("MASK ADDU.QB");
13693             gen_reserved_instruction(ctx);
13694             break;
13695 
13696         }
13697         break;
13698     case OPC_CMPU_EQ_QB_DSP:
13699         op2 = MASK_CMPU_EQ_QB(ctx->opcode);
13700         switch (op2) {
13701         case OPC_PRECR_SRA_PH_W:
13702         case OPC_PRECR_SRA_R_PH_W:
13703             gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
13704             break;
13705         case OPC_PRECR_QB_PH:
13706         case OPC_PRECRQ_QB_PH:
13707         case OPC_PRECRQ_PH_W:
13708         case OPC_PRECRQ_RS_PH_W:
13709         case OPC_PRECRQU_S_QB_PH:
13710             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
13711             break;
13712         case OPC_CMPU_EQ_QB:
13713         case OPC_CMPU_LT_QB:
13714         case OPC_CMPU_LE_QB:
13715         case OPC_CMP_EQ_PH:
13716         case OPC_CMP_LT_PH:
13717         case OPC_CMP_LE_PH:
13718             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
13719             break;
13720         case OPC_CMPGU_EQ_QB:
13721         case OPC_CMPGU_LT_QB:
13722         case OPC_CMPGU_LE_QB:
13723         case OPC_CMPGDU_EQ_QB:
13724         case OPC_CMPGDU_LT_QB:
13725         case OPC_CMPGDU_LE_QB:
13726         case OPC_PICK_QB:
13727         case OPC_PICK_PH:
13728         case OPC_PACKRL_PH:
13729             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
13730             break;
13731         default:            /* Invalid */
13732             MIPS_INVAL("MASK CMPU.EQ.QB");
13733             gen_reserved_instruction(ctx);
13734             break;
13735         }
13736         break;
13737     case OPC_SHLL_QB_DSP:
13738         gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
13739         break;
13740     case OPC_DPA_W_PH_DSP:
13741         op2 = MASK_DPA_W_PH(ctx->opcode);
13742         switch (op2) {
13743         case OPC_DPAU_H_QBL:
13744         case OPC_DPAU_H_QBR:
13745         case OPC_DPSU_H_QBL:
13746         case OPC_DPSU_H_QBR:
13747         case OPC_DPA_W_PH:
13748         case OPC_DPAX_W_PH:
13749         case OPC_DPAQ_S_W_PH:
13750         case OPC_DPAQX_S_W_PH:
13751         case OPC_DPAQX_SA_W_PH:
13752         case OPC_DPS_W_PH:
13753         case OPC_DPSX_W_PH:
13754         case OPC_DPSQ_S_W_PH:
13755         case OPC_DPSQX_S_W_PH:
13756         case OPC_DPSQX_SA_W_PH:
13757         case OPC_MULSAQ_S_W_PH:
13758         case OPC_DPAQ_SA_L_W:
13759         case OPC_DPSQ_SA_L_W:
13760         case OPC_MAQ_S_W_PHL:
13761         case OPC_MAQ_S_W_PHR:
13762         case OPC_MAQ_SA_W_PHL:
13763         case OPC_MAQ_SA_W_PHR:
13764         case OPC_MULSA_W_PH:
13765             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
13766             break;
13767         default:            /* Invalid */
13768             MIPS_INVAL("MASK DPAW.PH");
13769             gen_reserved_instruction(ctx);
13770             break;
13771         }
13772         break;
13773     case OPC_INSV_DSP:
13774         op2 = MASK_INSV(ctx->opcode);
13775         switch (op2) {
13776         case OPC_INSV:
13777             check_dsp(ctx);
13778             {
13779                 TCGv t0, t1;
13780 
13781                 if (rt == 0) {
13782                     break;
13783                 }
13784 
13785                 t0 = tcg_temp_new();
13786                 t1 = tcg_temp_new();
13787 
13788                 gen_load_gpr(t0, rt);
13789                 gen_load_gpr(t1, rs);
13790 
13791                 gen_helper_insv(cpu_gpr[rt], tcg_env, t1, t0);
13792                 break;
13793             }
13794         default:            /* Invalid */
13795             MIPS_INVAL("MASK INSV");
13796             gen_reserved_instruction(ctx);
13797             break;
13798         }
13799         break;
13800     case OPC_APPEND_DSP:
13801         gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
13802         break;
13803     case OPC_EXTR_W_DSP:
13804         op2 = MASK_EXTR_W(ctx->opcode);
13805         switch (op2) {
13806         case OPC_EXTR_W:
13807         case OPC_EXTR_R_W:
13808         case OPC_EXTR_RS_W:
13809         case OPC_EXTR_S_H:
13810         case OPC_EXTRV_S_H:
13811         case OPC_EXTRV_W:
13812         case OPC_EXTRV_R_W:
13813         case OPC_EXTRV_RS_W:
13814         case OPC_EXTP:
13815         case OPC_EXTPV:
13816         case OPC_EXTPDP:
13817         case OPC_EXTPDPV:
13818             gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
13819             break;
13820         case OPC_RDDSP:
13821             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
13822             break;
13823         case OPC_SHILO:
13824         case OPC_SHILOV:
13825         case OPC_MTHLIP:
13826         case OPC_WRDSP:
13827             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
13828             break;
13829         default:            /* Invalid */
13830             MIPS_INVAL("MASK EXTR.W");
13831             gen_reserved_instruction(ctx);
13832             break;
13833         }
13834         break;
13835 #if defined(TARGET_MIPS64)
13836     case OPC_ABSQ_S_QH_DSP:
13837         op2 = MASK_ABSQ_S_QH(ctx->opcode);
13838         switch (op2) {
13839         case OPC_PRECEQ_L_PWL:
13840         case OPC_PRECEQ_L_PWR:
13841         case OPC_PRECEQ_PW_QHL:
13842         case OPC_PRECEQ_PW_QHR:
13843         case OPC_PRECEQ_PW_QHLA:
13844         case OPC_PRECEQ_PW_QHRA:
13845         case OPC_PRECEQU_QH_OBL:
13846         case OPC_PRECEQU_QH_OBR:
13847         case OPC_PRECEQU_QH_OBLA:
13848         case OPC_PRECEQU_QH_OBRA:
13849         case OPC_PRECEU_QH_OBL:
13850         case OPC_PRECEU_QH_OBR:
13851         case OPC_PRECEU_QH_OBLA:
13852         case OPC_PRECEU_QH_OBRA:
13853         case OPC_ABSQ_S_OB:
13854         case OPC_ABSQ_S_PW:
13855         case OPC_ABSQ_S_QH:
13856             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
13857             break;
13858         case OPC_REPL_OB:
13859         case OPC_REPL_PW:
13860         case OPC_REPL_QH:
13861         case OPC_REPLV_OB:
13862         case OPC_REPLV_PW:
13863         case OPC_REPLV_QH:
13864             gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
13865             break;
13866         default:            /* Invalid */
13867             MIPS_INVAL("MASK ABSQ_S.QH");
13868             gen_reserved_instruction(ctx);
13869             break;
13870         }
13871         break;
13872     case OPC_ADDU_OB_DSP:
13873         op2 = MASK_ADDU_OB(ctx->opcode);
13874         switch (op2) {
13875         case OPC_RADDU_L_OB:
13876         case OPC_SUBQ_PW:
13877         case OPC_SUBQ_S_PW:
13878         case OPC_SUBQ_QH:
13879         case OPC_SUBQ_S_QH:
13880         case OPC_SUBU_OB:
13881         case OPC_SUBU_S_OB:
13882         case OPC_SUBU_QH:
13883         case OPC_SUBU_S_QH:
13884         case OPC_SUBUH_OB:
13885         case OPC_SUBUH_R_OB:
13886         case OPC_ADDQ_PW:
13887         case OPC_ADDQ_S_PW:
13888         case OPC_ADDQ_QH:
13889         case OPC_ADDQ_S_QH:
13890         case OPC_ADDU_OB:
13891         case OPC_ADDU_S_OB:
13892         case OPC_ADDU_QH:
13893         case OPC_ADDU_S_QH:
13894         case OPC_ADDUH_OB:
13895         case OPC_ADDUH_R_OB:
13896             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
13897             break;
13898         case OPC_MULEQ_S_PW_QHL:
13899         case OPC_MULEQ_S_PW_QHR:
13900         case OPC_MULEU_S_QH_OBL:
13901         case OPC_MULEU_S_QH_OBR:
13902         case OPC_MULQ_RS_QH:
13903             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
13904             break;
13905         default:            /* Invalid */
13906             MIPS_INVAL("MASK ADDU.OB");
13907             gen_reserved_instruction(ctx);
13908             break;
13909         }
13910         break;
13911     case OPC_CMPU_EQ_OB_DSP:
13912         op2 = MASK_CMPU_EQ_OB(ctx->opcode);
13913         switch (op2) {
13914         case OPC_PRECR_SRA_QH_PW:
13915         case OPC_PRECR_SRA_R_QH_PW:
13916             /* Return value is rt. */
13917             gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
13918             break;
13919         case OPC_PRECR_OB_QH:
13920         case OPC_PRECRQ_OB_QH:
13921         case OPC_PRECRQ_PW_L:
13922         case OPC_PRECRQ_QH_PW:
13923         case OPC_PRECRQ_RS_QH_PW:
13924         case OPC_PRECRQU_S_OB_QH:
13925             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
13926             break;
13927         case OPC_CMPU_EQ_OB:
13928         case OPC_CMPU_LT_OB:
13929         case OPC_CMPU_LE_OB:
13930         case OPC_CMP_EQ_QH:
13931         case OPC_CMP_LT_QH:
13932         case OPC_CMP_LE_QH:
13933         case OPC_CMP_EQ_PW:
13934         case OPC_CMP_LT_PW:
13935         case OPC_CMP_LE_PW:
13936             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
13937             break;
13938         case OPC_CMPGDU_EQ_OB:
13939         case OPC_CMPGDU_LT_OB:
13940         case OPC_CMPGDU_LE_OB:
13941         case OPC_CMPGU_EQ_OB:
13942         case OPC_CMPGU_LT_OB:
13943         case OPC_CMPGU_LE_OB:
13944         case OPC_PACKRL_PW:
13945         case OPC_PICK_OB:
13946         case OPC_PICK_PW:
13947         case OPC_PICK_QH:
13948             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
13949             break;
13950         default:            /* Invalid */
13951             MIPS_INVAL("MASK CMPU_EQ.OB");
13952             gen_reserved_instruction(ctx);
13953             break;
13954         }
13955         break;
13956     case OPC_DAPPEND_DSP:
13957         gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
13958         break;
13959     case OPC_DEXTR_W_DSP:
13960         op2 = MASK_DEXTR_W(ctx->opcode);
13961         switch (op2) {
13962         case OPC_DEXTP:
13963         case OPC_DEXTPDP:
13964         case OPC_DEXTPDPV:
13965         case OPC_DEXTPV:
13966         case OPC_DEXTR_L:
13967         case OPC_DEXTR_R_L:
13968         case OPC_DEXTR_RS_L:
13969         case OPC_DEXTR_W:
13970         case OPC_DEXTR_R_W:
13971         case OPC_DEXTR_RS_W:
13972         case OPC_DEXTR_S_H:
13973         case OPC_DEXTRV_L:
13974         case OPC_DEXTRV_R_L:
13975         case OPC_DEXTRV_RS_L:
13976         case OPC_DEXTRV_S_H:
13977         case OPC_DEXTRV_W:
13978         case OPC_DEXTRV_R_W:
13979         case OPC_DEXTRV_RS_W:
13980             gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
13981             break;
13982         case OPC_DMTHLIP:
13983         case OPC_DSHILO:
13984         case OPC_DSHILOV:
13985             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
13986             break;
13987         default:            /* Invalid */
13988             MIPS_INVAL("MASK EXTR.W");
13989             gen_reserved_instruction(ctx);
13990             break;
13991         }
13992         break;
13993     case OPC_DPAQ_W_QH_DSP:
13994         op2 = MASK_DPAQ_W_QH(ctx->opcode);
13995         switch (op2) {
13996         case OPC_DPAU_H_OBL:
13997         case OPC_DPAU_H_OBR:
13998         case OPC_DPSU_H_OBL:
13999         case OPC_DPSU_H_OBR:
14000         case OPC_DPA_W_QH:
14001         case OPC_DPAQ_S_W_QH:
14002         case OPC_DPS_W_QH:
14003         case OPC_DPSQ_S_W_QH:
14004         case OPC_MULSAQ_S_W_QH:
14005         case OPC_DPAQ_SA_L_PW:
14006         case OPC_DPSQ_SA_L_PW:
14007         case OPC_MULSAQ_S_L_PW:
14008             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14009             break;
14010         case OPC_MAQ_S_W_QHLL:
14011         case OPC_MAQ_S_W_QHLR:
14012         case OPC_MAQ_S_W_QHRL:
14013         case OPC_MAQ_S_W_QHRR:
14014         case OPC_MAQ_SA_W_QHLL:
14015         case OPC_MAQ_SA_W_QHLR:
14016         case OPC_MAQ_SA_W_QHRL:
14017         case OPC_MAQ_SA_W_QHRR:
14018         case OPC_MAQ_S_L_PWL:
14019         case OPC_MAQ_S_L_PWR:
14020         case OPC_DMADD:
14021         case OPC_DMADDU:
14022         case OPC_DMSUB:
14023         case OPC_DMSUBU:
14024             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14025             break;
14026         default:            /* Invalid */
14027             MIPS_INVAL("MASK DPAQ.W.QH");
14028             gen_reserved_instruction(ctx);
14029             break;
14030         }
14031         break;
14032     case OPC_DINSV_DSP:
14033         op2 = MASK_INSV(ctx->opcode);
14034         switch (op2) {
14035         case OPC_DINSV:
14036         {
14037             TCGv t0, t1;
14038 
14039             check_dsp(ctx);
14040 
14041             if (rt == 0) {
14042                 break;
14043             }
14044 
14045             t0 = tcg_temp_new();
14046             t1 = tcg_temp_new();
14047 
14048             gen_load_gpr(t0, rt);
14049             gen_load_gpr(t1, rs);
14050 
14051             gen_helper_dinsv(cpu_gpr[rt], tcg_env, t1, t0);
14052             break;
14053         }
14054         default:            /* Invalid */
14055             MIPS_INVAL("MASK DINSV");
14056             gen_reserved_instruction(ctx);
14057             break;
14058         }
14059         break;
14060     case OPC_SHLL_OB_DSP:
14061         gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14062         break;
14063 #endif
14064     default:            /* Invalid */
14065         MIPS_INVAL("special3_legacy");
14066         gen_reserved_instruction(ctx);
14067         break;
14068     }
14069 }
14070 
14071 
14072 #if defined(TARGET_MIPS64)
14073 
decode_mmi(CPUMIPSState * env,DisasContext * ctx)14074 static void decode_mmi(CPUMIPSState *env, DisasContext *ctx)
14075 {
14076     uint32_t opc = MASK_MMI(ctx->opcode);
14077     int rs = extract32(ctx->opcode, 21, 5);
14078     int rt = extract32(ctx->opcode, 16, 5);
14079     int rd = extract32(ctx->opcode, 11, 5);
14080 
14081     switch (opc) {
14082     case MMI_OPC_MULT1:
14083     case MMI_OPC_MULTU1:
14084     case MMI_OPC_MADD:
14085     case MMI_OPC_MADDU:
14086     case MMI_OPC_MADD1:
14087     case MMI_OPC_MADDU1:
14088         gen_mul_txx9(ctx, opc, rd, rs, rt);
14089         break;
14090     case MMI_OPC_DIV1:
14091     case MMI_OPC_DIVU1:
14092         gen_div1_tx79(ctx, opc, rs, rt);
14093         break;
14094     default:
14095         MIPS_INVAL("TX79 MMI class");
14096         gen_reserved_instruction(ctx);
14097         break;
14098     }
14099 }
14100 
gen_mmi_sq(DisasContext * ctx,int base,int rt,int offset)14101 static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset)
14102 {
14103     gen_reserved_instruction(ctx);    /* TODO: MMI_OPC_SQ */
14104 }
14105 
14106 /*
14107  * The TX79-specific instruction Store Quadword
14108  *
14109  * +--------+-------+-------+------------------------+
14110  * | 011111 |  base |   rt  |           offset       | SQ
14111  * +--------+-------+-------+------------------------+
14112  *      6       5       5                 16
14113  *
14114  * has the same opcode as the Read Hardware Register instruction
14115  *
14116  * +--------+-------+-------+-------+-------+--------+
14117  * | 011111 | 00000 |   rt  |   rd  | 00000 | 111011 | RDHWR
14118  * +--------+-------+-------+-------+-------+--------+
14119  *      6       5       5       5       5        6
14120  *
14121  * that is required, trapped and emulated by the Linux kernel. However, all
14122  * RDHWR encodings yield address error exceptions on the TX79 since the SQ
14123  * offset is odd. Therefore all valid SQ instructions can execute normally.
14124  * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
14125  * between SQ and RDHWR, as the Linux kernel does.
14126  */
decode_mmi_sq(CPUMIPSState * env,DisasContext * ctx)14127 static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx)
14128 {
14129     int base = extract32(ctx->opcode, 21, 5);
14130     int rt = extract32(ctx->opcode, 16, 5);
14131     int offset = extract32(ctx->opcode, 0, 16);
14132 
14133 #ifdef CONFIG_USER_ONLY
14134     uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
14135     uint32_t op2 = extract32(ctx->opcode, 6, 5);
14136 
14137     if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
14138         int rd = extract32(ctx->opcode, 11, 5);
14139 
14140         gen_rdhwr(ctx, rt, rd, 0);
14141         return;
14142     }
14143 #endif
14144 
14145     gen_mmi_sq(ctx, base, rt, offset);
14146 }
14147 
14148 #endif
14149 
decode_opc_special3(CPUMIPSState * env,DisasContext * ctx)14150 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
14151 {
14152     int rs, rt, rd, sa;
14153     uint32_t op1, op2;
14154     int16_t imm;
14155 
14156     rs = (ctx->opcode >> 21) & 0x1f;
14157     rt = (ctx->opcode >> 16) & 0x1f;
14158     rd = (ctx->opcode >> 11) & 0x1f;
14159     sa = (ctx->opcode >> 6) & 0x1f;
14160     imm = sextract32(ctx->opcode, 7, 9);
14161 
14162     op1 = MASK_SPECIAL3(ctx->opcode);
14163 
14164     /*
14165      * EVA loads and stores overlap Loongson 2E instructions decoded by
14166      * decode_opc_special3_legacy(), so be careful to allow their decoding when
14167      * EVA is absent.
14168      */
14169     if (ctx->eva) {
14170         switch (op1) {
14171         case OPC_LWLE:
14172         case OPC_LWRE:
14173         case OPC_LBUE:
14174         case OPC_LHUE:
14175         case OPC_LBE:
14176         case OPC_LHE:
14177         case OPC_LLE:
14178         case OPC_LWE:
14179             check_cp0_enabled(ctx);
14180             gen_ld(ctx, op1, rt, rs, imm);
14181             return;
14182         case OPC_SWLE:
14183         case OPC_SWRE:
14184         case OPC_SBE:
14185         case OPC_SHE:
14186         case OPC_SWE:
14187             check_cp0_enabled(ctx);
14188             gen_st(ctx, op1, rt, rs, imm);
14189             return;
14190         case OPC_SCE:
14191             check_cp0_enabled(ctx);
14192             gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_SL, true);
14193             return;
14194         case OPC_CACHEE:
14195             check_eva(ctx);
14196             check_cp0_enabled(ctx);
14197             if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
14198                 gen_cache_operation(ctx, rt, rs, imm);
14199             }
14200             return;
14201         case OPC_PREFE:
14202             check_cp0_enabled(ctx);
14203             /* Treat as NOP. */
14204             return;
14205         }
14206     }
14207 
14208     switch (op1) {
14209     case OPC_EXT:
14210     case OPC_INS:
14211         check_insn(ctx, ISA_MIPS_R2);
14212         gen_bitops(ctx, op1, rt, rs, sa, rd);
14213         break;
14214     case OPC_BSHFL:
14215         op2 = MASK_BSHFL(ctx->opcode);
14216         switch (op2) {
14217         case OPC_ALIGN:
14218         case OPC_ALIGN_1:
14219         case OPC_ALIGN_2:
14220         case OPC_ALIGN_3:
14221         case OPC_BITSWAP:
14222             check_insn(ctx, ISA_MIPS_R6);
14223             decode_opc_special3_r6(env, ctx);
14224             break;
14225         default:
14226             check_insn(ctx, ISA_MIPS_R2);
14227             gen_bshfl(ctx, op2, rt, rd);
14228             break;
14229         }
14230         break;
14231 #if defined(TARGET_MIPS64)
14232     case OPC_DEXTM:
14233     case OPC_DEXTU:
14234     case OPC_DEXT:
14235     case OPC_DINSM:
14236     case OPC_DINSU:
14237     case OPC_DINS:
14238         check_insn(ctx, ISA_MIPS_R2);
14239         check_mips_64(ctx);
14240         gen_bitops(ctx, op1, rt, rs, sa, rd);
14241         break;
14242     case OPC_DBSHFL:
14243         op2 = MASK_DBSHFL(ctx->opcode);
14244         switch (op2) {
14245         case OPC_DALIGN:
14246         case OPC_DALIGN_1:
14247         case OPC_DALIGN_2:
14248         case OPC_DALIGN_3:
14249         case OPC_DALIGN_4:
14250         case OPC_DALIGN_5:
14251         case OPC_DALIGN_6:
14252         case OPC_DALIGN_7:
14253         case OPC_DBITSWAP:
14254             check_insn(ctx, ISA_MIPS_R6);
14255             decode_opc_special3_r6(env, ctx);
14256             break;
14257         default:
14258             check_insn(ctx, ISA_MIPS_R2);
14259             check_mips_64(ctx);
14260             op2 = MASK_DBSHFL(ctx->opcode);
14261             gen_bshfl(ctx, op2, rt, rd);
14262             break;
14263         }
14264         break;
14265 #endif
14266     case OPC_RDHWR:
14267         gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
14268         break;
14269     case OPC_FORK:
14270         check_mt(ctx);
14271         {
14272             TCGv t0 = tcg_temp_new();
14273             TCGv t1 = tcg_temp_new();
14274 
14275             gen_load_gpr(t0, rt);
14276             gen_load_gpr(t1, rs);
14277             gen_helper_fork(t0, t1);
14278         }
14279         break;
14280     case OPC_YIELD:
14281         check_mt(ctx);
14282         {
14283             TCGv t0 = tcg_temp_new();
14284 
14285             gen_load_gpr(t0, rs);
14286             gen_helper_yield(t0, tcg_env, t0);
14287             gen_store_gpr(t0, rd);
14288         }
14289         break;
14290     default:
14291         if (ctx->insn_flags & ISA_MIPS_R6) {
14292             decode_opc_special3_r6(env, ctx);
14293         } else {
14294             decode_opc_special3_legacy(env, ctx);
14295         }
14296     }
14297 }
14298 
decode_opc_legacy(CPUMIPSState * env,DisasContext * ctx)14299 static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx)
14300 {
14301     int32_t offset;
14302     int rs, rt, rd, sa;
14303     uint32_t op, op1;
14304     int16_t imm;
14305 
14306     op = MASK_OP_MAJOR(ctx->opcode);
14307     rs = (ctx->opcode >> 21) & 0x1f;
14308     rt = (ctx->opcode >> 16) & 0x1f;
14309     rd = (ctx->opcode >> 11) & 0x1f;
14310     sa = (ctx->opcode >> 6) & 0x1f;
14311     imm = (int16_t)ctx->opcode;
14312     switch (op) {
14313     case OPC_SPECIAL:
14314         decode_opc_special(env, ctx);
14315         break;
14316     case OPC_SPECIAL2:
14317 #if defined(TARGET_MIPS64)
14318         if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
14319             decode_mmi(env, ctx);
14320             break;
14321         }
14322 #endif
14323         if (TARGET_LONG_BITS == 32 && (ctx->insn_flags & ASE_MXU)) {
14324             if (decode_ase_mxu(ctx, ctx->opcode)) {
14325                 break;
14326             }
14327         }
14328         decode_opc_special2_legacy(env, ctx);
14329         break;
14330     case OPC_SPECIAL3:
14331 #if defined(TARGET_MIPS64)
14332         if (ctx->insn_flags & INSN_R5900) {
14333             decode_mmi_sq(env, ctx);    /* MMI_OPC_SQ */
14334         } else {
14335             decode_opc_special3(env, ctx);
14336         }
14337 #else
14338         decode_opc_special3(env, ctx);
14339 #endif
14340         break;
14341     case OPC_REGIMM:
14342         op1 = MASK_REGIMM(ctx->opcode);
14343         switch (op1) {
14344         case OPC_BLTZL: /* REGIMM branches */
14345         case OPC_BGEZL:
14346         case OPC_BLTZALL:
14347         case OPC_BGEZALL:
14348             check_insn(ctx, ISA_MIPS2);
14349             check_insn_opc_removed(ctx, ISA_MIPS_R6);
14350             /* Fallthrough */
14351         case OPC_BLTZ:
14352         case OPC_BGEZ:
14353             gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
14354             break;
14355         case OPC_BLTZAL:
14356         case OPC_BGEZAL:
14357             if (ctx->insn_flags & ISA_MIPS_R6) {
14358                 if (rs == 0) {
14359                     /* OPC_NAL, OPC_BAL */
14360                     gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
14361                 } else {
14362                     gen_reserved_instruction(ctx);
14363                 }
14364             } else {
14365                 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
14366             }
14367             break;
14368         case OPC_TGEI: /* REGIMM traps */
14369         case OPC_TGEIU:
14370         case OPC_TLTI:
14371         case OPC_TLTIU:
14372         case OPC_TEQI:
14373         case OPC_TNEI:
14374             check_insn(ctx, ISA_MIPS2);
14375             check_insn_opc_removed(ctx, ISA_MIPS_R6);
14376             gen_trap(ctx, op1, rs, -1, imm, 0);
14377             break;
14378         case OPC_SIGRIE:
14379             check_insn(ctx, ISA_MIPS_R6);
14380             gen_reserved_instruction(ctx);
14381             break;
14382         case OPC_SYNCI:
14383             check_insn(ctx, ISA_MIPS_R2);
14384             /*
14385              * Break the TB to be able to sync copied instructions
14386              * immediately.
14387              */
14388             ctx->base.is_jmp = DISAS_STOP;
14389             break;
14390         case OPC_BPOSGE32:    /* MIPS DSP branch */
14391 #if defined(TARGET_MIPS64)
14392         case OPC_BPOSGE64:
14393 #endif
14394             check_dsp(ctx);
14395             gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
14396             break;
14397 #if defined(TARGET_MIPS64)
14398         case OPC_DAHI:
14399             check_insn(ctx, ISA_MIPS_R6);
14400             check_mips_64(ctx);
14401             if (rs != 0) {
14402                 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
14403             }
14404             break;
14405         case OPC_DATI:
14406             check_insn(ctx, ISA_MIPS_R6);
14407             check_mips_64(ctx);
14408             if (rs != 0) {
14409                 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
14410             }
14411             break;
14412 #endif
14413         default:            /* Invalid */
14414             MIPS_INVAL("regimm");
14415             gen_reserved_instruction(ctx);
14416             break;
14417         }
14418         break;
14419     case OPC_CP0:
14420         check_cp0_enabled(ctx);
14421         op1 = MASK_CP0(ctx->opcode);
14422         switch (op1) {
14423         case OPC_MFC0:
14424         case OPC_MTC0:
14425         case OPC_MFTR:
14426         case OPC_MTTR:
14427         case OPC_MFHC0:
14428         case OPC_MTHC0:
14429 #if defined(TARGET_MIPS64)
14430         case OPC_DMFC0:
14431         case OPC_DMTC0:
14432 #endif
14433 #ifndef CONFIG_USER_ONLY
14434             gen_cp0(env, ctx, op1, rt, rd);
14435 #endif /* !CONFIG_USER_ONLY */
14436             break;
14437         case OPC_C0:
14438         case OPC_C0_1:
14439         case OPC_C0_2:
14440         case OPC_C0_3:
14441         case OPC_C0_4:
14442         case OPC_C0_5:
14443         case OPC_C0_6:
14444         case OPC_C0_7:
14445         case OPC_C0_8:
14446         case OPC_C0_9:
14447         case OPC_C0_A:
14448         case OPC_C0_B:
14449         case OPC_C0_C:
14450         case OPC_C0_D:
14451         case OPC_C0_E:
14452         case OPC_C0_F:
14453 #ifndef CONFIG_USER_ONLY
14454             gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
14455 #endif /* !CONFIG_USER_ONLY */
14456             break;
14457         case OPC_MFMC0:
14458 #ifndef CONFIG_USER_ONLY
14459             {
14460                 uint32_t op2;
14461                 TCGv t0 = tcg_temp_new();
14462 
14463                 op2 = MASK_MFMC0(ctx->opcode);
14464                 switch (op2) {
14465                 case OPC_DMT:
14466                     check_cp0_mt(ctx);
14467                     gen_helper_dmt(t0);
14468                     gen_store_gpr(t0, rt);
14469                     break;
14470                 case OPC_EMT:
14471                     check_cp0_mt(ctx);
14472                     gen_helper_emt(t0);
14473                     gen_store_gpr(t0, rt);
14474                     break;
14475                 case OPC_DVPE:
14476                     check_cp0_mt(ctx);
14477                     gen_helper_dvpe(t0, tcg_env);
14478                     gen_store_gpr(t0, rt);
14479                     break;
14480                 case OPC_EVPE:
14481                     check_cp0_mt(ctx);
14482                     gen_helper_evpe(t0, tcg_env);
14483                     gen_store_gpr(t0, rt);
14484                     break;
14485                 case OPC_DVP:
14486                     check_insn(ctx, ISA_MIPS_R6);
14487                     if (ctx->vp) {
14488                         gen_helper_dvp(t0, tcg_env);
14489                         gen_store_gpr(t0, rt);
14490                     }
14491                     break;
14492                 case OPC_EVP:
14493                     check_insn(ctx, ISA_MIPS_R6);
14494                     if (ctx->vp) {
14495                         gen_helper_evp(t0, tcg_env);
14496                         gen_store_gpr(t0, rt);
14497                     }
14498                     break;
14499                 case OPC_DI:
14500                     check_insn(ctx, ISA_MIPS_R2);
14501                     save_cpu_state(ctx, 1);
14502                     gen_helper_di(t0, tcg_env);
14503                     gen_store_gpr(t0, rt);
14504                     /*
14505                      * Stop translation as we may have switched
14506                      * the execution mode.
14507                      */
14508                     ctx->base.is_jmp = DISAS_STOP;
14509                     break;
14510                 case OPC_EI:
14511                     check_insn(ctx, ISA_MIPS_R2);
14512                     save_cpu_state(ctx, 1);
14513                     gen_helper_ei(t0, tcg_env);
14514                     gen_store_gpr(t0, rt);
14515                     /*
14516                      * DISAS_STOP isn't sufficient, we need to ensure we break
14517                      * out of translated code to check for pending interrupts.
14518                      */
14519                     gen_save_pc(ctx->base.pc_next + 4);
14520                     ctx->base.is_jmp = DISAS_EXIT;
14521                     break;
14522                 default:            /* Invalid */
14523                     MIPS_INVAL("mfmc0");
14524                     gen_reserved_instruction(ctx);
14525                     break;
14526                 }
14527             }
14528 #endif /* !CONFIG_USER_ONLY */
14529             break;
14530         case OPC_RDPGPR:
14531             check_insn(ctx, ISA_MIPS_R2);
14532             gen_load_srsgpr(rt, rd);
14533             break;
14534         case OPC_WRPGPR:
14535             check_insn(ctx, ISA_MIPS_R2);
14536             gen_store_srsgpr(rt, rd);
14537             break;
14538         default:
14539             MIPS_INVAL("cp0");
14540             gen_reserved_instruction(ctx);
14541             break;
14542         }
14543         break;
14544     case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
14545         if (ctx->insn_flags & ISA_MIPS_R6) {
14546             /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
14547             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
14548         } else {
14549             /* OPC_ADDI */
14550             /* Arithmetic with immediate opcode */
14551             gen_arith_imm(ctx, op, rt, rs, imm);
14552         }
14553         break;
14554     case OPC_ADDIU:
14555          gen_arith_imm(ctx, op, rt, rs, imm);
14556          break;
14557     case OPC_SLTI: /* Set on less than with immediate opcode */
14558     case OPC_SLTIU:
14559          gen_slt_imm(ctx, op, rt, rs, imm);
14560          break;
14561     case OPC_ANDI: /* Arithmetic with immediate opcode */
14562     case OPC_LUI: /* OPC_AUI */
14563     case OPC_ORI:
14564     case OPC_XORI:
14565          gen_logic_imm(ctx, op, rt, rs, imm);
14566          break;
14567     case OPC_J: /* Jump */
14568     case OPC_JAL:
14569          offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
14570          gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
14571          break;
14572     /* Branch */
14573     case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
14574         if (ctx->insn_flags & ISA_MIPS_R6) {
14575             if (rt == 0) {
14576                 gen_reserved_instruction(ctx);
14577                 break;
14578             }
14579             /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
14580             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
14581         } else {
14582             /* OPC_BLEZL */
14583             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
14584         }
14585         break;
14586     case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
14587         if (ctx->insn_flags & ISA_MIPS_R6) {
14588             if (rt == 0) {
14589                 gen_reserved_instruction(ctx);
14590                 break;
14591             }
14592             /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
14593             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
14594         } else {
14595             /* OPC_BGTZL */
14596             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
14597         }
14598         break;
14599     case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
14600         if (rt == 0) {
14601             /* OPC_BLEZ */
14602             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
14603         } else {
14604             check_insn(ctx, ISA_MIPS_R6);
14605             /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
14606             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
14607         }
14608         break;
14609     case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
14610         if (rt == 0) {
14611             /* OPC_BGTZ */
14612             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
14613         } else {
14614             check_insn(ctx, ISA_MIPS_R6);
14615             /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
14616             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
14617         }
14618         break;
14619     case OPC_BEQL:
14620     case OPC_BNEL:
14621         check_insn(ctx, ISA_MIPS2);
14622          check_insn_opc_removed(ctx, ISA_MIPS_R6);
14623         /* Fallthrough */
14624     case OPC_BEQ:
14625     case OPC_BNE:
14626          gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
14627          break;
14628     case OPC_LL: /* Load and stores */
14629         check_insn(ctx, ISA_MIPS2);
14630         if (ctx->insn_flags & INSN_R5900) {
14631             check_insn_opc_user_only(ctx, INSN_R5900);
14632         }
14633         /* Fallthrough */
14634     case OPC_LWL:
14635     case OPC_LWR:
14636     case OPC_LB:
14637     case OPC_LH:
14638     case OPC_LW:
14639     case OPC_LWPC:
14640     case OPC_LBU:
14641     case OPC_LHU:
14642          gen_ld(ctx, op, rt, rs, imm);
14643          break;
14644     case OPC_SWL:
14645     case OPC_SWR:
14646     case OPC_SB:
14647     case OPC_SH:
14648     case OPC_SW:
14649          gen_st(ctx, op, rt, rs, imm);
14650          break;
14651     case OPC_SC:
14652         check_insn(ctx, ISA_MIPS2);
14653         if (ctx->insn_flags & INSN_R5900) {
14654             check_insn_opc_user_only(ctx, INSN_R5900);
14655         }
14656         gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_SL, false);
14657         break;
14658     case OPC_CACHE:
14659         check_cp0_enabled(ctx);
14660         check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1);
14661         if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
14662             gen_cache_operation(ctx, rt, rs, imm);
14663         }
14664         /* Treat as NOP. */
14665         break;
14666     case OPC_PREF:
14667         check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 | INSN_R5900);
14668         /* Treat as NOP. */
14669         break;
14670 
14671     /* Floating point (COP1). */
14672     case OPC_LWC1:
14673     case OPC_LDC1:
14674     case OPC_SWC1:
14675     case OPC_SDC1:
14676         gen_cop1_ldst(ctx, op, rt, rs, imm);
14677         break;
14678 
14679     case OPC_CP1:
14680         op1 = MASK_CP1(ctx->opcode);
14681 
14682         switch (op1) {
14683         case OPC_MFHC1:
14684         case OPC_MTHC1:
14685             check_cp1_enabled(ctx);
14686             check_insn(ctx, ISA_MIPS_R2);
14687             /* fall through */
14688         case OPC_MFC1:
14689         case OPC_CFC1:
14690         case OPC_MTC1:
14691         case OPC_CTC1:
14692             check_cp1_enabled(ctx);
14693             gen_cp1(ctx, op1, rt, rd);
14694             break;
14695 #if defined(TARGET_MIPS64)
14696         case OPC_DMFC1:
14697         case OPC_DMTC1:
14698             check_cp1_enabled(ctx);
14699             check_insn(ctx, ISA_MIPS3);
14700             check_mips_64(ctx);
14701             gen_cp1(ctx, op1, rt, rd);
14702             break;
14703 #endif
14704         case OPC_BC1EQZ: /* OPC_BC1ANY2 */
14705             check_cp1_enabled(ctx);
14706             if (ctx->insn_flags & ISA_MIPS_R6) {
14707                 /* OPC_BC1EQZ */
14708                 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
14709                                        rt, imm << 2, 4);
14710             } else {
14711                 /* OPC_BC1ANY2 */
14712                 check_cop1x(ctx);
14713                 if (!ase_3d_available(env)) {
14714                     return false;
14715                 }
14716                 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
14717                                     (rt >> 2) & 0x7, imm << 2);
14718             }
14719             break;
14720         case OPC_BC1NEZ:
14721             check_cp1_enabled(ctx);
14722             check_insn(ctx, ISA_MIPS_R6);
14723             gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
14724                                    rt, imm << 2, 4);
14725             break;
14726         case OPC_BC1ANY4:
14727             check_cp1_enabled(ctx);
14728             check_insn_opc_removed(ctx, ISA_MIPS_R6);
14729             check_cop1x(ctx);
14730             if (!ase_3d_available(env)) {
14731                 return false;
14732             }
14733             /* fall through */
14734         case OPC_BC1:
14735             check_cp1_enabled(ctx);
14736             check_insn_opc_removed(ctx, ISA_MIPS_R6);
14737             gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
14738                                 (rt >> 2) & 0x7, imm << 2);
14739             break;
14740         case OPC_PS_FMT:
14741             check_ps(ctx);
14742             /* fall through */
14743         case OPC_S_FMT:
14744         case OPC_D_FMT:
14745             check_cp1_enabled(ctx);
14746             gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
14747                        (imm >> 8) & 0x7);
14748             break;
14749         case OPC_W_FMT:
14750         case OPC_L_FMT:
14751         {
14752             int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
14753             check_cp1_enabled(ctx);
14754             if (ctx->insn_flags & ISA_MIPS_R6) {
14755                 switch (r6_op) {
14756                 case R6_OPC_CMP_AF_S:
14757                 case R6_OPC_CMP_UN_S:
14758                 case R6_OPC_CMP_EQ_S:
14759                 case R6_OPC_CMP_UEQ_S:
14760                 case R6_OPC_CMP_LT_S:
14761                 case R6_OPC_CMP_ULT_S:
14762                 case R6_OPC_CMP_LE_S:
14763                 case R6_OPC_CMP_ULE_S:
14764                 case R6_OPC_CMP_SAF_S:
14765                 case R6_OPC_CMP_SUN_S:
14766                 case R6_OPC_CMP_SEQ_S:
14767                 case R6_OPC_CMP_SEUQ_S:
14768                 case R6_OPC_CMP_SLT_S:
14769                 case R6_OPC_CMP_SULT_S:
14770                 case R6_OPC_CMP_SLE_S:
14771                 case R6_OPC_CMP_SULE_S:
14772                 case R6_OPC_CMP_OR_S:
14773                 case R6_OPC_CMP_UNE_S:
14774                 case R6_OPC_CMP_NE_S:
14775                 case R6_OPC_CMP_SOR_S:
14776                 case R6_OPC_CMP_SUNE_S:
14777                 case R6_OPC_CMP_SNE_S:
14778                     gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
14779                     break;
14780                 case R6_OPC_CMP_AF_D:
14781                 case R6_OPC_CMP_UN_D:
14782                 case R6_OPC_CMP_EQ_D:
14783                 case R6_OPC_CMP_UEQ_D:
14784                 case R6_OPC_CMP_LT_D:
14785                 case R6_OPC_CMP_ULT_D:
14786                 case R6_OPC_CMP_LE_D:
14787                 case R6_OPC_CMP_ULE_D:
14788                 case R6_OPC_CMP_SAF_D:
14789                 case R6_OPC_CMP_SUN_D:
14790                 case R6_OPC_CMP_SEQ_D:
14791                 case R6_OPC_CMP_SEUQ_D:
14792                 case R6_OPC_CMP_SLT_D:
14793                 case R6_OPC_CMP_SULT_D:
14794                 case R6_OPC_CMP_SLE_D:
14795                 case R6_OPC_CMP_SULE_D:
14796                 case R6_OPC_CMP_OR_D:
14797                 case R6_OPC_CMP_UNE_D:
14798                 case R6_OPC_CMP_NE_D:
14799                 case R6_OPC_CMP_SOR_D:
14800                 case R6_OPC_CMP_SUNE_D:
14801                 case R6_OPC_CMP_SNE_D:
14802                     gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
14803                     break;
14804                 default:
14805                     gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
14806                                rt, rd, sa, (imm >> 8) & 0x7);
14807 
14808                     break;
14809                 }
14810             } else {
14811                 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
14812                            (imm >> 8) & 0x7);
14813             }
14814             break;
14815         }
14816         default:
14817             MIPS_INVAL("cp1");
14818             gen_reserved_instruction(ctx);
14819             break;
14820         }
14821         break;
14822 
14823     /* Compact branches [R6] and COP2 [non-R6] */
14824     case OPC_BC: /* OPC_LWC2 */
14825     case OPC_BALC: /* OPC_SWC2 */
14826         if (ctx->insn_flags & ISA_MIPS_R6) {
14827             /* OPC_BC, OPC_BALC */
14828             gen_compute_compact_branch(ctx, op, 0, 0,
14829                                        sextract32(ctx->opcode << 2, 0, 28));
14830         } else if (ctx->insn_flags & ASE_LEXT) {
14831             gen_loongson_lswc2(ctx, rt, rs, rd);
14832         } else {
14833             /* OPC_LWC2, OPC_SWC2 */
14834             /* COP2: Not implemented. */
14835             generate_exception_err(ctx, EXCP_CpU, 2);
14836         }
14837         break;
14838     case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
14839     case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
14840         if (ctx->insn_flags & ISA_MIPS_R6) {
14841             if (rs != 0) {
14842                 /* OPC_BEQZC, OPC_BNEZC */
14843                 gen_compute_compact_branch(ctx, op, rs, 0,
14844                                            sextract32(ctx->opcode << 2, 0, 23));
14845             } else {
14846                 /* OPC_JIC, OPC_JIALC */
14847                 gen_compute_compact_branch(ctx, op, 0, rt, imm);
14848             }
14849         } else if (ctx->insn_flags & ASE_LEXT) {
14850             gen_loongson_lsdc2(ctx, rt, rs, rd);
14851         } else {
14852             /* OPC_LWC2, OPC_SWC2 */
14853             /* COP2: Not implemented. */
14854             generate_exception_err(ctx, EXCP_CpU, 2);
14855         }
14856         break;
14857     case OPC_CP2:
14858         check_insn(ctx, ASE_LMMI);
14859         /* Note that these instructions use different fields.  */
14860         gen_loongson_multimedia(ctx, sa, rd, rt);
14861         break;
14862 
14863     case OPC_CP3:
14864         if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
14865             check_cp1_enabled(ctx);
14866             op1 = MASK_CP3(ctx->opcode);
14867             switch (op1) {
14868             case OPC_LUXC1:
14869             case OPC_SUXC1:
14870                 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2);
14871                 /* Fallthrough */
14872             case OPC_LWXC1:
14873             case OPC_LDXC1:
14874             case OPC_SWXC1:
14875             case OPC_SDXC1:
14876                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
14877                 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
14878                 break;
14879             case OPC_PREFX:
14880                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
14881                 /* Treat as NOP. */
14882                 break;
14883             case OPC_ALNV_PS:
14884                 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2);
14885                 /* Fallthrough */
14886             case OPC_MADD_S:
14887             case OPC_MADD_D:
14888             case OPC_MADD_PS:
14889             case OPC_MSUB_S:
14890             case OPC_MSUB_D:
14891             case OPC_MSUB_PS:
14892             case OPC_NMADD_S:
14893             case OPC_NMADD_D:
14894             case OPC_NMADD_PS:
14895             case OPC_NMSUB_S:
14896             case OPC_NMSUB_D:
14897             case OPC_NMSUB_PS:
14898                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
14899                 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
14900                 break;
14901             default:
14902                 MIPS_INVAL("cp3");
14903                 gen_reserved_instruction(ctx);
14904                 break;
14905             }
14906         } else {
14907             generate_exception_err(ctx, EXCP_CpU, 1);
14908         }
14909         break;
14910 
14911 #if defined(TARGET_MIPS64)
14912     /* MIPS64 opcodes */
14913     case OPC_LLD:
14914         if (ctx->insn_flags & INSN_R5900) {
14915             check_insn_opc_user_only(ctx, INSN_R5900);
14916         }
14917         /* fall through */
14918     case OPC_LDL:
14919     case OPC_LDR:
14920     case OPC_LWU:
14921     case OPC_LD:
14922         check_insn(ctx, ISA_MIPS3);
14923         check_mips_64(ctx);
14924         gen_ld(ctx, op, rt, rs, imm);
14925         break;
14926     case OPC_SDL:
14927     case OPC_SDR:
14928     case OPC_SD:
14929         check_insn(ctx, ISA_MIPS3);
14930         check_mips_64(ctx);
14931         gen_st(ctx, op, rt, rs, imm);
14932         break;
14933     case OPC_SCD:
14934         check_insn(ctx, ISA_MIPS3);
14935         if (ctx->insn_flags & INSN_R5900) {
14936             check_insn_opc_user_only(ctx, INSN_R5900);
14937         }
14938         check_mips_64(ctx);
14939         gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_UQ, false);
14940         break;
14941     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
14942         if (ctx->insn_flags & ISA_MIPS_R6) {
14943             /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
14944             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
14945         } else {
14946             /* OPC_DADDI */
14947             check_insn(ctx, ISA_MIPS3);
14948             check_mips_64(ctx);
14949             gen_arith_imm(ctx, op, rt, rs, imm);
14950         }
14951         break;
14952     case OPC_DADDIU:
14953         check_insn(ctx, ISA_MIPS3);
14954         check_mips_64(ctx);
14955         gen_arith_imm(ctx, op, rt, rs, imm);
14956         break;
14957 #else
14958     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
14959         if (ctx->insn_flags & ISA_MIPS_R6) {
14960             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
14961         } else {
14962             MIPS_INVAL("major opcode");
14963             gen_reserved_instruction(ctx);
14964         }
14965         break;
14966 #endif
14967     case OPC_DAUI: /* OPC_JALX */
14968         if (ctx->insn_flags & ISA_MIPS_R6) {
14969 #if defined(TARGET_MIPS64)
14970             /* OPC_DAUI */
14971             check_mips_64(ctx);
14972             if (rs == 0) {
14973                 generate_exception(ctx, EXCP_RI);
14974             } else if (rt != 0) {
14975                 TCGv t0 = tcg_temp_new();
14976                 gen_load_gpr(t0, rs);
14977                 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
14978             }
14979 #else
14980             gen_reserved_instruction(ctx);
14981             MIPS_INVAL("major opcode");
14982 #endif
14983         } else {
14984             /* OPC_JALX */
14985             check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
14986             offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
14987             gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
14988         }
14989         break;
14990     case OPC_MDMX:
14991         /* MDMX: Not implemented. */
14992         break;
14993     case OPC_PCREL:
14994         check_insn(ctx, ISA_MIPS_R6);
14995         gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
14996         break;
14997     default:            /* Invalid */
14998         MIPS_INVAL("major opcode");
14999         return false;
15000     }
15001     return true;
15002 }
15003 
decode_opc(CPUMIPSState * env,DisasContext * ctx)15004 static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
15005 {
15006     /* make sure instructions are on a word boundary */
15007     if (ctx->base.pc_next & 0x3) {
15008         env->CP0_BadVAddr = ctx->base.pc_next;
15009         generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
15010         return;
15011     }
15012 
15013     /* Handle blikely not taken case */
15014     if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
15015         TCGLabel *l1 = gen_new_label();
15016 
15017         tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
15018         tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
15019         gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
15020         gen_set_label(l1);
15021     }
15022 
15023     /* Transition to the auto-generated decoder.  */
15024 
15025     /* Vendor specific extensions */
15026     if (cpu_supports_isa(env, INSN_R5900) && decode_ext_txx9(ctx, ctx->opcode)) {
15027         return;
15028     }
15029     if (cpu_supports_isa(env, INSN_VR54XX) && decode_ext_vr54xx(ctx, ctx->opcode)) {
15030         return;
15031     }
15032     if (TARGET_LONG_BITS == 64 && decode_ext_loongson(ctx, ctx->opcode)) {
15033         return;
15034     }
15035 #if defined(TARGET_MIPS64)
15036     if (ase_lcsr_available(env) && decode_ase_lcsr(ctx, ctx->opcode)) {
15037         return;
15038     }
15039     if (cpu_supports_isa(env, INSN_OCTEON) && decode_ext_octeon(ctx, ctx->opcode)) {
15040         return;
15041     }
15042 #endif
15043 
15044     /* ISA extensions */
15045     if (ase_msa_available(env) && decode_ase_msa(ctx, ctx->opcode)) {
15046         return;
15047     }
15048 
15049     /* ISA (from latest to oldest) */
15050     if (cpu_supports_isa(env, ISA_MIPS_R6) && decode_isa_rel6(ctx, ctx->opcode)) {
15051         return;
15052     }
15053 
15054     if (decode_opc_legacy(env, ctx)) {
15055         return;
15056     }
15057 
15058     gen_reserved_instruction(ctx);
15059 }
15060 
mips_tr_init_disas_context(DisasContextBase * dcbase,CPUState * cs)15061 static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
15062 {
15063     DisasContext *ctx = container_of(dcbase, DisasContext, base);
15064     CPUMIPSState *env = cpu_env(cs);
15065 
15066     ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
15067     ctx->saved_pc = -1;
15068     ctx->insn_flags = env->insn_flags;
15069     ctx->CP0_Config0 = env->CP0_Config0;
15070     ctx->CP0_Config1 = env->CP0_Config1;
15071     ctx->CP0_Config2 = env->CP0_Config2;
15072     ctx->CP0_Config3 = env->CP0_Config3;
15073     ctx->CP0_Config5 = env->CP0_Config5;
15074     ctx->btarget = 0;
15075     ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
15076     ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
15077     ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
15078     ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
15079     ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
15080     ctx->PAMask = env->PAMask;
15081     ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
15082     ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
15083     ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
15084     ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
15085     ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
15086     /* Restore delay slot state from the tb context.  */
15087     ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
15088     ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
15089     ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
15090              (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
15091     ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
15092     ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
15093     ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
15094     ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
15095     ctx->mi = (env->CP0_Config5 >> CP0C5_MI) & 1;
15096     ctx->gi = (env->CP0_Config5 >> CP0C5_GI) & 3;
15097     restore_cpu_state(env, ctx);
15098 #ifdef CONFIG_USER_ONLY
15099         ctx->mem_idx = MIPS_HFLAG_UM;
15100 #else
15101         ctx->mem_idx = hflags_mmu_index(ctx->hflags);
15102 #endif
15103     ctx->default_tcg_memop_mask = (!(ctx->insn_flags & ISA_NANOMIPS32) &&
15104                                   (ctx->insn_flags & (ISA_MIPS_R6 |
15105                                   INSN_LOONGSON3A))) ? MO_UNALN : MO_ALIGN;
15106 
15107     /*
15108      * Execute a branch and its delay slot as a single instruction.
15109      * This is what GDB expects and is consistent with what the
15110      * hardware does (e.g. if a delay slot instruction faults, the
15111      * reported PC is the PC of the branch).
15112      */
15113     if ((tb_cflags(ctx->base.tb) & CF_SINGLE_STEP) &&
15114         (ctx->hflags & MIPS_HFLAG_BMASK)) {
15115         ctx->base.max_insns = 2;
15116     }
15117 
15118     LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
15119               ctx->hflags);
15120 }
15121 
mips_tr_tb_start(DisasContextBase * dcbase,CPUState * cs)15122 static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
15123 {
15124 }
15125 
mips_tr_insn_start(DisasContextBase * dcbase,CPUState * cs)15126 static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
15127 {
15128     DisasContext *ctx = container_of(dcbase, DisasContext, base);
15129 
15130     tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
15131                        ctx->btarget);
15132 }
15133 
mips_tr_translate_insn(DisasContextBase * dcbase,CPUState * cs)15134 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
15135 {
15136     CPUMIPSState *env = cpu_env(cs);
15137     DisasContext *ctx = container_of(dcbase, DisasContext, base);
15138     int insn_bytes;
15139     int is_slot;
15140 
15141     is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
15142     if (ctx->insn_flags & ISA_NANOMIPS32) {
15143         ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
15144         insn_bytes = decode_isa_nanomips(env, ctx);
15145     } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
15146         ctx->opcode = translator_ldl(env, &ctx->base, ctx->base.pc_next);
15147         insn_bytes = 4;
15148         decode_opc(env, ctx);
15149     } else if (ctx->insn_flags & ASE_MICROMIPS) {
15150         ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
15151         insn_bytes = decode_isa_micromips(env, ctx);
15152     } else if (ctx->insn_flags & ASE_MIPS16) {
15153         ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
15154         insn_bytes = decode_ase_mips16e(env, ctx);
15155     } else {
15156         gen_reserved_instruction(ctx);
15157         g_assert(ctx->base.is_jmp == DISAS_NORETURN);
15158         return;
15159     }
15160 
15161     if (ctx->hflags & MIPS_HFLAG_BMASK) {
15162         if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
15163                              MIPS_HFLAG_FBNSLOT))) {
15164             /*
15165              * Force to generate branch as there is neither delay nor
15166              * forbidden slot.
15167              */
15168             is_slot = 1;
15169         }
15170         if ((ctx->hflags & MIPS_HFLAG_M16) &&
15171             (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
15172             /*
15173              * Force to generate branch as microMIPS R6 doesn't restrict
15174              * branches in the forbidden slot.
15175              */
15176             is_slot = 1;
15177         }
15178     }
15179     if (is_slot) {
15180         gen_branch(ctx, insn_bytes);
15181     }
15182     if (ctx->base.is_jmp == DISAS_SEMIHOST) {
15183         generate_exception_err(ctx, EXCP_SEMIHOST, insn_bytes);
15184     }
15185     ctx->base.pc_next += insn_bytes;
15186 
15187     if (ctx->base.is_jmp != DISAS_NEXT) {
15188         return;
15189     }
15190 
15191     /*
15192      * End the TB on (most) page crossings.
15193      * See mips_tr_init_disas_context about single-stepping a branch
15194      * together with its delay slot.
15195      */
15196     if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE
15197         && !(tb_cflags(ctx->base.tb) & CF_SINGLE_STEP)) {
15198         ctx->base.is_jmp = DISAS_TOO_MANY;
15199     }
15200 }
15201 
mips_tr_tb_stop(DisasContextBase * dcbase,CPUState * cs)15202 static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
15203 {
15204     DisasContext *ctx = container_of(dcbase, DisasContext, base);
15205 
15206     switch (ctx->base.is_jmp) {
15207     case DISAS_STOP:
15208         gen_save_pc(ctx->base.pc_next);
15209         tcg_gen_lookup_and_goto_ptr();
15210         break;
15211     case DISAS_NEXT:
15212     case DISAS_TOO_MANY:
15213         save_cpu_state(ctx, 0);
15214         gen_goto_tb(ctx, 0, ctx->base.pc_next);
15215         break;
15216     case DISAS_EXIT:
15217         tcg_gen_exit_tb(NULL, 0);
15218         break;
15219     case DISAS_NORETURN:
15220         break;
15221     default:
15222         g_assert_not_reached();
15223     }
15224 }
15225 
15226 static const TranslatorOps mips_tr_ops = {
15227     .init_disas_context = mips_tr_init_disas_context,
15228     .tb_start           = mips_tr_tb_start,
15229     .insn_start         = mips_tr_insn_start,
15230     .translate_insn     = mips_tr_translate_insn,
15231     .tb_stop            = mips_tr_tb_stop,
15232 };
15233 
gen_intermediate_code(CPUState * cs,TranslationBlock * tb,int * max_insns,vaddr pc,void * host_pc)15234 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
15235                            vaddr pc, void *host_pc)
15236 {
15237     DisasContext ctx;
15238 
15239     translator_loop(cs, tb, max_insns, pc, host_pc, &mips_tr_ops, &ctx.base);
15240 }
15241 
mips_tcg_init(void)15242 void mips_tcg_init(void)
15243 {
15244     cpu_gpr[0] = NULL;
15245     for (unsigned i = 1; i < 32; i++)
15246         cpu_gpr[i] = tcg_global_mem_new(tcg_env,
15247                                         offsetof(CPUMIPSState,
15248                                                  active_tc.gpr[i]),
15249                                         regnames[i]);
15250 #if defined(TARGET_MIPS64)
15251     cpu_gpr_hi[0] = NULL;
15252 
15253     for (unsigned i = 1; i < 32; i++) {
15254         g_autofree char *rname = g_strdup_printf("%s[hi]", regnames[i]);
15255 
15256         cpu_gpr_hi[i] = tcg_global_mem_new_i64(tcg_env,
15257                                                offsetof(CPUMIPSState,
15258                                                         active_tc.gpr_hi[i]),
15259                                                rname);
15260     }
15261 #endif /* !TARGET_MIPS64 */
15262     for (unsigned i = 0; i < 32; i++) {
15263         int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
15264 
15265         fpu_f64[i] = tcg_global_mem_new_i64(tcg_env, off, fregnames[i]);
15266     }
15267     msa_translate_init();
15268     cpu_PC = tcg_global_mem_new(tcg_env,
15269                                 offsetof(CPUMIPSState, active_tc.PC), "PC");
15270     for (unsigned i = 0; i < MIPS_DSP_ACC; i++) {
15271         cpu_HI[i] = tcg_global_mem_new(tcg_env,
15272                                        offsetof(CPUMIPSState, active_tc.HI[i]),
15273                                        regnames_HI[i]);
15274         cpu_LO[i] = tcg_global_mem_new(tcg_env,
15275                                        offsetof(CPUMIPSState, active_tc.LO[i]),
15276                                        regnames_LO[i]);
15277     }
15278     cpu_dspctrl = tcg_global_mem_new(tcg_env,
15279                                      offsetof(CPUMIPSState,
15280                                               active_tc.DSPControl),
15281                                      "DSPControl");
15282     bcond = tcg_global_mem_new(tcg_env,
15283                                offsetof(CPUMIPSState, bcond), "bcond");
15284     btarget = tcg_global_mem_new(tcg_env,
15285                                  offsetof(CPUMIPSState, btarget), "btarget");
15286     hflags = tcg_global_mem_new_i32(tcg_env,
15287                                     offsetof(CPUMIPSState, hflags), "hflags");
15288 
15289     fpu_fcr0 = tcg_global_mem_new_i32(tcg_env,
15290                                       offsetof(CPUMIPSState, active_fpu.fcr0),
15291                                       "fcr0");
15292     fpu_fcr31 = tcg_global_mem_new_i32(tcg_env,
15293                                        offsetof(CPUMIPSState, active_fpu.fcr31),
15294                                        "fcr31");
15295     cpu_lladdr = tcg_global_mem_new(tcg_env, offsetof(CPUMIPSState, lladdr),
15296                                     "lladdr");
15297     cpu_llval = tcg_global_mem_new(tcg_env, offsetof(CPUMIPSState, llval),
15298                                    "llval");
15299 
15300     if (TARGET_LONG_BITS == 32) {
15301         mxu_translate_init();
15302     }
15303 }
15304 
mips_restore_state_to_opc(CPUState * cs,const TranslationBlock * tb,const uint64_t * data)15305 void mips_restore_state_to_opc(CPUState *cs,
15306                                const TranslationBlock *tb,
15307                                const uint64_t *data)
15308 {
15309     CPUMIPSState *env = cpu_env(cs);
15310 
15311     env->active_tc.PC = data[0];
15312     env->hflags &= ~MIPS_HFLAG_BMASK;
15313     env->hflags |= data[1];
15314     switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
15315     case MIPS_HFLAG_BR:
15316         break;
15317     case MIPS_HFLAG_BC:
15318     case MIPS_HFLAG_BL:
15319     case MIPS_HFLAG_B:
15320         env->btarget = data[2];
15321         break;
15322     }
15323 }
15324